FS-5106 fire an event when a sip client doesn't respond to option-ping

When all-reg-options-ping is enabled, this adds a new custom event to mod_sofia
(sofia::sip_user_state), which is fired when a client stops responding to such
ping packets (or when it is reachable again).

Add two needed new columns to the sip_registrations table:
  - ping_status, which is "Reachable" or "Unreachable" depending on the client
    status;
  - ping_count, which tracks the number of ping responses received and is used
    to provide some kind of hysteresis to avoid firing the event in case of
    transitory network failures.

Then ping_count is checked against two threshold values, sip-user-ping-min
and sip-user-ping-max in a similar fashion as the ping-{max,min} options for
the gateways. These two values are configurable in the profile's xml
configuration file.

Also, if unregister-on-options-fail is enabled, the client is unregistered
based on the number of OPTIONS failure which is also checked against the
sip-user-ping-{min,max} values.
This commit is contained in:
Flavio Grossi 2014-09-09 09:43:47 +02:00
parent dac4afbfdb
commit 5653551904
5 changed files with 208 additions and 28 deletions

View File

@ -2418,6 +2418,7 @@ static int show_reg_callback(void *pArg, int argc, char **argv, char **columnNam
"Contact: \t%s\n"
"Agent: \t%s\n"
"Status: \t%s(%s) EXP(%s) EXPSECS(%d)\n"
"Ping-Status:\t%s\n"
"Host: \t%s\n"
"IP: \t%s\n"
"Port: \t%s\n"
@ -2425,9 +2426,9 @@ static int show_reg_callback(void *pArg, int argc, char **argv, char **columnNam
"Auth-Realm: \t%s\n"
"MWI-Account:\t%s@%s\n\n",
switch_str_nil(argv[0]), switch_str_nil(argv[1]), switch_str_nil(argv[2]), switch_str_nil(argv[3]),
switch_str_nil(argv[7]), switch_str_nil(argv[4]), switch_str_nil(argv[5]), exp_buf, exp_secs, switch_str_nil(argv[11]),
switch_str_nil(argv[12]), switch_str_nil(argv[13]), switch_str_nil(argv[14]), switch_str_nil(argv[15]),
switch_str_nil(argv[16]), switch_str_nil(argv[17]));
switch_str_nil(argv[7]), switch_str_nil(argv[4]), switch_str_nil(argv[5]), exp_buf, exp_secs, switch_str_nil(argv[18]),
switch_str_nil(argv[11]), switch_str_nil(argv[12]), switch_str_nil(argv[13]), switch_str_nil(argv[14]),
switch_str_nil(argv[15]), switch_str_nil(argv[16]), switch_str_nil(argv[17]));
return 0;
}
@ -2459,6 +2460,7 @@ static int show_reg_callback_xml(void *pArg, int argc, char **argv, char **colum
cb->stream->write_function(cb->stream, " <agent>%s</agent>\n", switch_amp_encode(switch_str_nil(argv[7]), xmlbuf, buflen));
cb->stream->write_function(cb->stream, " <status>%s(%s) exp(%s) expsecs(%d)</status>\n", switch_str_nil(argv[4]), switch_str_nil(argv[5]),
exp_buf, exp_secs);
cb->stream->write_function(cb->stream, " <ping-status>%s</ping-status>\n", switch_str_nil(argv[18]));
cb->stream->write_function(cb->stream, " <host>%s</host>\n", switch_str_nil(argv[11]));
cb->stream->write_function(cb->stream, " <network-ip>%s</network-ip>\n", switch_str_nil(argv[12]));
cb->stream->write_function(cb->stream, " <network-port>%s</network-port>\n", switch_str_nil(argv[13]));
@ -2682,19 +2684,19 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t
if (!sql && argv[2] && !strcasecmp(argv[2], "pres") && argv[3]) {
sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,"
"rpid,expires,user_agent,server_user,server_host,profile_name,hostname,"
"network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host"
"network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status"
" from sip_registrations where profile_name='%q' and presence_hosts like '%%%q%%'", profile->name, argv[3]);
}
if (!sql && argv[2] && !strcasecmp(argv[2], "reg") && argv[3]) {
sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,"
"rpid,expires,user_agent,server_user,server_host,profile_name,hostname,"
"network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host"
"network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host, ping_status"
" from sip_registrations where profile_name='%q' and contact like '%%%q%%'", profile->name, argv[3]);
}
if (!sql && argv[2] && !strcasecmp(argv[2], "reg")) {
sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,"
"rpid,expires,user_agent,server_user,server_host,profile_name,hostname,"
"network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host"
"network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status"
" from sip_registrations where profile_name='%q'", profile->name);
}
if (!sql && argv[2] && !strcasecmp(argv[2], "user") && argv[3]) {
@ -2721,7 +2723,7 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t
sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,"
"rpid,expires,user_agent,server_user,server_host,profile_name,hostname,"
"network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host"
"network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status"
" from sip_registrations where profile_name='%q' and %s", profile->name, sqlextra);
switch_safe_free(dup);
switch_safe_free(sqlextra);
@ -2965,21 +2967,21 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl
sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,"
"rpid,expires,user_agent,server_user,server_host,profile_name,hostname,"
"network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host"
"network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status"
" from sip_registrations where profile_name='%q' and presence_hosts like '%%%q%%'", profile->name, argv[3]);
}
if (!sql && argv[2] && !strcasecmp(argv[2], "reg") && argv[3]) {
sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,"
"rpid,expires,user_agent,server_user,server_host,profile_name,hostname,"
"network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host"
"network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status"
" from sip_registrations where profile_name='%q' and contact like '%%%q%%'", profile->name, argv[3]);
}
if (!sql && argv[2] && !strcasecmp(argv[2], "reg")) {
sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,"
"rpid,expires,user_agent,server_user,server_host,profile_name,hostname,"
"network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host"
"network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status"
" from sip_registrations where profile_name='%q'", profile->name);
}
if (!sql && argv[2] && !strcasecmp(argv[2], "user") && argv[3]) {
@ -3006,7 +3008,7 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl
sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,"
"rpid,expires,user_agent,server_user,server_host,profile_name,hostname,"
"network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host"
"network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status"
" from sip_registrations where profile_name='%q' and %s", profile->name, sqlextra);
switch_safe_free(dup);
switch_safe_free(sqlextra);

