@ -1418,16 +1418,95 @@ void ast_sip_session_unsuspend(struct ast_sip_session *session)
ao2_ref ( suspender , - 1 ) ;
}
static int session_outbound_auth ( pjsip_dialog * dlg , pjsip_tx_data * tdata , void * user_data )
/*!
* \ internal
* \ brief Handle initial INVITE challenge response message .
* \ since 13.5 .0
*
* \ param rdata PJSIP receive response message data .
*
* \ retval PJ_FALSE Did not handle message .
* \ retval PJ_TRUE Handled message .
*/
static pj_bool_t outbound_invite_auth ( pjsip_rx_data * rdata )
{
pjsip_inv_session * inv = pjsip_dlg_get_inv_session ( dlg ) ;
struct ast_sip_session * session = inv - > mod_data [ session_module . id ] ;
pjsip_transaction * tsx ;
pjsip_dialog * dlg ;
pjsip_inv_session * inv ;
pjsip_tx_data * tdata ;
struct ast_sip_session * session ;
if ( rdata - > msg_info . msg - > line . status . code ! = 401
& & rdata - > msg_info . msg - > line . status . code ! = 407 ) {
/* Doesn't pertain to us. Move on */
return PJ_FALSE ;
}
tsx = pjsip_rdata_get_tsx ( rdata ) ;
dlg = pjsip_rdata_get_dlg ( rdata ) ;
if ( ! dlg | | ! tsx ) {
return PJ_FALSE ;
}
if ( inv - > state < PJSIP_INV_STATE_CONFIRMED & & tdata - > msg - > line . req . method . id = = PJSIP_INVITE_METHOD ) {
pjsip_inv_uac_restart ( inv , PJ_FALSE ) ;
if ( tsx - > method . id ! = PJSIP_INVITE_METHOD ) {
/* Not an INVITE that needs authentication */
return PJ_FALSE ;
}
inv = pjsip_dlg_get_inv_session ( dlg ) ;
if ( PJSIP_INV_STATE_CONFIRMED < = inv - > state ) {
/*
* We cannot handle reINVITE authentication at this
* time because the reINVITE transaction is still in
* progress .
*/
ast_debug ( 1 , " A reINVITE is being challenged. \n " ) ;
return PJ_FALSE ;
}
ast_debug ( 1 , " Initial INVITE is being challenged. \n " ) ;
session = inv - > mod_data [ session_module . id ] ;
if ( ast_sip_create_request_with_auth ( & session - > endpoint - > outbound_auths , rdata , tsx ,
& tdata ) ) {
return PJ_FALSE ;
}
/*
* Restart the outgoing initial INVITE transaction to deal
* with authentication .
*/
pjsip_inv_uac_restart ( inv , PJ_FALSE ) ;
ast_sip_session_send_request ( session , tdata ) ;
return 0 ;
return PJ_TRUE ;
}
static pjsip_module outbound_invite_auth_module = {
. name = { " Outbound INVITE Auth " , 20 } ,
. priority = PJSIP_MOD_PRIORITY_DIALOG_USAGE ,
. on_rx_response = outbound_invite_auth ,
} ;
/*!
* \ internal
* \ brief Setup outbound initial INVITE authentication .
* \ since 13.5 .0
*
* \ param dlg PJSIP dialog to attach outbound authentication .
*
* \ retval 0 on success .
* \ retval - 1 on error .
*/
static int setup_outbound_invite_auth ( pjsip_dialog * dlg )
{
pj_status_t status ;
+ + dlg - > sess_count ;
status = pjsip_dlg_add_usage ( dlg , & outbound_invite_auth_module , NULL ) ;
- - dlg - > sess_count ;
return status ! = PJ_SUCCESS ? - 1 : 0 ;
}
struct ast_sip_session * ast_sip_session_create_outgoing ( struct ast_sip_endpoint * endpoint ,
@ -1465,7 +1544,7 @@ struct ast_sip_session *ast_sip_session_create_outgoing(struct ast_sip_endpoint
return NULL ;
}
if ( ast_sip_dialog_setup_outbound_authentication( dlg , endpoint , session_outbound_auth , NULL ) ) {
if ( setup_outbound_invite_auth( dlg ) ) {
pjsip_dlg_terminate ( dlg ) ;
return NULL ;
}
@ -1505,7 +1584,7 @@ struct ast_sip_session *ast_sip_session_create_outgoing(struct ast_sip_endpoint
ao2_cleanup ( joint_caps ) ;
}
if ( ( pjsip_dlg_add_usage ( dlg , & session_module , NULL ) ! = PJ_SUCCESS ) ) {
if ( pjsip_dlg_add_usage ( dlg , & session_module , NULL ) ! = PJ_SUCCESS ) {
pjsip_inv_terminate ( inv_session , 500 , PJ_FALSE ) ;
/* Since we are not notifying ourselves that the INVITE session is being terminated
* we need to manually drop its reference to session
@ -2254,6 +2333,7 @@ static void session_inv_on_tsx_state_changed(pjsip_inv_session *inv, pjsip_trans
{
ast_sip_session_response_cb cb ;
struct ast_sip_session * session = inv - > mod_data [ session_module . id ] ;
pjsip_tx_data * tdata ;
print_debug_details ( inv , tsx , e ) ;
if ( ! session ) {
@ -2283,12 +2363,23 @@ static void session_inv_on_tsx_state_changed(pjsip_inv_session *inv, pjsip_trans
if ( tsx - > status_code = = PJSIP_SC_REQUEST_PENDING ) {
reschedule_reinvite ( session , cb ) ;
return ;
} else if ( inv - > state = = PJSIP_INV_STATE_CONFIRMED & &
tsx - > status_code ! = 488 ) {
/* Other reinvite failures (except 488) result in destroying the session. */
pjsip_tx_data * tdata ;
if ( pjsip_inv_end_session ( inv , 500 , NULL , & tdata ) = = PJ_SUCCESS ) {
ast_sip_session_send_request ( session , tdata ) ;
}
if ( inv - > state = = PJSIP_INV_STATE_CONFIRMED ) {
ast_debug ( 1 , " reINVITE received final response code %d \n " ,
tsx - > status_code ) ;
if ( ( tsx - > status_code = = 401 | | tsx - > status_code = = 407 )
& & ! ast_sip_create_request_with_auth (
& session - > endpoint - > outbound_auths ,
e - > body . tsx_state . src . rdata , tsx , & tdata ) ) {
/* Send authed reINVITE */
ast_sip_session_send_request_with_cb ( session , tdata , cb ) ;
return ;
}
if ( tsx - > status_code ! = 488 ) {
/* Other reinvite failures (except 488) result in destroying the session. */
if ( pjsip_inv_end_session ( inv , 500 , NULL , & tdata ) = = PJ_SUCCESS ) {
ast_sip_session_send_request ( session , tdata ) ;
}
}
}
} else if ( tsx - > state = = PJSIP_TSX_STATE_TERMINATED ) {
@ -2299,14 +2390,30 @@ static void session_inv_on_tsx_state_changed(pjsip_inv_session *inv, pjsip_trans
* a cancelled call . Our role is to immediately send a BYE to end the
* dialog .
*/
pjsip_tx_data * tdata ;
if ( pjsip_inv_end_session ( inv , 500 , NULL , & tdata ) = = PJ_SUCCESS ) {
ast_sip_session_send_request ( session , tdata ) ;
}
}
}
}
} else {
/* All other methods */
if ( tsx - > role = = PJSIP_ROLE_UAC ) {
if ( tsx - > state = = PJSIP_TSX_STATE_COMPLETED ) {
/* This means we got a final response to our outgoing method */
ast_debug ( 1 , " %.*s received final response code %d \n " ,
( int ) pj_strlen ( & tsx - > method . name ) , pj_strbuf ( & tsx - > method . name ) ,
tsx - > status_code ) ;
if ( ( tsx - > status_code = = 401 | | tsx - > status_code = = 407 )
& & ! ast_sip_create_request_with_auth (
& session - > endpoint - > outbound_auths ,
e - > body . tsx_state . src . rdata , tsx , & tdata ) ) {
/* Send authed version of the method */
ast_sip_session_send_request_with_cb ( session , tdata , cb ) ;
return ;
}
}
}
}
if ( cb ) {
cb ( session , e - > body . tsx_state . src . rdata ) ;
@ -2640,6 +2747,7 @@ static int load_module(void)
return AST_MODULE_LOAD_DECLINE ;
}
ast_sip_register_service ( & session_reinvite_module ) ;
ast_sip_register_service ( & outbound_invite_auth_module ) ;
ast_module_shutdown_ref ( ast_module_info - > self ) ;
@ -2648,6 +2756,7 @@ static int load_module(void)
static int unload_module ( void )
{
ast_sip_unregister_service ( & outbound_invite_auth_module ) ;
ast_sip_unregister_service ( & session_reinvite_module ) ;
ast_sip_unregister_service ( & session_module ) ;
ast_sorcery_delete ( ast_sip_get_sorcery ( ) , nat_hook ) ;