Example #1
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);
}
Example #2
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);
}
Example #3
0
/*
 * Responder set the first bit of the tid field. If we get a packet from the 
 * responder, we are the initiator and vice versa.
 *
 * Return 1, when the event is for responder, 0 when it is for initiator and 
 * -1 when error.
 */
int wtp_event_is_for_responder(WAPEvent *event)
{

     switch(event->type){
          
     case RcvInvoke:
         return event->u.RcvInvoke.tid < INITIATOR_TID_LIMIT;

     case RcvSegInvoke:
        return event->u.RcvSegInvoke.tid < INITIATOR_TID_LIMIT;

     case RcvResult:
         return event->u.RcvResult.tid < INITIATOR_TID_LIMIT;

     case RcvAck:
        return event->u.RcvAck.tid < INITIATOR_TID_LIMIT;

     case RcvNegativeAck:
        return event->u.RcvNegativeAck.tid < INITIATOR_TID_LIMIT;

     case RcvAbort:
        return event->u.RcvAbort.tid < INITIATOR_TID_LIMIT;

     case RcvErrorPDU:
        return event->u.RcvErrorPDU.tid < INITIATOR_TID_LIMIT;

     default:
        error(1, "Received an erroneous PDU corresponding an event");
        wap_event_dump(event);
        return -1;
     }
}
Example #4
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);
}
Example #5
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);
}
Example #6
0
/*****************************************************************************
 *
 * INTERNAL FUNCTIONS:
 *
 * If pdu was truncated, tid cannot be trusted. We ignore this message.
 */
static int truncated_datagram(WAPEvent *dgram)
{
    gw_assert(dgram->type == T_DUnitdata_Ind);

    if (octstr_len(dgram->u.T_DUnitdata_Ind.user_data) < 3) {
        debug("wap.wtp", 0, "A too short PDU received");
        wap_event_dump(dgram);
        return 1;
    } else
        return 0;
}
Example #7
0
static void cant_handle_event(WSPMachine *sm, WAPEvent *event) {
	/* We do the rest of the pre-state-machine tests here.  The first
	 * four were done in find_session_machine().  The fifth is a
	 * class 1 or 2 TR-Invoke.ind not handled by the state tables. */
	if (event->type == TR_Invoke_Ind &&
	    (event->u.TR_Invoke_Ind.tcl == 1 ||
	     event->u.TR_Invoke_Ind.tcl == 2)) {
		warning(0, "WSP: Can't handle TR-Invoke.ind, aborting transaction.");
		debug("wap.wsp", 0, "WSP: The unhandled event:");
		wap_event_dump(event);
		send_abort(WSP_ABORT_PROTOERR,
			event->u.TR_Invoke_Ind.handle);
	/* The sixth is a class 0 TR-Invoke.ind not handled by state tables. */
	} else if (event->type == TR_Invoke_Ind) {
		warning(0, "WSP: Can't handle TR-Invoke.ind, ignoring.");
		debug("wap.wsp", 0, "WSP: The ignored event:");
		wap_event_dump(event);
	/* The seventh is any other event not handled by state tables. */
	} else {
		error(0, "WSP: Can't handle event. Aborting session.");
		debug("wap.wsp", 0, "WSP: The unhandled event:");
		wap_event_dump(event);
		/* TR-Abort.req(PROTOERR) if it is some other transaction
		 * event than abort. */
		/* Currently that means TR-Result.cnf, because we already
		 * tested for Invoke. */
		/* FIXME We need a better way to get at event values than
		 * by hardcoding the types. */
		if (event->type == TR_Result_Cnf) {
			send_abort(WSP_ABORT_PROTOERR,
				event->u.TR_Result_Cnf.handle);
		}
		/* Abort(PROTOERR) all method and push transactions */
		abort_methods(sm, WSP_ABORT_PROTOERR);
                abort_pushes(sm, WSP_ABORT_PROTOERR);
		/* S-Disconnect.ind(PROTOERR) */
		indicate_disconnect(sm, WSP_ABORT_PROTOERR);
	}
}
Example #8
0
/*
 * Add push flag into push headers. Push flag is defined in ota, p. 17-18.
 * If there is no flags set, no Push-Flag header is added.
 */
