2007-04-02 19:54:25 +00:00
/*
* FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
2010-02-06 03:38:24 +00:00
* Copyright ( C ) 2005 - 2010 , Anthony Minessale II < anthm @ freeswitch . org >
2007-04-02 19:54:25 +00:00
*
* Version : MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 ( the " License " ) ; you may not use this file except in compliance with
* the License . You may obtain a copy of the License at
* http : //www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an " AS IS " basis ,
* WITHOUT WARRANTY OF ANY KIND , either express or implied . See the License
* for the specific language governing rights and limitations under the
* License .
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
*
* The Initial Developer of the Original Code is
2009-02-04 21:20:54 +00:00
* Anthony Minessale II < anthm @ freeswitch . org >
2007-04-02 19:54:25 +00:00
* Portions created by the Initial Developer are Copyright ( C )
* the Initial Developer . All Rights Reserved .
*
* Contributor ( s ) :
*
2009-02-04 21:20:54 +00:00
* Anthony Minessale II < anthm @ freeswitch . org >
2008-07-30 18:50:47 +00:00
* Ken Rice , < krice at cometsig . com > ( work sponsored by Comet Signaling LLC , CopperCom , Inc and Asteria Solutions Group , Inc )
2007-04-02 19:54:25 +00:00
* Paul D . Tinsley < pdt at jackhammer . org >
* Bret McDanel < trixter AT 0xdecafbad . com >
2007-04-07 03:04:46 +00:00
* Marcel Barbulescu < marcelbarbulescu @ gmail . com >
2008-01-12 19:15:05 +00:00
* David Knell < >
2009-03-04 19:45:10 +00:00
* Eliot Gable < egable AT . AT broadvox . com >
2007-04-02 19:54:25 +00:00
*
*
* sofia_ref . c - - SOFIA SIP Endpoint ( registration code )
*
*/
2007-03-31 19:01:33 +00:00
# include "mod_sofia.h"
2009-03-22 20:04:56 +00:00
static void sofia_reg_new_handle ( sofia_gateway_t * gateway_ptr , int attach )
2008-01-29 21:56:36 +00:00
{
2009-03-22 05:15:17 +00:00
int ss_state = nua_callstate_authenticating ;
2008-05-27 04:54:52 +00:00
if ( gateway_ptr - > nh ) {
nua_handle_bind ( gateway_ptr - > nh , NULL ) ;
nua_handle_destroy ( gateway_ptr - > nh ) ;
gateway_ptr - > nh = NULL ;
2009-03-22 05:15:17 +00:00
sofia_private_free ( gateway_ptr - > sofia_private ) ;
2008-05-27 04:54:52 +00:00
}
2007-03-31 19:01:33 +00:00
2009-03-22 05:15:17 +00:00
gateway_ptr - > nh = nua_handle ( gateway_ptr - > profile - > nua , NULL ,
SIPTAG_CALL_ID_STR ( gateway_ptr - > uuid_str ) ,
SIPTAG_TO_STR ( gateway_ptr - > register_to ) ,
NUTAG_CALLSTATE_REF ( ss_state ) , SIPTAG_FROM_STR ( gateway_ptr - > register_from ) , TAG_END ( ) ) ;
2009-03-22 20:04:56 +00:00
if ( attach ) {
if ( ! gateway_ptr - > sofia_private ) {
gateway_ptr - > sofia_private = malloc ( sizeof ( * gateway_ptr - > sofia_private ) ) ;
switch_assert ( gateway_ptr - > sofia_private ) ;
}
memset ( gateway_ptr - > sofia_private , 0 , sizeof ( * gateway_ptr - > sofia_private ) ) ;
2010-02-06 03:38:24 +00:00
2009-03-22 20:04:56 +00:00
gateway_ptr - > sofia_private - > gateway = gateway_ptr ;
nua_handle_bind ( gateway_ptr - > nh , gateway_ptr - > sofia_private ) ;
}
2009-03-22 05:15:17 +00:00
}
static void sofia_reg_kill_reg ( sofia_gateway_t * gateway_ptr )
{
2009-04-03 13:14:26 +00:00
if ( gateway_ptr - > state ! = REG_STATE_REGED ) {
if ( gateway_ptr - > nh ) {
nua_handle_destroy ( gateway_ptr - > nh ) ;
gateway_ptr - > nh = NULL ;
}
return ;
}
2010-02-06 03:38:24 +00:00
2009-04-03 13:14:26 +00:00
/*
2010-02-06 03:38:24 +00:00
if ( ! gateway_ptr - > nh ) {
sofia_reg_new_handle ( gateway_ptr , SWITCH_FALSE ) ;
}
*/
2009-03-22 05:15:17 +00:00
if ( gateway_ptr - > nh ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " UN-Registering %s \n " , gateway_ptr - > name ) ;
2010-02-06 03:38:24 +00:00
nua_unregister ( gateway_ptr - > nh , NUTAG_URL ( gateway_ptr - > register_url ) , NUTAG_REGISTRAR ( gateway_ptr - > register_proxy ) , TAG_END ( ) ) ;
2009-03-22 05:15:17 +00:00
}
2010-02-06 03:38:24 +00:00
2009-04-03 13:14:26 +00:00
2008-01-29 21:56:36 +00:00
}
2007-04-20 18:06:06 +00:00
2010-05-10 12:33:31 -04:00
void sofia_reg_fire_custom_gateway_state_event ( sofia_gateway_t * gateway , int status , const char * phrase )
2010-02-06 03:38:24 +00:00
{
2008-10-10 15:36:02 +00:00
switch_event_t * s_event ;
if ( switch_event_create_subclass ( & s_event , SWITCH_EVENT_CUSTOM , MY_EVENT_GATEWAY_STATE ) = = SWITCH_STATUS_SUCCESS ) {
2009-04-21 01:02:45 +00:00
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " Gateway " , gateway - > name ) ;
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " State " , sofia_state_string ( gateway - > state ) ) ;
2010-05-10 12:33:31 -04:00
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " Ping-Status " , sofia_gateway_status_name ( gateway - > status ) ) ;
2010-01-15 15:18:07 +00:00
if ( ! zstr ( phrase ) ) {
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " Phrase " , phrase ) ;
}
if ( status ) {
switch_event_add_header ( s_event , SWITCH_STACK_BOTTOM , " Status " , " %d " , status ) ;
}
2008-10-10 15:36:02 +00:00
switch_event_fire ( & s_event ) ;
}
}
2007-04-04 03:08:17 +00:00
void sofia_reg_unregister ( sofia_profile_t * profile )
2007-03-31 19:01:33 +00:00
{
2007-04-29 01:16:49 +00:00
sofia_gateway_t * gateway_ptr ;
2010-03-25 00:28:56 +00:00
switch_mutex_lock ( mod_sofia_globals . hash_mutex ) ;
2007-03-31 19:01:33 +00:00
for ( gateway_ptr = profile - > gateways ; gateway_ptr ; gateway_ptr = gateway_ptr - > next ) {
2009-03-22 20:04:56 +00:00
2007-03-31 19:01:33 +00:00
if ( gateway_ptr - > sofia_private ) {
2009-03-22 05:15:17 +00:00
sofia_private_free ( gateway_ptr - > sofia_private ) ;
2007-03-31 19:01:33 +00:00
}
2009-03-22 20:04:56 +00:00
2009-04-03 13:14:26 +00:00
if ( gateway_ptr - > state = = REG_STATE_REGED ) {
sofia_reg_kill_reg ( gateway_ptr ) ;
}
2009-03-22 20:04:56 +00:00
2007-03-31 19:01:33 +00:00
}
2010-03-25 00:28:56 +00:00
switch_mutex_unlock ( mod_sofia_globals . hash_mutex ) ;
2007-03-31 19:01:33 +00:00
}
2008-11-24 15:52:55 +00:00
void sofia_sub_check_gateway ( sofia_profile_t * profile , time_t now )
{
/* NOTE: A lot of the mechanism in place here for refreshing subscriptions is
* pretty much redundant , as the sofia stack takes it upon itself to
* refresh subscriptions on its own , based on the value of the Expires
* header ( which we control in the outgoing subscription request )
*/
sofia_gateway_t * gateway_ptr ;
2010-02-06 03:38:24 +00:00
2010-03-25 00:28:56 +00:00
switch_mutex_lock ( mod_sofia_globals . hash_mutex ) ;
2008-11-24 15:52:55 +00:00
for ( gateway_ptr = profile - > gateways ; gateway_ptr ; gateway_ptr = gateway_ptr - > next ) {
sofia_gateway_subscription_t * gw_sub_ptr ;
for ( gw_sub_ptr = gateway_ptr - > subscriptions ; gw_sub_ptr ; gw_sub_ptr = gw_sub_ptr - > next ) {
int ss_state = nua_callstate_authenticating ;
sub_state_t ostate = gw_sub_ptr - > state ;
2009-06-03 22:00:49 +00:00
char * user_via = NULL ;
2010-02-06 03:38:24 +00:00
2008-11-24 15:52:55 +00:00
if ( ! now ) {
gw_sub_ptr - > state = ostate = SUB_STATE_UNSUBED ;
gw_sub_ptr - > expires_str = " 0 " ;
}
2009-06-03 22:00:49 +00:00
2009-06-04 05:50:16 +00:00
if ( sofia_glue_check_nat ( gateway_ptr - > profile , gateway_ptr - > register_proxy ) ) {
user_via = sofia_glue_create_external_via ( NULL , gateway_ptr - > profile , gateway_ptr - > register_transport ) ;
}
2008-11-24 15:52:55 +00:00
switch ( ostate ) {
case SUB_STATE_NOSUB :
break ;
case SUB_STATE_SUBSCRIBE :
gw_sub_ptr - > expires = now + gw_sub_ptr - > freq ;
gw_sub_ptr - > state = SUB_STATE_SUBED ;
break ;
case SUB_STATE_UNSUBSCRIBE :
gw_sub_ptr - > state = SUB_STATE_NOSUB ;
2009-03-22 05:15:17 +00:00
2008-11-24 15:52:55 +00:00
/* not tested .. */
nua_unsubscribe ( gateway_ptr - > nh ,
2009-06-03 22:00:49 +00:00
NUTAG_URL ( gateway_ptr - > register_url ) ,
TAG_IF ( user_via , SIPTAG_VIA_STR ( user_via ) ) ,
SIPTAG_EVENT_STR ( gw_sub_ptr - > event ) ,
SIPTAG_ACCEPT_STR ( gw_sub_ptr - > content_type ) ,
SIPTAG_TO_STR ( gateway_ptr - > register_from ) ,
2010-02-06 03:38:24 +00:00
SIPTAG_FROM_STR ( gateway_ptr - > register_from ) , SIPTAG_CONTACT_STR ( gateway_ptr - > register_contact ) , TAG_NULL ( ) ) ;
2008-11-24 15:52:55 +00:00
break ;
case SUB_STATE_UNSUBED :
2009-03-22 05:15:17 +00:00
gateway_ptr - > sub_nh = nua_handle ( gateway_ptr - > profile - > nua , NULL ,
NUTAG_URL ( gateway_ptr - > register_proxy ) ,
2009-06-03 22:00:49 +00:00
TAG_IF ( user_via , SIPTAG_VIA_STR ( user_via ) ) ,
2009-03-22 05:15:17 +00:00
SIPTAG_TO_STR ( gateway_ptr - > register_to ) ,
2010-02-06 03:38:24 +00:00
NUTAG_CALLSTATE_REF ( ss_state ) , SIPTAG_FROM_STR ( gateway_ptr - > register_from ) , TAG_END ( ) ) ;
2009-03-22 05:15:17 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " subscribing to [%s] on gateway [%s] \n " , gw_sub_ptr - > event , gateway_ptr - > name ) ;
2010-02-06 03:38:24 +00:00
2008-11-24 15:52:55 +00:00
gateway_ptr - > sofia_private = malloc ( sizeof ( * gateway_ptr - > sofia_private ) ) ;
switch_assert ( gateway_ptr - > sofia_private ) ;
2010-02-06 03:38:24 +00:00
2008-11-24 15:52:55 +00:00
memset ( gateway_ptr - > sofia_private , 0 , sizeof ( * gateway_ptr - > sofia_private ) ) ;
gateway_ptr - > sofia_private - > gateway = gateway_ptr ;
nua_handle_bind ( gateway_ptr - > nh , gateway_ptr - > sofia_private ) ;
if ( now ) {
2010-02-06 03:38:24 +00:00
nua_subscribe ( gateway_ptr - > sub_nh , NUTAG_URL ( gateway_ptr - > register_url ) , TAG_IF ( user_via , SIPTAG_VIA_STR ( user_via ) ) , SIPTAG_EVENT_STR ( gw_sub_ptr - > event ) , SIPTAG_ACCEPT_STR ( gw_sub_ptr - > content_type ) , SIPTAG_TO_STR ( gateway_ptr - > register_from ) , SIPTAG_FROM_STR ( gateway_ptr - > register_from ) , SIPTAG_CONTACT_STR ( gateway_ptr - > register_contact ) , SIPTAG_EXPIRES_STR ( gw_sub_ptr - > expires_str ) , // sofia stack bases its auto-refresh stuff on this
2009-06-03 22:00:49 +00:00
TAG_NULL ( ) ) ;
2008-11-24 15:52:55 +00:00
gw_sub_ptr - > retry = now + gw_sub_ptr - > retry_seconds ;
} else {
2009-03-22 05:15:17 +00:00
nua_unsubscribe ( gateway_ptr - > sub_nh ,
2009-06-03 22:00:49 +00:00
NUTAG_URL ( gateway_ptr - > register_url ) ,
TAG_IF ( user_via , SIPTAG_VIA_STR ( user_via ) ) ,
SIPTAG_EVENT_STR ( gw_sub_ptr - > event ) ,
SIPTAG_ACCEPT_STR ( gw_sub_ptr - > content_type ) ,
SIPTAG_FROM_STR ( gateway_ptr - > register_from ) ,
SIPTAG_TO_STR ( gateway_ptr - > register_from ) ,
2010-02-06 03:38:24 +00:00
SIPTAG_CONTACT_STR ( gateway_ptr - > register_contact ) , SIPTAG_EXPIRES_STR ( gw_sub_ptr - > expires_str ) , TAG_NULL ( ) ) ;
2008-11-24 15:52:55 +00:00
}
gw_sub_ptr - > state = SUB_STATE_TRYING ;
break ;
2010-02-06 03:38:24 +00:00
2008-11-24 15:52:55 +00:00
case SUB_STATE_FAILED :
case SUB_STATE_TRYING :
if ( gw_sub_ptr - > retry & & now > = gw_sub_ptr - > retry ) {
gw_sub_ptr - > state = SUB_STATE_UNSUBED ;
gw_sub_ptr - > retry = 0 ;
}
break ;
default :
if ( now > = gw_sub_ptr - > expires ) {
gw_sub_ptr - > state = SUB_STATE_UNSUBED ;
}
break ;
}
2009-06-03 22:00:49 +00:00
switch_safe_free ( user_via ) ;
2008-11-24 15:52:55 +00:00
}
}
2010-03-25 00:28:56 +00:00
switch_mutex_unlock ( mod_sofia_globals . hash_mutex ) ;
2008-11-24 15:52:55 +00:00
}
2007-04-04 03:08:17 +00:00
void sofia_reg_check_gateway ( sofia_profile_t * profile , time_t now )
2007-03-31 19:01:33 +00:00
{
2008-07-08 22:05:34 +00:00
sofia_gateway_t * gateway_ptr , * last = NULL ;
2010-01-23 19:08:44 +00:00
switch_event_t * event ;
2010-02-18 22:39:08 +00:00
char * pkey ;
2008-07-08 22:05:34 +00:00
2010-03-25 00:28:56 +00:00
switch_mutex_lock ( mod_sofia_globals . hash_mutex ) ;
2008-07-08 22:05:34 +00:00
for ( gateway_ptr = profile - > gateways ; gateway_ptr ; gateway_ptr = gateway_ptr - > next ) {
if ( gateway_ptr - > deleted & & gateway_ptr - > state = = REG_STATE_NOREG ) {
if ( last ) {
last - > next = gateway_ptr - > next ;
} else {
profile - > gateways = gateway_ptr - > next ;
}
2010-02-18 22:39:08 +00:00
pkey = switch_mprintf ( " %s::%s " , profile - > name , gateway_ptr - > name ) ;
2008-07-08 22:05:34 +00:00
2010-02-18 22:39:08 +00:00
switch_core_hash_delete ( mod_sofia_globals . gateway_hash , pkey ) ;
2008-07-08 22:05:34 +00:00
switch_core_hash_delete ( mod_sofia_globals . gateway_hash , gateway_ptr - > name ) ;
2010-02-18 22:39:08 +00:00
free ( pkey ) ;
2008-10-11 05:42:52 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " Deleted gateway %s \n " , gateway_ptr - > name ) ;
2010-01-23 19:08:44 +00:00
if ( switch_event_create_subclass ( & event , SWITCH_EVENT_CUSTOM , MY_EVENT_GATEWAY_DEL ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " profile-name " , gateway_ptr - > profile - > name ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Gateway " , gateway_ptr - > name ) ;
switch_event_fire ( & event ) ;
}
2009-01-23 20:33:30 +00:00
if ( gateway_ptr - > ob_vars ) {
switch_event_destroy ( & gateway_ptr - > ob_vars ) ;
}
if ( gateway_ptr - > ib_vars ) {
switch_event_destroy ( & gateway_ptr - > ib_vars ) ;
2008-10-21 22:40:20 +00:00
}
2008-07-09 17:54:03 +00:00
} else {
last = gateway_ptr ;
2008-07-08 22:05:34 +00:00
}
}
2007-03-31 19:01:33 +00:00
for ( gateway_ptr = profile - > gateways ; gateway_ptr ; gateway_ptr = gateway_ptr - > next ) {
reg_state_t ostate = gateway_ptr - > state ;
2009-06-03 22:00:49 +00:00
char * user_via = NULL ;
2007-03-31 19:01:33 +00:00
2007-04-29 01:16:49 +00:00
if ( ! now ) {
gateway_ptr - > state = ostate = REG_STATE_UNREGED ;
gateway_ptr - > expires_str = " 0 " ;
}
2009-07-14 19:32:42 +00:00
if ( gateway_ptr - > ping & & ! gateway_ptr - > pinging & & ( now > = gateway_ptr - > ping & & ( ostate = = REG_STATE_NOREG | | ostate = = REG_STATE_REGED ) ) & &
! gateway_ptr - > deleted ) {
2009-07-14 18:25:38 +00:00
nua_handle_t * nh = nua_handle ( profile - > nua , NULL , NUTAG_URL ( gateway_ptr - > register_url ) , TAG_END ( ) ) ;
2008-04-30 22:09:54 +00:00
sofia_private_t * pvt ;
2009-07-14 23:39:57 +00:00
if ( sofia_glue_check_nat ( gateway_ptr - > profile , gateway_ptr - > register_proxy ) ) {
user_via = sofia_glue_create_external_via ( NULL , gateway_ptr - > profile , gateway_ptr - > register_transport ) ;
}
2008-04-30 22:09:54 +00:00
pvt = malloc ( sizeof ( * pvt ) ) ;
switch_assert ( pvt ) ;
memset ( pvt , 0 , sizeof ( * pvt ) ) ;
2008-05-07 14:22:36 +00:00
pvt - > destroy_nh = 1 ;
2009-03-22 05:15:17 +00:00
pvt - > destroy_me = 1 ;
2008-04-30 22:09:54 +00:00
switch_copy_string ( pvt - > gateway_name , gateway_ptr - > name , sizeof ( pvt - > gateway_name ) ) ;
nua_handle_bind ( nh , pvt ) ;
gateway_ptr - > pinging = 1 ;
2010-02-06 03:38:24 +00:00
nua_options ( nh ,
2009-07-14 18:25:38 +00:00
TAG_IF ( gateway_ptr - > register_sticky_proxy , NUTAG_PROXY ( gateway_ptr - > register_sticky_proxy ) ) ,
2009-07-14 23:39:57 +00:00
TAG_IF ( user_via , SIPTAG_VIA_STR ( user_via ) ) ,
2009-07-14 18:25:38 +00:00
SIPTAG_TO_STR ( gateway_ptr - > register_from ) ,
2010-02-06 03:38:24 +00:00
SIPTAG_CONTACT_STR ( gateway_ptr - > register_contact ) , SIPTAG_FROM_STR ( gateway_ptr - > register_from ) , TAG_END ( ) ) ;
2009-07-14 23:39:57 +00:00
switch_safe_free ( user_via ) ;
user_via = NULL ;
2008-04-30 22:09:54 +00:00
}
2008-05-27 04:54:52 +00:00
2007-03-31 19:01:33 +00:00
switch ( ostate ) {
2007-04-07 03:04:46 +00:00
case REG_STATE_NOREG :
2008-11-24 16:56:21 +00:00
if ( ! gateway_ptr - > ping & & ! gateway_ptr - > pinging ) {
gateway_ptr - > status = SOFIA_GATEWAY_UP ;
}
2007-04-07 03:04:46 +00:00
break ;
2007-03-31 19:01:33 +00:00
case REG_STATE_REGISTER :
2008-10-12 03:56:11 +00:00
if ( profile - > debug ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Registered %s \n " , gateway_ptr - > name ) ;
}
2008-11-24 16:56:21 +00:00
gateway_ptr - > failures = 0 ;
if ( gateway_ptr - > freq > 60 ) {
2008-10-07 22:15:51 +00:00
gateway_ptr - > expires = now + ( gateway_ptr - > freq - 15 ) ;
} else {
gateway_ptr - > expires = now + ( gateway_ptr - > freq - 2 ) ;
}
2007-03-31 19:01:33 +00:00
gateway_ptr - > state = REG_STATE_REGED ;
2008-04-30 22:09:54 +00:00
gateway_ptr - > status = SOFIA_GATEWAY_UP ;
2007-03-31 19:01:33 +00:00
break ;
2007-09-18 17:31:36 +00:00
case REG_STATE_UNREGISTER :
2009-03-22 05:15:17 +00:00
sofia_reg_kill_reg ( gateway_ptr ) ;
2007-09-18 17:31:36 +00:00
gateway_ptr - > state = REG_STATE_NOREG ;
break ;
2007-03-31 19:01:33 +00:00
case REG_STATE_UNREGED :
2008-05-07 20:06:46 +00:00
gateway_ptr - > status = SOFIA_GATEWAY_DOWN ;
2009-12-02 20:47:46 +00:00
gateway_ptr - > retry = 0 ;
2010-02-06 03:38:24 +00:00
2010-02-16 00:07:50 +00:00
if ( ! gateway_ptr - > nh ) {
2010-02-06 03:38:24 +00:00
sofia_reg_new_handle ( gateway_ptr , now ? 1 : 0 ) ;
2010-02-16 00:07:50 +00:00
}
2009-06-03 22:00:49 +00:00
2009-06-04 05:43:34 +00:00
if ( sofia_glue_check_nat ( gateway_ptr - > profile , gateway_ptr - > register_proxy ) ) {
user_via = sofia_glue_create_external_via ( NULL , gateway_ptr - > profile , gateway_ptr - > register_transport ) ;
}
2009-06-03 22:00:49 +00:00
2009-03-22 05:15:17 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " Registering %s \n " , gateway_ptr - > name ) ;
2010-02-06 03:38:24 +00:00
2009-03-22 05:15:17 +00:00
if ( now ) {
nua_register ( gateway_ptr - > nh ,
NUTAG_URL ( gateway_ptr - > register_url ) ,
TAG_IF ( gateway_ptr - > register_sticky_proxy , NUTAG_PROXY ( gateway_ptr - > register_sticky_proxy ) ) ,
2009-06-03 22:00:49 +00:00
TAG_IF ( user_via , SIPTAG_VIA_STR ( user_via ) ) ,
2009-11-03 23:21:02 +00:00
SIPTAG_TO_STR ( gateway_ptr - > distinct_to ? gateway_ptr - > register_to : gateway_ptr - > register_from ) ,
2009-03-22 05:15:17 +00:00
SIPTAG_CONTACT_STR ( gateway_ptr - > register_contact ) ,
2010-02-06 03:38:24 +00:00
SIPTAG_FROM_STR ( gateway_ptr - > register_from ) ,
2009-03-22 05:15:17 +00:00
SIPTAG_EXPIRES_STR ( gateway_ptr - > expires_str ) ,
NUTAG_REGISTRAR ( gateway_ptr - > register_proxy ) ,
NUTAG_OUTBOUND ( " no-options-keepalive " ) , NUTAG_OUTBOUND ( " no-validate " ) , NUTAG_KEEPALIVE ( 0 ) , TAG_NULL ( ) ) ;
2008-11-24 16:56:21 +00:00
gateway_ptr - > retry = now + gateway_ptr - > retry_seconds ;
2007-03-31 19:01:33 +00:00
} else {
2009-03-22 05:15:17 +00:00
nua_unregister ( gateway_ptr - > nh ,
NUTAG_URL ( gateway_ptr - > register_url ) ,
2009-06-03 22:00:49 +00:00
TAG_IF ( user_via , SIPTAG_VIA_STR ( user_via ) ) ,
2009-03-22 05:15:17 +00:00
SIPTAG_FROM_STR ( gateway_ptr - > register_from ) ,
2009-11-03 23:21:02 +00:00
SIPTAG_TO_STR ( gateway_ptr - > distinct_to ? gateway_ptr - > register_to : gateway_ptr - > register_from ) ,
2009-03-22 05:15:17 +00:00
SIPTAG_EXPIRES_STR ( gateway_ptr - > expires_str ) ,
NUTAG_REGISTRAR ( gateway_ptr - > register_proxy ) ,
NUTAG_OUTBOUND ( " no-options-keepalive " ) , NUTAG_OUTBOUND ( " no-validate " ) , NUTAG_KEEPALIVE ( 0 ) , TAG_NULL ( ) ) ;
2007-03-31 19:01:33 +00:00
}
2009-03-22 05:15:17 +00:00
gateway_ptr - > retry = now + gateway_ptr - > retry_seconds ;
2010-02-06 03:38:24 +00:00
gateway_ptr - > state = REG_STATE_TRYING ;
2009-07-14 23:39:57 +00:00
switch_safe_free ( user_via ) ;
user_via = NULL ;
2007-03-31 19:01:33 +00:00
break ;
2007-05-10 16:15:07 +00:00
case REG_STATE_FAILED :
2009-12-02 20:47:46 +00:00
{
2009-12-11 22:21:29 +00:00
int sec ;
2009-12-02 20:47:46 +00:00
if ( gateway_ptr - > failure_status = = 503 ) {
2009-12-11 22:21:29 +00:00
sec = gateway_ptr - > retry_seconds ;
2010-02-06 03:38:24 +00:00
} else {
2009-12-02 20:47:46 +00:00
sec = gateway_ptr - > retry_seconds * ( gateway_ptr - > failures + 1 ) ;
}
2010-02-06 03:38:24 +00:00
2010-01-08 17:42:56 +00:00
gateway_ptr - > retry = switch_epoch_time_now ( NULL ) + sec ;
2009-12-02 20:47:46 +00:00
gateway_ptr - > status = SOFIA_GATEWAY_DOWN ;
gateway_ptr - > state = REG_STATE_FAIL_WAIT ;
gateway_ptr - > failure_status = 0 ;
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " %s Failed Registration, setting retry to %d seconds. \n " ,
2009-12-11 22:21:29 +00:00
gateway_ptr - > name , sec ) ;
2009-12-02 20:47:46 +00:00
}
2008-11-24 16:56:21 +00:00
break ;
case REG_STATE_FAIL_WAIT :
if ( ! gateway_ptr - > retry | | now > = gateway_ptr - > retry ) {
2007-03-31 19:01:33 +00:00
gateway_ptr - > state = REG_STATE_UNREGED ;
2008-11-24 16:56:21 +00:00
}
break ;
case REG_STATE_TRYING :
if ( ! gateway_ptr - > retry | | now > = gateway_ptr - > retry ) {
gateway_ptr - > state = REG_STATE_FAILED ;
2007-03-31 19:01:33 +00:00
}
break ;
default :
if ( now > = gateway_ptr - > expires ) {
gateway_ptr - > state = REG_STATE_UNREGED ;
}
break ;
}
2008-10-10 15:36:02 +00:00
if ( ostate ! = gateway_ptr - > state ) {
2010-01-15 15:18:07 +00:00
sofia_reg_fire_custom_gateway_state_event ( gateway_ptr , 0 , NULL ) ;
2008-10-10 15:36:02 +00:00
}
2007-03-31 19:01:33 +00:00
}
2010-03-25 00:28:56 +00:00
switch_mutex_unlock ( mod_sofia_globals . hash_mutex ) ;
2007-03-31 19:01:33 +00:00
}
int sofia_reg_find_callback ( void * pArg , int argc , char * * argv , char * * columnNames )
{
struct callback_t * cbt = ( struct callback_t * ) pArg ;
2010-08-18 14:58:14 -05:00
if ( ! cbt - > len ) {
switch_console_push_match ( & cbt - > list , argv [ 0 ] ) ;
cbt - > matches + + ;
return 0 ;
}
2007-03-31 19:01:33 +00:00
switch_copy_string ( cbt - > val , argv [ 0 ] , cbt - > len ) ;
cbt - > matches + + ;
2010-08-18 14:58:14 -05:00
return cbt - > matches = = 1 ? 0 : 1 ;
2007-03-31 19:01:33 +00:00
}
2007-05-22 15:03:21 +00:00
int sofia_reg_nat_callback ( void * pArg , int argc , char * * argv , char * * columnNames )
{
sofia_profile_t * profile = ( sofia_profile_t * ) pArg ;
nua_handle_t * nh ;
char to [ 128 ] = " " ;
2009-06-19 15:48:23 +00:00
sofia_destination_t * dst = NULL ;
2007-05-22 15:03:21 +00:00
2008-04-14 16:10:18 +00:00
switch_snprintf ( to , sizeof ( to ) , " sip:%s@%s " , argv [ 1 ] , argv [ 2 ] ) ;
2009-06-19 15:48:23 +00:00
dst = sofia_glue_get_destination ( argv [ 3 ] ) ;
switch_assert ( dst ) ;
2010-09-15 15:38:25 -05:00
2010-02-06 03:38:24 +00:00
nh = nua_handle ( profile - > nua , NULL , SIPTAG_FROM_STR ( profile - > url ) , SIPTAG_TO_STR ( to ) , NUTAG_URL ( dst - > contact ) , SIPTAG_CONTACT_STR ( profile - > url ) ,
TAG_END ( ) ) ;
2008-05-07 14:22:36 +00:00
nua_handle_bind ( nh , & mod_sofia_globals . destroy_private ) ;
2010-09-15 15:38:25 -05:00
nua_options ( nh ,
NTATAG_SIP_T2 ( 5000 ) ,
NTATAG_SIP_T4 ( 10000 ) ,
TAG_IF ( dst - > route_uri , NUTAG_PROXY ( dst - > route_uri ) ) , TAG_IF ( dst - > route , SIPTAG_ROUTE_STR ( dst - > route ) ) , TAG_END ( ) ) ;
2007-10-28 16:07:23 +00:00
2009-06-19 15:48:23 +00:00
sofia_glue_free_destination ( dst ) ;
2008-05-27 04:54:52 +00:00
2007-05-22 15:03:21 +00:00
return 0 ;
}
2008-05-07 20:06:46 +00:00
int sofia_sub_del_callback ( void * pArg , int argc , char * * argv , char * * columnNames )
{
sofia_profile_t * profile = ( sofia_profile_t * ) pArg ;
nua_handle_t * nh ;
if ( argv [ 0 ] ) {
if ( ( nh = nua_handle_by_call_id ( profile - > nua , argv [ 0 ] ) ) ) {
nua_handle_destroy ( nh ) ;
}
}
return 0 ;
}
2010-02-06 03:38:24 +00:00
void sofia_reg_send_reboot ( sofia_profile_t * profile , const char * user , const char * host , const char * contact , const char * user_agent ,
const char * network_ip )
2008-07-17 20:47:42 +00:00
{
const char * event = " check-sync " ;
2009-08-21 00:59:09 +00:00
const char * contenttype = " application/simple-message-summary " ;
const char * body = " " ;
2008-07-17 20:47:42 +00:00
if ( switch_stristr ( " snom " , user_agent ) ) {
event = " check-sync;reboot=true " ;
} else if ( switch_stristr ( " linksys " , user_agent ) ) {
event = " reboot_now " ;
2010-01-13 15:57:58 +00:00
} else if ( switch_stristr ( " spa " , user_agent ) ) {
event = " reboot " ;
2008-07-17 20:47:42 +00:00
}
2009-08-21 00:59:09 +00:00
sofia_glue_send_notify ( profile , user , host , event , contenttype , body , contact , network_ip ) ;
2008-07-17 20:47:42 +00:00
}
2009-03-22 05:15:17 +00:00
int sofia_sla_dialog_del_callback ( void * pArg , int argc , char * * argv , char * * columnNames )
{
sofia_profile_t * profile = ( sofia_profile_t * ) pArg ;
nua_handle_t * nh = NULL ;
if ( ( nh = nua_handle_by_call_id ( profile - > nua , argv [ 0 ] ) ) ) {
nua_handle_destroy ( nh ) ;
}
2010-02-06 03:38:24 +00:00
2009-03-22 05:15:17 +00:00
return 0 ;
}
2008-07-17 20:47:42 +00:00
2007-03-31 19:01:33 +00:00
int sofia_reg_del_callback ( void * pArg , int argc , char * * argv , char * * columnNames )
{
switch_event_t * s_event ;
2008-07-17 20:47:42 +00:00
sofia_profile_t * profile = ( sofia_profile_t * ) pArg ;
2010-02-06 03:38:24 +00:00
2009-06-03 21:08:34 +00:00
if ( argc > 12 & & atoi ( argv [ 12 ] ) = = 1 ) {
sofia_reg_send_reboot ( profile , argv [ 1 ] , argv [ 2 ] , argv [ 3 ] , argv [ 7 ] , argv [ 11 ] ) ;
2008-07-17 20:47:42 +00:00
}
2007-03-31 19:01:33 +00:00
if ( argc > = 3 ) {
if ( switch_event_create_subclass ( & s_event , SWITCH_EVENT_CUSTOM , MY_EVENT_EXPIRE ) = = SWITCH_STATUS_SUCCESS ) {
2009-02-10 18:30:49 +00:00
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " profile-name " , argv [ 10 ] ) ;
2008-08-16 02:19:43 +00:00
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " call-id " , argv [ 0 ] ) ;
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " user " , argv [ 1 ] ) ;
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " host " , argv [ 2 ] ) ;
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " contact " , argv [ 3 ] ) ;
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " expires " , argv [ 6 ] ) ;
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " user-agent " , argv [ 7 ] ) ;
2007-03-31 19:01:33 +00:00
switch_event_fire ( & s_event ) ;
}
2010-02-03 19:40:24 +00:00
2010-09-15 15:38:25 -05:00
if ( switch_event_create ( & s_event , SWITCH_EVENT_PRESENCE_IN ) = = SWITCH_STATUS_SUCCESS ) {
2010-02-03 19:40:24 +00:00
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " proto " , SOFIA_CHAT_PROTO ) ;
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " rpid " , " away " ) ;
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " login " , profile - > url ) ;
if ( argv [ 4 ] ) {
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " user-agent " , argv [ 4 ] ) ;
}
if ( argv [ 1 ] & & argv [ 2 ] ) {
switch_event_add_header ( s_event , SWITCH_STACK_BOTTOM , " from " , " %s@%s " , argv [ 1 ] , argv [ 2 ] ) ;
}
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " status " , " Unregistered " ) ;
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " event_type " , " presence " ) ;
switch_event_fire ( & s_event ) ;
}
2007-03-31 19:01:33 +00:00
}
return 0 ;
}
2008-07-17 20:47:42 +00:00
void sofia_reg_expire_call_id ( sofia_profile_t * profile , const char * call_id , int reboot )
2008-03-25 22:06:48 +00:00
{
2009-08-11 01:26:51 +00:00
char * sql = NULL ;
char * sqlextra = NULL ;
2009-05-15 19:36:43 +00:00
char * dup = strdup ( call_id ) ;
char * host = NULL , * user = NULL ;
2008-07-17 20:47:42 +00:00
2009-05-15 19:36:43 +00:00
switch_assert ( dup ) ;
2008-05-27 04:54:52 +00:00
2009-05-15 19:36:43 +00:00
if ( ( host = strchr ( dup , ' @ ' ) ) ) {
2008-07-17 20:47:42 +00:00
* host + + = ' \0 ' ;
2009-05-15 19:36:43 +00:00
user = dup ;
} else {
host = dup ;
2008-07-17 20:47:42 +00:00
}
2009-05-15 19:36:43 +00:00
2008-07-17 20:47:42 +00:00
if ( ! host ) {
host = " none " ;
}
2009-10-23 16:03:42 +00:00
if ( zstr ( user ) ) {
2009-08-11 01:26:51 +00:00
sqlextra = switch_mprintf ( " or (sip_host='%q') " , host ) ;
2009-05-15 19:36:43 +00:00
} else {
2009-08-11 01:26:51 +00:00
sqlextra = switch_mprintf ( " or (sip_user='%q' and sip_host='%q') " , user , host ) ;
2009-05-15 19:36:43 +00:00
}
2009-08-11 01:26:51 +00:00
sql = switch_mprintf ( " select call_id,sip_user,sip_host,contact,status,rpid,expires "
2010-02-06 03:38:24 +00:00
" ,user_agent,server_user,server_host,profile_name,network_ip "
" ,%d from sip_registrations where call_id='%q' %s " , reboot , call_id , sqlextra ) ;
2009-08-11 01:26:51 +00:00
switch_safe_free ( sqlextra ) ;
2010-02-06 03:38:24 +00:00
2008-03-25 22:06:48 +00:00
switch_mutex_lock ( profile - > ireg_mutex ) ;
2009-11-12 03:52:07 +00:00
sofia_glue_execute_sql_callback ( profile , NULL , sql , sofia_reg_del_callback , profile ) ;
2008-03-25 22:06:48 +00:00
switch_mutex_unlock ( profile - > ireg_mutex ) ;
2009-08-11 01:26:51 +00:00
switch_safe_free ( sql ) ;
2010-02-06 03:38:24 +00:00
sql = switch_mprintf ( " delete from sip_registrations where call_id='%q' or (sip_user='%q' and sip_host='%q') " , call_id , user , host ) ;
2010-07-29 23:39:39 -05:00
sofia_glue_execute_sql_now ( profile , & sql , SWITCH_FALSE ) ;
2008-07-17 20:47:42 +00:00
2009-08-11 01:26:51 +00:00
switch_safe_free ( sql ) ;
2009-05-15 19:36:43 +00:00
switch_safe_free ( dup ) ;
2008-07-17 20:47:42 +00:00
2008-03-25 22:06:48 +00:00
}
2007-05-22 15:03:21 +00:00
2008-07-17 20:47:42 +00:00
void sofia_reg_check_expire ( sofia_profile_t * profile , time_t now , int reboot )
2007-03-31 19:01:33 +00:00
{
char sql [ 1024 ] ;
2008-05-07 20:06:46 +00:00
switch_mutex_lock ( profile - > ireg_mutex ) ;
2007-04-29 01:16:49 +00:00
if ( now ) {
2009-06-03 21:08:34 +00:00
switch_snprintf ( sql , sizeof ( sql ) , " select call_id,sip_user,sip_host,contact,status,rpid,expires "
" ,user_agent,server_user,server_host,profile_name,network_ip "
2008-09-18 00:01:03 +00:00
" ,%d from sip_registrations where expires > 0 and expires <= %ld " , reboot , ( long ) now ) ;
2007-04-29 01:16:49 +00:00
} else {
2009-06-03 21:08:34 +00:00
switch_snprintf ( sql , sizeof ( sql ) , " select call_id,sip_user,sip_host,contact,status,rpid,expires "
2010-02-06 03:38:24 +00:00
" ,user_agent,server_user,server_host,profile_name,network_ip " " ,%d from sip_registrations where expires > 0 " , reboot ) ;
2007-04-29 01:16:49 +00:00
}
2007-03-31 19:01:33 +00:00
2009-11-12 03:52:07 +00:00
sofia_glue_execute_sql_callback ( profile , NULL , sql , sofia_reg_del_callback , profile ) ;
2007-04-29 01:16:49 +00:00
if ( now ) {
2010-02-06 03:38:24 +00:00
switch_snprintf ( sql , sizeof ( sql ) , " delete from sip_registrations where expires > 0 and expires <= %ld and hostname='%s' " ,
2008-09-18 00:01:03 +00:00
( long ) now , mod_sofia_globals . hostname ) ;
2007-04-29 01:16:49 +00:00
} else {
2008-09-23 00:10:19 +00:00
switch_snprintf ( sql , sizeof ( sql ) , " delete from sip_registrations where expires > 0 and hostname='%s' " , mod_sofia_globals . hostname ) ;
2007-04-29 01:16:49 +00:00
}
2008-04-14 15:07:43 +00:00
2009-11-12 03:52:07 +00:00
sofia_glue_actually_execute_sql ( profile , sql , NULL ) ;
2008-05-27 04:54:52 +00:00
2008-11-22 01:34:19 +00:00
2009-03-22 05:15:17 +00:00
if ( now ) {
switch_snprintf ( sql , sizeof ( sql ) , " select call_id from sip_shared_appearance_dialogs where hostname='%s' "
2010-02-06 03:38:24 +00:00
" and profile_name='%s' and expires <= %ld " , mod_sofia_globals . hostname , profile - > name , ( long ) now ) ;
2009-11-12 03:52:07 +00:00
sofia_glue_execute_sql_callback ( profile , NULL , sql , sofia_sla_dialog_del_callback , profile ) ;
2010-02-06 03:38:24 +00:00
switch_snprintf ( sql , sizeof ( sql ) , " delete from sip_registrations where expires > 0 and hostname='%s' and expires <= %ld " ,
2009-03-22 05:15:17 +00:00
mod_sofia_globals . hostname , ( long ) now ) ;
2009-11-12 03:52:07 +00:00
sofia_glue_actually_execute_sql ( profile , sql , NULL ) ;
2009-03-22 05:15:17 +00:00
}
2008-11-22 01:34:19 +00:00
if ( now ) {
2010-02-06 03:38:24 +00:00
switch_snprintf ( sql , sizeof ( sql ) , " delete from sip_presence where expires > 0 and expires <= %ld and hostname='%s' " ,
2008-11-22 01:34:19 +00:00
( long ) now , mod_sofia_globals . hostname ) ;
} else {
switch_snprintf ( sql , sizeof ( sql ) , " delete from sip_presence where expires > 0 and hostname='%s' " , mod_sofia_globals . hostname ) ;
}
2009-11-12 03:52:07 +00:00
sofia_glue_actually_execute_sql ( profile , sql , NULL ) ;
2008-11-22 01:34:19 +00:00
2007-04-29 01:16:49 +00:00
if ( now ) {
2010-02-06 03:38:24 +00:00
switch_snprintf ( sql , sizeof ( sql ) , " delete from sip_authentication where expires > 0 and expires <= %ld and hostname='%s' " ,
2008-09-18 00:01:03 +00:00
( long ) now , mod_sofia_globals . hostname ) ;
2007-04-29 01:16:49 +00:00
} else {
2008-09-23 00:10:19 +00:00
switch_snprintf ( sql , sizeof ( sql ) , " delete from sip_authentication where expires > 0 and hostname='%s' " , mod_sofia_globals . hostname ) ;
2007-04-29 01:16:49 +00:00
}
2008-04-14 15:07:43 +00:00
2009-11-12 03:52:07 +00:00
sofia_glue_actually_execute_sql ( profile , sql , NULL ) ;
2010-09-15 15:38:25 -05:00
2008-05-07 20:06:46 +00:00
if ( now ) {
2010-02-06 03:38:24 +00:00
switch_snprintf ( sql , sizeof ( sql ) ,
" select call_id from sip_subscriptions where (expires = -1 or (expires > 0 and expires <= %ld)) and hostname='%s' " , ( long ) now ,
2010-01-09 00:34:17 +00:00
mod_sofia_globals . hostname ) ;
2010-02-06 03:38:24 +00:00
} else {
2010-09-15 15:38:25 -05:00
switch_snprintf ( sql , sizeof ( sql ) , " select sub_to_user,sub_to_host,call_id from sip_subscriptions where expires >= -1 and hostname='%s' " ,
mod_sofia_globals . hostname ) ;
2008-05-07 20:06:46 +00:00
}
2009-11-12 03:52:07 +00:00
sofia_glue_execute_sql_callback ( profile , NULL , sql , sofia_sub_del_callback , profile ) ;
2008-05-07 20:06:46 +00:00
2007-04-29 01:16:49 +00:00
if ( now ) {
2010-02-06 03:38:24 +00:00
switch_snprintf ( sql , sizeof ( sql ) , " delete from sip_subscriptions where (expires = -1 or (expires > 0 and expires <= %ld)) and hostname='%s' " ,
2008-09-18 00:01:03 +00:00
( long ) now , mod_sofia_globals . hostname ) ;
2007-04-29 01:16:49 +00:00
} else {
2010-01-09 00:34:17 +00:00
switch_snprintf ( sql , sizeof ( sql ) , " delete from sip_subscriptions where expires >= -1 and hostname='%s' " , mod_sofia_globals . hostname ) ;
}
sofia_glue_actually_execute_sql ( profile , sql , NULL ) ;
if ( now ) {
2010-02-06 03:38:24 +00:00
switch_snprintf ( sql , sizeof ( sql ) , " delete from sip_dialogs where (expires = -1 or (expires > 0 and expires <= %ld)) and hostname='%s' " ,
2010-01-09 00:34:17 +00:00
( long ) now , mod_sofia_globals . hostname ) ;
} else {
switch_snprintf ( sql , sizeof ( sql ) , " delete from sip_dialogs where expires >= -1 and hostname='%s' " , mod_sofia_globals . hostname ) ;
2007-04-29 01:16:49 +00:00
}
2008-04-14 15:07:43 +00:00
2009-11-12 03:52:07 +00:00
sofia_glue_actually_execute_sql ( profile , sql , NULL ) ;
2008-05-27 04:54:52 +00:00
2007-03-31 19:01:33 +00:00
2010-09-15 15:38:25 -05:00
if ( now ) {
if ( sofia_test_pflag ( profile , PFLAG_ALL_REG_OPTIONS_PING ) ) {
switch_snprintf ( sql , sizeof ( sql ) , " select call_id,sip_user,sip_host,contact,status,rpid, "
" expires,user_agent,server_user,server_host,profile_name "
2010-10-15 17:59:00 -05:00
" from sip_registrations where hostname='%s' and "
" profile_name='%s' " , mod_sofia_globals . hostname , profile - > name ) ;
2010-09-15 15:38:25 -05:00
sofia_glue_execute_sql_callback ( profile , NULL , sql , sofia_reg_nat_callback , profile ) ;
} else if ( sofia_test_pflag ( profile , PFLAG_NAT_OPTIONS_PING ) ) {
switch_snprintf ( sql , sizeof ( sql ) , " select call_id,sip_user,sip_host,contact,status,rpid, "
" expires,user_agent,server_user,server_host,profile_name "
" from sip_registrations where (status like '%%NAT%%' "
2010-10-15 17:59:00 -05:00
" or contact like '%%fs_nat=yes%%') and hostname='%s' "
" and profile_name='%s' " , mod_sofia_globals . hostname , profile - > name ) ;
2010-09-15 15:38:25 -05:00
sofia_glue_execute_sql_callback ( profile , NULL , sql , sofia_reg_nat_callback , profile ) ;
}
2007-05-22 15:03:21 +00:00
}
2007-03-31 19:01:33 +00:00
switch_mutex_unlock ( profile - > ireg_mutex ) ;
}
2007-04-04 03:08:17 +00:00
char * sofia_reg_find_reg_url ( sofia_profile_t * profile , const char * user , const char * host , char * val , switch_size_t len )
2007-03-31 19:01:33 +00:00
{
struct callback_t cbt = { 0 } ;
2008-08-12 20:54:51 +00:00
char sql [ 512 ] = " " ;
2007-03-31 19:01:33 +00:00
if ( ! user ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Called with null user! \n " ) ;
return NULL ;
}
cbt . val = val ;
cbt . len = len ;
2007-04-04 03:08:17 +00:00
2007-03-31 19:01:33 +00:00
if ( host ) {
2010-02-06 03:38:24 +00:00
switch_snprintf ( sql , sizeof ( sql ) , " select contact from sip_registrations where sip_user='%s' and (sip_host='%s' or presence_hosts like '%%%s%%') " ,
user , host , host ) ;
2007-03-31 19:01:33 +00:00
} else {
2008-08-12 20:54:51 +00:00
switch_snprintf ( sql , sizeof ( sql ) , " select contact from sip_registrations where sip_user='%s' " , user ) ;
2007-03-31 19:01:33 +00:00
}
2009-11-12 03:52:07 +00:00
sofia_glue_execute_sql_callback ( profile , profile - > ireg_mutex , sql , sofia_reg_find_callback , & cbt ) ;
2007-03-31 19:01:33 +00:00
if ( cbt . matches ) {
return val ;
} else {
return NULL ;
}
}
2007-06-08 22:28:32 +00:00
2010-08-18 14:58:14 -05:00
switch_console_callback_match_t * sofia_reg_find_reg_url_multi ( sofia_profile_t * profile , const char * user , const char * host )
{
struct callback_t cbt = { 0 } ;
char sql [ 512 ] = " " ;
if ( ! user ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Called with null user! \n " ) ;
return NULL ;
}
if ( host ) {
switch_snprintf ( sql , sizeof ( sql ) , " select contact from sip_registrations where sip_user='%s' and (sip_host='%s' or presence_hosts like '%%%s%%') " ,
user , host , host ) ;
} else {
switch_snprintf ( sql , sizeof ( sql ) , " select contact from sip_registrations where sip_user='%s' " , user ) ;
}
sofia_glue_execute_sql_callback ( profile , profile - > ireg_mutex , sql , sofia_reg_find_callback , & cbt ) ;
return cbt . list ;
}
2008-09-02 03:46:27 +00:00
void sofia_reg_auth_challenge ( nua_t * nua , sofia_profile_t * profile , nua_handle_t * nh , sofia_regtype_t regtype , const char * realm , int stale )
2007-06-08 22:28:32 +00:00
{
switch_uuid_t uuid ;
char uuid_str [ SWITCH_UUID_FORMATTED_LENGTH + 1 ] ;
char * sql , * auth_str ;
switch_uuid_get ( & uuid ) ;
switch_uuid_format ( uuid_str , & uuid ) ;
2009-10-28 16:55:29 +00:00
sql = switch_mprintf ( " insert into sip_authentication (nonce,expires,profile_name,hostname, last_nc) "
2010-02-06 03:38:24 +00:00
" values('%q', %ld, '%q', '%q', 0) " , uuid_str ,
switch_epoch_time_now ( NULL ) + ( profile - > nonce_ttl ? profile - > nonce_ttl : DEFAULT_NONCE_TTL ) ,
2009-10-28 16:55:29 +00:00
profile - > name , mod_sofia_globals . hostname ) ;
2007-12-12 23:21:45 +00:00
switch_assert ( sql ! = NULL ) ;
2009-11-12 03:52:07 +00:00
sofia_glue_actually_execute_sql ( profile , sql , profile - > ireg_mutex ) ;
2008-04-08 15:36:58 +00:00
switch_safe_free ( sql ) ;
2007-06-08 22:28:32 +00:00
2009-11-23 16:49:05 +00:00
auth_str = switch_mprintf ( " Digest realm= \" %q \" , nonce= \" %q \" ,%s algorithm=MD5, qop= \" auth \" " , realm , uuid_str , stale ? " stale=true, " : " " ) ;
2007-06-08 22:28:32 +00:00
if ( regtype = = REG_REGISTER ) {
2008-05-27 04:54:52 +00:00
nua_respond ( nh , SIP_401_UNAUTHORIZED , TAG_IF ( nua , NUTAG_WITH_THIS ( nua ) ) , SIPTAG_WWW_AUTHENTICATE_STR ( auth_str ) , TAG_END ( ) ) ;
2007-06-08 22:28:32 +00:00
} else if ( regtype = = REG_INVITE ) {
2008-05-27 04:54:52 +00:00
nua_respond ( nh , SIP_407_PROXY_AUTH_REQUIRED , TAG_IF ( nua , NUTAG_WITH_THIS ( nua ) ) , SIPTAG_PROXY_AUTHENTICATE_STR ( auth_str ) , TAG_END ( ) ) ;
2007-06-08 22:28:32 +00:00
}
switch_safe_free ( auth_str ) ;
}
2008-05-27 04:54:52 +00:00
uint8_t sofia_reg_handle_register ( nua_t * nua , sofia_profile_t * profile , nua_handle_t * nh , sip_t const * sip , sofia_regtype_t regtype , char * key ,
2008-05-21 21:49:27 +00:00
uint32_t keylen , switch_event_t * * v_event , const char * is_nat )
2007-03-31 19:01:33 +00:00
{
2007-06-05 17:42:15 +00:00
sip_to_t const * to = NULL ;
2008-07-16 19:42:40 +00:00
sip_from_t const * from = NULL ;
2007-03-31 19:01:33 +00:00
sip_expires_t const * expires = NULL ;
sip_authorization_t const * authorization = NULL ;
sip_contact_t const * contact = NULL ;
2009-10-27 06:14:00 +00:00
char * sql ;
2007-03-31 19:01:33 +00:00
switch_event_t * s_event ;
2007-06-05 17:42:15 +00:00
const char * to_user = NULL ;
const char * to_host = NULL ;
2009-09-25 20:07:40 +00:00
char * mwi_account = NULL ;
char * dup_mwi_account = NULL ;
char * mwi_user = NULL ;
char * mwi_host = NULL ;
2009-10-21 23:09:41 +00:00
char * var = NULL ;
2008-07-16 19:42:40 +00:00
const char * from_user = NULL ;
const char * from_host = NULL ;
2008-09-08 22:38:37 +00:00
const char * reg_host = profile - > reg_db_domain ;
2010-09-02 16:01:50 -05:00
const char * sub_host = profile - > sub_domain ;
2007-03-31 19:01:33 +00:00
char contact_str [ 1024 ] = " " ;
2008-05-20 17:44:55 +00:00
int nat_hack = 0 ;
2008-10-22 17:40:43 +00:00
uint8_t multi_reg = 0 , multi_reg_contact = 0 , avoid_multi_reg = 0 ;
2007-04-20 18:06:06 +00:00
uint8_t stale = 0 , forbidden = 0 ;
2007-03-31 19:01:33 +00:00
auth_res_t auth_res ;
2009-04-30 00:09:41 +00:00
long exptime = 300 ;
2007-03-31 19:01:33 +00:00
switch_event_t * event ;
const char * rpid = " unknown " ;
const char * display = " \" user \" " ;
2007-04-20 18:06:06 +00:00
char network_ip [ 80 ] ;
2009-03-04 19:45:10 +00:00
char network_port_c [ 6 ] ;
2008-07-03 18:50:15 +00:00
char url_ip [ 80 ] ;
2007-09-18 17:31:36 +00:00
char * register_gateway = NULL ;
2007-05-21 19:11:37 +00:00
int network_port ;
2008-01-17 17:37:49 +00:00
const char * reg_desc = " Registered " ;
2007-10-24 23:20:47 +00:00
const char * call_id = NULL ;
2008-01-12 19:15:05 +00:00
char * force_user ;
2008-05-23 12:23:06 +00:00
char received_data [ 128 ] = " " ;
2008-06-26 20:19:09 +00:00
char * path_val = NULL ;
2009-03-25 20:14:07 +00:00
switch_event_t * auth_params = NULL ;
int r = 0 ;
2009-11-12 03:52:07 +00:00
long reg_count = 0 ;
2010-10-01 09:30:32 -05:00
int delete_subs ;
2010-09-15 15:38:25 -05:00
const char * agent = " unknown " ;
2010-10-01 09:30:32 -05:00
delete_subs = sofia_test_pflag ( profile , PFLAG_DEL_SUBS_ON_REG ) ;
2008-07-03 18:50:15 +00:00
2007-03-31 19:01:33 +00:00
/* all callers must confirm that sip, sip->sip_request and sip->sip_contact are not NULL */
2007-12-12 23:21:45 +00:00
switch_assert ( sip ! = NULL & & sip - > sip_contact ! = NULL & & sip - > sip_request ! = NULL ) ;
2007-03-31 19:01:33 +00:00
2010-02-06 03:38:24 +00:00
sofia_glue_get_addr ( nua_current_request ( nua ) , network_ip , sizeof ( network_ip ) , & network_port ) ;
2008-07-03 18:50:15 +00:00
2009-03-04 19:45:10 +00:00
snprintf ( network_port_c , sizeof ( network_port_c ) , " %d " , network_port ) ;
2009-06-03 21:08:34 +00:00
snprintf ( url_ip , sizeof ( url_ip ) , ( msg_addrinfo ( nua_current_request ( nua ) ) ) - > ai_addr - > sa_family = = AF_INET6 ? " [%s] " : " %s " , network_ip ) ;
2008-05-27 04:54:52 +00:00
2007-03-31 19:01:33 +00:00
expires = sip - > sip_expires ;
authorization = sip - > sip_authorization ;
contact = sip - > sip_contact ;
2007-06-05 17:42:15 +00:00
to = sip - > sip_to ;
2010-01-13 01:40:11 +00:00
from = sip - > sip_from ;
2007-03-31 19:01:33 +00:00
2010-09-15 15:38:25 -05:00
if ( sip - > sip_user_agent ) {
agent = sip - > sip_user_agent - > g_string ;
}
2010-01-13 01:40:11 +00:00
if ( from ) {
from_user = from - > a_url - > url_user ;
from_host = from - > a_url - > url_host ;
}
2010-02-06 03:38:24 +00:00
2007-06-05 17:42:15 +00:00
if ( to ) {
to_user = to - > a_url - > url_user ;
to_host = to - > a_url - > url_host ;
2007-03-31 19:01:33 +00:00
}
2010-02-06 03:38:24 +00:00
if ( ! to_user )
to_user = from_user ;
if ( ! to_host )
to_host = from_host ;
2010-01-13 01:40:11 +00:00
2007-06-05 17:42:15 +00:00
if ( ! to_user | | ! to_host ) {
2010-08-17 19:54:46 -05:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Can not do authorization without a complete header in REGISTER request from %s:%d \n " ,
network_ip , network_port ) ;
2007-05-11 00:41:40 +00:00
nua_respond ( nh , SIP_401_UNAUTHORIZED , NUTAG_WITH_THIS ( nua ) , TAG_END ( ) ) ;
2009-03-25 20:14:07 +00:00
switch_goto_int ( r , 1 , end ) ;
2007-03-31 19:01:33 +00:00
}
2008-09-08 22:38:37 +00:00
if ( ! reg_host ) {
reg_host = to_host ;
}
2010-09-02 16:01:50 -05:00
if ( ! sub_host ) {
sub_host = to_host ;
}
2008-09-08 22:38:37 +00:00
2007-03-31 19:01:33 +00:00
if ( contact - > m_url ) {
const char * port = contact - > m_url - > url_port ;
2008-04-07 14:03:10 +00:00
char new_port [ 25 ] = " " ;
2008-05-21 21:49:27 +00:00
const char * contact_host = contact - > m_url - > url_host ;
2008-06-26 20:19:09 +00:00
char * path_encoded = NULL ;
int path_encoded_len = 0 ;
2008-06-27 21:38:59 +00:00
const char * proto = " sip " ;
2008-07-03 15:01:46 +00:00
int is_tls = 0 , is_tcp = 0 ;
if ( switch_stristr ( " transport=tls " , sip - > sip_contact - > m_url - > url_params ) ) {
is_tls + = 1 ;
}
2010-02-06 03:38:24 +00:00
2008-06-27 21:38:59 +00:00
if ( sip - > sip_contact - > m_url - > url_type = = url_sips ) {
proto = " sips " ;
2008-07-03 15:01:46 +00:00
is_tls + = 2 ;
2008-06-27 21:38:59 +00:00
}
2010-02-06 03:38:24 +00:00
2008-07-03 15:01:46 +00:00
if ( switch_stristr ( " transport=tcp " , sip - > sip_contact - > m_url - > url_params ) ) {
is_tcp = 1 ;
}
2010-02-06 03:38:24 +00:00
2008-05-22 01:24:13 +00:00
display = contact - > m_display ;
2010-02-06 03:38:24 +00:00
2008-05-21 21:49:27 +00:00
if ( is_nat ) {
2008-07-03 15:01:46 +00:00
if ( is_tls ) {
reg_desc = " Registered(TLS-NAT) " ;
} else if ( is_tcp ) {
reg_desc = " Registered(TCP-NAT) " ;
} else {
reg_desc = " Registered(UDP-NAT) " ;
}
2009-04-30 00:09:41 +00:00
//contact_host = url_ip;
//switch_snprintf(new_port, sizeof(new_port), ":%d", network_port);
//port = NULL;
2008-07-03 15:01:46 +00:00
} else {
if ( is_tls ) {
reg_desc = " Registered(TLS) " ;
} else if ( is_tcp ) {
reg_desc = " Registered(TCP) " ;
} else {
reg_desc = " Registered(UDP) " ;
}
2008-05-21 21:49:27 +00:00
}
2008-05-27 04:54:52 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( display ) ) {
2007-06-05 17:42:15 +00:00
if ( to ) {
display = to - > a_display ;
2009-10-23 16:03:42 +00:00
if ( zstr ( display ) ) {
2007-03-31 19:01:33 +00:00
display = " \" user \" " ;
}
}
}
2008-06-26 20:19:09 +00:00
if ( sip - > sip_path ) {
2009-03-24 17:57:00 +00:00
path_val = sip_header_as_string ( nua_handle_home ( nh ) , ( void * ) sip - > sip_path ) ;
2010-09-29 15:47:58 -05:00
path_encoded_len = ( int ) ( strlen ( path_val ) * 3 ) + 1 ;
2008-06-26 20:19:09 +00:00
switch_zmalloc ( path_encoded , path_encoded_len ) ;
2008-06-27 16:01:40 +00:00
switch_copy_string ( path_encoded , " ;fs_path= " , 10 ) ;
switch_url_encode ( path_val , path_encoded + 9 , path_encoded_len - 9 ) ;
2009-04-30 00:09:41 +00:00
} else if ( is_nat ) {
char my_contact_str [ 1024 ] ;
2009-05-04 14:36:11 +00:00
if ( sip - > sip_contact - > m_url - > url_params ) {
2010-02-06 03:38:24 +00:00
switch_snprintf ( my_contact_str , sizeof ( my_contact_str ) , " sip:%s@%s:%d;%s " ,
2009-05-04 14:36:11 +00:00
contact - > m_url - > url_user , url_ip , network_port , sip - > sip_contact - > m_url - > url_params ) ;
} else {
switch_snprintf ( my_contact_str , sizeof ( my_contact_str ) , " sip:%s@%s:%d " , contact - > m_url - > url_user , url_ip , network_port ) ;
}
2010-09-29 15:47:58 -05:00
path_encoded_len = ( int ) ( strlen ( my_contact_str ) * 3 ) + 1 ;
2009-04-30 00:09:41 +00:00
switch_zmalloc ( path_encoded , path_encoded_len ) ;
switch_copy_string ( path_encoded , " ;fs_path= " , 10 ) ;
switch_url_encode ( my_contact_str , path_encoded + 9 , path_encoded_len - 9 ) ;
exptime = 30 ;
2008-06-26 20:19:09 +00:00
}
2008-04-07 14:03:10 +00:00
if ( port ) {
switch_snprintf ( new_port , sizeof ( new_port ) , " :%s " , port ) ;
2007-03-31 19:01:33 +00:00
}
2009-02-09 17:56:38 +00:00
if ( is_nat & & sofia_test_pflag ( profile , PFLAG_RECIEVED_IN_NAT_REG_CONTACT ) ) {
2008-11-21 16:15:29 +00:00
switch_snprintf ( received_data , sizeof ( received_data ) , " ;received=%s:%d " , url_ip , network_port ) ;
2008-05-23 12:23:06 +00:00
}
2007-03-31 19:01:33 +00:00
if ( contact - > m_url - > url_params ) {
2008-06-27 21:38:59 +00:00
switch_snprintf ( contact_str , sizeof ( contact_str ) , " %s <%s:%s@%s%s;%s%s%s%s> " ,
2010-02-06 03:38:24 +00:00
display , proto , contact - > m_url - > url_user , contact_host , new_port ,
2008-06-27 16:01:40 +00:00
contact - > m_url - > url_params , received_data , is_nat ? " ;fs_nat=yes " : " " , path_encoded ? path_encoded : " " ) ;
2007-03-31 19:01:33 +00:00
} else {
2008-06-27 21:38:59 +00:00
switch_snprintf ( contact_str , sizeof ( contact_str ) , " %s <%s:%s@%s%s%s%s%s> " , display , proto , contact - > m_url - > url_user , contact_host , new_port ,
2008-06-27 16:01:40 +00:00
received_data , is_nat ? " ;fs_nat=yes " : " " , path_encoded ? path_encoded : " " ) ;
2007-03-31 19:01:33 +00:00
}
2008-06-26 20:19:09 +00:00
switch_safe_free ( path_encoded ) ;
2007-03-31 19:01:33 +00:00
}
if ( expires ) {
exptime = expires - > ex_delta ;
} else if ( contact - > m_expires ) {
exptime = atol ( contact - > m_expires ) ;
}
if ( regtype = = REG_REGISTER ) {
authorization = sip - > sip_authorization ;
} else if ( regtype = = REG_INVITE ) {
authorization = sip - > sip_proxy_authorization ;
}
2009-02-09 17:56:38 +00:00
if ( regtype = = REG_AUTO_REGISTER | | ( regtype = = REG_REGISTER & & sofia_test_pflag ( profile , PFLAG_BLIND_REG ) ) ) {
2008-05-13 23:22:21 +00:00
regtype = REG_REGISTER ;
2007-03-31 19:01:33 +00:00
goto reg ;
}
if ( authorization ) {
2007-05-14 21:30:31 +00:00
char * v_contact_str ;
2008-05-27 04:54:52 +00:00
if ( ( auth_res = sofia_reg_parse_auth ( profile , authorization , sip , sip - > sip_request - > rq_method_name ,
2009-11-12 03:52:07 +00:00
key , keylen , network_ip , v_event , exptime , regtype , to_user , & auth_params , & reg_count ) ) = = AUTH_STALE ) {
2007-03-31 19:01:33 +00:00
stale = 1 ;
}
2008-05-27 04:54:52 +00:00
2008-05-16 18:40:09 +00:00
if ( exptime & & v_event & & * v_event ) {
2007-10-18 16:17:42 +00:00
char * exp_var ;
2008-07-15 18:04:17 +00:00
char * allow_multireg = NULL ;
allow_multireg = switch_event_get_header ( * v_event , " sip-allow-multiple-registrations " ) ;
2010-02-06 03:38:24 +00:00
if ( allow_multireg & & switch_false ( allow_multireg ) ) {
2008-07-15 18:04:17 +00:00
avoid_multi_reg = 1 ;
}
2007-10-18 16:17:42 +00:00
register_gateway = switch_event_get_header ( * v_event , " sip-register-gateway " ) ;
2008-05-27 04:54:52 +00:00
2008-01-12 19:15:05 +00:00
/* Allow us to force the SIP user to be something specific - needed if
* we - for example - want to be able to ensure that the username a UA can
* be contacted at is the same one that they used for authentication .
2008-05-27 04:54:52 +00:00
*/
2008-01-12 19:15:05 +00:00
if ( ( force_user = switch_event_get_header ( * v_event , " sip-force-user " ) ) ) {
to_user = force_user ;
}
2008-05-27 04:54:52 +00:00
2007-10-18 16:17:42 +00:00
if ( ( v_contact_str = switch_event_get_header ( * v_event , " sip-force-contact " ) ) ) {
2009-04-29 22:00:34 +00:00
if ( ! strcasecmp ( v_contact_str , " NDLB-connectile-dysfunction-2.0 " ) ) {
char * path_encoded ;
2009-04-29 23:27:24 +00:00
size_t path_encoded_len ;
2009-04-29 22:04:25 +00:00
char my_contact_str [ 1024 ] ;
2009-04-29 23:27:24 +00:00
switch_snprintf ( my_contact_str , sizeof ( my_contact_str ) , " sip:%s@%s:%d " , contact - > m_url - > url_user , url_ip , network_port ) ;
path_encoded_len = ( strlen ( my_contact_str ) * 3 ) + 1 ;
2009-04-29 22:00:34 +00:00
switch_zmalloc ( path_encoded , path_encoded_len ) ;
2009-04-29 23:27:24 +00:00
switch_copy_string ( path_encoded , " ;fs_nat=yes;fs_path= " , 21 ) ;
2009-04-29 22:56:19 +00:00
switch_url_encode ( my_contact_str , path_encoded + 20 , path_encoded_len - 20 ) ;
2009-04-29 22:00:34 +00:00
reg_desc = " Registered(AUTO-NAT-2.0) " ;
2009-04-30 00:09:41 +00:00
exptime = 30 ;
2009-04-29 22:48:21 +00:00
switch_snprintf ( contact_str + strlen ( contact_str ) , sizeof ( contact_str ) - strlen ( contact_str ) , " %s " , path_encoded ) ;
free ( path_encoded ) ;
2009-04-29 22:00:34 +00:00
} else {
if ( * received_data & & sofia_test_pflag ( profile , PFLAG_RECIEVED_IN_NAT_REG_CONTACT ) ) {
switch_snprintf ( received_data , sizeof ( received_data ) , " ;received=%s:%d " , url_ip , network_port ) ;
2007-09-18 17:31:36 +00:00
}
2010-02-06 03:38:24 +00:00
2009-04-29 22:00:34 +00:00
if ( ! strcasecmp ( v_contact_str , " nat-connectile-dysfunction " ) | |
! strcasecmp ( v_contact_str , " NDLB-connectile-dysfunction " ) | | ! strcasecmp ( v_contact_str , " NDLB-tls-connectile-dysfunction " ) ) {
if ( contact - > m_url - > url_params ) {
switch_snprintf ( contact_str , sizeof ( contact_str ) , " %s <sip:%s@%s:%d;%s%s;fs_nat=yes> " ,
display , contact - > m_url - > url_user , url_ip , network_port , contact - > m_url - > url_params , received_data ) ;
} else {
switch_snprintf ( contact_str , sizeof ( contact_str ) , " %s <sip:%s@%s:%d%s;fs_nat=yes> " , display , contact - > m_url - > url_user , url_ip ,
network_port , received_data ) ;
}
2010-03-26 16:23:49 +00:00
if ( switch_stristr ( v_contact_str , " transport=tls " ) ) {
2009-04-29 22:00:34 +00:00
reg_desc = " Registered(TLSHACK) " ;
} else {
reg_desc = " Registered(AUTO-NAT) " ;
2009-04-30 00:09:41 +00:00
exptime = 30 ;
2009-04-29 22:00:34 +00:00
}
nat_hack = 1 ;
2008-01-17 17:37:49 +00:00
} else {
2009-04-29 22:00:34 +00:00
char * p ;
switch_copy_string ( contact_str , v_contact_str , sizeof ( contact_str ) ) ;
for ( p = contact_str ; p & & * p ; p + + ) {
if ( * p = = ' \' ' | | * p = = ' [ ' | | * p = = ' ] ' ) {
* p = ' " ' ;
}
2007-09-18 17:31:36 +00:00
}
2007-05-21 19:11:37 +00:00
}
2007-05-14 22:04:28 +00:00
}
}
2008-05-27 04:54:52 +00:00
2007-10-18 16:17:42 +00:00
if ( ( exp_var = switch_event_get_header ( * v_event , " sip-force-expires " ) ) ) {
int tmp = atoi ( exp_var ) ;
if ( tmp > 0 ) {
exptime = tmp ;
}
}
2007-05-14 21:30:31 +00:00
}
2007-03-31 19:01:33 +00:00
if ( auth_res ! = AUTH_OK & & ! stale ) {
2009-02-27 18:15:50 +00:00
if ( profile - > debug ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Send %s for [%s@%s] \n " , forbidden ? " forbidden " : " challenge " , to_user , to_host ) ;
}
2007-03-31 19:01:33 +00:00
if ( auth_res = = AUTH_FORBIDDEN ) {
2008-05-27 04:54:52 +00:00
nua_respond ( nh , SIP_403_FORBIDDEN , NUTAG_WITH_THIS ( nua ) , TAG_END ( ) ) ;
2010-02-06 03:38:24 +00:00
2009-11-24 16:11:56 +00:00
/* Log line added to support Fail2Ban */
2009-11-24 16:24:24 +00:00
if ( sofia_test_pflag ( profile , PFLAG_LOG_AUTH_FAIL ) ) {
2009-11-24 16:11:56 +00:00
if ( regtype = = REG_REGISTER ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " SIP auth failure (REGISTER) on sofia profile '%s' "
" for [%s@%s] from ip %s \n " , profile - > name , to_user , to_host , network_ip ) ;
} else if ( regtype = = REG_INVITE ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " SIP auth failure (INVITE) on sofia profile '%s' "
" for [%s@%s] from ip %s \n " , profile - > name , to_user , to_host , network_ip ) ;
2010-02-06 03:38:24 +00:00
}
2009-11-24 16:11:56 +00:00
}
2007-03-31 19:01:33 +00:00
} else {
2008-05-27 04:54:52 +00:00
nua_respond ( nh , SIP_401_UNAUTHORIZED , NUTAG_WITH_THIS ( nua ) , TAG_END ( ) ) ;
2007-03-31 19:01:33 +00:00
}
2009-03-25 20:14:07 +00:00
switch_goto_int ( r , 1 , end ) ;
2007-03-31 19:01:33 +00:00
}
}
if ( ! authorization | | stale ) {
2009-02-17 20:36:21 +00:00
const char * realm = profile - > challenge_realm ;
2009-10-23 16:03:42 +00:00
if ( zstr ( realm ) | | ! strcasecmp ( realm , " auto_to " ) ) {
2009-02-17 20:36:21 +00:00
realm = to_host ;
} else if ( ! strcasecmp ( realm , " auto_from " ) ) {
realm = from_host ;
}
2008-09-22 14:40:13 +00:00
if ( regtype = = REG_REGISTER ) {
2009-02-17 20:36:21 +00:00
sofia_reg_auth_challenge ( nua , profile , nh , regtype , realm , stale ) ;
2008-09-22 14:40:13 +00:00
if ( profile - > debug ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Requesting Registration from: [%s@%s] \n " , to_user , to_host ) ;
}
} else {
2008-09-22 19:14:54 +00:00
sofia_reg_auth_challenge ( nua , profile , nh , regtype , realm , stale ) ;
2007-03-31 19:01:33 +00:00
}
2009-03-25 20:14:07 +00:00
switch_goto_int ( r , 1 , end ) ;
2007-03-31 19:01:33 +00:00
}
2008-05-27 04:54:52 +00:00
reg :
2007-03-31 19:01:33 +00:00
2009-10-21 23:09:41 +00:00
if ( v_event & & * v_event & & ( var = switch_event_get_header ( * v_event , " sip-force-extension " ) ) ) {
to_user = var ;
}
2009-09-26 05:41:05 +00:00
if ( v_event & & * v_event & & ( mwi_account = switch_event_get_header ( * v_event , " mwi-account " ) ) ) {
2009-09-25 20:07:40 +00:00
dup_mwi_account = strdup ( mwi_account ) ;
switch_assert ( dup_mwi_account ! = NULL ) ;
2010-06-02 01:09:54 +02:00
switch_split_user_domain ( dup_mwi_account , & mwi_user , & mwi_host ) ;
2009-09-25 20:07:40 +00:00
}
if ( ! mwi_user ) {
mwi_user = ( char * ) to_user ;
}
if ( ! mwi_host ) {
mwi_host = ( char * ) reg_host ;
}
2007-08-16 17:19:27 +00:00
if ( regtype ! = REG_REGISTER ) {
2009-03-25 20:14:07 +00:00
switch_goto_int ( r , 0 , end ) ;
2007-08-16 17:19:27 +00:00
}
2007-10-18 16:17:42 +00:00
2008-10-07 22:18:40 +00:00
call_id = sip - > sip_call_id - > i_id ;
2007-12-12 23:21:45 +00:00
switch_assert ( call_id ) ;
2007-10-18 16:17:42 +00:00
2008-07-15 18:04:17 +00:00
/* Does this profile supports multiple registrations ? */
2010-02-06 03:38:24 +00:00
multi_reg = ( sofia_test_pflag ( profile , PFLAG_MULTIREG ) ) ? 1 : 0 ;
multi_reg_contact = ( sofia_test_pflag ( profile , PFLAG_MULTIREG_CONTACT ) ) ? 1 : 0 ;
2008-07-15 18:04:17 +00:00
2010-02-06 03:38:24 +00:00
if ( multi_reg & & avoid_multi_reg ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG ,
" Disabling multiple registrations on a per-user basis for %s@%s \n " , switch_str_nil ( to_user ) , switch_str_nil ( to_host ) ) ;
2008-07-15 18:04:17 +00:00
multi_reg = 0 ;
}
2007-03-31 19:01:33 +00:00
if ( exptime ) {
2008-07-30 18:50:47 +00:00
char guess_ip4 [ 256 ] ;
2009-03-25 20:14:07 +00:00
const char * username = " unknown " ;
const char * realm = reg_host ;
if ( auth_params ) {
username = switch_event_get_header ( auth_params , " sip_auth_username " ) ;
realm = switch_event_get_header ( auth_params , " sip_auth_realm " ) ;
}
2007-12-14 02:09:22 +00:00
2008-07-15 18:04:17 +00:00
if ( multi_reg ) {
2010-09-02 16:01:50 -05:00
2010-09-15 15:38:25 -05:00
if ( delete_subs ) {
if ( reg_count = = 1 ) {
sql = switch_mprintf ( " delete from sip_subscriptions where sip_user='%q' and sip_host='%q' and contact='%q' " ,
to_user , sub_host , contact_str ) ;
sofia_glue_execute_sql_now ( profile , & sql , SWITCH_TRUE ) ;
}
2010-08-23 18:18:56 -05:00
}
2008-10-22 17:40:43 +00:00
if ( multi_reg_contact ) {
2010-02-06 03:38:24 +00:00
sql =
switch_mprintf ( " delete from sip_registrations where sip_user='%q' and sip_host='%q' and contact='%q' " , to_user , reg_host , contact_str ) ;
2008-10-22 17:40:43 +00:00
} else {
sql = switch_mprintf ( " delete from sip_registrations where call_id='%q' " , call_id ) ;
}
2007-03-31 19:01:33 +00:00
} else {
2010-09-15 15:38:25 -05:00
if ( delete_subs ) {
sql = switch_mprintf ( " delete from sip_subscriptions where sip_user='%q' and sip_host='%q' " , to_user , sub_host ) ;
sofia_glue_execute_sql_now ( profile , & sql , SWITCH_TRUE ) ;
}
2010-02-06 03:38:24 +00:00
sql = switch_mprintf ( " delete from sip_registrations where sip_user='%q' and sip_host='%q' " , to_user , reg_host ) ;
2007-10-18 01:02:01 +00:00
}
switch_mutex_lock ( profile - > ireg_mutex ) ;
2010-07-27 22:08:47 -05:00
sofia_glue_execute_sql_now ( profile , & sql , SWITCH_TRUE ) ;
2009-09-25 20:07:40 +00:00
2009-06-02 16:55:10 +00:00
switch_find_local_ip ( guess_ip4 , sizeof ( guess_ip4 ) , NULL , AF_INET ) ;
2010-09-02 16:01:50 -05:00
2010-07-29 23:39:39 -05:00
2008-09-18 00:01:03 +00:00
sql = switch_mprintf ( " insert into sip_registrations "
2009-03-25 20:14:07 +00:00
" (call_id,sip_user,sip_host,presence_hosts,contact,status,rpid,expires, "
2010-02-05 07:05:33 +00:00
" user_agent,server_user,server_host,profile_name,hostname,network_ip,network_port,sip_username,sip_realm, "
" mwi_user,mwi_host, orig_server_host, orig_hostname) "
" values ('%q','%q', '%q','%q','%q','%q', '%q', %ld, '%q', '%q', '%q', '%q', '%q', '%q', '%q','%q','%q','%q','%q','%q','%q') " ,
2008-09-18 00:01:03 +00:00
call_id , to_user , reg_host , profile - > presence_hosts ? profile - > presence_hosts : reg_host ,
2010-09-15 15:38:25 -05:00
contact_str , reg_desc , rpid , ( long ) switch_epoch_time_now ( NULL ) + ( long ) exptime + 60 ,
2010-02-05 07:05:33 +00:00
agent , from_user , guess_ip4 , profile - > name , mod_sofia_globals . hostname , network_ip , network_port_c , username , realm ,
mwi_user , mwi_host , guess_ip4 , mod_sofia_globals . hostname ) ;
2008-09-18 00:01:03 +00:00
2007-10-18 01:02:01 +00:00
if ( sql ) {
2010-07-27 22:08:47 -05:00
sofia_glue_execute_sql_now ( profile , & sql , SWITCH_TRUE ) ;
2007-03-31 19:01:33 +00:00
}
2008-11-25 20:54:58 +00:00
2010-07-29 23:39:39 -05:00
2007-10-18 01:02:01 +00:00
switch_mutex_unlock ( profile - > ireg_mutex ) ;
2007-03-31 19:01:33 +00:00
if ( switch_event_create_subclass ( & s_event , SWITCH_EVENT_CUSTOM , MY_EVENT_REGISTER ) = = SWITCH_STATUS_SUCCESS ) {
2008-08-16 02:19:43 +00:00
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " profile-name " , profile - > name ) ;
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " from-user " , to_user ) ;
2008-09-08 22:38:37 +00:00
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " from-host " , reg_host ) ;
2008-09-18 00:01:03 +00:00
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " presence-hosts " , profile - > presence_hosts ? profile - > presence_hosts : reg_host ) ;
2008-08-16 02:19:43 +00:00
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " contact " , contact_str ) ;
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " call-id " , call_id ) ;
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " rpid " , rpid ) ;
2009-11-09 22:26:28 +00:00
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " status " , reg_desc ) ;
2007-03-31 19:01:33 +00:00
switch_event_add_header ( s_event , SWITCH_STACK_BOTTOM , " expires " , " %ld " , ( long ) exptime ) ;
2008-08-16 02:19:43 +00:00
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " to-user " , from_user ) ;
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " to-host " , from_host ) ;
2009-03-04 19:45:10 +00:00
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " network-ip " , network_ip ) ;
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " network-port " , network_port_c ) ;
2009-03-25 20:14:07 +00:00
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " username " , username ) ;
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " realm " , realm ) ;
2009-06-16 18:46:28 +00:00
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " user-agent " , agent ) ;
2007-03-31 19:01:33 +00:00
switch_event_fire ( & s_event ) ;
}
2008-05-27 04:54:52 +00:00
2007-03-31 19:01:33 +00:00
2008-01-21 20:36:10 +00:00
if ( profile - > debug ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG ,
2008-09-08 22:38:37 +00:00
" Register: \n From: [%s@%s] \n Contact: [%s] \n Expires: [%ld] \n " , to_user , reg_host , contact_str , ( long ) exptime ) ;
2008-01-21 20:36:10 +00:00
}
2007-03-31 19:01:33 +00:00
2008-12-10 20:54:24 +00:00
#if 0
if ( switch_event_create ( & event , SWITCH_EVENT_PRESENCE_IN ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " proto " , SOFIA_CHAT_PROTO ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " rpid " , rpid ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " login " , profile - > url ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " user-agent " ,
( sip & & sip - > sip_user_agent ) ? sip - > sip_user_agent - > g_string : " unknown " ) ;
2010-09-02 16:01:50 -05:00
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " from " , " %s@%s " , to_user , sub_host ) ;
2008-12-10 20:54:24 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " status " , " Registered " ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " event_type " , " presence " ) ;
switch_event_fire ( & event ) ;
}
# else
2009-11-12 03:52:07 +00:00
2010-02-06 03:38:24 +00:00
if ( sofia_test_pflag ( profile , PFLAG_MESSAGE_QUERY_ON_REGISTER ) | |
2009-11-12 03:52:07 +00:00
( reg_count = = 1 & & sofia_test_pflag ( profile , PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER ) ) ) {
if ( switch_event_create ( & event , SWITCH_EVENT_PRESENCE_PROBE ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " proto " , " sip " ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " login " , profile - > url ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " rpid " , rpid ) ;
2010-09-02 16:01:50 -05:00
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " from " , " %s@%s " , to_user , sub_host ) ;
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " to " , " %s@%s " , to_user , sub_host ) ;
2009-11-12 03:52:07 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " status " , " Registered " ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " event_subtype " , " probe " ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " event_type " , " presence " ) ;
switch_event_fire ( & event ) ;
}
2007-03-31 19:01:33 +00:00
}
2008-12-10 20:54:24 +00:00
# endif
2008-12-11 20:20:20 +00:00
2007-03-31 19:01:33 +00:00
} else {
2010-02-06 03:38:24 +00:00
2010-07-27 22:08:47 -05:00
if ( switch_event_create ( & event , SWITCH_EVENT_PRESENCE_IN ) = = SWITCH_STATUS_SUCCESS ) {
2008-12-11 20:20:20 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " proto " , SOFIA_CHAT_PROTO ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " rpid " , rpid ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " login " , profile - > url ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " user-agent " ,
( sip & & sip - > sip_user_agent ) ? sip - > sip_user_agent - > g_string : " unknown " ) ;
2010-09-02 16:01:50 -05:00
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " from " , " %s@%s " , to_user , sub_host ) ;
2009-03-22 05:15:17 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " status " , " Unregistered " ) ;
2008-12-11 20:20:20 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " event_type " , " presence " ) ;
switch_event_fire ( & event ) ;
}
#if 0
if ( switch_event_create ( & event , SWITCH_EVENT_PRESENCE_OUT ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " proto " , " sip " ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " login " , profile - > url ) ;
2010-09-02 16:01:50 -05:00
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " from " , " %s+%s@%s " , SOFIA_CHAT_PROTO , to_user , sub_host ) ;
2008-12-11 20:20:20 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " status " , " unavailable " ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " rpid " , rpid ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " event_type " , " presence " ) ;
switch_event_fire ( & event ) ;
}
# endif
2008-07-15 18:04:17 +00:00
if ( multi_reg ) {
2007-10-18 01:02:01 +00:00
char * icontact , * p ;
icontact = sofia_glue_get_url_from_contact ( contact_str , 1 ) ;
if ( ( p = strchr ( icontact , ' ; ' ) ) ) {
* p = ' \0 ' ;
}
2007-10-18 16:17:42 +00:00
if ( ( p = strchr ( icontact + 4 , ' : ' ) ) ) {
* p = ' \0 ' ;
}
2010-09-15 15:38:25 -05:00
if ( delete_subs ) {
if ( multi_reg_contact ) {
sql =
switch_mprintf ( " delete from sip_subscriptions where sip_user='%q' and sip_host='%q' and contact='%q' " , to_user , sub_host , contact_str ) ;
} else {
sql = switch_mprintf ( " delete from sip_subscriptions where call_id='%q' " , call_id ) ;
}
2008-05-27 04:54:52 +00:00
2010-09-15 15:38:25 -05:00
sofia_glue_execute_sql_now ( profile , & sql , SWITCH_TRUE ) ;
}
2008-10-22 17:40:43 +00:00
if ( multi_reg_contact ) {
2010-02-06 03:38:24 +00:00
sql =
switch_mprintf ( " delete from sip_registrations where sip_user='%q' and sip_host='%q' and contact='%q' " , to_user , reg_host , contact_str ) ;
2008-10-22 17:40:43 +00:00
} else {
sql = switch_mprintf ( " delete from sip_registrations where call_id='%q' " , call_id ) ;
2007-10-18 01:02:01 +00:00
}
2008-10-22 17:40:43 +00:00
2010-07-29 23:39:39 -05:00
sofia_glue_execute_sql_now ( profile , & sql , SWITCH_TRUE ) ;
2008-10-22 17:40:43 +00:00
2007-10-18 01:02:01 +00:00
switch_safe_free ( icontact ) ;
} else {
2010-09-15 15:38:25 -05:00
if ( delete_subs ) {
if ( ( sql = switch_mprintf ( " delete from sip_subscriptions where sip_user='%q' and sip_host='%q' " , to_user , sub_host ) ) ) {
sofia_glue_execute_sql_now ( profile , & sql , SWITCH_TRUE ) ;
}
2007-10-18 01:02:01 +00:00
}
2008-11-05 18:22:36 +00:00
if ( ( sql = switch_mprintf ( " delete from sip_registrations where sip_user='%q' and sip_host='%q' " , to_user , reg_host ) ) ) {
2010-07-29 23:39:39 -05:00
sofia_glue_execute_sql_now ( profile , & sql , SWITCH_TRUE ) ;
2007-10-18 01:02:01 +00:00
}
2007-04-23 20:38:00 +00:00
}
2007-03-31 19:01:33 +00:00
}
if ( regtype = = REG_REGISTER ) {
2008-05-22 17:24:10 +00:00
char exp_param [ 128 ] = " " ;
2008-12-31 16:23:24 +00:00
char date [ 80 ] = " " ;
2010-08-28 23:16:00 -04:00
switch_event_t * s_mwi_event = NULL ;
2009-11-12 03:52:07 +00:00
2008-05-29 13:25:53 +00:00
s_event = NULL ;
2008-05-27 04:54:52 +00:00
2008-05-22 17:24:10 +00:00
if ( exptime ) {
2008-05-28 23:36:56 +00:00
switch_snprintf ( exp_param , sizeof ( exp_param ) , " expires=%ld " , exptime ) ;
2009-03-24 17:57:00 +00:00
sip_contact_add_param ( nua_handle_home ( nh ) , sip - > sip_contact , exp_param ) ;
2010-02-06 03:38:24 +00:00
if ( sofia_test_pflag ( profile , PFLAG_MESSAGE_QUERY_ON_REGISTER ) | |
2009-11-12 03:52:07 +00:00
( reg_count = = 1 & & sofia_test_pflag ( profile , PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER ) ) ) {
2010-08-28 23:16:00 -04:00
if ( switch_event_create ( & s_mwi_event , SWITCH_EVENT_MESSAGE_QUERY ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_add_header ( s_mwi_event , SWITCH_STACK_BOTTOM , " Message-Account " , " sip:%s@%s " , mwi_user , mwi_host ) ;
switch_event_add_header_string ( s_mwi_event , SWITCH_STACK_BOTTOM , " VM-Sofia-Profile " , profile - > name ) ;
switch_event_add_header_string ( s_mwi_event , SWITCH_STACK_BOTTOM , " VM-Call-ID " , call_id ) ;
2009-04-24 14:33:54 +00:00
}
2008-05-29 13:25:53 +00:00
}
2010-07-27 22:08:47 -05:00
2010-09-02 16:01:50 -05:00
#if 0
if ( switch_event_create ( & s_event , SWITCH_EVENT_PRESENCE_PROBE ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " proto " , SOFIA_CHAT_PROTO ) ;
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " login " , profile - > name ) ;
switch_event_add_header ( s_event , SWITCH_STACK_BOTTOM , " from " , " %s@%s " , to_user , sub_host ) ;
switch_event_add_header ( s_event , SWITCH_STACK_BOTTOM , " to " , " %s@%s " , to_user , sub_host ) ;
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " event_type " , " presence " ) ;
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " alt_event_type " , " dialog " ) ;
switch_event_fire ( & s_event ) ;
}
# else
2010-07-27 22:08:47 -05:00
if ( switch_event_create ( & s_event , SWITCH_EVENT_PRESENCE_IN ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " proto " , SOFIA_CHAT_PROTO ) ;
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " login " , profile - > name ) ;
2010-09-02 16:01:50 -05:00
switch_event_add_header ( s_event , SWITCH_STACK_BOTTOM , " from " , " %s@%s " , to_user , sub_host ) ;
2010-08-24 11:53:46 -05:00
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " rpid " , " unknown " ) ;
2010-07-27 22:08:47 -05:00
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " status " , " Registered " ) ;
switch_event_fire ( & s_event ) ;
2010-09-02 16:01:50 -05:00
}
# endif
2008-05-29 13:25:53 +00:00
} else {
if ( switch_event_create_subclass ( & s_event , SWITCH_EVENT_CUSTOM , MY_EVENT_UNREGISTER ) = = SWITCH_STATUS_SUCCESS ) {
2008-08-16 02:19:43 +00:00
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " profile-name " , profile - > name ) ;
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " from-user " , to_user ) ;
2008-09-08 22:38:37 +00:00
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " from-host " , reg_host ) ;
2008-08-16 02:19:43 +00:00
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " contact " , contact_str ) ;
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " call-id " , call_id ) ;
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " rpid " , rpid ) ;
2008-05-29 13:25:53 +00:00
switch_event_add_header ( s_event , SWITCH_STACK_BOTTOM , " expires " , " %ld " , ( long ) exptime ) ;
2008-05-16 18:40:09 +00:00
}
2007-10-18 16:17:42 +00:00
}
2010-02-06 03:38:24 +00:00
2009-01-25 21:23:07 +00:00
switch_rfc822_date ( date , switch_micro_time_now ( ) ) ;
2008-12-31 16:23:24 +00:00
nua_respond ( nh , SIP_200_OK , SIPTAG_CONTACT ( sip - > sip_contact ) ,
2010-02-06 03:38:24 +00:00
TAG_IF ( path_val , SIPTAG_PATH_STR ( path_val ) ) , NUTAG_WITH_THIS ( nua ) , SIPTAG_DATE_STR ( date ) , TAG_END ( ) ) ;
2008-05-27 04:54:52 +00:00
2008-05-29 13:25:53 +00:00
if ( s_event ) {
switch_event_fire ( & s_event ) ;
2010-08-28 23:16:00 -04:00
}
if ( s_mwi_event ) {
switch_event_fire ( & s_mwi_event ) ;
2008-05-29 13:25:53 +00:00
}
2010-02-06 03:38:24 +00:00
2010-01-09 00:34:17 +00:00
if ( * contact_str & & sofia_test_pflag ( profile , PFLAG_MANAGE_SHARED_APPEARANCE_SYLANTRO ) ) {
2009-11-12 03:52:07 +00:00
sofia_sla_handle_register ( nua , profile , sip , exptime , contact_str ) ;
2009-01-30 16:46:37 +00:00
}
2009-03-25 20:14:07 +00:00
switch_goto_int ( r , 1 , end ) ;
2007-03-31 19:01:33 +00:00
}
2009-03-25 20:14:07 +00:00
2010-02-06 03:38:24 +00:00
end :
2009-09-25 20:07:40 +00:00
switch_safe_free ( dup_mwi_account ) ;
2009-03-25 20:14:07 +00:00
if ( auth_params ) {
switch_event_destroy ( & auth_params ) ;
}
2010-02-06 03:38:24 +00:00
return ( uint8_t ) r ;
2007-03-31 19:01:33 +00:00
}
2008-05-27 04:54:52 +00:00
void sofia_reg_handle_sip_i_register ( nua_t * nua , sofia_profile_t * profile , nua_handle_t * nh , sofia_private_t * sofia_private , sip_t const * sip ,
tagi_t tags [ ] )
2007-03-31 19:01:33 +00:00
{
char key [ 128 ] = " " ;
2007-05-14 22:04:28 +00:00
switch_event_t * v_event = NULL ;
2008-03-26 22:14:09 +00:00
char network_ip [ 80 ] ;
2008-05-13 23:22:21 +00:00
sofia_regtype_t type = REG_REGISTER ;
2008-05-20 16:41:57 +00:00
int network_port = 0 ;
2008-05-21 21:49:27 +00:00
char * is_nat = NULL ;
2008-07-03 15:01:46 +00:00
2010-09-03 14:11:06 -05:00
if ( sip - > sip_to & & sip - > sip_to - > a_url & & sip - > sip_to - > a_url - > url_host ) {
const char * to_host = sip - > sip_to - > a_url - > url_host ;
if ( profile - > reg_db_domain ) {
if ( ! sofia_glue_profile_exists ( to_host ) ) {
if ( sofia_glue_add_profile ( switch_core_strdup ( profile - > pool , to_host ) , profile ) = = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " Auto-Adding Alias [%s] for profile [%s] \n " , to_host , profile - > name ) ;
}
}
}
}
2010-02-06 03:38:24 +00:00
sofia_glue_get_addr ( nua_current_request ( nua ) , network_ip , sizeof ( network_ip ) , & network_port ) ;
2008-05-20 16:41:57 +00:00
if ( ! ( sip - > sip_contact & & sip - > sip_contact - > m_url ) ) {
2010-06-14 14:12:14 -05:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " NO CONTACT! ip: %s, port: %i \n " , network_ip , network_port ) ;
2008-05-20 16:41:57 +00:00
nua_respond ( nh , 400 , " Missing Contact Header " , TAG_END ( ) ) ;
goto end ;
}
if ( ! ( profile - > mflags & MFLAG_REGISTER ) ) {
2008-05-27 04:54:52 +00:00
nua_respond ( nh , SIP_403_FORBIDDEN , NUTAG_WITH_THIS ( nua ) , TAG_END ( ) ) ;
2008-05-20 16:41:57 +00:00
goto end ;
}
2009-02-09 17:56:38 +00:00
if ( sofia_test_pflag ( profile , PFLAG_AGGRESSIVE_NAT_DETECTION ) ) {
2008-07-03 15:01:46 +00:00
if ( sip & & sip - > sip_via ) {
const char * port = sip - > sip_via - > v_port ;
const char * host = sip - > sip_via - > v_host ;
2010-02-06 03:38:24 +00:00
2008-07-03 15:01:46 +00:00
if ( host & & sip - > sip_via - > v_received ) {
is_nat = " via received " ;
} else if ( host & & strcmp ( network_ip , host ) ) {
is_nat = " via host " ;
} else if ( port & & atoi ( port ) ! = network_port ) {
is_nat = " via port " ;
2008-06-27 21:38:59 +00:00
}
2008-05-21 21:49:27 +00:00
}
2008-07-03 15:01:46 +00:00
}
2008-05-21 21:49:27 +00:00
2010-10-12 11:41:28 -05:00
/* FS-2773: This causes issues with Cisco phones.
* if ( ! is_nat & & sip & & sip - > sip_via & & sip - > sip_via - > v_port & &
* atoi ( sip - > sip_via - > v_port ) = = 5060 & & network_port ! = 5060 ) {
* is_nat = " via port " ;
* }
*/
2010-04-27 13:56:37 -05:00
2008-07-03 15:01:46 +00:00
if ( ! is_nat & & profile - > nat_acl_count ) {
uint32_t x = 0 ;
int ok = 1 ;
char * last_acl = NULL ;
const char * contact_host = NULL ;
2008-06-27 21:38:59 +00:00
2008-07-03 15:01:46 +00:00
if ( sip & & sip - > sip_contact & & sip - > sip_contact - > m_url ) {
contact_host = sip - > sip_contact - > m_url - > url_host ;
}
2008-05-27 04:54:52 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( contact_host ) ) {
2008-07-03 15:01:46 +00:00
for ( x = 0 ; x < profile - > nat_acl_count ; x + + ) {
last_acl = profile - > nat_acl [ x ] ;
if ( ! ( ok = switch_check_network_list_ip ( contact_host , last_acl ) ) ) {
break ;
2008-06-27 21:38:59 +00:00
}
2008-07-03 15:01:46 +00:00
}
2010-02-06 03:38:24 +00:00
2008-07-03 15:01:46 +00:00
if ( ok ) {
is_nat = last_acl ;
2008-05-21 21:49:27 +00:00
}
}
}
2010-02-06 03:38:24 +00:00
2008-05-20 16:41:57 +00:00
if ( profile - > reg_acl_count ) {
uint32_t x = 0 ;
int ok = 1 ;
char * last_acl = NULL ;
2008-05-13 23:22:21 +00:00
2008-05-27 04:54:52 +00:00
for ( x = 0 ; x < profile - > reg_acl_count ; x + + ) {
2008-05-13 23:22:21 +00:00
last_acl = profile - > reg_acl [ x ] ;
if ( ! ( ok = switch_check_network_list_ip ( network_ip , last_acl ) ) ) {
break ;
2008-03-26 22:14:09 +00:00
}
}
2008-05-27 04:54:52 +00:00
2009-02-09 17:56:38 +00:00
if ( ok & & ! sofia_test_pflag ( profile , PFLAG_BLIND_REG ) ) {
2008-05-13 23:22:21 +00:00
type = REG_AUTO_REGISTER ;
} else if ( ! ok ) {
2010-01-07 18:47:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " IP %s Rejected by register acl \" %s \" \n " , network_ip , profile - > reg_acl [ x ] ) ;
2008-11-02 20:14:12 +00:00
nua_respond ( nh , SIP_403_FORBIDDEN , NUTAG_WITH_THIS ( nua ) , TAG_END ( ) ) ;
2008-05-13 23:22:21 +00:00
goto end ;
}
2008-03-26 22:14:09 +00:00
}
2008-05-27 04:54:52 +00:00
2007-03-31 19:01:33 +00:00
if ( ! sip | | ! sip - > sip_request | | ! sip - > sip_request - > rq_method_name ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Received an invalid packet! \n " ) ;
2008-05-27 04:54:52 +00:00
nua_respond ( nh , SIP_500_INTERNAL_SERVER_ERROR , TAG_END ( ) ) ;
2008-03-05 20:31:18 +00:00
goto end ;
2007-03-31 19:01:33 +00:00
}
2010-02-06 03:38:24 +00:00
2009-12-02 01:58:05 +00:00
if ( is_nat & & profile - > local_network & & switch_check_network_list_ip ( network_ip , profile - > local_network ) ) {
2009-12-08 22:28:52 +00:00
if ( profile - > debug ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " IP %s is on local network, not seting NAT mode. \n " , network_ip ) ;
}
2009-11-16 21:14:38 +00:00
is_nat = NULL ;
}
2007-03-31 19:01:33 +00:00
2008-05-21 21:49:27 +00:00
sofia_reg_handle_register ( nua , profile , nh , sip , type , key , sizeof ( key ) , & v_event , is_nat ) ;
2010-02-06 03:38:24 +00:00
2007-05-14 22:04:28 +00:00
if ( v_event ) {
2009-10-08 15:29:06 +00:00
switch_event_destroy ( & v_event ) ;
2007-05-14 22:04:28 +00:00
}
2008-03-05 20:31:18 +00:00
2008-05-27 04:54:52 +00:00
end :
2008-03-05 20:31:18 +00:00
nua_handle_destroy ( nh ) ;
2007-03-31 19:01:33 +00:00
}
void sofia_reg_handle_sip_r_register ( int status ,
2008-05-20 22:28:34 +00:00
char const * phrase ,
2008-05-27 04:54:52 +00:00
nua_t * nua , sofia_profile_t * profile , nua_handle_t * nh , sofia_private_t * sofia_private , sip_t const * sip ,
tagi_t tags [ ] )
2007-03-31 19:01:33 +00:00
{
2010-02-04 21:23:36 +00:00
if ( status > = 500 ) {
2009-11-05 05:01:41 +00:00
if ( sofia_private & & sofia_private - > gateway ) {
nua_handle_destroy ( sofia_private - > gateway - > nh ) ;
sofia_private - > gateway - > nh = NULL ;
2009-11-05 07:06:19 +00:00
} else {
nua_handle_destroy ( nh ) ;
2009-11-05 05:01:41 +00:00
}
}
2010-02-06 03:38:24 +00:00
2007-03-31 19:01:33 +00:00
if ( sofia_private & & sofia_private - > gateway ) {
2008-10-10 15:36:02 +00:00
reg_state_t ostate = sofia_private - > gateway - > state ;
2007-03-31 19:01:33 +00:00
switch ( status ) {
case 200 :
2008-10-07 22:18:40 +00:00
if ( sip & & sip - > sip_contact ) {
2008-10-07 21:55:58 +00:00
sip_contact_t * contact = sip - > sip_contact ;
const char * new_expires ;
uint32_t expi ;
if ( contact - > m_next ) {
2010-02-06 03:38:24 +00:00
const char * sipip = profile - > extsipip ? profile - > extsipip : profile - > sipip ;
for ( ; contact & & strcasecmp ( contact - > m_url - > url_host , sipip ) ; contact = contact - > m_next ) ;
2008-10-07 21:55:58 +00:00
}
2008-10-07 22:15:51 +00:00
if ( ! contact ) {
contact = sip - > sip_contact ;
}
2008-10-07 21:55:58 +00:00
if ( contact - > m_expires ) {
new_expires = contact - > m_expires ;
expi = ( uint32_t ) atoi ( new_expires ) ;
2010-02-06 03:38:24 +00:00
2009-05-19 15:17:44 +00:00
if ( expi > 0 & & expi ! = sofia_private - > gateway - > freq ) {
2008-10-07 21:55:58 +00:00
sofia_private - > gateway - > freq = expi ;
2009-06-04 20:00:53 +00:00
sofia_private - > gateway - > expires_str = switch_core_sprintf ( sofia_private - > gateway - > pool , " %d " , expi ) ;
if ( expi > 60 ) {
sofia_private - > gateway - > expires = switch_epoch_time_now ( NULL ) + ( expi - 15 ) ;
} else {
sofia_private - > gateway - > expires = switch_epoch_time_now ( NULL ) + ( expi - 2 ) ;
}
2008-10-07 21:55:58 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG ,
" Changing expire time to %d by request of proxy %s \n " , expi , sofia_private - > gateway - > register_proxy ) ;
}
2007-03-31 19:01:33 +00:00
}
}
sofia_private - > gateway - > state = REG_STATE_REGISTER ;
break ;
case 100 :
break ;
default :
sofia_private - > gateway - > state = REG_STATE_FAILED ;
2009-12-02 20:47:46 +00:00
sofia_private - > gateway - > failure_status = status ;
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " %s Registration Failed with status %s [%d]. failure #%d \n " ,
2009-01-02 19:58:36 +00:00
sofia_private - > gateway - > name , switch_str_nil ( phrase ) , status , + + sofia_private - > gateway - > failures ) ;
2007-03-31 19:01:33 +00:00
break ;
}
2008-10-10 15:36:02 +00:00
if ( ostate ! = sofia_private - > gateway - > state ) {
2010-01-15 15:18:07 +00:00
sofia_reg_fire_custom_gateway_state_event ( sofia_private - > gateway , status , phrase ) ;
2008-10-10 15:36:02 +00:00
}
2007-03-31 19:01:33 +00:00
}
}
void sofia_reg_handle_sip_r_challenge ( int status ,
2007-12-04 00:21:32 +00:00
char const * phrase ,
2008-11-03 17:39:09 +00:00
nua_t * nua , sofia_profile_t * profile , nua_handle_t * nh , sofia_private_t * sofia_private ,
2007-12-04 00:21:32 +00:00
switch_core_session_t * session , sofia_gateway_t * gateway , sip_t const * sip , tagi_t tags [ ] )
2007-03-31 19:01:33 +00:00
{
sip_www_authenticate_t const * authenticate = NULL ;
char const * realm = NULL ;
char const * scheme = NULL ;
int indexnum ;
char * cur ;
char authentication [ 256 ] = " " ;
int ss_state ;
2008-07-17 13:36:02 +00:00
sofia_gateway_t * var_gateway = NULL ;
const char * gw_name = NULL ;
2009-03-28 02:16:34 +00:00
switch_channel_t * channel = NULL ;
const char * sip_auth_username = NULL ;
const char * sip_auth_password = NULL ;
2009-03-28 02:27:20 +00:00
if ( session & & ( channel = switch_core_session_get_channel ( session ) ) ) {
2009-03-28 02:16:34 +00:00
sip_auth_username = switch_channel_get_variable ( channel , " sip_auth_username " ) ;
sip_auth_password = switch_channel_get_variable ( channel , " sip_auth_password " ) ;
}
2007-03-31 19:01:33 +00:00
2008-11-03 17:39:09 +00:00
if ( sofia_private & & * sofia_private - > auth_gateway_name ) {
gw_name = sofia_private - > auth_gateway_name ;
}
2007-03-31 19:01:33 +00:00
if ( session ) {
private_object_t * tech_pvt ;
2008-07-17 13:36:02 +00:00
2009-02-09 17:56:38 +00:00
if ( ( tech_pvt = switch_core_session_get_private ( session ) ) & & sofia_test_flag ( tech_pvt , TFLAG_REFER ) ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Received reply from REFER \n " ) ;
2008-07-17 13:36:02 +00:00
goto end ;
}
2009-04-09 22:43:00 +00:00
gw_name = switch_channel_get_variable ( switch_core_session_get_channel ( session ) , " sip_use_gateway " ) ;
2008-07-17 13:36:02 +00:00
}
2007-03-31 19:01:33 +00:00
if ( sip - > sip_www_authenticate ) {
authenticate = sip - > sip_www_authenticate ;
} else if ( sip - > sip_proxy_authenticate ) {
authenticate = sip - > sip_proxy_authenticate ;
} else {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Missing Authenticate Header! \n " ) ;
2008-07-17 13:36:02 +00:00
goto end ;
2007-03-31 19:01:33 +00:00
}
scheme = ( char const * ) authenticate - > au_scheme ;
if ( authenticate - > au_params ) {
for ( indexnum = 0 ; ( cur = ( char * ) authenticate - > au_params [ indexnum ] ) ; indexnum + + ) {
if ( ( realm = strstr ( cur , " realm= " ) ) ) {
realm + = 6 ;
break ;
}
}
}
2008-07-17 14:32:01 +00:00
if ( ! gateway ) {
if ( gw_name ) {
2010-02-06 03:38:24 +00:00
var_gateway = sofia_reg_find_gateway ( ( char * ) gw_name ) ;
2008-07-17 14:32:01 +00:00
}
if ( ! var_gateway & & realm ) {
char rb [ 512 ] = " " ;
char * p = ( char * ) realm ;
2010-02-06 03:38:24 +00:00
while ( ( * p = = ' " ' ) ) {
2008-07-17 14:32:01 +00:00
p + + ;
}
switch_set_string ( rb , p ) ;
if ( ( p = strchr ( rb , ' " ' ) ) ) {
* p = ' \0 ' ;
}
2009-11-15 03:14:06 +00:00
if ( ! ( var_gateway = sofia_reg_find_gateway ( rb ) ) ) {
var_gateway = sofia_reg_find_gateway_by_realm ( rb ) ;
}
2008-07-17 14:32:01 +00:00
}
if ( ! var_gateway & & sip & & sip - > sip_to ) {
var_gateway = sofia_reg_find_gateway ( sip - > sip_to - > a_url - > url_host ) ;
}
2010-02-06 03:38:24 +00:00
2008-07-17 14:32:01 +00:00
if ( var_gateway ) {
gateway = var_gateway ;
}
}
2010-02-06 03:38:24 +00:00
2008-07-17 14:32:01 +00:00
2007-03-31 19:01:33 +00:00
if ( ! ( scheme & & realm ) ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " No scheme and realm! \n " ) ;
2008-07-17 13:36:02 +00:00
goto end ;
2007-03-31 19:01:33 +00:00
}
2009-03-28 01:50:36 +00:00
if ( sip_auth_username & & sip_auth_password ) {
switch_snprintf ( authentication , sizeof ( authentication ) , " %s:%s:%s:%s " , scheme , realm , sip_auth_username , sip_auth_password ) ;
} else if ( gateway ) {
switch_snprintf ( authentication , sizeof ( authentication ) , " %s:%s:%s:%s " , scheme , realm , gateway - > auth_username , gateway - > register_password ) ;
} else {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " No Matching gateway found \n " ) ;
2010-02-06 03:38:24 +00:00
goto cancel ;
2007-03-31 19:01:33 +00:00
}
2007-09-19 15:28:16 +00:00
2008-10-12 03:56:11 +00:00
if ( profile - > debug ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Authenticating '%s' with '%s'. \n " ,
2010-02-06 03:38:24 +00:00
( sip_auth_username & & sip_auth_password ) ? sip_auth_username : gateway - > auth_username , authentication ) ;
2008-10-12 03:56:11 +00:00
}
2007-03-31 19:01:33 +00:00
ss_state = nua_callstate_authenticating ;
tl_gets ( tags , NUTAG_CALLSTATE_REF ( ss_state ) , SIPTAG_WWW_AUTHENTICATE_REF ( authenticate ) , TAG_END ( ) ) ;
2009-03-28 01:50:36 +00:00
nua_authenticate ( nh , SIPTAG_EXPIRES_STR ( gateway ? gateway - > expires_str : " 3600 " ) , NUTAG_AUTH ( authentication ) , TAG_END ( ) ) ;
2007-12-04 00:21:32 +00:00
2008-07-17 13:36:02 +00:00
goto end ;
2007-04-20 16:05:37 +00:00
2008-05-27 04:54:52 +00:00
cancel :
2007-12-04 00:21:32 +00:00
2007-04-20 16:05:37 +00:00
if ( session ) {
2008-01-28 07:26:10 +00:00
switch_channel_hangup ( switch_core_session_get_channel ( session ) , SWITCH_CAUSE_MANDATORY_IE_MISSING ) ;
2007-04-20 16:05:37 +00:00
} else {
nua_cancel ( nh , TAG_END ( ) ) ;
}
2008-05-27 04:54:52 +00:00
2010-02-06 03:38:24 +00:00
end :
2008-07-17 13:36:02 +00:00
if ( var_gateway ) {
sofia_reg_release_gateway ( var_gateway ) ;
}
return ;
2007-03-31 19:01:33 +00:00
}
2009-11-12 03:52:07 +00:00
typedef struct {
char * nonce ;
switch_size_t nplen ;
int last_nc ;
} nonce_cb_t ;
static int sofia_reg_nonce_callback ( void * pArg , int argc , char * * argv , char * * columnNames )
{
nonce_cb_t * cb = ( nonce_cb_t * ) pArg ;
switch_copy_string ( cb - > nonce , argv [ 0 ] , cb - > nplen ) ;
2009-11-23 14:57:56 +00:00
if ( argc = = 2 ) {
cb - > last_nc = zstr ( argv [ 1 ] ) ? 0 : atoi ( argv [ 1 ] ) ;
} else {
cb - > last_nc = 0 ;
}
2009-11-12 03:52:07 +00:00
return 0 ;
}
2010-02-02 21:04:41 +00:00
static int sofia_reg_regcount_callback ( void * pArg , int argc , char * * argv , char * * columnNames )
{
int * ret = ( int * ) pArg ;
if ( argc = = 1 ) {
* ret = atoi ( argv [ 0 ] ) ;
}
return 0 ;
}
2010-02-06 03:38:24 +00:00
auth_res_t sofia_reg_parse_auth ( sofia_profile_t * profile ,
sip_authorization_t const * authorization ,
sip_t const * sip ,
2009-03-25 20:14:07 +00:00
const char * regstr ,
2010-02-06 03:38:24 +00:00
char * np ,
size_t nplen ,
char * ip ,
switch_event_t * * v_event ,
long exptime , sofia_regtype_t regtype , const char * to_user , switch_event_t * * auth_params , long * reg_count )
2007-03-31 19:01:33 +00:00
{
int indexnum ;
const char * cur ;
su_md5_t ctx ;
char uridigest [ 2 * SU_MD5_DIGEST_SIZE + 1 ] ;
char bigdigest [ 2 * SU_MD5_DIGEST_SIZE + 1 ] ;
2007-04-20 18:06:06 +00:00
char * username , * realm , * nonce , * uri , * qop , * cnonce , * nc , * response , * input = NULL , * input2 = NULL ;
2007-03-31 19:01:33 +00:00
auth_res_t ret = AUTH_FORBIDDEN ;
2008-01-31 22:40:48 +00:00
int first = 0 ;
2007-08-21 14:48:16 +00:00
const char * passwd = NULL ;
const char * a1_hash = NULL ;
2009-09-25 20:07:40 +00:00
const char * mwi_account = NULL ;
2010-04-26 06:04:45 -04:00
switch_bool_t allow_empty_password = SWITCH_TRUE ;
2010-02-04 14:50:53 +00:00
const char * call_id = NULL ;
2009-10-27 06:14:00 +00:00
char * sql ;
2009-05-18 17:16:48 +00:00
char * number_alias = NULL ;
2008-12-23 19:47:50 +00:00
switch_xml_t domain , xml = NULL , user , param , uparams , dparams , group = NULL , gparams = NULL ;
2007-08-27 20:43:34 +00:00
char hexdigest [ 2 * SU_MD5_DIGEST_SIZE + 1 ] = " " ;
2007-10-30 14:32:00 +00:00
char * domain_name = NULL ;
2008-01-23 20:59:25 +00:00
switch_event_t * params = NULL ;
2008-06-04 16:04:08 +00:00
const char * auth_acl = NULL ;
2009-11-12 03:52:07 +00:00
long ncl = 0 ;
2010-01-07 18:47:53 +00:00
sip_unknown_t * un ;
2010-02-02 21:04:41 +00:00
const char * user_agent = NULL ;
const char * user_agent_filter = profile - > user_agent_filter ;
uint32_t max_registrations_perext = profile - > max_registrations_perext ;
2007-10-30 14:32:00 +00:00
2007-04-30 16:26:44 +00:00
username = realm = nonce = uri = qop = cnonce = nc = response = NULL ;
2008-05-27 04:54:52 +00:00
2007-03-31 19:01:33 +00:00
if ( authorization - > au_params ) {
for ( indexnum = 0 ; ( cur = authorization - > au_params [ indexnum ] ) ; indexnum + + ) {
char * var , * val , * p , * work ;
var = val = work = NULL ;
if ( ( work = strdup ( cur ) ) ) {
var = work ;
if ( ( val = strchr ( var , ' = ' ) ) ) {
* val + + = ' \0 ' ;
while ( * val = = ' " ' ) {
* val + + = ' \0 ' ;
}
if ( ( p = strchr ( val , ' " ' ) ) ) {
* p = ' \0 ' ;
}
2007-04-20 18:06:06 +00:00
if ( ! strcasecmp ( var , " username " ) ) {
username = strdup ( val ) ;
} else if ( ! strcasecmp ( var , " realm " ) ) {
realm = strdup ( val ) ;
} else if ( ! strcasecmp ( var , " nonce " ) ) {
2007-03-31 19:01:33 +00:00
nonce = strdup ( val ) ;
} else if ( ! strcasecmp ( var , " uri " ) ) {
uri = strdup ( val ) ;
} else if ( ! strcasecmp ( var , " qop " ) ) {
qop = strdup ( val ) ;
} else if ( ! strcasecmp ( var , " cnonce " ) ) {
cnonce = strdup ( val ) ;
} else if ( ! strcasecmp ( var , " response " ) ) {
response = strdup ( val ) ;
} else if ( ! strcasecmp ( var , " nc " ) ) {
nc = strdup ( val ) ;
}
}
free ( work ) ;
}
}
}
2008-01-31 22:40:48 +00:00
if ( ! ( username & & realm & & nonce & & uri & & response ) ) {
2007-03-31 19:01:33 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Invalid Authorization header! \n " ) ;
2008-01-16 15:06:33 +00:00
ret = AUTH_STALE ;
2007-03-31 19:01:33 +00:00
goto end ;
}
2008-05-27 04:54:52 +00:00
2008-01-12 19:15:05 +00:00
/* Optional check that auth name == SIP username */
2009-02-09 17:56:38 +00:00
if ( ( regtype = = REG_REGISTER ) & & sofia_test_pflag ( profile , PFLAG_CHECKUSER ) ) {
2009-10-23 16:03:42 +00:00
if ( zstr ( username ) | | zstr ( to_user ) | | strcasecmp ( to_user , username ) ) {
2008-01-12 19:15:05 +00:00
/* Names don't match, so fail */
2009-11-17 00:12:54 +00:00
if ( profile - > debug ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " SIP username %s does not match auth username \n " , switch_str_nil ( to_user ) ) ;
}
2008-01-12 19:15:05 +00:00
goto end ;
}
}
2007-03-31 19:01:33 +00:00
2010-02-02 21:04:41 +00:00
user_agent = ( sip & & sip - > sip_user_agent ) ? sip - > sip_user_agent - > g_string : " unknown " ;
2009-10-23 16:03:42 +00:00
if ( zstr ( np ) ) {
2009-11-12 03:52:07 +00:00
nonce_cb_t cb = { 0 } ;
long nc_long = 0 ;
2007-08-21 14:48:16 +00:00
first = 1 ;
2010-02-06 03:38:24 +00:00
2009-10-28 16:55:29 +00:00
if ( nc ) {
2009-11-12 03:52:07 +00:00
nc_long = strtoul ( nc , 0 , 16 ) ;
sql = switch_mprintf ( " select nonce,last_nc from sip_authentication where nonce='%q' and last_nc < %lu " , nonce , nc_long ) ;
2009-10-28 16:55:29 +00:00
} else {
sql = switch_mprintf ( " select nonce from sip_authentication where nonce='%q' " , nonce ) ;
}
2009-11-12 03:52:07 +00:00
cb . nonce = np ;
cb . nplen = nplen ;
2010-02-06 03:38:24 +00:00
2007-12-12 23:21:45 +00:00
switch_assert ( sql ! = NULL ) ;
2010-05-04 09:50:55 -05:00
sofia_glue_execute_sql_callback ( profile , profile - > ireg_mutex , sql , sofia_reg_nonce_callback , & cb ) ;
2009-11-12 03:52:07 +00:00
free ( sql ) ;
//if (!sofia_glue_execute_sql2str(profile, profile->ireg_mutex, sql, np, nplen)) {
if ( zstr ( np ) ) {
sql = switch_mprintf ( " delete from sip_authentication where nonce='%q' " , nonce ) ;
sofia_glue_execute_sql ( profile , & sql , SWITCH_TRUE ) ;
2007-03-31 19:01:33 +00:00
ret = AUTH_STALE ;
goto end ;
}
2009-11-12 03:52:07 +00:00
if ( reg_count ) {
* reg_count = cb . last_nc + 1 ;
}
2008-05-27 04:54:52 +00:00
}
2008-10-02 17:10:05 +00:00
switch_event_create ( & params , SWITCH_EVENT_REQUEST_PARAMS ) ;
2008-01-23 20:59:25 +00:00
switch_assert ( params ) ;
2008-01-24 11:56:57 +00:00
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " action " , " sip_auth " ) ;
2008-01-24 22:09:39 +00:00
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " sip_profile " , profile - > name ) ;
2010-02-02 21:04:41 +00:00
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " sip_user_agent " , user_agent ) ;
2008-01-24 22:09:39 +00:00
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " sip_auth_username " , username ) ;
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " sip_auth_realm " , realm ) ;
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " sip_auth_nonce " , nonce ) ;
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " sip_auth_uri " , uri ) ;
2008-10-14 22:13:49 +00:00
if ( sip - > sip_contact ) {
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " sip_contact_user " , sip - > sip_contact - > m_url - > url_user ) ;
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " sip_contact_host " , sip - > sip_contact - > m_url - > url_host ) ;
}
if ( sip - > sip_to ) {
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " sip_to_user " , sip - > sip_to - > a_url - > url_user ) ;
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " sip_to_host " , sip - > sip_to - > a_url - > url_host ) ;
if ( sip - > sip_to - > a_url - > url_port ) {
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " sip_to_port " , sip - > sip_to - > a_url - > url_port ) ;
}
}
if ( sip - > sip_from ) {
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " sip_from_user " , sip - > sip_from - > a_url - > url_user ) ;
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " sip_from_host " , sip - > sip_from - > a_url - > url_host ) ;
if ( sip - > sip_from - > a_url - > url_port ) {
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " sip_from_port " , sip - > sip_from - > a_url - > url_port ) ;
}
}
if ( sip - > sip_request ) {
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " sip_request_user " , sip - > sip_request - > rq_url - > url_user ) ;
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " sip_request_host " , sip - > sip_request - > rq_url - > url_host ) ;
if ( sip - > sip_request - > rq_url - > url_port ) {
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " sip_request_port " , sip - > sip_request - > rq_url - > url_port ) ;
}
}
2010-01-07 18:47:53 +00:00
for ( un = sip - > sip_unknown ; un ; un = un - > un_next ) {
if ( ! strncasecmp ( un - > un_name , " X- " , 2 ) ) {
if ( ! zstr ( un - > un_value ) ) {
2010-01-21 00:12:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG10 , " adding %s => %s to xml_curl request \n " , un - > un_name , un - > un_value ) ;
2010-01-07 18:47:53 +00:00
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , un - > un_name , un - > un_value ) ;
}
} else {
2010-01-21 00:12:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG10 , " skipping %s => %s from xml_curl request \n " , un - > un_name , un - > un_value ) ;
2010-01-07 18:47:53 +00:00
}
}
2008-05-27 04:54:52 +00:00
if ( qop ) {
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " sip_auth_qop " , qop ) ;
}
if ( cnonce ) {
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " sip_auth_cnonce " , cnonce ) ;
}
if ( nc ) {
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " sip_auth_nc " , nc ) ;
}
2008-01-24 22:09:39 +00:00
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " sip_auth_response " , response ) ;
2008-01-31 22:40:48 +00:00
2008-01-24 22:09:39 +00:00
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " sip_auth_method " , ( sip & & sip - > sip_request ) ? sip - > sip_request - > rq_method_name : NULL ) ;
2009-03-25 20:14:07 +00:00
if ( auth_params ) {
switch_event_dup ( auth_params , params ) ;
}
2008-05-27 04:54:52 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( profile - > reg_domain ) ) {
2007-10-30 14:32:00 +00:00
domain_name = profile - > reg_domain ;
} else {
domain_name = realm ;
}
2008-05-27 04:54:52 +00:00
2010-02-06 03:38:24 +00:00
if ( switch_xml_locate_user ( " id " , zstr ( username ) ? " nobody " : username , domain_name , ip , & xml , & domain , & user , & group , params ) ! = SWITCH_STATUS_SUCCESS ) {
2008-10-11 05:42:52 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Can't find user [%s@%s] \n "
2008-07-22 15:07:16 +00:00
" You must define a domain called '%s' in your directory and add a user with the id= \" %s \" attribute \n "
2010-02-06 03:38:24 +00:00
" and you must configure your device to use the proper domain in it's authentication credentials. \n " , username , domain_name ,
domain_name , username ) ;
2008-07-22 15:07:16 +00:00
2007-08-21 14:48:16 +00:00
ret = AUTH_FORBIDDEN ;
goto end ;
2009-02-27 16:03:22 +00:00
} else {
const char * type = switch_xml_attr ( user , " type " ) ;
if ( type & & ! strcasecmp ( type , " pointer " ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Cant register a pointer. \n " ) ;
ret = AUTH_FORBIDDEN ;
goto end ;
}
2007-08-21 14:48:16 +00:00
}
2010-02-06 03:38:24 +00:00
2009-05-18 17:16:48 +00:00
if ( ! ( number_alias = ( char * ) switch_xml_attr ( user , " number-alias " ) ) ) {
2009-10-23 16:03:42 +00:00
number_alias = zstr ( username ) ? " nobody " : username ;
2007-10-12 17:12:31 +00:00
}
2007-12-10 23:48:54 +00:00
dparams = switch_xml_child ( domain , " params " ) ;
uparams = switch_xml_child ( user , " params " ) ;
2008-12-23 17:36:50 +00:00
if ( group ) {
gparams = switch_xml_child ( group , " params " ) ;
}
2007-12-10 23:48:54 +00:00
2007-12-12 23:28:09 +00:00
if ( ! ( dparams | | uparams ) ) {
2007-12-10 23:48:54 +00:00
ret = AUTH_OK ;
goto skip_auth ;
}
if ( dparams ) {
for ( param = switch_xml_child ( dparams , " param " ) ; param ; param = param - > next ) {
const char * var = switch_xml_attr_soft ( param , " name " ) ;
const char * val = switch_xml_attr_soft ( param , " value " ) ;
2008-05-27 04:54:52 +00:00
2008-08-12 18:28:13 +00:00
if ( ! strcasecmp ( var , " sip-forbid-register " ) & & switch_true ( val ) ) {
ret = AUTH_FORBIDDEN ;
goto end ;
}
2007-12-10 23:48:54 +00:00
if ( ! strcasecmp ( var , " password " ) ) {
passwd = val ;
}
2008-05-27 04:54:52 +00:00
2008-06-04 16:13:15 +00:00
if ( ! strcasecmp ( var , " auth-acl " ) ) {
2008-06-04 16:04:08 +00:00
auth_acl = val ;
}
2007-12-10 23:48:54 +00:00
if ( ! strcasecmp ( var , " a1-hash " ) ) {
a1_hash = val ;
}
2009-09-25 20:07:40 +00:00
if ( ! strcasecmp ( var , " mwi-account " ) ) {
mwi_account = val ;
}
2010-04-26 06:04:45 -04:00
if ( ! strcasecmp ( var , " allow-empty-password " ) ) {
allow_empty_password = switch_true ( val ) ;
}
2010-02-02 21:04:41 +00:00
if ( ! strcasecmp ( var , " user-agent-filter " ) ) {
user_agent_filter = val ;
}
if ( ! strcasecmp ( var , " max-registrations-per-extension " ) ) {
max_registrations_perext = atoi ( val ) ;
}
2007-04-20 18:06:06 +00:00
}
2007-12-10 23:48:54 +00:00
}
2008-12-23 17:36:50 +00:00
if ( gparams ) {
for ( param = switch_xml_child ( gparams , " param " ) ; param ; param = param - > next ) {
const char * var = switch_xml_attr_soft ( param , " name " ) ;
const char * val = switch_xml_attr_soft ( param , " value " ) ;
if ( ! strcasecmp ( var , " sip-forbid-register " ) & & switch_true ( val ) ) {
ret = AUTH_FORBIDDEN ;
goto end ;
}
if ( ! strcasecmp ( var , " password " ) ) {
passwd = val ;
}
if ( ! strcasecmp ( var , " auth-acl " ) ) {
auth_acl = val ;
}
if ( ! strcasecmp ( var , " a1-hash " ) ) {
a1_hash = val ;
}
2009-09-25 20:07:40 +00:00
if ( ! strcasecmp ( var , " mwi-account " ) ) {
mwi_account = val ;
}
2010-04-26 06:04:45 -04:00
if ( ! strcasecmp ( var , " allow-empty-password " ) ) {
allow_empty_password = switch_true ( val ) ;
}
2010-02-02 21:04:41 +00:00
if ( ! strcasecmp ( var , " user-agent-filter " ) ) {
user_agent_filter = val ;
}
if ( ! strcasecmp ( var , " max-registrations-per-extension " ) ) {
max_registrations_perext = atoi ( val ) ;
}
2008-12-23 17:36:50 +00:00
}
}
2007-12-10 23:48:54 +00:00
if ( uparams ) {
for ( param = switch_xml_child ( uparams , " param " ) ; param ; param = param - > next ) {
const char * var = switch_xml_attr_soft ( param , " name " ) ;
const char * val = switch_xml_attr_soft ( param , " value " ) ;
2008-05-27 04:54:52 +00:00
2008-08-12 18:28:13 +00:00
if ( ! strcasecmp ( var , " sip-forbid-register " ) & & switch_true ( val ) ) {
ret = AUTH_FORBIDDEN ;
goto end ;
}
2007-12-10 23:48:54 +00:00
if ( ! strcasecmp ( var , " password " ) ) {
passwd = val ;
}
2008-05-27 04:54:52 +00:00
2008-06-04 16:13:15 +00:00
if ( ! strcasecmp ( var , " auth-acl " ) ) {
2008-06-04 16:04:08 +00:00
auth_acl = val ;
}
2007-12-10 23:48:54 +00:00
if ( ! strcasecmp ( var , " a1-hash " ) ) {
a1_hash = val ;
}
2009-09-25 20:07:40 +00:00
if ( ! strcasecmp ( var , " mwi-account " ) ) {
mwi_account = val ;
}
2010-04-26 06:04:45 -04:00
if ( ! strcasecmp ( var , " allow-empty-password " ) ) {
allow_empty_password = switch_true ( val ) ;
}
2010-02-02 21:04:41 +00:00
if ( ! strcasecmp ( var , " user-agent-filter " ) ) {
user_agent_filter = val ;
}
if ( ! strcasecmp ( var , " max-registrations-per-extension " ) ) {
max_registrations_perext = atoi ( val ) ;
}
2007-04-20 18:06:06 +00:00
}
2007-08-21 14:48:16 +00:00
}
2007-04-30 16:26:44 +00:00
2008-06-04 16:04:08 +00:00
if ( auth_acl ) {
if ( ! switch_check_network_list_ip ( ip , auth_acl ) ) {
2010-09-29 15:47:58 -05:00
int network_ip_is_proxy = 0 ;
uint32_t x = 0 ;
2010-01-07 18:47:53 +00:00
char * last_acl = NULL ;
if ( profile - > proxy_acl_count = = 0 ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " IP %s Rejected by user acl [%s] and no proxy acl present \n " , ip , auth_acl ) ;
ret = AUTH_FORBIDDEN ;
goto end ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " IP %s Rejected by user acl [%s] checking proxy ACLs now \n " , ip , auth_acl ) ;
}
/* Check if network_ip is a proxy allowed to send us calls */
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " %d acls to check for proxy \n " , profile - > proxy_acl_count ) ;
2010-02-06 03:38:24 +00:00
2010-01-07 18:47:53 +00:00
for ( x = 0 ; x < profile - > proxy_acl_count ; x + + ) {
last_acl = profile - > proxy_acl [ x ] ;
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " checking %s against acl %s \n " , ip , last_acl ) ;
2010-01-07 18:47:53 +00:00
if ( switch_check_network_list_ip ( ip , last_acl ) ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " %s is a proxy according to the %s acl \n " , ip , last_acl ) ;
2010-01-07 18:47:53 +00:00
network_ip_is_proxy = 1 ;
break ;
}
}
/*
* if network_ip is a proxy allowed to send traffic , check for auth
* ip header and see if it matches against the auth acl
*/
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " network ip is a proxy [%d] \n " , network_ip_is_proxy ) ;
if ( network_ip_is_proxy ) {
int x_auth_ip = 0 ;
for ( un = sip - > sip_unknown ; un ; un = un - > un_next ) {
if ( ! strcasecmp ( un - > un_name , " X-AUTH-IP " ) ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " found auth ip [%s] header of [%s] \n " , un - > un_name , un - > un_value ) ;
2010-01-07 18:47:53 +00:00
if ( ! zstr ( un - > un_value ) ) {
if ( ! switch_check_network_list_ip ( un - > un_value , auth_acl ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " IP %s Rejected by user acl %s \n " , un - > un_value , auth_acl ) ;
ret = AUTH_FORBIDDEN ;
goto end ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG ,
2010-02-06 03:38:24 +00:00
" IP %s allowed by acl %s, checking credentials \n " , un - > un_value , auth_acl ) ;
2010-01-07 18:47:53 +00:00
x_auth_ip = 1 ;
break ;
}
}
}
}
if ( ! x_auth_ip ) {
ret = AUTH_FORBIDDEN ;
goto end ;
}
}
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " IP [%s] passed ACL check [%s] \n " , ip , auth_acl ) ;
2008-06-04 16:04:08 +00:00
}
}
2010-02-06 03:38:24 +00:00
2010-04-26 06:04:45 -04:00
if ( ! allow_empty_password & & zstr ( passwd ) & & zstr ( a1_hash ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Empty password denied for user %s@%s \n " , username , domain_name ) ;
ret = AUTH_FORBIDDEN ;
goto end ;
}
2009-10-23 16:03:42 +00:00
if ( zstr ( passwd ) & & zstr ( a1_hash ) ) {
2007-09-19 18:39:46 +00:00
ret = AUTH_OK ;
2007-12-10 23:48:54 +00:00
goto skip_auth ;
2007-09-19 18:39:46 +00:00
}
2010-02-06 03:38:24 +00:00
2007-09-19 18:39:46 +00:00
if ( ! a1_hash ) {
input = switch_mprintf ( " %s:%s:%s " , username , realm , passwd ) ;
su_md5_init ( & ctx ) ;
su_md5_strupdate ( & ctx , input ) ;
su_md5_hexdigest ( & ctx , hexdigest ) ;
su_md5_deinit ( & ctx ) ;
switch_safe_free ( input ) ;
a1_hash = hexdigest ;
2008-05-27 04:54:52 +00:00
2007-09-19 18:39:46 +00:00
}
2010-02-02 21:04:41 +00:00
if ( user_agent_filter ) {
if ( switch_regex_match ( user_agent , user_agent_filter ) = = SWITCH_STATUS_SUCCESS ) {
if ( sofia_test_pflag ( profile , PFLAG_LOG_AUTH_FAIL ) ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG ,
" SIP auth OK (REGISTER) due to user-agent-filter. Filter \" %s \" User-Agent \" %s \" \n " , user_agent_filter , user_agent ) ;
2010-02-02 21:04:41 +00:00
}
} else {
ret = AUTH_FORBIDDEN ;
if ( sofia_test_pflag ( profile , PFLAG_LOG_AUTH_FAIL ) ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING ,
" SIP auth failure (REGISTER) due to user-agent-filter. Filter \" %s \" User-Agent \" %s \" \n " , user_agent_filter ,
user_agent ) ;
2010-02-02 21:04:41 +00:00
}
goto end ;
}
}
2010-02-06 03:38:24 +00:00
if ( max_registrations_perext > 0 & & ( sip & & sip - > sip_contact & & ( sip - > sip_contact - > m_expires = = NULL | | atol ( sip - > sip_contact - > m_expires ) > 0 ) ) ) {
/* if expires is null still process */
/* expires == 0 means the phone is going to unregiser, so don't count against max */
2010-09-29 15:47:58 -05:00
uint32_t count = 0 ;
2010-02-04 14:50:53 +00:00
call_id = sip - > sip_call_id - > i_id ;
switch_assert ( call_id ) ;
2010-02-06 03:38:24 +00:00
2010-02-04 14:50:53 +00:00
sql = switch_mprintf ( " select count(sip_user) from sip_registrations where sip_user='%q' AND call_id <> '%q' " , username , call_id ) ;
2010-02-02 21:04:41 +00:00
switch_assert ( sql ! = NULL ) ;
sofia_glue_execute_sql_callback ( profile , NULL , sql , sofia_reg_regcount_callback , & count ) ;
free ( sql ) ;
2010-02-06 03:38:24 +00:00
if ( count + 1 > max_registrations_perext ) {
2010-02-02 21:04:41 +00:00
ret = AUTH_FORBIDDEN ;
if ( sofia_test_pflag ( profile , PFLAG_LOG_AUTH_FAIL ) ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING ,
" SIP auth failure (REGISTER) due to reaching max allowed registrations. Count: %d \n " , count ) ;
2010-02-02 21:04:41 +00:00
}
goto end ;
}
}
2010-02-06 03:38:24 +00:00
2008-05-27 04:54:52 +00:00
for_the_sake_of_interop :
2007-09-19 18:39:46 +00:00
if ( ( input = switch_mprintf ( " %s:%q " , regstr , uri ) ) ) {
su_md5_init ( & ctx ) ;
su_md5_strupdate ( & ctx , input ) ;
su_md5_hexdigest ( & ctx , uridigest ) ;
su_md5_deinit ( & ctx ) ;
}
2008-05-27 04:54:52 +00:00
if ( nc & & cnonce & & qop ) {
2009-07-23 17:48:36 +00:00
input2 = switch_mprintf ( " %s:%s:%s:%s:%s:%s " , a1_hash , nonce , nc , cnonce , qop , uridigest ) ;
2008-05-27 04:54:52 +00:00
} else {
2009-07-23 17:48:36 +00:00
input2 = switch_mprintf ( " %s:%s:%s " , a1_hash , nonce , uridigest ) ;
2008-05-27 04:54:52 +00:00
}
2007-09-19 18:39:46 +00:00
2009-10-28 16:55:29 +00:00
if ( input2 ) {
memset ( & ctx , 0 , sizeof ( ctx ) ) ;
su_md5_init ( & ctx ) ;
su_md5_strupdate ( & ctx , input2 ) ;
su_md5_hexdigest ( & ctx , bigdigest ) ;
su_md5_deinit ( & ctx ) ;
}
2008-01-31 22:40:48 +00:00
2009-10-28 16:55:29 +00:00
if ( input2 & & ! strcasecmp ( bigdigest , response ) ) {
2008-05-27 04:54:52 +00:00
ret = AUTH_OK ;
} else {
if ( ( profile - > ndlb & PFLAG_NDLB_BROKEN_AUTH_HASH ) & & strcasecmp ( regstr , " REGISTER " ) & & strcasecmp ( regstr , " INVITE " ) ) {
/* some clients send an ACK with the method 'INVITE' in the hash which will break auth so we will
try again with INVITE so we don ' t get people complaining to us when someone else ' s client has a bug . . . . . .
*/
switch_safe_free ( input ) ;
switch_safe_free ( input2 ) ;
regstr = " INVITE " ;
goto for_the_sake_of_interop ;
}
2008-01-31 22:40:48 +00:00
2008-05-27 04:54:52 +00:00
ret = AUTH_FORBIDDEN ;
}
2009-10-29 14:33:48 +00:00
2009-10-29 08:35:53 +00:00
switch_safe_free ( input2 ) ;
2008-05-27 04:54:52 +00:00
skip_auth :
2007-12-10 23:48:54 +00:00
2007-09-19 18:39:46 +00:00
if ( first & & ret = = AUTH_OK ) {
2007-11-02 19:19:19 +00:00
if ( v_event ) {
2009-03-24 23:44:03 +00:00
switch_event_create_plain ( v_event , SWITCH_EVENT_REQUEST_PARAMS ) ;
2007-11-02 19:19:19 +00:00
}
2009-03-24 23:44:03 +00:00
2010-02-06 03:38:24 +00:00
2007-11-02 17:34:14 +00:00
if ( v_event & & * v_event ) {
2009-06-19 20:49:18 +00:00
short int xparams_type [ 6 ] ;
switch_xml_t xparams [ 6 ] ;
2007-12-10 23:48:54 +00:00
int i = 0 ;
2009-05-18 17:16:48 +00:00
switch_event_add_header_string ( * v_event , SWITCH_STACK_BOTTOM , " sip_number_alias " , number_alias ) ;
2008-08-16 02:19:43 +00:00
switch_event_add_header_string ( * v_event , SWITCH_STACK_BOTTOM , " sip_auth_username " , username ) ;
switch_event_add_header_string ( * v_event , SWITCH_STACK_BOTTOM , " sip_auth_realm " , realm ) ;
2009-05-18 17:16:48 +00:00
switch_event_add_header_string ( * v_event , SWITCH_STACK_BOTTOM , " number_alias " , number_alias ) ;
2008-08-16 02:19:43 +00:00
switch_event_add_header_string ( * v_event , SWITCH_STACK_BOTTOM , " user_name " , username ) ;
2009-01-21 22:57:58 +00:00
switch_event_add_header_string ( * v_event , SWITCH_STACK_BOTTOM , " domain_name " , domain_name ) ;
2008-05-27 04:54:52 +00:00
2009-09-25 20:07:40 +00:00
if ( mwi_account ) {
switch_event_add_header_string ( * v_event , SWITCH_STACK_BOTTOM , " mwi-account " , mwi_account ) ;
}
2010-02-06 03:38:24 +00:00
2010-09-09 15:37:41 -04:00
if ( ( dparams = switch_xml_child ( domain , " params " ) ) ) {
2009-06-19 20:49:18 +00:00
xparams_type [ i ] = 0 ;
2010-09-09 15:37:41 -04:00
xparams [ i + + ] = dparams ;
2007-12-10 23:48:54 +00:00
}
2010-02-06 03:38:24 +00:00
2009-06-19 20:49:18 +00:00
if ( group & & ( gparams = switch_xml_child ( group , " params " ) ) ) {
xparams_type [ i ] = 0 ;
2008-12-23 17:36:50 +00:00
xparams [ i + + ] = gparams ;
}
2010-09-09 15:37:41 -04:00
if ( ( uparams = switch_xml_child ( user , " params " ) ) ) {
2009-06-19 20:49:18 +00:00
xparams_type [ i ] = 0 ;
2010-09-09 15:37:41 -04:00
xparams [ i + + ] = uparams ;
2009-06-19 20:49:18 +00:00
}
2010-09-09 15:37:41 -04:00
if ( ( dparams = switch_xml_child ( domain , " variables " ) ) ) {
2009-06-19 20:49:18 +00:00
xparams_type [ i ] = 1 ;
2010-09-09 15:37:41 -04:00
xparams [ i + + ] = dparams ;
2007-12-10 23:48:54 +00:00
}
2009-06-19 20:49:18 +00:00
if ( group & & ( gparams = switch_xml_child ( group , " variables " ) ) ) {
xparams_type [ i ] = 1 ;
xparams [ i + + ] = gparams ;
}
2010-09-09 15:37:41 -04:00
if ( ( uparams = switch_xml_child ( user , " variables " ) ) ) {
2009-06-19 20:49:18 +00:00
xparams_type [ i ] = 1 ;
2010-09-09 15:37:41 -04:00
xparams [ i + + ] = uparams ;
2009-06-19 20:49:18 +00:00
}
if ( i < = 6 ) {
2007-12-10 23:48:54 +00:00
int j = 0 ;
2010-09-09 15:37:41 -04:00
const char * gw_val = NULL ;
2007-12-10 23:48:54 +00:00
for ( j = 0 ; j < i ; j + + ) {
2010-02-06 03:38:24 +00:00
for ( param = switch_xml_child ( xparams [ j ] , ( xparams_type [ j ] ? " variable " : " param " ) ) ; param ; param = param - > next ) {
2007-12-10 23:48:54 +00:00
const char * var = switch_xml_attr_soft ( param , " name " ) ;
const char * val = switch_xml_attr_soft ( param , " value " ) ;
2010-02-06 03:38:24 +00:00
if ( ! zstr ( var ) & & ! zstr ( val ) & & ( xparams_type [ j ] = = 1 | | ! strncasecmp ( var , " sip- " , 4 ) | | ! strcasecmp ( var , " register-gateway " ) ) ) {
2010-09-09 15:37:41 -04:00
if ( profile - > debug ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " event_add_header -> '%s' = '%s' \n " , var , val ) ;
2009-06-19 20:49:18 +00:00
}
2010-09-09 15:37:41 -04:00
switch_event_add_header_string ( * v_event , SWITCH_STACK_BOTTOM , var , val ) ;
}
}
}
if ( ( gw_val = switch_event_get_header ( * v_event , " register-gateway " ) ) ) {
sofia_gateway_t * gateway_ptr = NULL ;
if ( ! strcasecmp ( gw_val , " all " ) ) {
switch_xml_t gateways_tag , gateway_tag ;
if ( ( gateways_tag = switch_xml_child ( user , " gateways " ) ) ) {
for ( gateway_tag = switch_xml_child ( gateways_tag , " gateway " ) ; gateway_tag ; gateway_tag = gateway_tag - > next ) {
char * name = ( char * ) switch_xml_attr_soft ( gateway_tag , " name " ) ;
if ( zstr ( name ) ) {
name = " anonymous " ;
}
2008-05-27 04:54:52 +00:00
2010-09-09 15:37:41 -04:00
if ( ( gateway_ptr = sofia_reg_find_gateway ( name ) ) ) {
reg_state_t ostate = gateway_ptr - > state ;
gateway_ptr - > retry = 0 ;
if ( exptime ) {
gateway_ptr - > state = REG_STATE_UNREGED ;
} else {
gateway_ptr - > state = REG_STATE_UNREGISTER ;
2007-12-10 23:48:54 +00:00
}
2010-09-09 15:37:41 -04:00
if ( ostate ! = gateway_ptr - > state ) {
sofia_reg_fire_custom_gateway_state_event ( gateway_ptr , 0 , NULL ) ;
2007-11-02 19:19:19 +00:00
}
2010-09-09 15:37:41 -04:00
sofia_reg_release_gateway ( gateway_ptr ) ;
}
2007-11-02 19:19:19 +00:00
2010-09-09 15:37:41 -04:00
}
}
} else {
int x , argc ;
char * mydata , * argv [ 50 ] ;
mydata = strdup ( gw_val ) ;
switch_assert ( mydata ! = NULL ) ;
argc = switch_separate_string ( mydata , ' , ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ;
for ( x = 0 ; x < argc ; x + + ) {
if ( ( gateway_ptr = sofia_reg_find_gateway ( ( char * ) argv [ x ] ) ) ) {
reg_state_t ostate = gateway_ptr - > state ;
gateway_ptr - > retry = 0 ;
if ( exptime ) {
gateway_ptr - > state = REG_STATE_UNREGED ;
} else {
gateway_ptr - > state = REG_STATE_UNREGISTER ;
}
if ( ostate ! = gateway_ptr - > state ) {
sofia_reg_fire_custom_gateway_state_event ( gateway_ptr , 0 , NULL ) ;
2007-12-10 23:48:54 +00:00
}
2010-09-09 15:37:41 -04:00
sofia_reg_release_gateway ( gateway_ptr ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Gateway '%s' not found. \n " , argv [ x ] ) ;
2007-09-18 17:31:36 +00:00
}
}
2010-09-09 15:37:41 -04:00
free ( mydata ) ;
2007-04-30 16:26:44 +00:00
}
}
}
}
2007-08-21 14:48:16 +00:00
}
2008-05-27 04:54:52 +00:00
end :
2008-01-23 20:59:25 +00:00
2009-10-28 16:55:29 +00:00
if ( nc & & cnonce & & qop ) {
2009-11-12 03:52:07 +00:00
ncl = strtoul ( nc , 0 , 16 ) ;
2009-10-28 16:55:29 +00:00
2009-10-30 11:09:53 +00:00
# if defined(_WIN32) && !defined(_WIN64)
2009-10-30 04:07:49 +00:00
# define LL_FMT "ll"
# else
# define LL_FMT "l"
# endif
2010-02-06 03:38:24 +00:00
sql = switch_mprintf ( " update sip_authentication set expires='% " LL_FMT " u',last_nc=%lu where nonce='%s' " ,
2009-11-12 03:52:07 +00:00
switch_epoch_time_now ( NULL ) + ( profile - > nonce_ttl ? profile - > nonce_ttl : exptime + 10 ) , ncl , nonce ) ;
2009-10-28 16:55:29 +00:00
switch_assert ( sql ! = NULL ) ;
2009-11-12 03:52:07 +00:00
sofia_glue_actually_execute_sql ( profile , sql , profile - > ireg_mutex ) ;
2009-10-28 16:55:29 +00:00
switch_safe_free ( sql ) ;
}
2008-01-23 20:59:25 +00:00
switch_event_destroy ( & params ) ;
2007-08-28 17:08:32 +00:00
if ( xml ) {
switch_xml_free ( xml ) ;
}
2008-01-23 20:59:25 +00:00
2007-03-31 19:01:33 +00:00
switch_safe_free ( input ) ;
2007-04-20 18:06:06 +00:00
switch_safe_free ( username ) ;
switch_safe_free ( realm ) ;
2007-03-31 19:01:33 +00:00
switch_safe_free ( nonce ) ;
switch_safe_free ( uri ) ;
switch_safe_free ( qop ) ;
switch_safe_free ( cnonce ) ;
switch_safe_free ( nc ) ;
switch_safe_free ( response ) ;
2009-11-12 03:52:07 +00:00
if ( reg_count & & ! * reg_count ) {
if ( ret = = AUTH_OK ) {
if ( ncl ) {
* reg_count = ncl ;
} else {
* reg_count = 1 ;
}
} else {
* reg_count = 0 ;
}
}
2007-03-31 19:01:33 +00:00
return ret ;
}
2008-07-17 14:32:01 +00:00
sofia_gateway_t * sofia_reg_find_gateway__ ( const char * file , const char * func , int line , const char * key )
2007-03-31 19:01:33 +00:00
{
2007-04-29 01:16:49 +00:00
sofia_gateway_t * gateway = NULL ;
2007-03-31 19:01:33 +00:00
2007-04-01 01:16:16 +00:00
switch_mutex_lock ( mod_sofia_globals . hash_mutex ) ;
2007-04-29 01:16:49 +00:00
if ( ( gateway = ( sofia_gateway_t * ) switch_core_hash_find ( mod_sofia_globals . gateway_hash , key ) ) ) {
2009-02-09 17:56:38 +00:00
if ( ! sofia_test_pflag ( gateway - > profile , PFLAG_RUNNING ) | | gateway - > deleted ) {
2008-05-27 04:54:52 +00:00
gateway = NULL ;
2008-04-04 18:53:24 +00:00
goto done ;
2008-01-08 16:35:20 +00:00
}
2010-02-16 00:07:50 +00:00
if ( sofia_reg_gateway_rdlock__ ( file , func , line , gateway ) ! = SWITCH_STATUS_SUCCESS ) {
2007-04-29 01:16:49 +00:00
gateway = NULL ;
}
}
2008-04-04 18:53:24 +00:00
2008-05-27 04:54:52 +00:00
done :
2007-04-29 01:16:49 +00:00
switch_mutex_unlock ( mod_sofia_globals . hash_mutex ) ;
2007-03-31 19:01:33 +00:00
return gateway ;
}
2009-11-15 03:14:06 +00:00
sofia_gateway_t * sofia_reg_find_gateway_by_realm__ ( const char * file , const char * func , int line , const char * key )
{
sofia_gateway_t * gateway = NULL ;
switch_hash_index_t * hi ;
const void * var ;
2010-02-06 03:38:24 +00:00
void * val ;
2009-11-15 03:14:06 +00:00
switch_mutex_lock ( mod_sofia_globals . hash_mutex ) ;
for ( hi = switch_hash_first ( NULL , mod_sofia_globals . gateway_hash ) ; hi ; hi = switch_hash_next ( hi ) ) {
switch_hash_this ( hi , & var , NULL , & val ) ;
2010-09-27 04:21:05 -04:00
if ( key & & ( gateway = ( sofia_gateway_t * ) val ) & & gateway - > register_realm & & ! strcasecmp ( gateway - > register_realm , key ) ) {
2010-05-21 14:40:36 -04:00
break ;
2009-11-15 03:14:06 +00:00
} else {
gateway = NULL ;
}
}
if ( gateway ) {
if ( ! sofia_test_pflag ( gateway - > profile , PFLAG_RUNNING ) | | gateway - > deleted ) {
gateway = NULL ;
goto done ;
}
if ( switch_thread_rwlock_tryrdlock ( gateway - > profile - > rwlock ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_ID_LOG , file , func , line , NULL , SWITCH_LOG_ERROR , " Profile %s is locked \n " , gateway - > profile - > name ) ;
gateway = NULL ;
}
}
if ( gateway ) {
# ifdef SOFIA_DEBUG_RWLOCKS
switch_log_printf ( SWITCH_CHANNEL_ID_LOG , file , func , line , SWITCH_LOG_ERROR , " XXXXXXXXXXXXXX GW LOCK %s \n " , gateway - > profile - > name ) ;
# endif
}
done :
switch_mutex_unlock ( mod_sofia_globals . hash_mutex ) ;
return gateway ;
}
2010-02-16 00:07:50 +00:00
switch_status_t sofia_reg_gateway_rdlock__ ( const char * file , const char * func , int line , sofia_gateway_t * gateway )
{
switch_status_t status = sofia_glue_profile_rdlock__ ( file , func , line , gateway - > profile ) ;
# ifdef SOFIA_DEBUG_RWLOCKS
2010-02-16 17:34:32 +00:00
if ( status = = SWITCH_STATUS_SUCCESS ) {
2010-02-16 00:07:50 +00:00
switch_log_printf ( SWITCH_CHANNEL_ID_LOG , file , func , line , SWITCH_LOG_ERROR , " XXXXXXXXXXXXXX GW LOCK %s \n " , gateway - > profile - > name ) ;
}
# endif
return status ;
}
2009-11-15 03:14:06 +00:00
2007-05-03 01:55:25 +00:00
void sofia_reg_release_gateway__ ( const char * file , const char * func , int line , sofia_gateway_t * gateway )
2007-04-29 01:16:49 +00:00
{
switch_thread_rwlock_unlock ( gateway - > profile - > rwlock ) ;
2007-05-03 01:55:25 +00:00
# ifdef SOFIA_DEBUG_RWLOCKS
switch_log_printf ( SWITCH_CHANNEL_ID_LOG , file , func , line , SWITCH_LOG_ERROR , " XXXXXXXXXXXXXX GW UNLOCK %s \n " , gateway - > profile - > name ) ;
# endif
2007-04-29 01:16:49 +00:00
}
2010-03-25 00:28:56 +00:00
switch_status_t sofia_reg_add_gateway ( sofia_profile_t * profile , const char * key , sofia_gateway_t * gateway )
2007-03-31 19:01:33 +00:00
{
2007-04-30 20:35:35 +00:00
switch_status_t status = SWITCH_STATUS_FALSE ;
2010-03-25 00:28:56 +00:00
char * pkey = switch_mprintf ( " %s::%s " , profile - > name , key ) ;
2007-04-30 20:35:35 +00:00
2007-04-01 01:16:16 +00:00
switch_mutex_lock ( mod_sofia_globals . hash_mutex ) ;
2010-03-25 00:28:56 +00:00
gateway - > next = profile - > gateways ;
profile - > gateways = gateway ;
2007-04-30 20:35:35 +00:00
if ( ! switch_core_hash_find ( mod_sofia_globals . gateway_hash , key ) ) {
status = switch_core_hash_insert ( mod_sofia_globals . gateway_hash , key , gateway ) ;
}
2010-03-25 00:28:56 +00:00
2010-02-18 22:39:08 +00:00
if ( ! switch_core_hash_find ( mod_sofia_globals . gateway_hash , pkey ) ) {
status = switch_core_hash_insert ( mod_sofia_globals . gateway_hash , pkey , gateway ) ;
}
2007-04-01 01:16:16 +00:00
switch_mutex_unlock ( mod_sofia_globals . hash_mutex ) ;
2007-03-31 19:01:33 +00:00
2010-02-18 22:39:08 +00:00
free ( pkey ) ;
2008-07-08 22:05:34 +00:00
if ( status = = SWITCH_STATUS_SUCCESS ) {
2010-01-23 18:43:38 +00:00
switch_event_t * s_event ;
2008-07-08 22:05:34 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " Added gateway '%s' to profile '%s' \n " , gateway - > name , gateway - > profile - > name ) ;
2010-01-23 18:43:38 +00:00
if ( switch_event_create_subclass ( & s_event , SWITCH_EVENT_CUSTOM , MY_EVENT_GATEWAY_ADD ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " Gateway " , gateway - > name ) ;
2010-01-23 19:08:44 +00:00
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " profile-name " , gateway - > profile - > name ) ;
2010-01-23 18:43:38 +00:00
switch_event_fire ( & s_event ) ;
}
2008-07-08 22:05:34 +00:00
}
2007-04-30 20:35:35 +00:00
return status ;
}
2007-03-31 19:01:33 +00:00
2008-01-27 05:02:52 +00:00
/* For Emacs:
* Local Variables :
* mode : c
2008-02-03 22:14:57 +00:00
* indent - tabs - mode : t
2008-01-27 05:02:52 +00:00
* tab - width : 4
* c - basic - offset : 4
* End :
* For VIM :
2008-07-03 19:12:26 +00:00
* vim : set softtabstop = 4 shiftwidth = 4 tabstop = 4 :
2008-01-27 05:02:52 +00:00
*/