@ -568,7 +568,8 @@ struct sip_auth {
# define SIP_PAGE2_RTCACHEFRIENDS (1 << 0)
# define SIP_PAGE2_RTUPDATE (1 << 1)
# define SIP_PAGE2_RTAUTOCLEAR (1 << 2)
# define SIP_PAGE2_RTIGNOREREGEXPIRE (1 << 3)
# define SIP_PAGE2_IGNOREREGEXPIRE (1 << 3)
# define SIP_PAGE2_RT_FROMCONTACT (1 << 4)
/* SIP packet flags */
# define SIP_PKT_DEBUG (1 << 0) /*!< Debug this packet */
@ -1039,8 +1040,9 @@ static int __sip_xmit(struct sip_pvt *p, char *data, int len)
res = sendto ( sipsock , data , len , 0 , ( struct sockaddr * ) & p - > recv , sizeof ( struct sockaddr_in ) ) ;
else
res = sendto ( sipsock , data , len , 0 , ( struct sockaddr * ) & p - > sa , sizeof ( struct sockaddr_in ) ) ;
if ( res ! = len ) {
ast_log ( LOG_WARNING , " sip_xmit of %p (len %d) to %s returned %d: %s\n " , data , len , ast_inet_ntoa ( iabuf , sizeof ( iabuf ) , p - > sa . sin_addr ) , res , strerror ( errno ) ) ;
ast_log ( LOG_WARNING , " sip_xmit of %p (len %d) to %s :%d returned %d: %s\n " , data , len , ast_inet_ntoa ( iabuf , sizeof ( iabuf ) , p - > sa . sin_addr ) , res , ntohs ( p - > sa . sin_port ) , strerror ( errno ) ) ;
}
return res ;
}
@ -1563,7 +1565,7 @@ static int sip_sendtext(struct ast_channel *ast, const char *text)
}
/*! \brief realtime_update_peer: Update peer object in realtime storage ---*/
static void realtime_update_peer ( const char * peername , struct sockaddr_in * sin , const char * username , int expirey )
static void realtime_update_peer ( const char * peername , struct sockaddr_in * sin , const char * username , const char * fullcontact , int expirey )
{
char port [ 10 ] ;
char ipaddr [ 20 ] ;
@ -1577,7 +1579,10 @@ static void realtime_update_peer(const char *peername, struct sockaddr_in *sin,
ast_inet_ntoa ( ipaddr , sizeof ( ipaddr ) , sin - > sin_addr ) ;
snprintf ( port , sizeof ( port ) , " %d " , ntohs ( sin - > sin_port ) ) ;
}
ast_update_realtime ( " sippeers " , " name " , peername , " ipaddr " , ipaddr , " port " , port , " regseconds " , regseconds , " username " , username , NULL ) ;
if ( fullcontact )
ast_update_realtime ( " sippeers " , " name " , peername , " ipaddr " , ipaddr , " port " , port , " regseconds " , regseconds , " username " , username , " fullcontact " , fullcontact , NULL ) ;
else
ast_update_realtime ( " sippeers " , " name " , peername , " ipaddr " , ipaddr , " port " , port , " regseconds " , regseconds , " username " , username , NULL ) ;
}
/*! \brief register_peer_exten: Automatically add peer extension to dial plan ---*/
@ -1629,10 +1634,10 @@ static void sip_destroy_peer(struct sip_peer *peer)
/*! \brief update_peer: Update peer data in database (if used) ---*/
static void update_peer ( struct sip_peer * p , int expiry )
{
int rtcachefriends = ast_test_flag ( & ( p - > flags_page2 ) , SIP_PAGE2_RTCACHEFRIENDS ) ;
if ( ast_test_flag ( ( & global_flags_page2 ) , SIP_PAGE2_RTUPDATE ) & &
( ast_test_flag ( p , SIP_REALTIME ) | |
ast_test_flag ( & ( p - > flags_page2 ) , SIP_PAGE2_RTCACHEFRIENDS ) ) ) {
realtime_update_peer ( p - > name , & p - > addr , p - > username , expiry ) ;
( ast_test_flag ( p , SIP_REALTIME ) | | rtcachefriends ) ) {
realtime_update_peer ( p - > name , & p - > addr , p - > username , rtcachefriends ? p - > fullcontact : NULL , expiry ) ;
}
}
@ -1677,14 +1682,14 @@ static struct sip_peer *realtime_peer(const char *peername, struct sockaddr_in *
ast_variables_destroy ( var ) ;
return ( struct sip_peer * ) NULL ;
}
/* Peer found in realtime, now build it in memory */
peer = build_peer ( newpeername , var , ! ast_test_flag ( ( & global_flags_page2 ) , SIP_PAGE2_RTCACHEFRIENDS ) ) ;
if ( ! peer ) {
ast_variables_destroy ( var ) ;
return ( struct sip_peer * ) NULL ;
}
if ( ast_test_flag ( ( & global_flags_page2 ) , SIP_PAGE2_RTCACHEFRIENDS ) ) {
/* Cache peer */
ast_copy_flags ( ( & peer - > flags_page2 ) , ( & global_flags_page2 ) , SIP_PAGE2_RTAUTOCLEAR | SIP_PAGE2_RTCACHEFRIENDS ) ;
@ -1699,6 +1704,7 @@ static struct sip_peer *realtime_peer(const char *peername, struct sockaddr_in *
ast_set_flag ( peer , SIP_REALTIME ) ;
}
ast_variables_destroy ( var ) ;
return peer ;
}
@ -5573,13 +5579,26 @@ static int transmit_request_with_auth(struct sip_pvt *p, int sipmethod, int seqn
return send_request ( p , & resp , reliable , seqno ? seqno : p - > ocseq ) ;
}
static void destroy_association ( struct sip_peer * peer )
{
if ( ! ast_test_flag ( ( & global_flags_page2 ) , SIP_PAGE2_IGNOREREGEXPIRE ) ) {
if ( ast_test_flag ( & ( peer - > flags_page2 ) , SIP_PAGE2_RT_FROMCONTACT ) ) {
ast_update_realtime ( " sippeers " , " name " , peer - > name , " fullcontact " , " " , " ipaddr " , " " , " port " , " " , " regseconds " , " 0 " , " username " , " " , NULL ) ;
} else {
ast_db_del ( " SIP/Registry " , peer - > name ) ;
}
}
}
/*! \brief expire_register: Expire registration of SIP peer ---*/
static int expire_register ( void * data )
{
struct sip_peer * peer = data ;
memset ( & peer - > addr , 0 , sizeof ( peer - > addr ) ) ;
ast_db_del ( " SIP/Registry " , peer - > name ) ;
destroy_association ( peer ) ;
manager_event ( EVENT_FLAG_SYSTEM , " PeerStatus " , " Peer: SIP/%s \r \n PeerStatus: Unregistered \r \n Cause: Expired \r \n " , peer - > name ) ;
register_peer_exten ( peer , 0 ) ;
peer - > expire = - 1 ;
@ -5612,6 +5631,8 @@ static void reg_source_db(struct sip_peer *peer)
int port ;
char * scan , * addr , * port_str , * expiry_str , * username , * contact ;
if ( ast_test_flag ( & ( peer - > flags_page2 ) , SIP_PAGE2_RT_FROMCONTACT ) )
return ;
if ( ast_db_get ( " SIP/Registry " , peer - > name , data , sizeof ( data ) ) )
return ;
@ -5792,7 +5813,9 @@ static enum parse_register_result parse_register_contact(struct sip_pvt *pvt, st
if ( p - > expire > - 1 )
ast_sched_del ( sched , p - > expire ) ;
p - > expire = - 1 ;
ast_db_del ( " SIP/Registry " , p - > name ) ;
destroy_association ( p ) ;
register_peer_exten ( p , 0 ) ;
p - > fullcontact [ 0 ] = ' \0 ' ;
p - > useragent [ 0 ] = ' \0 ' ;
@ -5865,7 +5888,7 @@ static enum parse_register_result parse_register_contact(struct sip_pvt *pvt, st
p - > expire = - 1 ;
pvt - > expiry = expiry ;
snprintf ( data , sizeof ( data ) , " %s:%d:%d:%s:%s " , ast_inet_ntoa ( iabuf , sizeof ( iabuf ) , p - > addr . sin_addr ) , ntohs ( p - > addr . sin_port ) , expiry , p - > username , p - > fullcontact ) ;
if ( ! ( ast_test_flag ( p , SIP_REALTIME ) & & ast_test_flag ( ( & p - > flags_page2 ) , SIP_PAGE2_RT CACHEFRIENDS) ) )
if ( ! ast_test_flag ( ( & p - > flags_page2 ) , SIP_PAGE2_RT _FROMCONTACT) )
ast_db_put ( " SIP/Registry " , p - > name , data ) ;
manager_event ( EVENT_FLAG_SYSTEM , " PeerStatus " , " Peer: SIP/%s \r \n PeerStatus: Registered \r \n " , p - > name ) ;
if ( inaddrcmp ( & p - > addr , & oldsin ) ) {
@ -8159,7 +8182,7 @@ static int sip_show_settings(int fd, int argc, char *argv[])
ast_cli ( fd , " Realtime Users: %s \n " , realtimeusers ? " Yes " : " No " ) ;
ast_cli ( fd , " Cache Friends: %s \n " , ast_test_flag ( & global_flags_page2 , SIP_PAGE2_RTCACHEFRIENDS ) ? " Yes " : " No " ) ;
ast_cli ( fd , " Update: %s \n " , ast_test_flag ( & global_flags_page2 , SIP_PAGE2_RTUPDATE ) ? " Yes " : " No " ) ;
ast_cli ( fd , " Ignore Reg. Expire: %s \n " , ast_test_flag ( & global_flags_page2 , SIP_PAGE2_ RT IGNOREREGEXPIRE) ? " Yes " : " No " ) ;
ast_cli ( fd , " Ignore Reg. Expire: %s \n " , ast_test_flag ( & global_flags_page2 , SIP_PAGE2_ IGNOREREGEXPIRE) ? " Yes " : " No " ) ;
ast_cli ( fd , " Auto Clear: %d \n " , global_rtautoclear ) ;
}
ast_cli ( fd , " \n ---- \n " ) ;
@ -11974,7 +11997,10 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int
inet_aton ( v - > value , & ( peer - > addr . sin_addr ) ) ;
} else if ( realtime & & ! strcasecmp ( v - > name , " name " ) )
ast_copy_string ( peer - > name , v - > value , sizeof ( peer - > name ) ) ;
else if ( ! strcasecmp ( v - > name , " secret " ) )
else if ( realtime & & ! strcasecmp ( v - > name , " fullcontact " ) ) {
ast_copy_string ( peer - > fullcontact , v - > value , sizeof ( peer - > fullcontact ) ) ;
ast_set_flag ( ( & peer - > flags_page2 ) , SIP_PAGE2_RT_FROMCONTACT ) ;
} else if ( ! strcasecmp ( v - > name , " secret " ) )
ast_copy_string ( peer - > secret , v - > value , sizeof ( peer - > secret ) ) ;
else if ( ! strcasecmp ( v - > name , " md5secret " ) )
ast_copy_string ( peer - > md5secret , v - > value , sizeof ( peer - > md5secret ) ) ;
@ -12117,11 +12143,12 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int
*/
v = v - > next ;
}
if ( realtime & & ! ast_test_flag ( ( & global_flags_page2 ) , SIP_PAGE2_ RT IGNOREREGEXPIRE) & & ast_test_flag ( peer , SIP_DYNAMIC ) ) {
if ( ! ast_test_flag ( ( & global_flags_page2 ) , SIP_PAGE2_ IGNOREREGEXPIRE) & & ast_test_flag ( peer , SIP_DYNAMIC ) ) {
time_t nowtime ;
time ( & nowtime ) ;
if ( ( nowtime - regseconds ) > 0 ) {
destroy_association ( peer ) ;
memset ( & peer - > addr , 0 , sizeof ( peer - > addr ) ) ;
if ( option_debug )
ast_log ( LOG_DEBUG , " Bah, we're expired (%ld/%ld/%ld)! \n " , nowtime - regseconds , regseconds , nowtime ) ;
@ -12239,8 +12266,8 @@ static int reload_config(void)
ast_set2_flag ( ( & global_flags_page2 ) , ast_true ( v - > value ) , SIP_PAGE2_RTCACHEFRIENDS ) ;
} else if ( ! strcasecmp ( v - > name , " rtupdate " ) ) {
ast_set2_flag ( ( & global_flags_page2 ) , ast_true ( v - > value ) , SIP_PAGE2_RTUPDATE ) ;
} else if ( ! strcasecmp ( v - > name , " rt ignoreregexpire" ) ) {
ast_set2_flag ( ( & global_flags_page2 ) , ast_true ( v - > value ) , SIP_PAGE2_ RT IGNOREREGEXPIRE) ;
} else if ( ! strcasecmp ( v - > name , " ignoreregexpire" ) ) {
ast_set2_flag ( ( & global_flags_page2 ) , ast_true ( v - > value ) , SIP_PAGE2_ IGNOREREGEXPIRE) ;
} else if ( ! strcasecmp ( v - > name , " rtautoclear " ) ) {
int i = atoi ( v - > value ) ;
if ( i > 0 )