View File

@ -84,6 +84,7 @@ typedef struct private_object private_object_t;
#define MY_EVENT_UNREGISTER "sofia::unregister"
#define MY_EVENT_EXPIRE "sofia::expire"
#define MY_EVENT_GATEWAY_STATE "sofia::gateway_state"
#define MY_EVENT_SIP_USER_STATE "sofia::sip_user_state"
#define MY_EVENT_NOTIFY_REFER "sofia::notify_refer"
#define MY_EVENT_REINVITE "sofia::reinvite"
#define MY_EVENT_GATEWAY_ADD "sofia::gateway_add"
@ -426,6 +427,13 @@ typedef enum {
SOFIA_GATEWAY_INVALID
} sofia_gateway_status_t;
typedef enum {
SOFIA_REG_REACHABLE,
SOFIA_REG_UNREACHABLE,
SOFIA_REG_INVALID
} sofia_sip_user_status_t;
typedef enum {
SUB_STATE_UNSUBED,
SUB_STATE_TRYING,
@ -603,6 +611,8 @@ struct sofia_profile {
char *challenge_realm;
char *pnp_prov_url;
char *pnp_notify_profile;
int sip_user_ping_max;
int sip_user_ping_min;
sofia_cid_type_t cid_type;
switch_core_media_dtmf_t dtmf_type;
int auto_restart;
@ -1124,6 +1134,9 @@ void sofia_profile_destroy(sofia_profile_t *profile);
switch_status_t sip_dig_function(_In_opt_z_ const char *cmd, _In_opt_ switch_core_session_t *session, _In_ switch_stream_handle_t *stream);
const char *sofia_gateway_status_name(sofia_gateway_status_t status);
void sofia_reg_fire_custom_gateway_state_event(sofia_gateway_t *gateway, int status, const char *phrase);
const char *sofia_sip_user_status_name(sofia_sip_user_status_t status);
void sofia_reg_fire_custom_sip_user_state_event(sofia_profile_t *profile, const char *sip_user, const char *contact,
const char* from_user, const char* from_host, const char *call_id, sofia_sip_user_status_t status, int options_res, const char *phrase);
uint32_t sofia_reg_reg_count(sofia_profile_t *profile, const char *user, const char *host);
char *sofia_media_get_multipart(switch_core_session_t *session, const char *prefix, const char *sdp, char **mp_type);
int sofia_glue_tech_simplify(private_object_t *tech_pvt);

View File

@ -2477,11 +2477,11 @@ void event_handler(switch_event_t *event)
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,"
"mwi_user, mwi_host, orig_server_host, orig_hostname) "
"values ('%q','%q','%q','%q','%q','Registered','%q',%ld, '%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q')",
"mwi_user, mwi_host, orig_server_host, orig_hostname, ping_status, ping_count) "
"values ('%q','%q','%q','%q','%q','Registered','%q',%ld, '%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q', '%q', %d)",
call_id, from_user, from_host, presence_hosts, contact_str, rpid, expires, user_agent, to_user, guess_ip4,
profile_name, mod_sofia_globals.hostname, network_ip, network_port, username, realm, mwi_user, mwi_host,
orig_server_host, orig_hostname);
orig_server_host, orig_hostname, "Reachable", 0);
if (sql) {
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
@ -2495,6 +2495,33 @@ void event_handler(switch_event_t *event)
end:
switch_safe_free(fixed_contact_str);
switch_safe_free(dup_mwi_account);
} else if ((subclass = switch_event_get_header_nil(event, "orig-event-subclass")) && !strcasecmp(subclass, MY_EVENT_SIP_USER_STATE)) {
char *profile_name = switch_event_get_header_nil(event, "orig-profile-name");
char *from_user = switch_event_get_header_nil(event, "orig-from-user");
char *from_host = switch_event_get_header_nil(event, "orig-from-host");
const char *call_id = switch_event_get_header_nil(event, "orig-call-id");
char *ping_status = switch_event_get_header_nil(event, "orig-Ping-Status");
sofia_profile_t *profile = NULL;
if (!profile_name || !(profile = sofia_glue_find_profile(profile_name))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Profile\n");
} else {
if (!strcmp(ping_status, "REACHABLE")) {
sql = switch_mprintf("update sip_registrations set ping_status='%s' where sip_user='%s' and sip_host='%s' and call_id='%q'",
"Reachable", from_user, from_host, call_id);
} else {
sql = switch_mprintf("update sip_registrations set ping_status='%s' where sip_user='%s' and sip_host='%s' and call_id='%q'",
"Unreachable", from_user, from_host, call_id);
}
if (sql) {
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Propagating sip_user_state for %s@%s. Ping-Status: %s\n", from_user, from_host, ping_status);
}
if (profile) {
sofia_glue_release_profile(profile);
}
}
}
}
@ -4014,6 +4041,9 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
profile->user_agent = switch_core_sprintf(profile->pool, "FreeSWITCH-mod_sofia/%s", switch_version_full());
profile->sip_user_ping_max = 3;
profile->sip_user_ping_min = 1;
profile->name = switch_core_strdup(profile->pool, xprofilename);
switch_snprintf(url, sizeof(url), "sofia_reg_%s", xprofilename);
@ -4772,6 +4802,10 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
} else {
sofia_clear_pflag(profile, PFLAG_UNREG_OPTIONS_FAIL);
}
} else if (!strcasecmp(var, "sip-user-ping-max")) {
profile->sip_user_ping_max = atoi(val);
} else if (!strcasecmp(var, "sip-user-ping-min")) {
profile->sip_user_ping_min = atoi(val);
} else if (!strcasecmp(var, "require-secure-rtp")) {
if (switch_true(val)) {
sofia_set_pflag(profile, PFLAG_SECURE);
@ -5545,6 +5579,44 @@ const char *sofia_gateway_status_name(sofia_gateway_status_t status)
}
}
const char *sofia_sip_user_status_name(sofia_sip_user_status_t status)
{
static const char *status_names[] = { "UNREACHABLE", "REACHABLE", NULL };
if (status < SOFIA_REG_INVALID) {
return status_names[status];
} else {
return "INVALID";
}
}
struct cb_helper_sip_user_status {
char *status;
size_t status_len;
char *contact;
size_t contact_len;
int count;
};
int sofia_sip_user_status_callback(void *pArg, int argc, char **argv, char **columnNames)
{
struct cb_helper_sip_user_status *cbt = (struct cb_helper_sip_user_status *) pArg;
if (argc != 3) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "expected 3 arguments from query, instead got %d\n", argc);
return 0;
}
switch_copy_string(cbt->status, argv[0], cbt->status_len);
cbt->count = (argv[1] && switch_is_number(argv[1])) ? atoi(argv[1]) : 0;
switch_copy_string(cbt->contact, argv[2], cbt->contact_len);
return 1;
}
static void sofia_handle_sip_r_options(switch_core_session_t *session, int status,
char const *phrase,
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
@ -5608,18 +5680,85 @@ static void sofia_handle_sip_r_options(switch_core_session_t *session, int statu
gateway->ping = switch_epoch_time_now(NULL) + gateway->ping_freq;
sofia_reg_release_gateway(gateway);
gateway->pinging = 0;
} else if (sofia_test_pflag(profile, PFLAG_UNREG_OPTIONS_FAIL) && (status != 200 && status != 486) &&
sip && sip->sip_to && sip->sip_call_id && sip->sip_call_id->i_id && strchr(sip->sip_call_id->i_id, '_')) {
char *sql;
time_t now = switch_epoch_time_now(NULL);
} else if (sip && sip->sip_to && sip->sip_call_id && sip->sip_call_id->i_id && strchr(sip->sip_call_id->i_id, '_')) {
const char *call_id = strchr(sip->sip_call_id->i_id, '_') + 1;
char *sql;
struct cb_helper_sip_user_status sip_user_status;
char ping_status[255] = "";
char sip_contact[1024] = "";
int sip_user_ping_min = profile->sip_user_ping_min;
int sip_user_ping_max = profile->sip_user_ping_max;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Expire registration '%s@%s' due to options failure\n",
sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host);
char *sip_user = switch_mprintf("%s@%s", sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host);
sip_user_status.status = ping_status;
sip_user_status.status_len = sizeof(ping_status);
sip_user_status.contact = sip_contact;
sip_user_status.contact_len = sizeof(sip_contact);
sql = switch_mprintf("select ping_status, ping_count, contact from sip_registrations where sip_user='%s' and sip_host='%s' and call_id='%q'",
sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_sip_user_status_callback, &sip_user_status);
switch_safe_free(sql);
if (status != 200 && status != 486) {
sip_user_status.count--;
if (sip_user_status.count >= 0) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Ping to sip user '%s@%s' failed with code %d - count %d, state %s\n",
sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, status, sip_user_status.count, sip_user_status.status);
sql = switch_mprintf("update sip_registrations set ping_count=%d where sip_user='%s' and sip_host='%s' and call_id='%q'", sip_user_status.count,
sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
switch_safe_free(sql);
}
if (sip_user_status.count < sip_user_ping_min) {
if (strcmp(sip_user_status.status, "Unreachable")) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Sip user '%s@%s' is now Unreachable\n",
sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host);
sql = switch_mprintf("update sip_registrations set ping_status='Unreachable' where sip_user='%s' and sip_host='%s' and call_id='%q'",
sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
switch_safe_free(sql);
sofia_reg_fire_custom_sip_user_state_event(profile, sip_user, sip_user_status.contact, sip->sip_to->a_url->url_user,
sip->sip_to->a_url->url_host, call_id, SOFIA_REG_REACHABLE, status, phrase);
if (sofia_test_pflag(profile, PFLAG_UNREG_OPTIONS_FAIL)) {
time_t now = switch_epoch_time_now(NULL);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Expire sip user '%s@%s' due to options failure\n",
sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host);
sql = switch_mprintf("update sip_registrations set expires=%ld where sip_user='%s' and sip_host='%s' and call_id='%q'",
(long) now, sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
switch_safe_free(sql);
}
}
}
} else {
sip_user_status.count++;
if (sip_user_status.count <= sip_user_ping_max) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Ping to sip user '%s@%s' succeeded with code %d - count %d, state %s\n",
sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, status, sip_user_status.count, sip_user_status.status);
sql = switch_mprintf("update sip_registrations set ping_count=%d where sip_user='%s' and sip_host='%s' and call_id='%q'", sip_user_status.count,
sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
switch_safe_free(sql);
}
if (sip_user_status.count >= sip_user_ping_min) {
if (strcmp(sip_user_status.status, "Reachable")) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Sip user '%s@%s' is now Reachable\n",
sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host);
sql = switch_mprintf("update sip_registrations set ping_status='Reachable' where sip_user='%s' and sip_host='%s' and call_id='%q'",
sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
switch_safe_free(sql);
sofia_reg_fire_custom_sip_user_state_event(profile, sip_user, sip_user_status.contact, sip->sip_to->a_url->url_user,
sip->sip_to->a_url->url_host, call_id, SOFIA_REG_UNREACHABLE, status, phrase);
}
}
}
switch_safe_free(sip_user);
sql = switch_mprintf("update sip_registrations set expires=%ld where sip_user='%s' and sip_host='%s' and call_id='%q'",
(long) now, sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
}
}

