@ -2566,7 +2566,7 @@ static void append_history_full(struct sip_pvt *p, const char *fmt, ...);
static void sip_dump_history ( struct sip_pvt * dialog ) ;
/*--- Device object handling */
static struct sip_peer * build_peer ( const char * name , struct ast_variable * v , struct ast_variable * alt , int realtime );
static struct sip_peer * build_peer ( const char * name , struct ast_variable * v , struct ast_variable * alt , int realtime , int devstate_only );
static int update_call_counter ( struct sip_pvt * fup , int event ) ;
static void sip_destroy_peer ( struct sip_peer * peer ) ;
static void sip_destroy_peer_fn ( void * peer ) ;
@ -4871,7 +4871,7 @@ static struct sip_peer *realtime_peer(const char *newpeername, struct sockaddr_i
/* Peer found in realtime, now build it in memory */
peer = build_peer ( newpeername , var , varregs , TRUE );
peer = build_peer ( newpeername , var , varregs , TRUE , devstate_only );
if ( ! peer ) {
if ( peerlist )
ast_config_destroy ( peerlist ) ;
@ -24135,7 +24135,7 @@ static void add_peer_mailboxes(struct sip_peer *peer, const char *value)
}
/*! \brief Build peer from configuration (file or realtime static/dynamic) */
static struct sip_peer * build_peer ( const char * name , struct ast_variable * v , struct ast_variable * alt , int realtime )
static struct sip_peer * build_peer ( const char * name , struct ast_variable * v , struct ast_variable * alt , int realtime , int devstate_only )
{
struct sip_peer * peer = NULL ;
struct ast_ha * oldha = NULL ;
@ -24208,8 +24208,10 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
peer - > transports = 0 ;
for ( ; v | | ( ( v = alt ) & & ! ( alt = NULL ) ) ; v = v - > next ) {
if ( handle_common_options ( & peerflags [ 0 ] , & mask [ 0 ] , v ) )
if ( ! devstate_only ) {
if ( handle_common_options ( & peerflags [ 0 ] , & mask [ 0 ] , v ) ) {
continue ;
}
if ( ! strcasecmp ( v - > name , " transport " ) & & ! ast_strlen_zero ( v - > value ) ) {
char * val = ast_strdupa ( v - > value ) ;
char * trans ;
@ -24217,14 +24219,15 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
while ( ( trans = strsep ( & val , " , " ) ) ) {
trans = ast_skip_blanks ( trans ) ;
if ( ! strncasecmp ( trans , " udp " , 3 ) )
if ( ! strncasecmp ( trans , " udp " , 3 ) ) {
peer - > transports | = SIP_TRANSPORT_UDP ;
else if ( ! strncasecmp ( trans , " tcp " , 3 ) )
} else if ( ! strncasecmp ( trans , " tcp " , 3 ) ) {
peer - > transports | = SIP_TRANSPORT_TCP ;
else if ( ! strncasecmp ( trans , " tls " , 3 ) )
} else if ( ! strncasecmp ( trans , " tls " , 3 ) ) {
peer - > transports | = SIP_TRANSPORT_TLS ;
else
} else {
ast_log ( LOG_NOTICE , " '%s' is not a valid transport type. if no other is specified, udp will be used. \n " , trans ) ;
}
if ( ! peer - > default_outbound_transport ) { /*!< The first transport listed should be default outbound */
peer - > default_outbound_transport = peer - > transports ;
@ -24232,13 +24235,9 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
}
} else if ( realtime & & ! strcasecmp ( v - > name , " regseconds " ) ) {
ast_get_time_t ( v - > value , & regseconds , 0 , NULL ) ;
} else if ( realtime & & ! strcasecmp ( v - > name , " lastms " ) ) {
sscanf ( v - > value , " %30d " , & peer - > lastms ) ;
} else if ( realtime & & ! strcasecmp ( v - > name , " ipaddr " ) & & ! ast_strlen_zero ( v - > value ) ) {
inet_aton ( v - > value , & ( peer - > addr . sin_addr ) ) ;
} else if ( realtime & & ! strcasecmp ( v - > name , " name " ) )
} else if ( realtime & & ! strcasecmp ( v - > name , " name " ) ) {
ast_copy_string ( peer - > name , v - > value , sizeof ( peer - > name ) ) ;
else if ( realtime & & ! strcasecmp ( v - > name , " fullcontact " ) ) {
} else if ( realtime & & ! strcasecmp ( v - > name , " fullcontact " ) ) {
if ( alt_fullcontact & & ! alt ) {
/* Reset, because the alternate also has a fullcontact and we
* do NOT want the field value to be doubled . It might be
@ -24266,11 +24265,11 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
ast_string_field_set ( peer , remotesecret , v - > value ) ;
} else if ( ! strcasecmp ( v - > name , " secret " ) ) {
ast_string_field_set ( peer , secret , v - > value ) ;
} else if ( ! strcasecmp ( v - > name , " md5secret " ) )
} else if ( ! strcasecmp ( v - > name , " md5secret " ) ) {
ast_string_field_set ( peer , md5secret , v - > value ) ;
else if ( ! strcasecmp ( v - > name , " auth " ) )
} else if ( ! strcasecmp ( v - > name , " auth " ) ) {
peer - > auth = add_realm_authentication ( peer - > auth , v - > value , v - > lineno ) ;
else if ( ! strcasecmp ( v - > name , " callerid " ) ) {
} else if ( ! strcasecmp ( v - > name , " callerid " ) ) {
char cid_name [ 80 ] = { ' \0 ' } , cid_num [ 80 ] = { ' \0 ' } ;
ast_callerid_split ( v - > value , cid_name , sizeof ( cid_name ) , cid_num , sizeof ( cid_num ) ) ;
@ -24342,10 +24341,10 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
}
} else if ( ! strcasecmp ( v - > name , " permit " ) | | ! strcasecmp ( v - > name , " deny " ) ) {
int ha_error = 0 ;
peer - > ha = ast_append_ha ( v - > name , v - > value , peer - > ha , & ha_error ) ;
if ( ha_error )
if ( ha_error ) {
ast_log ( LOG_ERROR , " Bad ACL entry in configuration line %d : %s \n " , v - > lineno , v - > value ) ;
}
} else if ( ! strcasecmp ( v - > name , " contactpermit " ) | | ! strcasecmp ( v - > name , " contactdeny " ) ) {
int ha_error = 0 ;
peer - > contactha = ast_append_ha ( v - > name + 7 , v - > value , peer - > contactha , & ha_error ) ;
@ -24353,14 +24352,16 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
ast_log ( LOG_ERROR , " Bad ACL entry in configuration line %d : %s \n " , v - > lineno , v - > value ) ;
}
} else if ( ! strcasecmp ( v - > name , " port " ) ) {
if ( ! realtime & & peer - > host_dynamic )
if ( ! realtime & & peer - > host_dynamic ) {
peer - > defaddr . sin_port = htons ( atoi ( v - > value ) ) ;
else
} else {
peer - > addr . sin_port = htons ( atoi ( v - > value ) ) ;
}
} else if ( ! strcasecmp ( v - > name , " callingpres " ) ) {
peer - > callingpres = ast_parse_caller_presentation ( v - > value ) ;
if ( peer - > callingpres = = - 1 )
if ( peer - > callingpres = = - 1 ) {
peer - > callingpres = atoi ( v - > value ) ;
}
} else if ( ! strcasecmp ( v - > name , " username " ) | | ! strcmp ( v - > name , " defaultuser " ) ) { /* "username" is deprecated */
ast_string_field_set ( peer , username , v - > value ) ;
if ( ! strcasecmp ( v - > name , " username " ) ) {
@ -24376,16 +24377,6 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
ast_string_field_set ( peer , regexten , v - > value ) ;
} else if ( ! strcasecmp ( v - > name , " callbackextension " ) ) {
ast_copy_string ( callback , v - > value , sizeof ( callback ) ) ;
} else if ( ! strcasecmp ( v - > name , " callcounter " ) ) {
peer - > call_limit = ast_true ( v - > value ) ? INT_MAX : 0 ;
} else if ( ! strcasecmp ( v - > name , " call-limit " ) ) {
peer - > call_limit = atoi ( v - > value ) ;
if ( peer - > call_limit < 0 )
peer - > call_limit = 0 ;
} else if ( ! strcasecmp ( v - > name , " busylevel " ) ) {
peer - > busy_level = atoi ( v - > value ) ;
if ( peer - > busy_level < 0 )
peer - > busy_level = 0 ;
} else if ( ! strcasecmp ( v - > name , " amaflags " ) ) {
format = ast_cdr_amaflags2int ( v - > value ) ;
if ( format < 0 ) {
@ -24423,12 +24414,14 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
peer - > pickupgroup = ast_get_group ( v - > value ) ;
} else if ( ! strcasecmp ( v - > name , " allow " ) ) {
int error = ast_parse_allow_disallow ( & peer - > prefs , & peer - > capability , v - > value , TRUE ) ;
if ( error )
if ( error ) {
ast_log ( LOG_WARNING , " Codec configuration errors found in line %d : %s = %s \n " , v - > lineno , v - > name , v - > value ) ;
}
} else if ( ! strcasecmp ( v - > name , " disallow " ) ) {
int error = ast_parse_allow_disallow ( & peer - > prefs , & peer - > capability , v - > value , FALSE ) ;
if ( error )
if ( error ) {
ast_log ( LOG_WARNING , " Codec configuration errors found in line %d : %s = %s \n " , v - > lineno , v - > name , v - > value ) ;
}
} else if ( ! strcasecmp ( v - > name , " preferred_codec_only " ) ) {
ast_set2_flag ( & peer - > flags [ 1 ] , ast_true ( v - > value ) , SIP_PAGE2_PREFERRED_CODEC ) ;
} else if ( ! strcasecmp ( v - > name , " registertrying " ) ) {
@ -24471,41 +24464,30 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
ast_log ( LOG_WARNING , " Timer B has been set lower than recommended. (RFC 3261, 17.1.1.2) \n " ) ;
}
}
} else if ( ! strcasecmp ( v - > name , " rtpkeepalive " ) ) {
if ( ( sscanf ( v - > value , " %30d " , & peer - > rtpkeepalive ) ! = 1 ) | | ( peer - > rtpkeepalive < 0 ) ) {
ast_log ( LOG_WARNING , " '%s' is not a valid RTP keepalive time at line %d. Using default. \n " , v - > value , v - > lineno ) ;
peer - > rtpkeepalive = global_rtpkeepalive ;
}
} else if ( ! strcasecmp ( v - > name , " setvar " ) ) {
peer - > chanvars = add_var ( v - > value , peer - > chanvars ) ;
} else if ( ! strcasecmp ( v - > name , " header " ) ) {
char tmp [ 4096 ] ;
snprintf ( tmp , sizeof ( tmp ) , " __SIPADDHEADERpre%2d=%s " , + + headercount , v - > value ) ;
peer - > chanvars = add_var ( tmp , peer - > chanvars ) ;
} else if ( ! strcasecmp ( v - > name , " qualify " ) ) {
if ( ! strcasecmp ( v - > value , " no " ) ) {
peer - > maxms = 0 ;
} else if ( ! strcasecmp ( v - > value , " yes " ) ) {
peer - > maxms = default_qualify ? default_qualify : DEFAULT_MAXMS ;
} else if ( sscanf ( v - > value , " %30d " , & peer - > maxms ) ! = 1 ) {
ast_log ( LOG_WARNING , " Qualification of peer '%s' should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf \n " , peer - > name , v - > lineno ) ;
peer - > maxms = 0 ;
}
if ( realtime & & ! ast_test_flag ( & global_flags [ 1 ] , SIP_PAGE2_RTCACHEFRIENDS ) & & peer - > maxms > 0 ) {
/* This would otherwise cause a network storm, where the
* qualify response refreshes the peer from the database ,
* which in turn causes another qualify to be sent , ad
* infinitum . */
ast_log ( LOG_WARNING , " Qualify is incompatible with dynamic uncached realtime. Please either turn rtcachefriends on or turn qualify off on peer '%s' \n " , peer - > name ) ;
peer - > maxms = 0 ;
}
} else if ( ! strcasecmp ( v - > name , " qualifyfreq " ) ) {
int i ;
if ( sscanf ( v - > value , " %30d " , & i ) = = 1 )
if ( sscanf ( v - > value , " %30d " , & i ) = = 1 ) {
peer - > qualifyfreq = i * 1000 ;
else {
} else {
ast_log ( LOG_WARNING , " Invalid qualifyfreq number '%s' at line %d of %s \n " , v - > value , v - > lineno , config ) ;
peer - > qualifyfreq = global_qualifyfreq ;
}
} else if ( ! strcasecmp ( v - > name , " maxcallbitrate " ) ) {
peer - > maxcallbitrate = atoi ( v - > value ) ;
if ( peer - > maxcallbitrate < 0 )
if ( peer - > maxcallbitrate < 0 ) {
peer - > maxcallbitrate = default_maxcallbitrate ;
}
} else if ( ! strcasecmp ( v - > name , " session-timers " ) ) {
int i = ( int ) str2stmode ( v - > value ) ;
if ( i < 0 ) {
@ -24542,6 +24524,44 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
}
}
/* These apply to devstate lookups */
if ( realtime & & ! strcasecmp ( v - > name , " lastms " ) ) {
sscanf ( v - > value , " %30d " , & peer - > lastms ) ;
} else if ( realtime & & ! strcasecmp ( v - > name , " ipaddr " ) & & ! ast_strlen_zero ( v - > value ) ) {
inet_aton ( v - > value , & ( peer - > addr . sin_addr ) ) ;
} else if ( ! strcasecmp ( v - > name , " qualify " ) ) {
if ( ! strcasecmp ( v - > value , " no " ) ) {
peer - > maxms = 0 ;
} else if ( ! strcasecmp ( v - > value , " yes " ) ) {
peer - > maxms = default_qualify ? default_qualify : DEFAULT_MAXMS ;
} else if ( sscanf ( v - > value , " %30d " , & peer - > maxms ) ! = 1 ) {
ast_log ( LOG_WARNING , " Qualification of peer '%s' should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf \n " , peer - > name , v - > lineno ) ;
peer - > maxms = 0 ;
}
if ( realtime & & ! ast_test_flag ( & global_flags [ 1 ] , SIP_PAGE2_RTCACHEFRIENDS ) & & peer - > maxms > 0 ) {
/* This would otherwise cause a network storm, where the
* qualify response refreshes the peer from the database ,
* which in turn causes another qualify to be sent , ad
* infinitum . */
ast_log ( LOG_WARNING , " Qualify is incompatible with dynamic uncached realtime. Please either turn rtcachefriends on or turn qualify off on peer '%s' \n " , peer - > name ) ;
peer - > maxms = 0 ;
}
} else if ( ! strcasecmp ( v - > name , " callcounter " ) ) {
peer - > call_limit = ast_true ( v - > value ) ? INT_MAX : 0 ;
} else if ( ! strcasecmp ( v - > name , " call-limit " ) ) {
peer - > call_limit = atoi ( v - > value ) ;
if ( peer - > call_limit < 0 ) {
peer - > call_limit = 0 ;
}
} else if ( ! strcasecmp ( v - > name , " busylevel " ) ) {
peer - > busy_level = atoi ( v - > value ) ;
if ( peer - > busy_level < 0 ) {
peer - > busy_level = 0 ;
}
}
}
if ( ! devstate_only ) {
if ( ! peer - > default_outbound_transport ) {
/* Set default set of transports */
peer - > transports = default_transports ;
@ -24559,8 +24579,8 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
set_socket_transport ( & peer - > socket , peer - > default_outbound_transport ) ;
}
if ( fullcontact - > used > 0 ) {
ast_string_field_set ( peer , fullcontact , fullcontact - > str ) ;
if ( ast_str_strlen ( fullcontact ) ) {
ast_string_field_set ( peer , fullcontact , ast_str_buffer ( fullcontact ) ) ;
peer - > rt_fromcontact = TRUE ;
/* We have a hostname in the fullcontact, but if we don't have an
* address listed on the entry ( or if it ' s ' dynamic ' ) , then we need to
@ -24596,11 +24616,13 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
ast_string_field_set ( peer , tohost , srvlookup ) ;
}
if ( ! peer - > addr . sin_port )
if ( ! peer - > addr . sin_port ) {
peer - > addr . sin_port = htons ( ( ( peer - > socket . type & SIP_TRANSPORT_TLS ) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT ) ) ;
}
if ( ! peer - > socket . port )
if ( ! peer - > socket . port ) {
peer - > socket . port = htons ( ( ( peer - > socket . type & SIP_TRANSPORT_TLS ) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT ) ) ;
}
if ( ! sip_cfg . ignore_regexpire & & peer - > host_dynamic & & realtime ) {
time_t nowtime = time ( NULL ) ;
@ -24621,10 +24643,12 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
ast_copy_flags ( & peer - > flags [ 0 ] , & peerflags [ 0 ] , mask [ 0 ] . flags ) ;
ast_copy_flags ( & peer - > flags [ 1 ] , & peerflags [ 1 ] , mask [ 1 ] . flags ) ;
if ( ast_test_flag ( & peer - > flags [ 1 ] , SIP_PAGE2_ALLOWSUBSCRIBE ) )
if ( ast_test_flag ( & peer - > flags [ 1 ] , SIP_PAGE2_ALLOWSUBSCRIBE ) ) {
sip_cfg . allowsubscribe = TRUE ; /* No global ban any more */
if ( ! found & & peer - > host_dynamic & & ! peer - > is_realtime )
}
if ( ! found & & peer - > host_dynamic & & ! peer - > is_realtime ) {
reg_source_db ( peer ) ;
}
/* If they didn't request that MWI is sent *only* on subscribe, go ahead and
* subscribe to it now . */
@ -24636,6 +24660,8 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
* way , then we will get events when app_voicemail gets loaded . */
sip_send_mwi_to_peer ( peer , NULL , 1 ) ;
}
}
peer - > the_mark = 0 ;
ast_free_ha ( oldha ) ;
@ -25364,7 +25390,7 @@ static int reload_config(enum channelreloadreason reason)
hassip = ast_variable_retrieve ( ucfg , cat , " hassip " ) ;
registersip = ast_variable_retrieve ( ucfg , cat , " registersip " ) ;
if ( ast_true ( hassip ) | | ( ! hassip & & genhassip ) ) {
peer = build_peer ( cat , gen , ast_variable_browse ( ucfg , cat ) , 0 );
peer = build_peer ( cat , gen , ast_variable_browse ( ucfg , cat ) , 0 , 0 );
if ( peer ) {
ao2_t_link ( peers , peer , " link peer into peer table " ) ;
if ( ( peer - > type & SIP_TYPE_PEER ) & & peer - > addr . sin_addr . s_addr ) {
@ -25426,7 +25452,7 @@ static int reload_config(enum channelreloadreason reason)
ast_log ( LOG_WARNING , " Unknown type '%s' for '%s' in %s \n " , utype , cat , " sip.conf " ) ;
continue ;
}
peer = build_peer ( cat , ast_variable_browse ( cfg , cat ) , NULL , 0 );
peer = build_peer ( cat , ast_variable_browse ( cfg , cat ) , NULL , 0 , 0 );
if ( peer ) {
ao2_t_link ( peers , peer , " link peer into peers table " ) ;
if ( ( peer - > type & SIP_TYPE_PEER ) & & peer - > addr . sin_addr . s_addr ) {