static List *add_push_flag(WAPEvent *e)
{
    int push_flag,
        trusted,
        authenticated,
        last;

    Octstr *buf;
    List *headers;

    flags_assert(e);

    if (e->type == Po_Unit_Push_Req) {
        trusted = e->u.Po_Unit_Push_Req.trusted << 1;
        authenticated = e->u.Po_Unit_Push_Req.authenticated;
        last = e->u.Po_Unit_Push_Req.last << 2;

        headers = http_header_duplicate(e->u.Po_Unit_Push_Req.push_headers);

    } else if (e->type == Po_Push_Req) {
        trusted = e->u.Po_Push_Req.trusted << 1;
        authenticated = e->u.Po_Push_Req.authenticated;
        last = e->u.Po_Push_Req.last << 2;

        headers = http_header_duplicate(e->u.Po_Push_Req.push_headers);

    } else if (e->type == Po_ConfirmedPush_Req) {
        trusted = e->u.Po_ConfirmedPush_Req.trusted << 1;
        authenticated = e->u.Po_ConfirmedPush_Req.authenticated;
        last = e->u.Po_ConfirmedPush_Req.last << 2;

        headers = http_header_duplicate(
            e->u.Po_ConfirmedPush_Req.push_headers);

    } else {
        debug("wap.ota", 0, "OTA: no push flag when the event is: \n");
        wap_event_dump(e);
        return NULL;
    }

    push_flag = 0;
    push_flag = push_flag | authenticated | trusted | last;
    
    if (push_flag) {
    buf = octstr_format("%d", push_flag);
    http_header_add(headers, "Push-Flag", octstr_get_cstr(buf)); 
    octstr_destroy(buf);
    }

    return headers;
}
Example #9
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);

}
Example #10
0
/* This function does NOT consume its event; it leaves that task up
 * to the parent session */
