unreg on sock disconnect
This commit is contained in:
parent
21408d4534
commit
e00ede7e7d
|
@ -2286,7 +2286,6 @@ int agent_create_master_transport(nta_agent_t *self, tagi_t *tags)
|
|||
{
|
||||
self->sa_tports =
|
||||
tport_tcreate(self, nta_agent_class, self->sa_root,
|
||||
TPTAG_SDWN_ERROR(0),
|
||||
TPTAG_IDLE(1800000),
|
||||
TAG_NEXT(tags));
|
||||
|
||||
|
@ -8339,6 +8338,14 @@ outgoing_tport_error(nta_agent_t *agent, nta_outgoing_t *orq,
|
|||
return;
|
||||
}
|
||||
}
|
||||
else if (error == 0) {
|
||||
/*
|
||||
* Server closed connection. RFC3261:
|
||||
* "there is no coupling between TCP connection state and SIP
|
||||
* processing."
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
if (outgoing_other_destinations(orq)) {
|
||||
outgoing_print_tport_error(orq, 5, "trying alternative server after ",
|
||||
|
|
|
@ -877,9 +877,171 @@ TCase *pingpong_tcase(int threading)
|
|||
return tc;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
static struct dialog *dialog = NULL;
|
||||
|
||||
static void registrar_setup(void)
|
||||
{
|
||||
struct event *event;
|
||||
tagi_t const *t;
|
||||
sip_contact_t *m;
|
||||
|
||||
dialog = su_home_new(sizeof *dialog); fail_if(!dialog);
|
||||
|
||||
nua = s2_nua_setup("register",
|
||||
NUTAG_APPL_METHOD("REGISTER"),
|
||||
NUTAG_ALLOW("REGISTER"),
|
||||
NUTAG_PROXY(SIP_NONE),
|
||||
TAG_END());
|
||||
|
||||
nua_get_params(nua, TAG_ANY(), TAG_END());
|
||||
event = s2_wait_for_event(nua_r_get_params, 200);
|
||||
fail_unless(event != NULL);
|
||||
|
||||
t = tl_find(event->data->e_tags, ntatag_contact);
|
||||
fail_unless(t != NULL);
|
||||
m = sip_contact_dup(dialog->home, (sip_contact_t *)t->t_value);
|
||||
fail_unless(m != NULL);
|
||||
|
||||
s2sip->sut.contact = m;
|
||||
}
|
||||
|
||||
static void registrar_thread_setup(void)
|
||||
{
|
||||
s2_nua_thread = 1;
|
||||
registrar_setup();
|
||||
}
|
||||
|
||||
static void registrar_threadless_setup(void)
|
||||
{
|
||||
s2_nua_thread = 1;
|
||||
registrar_setup();
|
||||
}
|
||||
|
||||
static void registrar_teardown(void)
|
||||
{
|
||||
s2_teardown_started("registrar");
|
||||
nua_shutdown(nua);
|
||||
fail_unless_event(nua_r_shutdown, 200);
|
||||
s2_nua_teardown();
|
||||
}
|
||||
|
||||
static void add_registrar_fixtures(TCase *tc, int threading)
|
||||
{
|
||||
void (*setup)(void);
|
||||
|
||||
if (threading)
|
||||
setup = registrar_thread_setup;
|
||||
else
|
||||
setup = registrar_threadless_setup;
|
||||
|
||||
tcase_add_checked_fixture(tc, setup, registrar_teardown);
|
||||
}
|
||||
|
||||
START_TEST(registrar_1_4_0)
|
||||
{
|
||||
struct event *event;
|
||||
nua_handle_t *nh;
|
||||
struct message *response;
|
||||
|
||||
S2_CASE("1.4.0", "Registrar", "Test receiving a REGISTER");
|
||||
|
||||
fail_if(s2_sip_request_to(dialog, SIP_METHOD_REGISTER, NULL,
|
||||
SIPTAG_FROM_STR("<sip:tst@example.com>"),
|
||||
SIPTAG_TO_STR("<sip:tst@example.com>"),
|
||||
TAG_END()));
|
||||
|
||||
event = s2_wait_for_event(nua_i_register, 100);
|
||||
fail_unless(event != NULL);
|
||||
nh = event->nh; fail_if(!nh);
|
||||
|
||||
nua_respond(nh, 200, "Ok",
|
||||
NUTAG_WITH_SAVED(event->event),
|
||||
TAG_END());
|
||||
|
||||
response = s2_sip_wait_for_response(200, SIP_METHOD_REGISTER);
|
||||
fail_if(!response);
|
||||
s2_sip_free_message(response);
|
||||
|
||||
nua_handle_destroy(nh);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(registrar_1_4_1)
|
||||
{
|
||||
struct event *event;
|
||||
nua_handle_t *nh;
|
||||
struct message *response;
|
||||
|
||||
S2_CASE("1.4.1", "Registrar", "Test receiving a REGISTER via TCP");
|
||||
|
||||
fail_if(s2_sip_request_to(dialog, SIP_METHOD_REGISTER, s2sip->tcp.tport,
|
||||
SIPTAG_FROM_STR("<sip:tst@example.com>"),
|
||||
SIPTAG_TO_STR("<sip:tst@example.com>"),
|
||||
TAG_END()));
|
||||
|
||||
event = s2_wait_for_event(nua_i_register, 100);
|
||||
fail_if(!event);
|
||||
nh = event->nh; fail_if(!nh);
|
||||
|
||||
nua_respond(nh, 200, "Ok",
|
||||
NUTAG_WITH_SAVED(event->event),
|
||||
TAG_END());
|
||||
|
||||
response = s2_sip_wait_for_response(200, SIP_METHOD_REGISTER);
|
||||
fail_if(!response);
|
||||
tport_shutdown(response->tport, 2);
|
||||
s2_sip_free_message(response);
|
||||
|
||||
event = s2_wait_for_event(nua_i_media_error, 0);
|
||||
fail_if(!event);
|
||||
nua_handle_destroy(nh);
|
||||
|
||||
fail_if(s2_sip_request_to(dialog, SIP_METHOD_REGISTER, s2sip->tcp.tport,
|
||||
SIPTAG_FROM_STR("<sip:tst@example.com>"),
|
||||
SIPTAG_TO_STR("<sip:tst@example.com>"),
|
||||
TAG_END()));
|
||||
|
||||
event = s2_wait_for_event(nua_i_register, 100);
|
||||
fail_if(!event);
|
||||
nh = event->nh; fail_if(!nh);
|
||||
|
||||
nua_respond(nh, 200, "Ok",
|
||||
NUTAG_WITH_SAVED(event->event),
|
||||
TAG_END());
|
||||
|
||||
response = s2_sip_wait_for_response(200, SIP_METHOD_REGISTER);
|
||||
fail_if(!response);
|
||||
nua_handle_destroy(nh);
|
||||
|
||||
s2_step();
|
||||
s2_step();
|
||||
s2_step();
|
||||
|
||||
tport_shutdown(response->tport, 2);
|
||||
s2_sip_free_message(response);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
TCase *registrar_tcase(int threading)
|
||||
{
|
||||
TCase *tc = tcase_create("1.4 - REGISTER server");
|
||||
|
||||
add_registrar_fixtures(tc, threading);
|
||||
|
||||
tcase_add_test(tc, registrar_1_4_0);
|
||||
tcase_add_test(tc, registrar_1_4_1);
|
||||
|
||||
tcase_set_timeout(tc, 10);
|
||||
|
||||
return tc;
|
||||
}
|
||||
|
||||
void check_register_cases(Suite *suite, int threading)
|
||||
{
|
||||
suite_add_tcase(suite, register_tcase(threading));
|
||||
suite_add_tcase(suite, pingpong_tcase(threading));
|
||||
suite_add_tcase(suite, registrar_tcase(threading));
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,9 @@
|
|||
|
||||
#include <assert.h>
|
||||
|
||||
#define TP_CLIENT_T struct nua_handle_s
|
||||
#define TP_STACK_T struct nta_agent_s
|
||||
|
||||
#include <sofia-sip/su_string.h>
|
||||
#include <sofia-sip/sip_protos.h>
|
||||
#include <sofia-sip/sip_status.h>
|
||||
|
@ -49,6 +52,79 @@
|
|||
|
||||
#include "nua_stack.h"
|
||||
|
||||
#include <sofia-sip/tport.h>
|
||||
#include <sofia-sip/nta_tport.h>
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Registrar usage */
|
||||
|
||||
struct registrar_usage
|
||||
{
|
||||
tport_t *tport; /**< */
|
||||
int pending; /**< Waiting for tport to close */
|
||||
};
|
||||
|
||||
static char const *nua_registrar_usage_name(nua_dialog_usage_t const *du)
|
||||
{
|
||||
return "registrar";
|
||||
}
|
||||
|
||||
static int nua_registrar_usage_add(nua_handle_t *nh,
|
||||
nua_dialog_state_t *ds,
|
||||
nua_dialog_usage_t *du)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nua_registrar_usage_remove(nua_handle_t *nh,
|
||||
nua_dialog_state_t *ds,
|
||||
nua_dialog_usage_t *du,
|
||||
nua_client_request_t *cr,
|
||||
nua_server_request_t *sr)
|
||||
{
|
||||
struct registrar_usage *ru;
|
||||
|
||||
ru = nua_dialog_usage_private(du);
|
||||
|
||||
if (ru->pending)
|
||||
tport_release(ru->tport, ru->pending, NULL, NULL, nh, 0), ru->pending = 0;
|
||||
|
||||
tport_unref(ru->tport), ru->tport = NULL;
|
||||
}
|
||||
|
||||
static void nua_registrar_usage_refresh(nua_handle_t *nh,
|
||||
nua_dialog_state_t *ds,
|
||||
nua_dialog_usage_t *du,
|
||||
sip_time_t now)
|
||||
{
|
||||
}
|
||||
|
||||
/** Terminate registration usage.
|
||||
*
|
||||
* @retval >0 shutdown done
|
||||
* @retval 0 shutdown in progress
|
||||
* @retval <0 try again later
|
||||
*/
|
||||
static int nua_registrar_usage_shutdown(nua_handle_t *nh,
|
||||
nua_dialog_state_t *ds,
|
||||
nua_dialog_usage_t *du)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static nua_usage_class const nua_registrar_usage[1] = {
|
||||
{
|
||||
sizeof (struct registrar_usage), sizeof nua_registrar_usage,
|
||||
nua_registrar_usage_add,
|
||||
nua_registrar_usage_remove,
|
||||
nua_registrar_usage_name,
|
||||
nua_base_usage_update_params,
|
||||
NULL,
|
||||
nua_registrar_usage_refresh,
|
||||
nua_registrar_usage_shutdown
|
||||
}};
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* REGISTER */
|
||||
|
||||
|
@ -93,6 +169,9 @@
|
|||
* @END_NUA_EVENT
|
||||
*/
|
||||
|
||||
static int nua_registrar_server_preprocess(nua_server_request_t *sr);
|
||||
static int nua_registrar_server_report(nua_server_request_t *, tagi_t const *);
|
||||
|
||||
nua_server_methods_t const nua_register_server_methods =
|
||||
{
|
||||
SIP_METHOD_REGISTER,
|
||||
|
@ -104,8 +183,78 @@ nua_server_methods_t const nua_register_server_methods =
|
|||
0, /* Do not add Contact */
|
||||
},
|
||||
nua_base_server_init,
|
||||
nua_base_server_preprocess,
|
||||
nua_registrar_server_preprocess,
|
||||
nua_base_server_params,
|
||||
nua_base_server_respond,
|
||||
nua_base_server_report,
|
||||
nua_registrar_server_report,
|
||||
};
|
||||
|
||||
static void
|
||||
registrar_tport_error(nta_agent_t *nta, nua_handle_t *nh,
|
||||
tport_t *tp, msg_t *msg, int error)
|
||||
{
|
||||
nua_dialog_state_t *ds = nh->nh_ds;
|
||||
nua_dialog_usage_t *du;
|
||||
struct registrar_usage *ru;
|
||||
|
||||
SU_DEBUG_3(("tport error %d: %s\n", error, su_strerror(error)));
|
||||
|
||||
du = nua_dialog_usage_get(ds, nua_registrar_usage, NULL);
|
||||
|
||||
if (du == NULL)
|
||||
return;
|
||||
|
||||
ru = nua_dialog_usage_private(du);
|
||||
if (ru->tport) {
|
||||
tport_release(ru->tport, ru->pending, NULL, NULL, nh, 0), ru->pending = 0;
|
||||
tport_unref(ru->tport), ru->tport = NULL;
|
||||
}
|
||||
|
||||
nua_stack_event(nh->nh_nua, nh, NULL,
|
||||
nua_i_media_error, 500, "Transport error detected",
|
||||
NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
nua_registrar_server_preprocess(nua_server_request_t *sr)
|
||||
{
|
||||
nua_handle_t *nh = sr->sr_owner;
|
||||
nua_dialog_state_t *ds = sr->sr_owner->nh_ds;
|
||||
nua_dialog_usage_t *du;
|
||||
struct registrar_usage *ru;
|
||||
tport_t *tport;
|
||||
|
||||
tport = nta_incoming_transport(nh->nh_nua->nua_nta, sr->sr_irq, sr->sr_request.msg);
|
||||
|
||||
if (!tport_is_tcp(tport))
|
||||
return 0;
|
||||
|
||||
du = nua_dialog_usage_get(ds, nua_registrar_usage, NULL);
|
||||
if (du == NULL)
|
||||
du = nua_dialog_usage_add(nh, ds, nua_registrar_usage, NULL);
|
||||
|
||||
if (du == NULL)
|
||||
return SR_STATUS1(sr, SIP_500_INTERNAL_SERVER_ERROR);
|
||||
|
||||
ru = nua_dialog_usage_private(du);
|
||||
|
||||
if (ru->tport && ru->tport != tport) {
|
||||
tport_release(ru->tport, ru->pending, NULL, NULL, nh, 0), ru->pending = 0;
|
||||
tport_unref(ru->tport), ru->tport = NULL;
|
||||
}
|
||||
|
||||
ru->tport = tport_ref(tport);
|
||||
ru->pending = tport_pend(tport, NULL, registrar_tport_error, nh);
|
||||
|
||||
tport_set_params(tport,
|
||||
TPTAG_SDWN_ERROR(1),
|
||||
TAG_END());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nua_registrar_server_report(nua_server_request_t *sr, tagi_t const *tags)
|
||||
{
|
||||
return nua_base_server_report(sr, tags);
|
||||
}
|
||||
|
|
|
@ -166,6 +166,10 @@ struct sofia_private {
|
|||
sofia_gateway_t *gateway;
|
||||
char gateway_name[256];
|
||||
char auth_gateway_name[256];
|
||||
char *call_id;
|
||||
char *network_ip;
|
||||
char *network_port;
|
||||
char *key;
|
||||
int destroy_nh;
|
||||
int destroy_me;
|
||||
int is_call;
|
||||
|
@ -838,7 +842,7 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
|
|||
void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, sofia_dispatch_event_t *de, tagi_t tags[]);
|
||||
|
||||
|
||||
void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
|
||||
void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t **sofia_private, sip_t const *sip,
|
||||
sofia_dispatch_event_t *de,
|
||||
tagi_t tags[]);
|
||||
|
||||
|
@ -919,8 +923,9 @@ void sofia_glue_pass_sdp(private_object_t *tech_pvt, char *sdp);
|
|||
switch_call_cause_t sofia_glue_sip_cause_to_freeswitch(int status);
|
||||
void sofia_glue_do_xfer_invite(switch_core_session_t *session);
|
||||
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, uint32_t keylen, switch_event_t **v_event, const char *is_nat);
|
||||
sofia_dispatch_event_t *de,
|
||||
sofia_regtype_t regtype, char *key,
|
||||
uint32_t keylen, switch_event_t **v_event, const char *is_nat, sofia_private_t **sofia_private_p);
|
||||
extern switch_endpoint_interface_t *sofia_endpoint_interface;
|
||||
void sofia_presence_set_chat_hash(private_object_t *tech_pvt, sip_t const *sip);
|
||||
switch_status_t sofia_on_hangup(switch_core_session_t *session);
|
||||
|
@ -1098,6 +1103,7 @@ int sofia_glue_check_nat(sofia_profile_t *profile, const char *network_ip);
|
|||
|
||||
switch_status_t sofia_glue_ext_address_lookup(sofia_profile_t *profile, char **ip, switch_port_t *port,
|
||||
const char *sourceip, switch_memory_pool_t *pool);
|
||||
void sofia_reg_check_socket(sofia_profile_t *profile, const char *call_id, const char *network_addr, const char *network_ip);
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
|
|
|
@ -1268,7 +1268,7 @@ static void our_sofia_event_callback(nua_event_t event,
|
|||
case nua_i_register:
|
||||
//nua_respond(nh, SIP_200_OK, SIPTAG_CONTACT(sip->sip_contact), NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
|
||||
//nua_handle_destroy(nh);
|
||||
sofia_reg_handle_sip_i_register(nua, profile, nh, sofia_private, sip, de, tags);
|
||||
sofia_reg_handle_sip_i_register(nua, profile, nh, &sofia_private, sip, de, tags);
|
||||
break;
|
||||
case nua_i_state:
|
||||
sofia_handle_sip_i_state(session, status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
|
||||
|
@ -1458,6 +1458,24 @@ static void our_sofia_event_callback(nua_event_t event,
|
|||
case nua_i_subscribe:
|
||||
sofia_presence_handle_sip_i_subscribe(status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
|
||||
break;
|
||||
case nua_i_media_error:
|
||||
{
|
||||
|
||||
if (sofia_private && sofia_private->call_id && sofia_private->network_ip && sofia_private->network_port) {
|
||||
char *sql;
|
||||
|
||||
sql = switch_mprintf("delete from sip_registrations where call_id='%q' and network_ip='%q' and network_port='%q'",
|
||||
sofia_private->call_id, sofia_private->network_ip, sofia_private->network_port);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "SOCKET DISCONNECT: %s %s:%s\n",
|
||||
sofia_private->call_id, sofia_private->network_ip, sofia_private->network_port);
|
||||
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
|
||||
|
||||
|
||||
sofia_reg_check_socket(profile, sofia_private->call_id, sofia_private->network_ip, sofia_private->network_port);
|
||||
}
|
||||
nua_handle_destroy(nh);
|
||||
}
|
||||
break;
|
||||
case nua_r_authenticate:
|
||||
|
||||
if (status >= 500) {
|
||||
|
@ -1486,6 +1504,10 @@ static void our_sofia_event_callback(nua_event_t event,
|
|||
tech_pvt->want_event = 0;
|
||||
}
|
||||
|
||||
if (sofia_private && sofia_private->call_id) {
|
||||
check_destroy = 0;
|
||||
}
|
||||
|
||||
switch (event) {
|
||||
case nua_i_subscribe:
|
||||
case nua_r_notify:
|
||||
|
@ -7837,7 +7859,7 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
|
|||
if (!strcmp(network_ip, profile->sipip) && network_port == profile->sip_port) {
|
||||
calling_myself++;
|
||||
} else {
|
||||
if (sofia_reg_handle_register(nua, profile, nh, sip, de, REG_INVITE, key, sizeof(key), &v_event, NULL)) {
|
||||
if (sofia_reg_handle_register(nua, profile, nh, sip, de, REG_INVITE, key, sizeof(key), &v_event, NULL, NULL)) {
|
||||
if (v_event) {
|
||||
switch_event_destroy(&v_event);
|
||||
}
|
||||
|
|
|
@ -636,15 +636,34 @@ int sofia_sla_dialog_del_callback(void *pArg, int argc, char **argv, char **colu
|
|||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int sofia_reg_del_callback(void *pArg, int argc, char **argv, char **columnNames)
|
||||
{
|
||||
switch_event_t *s_event;
|
||||
sofia_profile_t *profile = (sofia_profile_t *) pArg;
|
||||
|
||||
if (argc > 12 && atoi(argv[12]) == 1) {
|
||||
if (argc > 13 && atoi(argv[13]) == 1) {
|
||||
sofia_reg_send_reboot(profile, argv[0], argv[1], argv[2], argv[3], argv[7], argv[11]);
|
||||
}
|
||||
|
||||
sofia_reg_check_socket(profile, argv[0], argv[11], argv[12]);
|
||||
|
||||
|
||||
if (argc >= 3) {
|
||||
if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_EXPIRE) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile-name", argv[10]);
|
||||
|
@ -706,7 +725,7 @@ void sofia_reg_expire_call_id(sofia_profile_t *profile, const char *call_id, int
|
|||
}
|
||||
|
||||
sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,rpid,expires"
|
||||
",user_agent,server_user,server_host,profile_name,network_ip"
|
||||
",user_agent,server_user,server_host,profile_name,network_ip,network_port"
|
||||
",%d from sip_registrations where call_id='%q' %s", reboot, call_id, sqlextra);
|
||||
|
||||
|
||||
|
@ -728,11 +747,11 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot)
|
|||
|
||||
if (now) {
|
||||
sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,rpid,expires"
|
||||
",user_agent,server_user,server_host,profile_name,network_ip"
|
||||
",user_agent,server_user,server_host,profile_name,network_ip, network_port"
|
||||
",%d from sip_registrations where expires > 0 and expires <= %ld", reboot, (long) now);
|
||||
} else {
|
||||
sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,rpid,expires"
|
||||
",user_agent,server_user,server_host,profile_name,network_ip" ",%d from sip_registrations where expires > 0", reboot);
|
||||
",user_agent,server_user,server_host,profile_name,network_ip, network_port" ",%d from sip_registrations where expires > 0", reboot);
|
||||
}
|
||||
|
||||
sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_reg_del_callback, profile);
|
||||
|
@ -872,7 +891,7 @@ void sofia_reg_check_sync(sofia_profile_t *profile)
|
|||
char *sql;
|
||||
|
||||
sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,rpid,expires"
|
||||
",user_agent,server_user,server_host,profile_name,network_ip"
|
||||
",user_agent,server_user,server_host,profile_name,network_ip,network_port"
|
||||
" from sip_registrations where expires > 0");
|
||||
|
||||
|
||||
|
@ -1065,7 +1084,7 @@ static int debounce_check(sofia_profile_t *profile, const char *user, const char
|
|||
|
||||
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,
|
||||
uint32_t keylen, switch_event_t **v_event, const char *is_nat)
|
||||
uint32_t keylen, switch_event_t **v_event, const char *is_nat, sofia_private_t **sofia_private_p)
|
||||
{
|
||||
sip_to_t const *to = NULL;
|
||||
sip_from_t const *from = NULL;
|
||||
|
@ -1117,6 +1136,11 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
|
|||
const char *uparams = NULL;
|
||||
const char *p;
|
||||
char *utmp = NULL;
|
||||
sofia_private_t *sofia_private = NULL;
|
||||
|
||||
if (sofia_private_p) {
|
||||
sofia_private = *sofia_private_p;
|
||||
}
|
||||
|
||||
if (sip && sip->sip_contact->m_url->url_params) {
|
||||
uparams = sip->sip_contact->m_url->url_params;
|
||||
|
@ -1606,6 +1630,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
|
|||
multi_reg = (sofia_test_pflag(profile, PFLAG_MULTIREG)) ? 1 : 0;
|
||||
multi_reg_contact = (sofia_test_pflag(profile, PFLAG_MULTIREG_CONTACT)) ? 1 : 0;
|
||||
|
||||
|
||||
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));
|
||||
|
@ -1624,6 +1649,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
|
|||
username = switch_event_get_header(auth_params, "sip_auth_username");
|
||||
realm = switch_event_get_header(auth_params, "sip_auth_realm");
|
||||
}
|
||||
|
||||
if (auth_res != AUTH_RENEWED || !multi_reg) {
|
||||
if (multi_reg) {
|
||||
if (multi_reg_contact) {
|
||||
|
@ -1635,7 +1661,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
|
|||
} else {
|
||||
sql = switch_mprintf("delete from sip_registrations where sip_user='%q' and sip_host='%q'", to_user, reg_host);
|
||||
}
|
||||
|
||||
|
||||
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
|
||||
} else {
|
||||
char buf[32] = "";
|
||||
|
@ -1663,6 +1689,38 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
|
|||
|
||||
switch_safe_free(url);
|
||||
switch_safe_free(contact);
|
||||
|
||||
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
printf("SOFIA nh[%p] pvt[%p] call_id %s key %s\n", (void*) nh, (void *) sofia_private, call_id, key);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!update_registration) {
|
||||
sql = switch_mprintf("insert into sip_registrations "
|
||||
|
@ -1700,6 +1758,18 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
|
|||
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_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);
|
||||
|
@ -1739,6 +1809,8 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
|
|||
}
|
||||
}
|
||||
|
||||
sofia_reg_check_socket(profile, call_id, network_ip, network_port_c);
|
||||
|
||||
if (send && switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", rpid);
|
||||
|
@ -1769,7 +1841,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
|
|||
} else {
|
||||
sql = switch_mprintf("delete from sip_registrations where call_id='%q'", call_id);
|
||||
}
|
||||
|
||||
|
||||
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
|
||||
|
||||
switch_safe_free(icontact);
|
||||
|
@ -1927,8 +1999,8 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
|
|||
|
||||
|
||||
|
||||
void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
|
||||
sofia_dispatch_event_t *de,
|
||||
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,
|
||||
tagi_t tags[])
|
||||
{
|
||||
char key[128] = "";
|
||||
|
@ -1938,6 +2010,7 @@ void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_h
|
|||
int network_port = 0;
|
||||
char *is_nat = NULL;
|
||||
|
||||
|
||||
#if 0 /* This seems to cause undesirable effects so nevermind */
|
||||
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;
|
||||
|
@ -2043,15 +2116,15 @@ void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_h
|
|||
is_nat = NULL;
|
||||
}
|
||||
|
||||
sofia_reg_handle_register(nua, profile, nh, sip, de, type, key, sizeof(key), &v_event, is_nat);
|
||||
sofia_reg_handle_register(nua, profile, nh, sip, de, type, key, sizeof(key), &v_event, is_nat, sofia_private_p);
|
||||
|
||||
if (v_event) {
|
||||
switch_event_destroy(&v_event);
|
||||
}
|
||||
|
||||
end:
|
||||
|
||||
nua_handle_destroy(nh);
|
||||
|
||||
if (!sofia_private_p || !*sofia_private_p) nua_handle_destroy(nh);
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue