static void make_confirmed_push_request(WAPEvent *e) { WAPEvent *wsp_event; List *push_headers; gw_assert(e->type == Po_ConfirmedPush_Req); push_headers = add_push_flag(e); wsp_event = wap_event_create(S_ConfirmedPush_Req); wsp_event->u.S_ConfirmedPush_Req.server_push_id = e->u.Po_ConfirmedPush_Req.server_push_id; wsp_event->u.S_ConfirmedPush_Req.push_headers = push_headers; if (e->u.Po_ConfirmedPush_Req.push_body != NULL) wsp_event->u.S_ConfirmedPush_Req.push_body = octstr_duplicate(e->u.Po_ConfirmedPush_Req.push_body); else wsp_event->u.S_ConfirmedPush_Req.push_body = NULL; wsp_event->u.S_ConfirmedPush_Req.session_id = e->u.Po_ConfirmedPush_Req.session_handle; debug("wap.push.ota", 0, "OTA: making confirmed push request to wsp"); dispatch_to_wsp(wsp_event); }
static WAPEvent *unpack_ack(WTP_PDU *pdu, WAPAddrTuple *addr_tuple) { WAPEvent *event; WTP_TPI *tpi; int i, num_tpis; event = wap_event_create(RcvAck); event->u.RcvAck.tid = pdu->u.Ack.tid; event->u.RcvAck.tid_ok = pdu->u.Ack.tidverify; event->u.RcvAck.rid = pdu->u.Ack.rid; event->u.RcvAck.addr_tuple = wap_addr_tuple_duplicate(addr_tuple); /* Set default to 0 because Ack on 1 piece message has no tpi */ event->u.RcvAck.psn = 0; num_tpis = gwlist_len(pdu->options); for (i = 0; i < num_tpis; i++) { tpi = gwlist_get(pdu->options, i); if (tpi->type == TPI_PSN) { event->u.RcvAck.psn = octstr_get_bits(tpi->data,0,8); break; } } return event; }
static void wtls_application(WAPEvent * event, WTLSMachine * wtls_machine) { int listLen, i = 0; WAPEvent *dgram; wtls_Payload *payLoad; /* Apply the negotiated decryption/decoding/MAC check to the received data */ /* Take the userdata and pass it on up to the WTP/WSP, depending on the destination port */ listLen = gwlist_len(event->u.T_Unitdata_Ind.pdu_list); for (; i < listLen; i++) { payLoad = gwlist_consume(event->u.T_Unitdata_Ind.pdu_list); dgram = wap_event_create(T_DUnitdata_Ind); dgram->u.T_DUnitdata_Ind.addr_tuple = wap_addr_tuple_create(event->u.T_Unitdata_Ind.addr_tuple-> remote->address, event->u.T_Unitdata_Ind.addr_tuple-> remote->port, event->u.T_Unitdata_Ind.addr_tuple-> local->address, event->u.T_Unitdata_Ind.addr_tuple-> local->port); dgram->u.T_DUnitdata_Ind.user_data = payLoad->data; wap_dispatch_datagram(dgram); payLoad->data = NULL; wtls_payload_destroy(payLoad); } }
/****************************************************************************** * * EXTERNAL FUNCTIONS: * */ WAPEvent *wtls_unpack_wdp_datagram(Msg * msg) { WAPEvent *unitdataIndEvent; List *wtlsPayloadList; /* Dump the Msg */ msg_dump(msg, 0); /* Then, stuff it into a T_Unitdata_Ind Event */ unitdataIndEvent = wap_event_create(T_Unitdata_Ind); info(0, "Event created"); /* Firstly, the address */ unitdataIndEvent->u.T_Unitdata_Ind.addr_tuple = wap_addr_tuple_create(msg->wdp_datagram.source_address, msg->wdp_datagram.source_port, msg->wdp_datagram.destination_address, msg->wdp_datagram.destination_port); info(0, "Set address and stuff"); /* Attempt to stuff this baby into a list-of-WTLS-PDUs */ wtlsPayloadList = wtls_unpack_payloadlist(msg->wdp_datagram.user_data); info(0, "Datagram unpacked!"); /* Then, the pdu material */ unitdataIndEvent->u.T_Unitdata_Ind.pdu_list = wtlsPayloadList; /* And return the event */ return unitdataIndEvent; }
/* * For debugging: create S-ConfirmedPush.res by ourselves. */ static WAPEvent *response_confirmedpush(WSPPushClientMachine *cpm) { WAPEvent *e; e = wap_event_create(S_ConfirmedPush_Res); e->u.S_ConfirmedPush_Res.client_push_id = cpm->client_push_id; return e; }
static WAPEvent *response_responder_invoke(WSPPushClientMachine *cpm) { WAPEvent *e; e = wap_event_create(TR_Invoke_Res); e->u.TR_Invoke_Res.handle = cpm->transaction_id; return e; }
static WAPEvent *indicate_pushabort(WSPPushClientMachine *cpm, long abort_reason) { WAPEvent *e; e = wap_event_create(S_PushAbort_Ind); e->u.S_PushAbort_Ind.push_id = cpm->client_push_id; e->u.S_PushAbort_Ind.reason = abort_reason; return e; }
static void fatalAlert(WAPEvent * event, int description) { WAPEvent *abort; abort = wap_event_create(SEC_Terminate_Req); abort->u.SEC_Terminate_Req.addr_tuple = wap_addr_tuple_duplicate (event->u.T_Unitdata_Ind.addr_tuple); abort->u.SEC_Terminate_Req.alert_level = fatal_alert; abort->u.SEC_Terminate_Req.alert_desc = description; wtls_dispatch_event(abort); }
static WAPEvent *make_abort(long reason, long handle) { WAPEvent *wtp_event; wtp_event = wap_event_create(TR_Abort_Req); wtp_event->u.TR_Abort_Req.abort_type = 0x01; wtp_event->u.TR_Abort_Req.abort_reason = reason; wtp_event->u.TR_Abort_Req.handle = handle; return wtp_event; }
static WAPEvent *unpack_abort(WTP_PDU *pdu, WAPAddrTuple *addr_tuple) { WAPEvent *event; event = wap_event_create(RcvAbort); event->u.RcvAbort.tid = pdu->u.Abort.tid; event->u.RcvAbort.abort_type = pdu->u.Abort.abort_type; event->u.RcvAbort.abort_reason = pdu->u.Abort.abort_reason; event->u.RcvAbort.addr_tuple = wap_addr_tuple_duplicate(addr_tuple); return event; }
/* * Creates TR-Invoke.cnf event */ static WAPEvent *create_tr_invoke_cnf(WTPInitMachine *init_machine) { WAPEvent *event; gw_assert(init_machine != NULL); event = wap_event_create(TR_Invoke_Cnf); event->u.TR_Invoke_Cnf.handle = init_machine->mid; event->u.TR_Invoke_Cnf.addr_tuple = wap_addr_tuple_duplicate(init_machine->addr_tuple); return event; }
static WAPEvent *send_abort_to_responder(WSPPushClientMachine *cpm, long reason) { WAPEvent *e; e = wap_event_create(TR_Abort_Req); e->u.TR_Abort_Req.abort_type = USER; e->u.TR_Abort_Req.abort_reason = reason; e->u.TR_Abort_Req.handle = cpm->client_push_id; return e; }
static void make_unit_push_request(WAPEvent *e) { WAPEvent *wsp_event; List *push_headers; Octstr *smsc_id; Octstr *dlr_url; Octstr *smsbox_id; Octstr *push_body; Octstr *service_name; gw_assert(e->type == Po_Unit_Push_Req); gw_assert(e->u.Po_Unit_Push_Req.addr_tuple); gw_assert(e->u.Po_Unit_Push_Req.service_name); smsc_id = octstr_duplicate(e->u.Po_Unit_Push_Req.smsc_id); dlr_url = octstr_duplicate(e->u.Po_Unit_Push_Req.dlr_url); smsbox_id = octstr_duplicate(e->u.Po_Unit_Push_Req.smsbox_id); push_body = octstr_duplicate(e->u.Po_Unit_Push_Req.push_body); service_name = octstr_duplicate(e->u.Po_Unit_Push_Req.service_name); push_headers = add_push_flag(e); wsp_event = wap_event_create(S_Unit_Push_Req); wsp_event->u.S_Unit_Push_Req.addr_tuple = wap_addr_tuple_duplicate(e->u.Po_Unit_Push_Req.addr_tuple); wsp_event->u.S_Unit_Push_Req.push_id = e->u.Po_Unit_Push_Req.push_id; wsp_event->u.S_Unit_Push_Req.push_headers = push_headers; wsp_event->u.S_Unit_Push_Req.address_type = e->u.Po_Unit_Push_Req.address_type; if (smsc_id != NULL) wsp_event->u.S_Unit_Push_Req.smsc_id = smsc_id; else wsp_event->u.S_Unit_Push_Req.smsc_id = NULL; if (dlr_url != NULL) wsp_event->u.S_Unit_Push_Req.dlr_url = dlr_url; else wsp_event->u.S_Unit_Push_Req.dlr_url = NULL; wsp_event->u.S_Unit_Push_Req.dlr_mask = e->u.Po_Unit_Push_Req.dlr_mask; if (smsbox_id != NULL) wsp_event->u.S_Unit_Push_Req.smsbox_id = smsbox_id; else wsp_event->u.S_Unit_Push_Req.smsbox_id = NULL; wsp_event->u.S_Unit_Push_Req.service_name = service_name; if (push_body != NULL) wsp_event->u.S_Unit_Push_Req.push_body = push_body; else wsp_event->u.S_Unit_Push_Req.push_body = NULL; dispatch_to_wsp_unit(wsp_event); debug("wap.push.ota", 0, "OTA: made connectionless session service" " request"); }
static WAPEvent *unpack_negative_ack(WTP_PDU *pdu, WAPAddrTuple *addr_tuple) { WAPEvent *event; event = wap_event_create(RcvNegativeAck); event->u.RcvNegativeAck.tid = pdu->u.Negative_ack.tid; event->u.RcvNegativeAck.rid = pdu->u.Negative_ack.rid; event->u.RcvNegativeAck.nmissing = pdu->u.Negative_ack.nmissing; event->u.RcvNegativeAck.missing = octstr_duplicate(pdu->u.Negative_ack.missing); event->u.RcvNegativeAck.addr_tuple = wap_addr_tuple_duplicate(addr_tuple); return event; }
/* * Start retry interval timer (strictly speaking, timer iniatilised with retry * interval). Multiply timer value with init_timer_freq. */ static void start_initiator_timer_R(WTPInitMachine *machine) { WAPEvent *timer_event; int seconds; timer_event = wap_event_create(TimerTO_R); timer_event->u.TimerTO_R.handle = machine->mid; if (machine->u_ack) seconds = S_R_WITH_USER_ACK * init_timer_freq; else seconds = S_R_WITHOUT_USER_ACK * init_timer_freq; gwtimer_start(machine->timer, seconds, timer_event); }
static WAPEvent *pack_error(WAPEvent *datagram) { WAPEvent *event; gw_assert(datagram->type == T_DUnitdata_Ind); event = wap_event_create(RcvErrorPDU); event->u.RcvErrorPDU.tid = deduce_tid(datagram->u.T_DUnitdata_Ind.user_data); event->u.RcvErrorPDU.addr_tuple = wap_addr_tuple_duplicate(datagram->u.T_DUnitdata_Ind.addr_tuple); return event; }
static WAPEvent *indicate_confirmedpush(WSPPushClientMachine *cpm, Octstr *push_body) { WAPEvent *e; e = wap_event_create(S_ConfirmedPush_Ind); e->u.S_ConfirmedPush_Ind.client_push_id = cpm->client_push_id; e->u.S_ConfirmedPush_Ind.push_headers = http_header_duplicate(cpm->push_headers); e->u.S_ConfirmedPush_Ind.push_body = octstr_duplicate(push_body); return e; }
/* * Creates TR-Abort.ind event from an initiator state machine. In addtion, set * the ir_flag on. */ static WAPEvent *create_tr_abort_ind(WTPInitMachine *sm, long abort_reason) { WAPEvent *event; event = wap_event_create(TR_Abort_Ind); event->u.TR_Abort_Ind.abort_code = abort_reason; event->u.TR_Abort_Ind.addr_tuple = wap_addr_tuple_duplicate(sm->addr_tuple); event->u.TR_Abort_Ind.handle = sm->mid; event->u.TR_Abort_Ind.ir_flag = INITIATOR_INDICATION; return event; }
static WAPEvent *unpack_result(WTP_PDU *pdu, WAPAddrTuple *addr_tuple) { WAPEvent *event; event = wap_event_create(RcvResult); event->u.RcvResult.user_data = octstr_duplicate(pdu->u.Result.user_data); event->u.RcvResult.tid = pdu->u.Result.tid; event->u.RcvResult.rid = pdu->u.Result.rid; event->u.RcvResult.gtr = pdu->u.Result.gtr; event->u.RcvResult.ttr = pdu->u.Result.ttr; event->u.RcvResult.addr_tuple = wap_addr_tuple_duplicate(addr_tuple); return event; }
static void make_session_request(WAPEvent *e) { WAPEvent *wsp_event; List *appid_headers, *push_headers; gw_assert(e->type == Pom_SessionRequest_Req); push_headers = e->u.Pom_SessionRequest_Req.push_headers; check_session_request_headers(push_headers); wsp_event = wap_event_create(S_Unit_Push_Req); wsp_event->u.S_Unit_Push_Req.address_type = e->u.Pom_SessionRequest_Req.address_type; if (e->u.Pom_SessionRequest_Req.smsc_id != NULL) wsp_event->u.S_Unit_Push_Req.smsc_id = octstr_duplicate(e->u.Pom_SessionRequest_Req.smsc_id); else wsp_event->u.S_Unit_Push_Req.smsc_id = NULL; if (e->u.Pom_SessionRequest_Req.dlr_url != NULL) wsp_event->u.S_Unit_Push_Req.dlr_url = octstr_duplicate(e->u.Pom_SessionRequest_Req.dlr_url); else wsp_event->u.S_Unit_Push_Req.dlr_url = NULL; wsp_event->u.S_Unit_Push_Req.dlr_mask = e->u.Pom_SessionRequest_Req.dlr_mask; if (e->u.Pom_SessionRequest_Req.smsbox_id != NULL) wsp_event->u.S_Unit_Push_Req.smsbox_id = octstr_duplicate(e->u.Pom_SessionRequest_Req.smsbox_id); else wsp_event->u.S_Unit_Push_Req.smsbox_id = NULL; wsp_event->u.S_Unit_Push_Req.service_name = octstr_duplicate(e->u.Pom_SessionRequest_Req.service_name); wsp_event->u.S_Unit_Push_Req.push_id = e->u.Pom_SessionRequest_Req.push_id; wsp_event->u.S_Unit_Push_Req.addr_tuple = wap_addr_tuple_duplicate(e->u.Pom_SessionRequest_Req.addr_tuple); wsp_event->u.S_Unit_Push_Req.push_headers = http_header_duplicate(push_headers); appid_headers = http_header_find_all(push_headers, "X-WAP-Application-Id"); wsp_event->u.S_Unit_Push_Req.push_body = pack_sia(appid_headers); debug("wap.push.ota", 0, "OTA: making a connectionless session request for" " creating a session"); dispatch_to_wsp_unit(wsp_event); }
static void abort_push(WAPEvent *e) { WAPEvent *wsp_event; long reason; reason = e->u.Po_PushAbort_Req.reason; gw_assert(e->type == Po_PushAbort_Req); reason_assert(reason); wsp_event = wap_event_create(S_PushAbort_Req); wsp_event->u.S_PushAbort_Req.push_id = e->u.Po_PushAbort_Req.push_id; wsp_event->u.S_PushAbort_Req.reason = reason; wsp_event->u.S_PushAbort_Req.session_handle = e->u.Po_PushAbort_Req.session_id; dispatch_to_wsp(wsp_event); }
static WAPEvent *unpack_segmented_invoke(WTP_PDU *pdu, WAPAddrTuple *addr_tuple) { WAPEvent *event; event = wap_event_create(RcvSegInvoke); event->u.RcvSegInvoke.user_data = octstr_duplicate(pdu->u.Segmented_invoke.user_data); event->u.RcvSegInvoke.tid = pdu->u.Segmented_invoke.tid; event->u.RcvSegInvoke.rid = pdu->u.Segmented_invoke.rid; event->u.RcvSegInvoke.no_cache_supported = 0; event->u.RcvSegInvoke.gtr = pdu->u.Segmented_invoke.gtr; event->u.RcvSegInvoke.ttr = pdu->u.Segmented_invoke.ttr; event->u.RcvSegInvoke.psn = pdu->u.Segmented_invoke.psn; event->u.RcvSegInvoke.addr_tuple = wap_addr_tuple_duplicate(addr_tuple); return event; }
static void make_push_request(WAPEvent *e) { WAPEvent *wsp_event; List *push_headers; gw_assert(e->type == Po_Push_Req); push_headers = add_push_flag(e); wsp_event = wap_event_create(S_Push_Req); wsp_event->u.S_Push_Req.push_headers = push_headers; if (e->u.Po_Push_Req.push_body != NULL) wsp_event->u.S_Push_Req.push_body = octstr_duplicate(e->u.Po_Push_Req.push_body); else wsp_event->u.S_Push_Req.push_body = NULL; wsp_event->u.S_Push_Req.session_id = e->u.Po_Push_Req.session_handle; dispatch_to_wsp(wsp_event); }
static void disconnect_other_sessions(WSPMachine *sm) { List *old_sessions; WAPEvent *disconnect; WSPMachine *sm2; long i; old_sessions = gwlist_search_all(session_machines, sm, same_client); if (old_sessions == NULL) return; for (i = 0; i < gwlist_len(old_sessions); i++) { sm2 = gwlist_get(old_sessions, i); if (sm2 != sm) { disconnect = wap_event_create(Disconnect_Event); handle_session_event(sm2, disconnect, NULL); } } gwlist_destroy(old_sessions, NULL); }
static WAPEvent *unpack_invoke(WTP_PDU *pdu, WAPAddrTuple *addr_tuple) { WAPEvent *event; event = wap_event_create(RcvInvoke); event->u.RcvInvoke.user_data = octstr_duplicate(pdu->u.Invoke.user_data); event->u.RcvInvoke.tcl = pdu->u.Invoke.class; event->u.RcvInvoke.tid = pdu->u.Invoke.tid; event->u.RcvInvoke.tid_new = pdu->u.Invoke.tidnew; event->u.RcvInvoke.rid = pdu->u.Invoke.rid; event->u.RcvInvoke.up_flag = pdu->u.Invoke.uack; event->u.RcvInvoke.no_cache_supported = 0; event->u.RcvInvoke.version = pdu->u.Invoke.version; event->u.RcvInvoke.gtr = pdu->u.Invoke.gtr; event->u.RcvInvoke.ttr = pdu->u.Invoke.ttr; event->u.RcvInvoke.addr_tuple = wap_addr_tuple_duplicate(addr_tuple); return event; }
static WAPEvent *wdp_msg2event(Msg *msg) { WAPEvent *dgram = NULL; gw_assert(msg_type(msg) == wdp_datagram); if (msg->wdp_datagram.destination_port == server_port || msg->wdp_datagram.source_port == server_port || msg->wdp_datagram.destination_port == CONNECTION_ORIENTED_PORT || msg->wdp_datagram.source_port == CONNECTION_ORIENTED_PORT) { dgram = wap_event_create(T_DUnitdata_Ind); dgram->u.T_DUnitdata_Ind.addr_tuple = wap_addr_tuple_create( msg->wdp_datagram.source_address, msg->wdp_datagram.source_port, msg->wdp_datagram.destination_address, msg->wdp_datagram.destination_port); dgram->u.T_DUnitdata_Ind.user_data = octstr_duplicate(msg->wdp_datagram.user_data); } return dgram; }
{ WAPEvent *wtp_event; wtp_event = make_abort(reason, handle); dispatch_to_wtp_init(wtp_event); } /* * The server sends invoke (to be exact, makes TR-Invoke.req) only when it is * pushing. (Only the client disconnects sessions.) */ static void send_invoke(WSPMachine *m, WSP_PDU *pdu, WAPEvent *e, long class) { WAPEvent *wtp_event; wtp_event = wap_event_create(TR_Invoke_Req); wtp_event->u.TR_Invoke_Req.addr_tuple = wap_addr_tuple_duplicate(m->addr_tuple); /* * There is no mention of acknowledgement type in the specs.�But because * confirmed push is confirmed after response from OTA, provider acknowledge- * ments seem redundant. */ wtp_event->u.TR_Invoke_Req.up_flag = USER_ACKNOWLEDGEMENT; wtp_event->u.TR_Invoke_Req.tcl = class; if (e->type == S_ConfirmedPush_Req) wtp_event->u.TR_Invoke_Req.handle = e->u.S_ConfirmedPush_Req.server_push_id; wtp_event->u.TR_Invoke_Req.user_data = wsp_pdu_pack(pdu); wsp_pdu_destroy(pdu);
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); }
static void serverHello(WAPEvent * event, WTLSMachine * wtls_machine) { WAPEvent *req; wtls_PDU *serverHelloPDU; // wtls_PDU* certificatePDU; Random *tempRandom; /* List *certList; Certificate *cert; */ int randomCounter = 0; /* Our serverHello */ serverHelloPDU = wtls_pdu_create(Handshake_PDU); serverHelloPDU->rlen = 1; serverHelloPDU->snMode = wtls_machine->sequence_number_mode ? 1 : 0; serverHelloPDU->u.handshake.msg_type = server_hello; serverHelloPDU->u.handshake.server_hello = (ServerHello *) gw_malloc(sizeof(ServerHello)); /* Set our server version */ serverHelloPDU->u.handshake.server_hello->serverversion = 1; /* Get a suitably random number - store it in both the machine structure and outgoing PDU */ tempRandom = wtls_get_random(); wtls_machine->server_random = octstr_create(""); randomCounter = pack_int32(wtls_machine->server_random, 0, tempRandom->gmt_unix_time); octstr_insert(wtls_machine->server_random, tempRandom->random_bytes, octstr_len(wtls_machine->server_random)); serverHelloPDU->u.handshake.server_hello->random = tempRandom; /* At the moment, we don't support session caching, so tell them to forget about caching us */ serverHelloPDU->u.handshake.server_hello->session_id = octstr_format("%llu", wtls_machine->mid); /* We need to select an appropriate mechanism here from the ones listed */ serverHelloPDU->u.handshake.server_hello->client_key_id = event->u.SEC_Create_Res.client_key_id; /* Get our ciphersuite details */ serverHelloPDU->u.handshake.server_hello->ciphersuite = (CipherSuite *) gw_malloc(sizeof(CipherSuite)); serverHelloPDU->u.handshake.server_hello->ciphersuite->bulk_cipher_algo = event->u.SEC_Create_Res.bulk_cipher_algo; serverHelloPDU->u.handshake.server_hello->ciphersuite->mac_algo = event->u.SEC_Create_Res.mac_algo; serverHelloPDU->u.handshake.server_hello->comp_method = null_comp; /* We need to confirm the client's choice, or if they haven't * specified one, select one ourselves */ serverHelloPDU->u.handshake.server_hello->snmode = event->u.SEC_Create_Res.snmode; /* We need to either confirm the client's choice of key refresh rate, or choose a lower rate */ serverHelloPDU->u.handshake.server_hello->krefresh = event->u.SEC_Create_Res.krefresh; /* Add the PDUsto the server's outgoing list */ add_pdu(wtls_machine, serverHelloPDU); wtls_pdu_destroy(serverHelloPDU); /* Generate and dispatch a SEC_Exchange_Req or maybe a SEC_Commit_Req */ req = wap_event_create(SEC_Exchange_Req); req->u.SEC_Exchange_Req.addr_tuple = wap_addr_tuple_duplicate(event->u.T_Unitdata_Ind.addr_tuple); wtls_dispatch_event(req); debug("wtls", 0, "serverHello ~> Dispatching SEC_Exchange_Req event"); }
int main(int argc, char **argv) { int cf_index; int restart = 0; Msg *msg; Cfg *cfg; double heartbeat_freq = DEFAULT_HEARTBEAT; gwlib_init(); cf_index = get_and_set_debugs(argc, argv, NULL); setup_signal_handlers(); if (argv[cf_index] == NULL) config_filename = octstr_create("kannel.conf"); else config_filename = octstr_create(argv[cf_index]); cfg = cfg_create(config_filename); if (cfg_read(cfg) == -1) panic(0, "Couldn't read configuration from `%s'.", octstr_get_cstr(config_filename)); report_versions("wapbox"); cfg = init_wapbox(cfg); info(0, "------------------------------------------------------------"); info(0, GW_NAME " wapbox version %s starting up.", GW_VERSION); sequence_counter = counter_create(); wsp_session_init(&wtp_resp_dispatch_event, &wtp_initiator_dispatch_event, &wap_appl_dispatch, &wap_push_ppg_dispatch_event); wsp_unit_init(&dispatch_datagram, &wap_appl_dispatch); wsp_push_client_init(&wsp_push_client_dispatch_event, &wtp_resp_dispatch_event); if (cfg) wtp_initiator_init(&dispatch_datagram, &wsp_session_dispatch_event, timer_freq); wtp_resp_init(&dispatch_datagram, &wsp_session_dispatch_event, &wsp_push_client_dispatch_event, timer_freq); wap_appl_init(cfg); #if (HAVE_WTLS_OPENSSL) wtls_secmgr_init(); wtls_init(&write_to_bearerbox); #endif if (cfg) { wap_push_ota_init(&wsp_session_dispatch_event, &wsp_unit_dispatch_event); wap_push_ppg_init(&wap_push_ota_dispatch_event, &wap_appl_dispatch, cfg); } wml_init(wml_xml_strict); if (bearerbox_host == NULL) bearerbox_host = octstr_create(BB_DEFAULT_HOST); connect_to_bearerbox(bearerbox_host, bearerbox_port, bearerbox_ssl, NULL /* bearerbox_our_port */); if (cfg) wap_push_ota_bb_address_set(bearerbox_host); program_status = running; if (0 > heartbeat_start(write_to_bearerbox, heartbeat_freq, wap_appl_get_load)) { info(0, GW_NAME "Could not start heartbeat."); } while (program_status != shutting_down) { WAPEvent *dgram; int ret; /* block infinite for reading messages */ ret = read_from_bearerbox(&msg, INFINITE_TIME); if (ret == -1) { error(0, "Bearerbox is gone, restarting"); program_status = shutting_down; restart = 1; break; } else if (ret == 1) /* timeout */ continue; else if (msg == NULL) /* just to be sure, may not happens */ break; if (msg_type(msg) == admin) { if (msg->admin.command == cmd_shutdown) { info(0, "Bearerbox told us to die"); program_status = shutting_down; } else if (msg->admin.command == cmd_restart) { info(0, "Bearerbox told us to restart"); restart = 1; program_status = shutting_down; } /* * XXXX here should be suspend/resume, add RSN */ } else if (msg_type(msg) == wdp_datagram) { switch (msg->wdp_datagram.destination_port) { case CONNECTIONLESS_PORT: case CONNECTION_ORIENTED_PORT: dgram = wap_event_create(T_DUnitdata_Ind); dgram->u.T_DUnitdata_Ind.addr_tuple = wap_addr_tuple_create( msg->wdp_datagram.source_address, msg->wdp_datagram.source_port, msg->wdp_datagram.destination_address, msg->wdp_datagram.destination_port); dgram->u.T_DUnitdata_Ind.user_data = msg->wdp_datagram.user_data; msg->wdp_datagram.user_data = NULL; wap_dispatch_datagram(dgram); break; case WTLS_CONNECTIONLESS_PORT: case WTLS_CONNECTION_ORIENTED_PORT: #if (HAVE_WTLS_OPENSSL) dgram = wtls_unpack_wdp_datagram(msg); if (dgram != NULL) wtls_dispatch_event(dgram); #endif break; default: panic(0,"Bad packet received! This shouldn't happen!"); break; } } else { warning(0, "Received other message than wdp/admin, ignoring!"); } msg_destroy(msg); } info(0, GW_NAME " wapbox terminating."); program_status = shutting_down; heartbeat_stop(ALL_HEARTBEATS); counter_destroy(sequence_counter); if (cfg) wtp_initiator_shutdown(); wtp_resp_shutdown(); wsp_push_client_shutdown(); wsp_unit_shutdown(); wsp_session_shutdown(); wap_appl_shutdown(); radius_acct_shutdown(); if (cfg) { wap_push_ota_shutdown(); wap_push_ppg_shutdown(); } wml_shutdown(); close_connection_to_bearerbox(); alog_close(); wap_map_destroy(); wap_map_user_destroy(); octstr_destroy(device_home); octstr_destroy(bearerbox_host); octstr_destroy(config_filename); /* * Just sleep for a while to get bearerbox chance to restart. * Otherwise we will fail while trying to connect to bearerbox! */ if (restart) { gwthread_sleep(10.0); /* now really restart */ restart_box(argv); } log_close_all(); gwlib_shutdown(); return 0; }