Пример #1
0
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);
	}
}
Пример #2
0
/*
 * 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);
}
Пример #3
0
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);
}
Пример #4
0
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);
}
Пример #5
0
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 = &current_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);
}
Пример #6
0
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);
}
Пример #7
0
/*
 * 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;
   }
}
Пример #8
0
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);
}
Пример #9
0
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);
                }
}
Пример #10
0
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);
    }
}
Пример #11
0
/******************************************************************************
 *
 * 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;
}
Пример #12
0
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);
    }
}
Пример #13
0
/*
 * 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);      
}
Пример #14
0
/*
 * 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;
}
Пример #15
0
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);
}
Пример #16
0
/*
 * 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);

}
Пример #17
0
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);
}
Пример #18
0
Файл: wtp.c Проект: armic/erpts
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;
}
Пример #19
0
/*
 * 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;
}
Пример #20
0
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;
}
Пример #21
0
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;
}
Пример #22
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;
}
Пример #23
0
void wap_event_destroy_item(void *event) {
	wap_event_destroy(event);
}