2007-04-02 19:54:25 +00:00
|
|
|
/*
|
|
|
|
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
2012-04-18 11:51:48 -05:00
|
|
|
* Copyright (C) 2005-2012, 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>
|
2011-08-17 19:34:22 -05:00
|
|
|
* Leon de Rooij <leon@scarlet-internet.nl>
|
2007-04-02 19:54:25 +00:00
|
|
|
*
|
|
|
|
*
|
2011-08-17 19:34:22 -05:00
|
|
|
* sofia_reg.c -- SOFIA SIP Endpoint (registration code)
|
2007-04-02 19:54:25 +00:00
|
|
|
*
|
|
|
|
*/
|
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) {
|
2011-07-16 11:30:25 -05:00
|
|
|
gateway_ptr->sofia_private = malloc(sizeof(*gateway_ptr->sofia_private));
|
2011-07-16 01:02:22 -05:00
|
|
|
switch_assert(gateway_ptr->sofia_private);
|
2009-03-22 20:04:56 +00:00
|
|
|
}
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2012-07-17 17:01:10 -05:00
|
|
|
static void sofia_reg_new_sub_handle(sofia_gateway_subscription_t *gw_sub_ptr, int attach)
|
|
|
|
{
|
|
|
|
sofia_gateway_t *gateway_ptr = gw_sub_ptr->gateway;
|
2011-11-10 10:48:06 -06:00
|
|
|
char *user_via = NULL;
|
|
|
|
char *register_host = sofia_glue_get_register_host(gateway_ptr->register_proxy);
|
|
|
|
int ss_state = nua_callstate_authenticating;
|
2012-07-17 17:01:10 -05:00
|
|
|
|
2011-11-10 10:48:06 -06:00
|
|
|
/* check for NAT and place a Via header if necessary (hostname or non-local IP) */
|
|
|
|
if (register_host && sofia_glue_check_nat(gateway_ptr->profile, register_host)) {
|
|
|
|
user_via = sofia_glue_create_external_via(NULL, gateway_ptr->profile, gateway_ptr->register_transport);
|
|
|
|
}
|
2012-07-17 17:01:10 -05:00
|
|
|
|
|
|
|
if (gw_sub_ptr->nh) {
|
|
|
|
nua_handle_bind(gw_sub_ptr->nh, NULL);
|
|
|
|
nua_handle_destroy(gw_sub_ptr->nh);
|
|
|
|
gw_sub_ptr->nh = NULL;
|
2011-11-10 10:48:06 -06:00
|
|
|
sofia_private_free(gateway_ptr->sofia_private);
|
|
|
|
}
|
2012-07-17 17:01:10 -05:00
|
|
|
|
|
|
|
gw_sub_ptr->nh = nua_handle(gateway_ptr->profile->nua, NULL,
|
|
|
|
NUTAG_URL(gateway_ptr->register_proxy),
|
2011-11-10 10:48:06 -06:00
|
|
|
TAG_IF(user_via, SIPTAG_VIA_STR(user_via)),
|
|
|
|
SIPTAG_TO_STR(gateway_ptr->register_to),
|
|
|
|
NUTAG_CALLSTATE_REF(ss_state), SIPTAG_FROM_STR(gateway_ptr->register_from), TAG_END());
|
|
|
|
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));
|
|
|
|
|
|
|
|
gateway_ptr->sofia_private->gateway = gateway_ptr;
|
2012-07-17 17:01:10 -05:00
|
|
|
nua_handle_bind(gw_sub_ptr->nh, gateway_ptr->sofia_private);
|
2011-11-10 10:48:06 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
switch_safe_free(register_host);
|
|
|
|
switch_safe_free(user_via);
|
|
|
|
}
|
|
|
|
|
2012-07-17 17:01:10 -05:00
|
|
|
static void sofia_reg_kill_sub(sofia_gateway_subscription_t *gw_sub_ptr)
|
|
|
|
{
|
|
|
|
sofia_gateway_t *gateway_ptr = gw_sub_ptr->gateway;
|
2011-11-10 10:48:06 -06:00
|
|
|
|
2012-07-17 17:01:10 -05:00
|
|
|
if (gw_sub_ptr->nh) {
|
|
|
|
nua_handle_bind(gw_sub_ptr->nh, NULL);
|
2011-11-10 10:48:06 -06:00
|
|
|
}
|
2012-07-17 17:01:10 -05:00
|
|
|
|
|
|
|
if (gw_sub_ptr->state != SUB_STATE_SUBED && gw_sub_ptr->state != SUB_STATE_UNSUBSCRIBE) {
|
|
|
|
if (gw_sub_ptr->nh) {
|
|
|
|
nua_handle_destroy(gw_sub_ptr->nh);
|
|
|
|
gw_sub_ptr->nh = NULL;
|
2011-11-10 10:48:06 -06:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-07-17 17:01:10 -05:00
|
|
|
if (gw_sub_ptr->nh) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "UN-Subbing %s %s\n", gateway_ptr->name, gw_sub_ptr->event);
|
|
|
|
nua_unsubscribe(gw_sub_ptr->nh, NUTAG_URL(gw_sub_ptr->request_uri), TAG_END());
|
2011-11-10 10:48:06 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-03-22 05:15:17 +00:00
|
|
|
static void sofia_reg_kill_reg(sofia_gateway_t *gateway_ptr)
|
|
|
|
{
|
|
|
|
|
2012-04-13 15:58:49 -05:00
|
|
|
if (!gateway_ptr->nh) {
|
2009-04-03 13:14:26 +00:00
|
|
|
return;
|
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2012-04-13 15:58:49 -05:00
|
|
|
if (gateway_ptr->state == REG_STATE_REGED || gateway_ptr->state == REG_STATE_UNREGISTER) {
|
2009-03-22 05:15:17 +00:00
|
|
|
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());
|
2012-04-13 15:58:49 -05:00
|
|
|
} else {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Destroying registration handle for %s\n", gateway_ptr->name);
|
2009-03-22 05:15:17 +00:00
|
|
|
}
|
2012-04-13 15:58:49 -05:00
|
|
|
|
|
|
|
nua_handle_bind(gateway_ptr->nh, NULL);
|
|
|
|
nua_handle_destroy(gateway_ptr->nh);
|
|
|
|
gateway_ptr->nh = NULL;
|
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;
|
2011-11-10 10:48:06 -06:00
|
|
|
sofia_gateway_subscription_t *gw_sub_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
|
|
|
|
2011-10-04 17:46:49 -05:00
|
|
|
if (gateway_ptr->nh) {
|
|
|
|
nua_handle_bind(gateway_ptr->nh, NULL);
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
2011-11-10 10:48:06 -06:00
|
|
|
for (gw_sub_ptr = gateway_ptr->subscriptions; gw_sub_ptr; gw_sub_ptr = gw_sub_ptr->next) {
|
|
|
|
if (gw_sub_ptr->state == SUB_STATE_SUBED) {
|
2012-07-17 17:01:10 -05:00
|
|
|
sofia_reg_kill_sub(gw_sub_ptr);
|
2011-11-10 10:48:06 -06: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
|
|
|
|
2011-06-16 14:32:08 -05:00
|
|
|
switch_mutex_lock(profile->gw_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) {
|
|
|
|
sub_state_t ostate = gw_sub_ptr->state;
|
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
|
|
|
|
2012-07-17 17:01:10 -05:00
|
|
|
//gateway_ptr->sub_state = gw_sub_ptr->state;
|
2011-11-10 09:46:56 -06:00
|
|
|
|
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;
|
2012-07-17 17:01:10 -05:00
|
|
|
sofia_reg_kill_sub(gw_sub_ptr);
|
2008-11-24 15:52:55 +00:00
|
|
|
break;
|
|
|
|
case SUB_STATE_UNSUBED:
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2012-07-17 17:01:10 -05:00
|
|
|
sofia_reg_new_sub_handle(gw_sub_ptr, 1);
|
2011-11-10 10:48:06 -06:00
|
|
|
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "subscribing to [%s] on gateway [%s]\n", gw_sub_ptr->event, gateway_ptr->name);
|
2012-07-17 17:01:10 -05:00
|
|
|
|
2008-11-24 15:52:55 +00:00
|
|
|
if (now) {
|
2012-07-17 17:01:10 -05:00
|
|
|
nua_subscribe(gw_sub_ptr->nh,
|
|
|
|
NUTAG_URL(gw_sub_ptr->request_uri),
|
2010-11-22 14:59:25 -06:00
|
|
|
SIPTAG_EVENT_STR(gw_sub_ptr->event),
|
2012-07-17 17:01:10 -05:00
|
|
|
TAG_IF(strcmp(gw_sub_ptr->content_type, "NO_CONTENT_TYPE"), SIPTAG_ACCEPT_STR(gw_sub_ptr->content_type)),
|
2010-11-22 14:59:25 -06:00
|
|
|
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 {
|
2012-07-17 17:01:10 -05:00
|
|
|
nua_unsubscribe(gw_sub_ptr->nh,
|
|
|
|
NUTAG_URL(gw_sub_ptr->request_uri),
|
2009-06-03 22:00:49 +00:00
|
|
|
SIPTAG_EVENT_STR(gw_sub_ptr->event),
|
2012-07-17 17:01:10 -05:00
|
|
|
TAG_IF(strcmp(gw_sub_ptr->content_type, "NO_CONTENT_TYPE"), SIPTAG_ACCEPT_STR(gw_sub_ptr->content_type)),
|
2009-06-03 22:00:49 +00:00
|
|
|
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;
|
|
|
|
}
|
2011-11-10 10:48:06 -06:00
|
|
|
|
2008-11-24 15:52:55 +00:00
|
|
|
}
|
|
|
|
}
|
2011-06-16 14:32:08 -05:00
|
|
|
switch_mutex_unlock(profile->gw_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
|
|
|
{
|
2011-09-27 08:44:29 -05:00
|
|
|
sofia_gateway_t *check, *gateway_ptr, *last = NULL;
|
2010-01-23 19:08:44 +00:00
|
|
|
switch_event_t *event;
|
2012-01-10 08:51:14 -06:00
|
|
|
int delta = 0;
|
2008-07-08 22:05:34 +00:00
|
|
|
|
2011-06-16 14:32:08 -05:00
|
|
|
switch_mutex_lock(profile->gw_mutex);
|
2008-07-08 22:05:34 +00:00
|
|
|
for (gateway_ptr = profile->gateways; gateway_ptr; gateway_ptr = gateway_ptr->next) {
|
2011-09-27 08:44:29 -05:00
|
|
|
if (gateway_ptr->deleted) {
|
|
|
|
if ((check = switch_core_hash_find(mod_sofia_globals.gateway_hash, gateway_ptr->name)) && check == gateway_ptr) {
|
|
|
|
char *pkey = switch_mprintf("%s::%s", profile->name, gateway_ptr->name);
|
|
|
|
switch_assert(pkey);
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removing gateway %s from hash.\n", pkey);
|
|
|
|
switch_core_hash_delete(mod_sofia_globals.gateway_hash, pkey);
|
|
|
|
switch_core_hash_delete(mod_sofia_globals.gateway_hash, gateway_ptr->name);
|
|
|
|
free(pkey);
|
2008-07-08 22:05:34 +00:00
|
|
|
}
|
2010-02-18 22:39:08 +00:00
|
|
|
|
2011-09-27 08:44:29 -05:00
|
|
|
if (gateway_ptr->state == REG_STATE_NOREG) {
|
2010-02-18 22:39:08 +00:00
|
|
|
|
2011-09-27 08:44:29 -05:00
|
|
|
if (last) {
|
|
|
|
last->next = gateway_ptr->next;
|
|
|
|
} else {
|
|
|
|
profile->gateways = gateway_ptr->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleted gateway %s\n", gateway_ptr->name);
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
if (gateway_ptr->ob_vars) {
|
|
|
|
switch_event_destroy(&gateway_ptr->ob_vars);
|
|
|
|
}
|
|
|
|
if (gateway_ptr->ib_vars) {
|
|
|
|
switch_event_destroy(&gateway_ptr->ib_vars);
|
|
|
|
}
|
2012-12-06 11:45:13 -06:00
|
|
|
} else {
|
|
|
|
last = gateway_ptr;
|
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;
|
2010-11-22 14:59:25 -06:00
|
|
|
char *register_host = 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());
|
2011-07-16 01:02:22 -05:00
|
|
|
sofia_private_t *pvt;
|
2008-04-30 22:09:54 +00:00
|
|
|
|
2010-11-22 14:59:25 -06:00
|
|
|
register_host = sofia_glue_get_register_host(gateway_ptr->register_proxy);
|
|
|
|
|
|
|
|
/* check for NAT and place a Via header if necessary (hostname or non-local IP) */
|
2010-11-23 09:54:50 -06:00
|
|
|
if (register_host && sofia_glue_check_nat(gateway_ptr->profile, register_host)) {
|
2009-07-14 23:39:57 +00:00
|
|
|
user_via = sofia_glue_create_external_via(NULL, gateway_ptr->profile, gateway_ptr->register_transport);
|
|
|
|
}
|
|
|
|
|
2010-11-22 14:59:25 -06:00
|
|
|
switch_safe_free(register_host);
|
|
|
|
|
2011-07-16 01:02:22 -05:00
|
|
|
pvt = malloc(sizeof(*pvt));
|
|
|
|
switch_assert(pvt);
|
|
|
|
memset(pvt, 0, sizeof(*pvt));
|
|
|
|
pvt->destroy_nh = 1;
|
|
|
|
pvt->destroy_me = 1;
|
|
|
|
switch_copy_string(pvt->gateway_name, gateway_ptr->name, sizeof(pvt->gateway_name));
|
|
|
|
nua_handle_bind(nh, pvt);
|
2008-04-30 22:09:54 +00:00
|
|
|
|
|
|
|
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)),
|
2012-01-29 17:37:56 -06:00
|
|
|
SIPTAG_TO_STR(gateway_ptr->options_to_uri), SIPTAG_FROM_STR(gateway_ptr->options_from_uri),
|
|
|
|
TAG_IF(gateway_ptr->options_user_agent, SIPTAG_USER_AGENT_STR(gateway_ptr->options_user_agent)),
|
|
|
|
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;
|
|
|
|
|
2012-01-10 08:51:14 -06:00
|
|
|
if (gateway_ptr->freq > 30) {
|
|
|
|
delta = (gateway_ptr->freq - 15);
|
2008-10-07 22:15:51 +00:00
|
|
|
} else {
|
2012-01-10 08:51:14 -06:00
|
|
|
delta = (gateway_ptr->freq / 2);
|
2008-10-07 22:15:51 +00:00
|
|
|
}
|
|
|
|
|
2012-01-10 08:51:14 -06:00
|
|
|
if (delta < 1) {
|
|
|
|
delta = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
gateway_ptr->expires = now + delta;
|
|
|
|
|
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;
|
2012-01-10 08:51:14 -06:00
|
|
|
gateway_ptr->status = SOFIA_GATEWAY_DOWN;
|
2007-09-18 17:31:36 +00:00
|
|
|
break;
|
2007-03-31 19:01:33 +00:00
|
|
|
case REG_STATE_UNREGED:
|
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
|
|
|
|
2010-11-22 14:59:25 -06:00
|
|
|
register_host = sofia_glue_get_register_host(gateway_ptr->register_proxy);
|
|
|
|
|
|
|
|
/* check for NAT and place a Via header if necessary (hostname or non-local IP) */
|
2010-11-23 09:54:50 -06:00
|
|
|
if (register_host && sofia_glue_check_nat(gateway_ptr->profile, register_host)) {
|
2009-06-04 05:43:34 +00:00
|
|
|
user_via = sofia_glue_create_external_via(NULL, gateway_ptr->profile, gateway_ptr->register_transport);
|
|
|
|
}
|
2009-06-03 22:00:49 +00:00
|
|
|
|
2010-11-22 14:59:25 -06:00
|
|
|
switch_safe_free(register_host);
|
|
|
|
|
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 {
|
2012-01-10 08:51:14 -06:00
|
|
|
gateway_ptr->status = SOFIA_GATEWAY_DOWN;
|
2009-03-22 05:15:17 +00:00
|
|
|
nua_unregister(gateway_ptr->nh,
|
|
|
|
NUTAG_URL(gateway_ptr->register_url),
|
2012-05-15 08:48:08 -05:00
|
|
|
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-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
|
|
|
}
|
2010-11-03 10:58:32 -05:00
|
|
|
gateway_ptr->reg_timeout = now + gateway_ptr->reg_timeout_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;
|
|
|
|
|
2010-11-02 17:58:24 -05:00
|
|
|
case REG_STATE_TIMEOUT:
|
|
|
|
{
|
|
|
|
nua_handle_t *nh = gateway_ptr->nh;
|
|
|
|
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Timeout Registering %s\n", gateway_ptr->name);
|
|
|
|
|
|
|
|
gateway_ptr->nh = NULL;
|
|
|
|
nua_handle_destroy(nh);
|
|
|
|
gateway_ptr->state = REG_STATE_FAILED;
|
|
|
|
gateway_ptr->failures++;
|
|
|
|
gateway_ptr->failure_status = 908;
|
|
|
|
}
|
|
|
|
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
|
|
|
|
2012-03-28 12:26:29 -05:00
|
|
|
if (gateway_ptr->failure_status == 503 || gateway_ptr->failure_status == 908 || gateway_ptr->failures < 1) {
|
2009-12-11 22:21:29 +00:00
|
|
|
sec = gateway_ptr->retry_seconds;
|
2010-02-06 03:38:24 +00:00
|
|
|
} else {
|
2012-03-28 12:26:29 -05:00
|
|
|
sec = gateway_ptr->retry_seconds * gateway_ptr->failures;
|
2009-12-02 20:47:46 +00:00
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2012-03-28 12:26:29 -05:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s Failed Registration [%d], setting retry to %d seconds.\n",
|
|
|
|
gateway_ptr->name, gateway_ptr->failure_status, sec);
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
}
|
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:
|
2010-11-03 10:58:32 -05:00
|
|
|
if (now >= gateway_ptr->reg_timeout) {
|
2010-11-02 17:58:24 -05:00
|
|
|
gateway_ptr->state = REG_STATE_TIMEOUT;
|
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
|
|
|
}
|
2011-06-16 14:32:08 -05:00
|
|
|
switch_mutex_unlock(profile->gw_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
|
|
|
}
|
|
|
|
|
2011-08-17 19:34:22 -05:00
|
|
|
|
|
|
|
int sofia_reg_find_reg_with_positive_expires_callback(void *pArg, int argc, char **argv, char **columnNames)
|
|
|
|
{
|
|
|
|
struct callback_t *cbt = (struct callback_t *) pArg;
|
|
|
|
sofia_destination_t *dst = NULL;
|
|
|
|
long int expires;
|
|
|
|
char *contact = NULL;
|
|
|
|
|
2013-01-07 10:13:58 -06:00
|
|
|
if (zstr(argv[0])) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cbt->contact_str && !strcasecmp(argv[0], cbt->contact_str)) {
|
2012-11-27 13:48:57 -05:00
|
|
|
expires = cbt->exptime;
|
|
|
|
} else {
|
|
|
|
expires = atol(argv[1]) - 60 - (long) cbt->time;
|
|
|
|
}
|
2011-08-17 19:34:22 -05:00
|
|
|
|
|
|
|
if (expires > 0) {
|
|
|
|
dst = sofia_glue_get_destination(argv[0]);
|
|
|
|
contact = switch_mprintf("<%s>;expires=%ld", dst->contact, expires);
|
|
|
|
|
|
|
|
if (!cbt->len) {
|
|
|
|
switch_console_push_match(&cbt->list, contact);
|
|
|
|
switch_safe_free(contact);
|
|
|
|
sofia_glue_free_destination(dst);
|
|
|
|
cbt->matches++;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch_copy_string(cbt->val, contact, cbt->len);
|
|
|
|
switch_safe_free(contact);
|
|
|
|
sofia_glue_free_destination(dst);
|
|
|
|
cbt->matches++;
|
|
|
|
return cbt->matches == 1 ? 0 : 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
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;
|
2012-11-29 12:59:33 -06:00
|
|
|
char to[512] = "", call_id[512] = "";
|
2009-06-19 15:48:23 +00:00
|
|
|
sofia_destination_t *dst = NULL;
|
2012-11-29 12:59:33 -06:00
|
|
|
switch_uuid_t uuid;
|
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]);
|
2012-07-10 23:04:16 -05:00
|
|
|
|
2012-11-29 12:59:33 -06:00
|
|
|
// create call-id for OPTIONS in the form "<uuid>_<original-register-call-id>"
|
|
|
|
switch_uuid_get(&uuid);
|
|
|
|
switch_uuid_format(call_id, &uuid);
|
|
|
|
strcat(call_id, "_");
|
|
|
|
strncat(call_id, argv[0], sizeof(call_id) - SWITCH_UUID_FORMATTED_LENGTH - 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),
|
2012-11-29 12:59:33 -06:00
|
|
|
SIPTAG_CALL_ID_STR(call_id), 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
|
|
|
|
2012-06-19 21:58:43 -04:00
|
|
|
void sofia_reg_send_reboot(sofia_profile_t *profile, const char *callid, const char *user, const char *host, const char *contact, const char *user_agent,
|
2010-02-06 03:38:24 +00:00
|
|
|
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";
|
2012-09-10 18:25:02 -05:00
|
|
|
char *body = NULL;
|
2008-07-17 20:47:42 +00:00
|
|
|
|
2010-12-03 18:58:39 -05:00
|
|
|
if (switch_stristr("snom", user_agent) || switch_stristr("yealink", user_agent)) {
|
2008-07-17 20:47:42 +00:00
|
|
|
event = "check-sync;reboot=true";
|
2013-01-31 17:58:27 -05:00
|
|
|
} else if (switch_stristr("Linksys/SPA8000", user_agent)) {
|
|
|
|
event = "check-sync";
|
2008-07-17 20:47:42 +00:00
|
|
|
} 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";
|
2012-09-19 14:44:42 -05:00
|
|
|
} else if (switch_stristr("Cisco-CP7960G", user_agent) || switch_stristr("Cisco-CP7940G", user_agent)) {
|
|
|
|
event = "check-sync";
|
2012-09-10 18:25:02 -05:00
|
|
|
} else if (switch_stristr("cisco", user_agent)) {
|
|
|
|
event = "service-control";
|
|
|
|
contenttype = "text/plain";
|
|
|
|
body = switch_mprintf("action=restart\n"
|
|
|
|
"RegisterCallId={%s}\n"
|
|
|
|
"ConfigVersionStamp={0000000000000000}\n"
|
|
|
|
"DialplanVersionStamp={0000000000000000}\n"
|
|
|
|
"SoftkeyVersionStamp={0000000000000000}", callid);
|
2008-07-17 20:47:42 +00:00
|
|
|
}
|
|
|
|
|
2012-09-10 18:25:02 -05:00
|
|
|
sofia_glue_send_notify(profile, user, host, event, contenttype, body ? body : "", contact, network_ip, callid);
|
|
|
|
|
|
|
|
switch_safe_free(body);
|
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
|
|
|
|
2013-01-26 23:16:26 -06:00
|
|
|
void sofia_reg_check_socket(sofia_profile_t *profile, const char *call_id, const char *network_addr, const char *network_ip)
|
|
|
|
{
|
|
|
|
char key[256] = "";
|
|
|
|
nua_handle_t *hnh;
|
|
|
|
|
|
|
|
switch_snprintf(key, sizeof(key), "%s%s%s", call_id, network_addr, network_ip);
|
|
|
|
switch_mutex_lock(profile->flag_mutex);
|
|
|
|
if ((hnh = switch_core_hash_find(profile->chat_hash, key))) {
|
|
|
|
switch_core_hash_delete(profile->chat_hash, key);
|
|
|
|
nua_handle_unref(hnh);
|
|
|
|
}
|
|
|
|
switch_mutex_unlock(profile->flag_mutex);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
2013-01-26 23:16:26 -06:00
|
|
|
if (argc > 13 && atoi(argv[13]) == 1) {
|
2012-06-19 21:58:43 -04:00
|
|
|
sofia_reg_send_reboot(profile, argv[0], 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
|
|
|
|
2013-01-26 23:16:26 -06:00
|
|
|
sofia_reg_check_socket(profile, argv[0], argv[11], argv[12]);
|
|
|
|
|
|
|
|
|
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]);
|
2012-11-07 12:10:50 -06:00
|
|
|
sofia_event_fire(profile, &s_event);
|
2007-03-31 19:01:33 +00:00
|
|
|
}
|
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");
|
2012-11-07 12:10:50 -06:00
|
|
|
sofia_event_fire(profile, &s_event);
|
2010-02-03 19:40:24 +00:00
|
|
|
}
|
|
|
|
|
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"
|
2013-01-26 23:16:26 -06:00
|
|
|
",user_agent,server_user,server_host,profile_name,network_ip,network_port"
|
2010-02-06 03:38:24 +00:00
|
|
|
",%d from sip_registrations where call_id='%q' %s", reboot, call_id, sqlextra);
|
|
|
|
|
2012-10-08 13:28:01 -05:00
|
|
|
|
2013-02-25 15:42:21 -06:00
|
|
|
sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_reg_del_callback, profile);
|
2009-08-11 01:26:51 +00:00
|
|
|
switch_safe_free(sql);
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2011-01-16 22:27:56 +00:00
|
|
|
sql = switch_mprintf("delete from sip_registrations where call_id='%q' %s", call_id, sqlextra);
|
2012-10-25 11:31:42 -05:00
|
|
|
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
|
2008-07-17 20:47:42 +00:00
|
|
|
|
2011-01-16 22:27:56 +00:00
|
|
|
switch_safe_free(sqlextra);
|
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
|
|
|
{
|
2012-10-25 11:31:42 -05:00
|
|
|
char *sql;
|
2008-05-07 20:06:46 +00:00
|
|
|
|
2007-04-29 01:16:49 +00:00
|
|
|
if (now) {
|
2012-10-25 11:31:42 -05:00
|
|
|
sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,rpid,expires"
|
2013-01-26 23:16:26 -06:00
|
|
|
",user_agent,server_user,server_host,profile_name,network_ip, network_port"
|
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 {
|
2012-10-25 11:31:42 -05:00
|
|
|
sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,rpid,expires"
|
2013-01-26 23:16:26 -06:00
|
|
|
",user_agent,server_user,server_host,profile_name,network_ip, network_port" ",%d from sip_registrations where expires > 0", reboot);
|
2007-04-29 01:16:49 +00:00
|
|
|
}
|
2007-03-31 19:01:33 +00:00
|
|
|
|
2013-02-25 15:42:21 -06:00
|
|
|
sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_reg_del_callback, profile);
|
2012-10-29 14:38:37 -05:00
|
|
|
free(sql);
|
|
|
|
|
2007-04-29 01:16:49 +00:00
|
|
|
if (now) {
|
2012-10-25 11:31:42 -05:00
|
|
|
sql = switch_mprintf("delete from sip_registrations where expires > 0 and expires <= %ld and hostname='%q'",
|
2008-09-18 00:01:03 +00:00
|
|
|
(long) now, mod_sofia_globals.hostname);
|
2007-04-29 01:16:49 +00:00
|
|
|
} else {
|
2012-10-25 11:31:42 -05:00
|
|
|
sql = switch_mprintf("delete from sip_registrations where expires > 0 and hostname='%q'", mod_sofia_globals.hostname);
|
2007-04-29 01:16:49 +00:00
|
|
|
}
|
2012-10-25 11:31:42 -05:00
|
|
|
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
|
|
|
|
|
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) {
|
2012-10-25 11:31:42 -05:00
|
|
|
sql = switch_mprintf("select call_id from sip_shared_appearance_dialogs where hostname='%q' "
|
2010-02-06 03:38:24 +00:00
|
|
|
"and profile_name='%s' and expires <= %ld", mod_sofia_globals.hostname, profile->name, (long) now);
|
|
|
|
|
2013-02-25 15:42:21 -06:00
|
|
|
sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_sla_dialog_del_callback, profile);
|
2012-10-29 14:38:37 -05:00
|
|
|
free(sql);
|
|
|
|
|
2012-10-25 11:31:42 -05:00
|
|
|
sql = switch_mprintf("delete from sip_shared_appearance_dialogs where expires > 0 and hostname='%q' and expires <= %ld",
|
2009-03-22 05:15:17 +00:00
|
|
|
mod_sofia_globals.hostname, (long) now);
|
|
|
|
|
|
|
|
|
2012-10-25 11:31:42 -05:00
|
|
|
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
|
2009-03-22 05:15:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-11-22 01:34:19 +00:00
|
|
|
if (now) {
|
2012-10-25 11:31:42 -05:00
|
|
|
sql = switch_mprintf("delete from sip_presence where expires > 0 and expires <= %ld and hostname='%q'",
|
2008-11-22 01:34:19 +00:00
|
|
|
(long) now, mod_sofia_globals.hostname);
|
|
|
|
} else {
|
2012-10-25 11:31:42 -05:00
|
|
|
sql = switch_mprintf("delete from sip_presence where expires > 0 and hostname='%q'", mod_sofia_globals.hostname);
|
2008-11-22 01:34:19 +00:00
|
|
|
}
|
|
|
|
|
2012-10-25 11:31:42 -05:00
|
|
|
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
|
2008-11-22 01:34:19 +00:00
|
|
|
|
2007-04-29 01:16:49 +00:00
|
|
|
if (now) {
|
2012-10-25 11:31:42 -05:00
|
|
|
sql = switch_mprintf("delete from sip_authentication where expires > 0 and expires <= %ld and hostname='%q'",
|
2008-09-18 00:01:03 +00:00
|
|
|
(long) now, mod_sofia_globals.hostname);
|
2007-04-29 01:16:49 +00:00
|
|
|
} else {
|
2012-10-25 11:31:42 -05:00
|
|
|
sql = switch_mprintf("delete from sip_authentication where expires > 0 and hostname='%q'", mod_sofia_globals.hostname);
|
2007-04-29 01:16:49 +00:00
|
|
|
}
|
2008-04-14 15:07:43 +00:00
|
|
|
|
2012-10-25 11:31:42 -05:00
|
|
|
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
|
2010-01-09 00:34:17 +00:00
|
|
|
|
2012-10-25 14:06:05 -05:00
|
|
|
sofia_presence_check_subscriptions(profile, now);
|
|
|
|
|
2010-01-09 00:34:17 +00:00
|
|
|
if (now) {
|
2012-10-25 11:31:42 -05:00
|
|
|
sql = switch_mprintf("delete from sip_dialogs where (expires = -1 or (expires > 0 and expires <= %ld)) and hostname='%q'",
|
2010-01-09 00:34:17 +00:00
|
|
|
(long) now, mod_sofia_globals.hostname);
|
|
|
|
} else {
|
2012-10-25 11:31:42 -05:00
|
|
|
sql = switch_mprintf("delete from sip_dialogs where expires >= -1 and hostname='%q'", mod_sofia_globals.hostname);
|
2007-04-29 01:16:49 +00:00
|
|
|
}
|
2008-04-14 15:07:43 +00:00
|
|
|
|
2012-10-25 11:31:42 -05:00
|
|
|
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
|
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)) {
|
2012-10-25 11:31:42 -05:00
|
|
|
sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,rpid,"
|
2010-09-15 15:38:25 -05:00
|
|
|
"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
|
|
|
|
2013-02-25 15:42:21 -06:00
|
|
|
sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_reg_nat_callback, profile);
|
2013-01-29 16:33:07 -06:00
|
|
|
switch_safe_free(sql);
|
2010-09-15 15:38:25 -05:00
|
|
|
} else if (sofia_test_pflag(profile, PFLAG_NAT_OPTIONS_PING)) {
|
2012-10-25 11:31:42 -05:00
|
|
|
sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,rpid,"
|
2010-09-15 15:38:25 -05:00
|
|
|
"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
|
|
|
|
2013-02-25 15:42:21 -06:00
|
|
|
sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_reg_nat_callback, profile);
|
2013-01-29 16:33:07 -06:00
|
|
|
switch_safe_free(sql);
|
2010-09-15 15:38:25 -05:00
|
|
|
}
|
2007-05-22 15:03:21 +00:00
|
|
|
}
|
|
|
|
|
2007-03-31 19:01:33 +00:00
|
|
|
}
|
|
|
|
|
2011-06-08 11:09:03 -05:00
|
|
|
|
|
|
|
int sofia_reg_check_callback(void *pArg, int argc, char **argv, char **columnNames)
|
|
|
|
{
|
|
|
|
sofia_profile_t *profile = (sofia_profile_t *) pArg;
|
|
|
|
|
2012-06-19 21:58:43 -04:00
|
|
|
sofia_reg_send_reboot(profile, argv[0], argv[1], argv[2], argv[3], argv[7], argv[11]);
|
2011-06-08 11:09:03 -05:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void sofia_reg_check_call_id(sofia_profile_t *profile, const char *call_id)
|
|
|
|
{
|
|
|
|
char *sql = NULL;
|
|
|
|
char *sqlextra = NULL;
|
|
|
|
char *dup = strdup(call_id);
|
|
|
|
char *host = NULL, *user = NULL;
|
|
|
|
|
|
|
|
switch_assert(dup);
|
|
|
|
|
|
|
|
if ((host = strchr(dup, '@'))) {
|
|
|
|
*host++ = '\0';
|
|
|
|
user = dup;
|
|
|
|
} else {
|
|
|
|
host = dup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!host) {
|
|
|
|
host = "none";
|
|
|
|
}
|
|
|
|
|
|
|
|
if (zstr(user)) {
|
|
|
|
sqlextra = switch_mprintf(" or (sip_host='%q')", host);
|
|
|
|
} else {
|
|
|
|
sqlextra = switch_mprintf(" or (sip_user='%q' and sip_host='%q')", user, host);
|
|
|
|
}
|
|
|
|
|
|
|
|
sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,rpid,expires"
|
|
|
|
",user_agent,server_user,server_host,profile_name,network_ip"
|
|
|
|
" from sip_registrations where call_id='%q' %s", call_id, sqlextra);
|
|
|
|
|
2012-10-08 13:28:01 -05:00
|
|
|
|
2013-02-25 15:42:21 -06:00
|
|
|
sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_reg_check_callback, profile);
|
2012-10-08 13:28:01 -05:00
|
|
|
|
2011-06-08 11:09:03 -05:00
|
|
|
|
|
|
|
switch_safe_free(sql);
|
|
|
|
switch_safe_free(sqlextra);
|
|
|
|
switch_safe_free(dup);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void sofia_reg_check_sync(sofia_profile_t *profile)
|
|
|
|
{
|
2012-10-25 11:31:42 -05:00
|
|
|
char *sql;
|
2011-06-08 11:09:03 -05:00
|
|
|
|
2012-10-25 11:31:42 -05:00
|
|
|
sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,rpid,expires"
|
2013-01-26 23:16:26 -06:00
|
|
|
",user_agent,server_user,server_host,profile_name,network_ip,network_port"
|
2011-06-08 11:09:03 -05:00
|
|
|
" from sip_registrations where expires > 0");
|
|
|
|
|
|
|
|
|
2013-02-25 15:42:21 -06:00
|
|
|
sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_reg_del_callback, profile);
|
2013-01-29 16:33:07 -06:00
|
|
|
switch_safe_free(sql);
|
|
|
|
|
2012-10-25 11:31:42 -05:00
|
|
|
sql = switch_mprintf("delete from sip_registrations where expires > 0 and hostname='%q'", mod_sofia_globals.hostname);
|
|
|
|
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
|
2011-06-08 11:09:03 -05:00
|
|
|
|
2012-10-25 11:31:42 -05:00
|
|
|
sql = switch_mprintf("delete from sip_presence where expires > 0 and hostname='%q'", mod_sofia_globals.hostname);
|
|
|
|
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
|
2011-06-08 11:09:03 -05:00
|
|
|
|
2012-10-25 11:31:42 -05:00
|
|
|
sql = switch_mprintf("delete from sip_authentication where expires > 0 and hostname='%q'", mod_sofia_globals.hostname);
|
|
|
|
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
|
2011-06-08 11:09:03 -05:00
|
|
|
|
2012-10-25 11:31:42 -05:00
|
|
|
sql = switch_mprintf("delete from sip_subscriptions where expires >= -1 and hostname='%q'", mod_sofia_globals.hostname);
|
|
|
|
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
|
2011-06-08 11:09:03 -05:00
|
|
|
|
2012-10-25 11:31:42 -05:00
|
|
|
sql = switch_mprintf("delete from sip_dialogs where expires >= -1 and hostname='%q'", mod_sofia_globals.hostname);
|
|
|
|
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
|
2011-06-08 11:09:03 -05:00
|
|
|
|
|
|
|
}
|
|
|
|
|
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 };
|
2012-10-25 11:31:42 -05:00
|
|
|
char *sql;
|
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) {
|
2012-10-25 11:31:42 -05:00
|
|
|
sql = switch_mprintf("select contact from sip_registrations where sip_user='%q' and (sip_host='%q' or presence_hosts like '%%%q%%')",
|
2010-02-06 03:38:24 +00:00
|
|
|
user, host, host);
|
2007-03-31 19:01:33 +00:00
|
|
|
} else {
|
2012-10-25 11:31:42 -05:00
|
|
|
sql = switch_mprintf("select contact from sip_registrations where sip_user='%q'", user);
|
2007-03-31 19:01:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-02-25 15:42:21 -06:00
|
|
|
sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_reg_find_callback, &cbt);
|
2007-03-31 19:01:33 +00:00
|
|
|
|
2013-01-29 16:33:07 -06:00
|
|
|
switch_safe_free(sql);
|
2007-03-31 19:01:33 +00:00
|
|
|
|
2013-02-18 12:58:33 -06:00
|
|
|
if (cbt.list) {
|
|
|
|
switch_console_free_matches(&cbt.list);
|
|
|
|
}
|
|
|
|
|
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 };
|
2012-10-25 11:31:42 -05:00
|
|
|
char *sql;
|
2010-08-18 14:58:14 -05:00
|
|
|
|
|
|
|
if (!user) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Called with null user!\n");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (host) {
|
2012-10-25 11:31:42 -05:00
|
|
|
sql = switch_mprintf("select contact from sip_registrations where sip_user='%q' and (sip_host='%q' or presence_hosts like '%%%q%%')",
|
2010-08-18 14:58:14 -05:00
|
|
|
user, host, host);
|
|
|
|
} else {
|
2012-10-25 11:31:42 -05:00
|
|
|
sql = switch_mprintf("select contact from sip_registrations where sip_user='%q'", user);
|
2010-08-18 14:58:14 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-02-25 15:42:21 -06:00
|
|
|
sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_reg_find_callback, &cbt);
|
2013-01-29 16:33:07 -06:00
|
|
|
|
|
|
|
switch_safe_free(sql);
|
2010-08-18 14:58:14 -05:00
|
|
|
|
|
|
|
return cbt.list;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-11-27 13:48:57 -05:00
|
|
|
switch_console_callback_match_t *sofia_reg_find_reg_url_with_positive_expires_multi(sofia_profile_t *profile, const char *user, const char *host, time_t reg_time, const char *contact_str, long exptime)
|
2011-08-17 19:34:22 -05:00
|
|
|
{
|
|
|
|
struct callback_t cbt = { 0 };
|
2012-10-25 11:31:42 -05:00
|
|
|
char *sql;
|
2011-08-17 19:34:22 -05:00
|
|
|
|
|
|
|
if (!user) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Called with null user!\n");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (host) {
|
2012-10-25 11:31:42 -05:00
|
|
|
sql = switch_mprintf("select contact,expires from sip_registrations where sip_user='%q' and (sip_host='%q' or presence_hosts like '%%%q%%')",
|
2011-08-17 19:34:22 -05:00
|
|
|
user, host, host);
|
|
|
|
} else {
|
2012-10-25 11:31:42 -05:00
|
|
|
sql = switch_mprintf("select contact,expires from sip_registrations where sip_user='%q'", user);
|
2011-08-17 19:34:22 -05:00
|
|
|
}
|
|
|
|
|
2012-11-27 13:48:57 -05:00
|
|
|
cbt.time = reg_time;
|
|
|
|
cbt.contact_str = contact_str;
|
|
|
|
cbt.exptime = exptime;
|
|
|
|
|
2013-02-25 15:42:21 -06:00
|
|
|
sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_reg_find_reg_with_positive_expires_callback, &cbt);
|
2012-10-29 14:38:37 -05:00
|
|
|
free(sql);
|
2011-08-17 19:34:22 -05:00
|
|
|
|
|
|
|
return cbt.list;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-06-30 11:59:58 -05:00
|
|
|
void sofia_reg_auth_challenge(sofia_profile_t *profile, nua_handle_t *nh, sofia_dispatch_event_t *de,
|
2011-06-16 14:37:22 -05:00
|
|
|
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;
|
2011-06-30 11:59:58 -05:00
|
|
|
msg_t *msg = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
if (de && de->data) {
|
|
|
|
msg = de->data->e_msg;
|
|
|
|
}
|
2007-06-08 22:28:32 +00:00
|
|
|
|
|
|
|
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,
|
2011-03-28 10:27:06 -05:00
|
|
|
(long) 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);
|
2012-10-25 11:31:42 -05:00
|
|
|
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
|
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) {
|
2011-06-30 11:59:58 -05:00
|
|
|
nua_respond(nh, SIP_401_UNAUTHORIZED, TAG_IF(msg, NUTAG_WITH_THIS_MSG(msg)), SIPTAG_WWW_AUTHENTICATE_STR(auth_str), TAG_END());
|
2007-06-08 22:28:32 +00:00
|
|
|
} else if (regtype == REG_INVITE) {
|
2011-06-30 11:59:58 -05:00
|
|
|
nua_respond(nh, SIP_407_PROXY_AUTH_REQUIRED,
|
|
|
|
TAG_IF(msg, NUTAG_WITH_THIS_MSG(msg)),
|
|
|
|
SIPTAG_PROXY_AUTHENTICATE_STR(auth_str), TAG_END());
|
2007-06-08 22:28:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
switch_safe_free(auth_str);
|
|
|
|
}
|
|
|
|
|
2011-01-03 16:40:49 -06:00
|
|
|
uint32_t sofia_reg_reg_count(sofia_profile_t *profile, const char *user, const char *host)
|
|
|
|
{
|
|
|
|
char buf[32] = "";
|
|
|
|
char *sql;
|
|
|
|
|
|
|
|
sql = switch_mprintf("select count(*) from sip_registrations where profile_name='%q' and "
|
|
|
|
"sip_user='%q' and (sip_host='%q' or presence_hosts like '%%%q%%')", profile->name, user, host, host);
|
|
|
|
|
2013-02-25 15:42:21 -06:00
|
|
|
sofia_glue_execute_sql2str(profile, profile->dbh_mutex, sql, buf, sizeof(buf));
|
2011-01-03 16:40:49 -06:00
|
|
|
switch_safe_free(sql);
|
|
|
|
return atoi(buf);
|
|
|
|
}
|
|
|
|
|
2012-05-22 10:27:18 -05:00
|
|
|
static int debounce_check(sofia_profile_t *profile, const char *user, const char *host)
|
|
|
|
{
|
|
|
|
char key[512] = "";
|
|
|
|
int r = 0;
|
|
|
|
time_t *last, now = switch_epoch_time_now(NULL);
|
|
|
|
|
|
|
|
snprintf(key, sizeof(key), "%s%s", user, host);
|
|
|
|
|
2012-11-29 08:35:28 -06:00
|
|
|
switch_mutex_lock(profile->ireg_mutex);
|
2012-05-22 10:27:18 -05:00
|
|
|
if ((last = switch_core_hash_find(profile->mwi_debounce_hash, key))) {
|
|
|
|
if (now - *last > 30) {
|
|
|
|
*last = now;
|
|
|
|
r = 1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
last = switch_core_alloc(profile->pool, sizeof(*last));
|
|
|
|
*last = now;
|
2013-02-18 12:58:33 -06:00
|
|
|
|
2012-05-22 10:27:18 -05:00
|
|
|
switch_core_hash_insert(profile->mwi_debounce_hash, key, last);
|
|
|
|
r = 1;
|
|
|
|
}
|
2012-11-29 08:35:28 -06:00
|
|
|
switch_mutex_unlock(profile->ireg_mutex);
|
2012-05-22 10:27:18 -05:00
|
|
|
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-06-16 14:37:22 -05:00
|
|
|
uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip,
|
|
|
|
sofia_dispatch_event_t *de, sofia_regtype_t regtype, char *key,
|
2013-01-26 23:16:26 -06:00
|
|
|
uint32_t keylen, switch_event_t **v_event, const char *is_nat, sofia_private_t **sofia_private_p)
|
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;
|
2012-05-30 13:05:05 -05:00
|
|
|
const char *reg_meta = NULL;
|
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-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;
|
2011-12-16 12:28:22 -06:00
|
|
|
auth_res_t auth_res = AUTH_OK;
|
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-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-09-15 15:38:25 -05:00
|
|
|
const char *agent = "unknown";
|
2011-01-14 13:57:58 -06:00
|
|
|
const char *pres_on_reg = NULL;
|
|
|
|
int send_pres = 0;
|
2013-01-24 23:08:40 -06:00
|
|
|
int is_tls = 0, is_tcp = 0, is_ws = 0, is_wss = 0;
|
2012-10-11 10:36:07 -05:00
|
|
|
char expbuf[35] = "";
|
2012-11-27 13:48:57 -05:00
|
|
|
time_t reg_time = switch_epoch_time_now(NULL);
|
2013-01-24 23:08:40 -06:00
|
|
|
const char *vproto = NULL;
|
|
|
|
const char *proto = "sip";
|
2013-01-25 13:48:18 -06:00
|
|
|
const char *uparams = NULL;
|
|
|
|
const char *p;
|
|
|
|
char *utmp = NULL;
|
2013-01-26 23:16:26 -06:00
|
|
|
sofia_private_t *sofia_private = NULL;
|
|
|
|
|
|
|
|
if (sofia_private_p) {
|
|
|
|
sofia_private = *sofia_private_p;
|
|
|
|
}
|
2013-01-25 13:48:18 -06:00
|
|
|
|
|
|
|
if (sip && sip->sip_contact->m_url->url_params) {
|
|
|
|
uparams = sip->sip_contact->m_url->url_params;
|
|
|
|
} else {
|
|
|
|
uparams = NULL;
|
|
|
|
}
|
|
|
|
|
2013-01-24 23:08:40 -06:00
|
|
|
|
|
|
|
if (sip && sip->sip_via && (vproto = sip->sip_via->v_protocol)) {
|
|
|
|
if (!strcasecmp(vproto, "sip/2.0/ws")) {
|
|
|
|
is_ws = 1;
|
|
|
|
is_nat++;
|
|
|
|
} else if (!strcasecmp(vproto, "sip/2.0/wss")) {
|
|
|
|
is_wss = 1;
|
|
|
|
is_nat++;
|
2013-01-25 13:48:18 -06:00
|
|
|
|
|
|
|
if (uparams && (p = switch_stristr("transport=ws", uparams))) {
|
|
|
|
if (p[12] != 's') {
|
|
|
|
utmp = switch_string_replace(uparams, "transport=ws", "transport=wss");
|
|
|
|
}
|
|
|
|
}
|
2013-01-24 23:08:40 -06:00
|
|
|
}
|
|
|
|
}
|
2011-01-14 13:57:58 -06:00
|
|
|
|
|
|
|
if (v_event && *v_event) pres_on_reg = switch_event_get_header(*v_event, "send-presence-on-register");
|
|
|
|
|
|
|
|
if (!(send_pres = switch_true(pres_on_reg))) {
|
|
|
|
if (pres_on_reg && !strcasecmp(pres_on_reg, "first-only")) {
|
|
|
|
send_pres = 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-17 19:34:22 -05:00
|
|
|
/* all callers must confirm that sip and sip->sip_request are not NULL */
|
|
|
|
switch_assert(sip != NULL && sip->sip_request != NULL);
|
2007-03-31 19:01:33 +00:00
|
|
|
|
2011-06-16 14:37:22 -05:00
|
|
|
sofia_glue_get_addr(de->data->e_msg, 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);
|
|
|
|
|
2011-06-16 14:37:22 -05:00
|
|
|
snprintf(url_ip, sizeof(url_ip), (msg_addrinfo(de->data->e_msg))->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);
|
|
|
|
|
2011-06-16 14:37:22 -05:00
|
|
|
nua_respond(nh, SIP_401_UNAUTHORIZED, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
|
2009-03-25 20:14:07 +00:00
|
|
|
switch_goto_int(r, 1, end);
|
2007-03-31 19:01:33 +00:00
|
|
|
}
|
|
|
|
|
2012-01-24 17:38:36 -06:00
|
|
|
if (zstr(reg_host)) {
|
2008-09-08 22:38:37 +00:00
|
|
|
reg_host = to_host;
|
|
|
|
}
|
2012-01-24 17:38:36 -06:00
|
|
|
if (zstr(sub_host)) {
|
2010-09-02 16:01:50 -05:00
|
|
|
sub_host = to_host;
|
|
|
|
}
|
2008-09-08 22:38:37 +00:00
|
|
|
|
2011-08-17 19:34:22 -05:00
|
|
|
if (contact && contact->m_url) {
|
2007-03-31 19:01:33 +00:00
|
|
|
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;
|
2013-01-24 23:08:40 -06:00
|
|
|
|
2008-07-03 15:01:46 +00:00
|
|
|
|
2013-01-25 13:48:18 -06:00
|
|
|
if (uparams && switch_stristr("transport=tls", uparams)) {
|
2008-07-03 15:01:46 +00:00
|
|
|
is_tls += 1;
|
2013-03-27 11:12:35 -05:00
|
|
|
is_nat++;
|
2008-07-03 15:01:46 +00:00
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2013-01-25 13:48:18 -06:00
|
|
|
if (!is_wss && !is_ws && uparams && switch_stristr("transport=ws", uparams)) {
|
2013-01-24 15:13:17 -06:00
|
|
|
is_nat++;
|
|
|
|
is_ws += 1;
|
|
|
|
}
|
|
|
|
|
2013-01-24 23:08:40 -06:00
|
|
|
if (sip->sip_contact->m_url->url_type == url_sips) {
|
2008-06-27 21:38:59 +00:00
|
|
|
proto = "sips";
|
2008-07-03 15:01:46 +00:00
|
|
|
is_tls += 2;
|
2013-03-27 11:12:35 -05:00
|
|
|
is_nat++;
|
2008-06-27 21:38:59 +00:00
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2013-01-24 23:08:40 -06:00
|
|
|
|
2013-01-25 13:48:18 -06:00
|
|
|
if (uparams && switch_stristr("transport=tcp", uparams)) {
|
2008-07-03 15:01:46 +00:00
|
|
|
is_tcp = 1;
|
2013-03-27 11:12:35 -05:00
|
|
|
is_nat++;
|
2008-07-03 15:01:46 +00:00
|
|
|
}
|
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)";
|
2013-01-24 15:13:17 -06:00
|
|
|
} else if (is_ws) {
|
|
|
|
reg_desc = "Registered(WS-NAT)";
|
2013-01-24 23:08:40 -06:00
|
|
|
} else if (is_wss) {
|
|
|
|
reg_desc = "Registered(WSS-NAT)";
|
2008-07-03 15:01:46 +00:00
|
|
|
} 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];
|
2013-01-25 13:48:18 -06:00
|
|
|
if (uparams) {
|
2013-01-24 23:08:40 -06:00
|
|
|
switch_snprintf(my_contact_str, sizeof(my_contact_str), "%s:%s@%s:%d;%s", proto,
|
2013-01-25 13:48:18 -06:00
|
|
|
contact->m_url->url_user, url_ip, network_port, utmp ? utmp : uparams);
|
2009-05-04 14:36:11 +00:00
|
|
|
} else {
|
2013-01-24 23:08:40 -06:00
|
|
|
switch_snprintf(my_contact_str, sizeof(my_contact_str), "%s:%s@%s:%d", proto, contact->m_url->url_user, url_ip, network_port);
|
2009-05-04 14:36:11 +00:00
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2013-01-25 13:48:18 -06:00
|
|
|
if (uparams) {
|
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,
|
2013-01-25 13:48:18 -06:00
|
|
|
uparams,
|
|
|
|
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;
|
2011-08-17 19:34:22 -05:00
|
|
|
} else if (contact && contact->m_expires) {
|
2007-03-31 19:01:33 +00:00
|
|
|
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) {
|
2011-05-29 09:46:02 -05:00
|
|
|
char *v_contact_str = NULL;
|
2010-10-27 12:00:30 -05:00
|
|
|
const char *username = "unknown";
|
|
|
|
const char *realm = reg_host;
|
2011-06-16 14:37:22 -05:00
|
|
|
if ((auth_res = sofia_reg_parse_auth(profile, authorization, sip, de, 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, ®_count)) == AUTH_STALE) {
|
2007-03-31 19:01:33 +00:00
|
|
|
stale = 1;
|
|
|
|
}
|
2008-05-27 04:54:52 +00:00
|
|
|
|
2010-10-27 12:00:30 -05:00
|
|
|
|
|
|
|
if (auth_params) {
|
|
|
|
username = switch_event_get_header(auth_params, "sip_auth_username");
|
|
|
|
realm = switch_event_get_header(auth_params, "sip_auth_realm");
|
|
|
|
}
|
|
|
|
if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_REGISTER_ATTEMPT) == SWITCH_STATUS_SUCCESS) {
|
|
|
|
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);
|
|
|
|
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-host", reg_host);
|
2011-08-17 19:34:22 -05:00
|
|
|
if (contact)
|
|
|
|
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "contact", contact_str);
|
2010-10-27 12:00:30 -05:00
|
|
|
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);
|
|
|
|
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "status", reg_desc);
|
2011-08-17 19:34:22 -05:00
|
|
|
if (contact)
|
|
|
|
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "expires", "%ld", (long) exptime);
|
2010-10-27 12:00:30 -05: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);
|
|
|
|
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);
|
|
|
|
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "username", username);
|
|
|
|
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "realm", realm);
|
|
|
|
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "user-agent", agent);
|
2012-04-17 17:28:47 -07:00
|
|
|
switch (auth_res) {
|
|
|
|
case AUTH_OK:
|
|
|
|
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "auth-result", "SUCCESS");
|
|
|
|
break;
|
|
|
|
case AUTH_RENEWED:
|
|
|
|
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "auth-result", "RENEWED");
|
|
|
|
break;
|
|
|
|
case AUTH_STALE:
|
|
|
|
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "auth-result", "STALE");
|
|
|
|
break;
|
|
|
|
case AUTH_FORBIDDEN:
|
|
|
|
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "auth-result", "FORBIDDEN");
|
|
|
|
break;
|
|
|
|
}
|
2010-10-27 12:00:30 -05:00
|
|
|
switch_event_fire(&s_event);
|
|
|
|
}
|
|
|
|
|
2011-08-17 19:34:22 -05:00
|
|
|
if (contact && exptime && v_event && *v_event) {
|
2011-12-22 14:03:32 -06:00
|
|
|
uint32_t exp_var;
|
|
|
|
uint32_t exp_max_deviation_var;
|
2008-07-15 18:04:17 +00:00
|
|
|
char *allow_multireg = NULL;
|
2011-01-06 16:01:07 -06:00
|
|
|
int auto_connectile = 0;
|
2008-07-15 18:04:17 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
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
|
|
|
|
2011-03-28 18:31:40 -05:00
|
|
|
if (profile->server_rport_level == 3 && sip->sip_user_agent &&
|
2010-12-21 19:32:54 -06:00
|
|
|
sip->sip_user_agent->g_string && !strncasecmp(sip->sip_user_agent->g_string, "Polycom", 7)) {
|
2011-01-06 16:01:07 -06:00
|
|
|
if (sip && sip->sip_via) {
|
|
|
|
const char *host = sip->sip_via->v_host;
|
|
|
|
const char *c_port = sip->sip_via->v_port;
|
|
|
|
int port = 0;
|
|
|
|
|
|
|
|
if (c_port) port = atoi(c_port);
|
|
|
|
if (!port) port = 5060;
|
|
|
|
|
|
|
|
if (host && strcmp(network_ip, host)) {
|
|
|
|
auto_connectile = 1;
|
|
|
|
} else if (port != network_port) {
|
|
|
|
auto_connectile = 1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
auto_connectile = 1;
|
|
|
|
}
|
2010-12-21 19:32:54 -06:00
|
|
|
}
|
|
|
|
|
2011-03-19 10:14:50 -04:00
|
|
|
if (auto_connectile || (v_contact_str = switch_event_get_header(*v_event, "sip-force-contact"))) {
|
|
|
|
if (auto_connectile || (!strcasecmp(v_contact_str, "NDLB-connectile-dysfunction-2.0"))) {
|
2011-08-04 00:02:13 -05:00
|
|
|
char *path_encoded = NULL;
|
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];
|
|
|
|
|
2013-01-24 23:08:40 -06:00
|
|
|
switch_snprintf(my_contact_str, sizeof(my_contact_str), "%s:%s@%s:%d", proto, contact->m_url->url_user, url_ip, network_port);
|
2009-04-29 23:27:24 +00:00
|
|
|
path_encoded_len = (strlen(my_contact_str) * 3) + 1;
|
2009-04-29 22:00:34 +00:00
|
|
|
|
2011-08-04 00:02:13 -05:00
|
|
|
if (!switch_stristr("fs_path=", contact_str)) {
|
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;
|
2011-01-19 11:35:48 -06:00
|
|
|
|
|
|
|
/* place fs_path (the encoded path) inside the <...> of the contact string, if possible */
|
|
|
|
if (contact_str[strlen(contact_str) - 1] == '>') {
|
|
|
|
switch_snprintf(contact_str + strlen(contact_str) - 1, sizeof(contact_str) - strlen(contact_str) + 1, "%s>", path_encoded);
|
|
|
|
} else {
|
|
|
|
switch_snprintf(contact_str + strlen(contact_str), sizeof(contact_str) - strlen(contact_str), "%s", path_encoded);
|
|
|
|
}
|
2011-08-04 00:02:13 -05:00
|
|
|
switch_safe_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")) {
|
2013-01-25 13:48:18 -06:00
|
|
|
if (uparams) {
|
2013-01-24 23:08:40 -06:00
|
|
|
switch_snprintf(contact_str, sizeof(contact_str), "%s <%s:%s@%s:%d;%s%s;fs_nat=yes>",
|
2013-01-25 13:48:18 -06:00
|
|
|
display, proto, contact->m_url->url_user, url_ip, network_port, uparams, received_data);
|
2009-04-29 22:00:34 +00:00
|
|
|
} else {
|
2013-01-24 23:08:40 -06:00
|
|
|
switch_snprintf(contact_str, sizeof(contact_str), "%s <%s:%s@%s:%d%s;fs_nat=yes>", display, proto,
|
|
|
|
contact->m_url->url_user, url_ip,
|
2009-04-29 22:00:34 +00:00
|
|
|
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
|
|
|
}
|
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
|
|
|
|
2011-12-22 14:03:32 -06:00
|
|
|
if ( (( exp_var = atoi(switch_event_get_header_nil(*v_event, "sip-force-expires")) )) ||
|
|
|
|
(( exp_var = profile->sip_force_expires )) ) {
|
|
|
|
if (exp_var > 0) {
|
|
|
|
exptime = exp_var;
|
2007-10-18 16:17:42 +00:00
|
|
|
}
|
|
|
|
}
|
2011-12-22 14:03:32 -06:00
|
|
|
|
|
|
|
if ( (( exp_max_deviation_var = atoi(switch_event_get_header_nil(*v_event, "sip-expires-max-deviation")) )) ||
|
|
|
|
(( exp_max_deviation_var = profile->sip_expires_max_deviation )) ) {
|
|
|
|
if (exp_max_deviation_var > 0) {
|
|
|
|
int exp_deviation;
|
|
|
|
srand( (unsigned) ( (unsigned)(intptr_t)switch_thread_self() + switch_micro_time_now() ) );
|
|
|
|
/* random number between negative exp_max_deviation_var and positive exp_max_deviation_var: */
|
|
|
|
exp_deviation = ( rand() % ( exp_max_deviation_var * 2 ) ) - exp_max_deviation_var;
|
|
|
|
exptime += exp_deviation;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-05-14 21:30:31 +00:00
|
|
|
}
|
|
|
|
|
2011-12-16 14:31:15 -05:00
|
|
|
if (auth_res != AUTH_OK && auth_res != AUTH_RENEWED && !stale) {
|
2010-12-20 08:43:13 -06:00
|
|
|
if (auth_res == AUTH_FORBIDDEN) {
|
2011-06-16 14:37:22 -05:00
|
|
|
nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
|
2010-12-20 08:43:13 -06:00
|
|
|
forbidden = 1;
|
|
|
|
} else {
|
2011-06-16 14:37:22 -05:00
|
|
|
nua_respond(nh, SIP_401_UNAUTHORIZED, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
|
2010-11-24 10:34:02 -06:00
|
|
|
}
|
|
|
|
|
2009-02-27 18:15:50 +00:00
|
|
|
if (profile->debug) {
|
2010-11-24 10:34:02 -06:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Send %s for [%s@%s]\n",
|
|
|
|
forbidden ? "forbidden" : "challenge", to_user, to_host);
|
2009-02-27 18:15:50 +00:00
|
|
|
}
|
2010-12-20 08:43:13 -06:00
|
|
|
/* Log line added to support Fail2Ban */
|
|
|
|
if (sofia_test_pflag(profile, PFLAG_LOG_AUTH_FAIL)) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "SIP auth %s (%s) on sofia profile '%s' "
|
|
|
|
"for [%s@%s] from ip %s\n", forbidden ? "failure" : "challenge",
|
|
|
|
(regtype == REG_INVITE) ? "INVITE" : "REGISTER", profile->name, to_user, to_host, network_ip);
|
2007-03-31 19:01:33 +00:00
|
|
|
}
|
2010-12-20 08:43:13 -06:00
|
|
|
|
2012-04-17 17:28:47 -07:00
|
|
|
if (forbidden && switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_REGISTER_FAILURE) == SWITCH_STATUS_SUCCESS) {
|
|
|
|
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile-name", profile->name);
|
|
|
|
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "to-user", to_user);
|
|
|
|
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "to-host", to_host);
|
|
|
|
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "network-ip", network_ip);
|
2012-04-20 15:05:02 -07:00
|
|
|
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "user-agent", agent);
|
|
|
|
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile-name", profile->name);
|
|
|
|
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "network-port", network_port_c);
|
2012-04-17 17:28:47 -07:00
|
|
|
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "registration-type", (regtype == REG_INVITE) ? "INVITE" : "REGISTER");
|
|
|
|
switch_event_fire(&s_event);
|
|
|
|
}
|
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;
|
|
|
|
|
2010-10-27 12:00:30 -05:00
|
|
|
if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_PRE_REGISTER) == SWITCH_STATUS_SUCCESS) {
|
|
|
|
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);
|
|
|
|
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-host", reg_host);
|
2011-08-17 19:34:22 -05:00
|
|
|
if (contact)
|
|
|
|
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "contact", contact_str);
|
2010-10-27 12:00:30 -05:00
|
|
|
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);
|
|
|
|
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "status", reg_desc);
|
2011-08-17 19:34:22 -05:00
|
|
|
if (contact)
|
|
|
|
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "expires", "%ld", (long) exptime);
|
2010-10-27 12:00:30 -05: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);
|
|
|
|
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);
|
|
|
|
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "user-agent", agent);
|
|
|
|
switch_event_fire(&s_event);
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2011-06-30 11:59:58 -05:00
|
|
|
sofia_reg_auth_challenge(profile, nh, de, regtype, realm, stale);
|
2010-12-20 08:43:13 -06:00
|
|
|
|
|
|
|
if (profile->debug) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Send challenge for [%s@%s]\n", to_user, to_host);
|
2007-03-31 19:01:33 +00:00
|
|
|
}
|
2010-12-20 08:43:13 -06:00
|
|
|
/* Log line added to support Fail2Ban */
|
|
|
|
if (sofia_test_pflag(profile, PFLAG_LOG_AUTH_FAIL)) {
|
2011-11-23 13:25:24 -06:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "SIP auth challenge (%s) on sofia profile '%s' "
|
2010-12-20 08:43:13 -06:00
|
|
|
"for [%s@%s] from ip %s\n", (regtype == REG_INVITE) ? "INVITE" : "REGISTER",
|
|
|
|
profile->name, to_user, to_host, network_ip);
|
|
|
|
}
|
|
|
|
|
2009-03-25 20:14:07 +00:00
|
|
|
switch_goto_int(r, 1, end);
|
2007-03-31 19:01:33 +00:00
|
|
|
}
|
2011-08-17 19:34:22 -05:00
|
|
|
|
|
|
|
if (!contact)
|
|
|
|
goto respond_200_ok;
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2012-05-30 13:05:05 -05:00
|
|
|
if (v_event && *v_event && (var = switch_event_get_header(*v_event, "registration_metadata"))) {
|
|
|
|
reg_meta = 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
|
|
|
|
2013-01-26 23:16:26 -06: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;
|
2011-02-11 23:10:12 -06:00
|
|
|
char *url = NULL;
|
|
|
|
char *contact = NULL;
|
2011-12-16 14:31:15 -05:00
|
|
|
switch_bool_t update_registration = SWITCH_FALSE;
|
2009-03-25 20:14:07 +00:00
|
|
|
|
|
|
|
if (auth_params) {
|
|
|
|
username = switch_event_get_header(auth_params, "sip_auth_username");
|
|
|
|
realm = switch_event_get_header(auth_params, "sip_auth_realm");
|
|
|
|
}
|
2013-01-26 23:16:26 -06:00
|
|
|
|
2012-01-17 16:12:56 -05:00
|
|
|
if (auth_res != AUTH_RENEWED || !multi_reg) {
|
2011-12-16 14:31:15 -05:00
|
|
|
if (multi_reg) {
|
|
|
|
if (multi_reg_contact) {
|
|
|
|
sql =
|
|
|
|
switch_mprintf("delete from sip_registrations where sip_user='%q' and sip_host='%q' and contact='%q'", to_user, reg_host, contact_str);
|
|
|
|
} else {
|
|
|
|
sql = switch_mprintf("delete from sip_registrations where call_id='%q'", call_id);
|
|
|
|
}
|
2008-10-22 17:40:43 +00:00
|
|
|
} else {
|
2011-12-16 14:31:15 -05:00
|
|
|
sql = switch_mprintf("delete from sip_registrations where sip_user='%q' and sip_host='%q'", to_user, reg_host);
|
2008-10-22 17:40:43 +00:00
|
|
|
}
|
2013-01-26 23:16:26 -06:00
|
|
|
|
2011-12-16 14:31:15 -05:00
|
|
|
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
|
2007-03-31 19:01:33 +00:00
|
|
|
} else {
|
2011-12-16 14:31:15 -05:00
|
|
|
char buf[32] = "";
|
2012-10-12 17:49:15 -04:00
|
|
|
|
|
|
|
|
|
|
|
sql = switch_mprintf("select count(*) from sip_registrations where sip_user='%q' and sip_username='%q' and sip_host='%q' and contact='%q'",
|
|
|
|
to_user, username, reg_host, contact_str);
|
2011-12-16 14:31:15 -05:00
|
|
|
|
2012-10-08 13:28:01 -05:00
|
|
|
|
2011-12-17 13:06:37 -05:00
|
|
|
|
2013-02-25 15:42:21 -06:00
|
|
|
sofia_glue_execute_sql2str(profile, profile->dbh_mutex, sql, buf, sizeof(buf));
|
2011-12-16 14:31:15 -05:00
|
|
|
switch_safe_free(sql);
|
|
|
|
if (atoi(buf) > 0) {
|
|
|
|
update_registration = SWITCH_TRUE;
|
2010-09-15 15:38:25 -05:00
|
|
|
}
|
2007-10-18 01:02:01 +00:00
|
|
|
}
|
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
|
|
|
|
2011-02-11 23:10:12 -06:00
|
|
|
contact = sofia_glue_get_url_from_contact(contact_str, 1);
|
2013-01-24 23:08:40 -06:00
|
|
|
url = switch_mprintf("sofia/%q/%s:%q", profile->name, proto, sofia_glue_strip_proto(contact));
|
2010-07-29 23:39:39 -05:00
|
|
|
|
2012-11-27 13:48:57 -05:00
|
|
|
switch_core_add_registration(to_user, reg_host, call_id, url, (long) reg_time + (long) exptime + 60,
|
2012-05-30 13:05:05 -05:00
|
|
|
network_ip, network_port_c, is_tls ? "tls" : is_tcp ? "tcp" : "udp", reg_meta);
|
2011-02-11 23:10:12 -06:00
|
|
|
|
|
|
|
switch_safe_free(url);
|
|
|
|
switch_safe_free(contact);
|
2013-01-26 23:16:26 -06:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((is_wss || is_ws || is_tcp || is_tls) && !sofia_private && call_id) {
|
|
|
|
char key[256] = "";
|
|
|
|
nua_handle_t *hnh;
|
|
|
|
switch_snprintf(key, sizeof(key), "%s%s%s", call_id, network_ip, network_port_c);
|
|
|
|
|
|
|
|
switch_mutex_lock(profile->flag_mutex);
|
|
|
|
hnh = switch_core_hash_find(profile->chat_hash, key);
|
|
|
|
switch_mutex_unlock(profile->flag_mutex);
|
|
|
|
|
|
|
|
if (!hnh) {
|
|
|
|
if (!(sofia_private = su_alloc(nh->nh_home, sizeof(*sofia_private)))) {
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
|
|
|
|
memset(sofia_private, 0, sizeof(*sofia_private));
|
|
|
|
sofia_private->call_id = su_strdup(nh->nh_home, call_id);
|
|
|
|
sofia_private->network_ip = su_strdup(nh->nh_home, network_ip);
|
|
|
|
sofia_private->network_port = su_strdup(nh->nh_home, network_port_c);
|
|
|
|
sofia_private->key = su_strdup(nh->nh_home, key);
|
|
|
|
sofia_private->is_static++;
|
|
|
|
*sofia_private_p = sofia_private;
|
|
|
|
nua_handle_bind(nh, sofia_private);
|
|
|
|
nua_handle_ref(nh);
|
|
|
|
switch_core_hash_insert(profile->chat_hash, key, nh);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-02-11 23:10:12 -06:00
|
|
|
|
2011-12-16 14:31:15 -05:00
|
|
|
if (!update_registration) {
|
|
|
|
sql = switch_mprintf("insert into sip_registrations "
|
|
|
|
"(call_id,sip_user,sip_host,presence_hosts,contact,status,rpid,expires,"
|
|
|
|
"user_agent,server_user,server_host,profile_name,hostname,network_ip,network_port,sip_username,sip_realm,"
|
2012-01-10 17:33:40 -06:00
|
|
|
"mwi_user,mwi_host, orig_server_host, orig_hostname, sub_host) "
|
|
|
|
"values ('%q','%q', '%q','%q','%q','%q', '%q', %ld, '%q', '%q', '%q', '%q', '%q', '%q', '%q','%q','%q','%q','%q','%q','%q','%q')",
|
2012-01-26 04:46:48 -06:00
|
|
|
call_id, to_user, reg_host, profile->presence_hosts ? profile->presence_hosts : "",
|
2012-11-27 13:48:57 -05:00
|
|
|
contact_str, reg_desc, rpid, (long) reg_time + (long) exptime + 60,
|
2011-12-16 14:31:15 -05:00
|
|
|
agent, from_user, guess_ip4, profile->name, mod_sofia_globals.hostname, network_ip, network_port_c, username, realm,
|
2012-01-10 17:33:40 -06:00
|
|
|
mwi_user, mwi_host, guess_ip4, mod_sofia_globals.hostname, sub_host);
|
2011-12-16 14:31:15 -05:00
|
|
|
} else {
|
2012-12-15 08:55:02 -06:00
|
|
|
sql = switch_mprintf("update sip_registrations set call_id='%q',"
|
2012-01-24 17:38:36 -06:00
|
|
|
"sub_host='%q', network_ip='%q',network_port='%q',"
|
2012-11-21 10:00:44 -06:00
|
|
|
"presence_hosts='%q', server_host='%q', orig_server_host='%q',"
|
2012-12-15 08:55:02 -06:00
|
|
|
"hostname='%q', orig_hostname='%q',"
|
2012-10-12 17:49:15 -04:00
|
|
|
"expires = %ld where sip_user='%q' and sip_username='%q' and sip_host='%q' and contact='%q'",
|
2012-12-15 08:55:02 -06:00
|
|
|
call_id, sub_host, network_ip, network_port_c,
|
2012-11-21 10:00:44 -06:00
|
|
|
profile->presence_hosts ? profile->presence_hosts : "", guess_ip4, guess_ip4,
|
|
|
|
mod_sofia_globals.hostname, mod_sofia_globals.hostname,
|
2012-11-27 13:48:57 -05:00
|
|
|
(long) reg_time + (long) exptime + 60,
|
2012-10-12 17:49:15 -04:00
|
|
|
to_user, username, reg_host, contact_str);
|
2011-12-16 14:31:15 -05: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
|
|
|
|
2011-12-16 14:31:15 -05:00
|
|
|
if (!update_registration && sofia_reg_reg_count(profile, to_user, reg_host) == 1) {
|
2011-01-03 16:40:49 -06:00
|
|
|
sql = switch_mprintf("delete from sip_presence where sip_user='%q' and sip_host='%q' and profile_name='%q' and open_closed='closed'",
|
|
|
|
to_user, reg_host, profile->name);
|
2011-01-05 11:32:00 -06:00
|
|
|
if (mod_sofia_globals.debug_presence > 0) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "DELETE PRESENCE SQL: %s\n", sql);
|
|
|
|
}
|
2011-01-03 16:40:49 -06:00
|
|
|
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
|
|
|
|
}
|
2010-07-29 23:39:39 -05:00
|
|
|
|
2013-01-26 23:16:26 -06:00
|
|
|
if (multi_reg) {
|
|
|
|
if (multi_reg_contact) {
|
|
|
|
sql = switch_mprintf("delete from sip_registrations where contact='%q' and expires!=%ld", contact_str, (long) reg_time + (long) exptime + 60);
|
|
|
|
} else {
|
|
|
|
sql = switch_mprintf("delete from sip_registrations where call_id='%q' and expires!=%ld", call_id, (long) reg_time + (long) exptime + 60);
|
|
|
|
}
|
|
|
|
|
|
|
|
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
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);
|
2012-01-26 04:46:48 -06:00
|
|
|
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "presence-hosts", profile->presence_hosts ? profile->presence_hosts : "n/a");
|
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);
|
2013-01-16 16:50:07 +00:00
|
|
|
if (update_registration) {
|
|
|
|
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "update-reg", "true");
|
|
|
|
}
|
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:\nFrom: [%s@%s]\nContact: [%s]\nExpires: [%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
|
|
|
|
|
|
|
} else {
|
2011-01-03 16:40:49 -06:00
|
|
|
int send = 1;
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2011-01-03 16:40:49 -06:00
|
|
|
if (multi_reg) {
|
|
|
|
if (sofia_reg_reg_count(profile, to_user, sub_host) > 0) {
|
|
|
|
send = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-26 23:16:26 -06:00
|
|
|
sofia_reg_check_socket(profile, call_id, network_ip, network_port_c);
|
|
|
|
|
2011-01-03 16:40:49 -06:00
|
|
|
if (send && 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");
|
2011-10-24 18:54:22 -05:00
|
|
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "presence-source", "register");
|
2008-12-11 20:20:20 +00:00
|
|
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
|
|
|
|
switch_event_fire(&event);
|
|
|
|
}
|
2012-01-26 04:46:48 -06:00
|
|
|
|
2008-12-11 20:20:20 +00:00
|
|
|
|
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';
|
|
|
|
}
|
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
|
|
|
}
|
2013-01-26 23:16:26 -06: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 {
|
2012-01-03 11:40:52 -06: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
|
|
|
}
|
|
|
|
|
2011-08-17 19:34:22 -05:00
|
|
|
respond_200_ok:
|
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
|
|
|
|
2011-08-17 19:34:22 -05:00
|
|
|
switch_console_callback_match_t *contact_list = NULL;
|
|
|
|
tagi_t *contact_tags;
|
|
|
|
switch_console_callback_match_node_t *m;
|
|
|
|
int i;
|
2008-05-27 04:54:52 +00:00
|
|
|
|
2011-08-17 19:34:22 -05:00
|
|
|
s_event = NULL;
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2011-08-17 19:34:22 -05:00
|
|
|
if (contact) {
|
|
|
|
if (exptime) {
|
2012-05-22 10:27:18 -05:00
|
|
|
int debounce_ok = debounce_check(profile, mwi_user, mwi_host);
|
|
|
|
|
2011-08-17 19:34:22 -05:00
|
|
|
switch_snprintf(exp_param, sizeof(exp_param), "expires=%ld", exptime);
|
|
|
|
sip_contact_add_param(nua_handle_home(nh), sip->sip_contact, exp_param);
|
2012-05-22 10:27:18 -05:00
|
|
|
|
|
|
|
if ((sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER) ||
|
|
|
|
(reg_count == 1 && sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER))) && debounce_ok) {
|
|
|
|
|
2011-08-17 19:34:22 -05:00
|
|
|
if (switch_event_create(&s_mwi_event, SWITCH_EVENT_MESSAGE_QUERY) == SWITCH_STATUS_SUCCESS) {
|
2013-01-24 23:08:40 -06:00
|
|
|
switch_event_add_header(s_mwi_event, SWITCH_STACK_BOTTOM, "Message-Account", "%s:%s@%s", proto, mwi_user, mwi_host);
|
2012-02-10 10:49:19 -06:00
|
|
|
switch_event_add_header_string(s_mwi_event, SWITCH_STACK_BOTTOM, "VM-Sofia-Profile", profile->name);
|
2011-08-17 19:34:22 -05:00
|
|
|
switch_event_add_header_string(s_mwi_event, SWITCH_STACK_BOTTOM, "VM-Call-ID", call_id);
|
|
|
|
}
|
2009-04-24 14:33:54 +00:00
|
|
|
}
|
2010-07-27 22:08:47 -05:00
|
|
|
|
2012-05-22 10:27:18 -05:00
|
|
|
if ((sofia_test_pflag(profile, PFLAG_PRESENCE_ON_REGISTER) ||
|
2011-08-17 19:34:22 -05:00
|
|
|
(reg_count == 1 && sofia_test_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER))
|
2012-05-22 10:27:18 -05:00
|
|
|
|| send_pres == 1 || (reg_count == 1 && send_pres == 2)) && debounce_ok) {
|
2011-01-14 13:57:58 -06:00
|
|
|
|
2011-08-17 19:34:22 -05:00
|
|
|
if (sofia_test_pflag(profile, PFLAG_PRESENCE_PROBE_ON_REGISTER)) {
|
|
|
|
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");
|
2011-10-24 18:54:22 -05:00
|
|
|
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "presence-source", "register");
|
2011-08-17 19:34:22 -05:00
|
|
|
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
|
|
|
|
switch_event_fire(&s_event);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
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);
|
2011-10-24 18:54:22 -05:00
|
|
|
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "presence-source", "register");
|
2011-08-17 19:34:22 -05:00
|
|
|
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from", "%s@%s", to_user, sub_host);
|
|
|
|
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "rpid", "unknown");
|
|
|
|
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "status", "Registered");
|
|
|
|
switch_event_fire(&s_event);
|
|
|
|
}
|
2011-01-14 13:57:58 -06:00
|
|
|
}
|
2011-08-17 19:34:22 -05:00
|
|
|
}
|
|
|
|
} else {
|
2011-09-08 17:57:07 -04:00
|
|
|
const char *username = "unknown";
|
|
|
|
if (auth_params) {
|
|
|
|
username = switch_event_get_header(auth_params, "sip_auth_username");
|
|
|
|
}
|
|
|
|
|
2011-08-17 19:34:22 -05:00
|
|
|
switch_core_del_registration(to_user, reg_host, call_id);
|
|
|
|
|
|
|
|
if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_UNREGISTER) == SWITCH_STATUS_SUCCESS) {
|
|
|
|
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile-name", profile->name);
|
2011-09-08 17:57:07 -04:00
|
|
|
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "username", username);
|
2011-08-17 19:34:22 -05:00
|
|
|
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-user", to_user);
|
|
|
|
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-host", reg_host);
|
|
|
|
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);
|
|
|
|
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "expires", "%ld", (long) exptime);
|
2010-11-24 21:39:08 -06:00
|
|
|
}
|
2010-09-02 16:01:50 -05:00
|
|
|
}
|
2011-08-17 19:34:22 -05:00
|
|
|
}
|
2011-02-14 11:27:55 -06:00
|
|
|
|
2011-08-17 19:34:22 -05:00
|
|
|
switch_rfc822_date(date, switch_micro_time_now());
|
|
|
|
|
|
|
|
/* generate and respond a 200 OK */
|
|
|
|
|
2012-10-11 10:36:07 -05:00
|
|
|
if ((profile->ndlb & PFLAG_NDLB_EXPIRES_IN_REGISTER_RESPONSE)) {
|
|
|
|
switch_snprintf(expbuf, sizeof(expbuf), "%ld", exptime);
|
|
|
|
}
|
|
|
|
|
2011-08-17 19:34:22 -05:00
|
|
|
if (mod_sofia_globals.reg_deny_binding_fetch_and_no_lookup) {
|
|
|
|
/* handle backwards compatibility - contacts will not be looked up but only copied from the request into the response
|
|
|
|
remove this condition later if nobody complains about the extra select of the below new behavior
|
|
|
|
also remove the parts in mod_sofia.h, sofia.c and sofia_reg.c that refer to reg_deny_binding_fetch_and_no_lookup */
|
|
|
|
nua_respond(nh, SIP_200_OK, TAG_IF(contact, SIPTAG_CONTACT(sip->sip_contact)), TAG_IF(path_val, SIPTAG_PATH_STR(path_val)),
|
2012-10-11 10:36:07 -05:00
|
|
|
TAG_IF(!zstr(expbuf), SIPTAG_EXPIRES_STR(expbuf)),
|
|
|
|
NUTAG_WITH_THIS_MSG(de->data->e_msg), SIPTAG_DATE_STR(date), TAG_END());
|
2011-08-17 19:34:22 -05:00
|
|
|
|
2012-11-27 13:48:57 -05:00
|
|
|
} else if ((contact_list = sofia_reg_find_reg_url_with_positive_expires_multi(profile, from_user, reg_host, reg_time, contact_str, exptime))) {
|
2011-08-17 19:34:22 -05:00
|
|
|
/* all + 1 tag_i elements initialized as NULL - last one implies TAG_END() */
|
|
|
|
switch_zmalloc(contact_tags, sizeof(*contact_tags) * (contact_list->count + 1));
|
|
|
|
i = 0;
|
|
|
|
for (m = contact_list->head; m; m = m->next) {
|
|
|
|
contact_tags[i].t_tag = siptag_contact_str;
|
|
|
|
contact_tags[i].t_value = (tag_value_t) m->val;
|
|
|
|
++i;
|
2008-05-16 18:40:09 +00:00
|
|
|
}
|
2012-10-11 10:36:07 -05:00
|
|
|
|
2011-08-17 19:34:22 -05:00
|
|
|
|
|
|
|
nua_respond(nh, SIP_200_OK, TAG_IF(path_val, SIPTAG_PATH_STR(path_val)),
|
2012-10-11 10:36:07 -05:00
|
|
|
TAG_IF(!zstr(expbuf), SIPTAG_EXPIRES_STR(expbuf)),
|
|
|
|
NUTAG_WITH_THIS_MSG(de->data->e_msg), SIPTAG_DATE_STR(date), TAG_NEXT(contact_tags));
|
2011-08-17 19:34:22 -05:00
|
|
|
|
|
|
|
switch_safe_free(contact_tags);
|
|
|
|
switch_console_free_matches(&contact_list);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
/* respond without any contacts */
|
|
|
|
nua_respond(nh, SIP_200_OK, TAG_IF(path_val, SIPTAG_PATH_STR(path_val)),
|
2012-10-11 10:36:07 -05:00
|
|
|
TAG_IF(!zstr(expbuf), SIPTAG_EXPIRES_STR(expbuf)),
|
|
|
|
NUTAG_WITH_THIS_MSG(de->data->e_msg), SIPTAG_DATE_STR(date), TAG_END());
|
2007-10-18 16:17:42 +00:00
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
|
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
|
|
|
|
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);
|
2013-01-25 13:48:18 -06:00
|
|
|
switch_safe_free(utmp);
|
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
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-01-26 23:16:26 -06:00
|
|
|
void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t **sofia_private_p, sip_t const *sip,
|
|
|
|
sofia_dispatch_event_t *de,
|
2008-05-27 04:54:52 +00:00
|
|
|
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
|
|
|
|
2013-01-26 23:16:26 -06:00
|
|
|
|
2010-11-11 10:49:02 -06:00
|
|
|
#if 0 /* This seems to cause undesirable effects so nevermind */
|
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-11-11 10:49:02 -06:00
|
|
|
#endif
|
2010-09-03 14:11:06 -05:00
|
|
|
|
2011-06-16 14:37:22 -05:00
|
|
|
sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
|
2008-05-20 16:41:57 +00:00
|
|
|
|
2011-08-17 19:34:22 -05:00
|
|
|
/* backwards compatibility */
|
|
|
|
if (mod_sofia_globals.reg_deny_binding_fetch_and_no_lookup && !(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)) {
|
2011-06-16 14:37:22 -05:00
|
|
|
nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS_MSG(de->data->e_msg), 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
|
|
|
}
|
2010-10-22 11:22:07 -05:00
|
|
|
|
|
|
|
if (!is_nat && sip->sip_via->v_port &&
|
|
|
|
atoi(sip->sip_via->v_port) == 5060 && network_port != 5060 ) {
|
|
|
|
is_nat = "via port";
|
|
|
|
}
|
2008-05-21 21:49:27 +00:00
|
|
|
}
|
2008-07-03 15:01:46 +00:00
|
|
|
}
|
2008-05-21 21:49:27 +00: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]);
|
2011-06-16 14:37:22 -05:00
|
|
|
nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS_MSG(de->data->e_msg), 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
|
|
|
|
2013-01-26 23:16:26 -06:00
|
|
|
sofia_reg_handle_register(nua, profile, nh, sip, de, type, key, sizeof(key), &v_event, is_nat, sofia_private_p);
|
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:
|
2013-01-26 23:16:26 -06:00
|
|
|
|
|
|
|
if (!sofia_private_p || !*sofia_private_p) nua_handle_destroy(nh);
|
2008-03-05 20:31:18 +00:00
|
|
|
|
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,
|
2011-06-16 14:37:22 -05:00
|
|
|
sofia_dispatch_event_t *de,
|
2008-05-27 04:54:52 +00:00
|
|
|
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) {
|
2011-07-29 21:55:52 -05:00
|
|
|
char *full;
|
|
|
|
|
|
|
|
for (; contact; contact = contact->m_next) {
|
|
|
|
if ((full = sip_header_as_string(nh->nh_home, (void *) contact))) {
|
|
|
|
if (switch_stristr(sofia_private->gateway->register_contact, full)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
su_free(nh->nh_home, full);
|
|
|
|
}
|
|
|
|
}
|
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) {
|
2012-11-21 18:14:15 -06:00
|
|
|
//sofia_private->gateway->freq = expi;
|
|
|
|
//sofia_private->gateway->expires_str = switch_core_sprintf(sofia_private->gateway->pool, "%d", expi);
|
|
|
|
|
2009-06-04 20:00:53 +00:00
|
|
|
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,
|
2011-06-16 14:37:22 -05:00
|
|
|
switch_core_session_t *session, sofia_gateway_t *gateway, sip_t const *sip,
|
|
|
|
sofia_dispatch_event_t *de, 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;
|
2010-10-27 14:09:38 -05:00
|
|
|
char *dup_user = NULL;
|
|
|
|
char *dup_pass = 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;
|
2012-01-26 16:54:27 -06: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-10-27 14:09:38 -05:00
|
|
|
if (!gateway && !sip_auth_username && sip && sip->sip_to && sip->sip_to->a_url && sip->sip_to->a_url->url_user && sip->sip_to->a_url->url_host) {
|
|
|
|
switch_xml_t x_user, x_param, x_params;
|
|
|
|
switch_event_t *locate_params;
|
|
|
|
|
|
|
|
switch_event_create(&locate_params, SWITCH_EVENT_REQUEST_PARAMS);
|
|
|
|
switch_assert(locate_params);
|
|
|
|
|
2011-12-15 13:22:14 -05:00
|
|
|
switch_event_add_header_string(locate_params, SWITCH_STACK_BOTTOM, "action", "reverse-auth-lookup");
|
2010-10-27 14:09:38 -05:00
|
|
|
|
2012-06-19 21:58:43 -04:00
|
|
|
if ( sip->sip_call_id ) {
|
2012-06-19 22:43:28 -04:00
|
|
|
switch_event_add_header_string(locate_params, SWITCH_STACK_BOTTOM, "sip_call_id", sip->sip_call_id->i_id);
|
2012-06-19 21:58:43 -04:00
|
|
|
}
|
|
|
|
|
2010-10-27 14:09:38 -05:00
|
|
|
if (switch_xml_locate_user_merged("id", sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, NULL,
|
|
|
|
&x_user, locate_params) == SWITCH_STATUS_SUCCESS) {
|
|
|
|
if ((x_params = switch_xml_child(x_user, "params"))) {
|
|
|
|
for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) {
|
|
|
|
const char *var = switch_xml_attr_soft(x_param, "name");
|
|
|
|
const char *val = switch_xml_attr_soft(x_param, "value");
|
|
|
|
|
|
|
|
if (!strcasecmp(var, "reverse-auth-user")) {
|
|
|
|
dup_user = strdup(val);
|
|
|
|
sip_auth_username = dup_user;
|
|
|
|
} else if (!strcasecmp(var, "reverse-auth-pass")) {
|
|
|
|
dup_pass = strdup(val);
|
|
|
|
sip_auth_password = dup_pass;
|
|
|
|
}
|
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2010-10-27 14:09:38 -05:00
|
|
|
switch_xml_free(x_user);
|
|
|
|
}
|
|
|
|
}
|
2008-07-17 14:32:01 +00:00
|
|
|
|
2010-10-27 14:09:38 -05:00
|
|
|
switch_event_destroy(&locate_params);
|
|
|
|
}
|
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 {
|
2012-04-03 12:37:52 -05:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,
|
|
|
|
"Cannot locate any authentication credentials to complete an authentication request for realm '%s'\n", realm);
|
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());
|
|
|
|
|
2012-04-03 12:37:52 -05:00
|
|
|
nua_authenticate(nh,
|
|
|
|
TAG_IF(sofia_private && sofia_private->gateway, 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
|
|
|
|
2010-10-27 14:09:38 -05:00
|
|
|
|
|
|
|
switch_safe_free(dup_user);
|
|
|
|
switch_safe_free(dup_pass);
|
|
|
|
|
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,
|
2011-06-16 14:37:22 -05:00
|
|
|
sofia_dispatch_event_t *de,
|
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;
|
2011-05-23 17:15:32 -05:00
|
|
|
switch_xml_t user = NULL, param, uparams;
|
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;
|
2012-11-16 20:09:38 -06:00
|
|
|
|
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);
|
2012-11-16 20:09:38 -06:00
|
|
|
|
2013-02-25 15:42:21 -06:00
|
|
|
sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_reg_nonce_callback, &cb);
|
2009-11-12 03:52:07 +00:00
|
|
|
free(sql);
|
|
|
|
|
2013-02-25 15:42:21 -06:00
|
|
|
//if (!sofia_glue_execute_sql2str(profile, profile->dbh_mutex, sql, np, nplen)) {
|
2009-11-12 03:52:07 +00:00
|
|
|
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(¶ms, 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
|
|
|
|
2011-05-23 17:15:32 -05:00
|
|
|
if (switch_xml_locate_user_merged("id", zstr(username) ? "nobody" : username, domain_name, ip, &user, params) != SWITCH_STATUS_SUCCESS) {
|
2013-03-14 11:06:02 -05:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't find user [%s@%s] from %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,
|
2013-03-14 11:06:02 -05:00
|
|
|
ip, 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
|
|
|
}
|
|
|
|
|
2011-05-23 17:15:32 -05:00
|
|
|
if (!(uparams = switch_xml_child(user, "params"))) {
|
2007-12-10 23:48:54 +00:00
|
|
|
ret = AUTH_OK;
|
|
|
|
goto skip_auth;
|
2011-05-23 17:15:32 -05:00
|
|
|
} else {
|
2007-12-10 23:48:54 +00:00
|
|
|
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:
|
2011-12-16 14:31:15 -05:00
|
|
|
if (first && (ret == AUTH_OK || ret == AUTH_RENEWED)) {
|
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 ((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 ((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);
|
2012-10-25 11:31:42 -05:00
|
|
|
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
|
2011-12-16 14:31:15 -05:00
|
|
|
|
|
|
|
if (ret == AUTH_OK)
|
|
|
|
ret = AUTH_RENEWED;
|
2009-10-28 16:55:29 +00:00
|
|
|
}
|
|
|
|
|
2008-01-23 20:59:25 +00:00
|
|
|
switch_event_destroy(¶ms);
|
|
|
|
|
2011-05-23 17:15:32 -05:00
|
|
|
if (user) {
|
|
|
|
switch_xml_free(user);
|
2007-08-28 17:08:32 +00:00
|
|
|
}
|
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) {
|
2011-12-16 14:31:15 -05:00
|
|
|
if ((ret == AUTH_OK || ret == AUTH_RENEWED)) {
|
2009-11-12 03:52:07 +00:00
|
|
|
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);
|
2011-09-27 08:44:29 -05:00
|
|
|
if (key && (gateway = (sofia_gateway_t *) val) && !gateway->deleted && 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);
|
2011-09-27 08:44:29 -05:00
|
|
|
sofia_gateway_t *gp;
|
2007-04-30 20:35:35 +00:00
|
|
|
|
2011-06-16 14:32:08 -05:00
|
|
|
switch_mutex_lock(profile->gw_mutex);
|
2010-03-25 00:28:56 +00:00
|
|
|
|
|
|
|
gateway->next = profile->gateways;
|
|
|
|
profile->gateways = gateway;
|
|
|
|
|
2011-06-16 14:32:08 -05:00
|
|
|
switch_mutex_unlock(profile->gw_mutex);
|
|
|
|
|
|
|
|
switch_mutex_lock(mod_sofia_globals.hash_mutex);
|
2011-09-27 08:44:29 -05:00
|
|
|
|
|
|
|
if ((gp = switch_core_hash_find(mod_sofia_globals.gateway_hash, key))) {
|
|
|
|
if (gp->deleted) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removing deleted gateway from hash.\n");
|
|
|
|
switch_core_hash_delete(mod_sofia_globals.gateway_hash, gp->name);
|
|
|
|
switch_core_hash_delete(mod_sofia_globals.gateway_hash, pkey);
|
|
|
|
switch_core_hash_delete(mod_sofia_globals.gateway_hash, key);
|
|
|
|
}
|
2007-04-30 20:35:35 +00:00
|
|
|
}
|
2010-03-25 00:28:56 +00:00
|
|
|
|
2011-09-27 08:44:29 -05:00
|
|
|
if (!switch_core_hash_find(mod_sofia_globals.gateway_hash, key) && !switch_core_hash_find(mod_sofia_globals.gateway_hash, pkey)) {
|
|
|
|
status = switch_core_hash_insert(mod_sofia_globals.gateway_hash, key, gateway);
|
2010-02-18 22:39:08 +00:00
|
|
|
status = switch_core_hash_insert(mod_sofia_globals.gateway_hash, pkey, gateway);
|
2011-09-27 08:44:29 -05:00
|
|
|
} else {
|
|
|
|
status = SWITCH_STATUS_FALSE;
|
2010-02-18 22:39:08 +00:00
|
|
|
}
|
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
|
|
|
*/
|