📄 wap_push_ppg.c
字号:
/* ==================================================================== * The Kannel Software License, Version 1.0 * * Copyright (c) 2001-2005 Kannel Group * Copyright (c) 1998-2001 WapIT Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Kannel Group (http://www.kannel.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Kannel" and "Kannel Group" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please * contact org@kannel.org. * * 5. Products derived from this software may not be called "Kannel", * nor may "Kannel" appear in their name, without prior written * permission of the Kannel Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Kannel Group. For more information on * the Kannel Group, please see <http://www.kannel.org/>. * * Portions of this software are based upon software originally written at * WapIT Ltd., Helsinki, Finland for the Kannel project. */ /* * wap_push_ppg.c: General logic of a push proxy gateway. * * This module implements following WAP Forum specifications: * WAP-151-PPGService-19990816-a (called afterwards PPG), * WAP-164-PAP-19991108-a (PAP), * WAP-164_100-PAP-20000218-a (PAP implementation note). * * We refer following WAP Forum specifications: * WAP-145-PushMessage-19990816-a (push message) * WAP-200-WDP-20001212-a (WDP) * WAP-203-WSP-20000504-a (WSP) * WAP-189-PushOTA-20000217-a (OTA). * * In addition, RFCs 1521 and 2045 are referred. * * By Aarno Syv鋳nen for Wapit Ltd, Wiral Ltd and Global Networks Inc. */#include <time.h>#include <ctype.h>#include "wap_push_ppg.h"#include "wap/wap_events.h"#include "wap/wsp_caps.h"#include "wml_compiler.h"#include "wap-appl.h"#include "wap/wsp.h"#include "wap/wsp_strings.h"#include "wap_push_si_compiler.h"#include "wap_push_sl_compiler.h"#include "wap_push_pap_compiler.h"#include "wap_push_pap_mime.h"#include "wap_push_ppg_pushuser.h"enum { TIME_EXPIRED = 0, TIME_TOO_EARLY = 1, NO_CONSTRAINTS = 2};/* * Default values for configuration variables */enum { DEFAULT_HTTP_PORT = 8080, NO_HTTPS_PORT = -1, DEFAULT_NUMBER_OF_PUSHES = 100, PI_TRUSTED = 1, SSL_CONNECTION_OFF = 0, DEFAULT_NUMBER_OF_USERS = 1024, USER_CONFIGURATION_NOT_ADDED = 0};enum { USER_CONFIGURATION_ADDED = 1 };#define DEFAULT_PPG_URL "/wappush"/***************************************************************************** * * Internal data structures * * Give the status of the push ppg module: * * limbo * not running at all * running * operating normally * terminating * waiting for operations to terminate, returning to limbo */static enum {limbo, running, terminating} run_status = limbo;/* * The external event queue for this module */static List *ppg_queue = NULL;/* * The internal event queue for this module (allowing listening of many ports) */static List *pap_queue = NULL;/* * List of ppg session machines (it is, of currently active sessions) */static List *ppg_machines = NULL;/* * List of currently active unit pushes (we need a threadsafe storage for them, * because pushes can be cancelled and queried): */static List *ppg_unit_pushes = NULL;/* * Counter to store our internal push id. */static Counter *push_id_counter = NULL;/* * We need a mapping between HTTPClient structures, used by http library, and * push ids, used by ppg. */static Dict *http_clients = NULL;/* * Mapping between urls used by pi and push ids used by ppg. */static Dict *urls = NULL;/* * Push content packed for compilers (wml, si, sl, co). */struct content { Octstr *body; Octstr *type; Octstr *charset;};static wap_dispatch_func_t *dispatch_to_ota;static wap_dispatch_func_t *dispatch_to_appl;/* * Configurable variables of ppg core group (for general configuration of a * ppg), with some default values. */static Octstr *ppg_url = NULL ;static long ppg_port = DEFAULT_HTTP_PORT;#ifdef HAVE_LIBSSLstatic long ppg_ssl_port = NO_HTTPS_PORT;#endifstatic long number_of_pushes = DEFAULT_NUMBER_OF_PUSHES;static int trusted_pi = PI_TRUSTED;static long number_of_users = DEFAULT_NUMBER_OF_USERS;static Octstr *ppg_deny_ip = NULL;static Octstr *ppg_allow_ip = NULL; static int user_configuration = USER_CONFIGURATION_NOT_ADDED;static Octstr *global_sender = NULL;static Octstr *ppg_default_smsc = NULL; #ifdef HAVE_LIBSSLstatic Octstr *ssl_server_cert_file = NULL;static Octstr *ssl_server_key_file = NULL;#endifstatic Octstr *ppg_dlr_url = NULL;static Octstr *ppg_smsbox_id = NULL; static Octstr *service_name = NULL;struct PAPEvent { HTTPClient *client; Octstr *ip; Octstr *url; List *push_headers; Octstr *mime_content; List *cgivars;};typedef struct PAPEvent PAPEvent;/***************************************************************************** * * Prototypes of internal functions * * Event handling */static void ota_read_thread(void *arg);static void http_read_thread(void *arg);#ifdef HAVE_LIBSSLstatic void https_read_thread(void *arg);#endifstatic void handle_internal_event(WAPEvent *e);static void pap_request_thread(void *arg);static int handle_push_message(HTTPClient **c, WAPEvent *ppg_event, int status);static PAPEvent *pap_event_create(Octstr *ip, Octstr *url, List *push_headers, Octstr *mime_content, List *cgivars, HTTPClient *client);static void pap_event_destroy(PAPEvent *p);static void pap_event_destroy_item(void *p);static void pap_event_unpack(PAPEvent *p, Octstr **ip, Octstr **url, List **push_headers, Octstr **mime_content, List **cgivars, HTTPClient **client);/* * Constructors and destructors for machines. */static PPGSessionMachine *session_machine_create(WAPAddrTuple *tuple, WAPEvent *e);static void session_machine_destroy(void *p);static PPGPushMachine *push_machine_create(WAPEvent *e, WAPAddrTuple *tuple);static void push_machine_destroy(void *pm);static void push_machines_list_destroy(List *pl);/* * Communicating other modules (ota and appl) */static void create_session(WAPEvent *e, PPGPushMachine *pm);static void request_confirmed_push(long last, PPGPushMachine *pm, PPGSessionMachine *sm);static void request_unit_push(long last, PPGPushMachine *pm);static void request_push(long last, PPGPushMachine *sm);static int response_push_connection(WAPEvent *e, PPGSessionMachine *sm);static HTTPClient *response_push_message(PPGPushMachine *pm, long code, int status);/* * Functions to find machines using various identifiers, and related help * functions. */static PPGSessionMachine *session_find_using_pi_client_address(Octstr *addr);static PPGPushMachine *find_ppg_push_machine_using_pid(PPGSessionMachine *sm, long pid);static PPGPushMachine *find_ppg_push_machine_using_pi_push_id( PPGSessionMachine *sm, Octstr *pi_push_id);static PPGPushMachine *find_unit_ppg_push_machine_using_pi_push_id( Octstr *pi_push_id);static int push_has_pi_push_id(void *a, void *b);static int push_has_pid(void *a, void *b);static int session_has_pi_client_address(void *a, void *b);static int session_has_addr(void *a, void *b);static int session_has_sid(void *a, void *b);/* * Main logic of PPG. */static int check_capabilities(List *requested, List *assumed);static int transform_message(WAPEvent **e, WAPAddrTuple **tuple, List *push_headers, int connected, Octstr **type);static long check_x_wap_application_id_header(List **push_headers);static int pap_convert_content(struct content *content);static int pap_get_content(struct content *content);static int select_bearer_network(WAPEvent **e);static int delivery_time_constraints(WAPEvent *e, PPGPushMachine *pm);static void deliver_confirmed_push(long last, PPGPushMachine *pm, PPGSessionMachine *sm);static PPGPushMachine *deliver_unit_push(long last, PPGPushMachine *pm, PPGSessionMachine *sm, int session_exists);static int store_push_data(PPGPushMachine **pm, PPGSessionMachine *sm, WAPEvent *e, WAPAddrTuple *tuple, int cless);static PPGPushMachine *update_push_data_with_attribute(PPGSessionMachine **sm, PPGPushMachine *pm, long reason, long status);static void remove_push_data(PPGSessionMachine *sm, PPGPushMachine *pm, int cless);static void remove_session_data(PPGSessionMachine *sm, int status);static void remove_pushless_session(PPGSessionMachine *sm);static PPGSessionMachine *store_session_data(PPGSessionMachine *sm, WAPEvent *e, WAPAddrTuple *tuple, int *session_exists);static PPGSessionMachine *update_session_data_with_headers( PPGSessionMachine *sm, PPGPushMachine *pm);static void deliver_pending_pushes(PPGSessionMachine *sm, int last);static PPGPushMachine *abort_delivery(PPGSessionMachine *sm, int status);static PPGSessionMachine *update_session_data(PPGSessionMachine *sm, long sid, long port, List *caps);static int confirmation_requested(WAPEvent *e);static int cless_accepted(WAPEvent *e, PPGSessionMachine *sm);/* * Header functions */static int headers_acceptable(List *push_headers, Octstr **content_header);static int type_is(Octstr *content_header, char *required_type);static int get_mime_boundary(List *push_headers, Octstr *content_header, Octstr **boundary);static void change_header_value(List **push_headers, char *name, char *value);static void remove_mime_headers(List **push_headers);static void remove_link_headers(List **push_headers);static void remove_x_kannel_headers(List **push_headers);/* * Communicating with pi. */static void send_bad_message_response(HTTPClient **c, Octstr *body_fragment, int code, int status);static HTTPClient *send_push_response(WAPEvent *e, int status);static void send_to_pi(HTTPClient **c, Octstr *reply_body, int status);static void tell_fatal_error(HTTPClient **c, WAPEvent *e, Octstr *url, int status, int code);/* * PPG core authentication (not related to any particular user). */static int read_ppg_config(Cfg *cfg);static int ip_allowed_by_ppg(Octstr *ip);/* * Interface to various compilers */static Octstr *convert_wml_to_wmlc(struct content *content);static Octstr *convert_si_to_sic(struct content *content);static Octstr *convert_sl_to_slc(struct content *content);/* * Setting values for controlling sms level. (Pap control document enables * some control, but not enough.) */static Octstr *set_smsc_id(List *headers, Octstr *username, int trusted_pi);static Octstr *set_dlr_url(List *headers, Octstr *username, int trusted_pi);static long set_dlr_mask(List *headers, Octstr *dlr_url);static Octstr *set_smsbox_id(List *headers, Octstr *username, int trusted_pi);static Octstr *set_service_name(void);/* * Various utility functions */static Octstr *set_time(void);static int deliver_before_test_cleared(Octstr *before, struct tm now);static int deliver_after_test_cleared(Octstr *after, struct tm now);static void session_machine_assert(PPGSessionMachine *sm);static void push_machine_assert(PPGPushMachine *pm);static Octstr *tell_ppg_name(void);static Octstr *describe_code(long code);static long ota_abort_to_pap(long reason);static int content_transformable(List *push_headers);static WAPAddrTuple *set_addr_tuple(Octstr *address, long cliport, long servport, long address_type, List *push_headers);static WAPAddrTuple *addr_tuple_change_cliport(WAPAddrTuple *tuple, long port);static void initialize_time_item_array(long time_data[], struct tm now);static int date_item_compare(Octstr *before, long time_data, long pos);static long parse_appid_header(Octstr **assigned_code);static Octstr *escape_fragment(Octstr *fragment);static int coriented_deliverable(long code);static int is_phone_number(long type_of_address);static void replace_octstr_char(Octstr *os1, Octstr *os2, long *pos);/***************************************************************************** * * EXTERNAL FUNCTIONS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -