@ -1237,6 +1237,39 @@ static const struct ast_channel_tech iax2_tech = {
. func_channel_read = acf_channel_read ,
} ;
/*!
* \ internal
* \ brief Obtain the owner channel lock if the owner exists .
*
* \ param callno IAX2 call id .
*
* \ note Assumes the iaxsl [ callno ] lock is already obtained .
*
* \ note
* IMPORTANT NOTE ! ! ! Any time this function is used , even if
* iaxs [ callno ] was valid before calling it , it may no longer be
* valid after calling it . This function may unlock and lock
* the mutex associated with this callno , meaning that another
* thread may grab it and destroy the call .
*
* \ return Nothing
*/
static void iax2_lock_owner ( int callno )
{
for ( ; ; ) {
if ( ! iaxs [ callno ] | | ! iaxs [ callno ] - > owner ) {
/* There is no owner lock to get. */
break ;
}
if ( ! ast_channel_trylock ( iaxs [ callno ] - > owner ) ) {
/* We got the lock */
break ;
}
/* Avoid deadlock by pausing and trying again */
DEADLOCK_AVOIDANCE ( & iaxsl [ callno ] ) ;
}
}
static void mwi_event_cb ( const struct ast_event * event , void * userdata )
{
/* The MWI subscriptions exist just so the core knows we care about those
@ -2890,18 +2923,10 @@ static int find_callno_locked(unsigned short callno, unsigned short dcallno, str
*/
static int iax2_queue_frame ( int callno , struct ast_frame * f )
{
for ( ; ; ) {
if ( iaxs [ callno ] & & iaxs [ callno ] - > owner ) {
if ( ast_channel_trylock ( iaxs [ callno ] - > owner ) ) {
/* Avoid deadlock by pausing and trying again */
DEADLOCK_AVOIDANCE ( & iaxsl [ callno ] ) ;
} else {
ast_queue_frame ( iaxs [ callno ] - > owner , f ) ;
ast_channel_unlock ( iaxs [ callno ] - > owner ) ;
break ;
}
} else
break ;
iax2_lock_owner ( callno ) ;
if ( iaxs [ callno ] & & iaxs [ callno ] - > owner ) {
ast_queue_frame ( iaxs [ callno ] - > owner , f ) ;
ast_channel_unlock ( iaxs [ callno ] - > owner ) ;
}
return 0 ;
}
@ -2921,18 +2946,10 @@ static int iax2_queue_frame(int callno, struct ast_frame *f)
*/
static int iax2_queue_hangup ( int callno )
{
for ( ; ; ) {
if ( iaxs [ callno ] & & iaxs [ callno ] - > owner ) {
if ( ast_channel_trylock ( iaxs [ callno ] - > owner ) ) {
/* Avoid deadlock by pausing and trying again */
DEADLOCK_AVOIDANCE ( & iaxsl [ callno ] ) ;
} else {
ast_queue_hangup ( iaxs [ callno ] - > owner ) ;
ast_channel_unlock ( iaxs [ callno ] - > owner ) ;
break ;
}
} else
break ;
iax2_lock_owner ( callno ) ;
if ( iaxs [ callno ] & & iaxs [ callno ] - > owner ) {
ast_queue_hangup ( iaxs [ callno ] - > owner ) ;
ast_channel_unlock ( iaxs [ callno ] - > owner ) ;
}
return 0 ;
}
@ -2953,18 +2970,10 @@ static int iax2_queue_hangup(int callno)
static int iax2_queue_control_data ( int callno ,
enum ast_control_frame_type control , const void * data , size_t datalen )
{
for ( ; ; ) {
if ( iaxs [ callno ] & & iaxs [ callno ] - > owner ) {
if ( ast_channel_trylock ( iaxs [ callno ] - > owner ) ) {
/* Avoid deadlock by pausing and trying again */
DEADLOCK_AVOIDANCE ( & iaxsl [ callno ] ) ;
} else {
ast_queue_control_data ( iaxs [ callno ] - > owner , control , data , datalen ) ;
ast_channel_unlock ( iaxs [ callno ] - > owner ) ;
break ;
}
} else
break ;
iax2_lock_owner ( callno ) ;
if ( iaxs [ callno ] & & iaxs [ callno ] - > owner ) {
ast_queue_control_data ( iaxs [ callno ] - > owner , control , data , datalen ) ;
ast_channel_unlock ( iaxs [ callno ] - > owner ) ;
}
return 0 ;
}
@ -4143,6 +4152,12 @@ static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtr
return - 1 ;
}
iax2_lock_owner ( fr - > callno ) ;
if ( ! iaxs [ fr - > callno ] ) {
/* The call dissappeared so discard this frame that we could not send. */
iax2_frame_free ( fr ) ;
return - 1 ;
}
if ( ( owner = iaxs [ fr - > callno ] - > owner ) )
bridge = ast_bridged_channel ( owner ) ;
@ -4151,6 +4166,8 @@ static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtr
if ( ( ! ast_test_flag64 ( iaxs [ fr - > callno ] , IAX_FORCEJITTERBUF ) ) & & owner & & bridge & & ( bridge - > tech - > properties & AST_CHAN_TP_WANTSJITTER ) ) {
jb_frame frame ;
ast_channel_unlock ( owner ) ;
/* deliver any frames in the jb */
while ( jb_getall ( iaxs [ fr - > callno ] - > jb , & frame ) = = JB_OK ) {
__do_deliver ( frame . data ) ;
@ -4169,6 +4186,9 @@ static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtr
__do_deliver ( fr ) ;
return - 1 ;
}
if ( owner ) {
ast_channel_unlock ( owner ) ;
}
/* insert into jitterbuffer */
/* TODO: Perhaps we could act immediately if it's not droppable and late */
@ -9708,27 +9728,13 @@ static struct ast_custom_function iaxvar_function = {
static void set_hangup_source_and_cause ( int callno , unsigned char causecode )
{
int locked = 0 ;
struct ast_channel * owner = NULL ;
do {
if ( ast_channel_trylock ( iaxs [ callno ] - > owner ) ) {
DEADLOCK_AVOIDANCE ( & iaxsl [ callno ] ) ;
} else {
locked = 1 ;
owner = iaxs [ callno ] - > owner ;
}
}
while ( ! locked & & iaxs [ callno ] & & iaxs [ callno ] - > owner ) ;
iax2_lock_owner ( callno ) ;
if ( iaxs [ callno ] & & iaxs [ callno ] - > owner ) {
if ( causecode ) {
iaxs [ callno ] - > owner - > hangupcause = causecode ;
}
ast_set_hangupsource ( iaxs [ callno ] - > owner , iaxs [ callno ] - > owner - > name , 0 ) ;
ast_channel_unlock ( owner ) ;
} else if ( locked ) {
ast_channel_unlock ( owner ) ;
ast_channel_unlock ( iaxs [ callno ] - > owner ) ;
}
}
@ -9845,6 +9851,7 @@ static int socket_process(struct iax2_thread *thread)
if ( f . frametype = = AST_FRAME_IAX ) {
if ( iax_parse_ies ( & ies , thread - > buf + sizeof ( struct ast_iax2_full_hdr ) , f . datalen ) ) {
ast_log ( LOG_WARNING , " Undecodable frame received from '%s' \n " , ast_inet_ntoa ( sin . sin_addr ) ) ;
ast_variables_destroy ( ies . vars ) ;
return 1 ;
}
f . data . ptr = NULL ;
@ -9864,6 +9871,7 @@ static int socket_process(struct iax2_thread *thread)
if ( ! dcallno & & iax2_allow_new ( f . frametype , f . subclass . integer , 1 ) ) {
/* only set NEW_ALLOW if calltoken checks out */
if ( handle_call_token ( fh , & ies , & sin , fd ) ) {
ast_variables_destroy ( ies . vars ) ;
return 1 ;
}
@ -9881,6 +9889,7 @@ static int socket_process(struct iax2_thread *thread)
/* Don't know anything about it yet */
f . frametype = AST_FRAME_NULL ;
f . subclass . integer = 0 ;
memset ( & ies , 0 , sizeof ( ies ) ) ;
}
if ( ! fr - > callno ) {
@ -9904,6 +9913,7 @@ static int socket_process(struct iax2_thread *thread)
} else if ( f . frametype = = AST_FRAME_IAX & & ( f . subclass . integer = = IAX_COMMAND_REGREQ | | f . subclass . integer = = IAX_COMMAND_REGREL ) ) {
send_apathetic_reply ( 1 , ntohs ( fh - > scallno ) , & sin , IAX_COMMAND_REGREJ , ntohl ( fh - > ts ) , fh - > iseqno + 1 , fd , NULL ) ;
}
ast_variables_destroy ( ies . vars ) ;
return 1 ;
}
}
@ -9926,11 +9936,13 @@ static int socket_process(struct iax2_thread *thread)
}
if ( fr - > callno > 0 )
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
ast_variables_destroy ( ies . vars ) ;
return 1 ;
}
if ( ast_test_flag64 ( iaxs [ fr - > callno ] , IAX_ENCRYPTED ) & & ! decrypted ) {
if ( decrypt_frame ( fr - > callno , fh , & f , & res ) ) {
ast_log ( LOG_NOTICE , " Packet Decrypt Failed! \n " ) ;
ast_variables_destroy ( ies . vars ) ;
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
}
@ -10020,6 +10032,7 @@ static int socket_process(struct iax2_thread *thread)
/* Send a VNAK requesting retransmission */
iax2_vnak ( fr - > callno ) ;
}
ast_variables_destroy ( ies . vars ) ;
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
}
@ -10083,6 +10096,7 @@ static int socket_process(struct iax2_thread *thread)
iaxs [ fr - > callno ] - > rseqno = fr - > iseqno ;
else {
/* Stop processing now */
ast_variables_destroy ( ies . vars ) ;
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
}
@ -10095,6 +10109,7 @@ static int socket_process(struct iax2_thread *thread)
( ( f . subclass . integer ! = IAX_COMMAND_TXACC ) & &
( f . subclass . integer ! = IAX_COMMAND_TXCNT ) ) ) ) {
/* Only messages we accept from a transfer host are TXACC and TXCNT */
ast_variables_destroy ( ies . vars ) ;
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
}
@ -10108,6 +10123,7 @@ static int socket_process(struct iax2_thread *thread)
if ( ast_test_flag64 ( iaxs [ fr - > callno ] , IAX_DELAYPBXSTART ) ) {
ast_clear_flag64 ( iaxs [ fr - > callno ] , IAX_DELAYPBXSTART ) ;
if ( ! ast_iax2_new ( fr - > callno , AST_STATE_RING , iaxs [ fr - > callno ] - > chosenformat , NULL ) ) {
ast_variables_destroy ( ies . vars ) ;
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
}
@ -10117,6 +10133,13 @@ static int socket_process(struct iax2_thread *thread)
struct ast_datastore * variablestore = NULL ;
struct ast_variable * var , * prev = NULL ;
AST_LIST_HEAD ( , ast_var_t ) * varlist ;
iax2_lock_owner ( fr - > callno ) ;
if ( ! iaxs [ fr - > callno ] ) {
ast_variables_destroy ( ies . vars ) ;
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
}
if ( ( c = iaxs [ fr - > callno ] - > owner ) ) {
varlist = ast_calloc ( 1 , sizeof ( * varlist ) ) ;
variablestore = ast_datastore_alloc ( & iax2_variable_datastore_info , NULL ) ;
@ -10153,6 +10176,7 @@ static int socket_process(struct iax2_thread *thread)
ast_free ( varlist ) ;
}
}
ast_channel_unlock ( c ) ;
} else {
/* No channel yet, so transfer the variables directly over to the pvt,
* for later inheritance . */
@ -10182,14 +10206,11 @@ static int socket_process(struct iax2_thread *thread)
iaxs [ fr - > callno ] - > voiceformat = f . subclass . codec ;
ast_debug ( 1 , " Ooh, voice format changed to '%s' \n " , ast_getformatname ( f . subclass . codec ) ) ;
if ( iaxs [ fr - > callno ] - > owner ) {
format_t orignative ;
retryowner :
if ( ast_channel_trylock ( iaxs [ fr - > callno ] - > owner ) ) {
DEADLOCK_AVOIDANCE ( & iaxsl [ fr - > callno ] ) ;
if ( iaxs [ fr - > callno ] & & iaxs [ fr - > callno ] - > owner ) goto retryowner ;
}
iax2_lock_owner ( fr - > callno ) ;
if ( iaxs [ fr - > callno ] ) {
if ( iaxs [ fr - > callno ] - > owner ) {
format_t orignative ;
orignative = iaxs [ fr - > callno ] - > owner - > nativeformats ;
iaxs [ fr - > callno ] - > owner - > nativeformats = f . subclass . codec ;
if ( iaxs [ fr - > callno ] - > owner - > readformat )
@ -10261,22 +10282,32 @@ retryowner:
ast_set_flag64 ( iaxs [ fr - > callno ] , IAX_QUELCH ) ;
if ( ies . musiconhold ) {
if ( iaxs [ fr - > callno ] - > owner & & ast_bridged_channel ( iaxs [ fr - > callno ] - > owner ) ) {
iax2_lock_owner ( fr - > callno ) ;
if ( ! iaxs [ fr - > callno ] | | ! iaxs [ fr - > callno ] - > owner ) {
break ;
}
if ( ast_bridged_channel ( iaxs [ fr - > callno ] - > owner ) ) {
const char * moh_suggest = iaxs [ fr - > callno ] - > mohsuggest ;
/*
* We already hold the owner lock so we do not
* need to check iaxs [ fr - > callno ] after it returns .
*/
iax2_queue_control_data ( fr - > callno , AST_CONTROL_HOLD ,
S_OR ( moh_suggest , NULL ) ,
! ast_strlen_zero ( moh_suggest ) ? strlen ( moh_suggest ) + 1 : 0 ) ;
if ( ! iaxs [ fr - > callno ] ) {
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
}
}
ast_channel_unlock ( iaxs [ fr - > callno ] - > owner ) ;
}
}
break ;
case IAX_COMMAND_UNQUELCH :
if ( ast_test_flag ( & iaxs [ fr - > callno ] - > state , IAX_STATE_STARTED ) ) {
/* Generate Manager Unhold event, if necessary*/
iax2_lock_owner ( fr - > callno ) ;
if ( ! iaxs [ fr - > callno ] ) {
break ;
}
/* Generate Manager Unhold event, if necessary */
if ( iaxs [ fr - > callno ] - > owner & & ast_test_flag64 ( iaxs [ fr - > callno ] , IAX_QUELCH ) ) {
ast_manager_event ( iaxs [ fr - > callno ] - > owner , EVENT_FLAG_CALL , " Hold " ,
" Status: Off \r \n "
@ -10287,13 +10318,17 @@ retryowner:
}
ast_clear_flag64 ( iaxs [ fr - > callno ] , IAX_QUELCH ) ;
if ( iaxs [ fr - > callno ] - > owner & & ast_bridged_channel ( iaxs [ fr - > callno ] - > owner ) ) {
if ( ! iaxs [ fr - > callno ] - > owner ) {
break ;
}
if ( ast_bridged_channel ( iaxs [ fr - > callno ] - > owner ) ) {
/*
* We already hold the owner lock so we do not
* need to check iaxs [ fr - > callno ] after it returns .
*/
iax2_queue_control_data ( fr - > callno , AST_CONTROL_UNHOLD , NULL , 0 ) ;
if ( ! iaxs [ fr - > callno ] ) {
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
}
}
ast_channel_unlock ( iaxs [ fr - > callno ] - > owner ) ;
}
break ;
case IAX_COMMAND_TXACC :
@ -10320,8 +10355,7 @@ retryowner:
check_provisioning ( & sin , fd , ies . serviceident , ies . provver ) ;
ast_mutex_lock ( & iaxsl [ fr - > callno ] ) ;
if ( ! iaxs [ fr - > callno ] ) {
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
break ;
}
}
/* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
@ -10358,8 +10392,7 @@ retryowner:
ast_mutex_lock ( & iaxsl [ fr - > callno ] ) ;
if ( ! iaxs [ fr - > callno ] ) {
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
break ;
}
} else
exists = 0 ;
@ -10372,8 +10405,7 @@ retryowner:
iax_ie_append_byte ( & ied0 , IAX_IE_CAUSECODE , AST_CAUSE_NO_ROUTE_DESTINATION ) ;
send_command_final ( iaxs [ fr - > callno ] , AST_FRAME_IAX , IAX_COMMAND_REJECT , 0 , ied0 . buf , ied0 . pos , - 1 ) ;
if ( ! iaxs [ fr - > callno ] ) {
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
break ;
}
if ( authdebug )
ast_log ( LOG_NOTICE , " Rejected connect attempt from %s, request '%s@%s' does not exist \n " , ast_inet_ntoa ( sin . sin_addr ) , iaxs [ fr - > callno ] - > exten , iaxs [ fr - > callno ] - > context ) ;
@ -10419,8 +10451,7 @@ retryowner:
iax_ie_append_byte ( & ied0 , IAX_IE_CAUSECODE , AST_CAUSE_BEARERCAPABILITY_NOTAVAIL ) ;
send_command_final ( iaxs [ fr - > callno ] , AST_FRAME_IAX , IAX_COMMAND_REJECT , 0 , ied0 . buf , ied0 . pos , - 1 ) ;
if ( ! iaxs [ fr - > callno ] ) {
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
break ;
}
if ( authdebug ) {
char tmp [ 256 ] , tmp2 [ 256 ] , tmp3 [ 256 ] ;
@ -10473,8 +10504,7 @@ retryowner:
ast_log ( LOG_ERROR , " No best format in '%s'??? \n " , ast_getformatname_multiple ( tmp , sizeof ( tmp ) , iaxs [ fr - > callno ] - > peercapability & iaxs [ fr - > callno ] - > capability ) ) ;
send_command_final ( iaxs [ fr - > callno ] , AST_FRAME_IAX , IAX_COMMAND_REJECT , 0 , ied0 . buf , ied0 . pos , - 1 ) ;
if ( ! iaxs [ fr - > callno ] ) {
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
break ;
}
if ( authdebug ) {
ast_log ( LOG_NOTICE , " Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'. \n " ,
@ -10531,10 +10561,6 @@ retryowner:
iaxs [ fr - > callno ] - > encmethods = 0 ;
if ( ! authenticate_request ( fr - > callno ) & & iaxs [ fr - > callno ] )
ast_set_flag ( & iaxs [ fr - > callno ] - > state , IAX_STATE_AUTHENTICATED ) ;
if ( ! iaxs [ fr - > callno ] ) {
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
}
break ;
case IAX_COMMAND_DPREQ :
/* Request status in the dialplan */
@ -10556,8 +10582,7 @@ retryowner:
if ( iaxs [ fr - > callno ] - > owner ) {
set_hangup_source_and_cause ( fr - > callno , ies . causecode ) ;
if ( ! iaxs [ fr - > callno ] ) {
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
break ;
}
}
@ -10570,8 +10595,7 @@ retryowner:
if ( iaxs [ fr - > callno ] - > owner ) {
set_hangup_source_and_cause ( fr - > callno , ies . causecode ) ;
if ( ! iaxs [ fr - > callno ] ) {
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
break ;
}
}
@ -10593,40 +10617,54 @@ retryowner:
case IAX_COMMAND_TRANSFER :
{
struct ast_channel * bridged_chan ;
struct ast_channel * owner ;
if ( iaxs [ fr - > callno ] - > owner & & ( bridged_chan = ast_bridged_channel ( iaxs [ fr - > callno ] - > owner ) ) & & ies . called_number ) {
/* Set BLINDTRANSFER channel variables */
iax2_lock_owner ( fr - > callno ) ;
if ( ! iaxs [ fr - > callno ] ) {
/* Initiating call went away before we could transfer. */
break ;
}
owner = iaxs [ fr - > callno ] - > owner ;
bridged_chan = owner ? ast_bridged_channel ( owner ) : NULL ;
if ( bridged_chan & & ies . called_number ) {
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
pbx_builtin_setvar_helper ( iaxs [ fr - > callno ] - > owner , " BLINDTRANSFER " , bridged_chan - > name ) ;
ast_mutex_lock ( & iaxsl [ fr - > callno ] ) ;
if ( ! iaxs [ fr - > callno ] ) {
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
}
pbx_builtin_setvar_helper ( bridged_chan , " BLINDTRANSFER " , iaxs [ fr - > callno ] - > owner - > name ) ;
/* Set BLINDTRANSFER channel variables */
pbx_builtin_setvar_helper ( owner , " BLINDTRANSFER " , bridged_chan - > name ) ;
pbx_builtin_setvar_helper ( bridged_chan , " BLINDTRANSFER " , owner - > name ) ;
if ( ast_parking_ext_valid ( ies . called_number , c , iaxs [ fr - > callno ] - > context ) ) {
struct ast_channel * saved_channel = iaxs [ fr - > callno ] - > owner ;
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
if ( iax_park ( bridged_chan , saved_channel , ies . called_number ) ) {
ast_log ( LOG_WARNING , " Failed to park call on '%s' \n " , bridged_chan - > name ) ;
} else {
ast_debug ( 1 , " Parked call on '%s' \n " , ast_bridged_channel ( iaxs [ fr - > callno ] - > owner ) - > name ) ;
ast_debug ( 1 , " Parking call '%s' \n " , bridged_chan - > name ) ;
if ( iax_park ( bridged_chan , owner , ies . called_number ) ) {
ast_log ( LOG_WARNING , " Failed to park call '%s' \n " ,
bridged_chan - > name ) ;
}
ast_mutex_lock ( & iaxsl [ fr - > callno ] ) ;
} else {
if ( ast_async_goto ( bridged_chan , iaxs [ fr - > callno ] - > context , ies . called_number , 1 ) )
ast_log ( LOG_WARNING , " Async goto of '%s' to '%s@%s' failed \n " , bridged_chan - > name ,
ies . called_number , iaxs [ fr - > callno ] - > context ) ;
else {
ast_debug ( 1 , " Async goto of '%s' to '%s@%s' started \n " , bridged_chan - > name ,
ies . called_number , iaxs [ fr - > callno ] - > context ) ;
ast_mutex_lock ( & iaxsl [ fr - > callno ] ) ;
if ( iaxs [ fr - > callno ] ) {
if ( ast_async_goto ( bridged_chan , iaxs [ fr - > callno ] - > context ,
ies . called_number , 1 ) ) {
ast_log ( LOG_WARNING ,
" Async goto of '%s' to '%s@%s' failed \n " ,
bridged_chan - > name , ies . called_number ,
iaxs [ fr - > callno ] - > context ) ;
} else {
ast_debug ( 1 , " Async goto of '%s' to '%s@%s' started \n " ,
bridged_chan - > name , ies . called_number ,
iaxs [ fr - > callno ] - > context ) ;
}
} else {
/* Initiating call went away before we could transfer. */
}
}
} else {
ast_debug ( 1 , " Async goto not applicable on call %d \n " , fr - > callno ) ;
}
if ( owner ) {
ast_channel_unlock ( owner ) ;
}
break ;
}
@ -10655,8 +10693,7 @@ retryowner:
iax_ie_append_byte ( & ied0 , IAX_IE_CAUSECODE , AST_CAUSE_BEARERCAPABILITY_NOTAVAIL ) ;
send_command_final ( iaxs [ fr - > callno ] , AST_FRAME_IAX , IAX_COMMAND_REJECT , 0 , ied0 . buf , ied0 . pos , - 1 ) ;
if ( ! iaxs [ fr - > callno ] ) {
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
break ;
}
if ( authdebug ) {
char tmp1 [ 256 ] , tmp2 [ 256 ] ;
@ -10667,24 +10704,18 @@ retryowner:
}
} else {
ast_set_flag ( & iaxs [ fr - > callno ] - > state , IAX_STATE_STARTED ) ;
if ( iaxs [ fr - > callno ] - > owner ) {
iax2_lock_owner ( fr - > callno ) ;
if ( iaxs [ fr - > callno ] & & iaxs [ fr - > callno ] - > owner ) {
/* Switch us to use a compatible format */
iaxs [ fr - > callno ] - > owner - > nativeformats = iaxs [ fr - > callno ] - > peerformat ;
ast_verb ( 3 , " Format for call is %s \n " , ast_getformatname ( iaxs [ fr - > callno ] - > owner - > nativeformats ) ) ;
retryowner2 :
if ( ast_channel_trylock ( iaxs [ fr - > callno ] - > owner ) ) {
DEADLOCK_AVOIDANCE ( & iaxsl [ fr - > callno ] ) ;
if ( iaxs [ fr - > callno ] & & iaxs [ fr - > callno ] - > owner ) goto retryowner2 ;
}
if ( iaxs [ fr - > callno ] & & iaxs [ fr - > callno ] - > owner ) {
/* Setup read/write formats properly. */
if ( iaxs [ fr - > callno ] - > owner - > writeformat )
ast_set_write_format ( iaxs [ fr - > callno ] - > owner , iaxs [ fr - > callno ] - > owner - > writeformat ) ;
if ( iaxs [ fr - > callno ] - > owner - > readformat )
ast_set_read_format ( iaxs [ fr - > callno ] - > owner , iaxs [ fr - > callno ] - > owner - > readformat ) ;
ast_channel_unlock ( iaxs [ fr - > callno ] - > owner ) ;
}
/* Setup read/write formats properly. */
if ( iaxs [ fr - > callno ] - > owner - > writeformat )
ast_set_write_format ( iaxs [ fr - > callno ] - > owner , iaxs [ fr - > callno ] - > owner - > writeformat ) ;
if ( iaxs [ fr - > callno ] - > owner - > readformat )
ast_set_read_format ( iaxs [ fr - > callno ] - > owner , iaxs [ fr - > callno ] - > owner - > readformat ) ;
ast_channel_unlock ( iaxs [ fr - > callno ] - > owner ) ;
}
}
if ( iaxs [ fr - > callno ] ) {
@ -10698,10 +10729,6 @@ retryowner2:
case IAX_COMMAND_POKE :
/* Send back a pong packet with the original timestamp */
send_command_final ( iaxs [ fr - > callno ] , AST_FRAME_IAX , IAX_COMMAND_PONG , fr - > ts , NULL , 0 , - 1 ) ;
if ( ! iaxs [ fr - > callno ] ) {
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
}
break ;
case IAX_COMMAND_PING :
{
@ -10801,10 +10828,6 @@ retryowner2:
ies . username ? ies . username : " <unknown> " , ast_inet_ntoa ( iaxs [ fr - > callno ] - > addr . sin_addr ) ) ;
iax2_queue_frame ( fr - > callno , & hangup_fr ) ;
}
if ( ! iaxs [ fr - > callno ] ) {
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
}
break ;
case IAX_COMMAND_AUTHREP :
/* For security, always ack immediately */
@ -10835,8 +10858,7 @@ retryowner2:
iax_ie_append_byte ( & ied0 , IAX_IE_CAUSECODE , AST_CAUSE_NO_ROUTE_DESTINATION ) ;
send_command_final ( iaxs [ fr - > callno ] , AST_FRAME_IAX , IAX_COMMAND_REJECT , 0 , ied0 . buf , ied0 . pos , - 1 ) ;
if ( ! iaxs [ fr - > callno ] ) {
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
break ;
}
} else {
/* Select an appropriate format */
@ -10894,8 +10916,7 @@ retryowner2:
iax_ie_append_byte ( & ied0 , IAX_IE_CAUSECODE , AST_CAUSE_BEARERCAPABILITY_NOTAVAIL ) ;
send_command_final ( iaxs [ fr - > callno ] , AST_FRAME_IAX , IAX_COMMAND_REJECT , 0 , ied0 . buf , ied0 . pos , - 1 ) ;
if ( ! iaxs [ fr - > callno ] ) {
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
break ;
}
} else {
/* Pick one... */
@ -10948,8 +10969,7 @@ retryowner2:
iax_ie_append_byte ( & ied0 , IAX_IE_CAUSECODE , AST_CAUSE_BEARERCAPABILITY_NOTAVAIL ) ;
send_command_final ( iaxs [ fr - > callno ] , AST_FRAME_IAX , IAX_COMMAND_REJECT , 0 , ied0 . buf , ied0 . pos , - 1 ) ;
if ( ! iaxs [ fr - > callno ] ) {
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
break ;
}
}
}
@ -11042,8 +11062,7 @@ immediatedial:
iax_ie_append_byte ( & ied0 , IAX_IE_CAUSECODE , AST_CAUSE_NO_ROUTE_DESTINATION ) ;
send_command_final ( iaxs [ fr - > callno ] , AST_FRAME_IAX , IAX_COMMAND_REJECT , 0 , ied0 . buf , ied0 . pos , - 1 ) ;
if ( ! iaxs [ fr - > callno ] ) {
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
break ;
}
} else {
char tmp [ 256 ] ;
@ -11111,16 +11130,14 @@ immediatedial:
send_command_immediate ( iaxs [ fr - > callno ] , AST_FRAME_IAX , IAX_COMMAND_ACK , fr - > ts , NULL , 0 , fr - > iseqno ) ;
if ( register_verify ( fr - > callno , & sin , & ies ) ) {
if ( ! iaxs [ fr - > callno ] ) {
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
break ;
}
/* Send delayed failure */
auth_fail ( fr - > callno , IAX_COMMAND_REGREJ ) ;
break ;
}
if ( ! iaxs [ fr - > callno ] ) {
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
break ;
}
if ( ( ast_strlen_zero ( iaxs [ fr - > callno ] - > secret ) & & ast_strlen_zero ( iaxs [ fr - > callno ] - > inkeys ) ) | |
ast_test_flag ( & iaxs [ fr - > callno ] - > state , IAX_STATE_AUTHENTICATED ) ) {
@ -11130,25 +11147,16 @@ immediatedial:
if ( update_registry ( & sin , fr - > callno , ies . devicetype , fd , ies . refresh ) )
ast_log ( LOG_WARNING , " Registry error \n " ) ;
if ( ! iaxs [ fr - > callno ] ) {
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
break ;
}
if ( ies . provverpres & & ies . serviceident & & sin . sin_addr . s_addr ) {
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
check_provisioning ( & sin , fd , ies . serviceident , ies . provver ) ;
ast_mutex_lock ( & iaxsl [ fr - > callno ] ) ;
if ( ! iaxs [ fr - > callno ] ) {
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
}
}
break ;
}
registry_authrequest ( fr - > callno ) ;
if ( ! iaxs [ fr - > callno ] ) {
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
}
break ;
case IAX_COMMAND_REGACK :
if ( iax2_ack_registry ( & ies , & sin , fr - > callno ) )
@ -11176,10 +11184,6 @@ immediatedial:
iax_ie_append_str ( & ied0 , IAX_IE_CAUSE , " No authority found " ) ;
iax_ie_append_byte ( & ied0 , IAX_IE_CAUSECODE , AST_CAUSE_FACILITY_NOT_SUBSCRIBED ) ;
send_command_final ( iaxs [ fr - > callno ] , AST_FRAME_IAX , IAX_COMMAND_REJECT , 0 , ied0 . buf , ied0 . pos , - 1 ) ;
if ( ! iaxs [ fr - > callno ] ) {
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
}
}
break ;
case IAX_COMMAND_TXREJ :
@ -11301,10 +11305,6 @@ immediatedial:
send_command_final ( iaxs [ fr - > callno ] , AST_FRAME_IAX , IAX_COMMAND_FWDATA , 0 , ied0 . buf , ied0 . pos , - 1 ) ;
else
send_command ( iaxs [ fr - > callno ] , AST_FRAME_IAX , IAX_COMMAND_FWDATA , 0 , ied0 . buf , ied0 . pos , - 1 ) ;
if ( ! iaxs [ fr - > callno ] ) {
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
}
break ;
case IAX_COMMAND_CALLTOKEN :
{
@ -11350,6 +11350,7 @@ immediatedial:
else {
ast_log ( LOG_WARNING , " Received mini frame before first full video frame \n " ) ;
iax2_vnak ( fr - > callno ) ;
ast_variables_destroy ( ies . vars ) ;
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
}
@ -11372,12 +11373,14 @@ immediatedial:
else {
ast_debug ( 1 , " Received mini frame before first full voice frame \n " ) ;
iax2_vnak ( fr - > callno ) ;
ast_variables_destroy ( ies . vars ) ;
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
}
f . datalen = res - sizeof ( struct ast_iax2_mini_hdr ) ;
if ( f . datalen < 0 ) {
ast_log ( LOG_WARNING , " Datalen < 0? \n " ) ;
ast_variables_destroy ( ies . vars ) ;
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
}
@ -11395,6 +11398,7 @@ immediatedial:
}
/* Don't pass any packets until we're started */
if ( ! ast_test_flag ( & iaxs [ fr - > callno ] - > state , IAX_STATE_STARTED ) ) {
ast_variables_destroy ( ies . vars ) ;
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
}
@ -11403,6 +11407,7 @@ immediatedial:
struct ast_party_connected_line connected ;
if ( ! ast_test_flag64 ( iaxs [ fr - > callno ] , IAX_RECVCONNECTEDLINE ) ) {
ast_variables_destroy ( ies . vars ) ;
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
}
@ -11465,6 +11470,7 @@ immediatedial:
}
/* Always run again */
ast_variables_destroy ( ies . vars ) ;
ast_mutex_unlock ( & iaxsl [ fr - > callno ] ) ;
return 1 ;
}