@ -487,8 +487,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
# endif
/* Arguments for find_peer */
# define FINDALLDEVICES FALSE
# define FINDONLYUSERS TRUE
# define FINDUSERS (1 << 0)
# define FINDPEERS (1 << 1)
# define FINDALLDEVICES (FINDUSERS | FINDPEERS)
# define SIPBUFSIZE 512 /*!< Buffer size for many operations */
@ -1898,7 +1899,6 @@ struct sip_peer {
/*XXX Seems like we suddenly have two flags with the same content. Why? To be continued... */
enum sip_peer_type type ; /*!< Distinguish between "user" and "peer" types. This is used solely for CLI and manager commands */
char onlymatchonip ; /*!< Only match on IP for incoming calls (old type=peer) */
} ;
@ -2438,7 +2438,7 @@ static void sip_dump_history(struct sip_pvt *dialog);
/*--- Device object handling */
static struct sip_peer * temp_peer ( const char * name ) ;
static struct sip_peer * build_peer ( const char * name , struct ast_variable * v , struct ast_variable * alt , int realtime , int ispeer );
static struct sip_peer * build_peer ( const char * name , struct ast_variable * v , struct ast_variable * alt , int realtime );
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 ) ;
@ -4471,7 +4471,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 , FALSE );
peer = build_peer ( newpeername , var , varregs , TRUE );
if ( ! peer ) {
if ( peerlist )
ast_config_destroy ( peerlist ) ;
@ -4513,38 +4513,52 @@ static struct sip_peer *realtime_peer(const char *newpeername, struct sockaddr_i
static int find_by_name ( void * obj , void * arg , void * data , int flags )
{
struct sip_peer * search = obj , * match = arg ;
int * forcenamematch = data ;
int * which_objects = data ;
/* Usernames in SIP uri's are case sensitive. Domains are not */
if ( strcmp ( search - > name , match - > name ) ) {
return 0 ;
}
/* If we're only looking for name matches, we should avoid type=peer devices,
since these should not match on any name - based search */
if ( * forcenamematch & & search - > onlymatchonip ) {
return 0 ;
switch ( * which_objects ) {
case FINDUSERS :
if ( ! ( search - > type & SIP_TYPE_USER ) ) {
return 0 ;
}
break ;
case FINDPEERS :
if ( ! ( search - > type & SIP_TYPE_PEER ) ) {
return 0 ;
}
break ;
case FINDALLDEVICES :
break ;
}
return CMP_MATCH | CMP_STOP ;
}
/*! \brief Locate device by name or ip address
/*!
* \ brief Locate device by name or ip address
*
* \ param which_objects Define which objects should be matched when doing a lookup
* by name . Valid options are FINDUSERS , FINDPEERS , or FINDALLDEVICES .
* Note that this option is not used at all when doing a lookup by IP .
*
* This is used on find matching device on name or ip / port .
If the device was declared as type = peer , we don ' t match on peer name on incoming INVITEs .
\ note Avoid using this function in new functions if there is a way to avoid it ,
since it might cause a database lookup .
*/
static struct sip_peer * find_peer ( const char * peer , struct sockaddr_in * sin , int realtime , int forcenamematch , int devstate_only )
* If the device was declared as type = peer , we don ' t match on peer name on incoming INVITEs .
*
* \ note Avoid using this function in new functions if there is a way to avoid it ,
* since it might cause a database lookup .
*/
static struct sip_peer * find_peer ( const char * peer , struct sockaddr_in * sin , int realtime , int which_objects , int devstate_only )
{
struct sip_peer * p = NULL ;
struct sip_peer tmp_peer ;
if ( peer ) {
ast_copy_string ( tmp_peer . name , peer , sizeof ( tmp_peer . name ) ) ;
p = ao2_t_callback_data ( peers , OBJ_POINTER , find_by_name , & tmp_peer , & forcenamematch , " ao2_find in peers table " ) ;
p = ao2_t_callback_data ( peers , OBJ_POINTER , find_by_name , & tmp_peer , & which_objects , " ao2_find in peers table " ) ;
} else if ( sin ) { /* search by addr? */
tmp_peer . addr . sin_addr . s_addr = sin - > sin_addr . s_addr ;
tmp_peer . addr . sin_port = sin - > sin_port ;
@ -4839,7 +4853,7 @@ static int create_addr(struct sip_pvt *dialog, const char *opeer, struct sockadd
dialog - > sa . sin_family = AF_INET ;
dialog - > timer_t1 = global_t1 ; /* Default SIP retransmission timer T1 (RFC 3261) */
dialog - > timer_b = global_timer_b ; /* Default SIP transaction timer B (RFC 3261) */
peer = find_peer ( peername , NULL , TRUE , FIND ALLDEVICE S, FALSE ) ;
peer = find_peer ( peername , NULL , TRUE , FIND PEER S, FALSE ) ;
if ( peer ) {
int res ;
@ -11972,7 +11986,7 @@ static enum check_auth_result register_verify(struct sip_pvt *p, struct sockaddr
ast_string_field_set ( p , exten , name ) ;
build_contact ( p ) ;
peer = find_peer ( name , NULL , TRUE , FIND ALLDEVICE S, FALSE ) ;
peer = find_peer ( name , NULL , TRUE , FIND PEER S, FALSE ) ;
if ( ! ( peer & & ast_apply_ha ( peer - > ha , sin ) ) ) {
/* Peer fails ACL check */
if ( peer ) {
@ -12884,11 +12898,11 @@ static enum check_auth_result check_peer_ok(struct sip_pvt *p, char *of,
peer = find_peer ( of , NULL , TRUE , FINDALLDEVICES , FALSE ) ;
} else {
/* First find devices based on username (avoid all type=peer's) */
peer = find_peer ( of , NULL , TRUE , FIND ONLY USERS, FALSE ) ;
peer = find_peer ( of , NULL , TRUE , FIND USERS, FALSE ) ;
/* Then find devices based on IP */
if ( ! peer ) {
peer = find_peer ( NULL , & p - > recv , TRUE , FIND ALLDEVICE S, FALSE ) ;
peer = find_peer ( NULL , & p - > recv , TRUE , FIND PEER S, FALSE ) ;
}
}
@ -14226,7 +14240,7 @@ static char *_sip_qualify_peer(int type, int fd, struct mansession *s, const str
return CLI_SHOWUSAGE ;
load_realtime = ( argc = = 5 & & ! strcmp ( argv [ 4 ] , " load " ) ) ? TRUE : FALSE ;
if ( ( peer = find_peer ( argv [ 3 ] , NULL , load_realtime , FIND ALLDEVICE S, FALSE ) ) ) {
if ( ( peer = find_peer ( argv [ 3 ] , NULL , load_realtime , FIND PEER S, FALSE ) ) ) {
sip_poke_peer ( peer , 1 ) ;
unref_peer ( peer , " qualify: done with peer " ) ;
} else if ( type = = 0 ) {
@ -14308,7 +14322,8 @@ static char *_sip_show_peer(int type, int fd, struct mansession *s, const struct
return CLI_SHOWUSAGE ;
load_realtime = ( argc = = 5 & & ! strcmp ( argv [ 4 ] , " load " ) ) ? TRUE : FALSE ;
peer = find_peer ( argv [ 3 ] , NULL , load_realtime , FINDALLDEVICES , FALSE ) ;
peer = find_peer ( argv [ 3 ] , NULL , load_realtime , FINDPEERS , FALSE ) ;
if ( s ) { /* Manager */
if ( peer ) {
const char * id = astman_get_header ( m , " ActionID " ) ;
@ -14590,7 +14605,7 @@ static char *sip_show_user(struct ast_cli_entry *e, int cmd, struct ast_cli_args
/* Load from realtime storage? */
load_realtime = ( a - > argc = = 5 & & ! strcmp ( a - > argv [ 4 ] , " load " ) ) ? TRUE : FALSE ;
if ( ( user = find_peer ( a - > argv [ 3 ] , NULL , load_realtime , TRUE , FALSE ) ) ) {
if ( ( user = find_peer ( a - > argv [ 3 ] , NULL , load_realtime , FINDUSERS , FALSE ) ) ) {
ao2_lock ( user ) ;
ast_cli ( a - > fd , " \n \n " ) ;
ast_cli ( a - > fd , " * Name : %s \n " , user - > name ) ;
@ -14748,7 +14763,7 @@ static char *sip_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_arg
if ( a - > argc ! = 3 )
return CLI_SHOWUSAGE ;
if ( ( peer = find_peer ( a - > argv [ 2 ] , NULL , load_realtime , FIND ALLDEVICE S, TRUE ) ) ) {
if ( ( peer = find_peer ( a - > argv [ 2 ] , NULL , load_realtime , FIND PEER S, TRUE ) ) ) {
if ( peer - > expire > 0 ) {
expire_register ( ref_peer ( peer , " ref for expire_register " ) ) ;
ast_cli ( a - > fd , " Unregistered peer \' %s \' \n \n " , a - > argv [ 2 ] ) ;
@ -15758,7 +15773,7 @@ static char *sip_do_debug_ip(int fd, char *arg)
/*! \brief Turn on SIP debugging for a given peer */
static char * sip_do_debug_peer ( int fd , char * arg )
{
struct sip_peer * peer = find_peer ( arg , NULL , TRUE , FIND ALLDEVICE S, FALSE ) ;
struct sip_peer * peer = find_peer ( arg , NULL , TRUE , FIND PEER S, FALSE ) ;
if ( ! peer )
ast_cli ( fd , " No such peer '%s' \n " , arg ) ;
else if ( peer - > addr . sin_addr . s_addr = = 0 )
@ -16213,7 +16228,7 @@ static int function_sippeer(struct ast_channel *chan, const char *cmd, char *dat
else
colname = " ip " ;
if ( ! ( peer = find_peer ( data , NULL , TRUE , FIND ALLDEVICE S, FALSE ) ) )
if ( ! ( peer = find_peer ( data , NULL , TRUE , FIND PEER S, FALSE ) ) )
return - 1 ;
if ( ! strcasecmp ( colname , " ip " ) ) {
@ -21571,7 +21586,7 @@ int st_get_se(struct sip_pvt *p, int max)
if ( p - > stimer - > st_cached_max_se ) {
return p - > stimer - > st_cached_max_se ;
} else if ( p - > peername ) {
struct sip_peer * pp = find_peer ( p - > peername , NULL , TRUE , FIND ALLDEVICE S, FALSE ) ;
struct sip_peer * pp = find_peer ( p - > peername , NULL , TRUE , FIND PEER S, FALSE ) ;
if ( pp ) {
p - > stimer - > st_cached_max_se = pp - > stimer . st_max_se ;
unref_peer ( pp , " unref peer pointer from find_peer call in st_get_se " ) ;
@ -21584,7 +21599,7 @@ int st_get_se(struct sip_pvt *p, int max)
if ( p - > stimer - > st_cached_min_se ) {
return p - > stimer - > st_cached_min_se ;
} else if ( p - > peername ) {
struct sip_peer * pp = find_peer ( p - > peername , NULL , TRUE , FIND ALLDEVICE S, FALSE ) ;
struct sip_peer * pp = find_peer ( p - > peername , NULL , TRUE , FIND PEER S, FALSE ) ;
if ( pp ) {
p - > stimer - > st_cached_min_se = pp - > stimer . st_min_se ;
unref_peer ( pp , " unref peer pointer from find_peer call in st_get_se (2) " ) ;
@ -21606,7 +21621,7 @@ enum st_refresher st_get_refresher(struct sip_pvt *p)
return p - > stimer - > st_cached_ref ;
if ( p - > peername ) {
struct sip_peer * pp = find_peer ( p - > peername , NULL , TRUE , FIND ALLDEVICE S, FALSE ) ;
struct sip_peer * pp = find_peer ( p - > peername , NULL , TRUE , FIND PEER S, FALSE ) ;
if ( pp ) {
p - > stimer - > st_cached_ref = pp - > stimer . st_ref ;
unref_peer ( pp , " unref peer pointer from find_peer call in st_get_refresher " ) ;
@ -21631,7 +21646,7 @@ enum st_mode st_get_mode(struct sip_pvt *p)
return p - > stimer - > st_cached_mode ;
if ( p - > peername ) {
struct sip_peer * pp = find_peer ( p - > peername , NULL , TRUE , FIND ALLDEVICE S, FALSE ) ;
struct sip_peer * pp = find_peer ( p - > peername , NULL , TRUE , FIND PEER S, FALSE ) ;
if ( pp ) {
p - > stimer - > st_cached_mode = pp - > stimer . st_mode_oper ;
unref_peer ( pp , " unref peer pointer from find_peer call in st_get_mode " ) ;
@ -22473,7 +22488,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 , int ispeer )
static struct sip_peer * build_peer ( const char * name , struct ast_variable * v , struct ast_variable * alt , int realtime )
{
struct sip_peer * peer = NULL ;
struct ast_ha * oldha = NULL ;
@ -22488,7 +22503,7 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
const char * srvlookup = NULL ;
static int deprecation_warning = 1 ;
struct ast_str * fullcontact = ast_str_alloca ( 512 ) ;
if ( ! realtime | | ast_test_flag ( & global_flags [ 1 ] , SIP_PAGE2_RTCACHEFRIENDS ) ) {
/* Note we do NOT use find_peer here, to avoid realtime recursion */
/* We also use a case-sensitive comparison (unlike find_peer) so
@ -22498,13 +22513,13 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
ast_copy_string ( tmp_peer . name , name , sizeof ( tmp_peer . name ) ) ;
peer = ao2_t_find ( peers , & tmp_peer , OBJ_POINTER | OBJ_UNLINK , " find and unlink peer from peers table " ) ;
}
if ( peer ) {
/* Already in the list, remove it and it will be added back (or FREE'd) */
found + + ;
if ( ! ( peer - > the_mark ) )
firstpass = 0 ;
} else {
} else {
if ( ! ( peer = ao2_t_alloc ( sizeof ( * peer ) , sip_destroy_peer_fn , " allocate a peer struct " ) ) )
return NULL ;
@ -22520,17 +22535,16 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
ast_atomic_fetchadd_int ( & speerobjs , 1 ) ;
}
peer - > onlymatchonip = ispeer ; /* If type=peer, don't match on caller ID for incoming calls */
/* Note that our peer HAS had its reference count increased */
if ( firstpass ) {
peer - > lastmsgssent = - 1 ;
oldha = peer - > ha ;
peer - > ha = NULL ;
set_peer_defaults ( peer ) ; /* Set peer defaults */
peer - > type = 0 ;
}
if ( ! found & & name )
ast_copy_string ( peer - > name , name , sizeof ( peer - > name ) ) ;
ast_copy_string ( peer - > name , name , sizeof ( peer - > name ) ) ;
/* If we have channel variables, remove them (reload) */
if ( peer - > chanvars ) {
@ -22584,13 +22598,10 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
}
} else if ( ! strcasecmp ( v - > name , " type " ) ) {
if ( ! strcasecmp ( v - > value , " peer " ) ) {
peer - > onlymatchonip = TRUE ; /* For realtime support, add type=peer in the table */
peer - > type = SIP_TYPE_PEER ;
peer - > type | = SIP_TYPE_PEER ;
} else if ( ! strcasecmp ( v - > value , " user " ) ) {
peer - > onlymatchonip = FALSE ;
peer - > type = SIP_TYPE_USER ;
peer - > type | = SIP_TYPE_USER ;
} else if ( ! strcasecmp ( v - > value , " friend " ) ) {
peer - > onlymatchonip = FALSE ;
peer - > type = SIP_TYPE_USER | SIP_TYPE_PEER ;
}
} else if ( ! strcasecmp ( v - > name , " remotesecret " ) ) {
@ -23667,10 +23678,10 @@ 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 , FALSE );
peer = build_peer ( cat , gen , ast_variable_browse ( ucfg , cat ) , 0 );
if ( peer ) {
ao2_t_link ( peers , peer , " link peer into peer table " ) ;
if ( peer - > addr . sin_addr . s_addr ) {
if ( ( peer - > type & SIP_TYPE_PEER ) & & peer - > addr . sin_addr . s_addr ) {
ao2_t_link ( peers_by_ip , peer , " link peer into peers_by_ip table " ) ;
}
@ -23719,27 +23730,24 @@ static int reload_config(enum channelreloadreason reason)
ast_log ( LOG_WARNING , " Section '%s' lacks type \n " , cat ) ;
continue ;
} else {
int is_peer = 0 ;
if ( ! strcasecmp ( utype , " user " ) ) {
is_peer = 1 ;
;
} else if ( ! strcasecmp ( utype , " friend " ) ) {
is_peer = 1 ;
} else if ( ! strcasecmp ( utype , " peer " ) )
is_peer = 2 ;
else {
;
} else if ( ! strcasecmp ( utype , " peer " ) ) {
;
} else {
ast_log ( LOG_WARNING , " Unknown type '%s' for '%s' in %s \n " , utype , cat , " sip.conf " ) ;
continue ;
}
if ( is_peer ) {
peer = build_peer ( cat , ast_variable_browse ( cfg , cat ) , NULL , 0 , is_peer = = 2 ) ;
if ( peer ) {
ao2_t_link ( peers , peer , " link peer into peers table " ) ;
if ( peer - > addr . sin_addr . s_addr ) {
ao2_t_link ( peers_by_ip , peer , " link peer into peers_by_ip table " ) ;
}
unref_peer ( peer , " unref the result of the build_peer call. Now, the links from the tables are the only ones left. " ) ;
peer_count + + ;
peer = build_peer ( cat , ast_variable_browse ( cfg , cat ) , NULL , 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 ) {
ao2_t_link ( peers_by_ip , peer , " link peer into peers_by_ip table " ) ;
}
unref_peer ( peer , " unref the result of the build_peer call. Now, the links from the tables are the only ones left. " ) ;
peer_count + + ;
}
}
}