@ -2288,7 +2288,7 @@ static char *handle_cli_iax2_prune_realtime(struct ast_cli_entry *e, int cmd, st
} else if ( ( peer = find_peer ( a - > argv [ 3 ] , 0 ) ) ) {
if ( ast_test_flag ( peer , IAX_RTCACHEFRIENDS ) ) {
ast_set_flag ( peer , IAX_RTAUTOCLEAR ) ;
expire_registry ( ( const void * ) peer - > name ) ;
expire_registry ( peer_ref ( peer ) ) ;
ast_cli ( a - > fd , " Peer %s was removed from the cache. \n " , a - > argv [ 3 ] ) ;
} else {
ast_cli ( a - > fd , " Peer %s is not eligible for this operation. \n " , a - > argv [ 3 ] ) ;
@ -3006,8 +3006,15 @@ static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in
if ( ast_test_flag ( ( & globalflags ) , IAX_RTCACHEFRIENDS ) ) {
ast_copy_flags ( peer , & globalflags , IAX_RTAUTOCLEAR | IAX_RTCACHEFRIENDS ) ;
if ( ast_test_flag ( peer , IAX_RTAUTOCLEAR ) ) {
peer - > expire = iax2_sched_replace ( peer - > expire , sched ,
( global_rtautoclear ) * 1000 , expire_registry , ( const void * ) peer - > name ) ;
if ( peer - > expire > - 1 ) {
if ( ! ast_sched_del ( sched , peer - > expire ) ) {
peer - > expire = - 1 ;
peer_unref ( peer ) ;
}
}
peer - > expire = iax2_sched_add ( sched , ( global_rtautoclear ) * 1000 , expire_registry , peer_ref ( peer ) ) ;
if ( peer - > expire = = - 1 )
peer_unref ( peer ) ;
}
ao2_link ( peers , peer_ref ( peer ) ) ;
if ( ast_test_flag ( peer , IAX_DYNAMIC ) )
@ -4818,8 +4825,19 @@ static char *handle_cli_iax2_unregister(struct ast_cli_entry *e, int cmd, struct
p = find_peer ( a - > argv [ 2 ] , 1 ) ;
if ( p ) {
if ( p - > expire > 0 ) {
expire_registry ( a - > argv [ 2 ] ) ;
ast_cli ( a - > fd , " Peer %s unregistered \n " , a - > argv [ 2 ] ) ;
struct iax2_peer tmp_peer = {
. name = a - > argv [ 2 ] ,
} ;
struct iax2_peer * peer ;
peer = ao2_find ( peers , & tmp_peer , OBJ_POINTER ) ;
if ( peer ) {
expire_registry ( peer_ref ( peer ) ) ; /* will release its own reference when done */
peer_unref ( peer ) ; /* ref from ao2_find() */
ast_cli ( a - > fd , " Peer %s unregistered \n " , a - > argv [ 2 ] ) ;
} else {
ast_cli ( a - > fd , " Peer %s not found \n " , a - > argv [ 2 ] ) ;
}
} else {
ast_cli ( a - > fd , " Peer %s not registered \n " , a - > argv [ 2 ] ) ;
}
@ -6324,15 +6342,29 @@ static void register_peer_exten(struct iax2_peer *peer, int onoff)
}
static void prune_peers ( void ) ;
static void unlink_peer ( struct iax2_peer * peer )
{
if ( peer - > expire > - 1 ) {
if ( ! ast_sched_del ( sched , peer - > expire ) ) {
peer - > expire = - 1 ;
peer_unref ( peer ) ;
}
}
if ( peer - > pokeexpire > - 1 ) {
if ( ! ast_sched_del ( sched , peer - > pokeexpire ) ) {
peer - > pokeexpire = - 1 ;
peer_unref ( peer ) ;
}
}
unlink_peer ( peer ) ;
}
static void __expire_registry ( const void * data )
{
const char * name = data ;
struct iax2_peer * peer = NULL ;
struct iax2_peer tmp_peer = {
. name = name ,
} ;
struct iax2_peer * peer = ( struct iax2_peer * ) data ;
peer = ao2_find ( peers , & tmp_peer , OBJ_POINTER ) ;
if ( ! peer )
return ;
@ -6354,7 +6386,7 @@ static void __expire_registry(const void *data)
iax2_regfunk ( peer - > name , 0 ) ;
if ( ast_test_flag ( peer , IAX_RTAUTOCLEAR ) )
ao2_unlink( peers , peer ) ;
unlink_peer( peer ) ;
peer_unref ( peer ) ;
}
@ -6393,9 +6425,16 @@ static void reg_source_db(struct iax2_peer *p)
p - > addr . sin_family = AF_INET ;
p - > addr . sin_addr = in ;
p - > addr . sin_port = htons ( atoi ( c ) ) ;
ast_device_state_changed ( " IAX2/%s " , p - > name ) ; /* Activate notification */
p - > expire = iax2_sched_replace ( p - > expire , sched ,
( p - > expiry + 10 ) * 1000 , expire_registry , ( const void * ) p - > name ) ;
if ( p - > expire > - 1 ) {
if ( ! ast_sched_del ( sched , p - > expire ) ) {
p - > expire = - 1 ;
peer_unref ( p ) ;
}
}
ast_device_state_changed ( " IAX2/%s " , p - > name ) ; /* Activate notification */
p - > expire = iax2_sched_add ( sched , ( p - > expiry + 10 ) * 1000 , expire_registry , peer_ref ( p ) ) ;
if ( p - > expire = = - 1 )
peer_unref ( p ) ;
if ( iax2_regfunk )
iax2_regfunk ( p - > name , 1 ) ;
register_peer_exten ( p , 1 ) ;
@ -6482,8 +6521,12 @@ static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, i
/* Store socket fd */
p - > sockfd = fd ;
/* Setup the expiry */
if ( p - > expire > - 1 )
ast_sched_del ( sched , p - > expire ) ;
if ( p - > expire > - 1 ) {
if ( ! ast_sched_del ( sched , p - > expire ) ) {
p - > expire = - 1 ;
peer_unref ( p ) ;
}
}
/* treat an unspecified refresh interval as the minimum */
if ( ! refresh )
refresh = min_reg_expire ;
@ -6498,8 +6541,11 @@ static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, i
} else {
p - > expiry = refresh ;
}
if ( p - > expiry & & sin - > sin_addr . s_addr )
p - > expire = iax2_sched_add ( sched , ( p - > expiry + 10 ) * 1000 , expire_registry , ( const void * ) p - > name ) ;
if ( p - > expiry & & sin - > sin_addr . s_addr ) {
p - > expire = iax2_sched_add ( sched , ( p - > expiry + 10 ) * 1000 , expire_registry , peer_ref ( p ) ) ;
if ( p - > expire = = - 1 )
peer_unref ( p ) ;
}
iax_ie_append_str ( & ied , IAX_IE_USERNAME , p - > name ) ;
iax_ie_append_int ( & ied , IAX_IE_DATETIME , iax2_datetime ( p - > zonetag ) ) ;
if ( sin - > sin_addr . s_addr ) {
@ -6760,6 +6806,7 @@ static void __iax2_poke_peer_s(const void *data)
{
struct iax2_peer * peer = ( struct iax2_peer * ) data ;
iax2_poke_peer ( peer , 0 ) ;
peer_unref ( peer ) ;
}
static int iax2_poke_peer_s ( const void * data )
@ -8301,13 +8348,19 @@ retryowner2:
peer - > historicms = iaxs [ fr - > callno ] - > pingtime ;
/* Remove scheduled iax2_poke_noanswer */
if ( peer - > pokeexpire > - 1 )
ast_sched_del ( sched , peer - > pokeexpire ) ;
if ( peer - > pokeexpire > - 1 ) {
if ( ! ast_sched_del ( sched , peer - > pokeexpire ) ) {
peer_unref ( peer ) ;
peer - > pokeexpire = - 1 ;
}
}
/* Schedule the next cycle */
if ( ( peer - > lastms < 0 ) | | ( peer - > historicms > peer - > maxms ) )
peer - > pokeexpire = iax2_sched_add ( sched , peer - > pokefreqnotok , iax2_poke_peer_s , peer ) ;
peer - > pokeexpire = iax2_sched_add ( sched , peer - > pokefreqnotok , iax2_poke_peer_s , peer_ref ( peer ) ) ;
else
peer - > pokeexpire = iax2_sched_add ( sched , peer - > pokefreqok , iax2_poke_peer_s , peer ) ;
peer - > pokeexpire = iax2_sched_add ( sched , peer - > pokefreqok , iax2_poke_peer_s , peer_ref ( peer ) ) ;
if ( peer - > pokeexpire = = - 1 )
peer_unref ( peer ) ;
/* and finally send the ack */
send_command_immediate ( iaxs [ fr - > callno ] , AST_FRAME_IAX , IAX_COMMAND_ACK , fr - > ts , NULL , 0 , fr - > iseqno ) ;
/* And wrap up the qualify call */
@ -9245,7 +9298,9 @@ static void __iax2_poke_noanswer(const void *data)
peer - > callno = 0 ;
peer - > lastms = - 1 ;
/* Try again quickly */
peer - > pokeexpire = iax2_sched_add ( sched , peer - > pokefreqnotok , iax2_poke_peer_s , peer ) ;
peer - > pokeexpire = iax2_sched_add ( sched , peer - > pokefreqnotok , iax2_poke_peer_s , peer_ref ( peer ) ) ;
if ( peer - > pokeexpire = = - 1 )
peer_unref ( peer ) ;
}
static int iax2_poke_noanswer ( const void * data )
@ -9256,6 +9311,7 @@ static int iax2_poke_noanswer(const void *data)
if ( schedule_action ( __iax2_poke_noanswer , data ) )
# endif
__iax2_poke_noanswer ( data ) ;
peer_unref ( peer ) ;
return 0 ;
}
@ -9298,16 +9354,23 @@ static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
/* Speed up retransmission times for this qualify call */
iaxs [ peer - > callno ] - > pingtime = peer - > maxms / 4 + 1 ;
iaxs [ peer - > callno ] - > peerpoke = peer ;
if ( peer - > pokeexpire > - 1 ) {
if ( ! ast_sched_del ( sched , peer - > pokeexpire ) ) {
peer - > pokeexpire = - 1 ;
peer_unref ( peer ) ;
}
}
/* Queue up a new task to handle no reply */
/* If the host is already unreachable then use the unreachable interval instead */
if ( peer - > lastms < 0 ) {
peer - > pokeexpire = iax2_sched_replace ( peer - > pokeexpire ,
sched , peer - > pokefreqnotok , iax2_poke_noanswer , peer ) ;
} else {
peer - > pokeexpire = iax2_sched_replace ( peer - > pokeexpire ,
sched , DEFAULT_MAXMS * 2 , iax2_poke_noanswer , peer ) ;
}
if ( peer - > lastms < 0 )
peer - > pokeexpire = iax2_sched_ add( sched , peer - > pokefreqnotok , iax2_poke_noanswer , peer_ref ( peer ) ) ;
else
peer - > pokeexpire = iax2_sched_add ( sched , DEFAULT_MAXMS * 2 , iax2_poke_noanswer , peer_ref ( peer ) ) ;
if ( peer - > pokeexpire = = - 1 )
peer_unref ( peer ) ;
/* And send the poke */
send_command ( iaxs [ peer - > callno ] , AST_FRAME_IAX , IAX_COMMAND_POKE , 0 , NULL , 0 , - 1 ) ;
@ -9658,11 +9721,6 @@ static void peer_destructor(void *obj)
ast_free_ha ( peer - > ha ) ;
/* Delete it, it needs to disappear */
if ( peer - > expire > - 1 )
ast_sched_del ( sched , peer - > expire ) ;
if ( peer - > pokeexpire > - 1 )
ast_sched_del ( sched , peer - > pokeexpire ) ;
if ( peer - > callno > 0 ) {
ast_mutex_lock ( & iaxsl [ peer - > callno ] ) ;
iax2_destroy ( peer - > callno ) ;
@ -10209,7 +10267,7 @@ static void prune_peers(void)
i = ao2_iterator_init ( peers , 0 ) ;
while ( ( peer = ao2_iterator_next ( & i ) ) ) {
if ( ast_test_flag ( peer , IAX_DELME ) )
ao2_unlink( peers , peer ) ;
unlink_peer( peer ) ;
peer_unref ( peer ) ;
}
}