Пример #1
0
/**
 * Create a new leg object for incoming request message.
 *
 * @param agent    agent object
 * @param callback function which is called for each 
 *                 incoming request belonging to this leg
 * @param magic    call leg context
 * @param msg      a request message
 *
 * @note The ownership of @a msg will pass back to NTA upon successful call
 * to the function nta_msg_leg(). In other words, if the call to @a
 * nta_msg_leg() is successful, the application may not do anything with @a
 * msg anymore.  Instead of that, NTA will create of a new incoming request
 * object for the @a msg and eventually return the request to application by
 * calling the @a callback function.
 *
 * @deprecated Use nta_leg_stateful() instead.
 */
nta_leg_t *nta_msg_leg(nta_agent_t *agent,
		       msg_t *msg,
		       nta_request_f *callback,
		       nta_leg_magic_t *magic,
		       ...)
{
  nta_leg_t *leg;
  sip_t *sip = sip_object(msg);

  SU_DEBUG_9(("\tnta_msg_leg(): called\n"));

  assert(msg && sip && sip->sip_request);

  if (!msg || !sip || !sip->sip_request || !callback)
    return NULL;

  leg = nta_leg_tcreate(agent, callback, magic,
			SIPTAG_CALL_ID(sip->sip_call_id),
			SIPTAG_FROM(sip->sip_to), /* local address */
			SIPTAG_TO(sip->sip_from), /* remote address */
			TAG_END());
  if (!leg) 
    /* xyzzy */;
  else if (nta_leg_server_route(leg, sip->sip_record_route, 
				sip->sip_contact) < 0)
    nta_leg_destroy(leg), leg = NULL;
  else if (nta_leg_stateful(leg, msg) < 0)
    nta_leg_destroy(leg), leg = NULL;

  SU_DEBUG_9(("\tnta_msg_leg(): returns %p\n", leg));

  return leg;
}
Пример #2
0
/**@internal
 * UAS tag and route.
 *
 * Update dialog tags and route on the UAS side.
 *
 * @param own  dialog owner
 * @param ds   dialog state
 * @param sip  SIP message containing response used to update dialog
 * @param rtag if true, set remote tag within the leg
 */
void nua_dialog_uas_route(nua_owner_t *own,
			  nua_dialog_state_t *ds,
			  sip_t const *sip,
			  int rtag)
{
  int established = nua_dialog_is_established(ds);

  if (!established && sip->sip_from->a_tag)
    ds->ds_remote_tag = su_strdup(own, sip->sip_from->a_tag);

  if (ds->ds_leg == NULL)
    return;

  nta_leg_server_route(ds->ds_leg, sip->sip_record_route, sip->sip_contact);
  ds->ds_route = ds->ds_route || sip->sip_record_route || sip->sip_contact;

  if (rtag && !established && sip->sip_from->a_tag)
    nta_leg_rtag(ds->ds_leg, sip->sip_from->a_tag);
}
Пример #3
0
    int DrachtioController::processRequestOutsideDialog( nta_leg_t* defaultLeg, nta_incoming_t* irq, sip_t const *sip) {
        DR_LOG(log_debug) << "processRequestOutsideDialog" << endl ;
        int rc = validateSipMessage( sip ) ;
        if( 0 != rc ) {
            return rc ;
        }

        switch (sip->sip_request->rq_method ) {
            case sip_method_invite:
            {
                /* TODO:  should support optional config to only allow invites from defined addresses */

                /* system-wide minimum session-expires is 90 seconds */
                if( sip->sip_session_expires && sip->sip_session_expires->x_delta < 90 ) {
                      nta_incoming_treply( irq, SIP_422_SESSION_TIMER_TOO_SMALL, 
                        SIPTAG_MIN_SE_STR("90"),
                        TAG_END() ) ; 
                      return 0;
                } 

                string transactionId ;
                generateUuid( transactionId ) ;

                nta_incoming_treply( irq, SIP_100_TRYING, TAG_END() ) ;                
 
                 if( !m_pClientController->route_request_outside_dialog( irq, sip, transactionId ) )  {
                    DR_LOG(log_error) << "No providers available for invite" << endl ;
                    return 503 ;
                }

                nta_leg_t* leg = nta_leg_tcreate(m_nta, legCallback, this,
                                                   SIPTAG_CALL_ID(sip->sip_call_id),
                                                   SIPTAG_CSEQ(sip->sip_cseq),
                                                   SIPTAG_TO(sip->sip_from),
                                                   SIPTAG_FROM(sip->sip_to),
                                                   TAG_END());
                if( NULL == leg ) {
                    DR_LOG(log_error) << "Error creating a leg for  origination" << endl ;
                    //TODO: we got a client out there with a dead INVITE now...
                    return 500 ;
                }
                boost::shared_ptr<SipDialog> dlg = boost::make_shared<SipDialog>( leg, irq, sip ) ;
                dlg->setTransactionId( transactionId ) ;

                string contactStr ;
                generateOutgoingContact( sip->sip_contact, contactStr ) ;
                nta_leg_server_route( leg, sip->sip_record_route, sip->sip_contact ) ;

                m_pDialogController->addIncomingInviteTransaction( leg, irq, sip, transactionId, dlg ) ;


            }
            break ;

            case sip_method_ack:

                /* success case: call has been established */
                nta_incoming_destroy( irq ) ;
                return 0 ;               
            case sip_method_register:
            case sip_method_message:
            case sip_method_options:
            case sip_method_notify:
            {
                string transactionId ;
                generateUuid( transactionId ) ;

                if( !m_pClientController->route_request_outside_dialog( irq, sip, transactionId ) )  {
                    DR_LOG(log_error) << "No providers available for register" << endl ;
                    return 503 ;
                }

                m_pDialogController->addIncomingRequestTransaction( irq, transactionId ) ;
                return 0 ;
            }
            
            case sip_method_bye:
            case sip_method_cancel:
                DR_LOG(log_error) << "Received BYE or CANCEL for unknown dialog: " << sip->sip_call_id->i_id << endl ;
                return 481 ;
                
            default:
                DR_LOG(log_error) << "DrachtioController::processRequestOutsideDialog - unsupported method type: " << sip->sip_request->rq_method_name << ": " << sip->sip_call_id->i_id << endl ;
                return 501 ;
                break ;
                
        }
        
        return 0 ;
    }