static void main_thread(void *arg) { WAPEvent *e; WSPMachine *sm; WSP_PDU *pdu; while (run_status == running && (e = gwlist_consume(queue)) != NULL) { wap_event_assert(e); switch (e->type) { case TR_Invoke_Ind: pdu = wsp_pdu_unpack(e->u.TR_Invoke_Ind.user_data); if (pdu == NULL) { warning(0, "WSP: Broken PDU ignored."); wap_event_destroy(e); continue; } break; default: pdu = NULL; break; } sm = find_session_machine(e, pdu); if (sm == NULL) { wap_event_destroy(e); } else { handle_session_event(sm, e, pdu); } wsp_pdu_destroy(pdu); } }
/* * Feed an event to a WSP push client state machine. Do not report errors to * the caller. */ static void push_client_event_handle(WSPPushClientMachine *cpm, WAPEvent *e) { WAPEvent *wtp_event; WSP_PDU *pdu = NULL; wap_event_assert(e); gw_assert(cpm); if (e->type == TR_Invoke_Ind) { pdu = wsp_pdu_unpack(e->u.TR_Invoke_Ind.user_data); /* * Class 1 tests here * Case 4, no session matching address quadruplet, handled by the session mach- * ine. * Tests from table WSP, page 45. Case 5, a PDU state tables cannot handle. */ if (pdu == NULL || pdu->type != ConfirmedPush) { wap_event_destroy(e); wtp_event = send_abort_to_responder(cpm, PROTOERR); wtp_resp_dispatch_event(wtp_event); return; } } debug("wap.wsp", 0, "WSP_PUSH: WSPPushClientMachine %ld, state %s," " event %s", cpm->client_push_id, name_push_client_state(cpm->state), wap_event_name(e->type)); #define PUSH_CLIENT_STATE_NAME(state) #define ROW(push_state, event_type, condition, action, next_state) \ if (cpm->state == push_state && \ e->type == event_type && \ (condition)) { \ action \ cpm->state = next_state; \ debug("wap.wsp", 0, "WSP_PUSH %ld: new state %s", \ cpm->client_push_id, #next_state); \ } else #include "wsp_push_client_states.def" { error(0, "WSP_PUSH: handle_event: unhandled event!"); debug("wap.wsp", 0, "Unhandled event was:"); wap_event_dump(e); wap_event_destroy(e); return; } wsp_pdu_destroy(pdu); wap_event_destroy(e); if (cpm->state == PUSH_CLIENT_NULL_STATE) push_client_machine_destroy(cpm); }
static void handle_ota_event(WAPEvent *e) { debug("wap.push.ota", 0, "OTA: event arrived"); switch (e->type) { case Pom_SessionRequest_Req: make_session_request(e); break; case Po_Push_Req: make_push_request(e); break; case Po_ConfirmedPush_Req: make_confirmed_push_request(e); break; case Po_Unit_Push_Req: make_unit_push_request(e); break; case Po_PushAbort_Req: abort_push(e); break; default: debug("wap.push.ota", 0, "OTA: unhandled event"); wap_event_dump(e); break; } wap_event_destroy(e); }
static void wtp_event_dump(Msg *msg) { WAPEvent *dgram; List *events; long i, n; dgram = wdp_msg2event(msg); if (dgram == NULL) error(0, "dgram is null"); /* pdu = wtp_pdu_unpack(dgram->u.T_DUnitdata_Ind.user_data); if (pdu == NULL) { error(0, "WTP PDU unpacking failed, WAP event is:"); wap_event_dump(dgram); } else { wtp_pdu_dump(pdu, 0); wtp_pdu_destroy(pdu); } */ events = wtp_unpack_wdp_datagram(dgram); n = gwlist_len(events); debug("wap.proxy",0,"datagram contains %ld events", n); i = 1; while (gwlist_len(events) > 0) { WAPEvent *event; event = gwlist_extract_first(events); info(0, "WTP: %ld/%ld event %s.", i, n, wap_event_name(event->type)); if (wtp_event_is_for_responder(event)) /* wtp_resp_dispatch_event(event); */ debug("",0,"datagram is for WTP responder"); else /* wtp_initiator_dispatch_event(event); */ debug("",0,"datagram is for WTP initiator"); wap_event_dump(event); /* switch (event->type) { RcvInvoke: debug("",0,"XXX invoke"); break; RcvResult: debug("",0,"XXX result"); break; default: error(0,"unkown WTP event type while unpacking"); break; } */ i++; } wap_event_destroy(dgram); gwlist_destroy(events, NULL); }
static void handle_session_event(WSPMachine *sm, WAPEvent *current_event, WSP_PDU *pdu) { debug("wap.wsp", 0, "WSP: machine %p, state %s, event %s", (void *) sm, state_name(sm->state), wap_event_name(current_event->type)); #define STATE_NAME(name) #define ROW(state_name, event, condition, action, next_state) \ { \ struct event *e; \ e = ¤t_event->u.event; \ if (sm->state == state_name && \ current_event->type == event && \ (condition)) { \ action \ sm->state = next_state; \ debug("wap.wsp", 0, "WSP %ld: New state %s", \ sm->session_id, #next_state); \ goto end; \ } \ } #include "wsp_server_session_states.def" cant_handle_event(sm, current_event); end: wap_event_destroy(current_event); if (sm->state == NULL_SESSION) machine_destroy(sm); }
static void wdp_event_dump(Msg *msg) { WAPEvent *dgram; if ((dgram = wdp_msg2event(msg)) != NULL) /* wap_dispatch_datagram(dgram); */ wap_event_dump(dgram); wap_event_destroy(dgram); }
/* * Feed an event to a WTP responder state machine. Handle all errors yourself, * do not report them to the caller. Note: Do not put {}s of the else block * inside the macro definition. */ static void wtls_event_handle(WTLSMachine * wtls_machine, WAPEvent * event) { debug("wap.wtls", 0, "WTLS: wtls_machine %ld, state %s, event %s.", wtls_machine->mid, stateName(wtls_machine->state), wap_event_name(event->type)); /* for T_Unitdata_Ind PDUs */ if (event->type == T_Unitdata_Ind) { /* if encryption: decrypt all pdus in the list */ if (wtls_machine->encrypted) wtls_decrypt_pdu_list(wtls_machine, event->u.T_Unitdata_Ind.pdu_list); /* add all handshake data to wtls_machine->handshake_data */ //add_all_handshake_data(wtls_machine, event->u.T_Unitdata_Ind.pdu_list); } #define STATE_NAME(state) #define ROW(wtls_state, event_type, condition, action, next_state) \ if (wtls_machine->state == wtls_state && \ event->type == event_type && \ (condition)) { \ action \ wtls_machine->state = next_state; \ debug("wap.wtls", 0, "WTLS %ld: New state %s", wtls_machine->mid, #next_state); \ } else #include "wtls_state-decl.h" { error(0, "WTLS: handle_event: unhandled event!"); debug("wap.wtls", 0, "WTLS: handle_event: Unhandled event was:"); wap_event_destroy(event); return; } if (event) wap_event_destroy(event); if (wtls_machine->state == NULL_STATE) { wtls_machine_destroy(wtls_machine); wtls_machine = NULL; } }
void gwtimer_destroy(Timer *timer) { gw_assert(initialized); if (timer == NULL) return; gwtimer_stop(timer); gwlist_remove_producer(timer->output); wap_event_destroy(timer->event); gw_free(timer); }
static void main_thread(void *arg) { WTLSMachine *sm; WAPEvent *e; while (wtls_run_status == running && (e = gwlist_consume(wtls_queue))) { sm = wtls_machine_find_or_create(e); if (sm == NULL) wap_event_destroy(e); else wtls_event_handle(sm, e); } }
static void main_thread(void *arg) { WSPPushClientMachine *cpm; WAPEvent *e; while (push_client_run_status == running && (e = gwlist_consume(push_client_queue)) != NULL) { cpm = push_client_machine_find_or_create(e); if (cpm == NULL) wap_event_destroy(e); else push_client_event_handle(cpm, e); } }
/****************************************************************************** * * EXTERNAL FUNCTIONS: * * Handles a possible concatenated message. Creates a list of wap events. */ List *wtp_unpack_wdp_datagram(WAPEvent *datagram) { List *events = NULL; WAPEvent *event = NULL; WAPEvent *subdgram = NULL; Octstr *data = NULL; long pdu_len; gw_assert(datagram->type == T_DUnitdata_Ind); events = gwlist_create(); if (concatenated_message(datagram->u.T_DUnitdata_Ind.user_data)) { data = octstr_duplicate(datagram->u.T_DUnitdata_Ind.user_data); octstr_delete(data, 0, 1); while (octstr_len(data) != 0) { if (octstr_get_bits(data, 0, 1) == 0) { pdu_len = octstr_get_char(data, 0); octstr_delete(data, 0, 1); } else { pdu_len = octstr_get_bits(data, 1, 15); octstr_delete(data, 0, 2); } subdgram = wap_event_duplicate(datagram); octstr_destroy(subdgram->u.T_DUnitdata_Ind.user_data); subdgram->u.T_DUnitdata_Ind.user_data = octstr_copy(data, 0, pdu_len); wap_event_assert(subdgram); if ((event = unpack_wdp_datagram_real(subdgram)) != NULL) { wap_event_assert(event); gwlist_append(events, event); } octstr_delete(data, 0, pdu_len); wap_event_destroy(subdgram); } octstr_destroy(data); } else if ((event = unpack_wdp_datagram_real(datagram)) != NULL) { wap_event_assert(event); gwlist_append(events, event); } else { warning(0, "WTP: Dropping unhandled datagram data:"); octstr_dump(datagram->u.T_DUnitdata_Ind.user_data, 0, GW_WARNING); } return events; }
static void main_thread(void *arg) { WTPInitMachine *sm; WAPEvent *e; while (initiator_run_status == running && (e = gwlist_consume(queue)) != NULL) { sm = init_machine_find_or_create(e); if (sm == NULL) wap_event_destroy(e); else handle_init_event(sm, e); } }
/* * Feed an event to a WTP initiator state machine. Handle all errors by do not * report them to the caller. WSP indication or conformation is handled by an * included state table. Note: Do not put {}s of the else block inside the * macro definition . */ static void handle_init_event(WTPInitMachine *init_machine, WAPEvent *event) { WAPEvent *wsp_event = NULL; debug("wap.wtp", 0, "WTP_INIT: initiator machine %ld, state %s," " event %s.", init_machine->mid, name_init_state(init_machine->state), wap_event_name(event->type)); #define INIT_STATE_NAME(state) #define ROW(init_state, event_type, condition, action, next_state) \ if (init_machine->state == init_state && \ event->type == event_type && \ (condition)) { \ action \ init_machine->state = next_state; \ debug("wap.wtp", 0, "WTP_INIT %ld: New state %s", \ init_machine->mid, #next_state); \ } else #include "wtp_init_states.def" { error(1, "WTP_INIT: handle_init_event: unhandled event!"); debug("wap.wtp.init", 0, "WTP_INIT: handle_init_event:" "Unhandled event was:"); wap_event_dump(event); wap_event_destroy(event); return; } if (event != NULL) { wap_event_destroy(event); } if (init_machine->state == INITIATOR_NULL_STATE) init_machine_destroy(init_machine); }
/* * Go back and remove this timer's elapse event from the output list, * to pretend that it didn't elapse after all. This is necessary * to deal with some races between the timer thread and the caller's * start/stop actions. */ static void abort_elapsed(Timer *timer) { long count; if (timer->elapsed_event == NULL) return; count = gwlist_delete_equal(timer->output, timer->elapsed_event); if (count > 0) { debug("timers", 0, "Aborting %s timer.", wap_event_name(timer->elapsed_event->type)); wap_event_destroy(timer->elapsed_event); } timer->elapsed_event = NULL; }
void gwtimer_start(Timer *timer, int interval, WAPEvent *event) { int wakeup = 0; gw_assert(initialized); gw_assert(timer != NULL); gw_assert(event != NULL || timer->event != NULL); lock(timers); /* Convert to absolute time */ interval += time(NULL); if (timer->elapses > 0) { /* Resetting an existing timer. Move it to its new * position in the heap. */ if (interval < timer->elapses && timer->index == 0) wakeup = 1; timer->elapses = interval; gw_assert(timers->heap->tab[timer->index] == timer); wakeup |= heap_adjust(timers->heap, timer->index); } else { /* Setting a new timer, or resetting an elapsed one. * First deal with a possible elapse event that may * still be on the output list. */ abort_elapsed(timer); /* Then activate the timer. */ timer->elapses = interval; gw_assert(timer->index < 0); heap_insert(timers->heap, timer); wakeup = timer->index == 0; /* Do we have a new top? */ } if (event != NULL) { wap_event_destroy(timer->event); timer->event = event; } unlock(timers); if (wakeup) gwthread_wakeup(timers->thread); }
/* * Send IP datagram as it is, segment SMS datagram if necessary. */ static void dispatch_datagram(WAPEvent *dgram) { Msg *msg, *part; List *sms_datagrams; static unsigned long msg_sequence = 0L; /* Used only by this function */ msg = part = NULL; sms_datagrams = NULL; if (dgram == NULL) { error(0, "WDP: dispatch_datagram received empty datagram, ignoring."); } else if (dgram->type != T_DUnitdata_Req) { warning(0, "WDP: dispatch_datagram received event of unexpected type."); wap_event_dump(dgram); } else if (dgram->u.T_DUnitdata_Req.address_type == ADDR_IPV4) { #ifdef HAVE_WTLS_OPENSSL if (dgram->u.T_DUnitdata_Req.addr_tuple->local->port >= WTLS_CONNECTIONLESS_PORT) wtls_dispatch_resp(dgram); else #endif /* HAVE_WTLS_OPENSSL */ { msg = pack_ip_datagram(dgram); write_to_bearerbox(msg); } } else { msg_sequence = counter_increase(sequence_counter) & 0xff; msg = pack_sms_datagram(dgram); sms_datagrams = sms_split(msg, NULL, NULL, NULL, NULL, concatenation, msg_sequence, max_messages, MAX_SMS_OCTETS); debug("wap",0,"WDP (wapbox): delivering %ld segments to bearerbox", gwlist_len(sms_datagrams)); while ((part = gwlist_extract_first(sms_datagrams)) != NULL) { write_to_bearerbox(part); } gwlist_destroy(sms_datagrams, NULL); msg_destroy(msg); } wap_event_destroy(dgram); }
static void clientHello(WAPEvent * event, WTLSMachine * wtls_machine) { /* The Wap event we have to dispatch */ WAPEvent *res; wtls_Payload *tempPayload; wtls_PDU *clientHelloPDU; CipherSuite *ciphersuite; int randomCounter, algo; tempPayload = (wtls_Payload *) gwlist_search(event->u.T_Unitdata_Ind.pdu_list, (void *)client_hello, match_handshake_type); if (!tempPayload) { error(0, "Illegal PDU while waiting for a ClientHello"); fatalAlert(event, unexpected_message); return; } clientHelloPDU = wtls_pdu_unpack(tempPayload, wtls_machine); /* Store the client's random value - use pack for simplicity */ wtls_machine->client_random = octstr_create(""); randomCounter = pack_int32(wtls_machine->client_random, 0, clientHelloPDU->u.handshake.client_hello-> random->gmt_unix_time); octstr_insert(wtls_machine->client_random, clientHelloPDU->u.handshake.client_hello->random-> random_bytes, randomCounter); /* Select the ciphersuite from the supplied list */ ciphersuite = wtls_choose_ciphersuite(clientHelloPDU->u.handshake.client_hello-> ciphersuites); if (!ciphersuite) { error(0, "Couldn't agree on encryption cipher. Aborting"); wtls_pdu_destroy(clientHelloPDU); fatalAlert(event, handshake_failure); return; } /* Set the relevant values in the wtls_machine and PDU structure */ wtls_machine->bulk_cipher_algorithm = ciphersuite->bulk_cipher_algo; wtls_machine->mac_algorithm = ciphersuite->mac_algo; /* Generate a SEC_Create_Res event, and pass it back into the queue */ res = wap_event_create(SEC_Create_Res); res->u.SEC_Create_Res.addr_tuple = wap_addr_tuple_duplicate(event->u.T_Unitdata_Ind.addr_tuple); res->u.SEC_Create_Res.bulk_cipher_algo = ciphersuite->bulk_cipher_algo; res->u.SEC_Create_Res.mac_algo = ciphersuite->mac_algo; res->u.SEC_Create_Res.client_key_id = wtls_choose_clientkeyid (clientHelloPDU->u.handshake.client_hello->client_key_ids, &algo); if (!res->u.SEC_Create_Res.client_key_id) { error(0, "Couldn't agree on key exchange protocol. Aborting"); wtls_pdu_destroy(clientHelloPDU); wap_event_destroy(res); fatalAlert(event, unknown_key_id); return; } wtls_machine->key_algorithm = algo; /* Set the sequence number mode in both the machine and the outgoing packet */ res->u.SEC_Create_Res.snmode = wtls_choose_snmode(clientHelloPDU->u.handshake.client_hello-> snmode); wtls_machine->sequence_number_mode = res->u.SEC_Create_Res.snmode; /* Set the key refresh mode in both the machine and the outgoing packet */ res->u.SEC_Create_Res.krefresh = clientHelloPDU->u.handshake.client_hello->krefresh; wtls_machine->key_refresh = res->u.SEC_Create_Res.krefresh; /* Global refresh variable */ debug("wtls", 0, "clientHello ~> Accepted refresh = %d, refresh_rate = " "%d", wtls_machine->key_refresh, 1 << wtls_machine->key_refresh); /* Keep the data so we can send it back in EXCHANGE * temporary - needs to delete old one if exists ! * wtls_machine->handshake_data = octstr_create(""); */ if (wtls_machine->handshake_data) octstr_destroy(wtls_machine->handshake_data); wtls_machine->handshake_data = octstr_create(""); octstr_append(wtls_machine->handshake_data, tempPayload->data); debug("wtls", 0, "clientHello ~> Dispatching SEC_Create_Res event"); wtls_pdu_destroy(clientHelloPDU); wtls_dispatch_event(res); }
WAPEvent *unpack_wdp_datagram_real(WAPEvent *datagram) { WTP_PDU *pdu; WAPEvent *event; Octstr *data; gw_assert(datagram->type == T_DUnitdata_Ind); data = datagram->u.T_DUnitdata_Ind.user_data; if (truncated_datagram(datagram)) { warning(0, "WTP: got a truncated datagram, ignoring"); return NULL; } pdu = wtp_pdu_unpack(data); /* * Wtp_pdu_unpack returned NULL, we build a rcv error event. */ if (pdu == NULL) { error(0, "WTP: cannot unpack pdu, creating an error pdu"); event = pack_error(datagram); return event; } event = NULL; switch (pdu->type) { case Invoke: event = unpack_invoke(pdu, datagram->u.T_DUnitdata_Ind.addr_tuple); /* if an WTP initiator gets invoke, it would be an illegal pdu. */ if (!wtp_event_is_for_responder(event)){ debug("wap.wtp", 0, "WTP: Invoke when initiator. Message was"); wap_event_destroy(event); event = pack_error(datagram); } break; case Segmented_invoke: event = unpack_segmented_invoke(pdu, datagram->u.T_DUnitdata_Ind.addr_tuple); break; case Result: event = unpack_result(pdu, datagram->u.T_DUnitdata_Ind.addr_tuple); /* if an WTP responder gets result, it would be an illegal pdu. */ if (wtp_event_is_for_responder(event)){ debug("wap.wtp", 0, "WTP: Result when responder. Message was"); wap_event_destroy(event); event = pack_error(datagram); } break; case Ack: event = unpack_ack(pdu, datagram->u.T_DUnitdata_Ind.addr_tuple); break; case Negative_ack: event = unpack_negative_ack(pdu, datagram->u.T_DUnitdata_Ind.addr_tuple); break; case Abort: event = unpack_abort(pdu, datagram->u.T_DUnitdata_Ind.addr_tuple); break; default: event = pack_error(datagram); debug("wap.wtp", 0, "WTP: Unhandled PDU type. Message was"); wap_event_dump(datagram); return event; } wtp_pdu_destroy(pdu); wap_event_assert(event); return event; }
/* * Checks client push machines list for a specific machine. Creates it, if the * event is TR-Invoke.ind. * Client push machine is identified (when searching) by transcation identifi- * er. * Note that only WTP responder send its class 1 messages to client push state * machine. So, it is no need to specify WTP machine type. */ static WSPPushClientMachine *push_client_machine_find_or_create(WAPEvent *e) { WSPPushClientMachine *cpm; long transid; cpm = NULL; transid = -1; switch (e->type) { case TR_Invoke_Ind: transid = e->u.TR_Invoke_Ind.handle; break; case S_ConfirmedPush_Res: transid = e->u.S_ConfirmedPush_Res.client_push_id; break; case S_PushAbort_Req: transid = e->u.S_PushAbort_Req.push_id; break; case Abort_Event: break; case TR_Abort_Ind: transid = e->u.TR_Abort_Ind.handle; break; default: debug("wap.wsp", 0, "WSP PUSH: push_client_find_or_create: unhandled" " event"); wap_event_dump(e); wap_event_destroy(e); return NULL; } gw_assert(transid != -1); cpm = push_client_machine_find_using_transid(transid); if (cpm == NULL) { switch (e->type) { case TR_Invoke_Ind: cpm = push_client_machine_create(transid); break; case S_ConfirmedPush_Res: case S_PushAbort_Req: error(0, "WSP_PUSH_CLIENT: POT primitive to a nonexisting" " push client machine"); break; case Abort_Event: error(0, "WSP_PUSH_CLIENT: internal abort to a nonexisting" " push client machine"); break; case TR_Abort_Ind: error(0, "WSP_PUSH_CLIENT: WTP abort to a nonexisting push client" " machine"); break; default: error(0, "WSP_PUSH_CLIENT: Cannot handle event type %s", wap_event_name(e->type)); break; } } return cpm; }
WAPEvent *unpack_wdp_datagram_real(WAPEvent *datagram) { WTP_PDU *pdu; WAPEvent *event; Octstr *data; gw_assert(datagram->type == T_DUnitdata_Ind); data = datagram->u.T_DUnitdata_Ind.user_data; if (truncated_datagram(datagram)) { warning(0, "WTP: got a truncated datagram, ignoring"); return NULL; } pdu = wtp_pdu_unpack(data); /* * wtp_pdu_unpack returned NULL, we have send here a rcv error event, * but now we silently drop the packet. Because we can't figure out * in the pack_error() call if the TID value and hence the direction * inditation is really for initiator or responder. */ if (pdu == NULL) { error(0, "WTP: cannot unpack pdu, dropping packet."); return NULL; } event = NULL; switch (pdu->type) { case Invoke: event = unpack_invoke(pdu, datagram->u.T_DUnitdata_Ind.addr_tuple); /* if an WTP initiator gets invoke, it would be an illegal pdu. */ if (!wtp_event_is_for_responder(event)){ debug("wap.wtp", 0, "WTP: Invoke when initiator. Message was"); wap_event_destroy(event); event = pack_error(datagram); } break; case Segmented_invoke: event = unpack_segmented_invoke(pdu, datagram->u.T_DUnitdata_Ind.addr_tuple); break; case Result: event = unpack_result(pdu, datagram->u.T_DUnitdata_Ind.addr_tuple); /* if an WTP responder gets result, it would be an illegal pdu. */ if (wtp_event_is_for_responder(event)){ debug("wap.wtp", 0, "WTP: Result when responder. Message was"); wap_event_destroy(event); event = pack_error(datagram); } break; case Ack: event = unpack_ack(pdu, datagram->u.T_DUnitdata_Ind.addr_tuple); break; case Negative_ack: event = unpack_negative_ack(pdu, datagram->u.T_DUnitdata_Ind.addr_tuple); break; case Abort: event = unpack_abort(pdu, datagram->u.T_DUnitdata_Ind.addr_tuple); break; default: event = pack_error(datagram); debug("wap.wtp", 0, "WTP: Unhandled PDU type. Message was"); wap_event_dump(datagram); return event; } wtp_pdu_destroy(pdu); wap_event_assert(event); return event; }
int main(int argc, char **argv) { int opt, ret; Octstr *pap_doc, *log_file; WAPEvent *e; log_file = NULL; gwlib_init(); while ((opt = getopt(argc, argv, "h:v:l:")) != EOF) { switch (opt) { case 'h': help(); exit(1); break; case 'v': log_set_output_level(atoi(optarg)); break; case 'l': octstr_destroy(log_file); log_file = octstr_create(optarg); break; case '?': default: error(0, "Invalid option %c", opt); help(); panic(0, "Stopping"); break; } } if (optind >= argc) { error(0, "Missing arguments"); help(); panic(0, "Stopping"); } if (log_file != NULL) { log_open(octstr_get_cstr(log_file), GW_DEBUG, GW_NON_EXCL); octstr_destroy(log_file); } pap_doc = octstr_read_file(argv[optind]); if (pap_doc == NULL) panic(0, "Cannot read the pap document"); e = NULL; ret = pap_compile(pap_doc, &e); if (ret < 0) { debug("test.pap", 0, "Unable to compile the pap document, rc %d", ret); return 1; } debug("test.pap", 0, "Compiling successfull, wap event being:\n"); wap_event_dump(e); wap_event_destroy(e); octstr_destroy(pap_doc); gwlib_shutdown(); return 0; }
/* * Try log in defined number of times, when got response 401 and authentica- * tion info is in headers. */ static int receive_push_reply(HTTPCaller *caller) { void *id; long *trid; int http_status, tries; List *reply_headers; Octstr *final_url, *auth_url, *reply_body, *os, *push_content, *auth_reply_body; WAPEvent *e; List *retry_headers; http_status = HTTP_UNAUTHORIZED; tries = 0; id = http_receive_result(caller, &http_status, &final_url, &reply_headers, &reply_body); if (id == NULL || http_status == -1 || final_url == NULL) { error(0, "push failed, no reason found"); goto push_failed; } while (use_headers && http_status == HTTP_UNAUTHORIZED && tries < retries) { debug("test.ppg", 0, "try number %d", tries); debug("test.ppg", 0, "authentication failure, get a challenge"); http_destroy_headers(reply_headers); push_content = push_content_create(); retry_headers = push_headers_create(octstr_len(push_content)); http_add_basic_auth(retry_headers, username, password); trid = gw_malloc(sizeof(long)); *trid = tries; http_start_request(caller, HTTP_METHOD_POST, final_url, retry_headers, push_content, 0, trid, NULL); debug("test.ppg ", 0, "TEST_PPG: doing response to %s", octstr_get_cstr(final_url)); octstr_destroy(push_content); http_destroy_headers(retry_headers); trid = http_receive_result(caller, &http_status, &auth_url, &reply_headers, &auth_reply_body); if (trid == NULL || http_status == -1 || auth_url == NULL) { error(0, "unable to send authorisation, no reason found"); goto push_failed; } debug("test.ppg", 0, "TEST_PPG: send authentication to %s, retry %ld", octstr_get_cstr(auth_url), *(long *) trid); gw_free(trid); octstr_destroy(auth_reply_body); octstr_destroy(auth_url); ++tries; } if (http_status == HTTP_NOT_FOUND) { error(0, "push failed, service not found"); goto push_failed; } if (http_status == HTTP_FORBIDDEN) { error(0, "push failed, service forbidden"); goto push_failed; } if (http_status == HTTP_UNAUTHORIZED) { if (use_headers) error(0, "tried %ld times, stopping", retries); else error(0, "push failed, authorisation failure"); goto push_failed; } debug("test.ppg", 0, "TEST_PPG: push %ld done: reply from, %s", *(long *) id, octstr_get_cstr(final_url)); gw_free(id); octstr_destroy(final_url); if (verbose) debug("test.ppg", 0, "TEST_PPG: reply headers were"); while ((os = gwlist_extract_first(reply_headers)) != NULL) { if (verbose) octstr_dump(os, 0); octstr_destroy(os); } if (verbose) { debug("test.ppg", 0, "TEST_PPG: reply body was"); octstr_dump(reply_body, 0); } e = NULL; if (pap_compile(reply_body, &e) < 0) { warning(0, "TEST_PPG: receive_push_reply: cannot compile pap message"); goto parse_error; } switch (e->type) { case Push_Response: debug("test.ppg", 0, "TEST_PPG: and type push response"); break; case Bad_Message_Response: debug("test.ppg", 0, "TEST_PPG: and type bad message response"); break; default: warning(0, "TEST_PPG: unknown event received from %s", octstr_get_cstr(final_url)); break; } octstr_destroy(reply_body); wap_event_destroy(e); http_destroy_headers(reply_headers); return 0; push_failed: gw_free(id); octstr_destroy(final_url); octstr_destroy(reply_body); http_destroy_headers(reply_headers); return -1; parse_error: octstr_destroy(reply_body); http_destroy_headers(reply_headers); wap_event_destroy(e); return -1; }
void wap_event_destroy_item(void *event) { wap_event_destroy(event); }