static void handle_method_event(WSPMachine *sm, WSPMethodMachine *msm, 
WAPEvent *current_event, WSP_PDU *pdu) {

	if (msm == NULL) {
		warning(0, "No method machine for event.");
		wap_event_dump(current_event);
		return;
	}
		
	debug("wap.wsp", 0, "WSP: method %ld, state %s, event %s",
		msm->transaction_id, state_name(msm->state), 
		wap_event_name(current_event->type));

	gw_assert(sm->session_id == msm->session_id);

	#define STATE_NAME(name)
	#define ROW(state_name, event, condition, action, next_state) \
		{ \
			struct event *e; \
			e = &current_event->u.event; \
			if (msm->state == state_name && \
			   current_event->type == event && \
			   (condition)) { \
				action \
				msm->state = next_state; \
				debug("wap.wsp", 0, "WSP %ld/%ld: New method state %s", \
					msm->session_id, msm->transaction_id, #next_state); \
				goto end; \
			} \
		}
	#include "wsp_server_method_states.def"
	
	cant_handle_event(sm, current_event);

end:
	if (msm->state == NULL_METHOD) {
		method_machine_destroy(msm);
		gwlist_delete_equal(sm->methodmachines, msm);
	}
}
Example #11
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);      
}
Example #12
0
static void handle_push_event(WSPMachine *sm, WSPPushMachine *pm, 
                              WAPEvent *current_event)
{
        if (pm == NULL) {
		warning(0, "No push machine for event.");
		wap_event_dump(current_event);
		return;
	}

        debug("wap.wsp", 0, "WSP(tid/pid): push %ld/%ld, state %s, event %s",
		pm->transaction_id, pm->server_push_id, state_name(pm->state), 
		wap_event_name(current_event->type));
	gw_assert(sm->session_id == pm->session_id);

        #define STATE_NAME(name)
	#define ROW(state_name, event, condition, action, next_state) \
		{ \
		    if (pm->state == state_name && \
			current_event->type == event && \
			(condition)) { \
			     action \
			     pm->state = next_state; \
			     debug("wap.wsp", 0, "WSP %ld/%ld: New push state %s", \
			           pm->session_id, pm->transaction_id, #next_state); \
				goto end; \
			} \
		}
	#include "wsp_server_push_states.def"

        cant_handle_event(sm, current_event);
end:
        if (pm->state == SERVER_PUSH_NULL_STATE) {
		push_machine_destroy(pm);
		gwlist_delete_equal(sm->pushmachines, pm);
	}
}
Example #13
0
static WSPMachine *find_session_machine(WAPEvent *event, WSP_PDU *pdu) {
	WSPMachine *sm;
	long session_id;
	WAPAddrTuple *tuple;
	
	tuple = NULL;
	session_id = -1;
	
	switch (event->type) {
	case TR_Invoke_Ind:
		tuple = wap_addr_tuple_duplicate(
				event->u.TR_Invoke_Ind.addr_tuple);
		break;

        case TR_Invoke_Cnf:
                tuple = wap_addr_tuple_duplicate(
				event->u.TR_Invoke_Cnf.addr_tuple);
	        break;

	case TR_Result_Cnf:
		tuple = wap_addr_tuple_duplicate(
				event->u.TR_Result_Cnf.addr_tuple);
		break;

	case TR_Abort_Ind:
		tuple = wap_addr_tuple_duplicate(
				event->u.TR_Abort_Ind.addr_tuple);
		break;

	case S_Connect_Res:
		session_id = event->u.S_Connect_Res.session_id;
		break;

	case S_Resume_Res:
		session_id = event->u.S_Resume_Res.session_id;
		break;

	case Disconnect_Event:
		session_id = event->u.Disconnect_Event.session_handle;
		break;

	case Suspend_Event:
		session_id = event->u.Suspend_Event.session_handle;
		break;

	case S_MethodInvoke_Res:
		session_id = event->u.S_MethodInvoke_Res.session_id;
		break;

	case S_MethodResult_Req:
		session_id = event->u.S_MethodResult_Req.session_id;
		break;

	case S_ConfirmedPush_Req:
                session_id = event->u.S_ConfirmedPush_Req.session_id;
	        break;

        case S_Push_Req:
                session_id = event->u.S_Push_Req.session_id;
	        break;

	default:
		error(0, "WSP: Cannot find machine for %s event",
			wap_event_name(event->type));
	}
	
	gw_assert(tuple != NULL || session_id != -1);

	/* Pre-state-machine tests, according to 7.1.5.  After the tests,
	 * caller will pass the event to sm if sm is not NULL. */
	sm = NULL;
	/* First test is for MRUEXCEEDED, and we don't have a MRU */

	/* Second test is for class 2 TR-Invoke.ind with Connect PDU */
	if (event->type == TR_Invoke_Ind &&
	    event->u.TR_Invoke_Ind.tcl == 2 &&
	    pdu->type == Connect) {
			/* Create a new session, even if there is already
			 * a session open for this address.  The new session
			 * will take care of killing the old ones. */
			sm = machine_create();
			gw_assert(tuple != NULL);
			sm->addr_tuple = wap_addr_tuple_duplicate(tuple);
			sm->connect_handle = event->u.TR_Invoke_Ind.handle;
	/* Third test is for class 2 TR-Invoke.ind with Resume PDU */
	} else if (event->type == TR_Invoke_Ind &&
		   event->u.TR_Invoke_Ind.tcl == 2 &&
	  	   pdu->type == Resume) {
		/* Pass to session identified by session id, not
		 * the address tuple. */
		session_id = pdu->u.Resume.sessionid;
		sm = gwlist_search(session_machines, &session_id,
				find_by_session_id);
		if (sm == NULL) {
			/* No session; TR-Abort.req(DISCONNECT) */
			send_abort(WSP_ABORT_DISCONNECT,
				event->u.TR_Invoke_Ind.handle);
		}
	/* Fourth test is for a class 1 or 2 TR-Invoke.Ind with no
	 * session for that address tuple.  We also handle class 0
	 * TR-Invoke.ind here by ignoring them; this seems to be
	 * an omission in the spec table. */
	} else if (event->type == TR_Invoke_Ind) {
		sm = gwlist_search(session_machines, tuple,
				 transaction_belongs_to_session);
		if (sm == NULL && (event->u.TR_Invoke_Ind.tcl == 1 ||
				event->u.TR_Invoke_Ind.tcl == 2)) {
			send_abort(WSP_ABORT_DISCONNECT,
				event->u.TR_Invoke_Ind.handle);
		}
	/* Other tests are for events not handled by the state tables;
	 * do those later, after we've tried to handle them. */
	} else {
		if (session_id != -1) {
			sm = gwlist_search(session_machines, &session_id,
				find_by_session_id);
		} else {
			sm = gwlist_search(session_machines, tuple,
				transaction_belongs_to_session);
		}
		/* The table doesn't really say what we should do with
		 * non-Invoke events for which there is no session.  But
		 * such a situation means there is an error _somewhere_
		 * in the gateway. */
		if (sm == NULL) {
			error(0, "WSP: Cannot find session machine for event.");
			wap_event_dump(event);
		}
	}

	wap_addr_tuple_destroy(tuple);
	return sm;
}
Example #14
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;
}
Example #15
0
static WTLSMachine *wtls_machine_find_or_create(WAPEvent * event)
{

          WTLSMachine *wtls_machine = NULL;
          long mid;
          WAPAddrTuple *tuple;

          tuple = NULL;
          mid = -1;

   debug("wap.wtls", 0, "event->type = %d", event->type);
		  
          /* Get the address that this PDU came in from */
          switch (event->type) {
          case T_Unitdata_Ind:
          case T_DUnitdata_Ind:
                  tuple = event->u.T_Unitdata_Ind.addr_tuple;
                  break;
          case SEC_Create_Request_Req:
          case SEC_Terminate_Req:
          case SEC_Exception_Req:
          case SEC_Create_Res:
          case SEC_Exchange_Req:
          case SEC_Commit_Req:
          case SEC_Unitdata_Req:
                  tuple = event->u.T_Unitdata_Ind.addr_tuple;
                  break;
          default:
                  debug("wap.wtls", 0, "WTLS: wtls_machine_find_or_create:"
                        "unhandled event (1)"); 
                  wap_event_dump(event);
                  return NULL;
          }

          /* Either the address or the machine id must be available at this point */
          gw_assert(tuple != NULL || mid != -1);

          /* Look for the machine owning this address */
          wtls_machine = wtls_machine_find(tuple, mid);

          /* Oh well, we didn't find one. We'll create one instead, provided
             it meets certain criteria */
   if (wtls_machine == NULL) {
      switch (event->type) {
                  case SEC_Create_Request_Req:
                          /* State NULL, case 1 */
         debug("wap.wtls", 0,
               "WTLS: received a SEC_Create_Request_Req, and don't know what to do with it...");
                          /* Create and dispatch a T_Unitdata_Req containing a HelloRequest */
                          /* And there's no need to do anything else, 'cause we return to state NULL */
                          break;
                  case T_Unitdata_Ind:
                  case T_DUnitdata_Ind:
                          /* State NULL, case 3 */
/*                           if (wtls_event_type(event) == Alert_No_Renegotiation) { */
                                  /* Create and dispatch a SEC_Exception_Ind event */
/*                                   debug("wap.wtls",0,"WTLS: received an Alert_no_Renegotiation; just dropped it."); */
                                  /* And there's no need to do anything else, 'cause we return to state NULL */
/*                                   break; */
/*                           } else */
/*                           if (event->u.T_Unitdata_Ind == ClientHello) { */
                                  /* State NULL, case 2 */
                          wtls_machine = wtls_machine_create(tuple);
                          /* And stick said event into machine, which should push us into state
                             CREATING after a SEC_Create_Ind */
/*                           } */
                          break;
                  default:
                          error(0, "WTLS: wtls_machine_find_or_create:"
                                " unhandled event (2)");
                          wap_event_dump(event);
                          break;
                  }
          }
          return wtls_machine;
}
Example #16
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;
}
Example #17
0
/*
 * Checks whether wtp initiator machines data structure includes a specific 
 * machine. The machine in question is identified with with source and 
 * destination address and port and tid.  First test incoming events 
 * (WTP 10.2) (Exception are tests nro 4 and 5: if we have a memory error, 
 * we panic (nro 4); nro 5 is already checked). If we have an ack with tid 
 * verification flag set and no corresponding transaction, we abort.(case nro 
 * 2). If the event was a normal ack or an abort, it is ignored (error nro 3).
 * In the case of TR-Invoke.req a new machine is created, in the case of 
 * TR-Abort.req we have a serious error. We must create a new tid for a new
 * transaction here, because machines are identified by an address tuple and a
 * tid. This tid is GenTID (WTP 10.4.2), which is used only by the wtp iniator 
 * thread.
 * Note that as internal tid representation, module uses RcvTID (as required
 * by module wtp_pack). So we we turn the first bit of the tid stored by the
 * init machine.
 */