View File

@ -1984,6 +1984,8 @@ int sofia_glue_init_sql(sofia_profile_t *profile)
" presence_hosts VARCHAR(255),\n"
" contact VARCHAR(1024),\n"
" status VARCHAR(255),\n"
" ping_status VARCHAR(255),\n"
" ping_count INTEGER,\n"
" rpid VARCHAR(255),\n"
" expires BIGINT,\n"
" user_agent VARCHAR(255),\n"
@ -2116,6 +2118,7 @@ int sofia_glue_init_sql(sofia_profile_t *profile)
"create index sr_expires on sip_registrations (expires)",
"create index sr_hostname on sip_registrations (hostname)",
"create index sr_status on sip_registrations (status)",
"create index sr_ping_status on sip_registrations (ping_status)",
"create index sr_network_ip on sip_registrations (network_ip)",
"create index sr_network_port on sip_registrations (network_port)",
"create index sr_sip_username on sip_registrations (sip_username)",
@ -2194,6 +2197,9 @@ int sofia_glue_init_sql(sofia_profile_t *profile)
switch_cache_db_test_reactive(dbh, test_sql, "drop table sip_registrations", reg_sql);
switch_cache_db_test_reactive(dbh, "select ping_count from sip_registrations", NULL, "alter table sip_registrations add column ping_count INTEGER default 0");
switch_cache_db_test_reactive(dbh, "select ping_status from sip_registrations", NULL, "alter table sip_registrations add column ping_status VARCHAR(255) default \"Reachable\"");
test2 = switch_mprintf("%s;%s", test_sql, test_sql);