static WTPInitMachine *init_machine_find_or_create(WAPEvent *event)
{
    WTPInitMachine *machine = NULL;
    long mid;
    static long tid = -1; 
    WAPAddrTuple *tuple;

    mid = -1;
    tuple = NULL;

    switch (event->type) {
    case RcvAck:
        tid = event->u.RcvAck.tid;
        tuple = event->u.RcvAck.addr_tuple;
    break;

    case RcvAbort:
        tid = event->u.RcvAbort.tid;
        tuple = event->u.RcvAbort.addr_tuple;
    break;

    case RcvErrorPDU:
        mid = event->u.RcvErrorPDU.tid;
        tid = event->u.RcvErrorPDU.tid;
        tuple = event->u.RcvErrorPDU.addr_tuple;
    break;
/*
 * When we are receiving an invoke requirement, we must create a new trans-
 * action and generate a new tid. This can be wrapped, and should have its 
 * first bit turned.
 */
    case TR_Invoke_Req:
	++tid;
        if (tid_wrapped(tid)) {
	    tidnew = 1;
            tid = 0;
        }
                   
	tid = rcv_tid(tid);
        tuple = event->u.TR_Invoke_Req.addr_tuple;
        mid = event->u.TR_Invoke_Req.handle;
    break;

    case TR_Abort_Req:
        tid = event->u.TR_Abort_Req.handle;
    break;

    case TimerTO_R:
        mid = event->u.TimerTO_R.handle;
    break;

    default:
	error(0, "WTP_INIT: machine_find_or_create: unhandled event");
        wap_event_dump(event);
        return NULL;
    }

    gw_assert(tuple != NULL || mid != -1);
    machine = init_machine_find(tuple, tid, mid);

    if (machine == NULL){

	switch (event->type){
	case RcvAck:   
   
/* 
 * Case nro 2 If we do not have a tid asked for, we send a negative answer, 
 * i.e. an abort with reason INVALIDTID. 
 */
	     if (event->u.RcvAck.tid_ok) {
		 dispatch_to_wdp(wtp_pack_abort(PROVIDER, INVALIDTID,
                                                tid, tuple));
             }

/* Case nro 3, normal ack */
             else
                 info(0, "WTP_INIT: machine_find_or_create: ack "
                     "received, yet having no machine");
	break;

/* Case nro 3, abort */
        case RcvAbort:
            info(0, "WTP_INIT: machine_find_or_create: abort "
                 "received, yet having no machine");
	break;

	case TR_Invoke_Req:
	    machine = init_machine_create(tuple, tid, tidnew);
            machine->mid = event->u.TR_Invoke_Req.handle;
	break;

	case TR_Abort_Req:
            error(0, "WTP_INIT: machine_find_or_create: WSP "
                  "primitive to a wrong WTP machine");
	break;

	case TimerTO_R:
	    error(0, "WTP_INIT: machine_find_or_create: timer "
                       "event without a corresponding machine");
        break;
       
        default:
            error(0, "WTP_INIT: machine_find_or_create: unhandled"
                  "event");
            wap_event_dump(event);
        break; 
        }
   } 

   return machine;
}
Example #18
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;
}
Example #19
0
File: wtp.c Project: 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;
}