View File

@ -161,6 +161,26 @@ void sofia_reg_fire_custom_gateway_state_event(sofia_gateway_t *gateway, int sta
}
}
void sofia_reg_fire_custom_sip_user_state_event(sofia_profile_t *profile, const char *sip_user, const char *contact,
const char* from_user, const char* from_host, const char *call_id, sofia_sip_user_status_t status, int options_res, const char *phrase)
{
switch_event_t *s_event;
if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_SIP_USER_STATE) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "sip_contact", contact);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile-name", profile->name);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "sip_user", sip_user);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-user", from_user);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-host", from_host);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "call-id", call_id);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "Ping-Status", sofia_sip_user_status_name(status));
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "Status", "%d", options_res);
if (!zstr(phrase)) {
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "Phrase", phrase);
}
switch_event_fire(&s_event);
}
}
void sofia_reg_unregister(sofia_profile_t *profile)
{
sofia_gateway_t *gateway_ptr;
@ -830,7 +850,7 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot)
sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,rpid,"
"expires,user_agent,server_user,server_host,profile_name"
" from sip_registrations where hostname='%s' and "
"profile_name='%s'", mod_sofia_globals.hostname, profile->name);
"profile_name='%s' and orig_hostname='%s'", mod_sofia_globals.hostname, profile->name, mod_sofia_globals.hostname);
sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_reg_nat_callback, profile);
switch_safe_free(sql);
@ -847,7 +867,7 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot)
"expires,user_agent,server_user,server_host,profile_name"
" from sip_registrations where (status like '%%NAT%%' "
"or contact like '%%fs_nat=yes%%') and hostname='%s' "
"and profile_name='%s'", mod_sofia_globals.hostname, profile->name);
"and profile_name='%s' and orig_hostname='%s'", mod_sofia_globals.hostname, profile->name, mod_sofia_globals.hostname);
sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_reg_nat_callback, profile);
switch_safe_free(sql);
@ -1805,12 +1825,12 @@ uint8_t sofia_reg_handle_register_token(nua_t *nua, sofia_profile_t *profile, nu
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,"
"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')",
"mwi_user,mwi_host, orig_server_host, orig_hostname, sub_host, ping_status, ping_count) "
"values ('%q','%q', '%q','%q','%q','%q', '%q', %ld, '%q', '%q', '%q', '%q', '%q', '%q', '%q','%q','%q','%q','%q','%q','%q','%q', '%q', %d)",
call_id, to_user, reg_host, profile->presence_hosts ? profile->presence_hosts : "",
contact_str, reg_desc, rpid, (long) reg_time + (long) exptime + profile->sip_expires_late_margin,
agent, from_user, guess_ip4, profile->name, mod_sofia_globals.hostname, network_ip, network_port_c, username, realm,
mwi_user, mwi_host, guess_ip4, mod_sofia_globals.hostname, sub_host);
mwi_user, mwi_host, guess_ip4, mod_sofia_globals.hostname, sub_host, "Reachable", 0);
} else {
sql = switch_mprintf("update sip_registrations set call_id='%q',"
"sub_host='%q', network_ip='%q',network_port='%q',"