solve problem from MODENDP-258 with an alternate approach, and make send-message-query-on-register=first-only and sql-in-transactions=true the defaults

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@15441 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2009-11-12 03:52:07 +00:00
parent 054d40a7e1
commit 397ef741c1
7 changed files with 307 additions and 173 deletions

View File

@ -2042,7 +2042,7 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t
profile->name);
}
sofia_glue_execute_sql_callback(profile, SWITCH_FALSE, profile->ireg_mutex, sql, show_reg_callback, &cb);
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, show_reg_callback, &cb);
switch_safe_free(sql);
stream->write_function(stream, "%s\n", line);
@ -2263,7 +2263,7 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl
profile->name);
}
sofia_glue_execute_sql_callback(profile, SWITCH_FALSE, profile->ireg_mutex, sql, show_reg_callback_xml, &cb);
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, show_reg_callback_xml, &cb);
switch_safe_free(sql);
stream->write_function(stream, " </registrations>\n");
@ -2653,7 +2653,7 @@ SWITCH_STANDARD_API(sofia_contact_function)
}
switch_assert(sql);
sofia_glue_execute_sql_callback(profile, SWITCH_FALSE, profile->ireg_mutex, sql, contact_callback, &cb);
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, contact_callback, &cb);
switch_safe_free(sql);
reply = (char *) mystream.data;
if (!zstr(reply) && end_of(reply) == ',') {
@ -3365,7 +3365,7 @@ static void general_event_handler(switch_event_t *event)
switch_mutex_lock(profile->ireg_mutex);
sofia_glue_execute_sql_callback(profile, SWITCH_TRUE, NULL, sql, notify_callback, profile);
sofia_glue_execute_sql_callback(profile, NULL, sql, notify_callback, profile);
switch_mutex_unlock(profile->ireg_mutex);
sofia_glue_release_profile(profile);

View File

@ -475,7 +475,8 @@ struct sofia_profile {
sofia_gateway_t *gateways;
su_home_t *home;
switch_hash_t *chat_hash;
switch_core_db_t *master_db;
switch_hash_t *db_hash;
//switch_core_db_t *master_db;
switch_thread_rwlock_t *rwlock;
switch_mutex_t *flag_mutex;
uint32_t inuse;
@ -670,6 +671,11 @@ typedef struct {
char *route_uri;
} sofia_destination_t;
typedef struct {
switch_core_db_t *db;
time_t last_used;
} sofia_cache_db_handle_t;
#define sofia_test_pflag(obj, flag) ((obj)->pflags[flag] ? 1 : 0)
#define sofia_set_pflag(obj, flag) (obj)->pflags[flag] = 1
#define sofia_set_pflag_locked(obj, flag) assert(obj->flag_mutex != NULL);\
@ -747,7 +753,7 @@ switch_status_t config_sofia(int reload, char *profile_name);
void sofia_reg_auth_challenge(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_regtype_t regtype, const char *realm, int stale);
auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, sip_authorization_t const *authorization,
sip_t const *sip, const char *regstr, 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 exptime, sofia_regtype_t regtype, const char *to_user, switch_event_t **auth_params, long *reg_count);
void sofia_reg_handle_sip_r_challenge(int status,
@ -773,7 +779,7 @@ void sofia_presence_handle_sip_i_subscribe(int status,
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]);
void sofia_glue_execute_sql(sofia_profile_t *profile, char **sqlp, switch_bool_t sql_already_dynamic);
void sofia_glue_actually_execute_sql(sofia_profile_t *profile, switch_bool_t master, char *sql, switch_mutex_t *mutex);
void sofia_glue_actually_execute_sql(sofia_profile_t *profile, char *sql, switch_mutex_t *mutex);
void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot);
void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now);
void sofia_sub_check_gateway(sofia_profile_t *profile, time_t now);
@ -795,7 +801,6 @@ void sofia_glue_sql_close(sofia_profile_t *profile);
int sofia_glue_init_sql(sofia_profile_t *profile);
char *sofia_overcome_sip_uri_weakness(switch_core_session_t *session, const char *uri, const sofia_transport_t transport, switch_bool_t uri_only, const char *params);
switch_bool_t sofia_glue_execute_sql_callback(sofia_profile_t *profile,
switch_bool_t master,
switch_mutex_t *mutex,
char *sql,
switch_core_db_callback_func_t callback,
@ -925,3 +930,4 @@ void sofia_glue_set_extra_headers(switch_channel_t *channel, sip_t const *sip, c
void sofia_info_send_sipfrag(switch_core_session_t *aleg, switch_core_session_t *bleg);
void sofia_update_callee_id(switch_core_session_t *session, sofia_profile_t *profile, sip_t const *sip, switch_bool_t send);
void sofia_send_callee_id(switch_core_session_t *session, const char *name, const char *number);
int sofia_sla_supported(sip_t const *sip);

View File

@ -591,7 +591,7 @@ void sofia_event_callback(nua_event_t event,
sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), NULL);
auth_res = sofia_reg_parse_auth(profile, authorization, sip,
(char *) sip->sip_request->rq_method_name, tech_pvt->key, strlen(tech_pvt->key), network_ip, NULL, 0,
REG_INVITE, NULL, NULL);
REG_INVITE, NULL, NULL, NULL);
}
if (auth_res != AUTH_OK) {
@ -943,7 +943,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_worker_thread_run(switch_thread_t *thread
sprintf(sqlbuf + len, "commit;\n");
//printf("TRANS:\n%s\n", sqlbuf);
sofia_glue_actually_execute_sql(profile, SWITCH_TRUE, sqlbuf, NULL);
sofia_glue_actually_execute_sql(profile, sqlbuf, NULL);
switch_mutex_unlock(profile->ireg_mutex);
loop_count = 0;
}
@ -951,7 +951,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_worker_thread_run(switch_thread_t *thread
if (qsize) {
switch_mutex_lock(profile->ireg_mutex);
while (switch_queue_trypop(profile->sql_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) {
sofia_glue_actually_execute_sql(profile, SWITCH_TRUE, (char *) pop, NULL);
sofia_glue_actually_execute_sql(profile, (char *) pop, NULL);
free(pop);
}
switch_mutex_unlock(profile->ireg_mutex);
@ -978,7 +978,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_worker_thread_run(switch_thread_t *thread
switch_mutex_lock(profile->ireg_mutex);
while (switch_queue_trypop(profile->sql_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) {
sofia_glue_actually_execute_sql(profile, SWITCH_TRUE, (char *) pop, NULL);
sofia_glue_actually_execute_sql(profile, (char *) pop, NULL);
free(pop);
}
switch_mutex_unlock(profile->ireg_mutex);
@ -1098,6 +1098,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void
NUTAG_APPL_METHOD("NOTIFY"),
NUTAG_APPL_METHOD("INFO"),
NUTAG_APPL_METHOD("ACK"),
NUTAG_APPL_METHOD("SUBSCRIBE"),
#ifdef MANUAL_BYE
NUTAG_APPL_METHOD("BYE"),
#endif
@ -1267,6 +1268,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void
sofia_glue_del_profile(profile);
switch_core_hash_destroy(&profile->chat_hash);
switch_core_hash_destroy(&profile->db_hash);
switch_thread_rwlock_unlock(profile->rwlock);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write unlock %s\n", profile->name);
@ -1864,6 +1866,7 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile)
if (switch_true(val)) {
sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER);
} else if (!strcasecmp(val, "first-only")) {
sofia_clear_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER);
sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER);
} else {
sofia_clear_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER);
@ -2387,6 +2390,7 @@ switch_status_t config_sofia(int reload, char *profile_name)
profile->dbname = switch_core_strdup(profile->pool, url);
switch_core_hash_init(&profile->chat_hash, profile->pool);
switch_core_hash_init(&profile->db_hash, profile->pool);
switch_thread_rwlock_create(&profile->rwlock, profile->pool);
switch_mutex_init(&profile->flag_mutex, SWITCH_MUTEX_NESTED, profile->pool);
profile->dtmf_duration = 100;
@ -2397,10 +2401,11 @@ switch_status_t config_sofia(int reload, char *profile_name)
sofia_set_pflag(profile, PFLAG_DISABLE_100REL);
profile->auto_restart = 1;
sofia_set_pflag(profile, PFLAG_AUTOFIX_TIMING);
sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER);
sofia_set_pflag(profile, PFLAG_RTP_AUTOFLUSH_DURING_BRIDGE);
profile->contact_user = SOFIA_DEFAULT_CONTACT_USER;
sofia_set_pflag(profile, PFLAG_PASS_CALLEE_ID);
sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER);
sofia_set_pflag(profile, PFLAG_SQL_IN_TRANS);
for (param = switch_xml_child(settings, "param"); param; param = param->next) {
char *var = (char *) switch_xml_attr_soft(param, "name");
@ -2479,6 +2484,7 @@ switch_status_t config_sofia(int reload, char *profile_name)
if (switch_true(val)) {
sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER);
} else if (!strcasecmp(val, "first-only")) {
sofia_clear_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER);
sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER);
} else {
sofia_clear_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER);
@ -2653,6 +2659,7 @@ switch_status_t config_sofia(int reload, char *profile_name)
} else if (!strcasecmp(var, "manage-shared-appearance")) {
if (switch_true(val)) {
sofia_set_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE);
profile->pres_type = PRES_TYPE_FULL;
profile->sla_contact = switch_core_sprintf(profile->pool, "sla-agent");
}
} else if (!strcasecmp(var, "disable-srv")) {

View File

@ -3609,6 +3609,7 @@ void sofia_glue_del_profile(sofia_profile_t *profile)
int sofia_glue_init_sql(sofia_profile_t *profile)
{
char *test_sql = NULL;
switch_core_db_t *db = NULL;
char reg_sql[] =
"CREATE TABLE sip_registrations (\n"
@ -3780,7 +3781,8 @@ int sofia_glue_init_sql(sofia_profile_t *profile)
test_sql = switch_mprintf("delete from sip_registrations where (contact like '%%TCP%%' "
"or status like '%%TCP%%' or status like '%%TLS%%') and hostname='%q' "
"and network_ip!='-1' and network_port!='-1' and sip_username != '-1' and mwi_user != '-1' and mwi_host != '-1'",
"and network_ip like '%%' and network_port like '%%' and sip_username "
"like '%%' and mwi_user like '%%' and mwi_host like '%%'",
mod_sofia_globals.hostname);
if (switch_odbc_handle_exec(profile->master_odbc, test_sql, NULL) != SWITCH_ODBC_SUCCESS) {
@ -3790,7 +3792,8 @@ int sofia_glue_init_sql(sofia_profile_t *profile)
free(test_sql);
test_sql = switch_mprintf("delete from sip_subscriptions where hostname='%q' and network_ip!='-1' and network_port!='-1'", mod_sofia_globals.hostname);
test_sql = switch_mprintf("delete from sip_subscriptions where hostname='%q' and network_ip like '%%' and network_port like '%%'",
mod_sofia_globals.hostname);
if (switch_odbc_handle_exec(profile->master_odbc, test_sql, NULL) != SWITCH_ODBC_SUCCESS) {
switch_odbc_handle_exec(profile->master_odbc, "DROP TABLE sip_subscriptions", NULL);
@ -3813,7 +3816,7 @@ int sofia_glue_init_sql(sofia_profile_t *profile)
}
free(test_sql);
test_sql = switch_mprintf("delete from sip_authentication where hostname='%q' and last_nc >= 0", mod_sofia_globals.hostname);
test_sql = switch_mprintf("delete from sip_authentication where hostname='%q' or last_nc >= 0", mod_sofia_globals.hostname);
if (switch_odbc_handle_exec(profile->master_odbc, test_sql, NULL) != SWITCH_ODBC_SUCCESS) {
switch_odbc_handle_exec(profile->master_odbc, "DROP TABLE sip_authentication", NULL);
@ -3821,7 +3824,7 @@ int sofia_glue_init_sql(sofia_profile_t *profile)
}
free(test_sql);
test_sql = switch_mprintf("delete from sip_shared_appearance_subscriptions where contact_str='' or hostname='%q' and network_ip!='-1'",
test_sql = switch_mprintf("delete from sip_shared_appearance_subscriptions where contact_str='' or hostname='%q' and network_ip like '%%'",
mod_sofia_globals.hostname);
if (switch_odbc_handle_exec(profile->master_odbc, test_sql, NULL) != SWITCH_ODBC_SUCCESS) {
switch_odbc_handle_exec(profile->master_odbc, "DROP TABLE sip_shared_appearance_subscriptions", NULL);
@ -3830,7 +3833,7 @@ int sofia_glue_init_sql(sofia_profile_t *profile)
free(test_sql);
test_sql = switch_mprintf("delete from sip_shared_appearance_dialogs where contact_str='' or hostname='%q' and network_ip!='-1'",
test_sql = switch_mprintf("delete from sip_shared_appearance_dialogs where contact_str='' or hostname='%q' and network_ip like '%%'",
mod_sofia_globals.hostname);
if (switch_odbc_handle_exec(profile->master_odbc, test_sql, NULL) != SWITCH_ODBC_SUCCESS) {
switch_odbc_handle_exec(profile->master_odbc, "DROP TABLE sip_shared_appearance_dialogs", NULL);
@ -3847,111 +3850,119 @@ int sofia_glue_init_sql(sofia_profile_t *profile)
} else if (profile->odbc_dsn) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC IS NOT AVAILABLE!\n");
} else {
if (!(profile->master_db = switch_core_db_open_file(profile->dbname))) {
if (!(db = switch_core_db_open_file(profile->dbname))) {
return 0;
}
test_sql = switch_mprintf("delete from sip_registrations where (contact like '%%TCP%%' "
"or status like '%%TCP%%' or status like '%%TLS%%') and hostname='%q' "
"and network_ip!='-1' and network_port!='-1' and sip_username != '-1' and mwi_user != '-1' and mwi_host != '-1'",
"and network_ip like '%%' and network_port like '%%' and sip_username "
"like '%%' and mwi_user like '%%' and mwi_host like '%%'",
mod_sofia_globals.hostname);
switch_core_db_test_reactive(profile->master_db, test_sql, "DROP TABLE sip_registrations", reg_sql);
switch_core_db_test_reactive(db, test_sql, "DROP TABLE sip_registrations", reg_sql);
free(test_sql);
test_sql = switch_mprintf("delete from sip_subscriptions where hostname='%q' and network_ip!='-1' and network_port!='-1'", mod_sofia_globals.hostname);
switch_core_db_test_reactive(profile->master_db, test_sql, "DROP TABLE sip_subscriptions", sub_sql);
test_sql = switch_mprintf("delete from sip_subscriptions where hostname='%q' and network_ip like '%%' or network_port like '%%'",
mod_sofia_globals.hostname);
switch_core_db_test_reactive(db, test_sql, "DROP TABLE sip_subscriptions", sub_sql);
free(test_sql);
test_sql = switch_mprintf("delete from sip_dialogs where hostname='%q' and contact like '%%'", mod_sofia_globals.hostname);
switch_core_db_test_reactive(profile->master_db, test_sql, "DROP TABLE sip_dialogs", dialog_sql);
switch_core_db_test_reactive(db, test_sql, "DROP TABLE sip_dialogs", dialog_sql);
free(test_sql);
test_sql = switch_mprintf("delete from sip_presence where hostname='%q'", mod_sofia_globals.hostname);
switch_core_db_test_reactive(profile->master_db, test_sql, "DROP TABLE sip_presence", pres_sql);
switch_core_db_test_reactive(db, test_sql, "DROP TABLE sip_presence", pres_sql);
free(test_sql);
test_sql = switch_mprintf("delete from sip_authentication where hostname='%q' and last_nc >= 0", mod_sofia_globals.hostname);
switch_core_db_test_reactive(profile->master_db, test_sql, "DROP TABLE sip_authentication", auth_sql);
test_sql = switch_mprintf("delete from sip_authentication where hostname='%q' or last_nc >= 0", mod_sofia_globals.hostname);
switch_core_db_test_reactive(db, test_sql, "DROP TABLE sip_authentication", auth_sql);
free(test_sql);
test_sql = switch_mprintf("delete from sip_shared_appearance_subscriptions where contact_str = '' or hostname='%q' and network_ip!='-1'",
test_sql = switch_mprintf("delete from sip_shared_appearance_subscriptions where contact_str = '' or hostname='%q' and network_ip like '%%'",
mod_sofia_globals.hostname);
switch_core_db_test_reactive(profile->master_db, test_sql, "DROP TABLE sip_shared_appearance_subscriptions", shared_appearance_sql);
switch_core_db_test_reactive(db, test_sql, "DROP TABLE sip_shared_appearance_subscriptions", shared_appearance_sql);
free(test_sql);
test_sql = switch_mprintf("delete from sip_shared_appearance_dialogs where contact_str = '' or hostname='%q'", mod_sofia_globals.hostname);
switch_core_db_test_reactive(profile->master_db, test_sql, "DROP TABLE sip_shared_appearance_dialogs", shared_appearance_dialogs_sql);
switch_core_db_test_reactive(db, test_sql, "DROP TABLE sip_shared_appearance_dialogs", shared_appearance_dialogs_sql);
free(test_sql);
switch_core_db_exec(profile->master_db, "create index if not exists ssa_hostname on sip_shared_appearance_subscriptions (hostname)",
switch_core_db_exec(db, "create index if not exists ssa_hostname on sip_shared_appearance_subscriptions (hostname)",
NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists ssa_subscriber on sip_shared_appearance_subscriptions (subscriber)",
switch_core_db_exec(db, "create index if not exists ssa_subscriber on sip_shared_appearance_subscriptions (subscriber)",
NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists ssa_profile_name on sip_shared_appearance_subscriptions (profile_name)",
switch_core_db_exec(db, "create index if not exists ssa_profile_name on sip_shared_appearance_subscriptions (profile_name)",
NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists ssa_aor on sip_shared_appearance_subscriptions (aor)", NULL, NULL, NULL);
switch_core_db_exec(db, "create index if not exists ssa_aor on sip_shared_appearance_subscriptions (aor)", NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists ssd_profile_name on sip_shared_appearance_dialogs (profile_name)",
switch_core_db_exec(db, "create index if not exists ssd_profile_name on sip_shared_appearance_dialogs (profile_name)",
NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists ssd_hostname on sip_shared_appearance_dialogs (hostname)",
switch_core_db_exec(db, "create index if not exists ssd_hostname on sip_shared_appearance_dialogs (hostname)",
NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists ssd_hostname on sip_shared_appearance_dialogs (network_ip)",
switch_core_db_exec(db, "create index if not exists ssd_hostname on sip_shared_appearance_dialogs (network_ip)",
NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists ssd_contact_str on sip_shared_appearance_dialogs (contact_str)",
switch_core_db_exec(db, "create index if not exists ssd_contact_str on sip_shared_appearance_dialogs (contact_str)",
NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists ssd_call_id on sip_shared_appearance_dialogs (call_id)",
switch_core_db_exec(db, "create index if not exists ssd_call_id on sip_shared_appearance_dialogs (call_id)",
NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists ssd_expires on sip_shared_appearance_dialogs (expires)",
switch_core_db_exec(db, "create index if not exists ssd_expires on sip_shared_appearance_dialogs (expires)",
NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists sr_call_id on sip_registrations (call_id)", NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists sr_sip_user on sip_registrations (sip_user)", NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists sr_sip_host on sip_registrations (sip_host)", NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists sr_profile_name on sip_registrations (profile_name)", NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists sr_presence_hosts on sip_registrations (presence_hosts)", NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists sr_contact on sip_registrations (contact)", NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists sr_expires on sip_registrations (expires)", NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists sr_hostname on sip_registrations (hostname)", NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists sr_status on sip_registrations (status)", NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists sr_network_ip on sip_registrations (network_ip)", NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists sr_network_port on sip_registrations (network_port)", NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists sr_sip_username on sip_registrations (sip_username)", NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists sr_sip_realm on sip_registrations (sip_realm)", NULL, NULL, NULL);
switch_core_db_exec(db, "create index if not exists sr_call_id on sip_registrations (call_id)", NULL, NULL, NULL);
switch_core_db_exec(db, "create index if not exists sr_sip_user on sip_registrations (sip_user)", NULL, NULL, NULL);
switch_core_db_exec(db, "create index if not exists sr_sip_host on sip_registrations (sip_host)", NULL, NULL, NULL);
switch_core_db_exec(db, "create index if not exists sr_profile_name on sip_registrations (profile_name)", NULL, NULL, NULL);
switch_core_db_exec(db, "create index if not exists sr_presence_hosts on sip_registrations (presence_hosts)", NULL, NULL, NULL);
switch_core_db_exec(db, "create index if not exists sr_contact on sip_registrations (contact)", NULL, NULL, NULL);
switch_core_db_exec(db, "create index if not exists sr_expires on sip_registrations (expires)", NULL, NULL, NULL);
switch_core_db_exec(db, "create index if not exists sr_hostname on sip_registrations (hostname)", NULL, NULL, NULL);
switch_core_db_exec(db, "create index if not exists sr_status on sip_registrations (status)", NULL, NULL, NULL);
switch_core_db_exec(db, "create index if not exists sr_network_ip on sip_registrations (network_ip)", NULL, NULL, NULL);
switch_core_db_exec(db, "create index if not exists sr_network_port on sip_registrations (network_port)", NULL, NULL, NULL);
switch_core_db_exec(db, "create index if not exists sr_sip_username on sip_registrations (sip_username)", NULL, NULL, NULL);
switch_core_db_exec(db, "create index if not exists sr_sip_realm on sip_registrations (sip_realm)", NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists ss_call_id on sip_subscriptions (call_id)", NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists ss_hostname on sip_subscriptions (hostname)", NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists ss_hostname on sip_subscriptions (network_ip)", NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists ss_sip_user on sip_subscriptions (sip_user)", NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists ss_sip_host on sip_subscriptions (sip_host)", NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists ss_presence_hosts on sip_subscriptions (presence_hosts)", NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists ss_event on sip_subscriptions (event)", NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists ss_proto on sip_subscriptions (proto)", NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists ss_sub_to_user on sip_subscriptions (sub_to_user)", NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists ss_sub_to_host on sip_subscriptions (sub_to_host)", NULL, NULL, NULL);
switch_core_db_exec(db, "create index if not exists ss_call_id on sip_subscriptions (call_id)", NULL, NULL, NULL);
switch_core_db_exec(db, "create index if not exists ss_hostname on sip_subscriptions (hostname)", NULL, NULL, NULL);
switch_core_db_exec(db, "create index if not exists ss_hostname on sip_subscriptions (network_ip)", NULL, NULL, NULL);
switch_core_db_exec(db, "create index if not exists ss_sip_user on sip_subscriptions (sip_user)", NULL, NULL, NULL);
switch_core_db_exec(db, "create index if not exists ss_sip_host on sip_subscriptions (sip_host)", NULL, NULL, NULL);
switch_core_db_exec(db, "create index if not exists ss_presence_hosts on sip_subscriptions (presence_hosts)", NULL, NULL, NULL);
switch_core_db_exec(db, "create index if not exists ss_event on sip_subscriptions (event)", NULL, NULL, NULL);
switch_core_db_exec(db, "create index if not exists ss_proto on sip_subscriptions (proto)", NULL, NULL, NULL);
switch_core_db_exec(db, "create index if not exists ss_sub_to_user on sip_subscriptions (sub_to_user)", NULL, NULL, NULL);
switch_core_db_exec(db, "create index if not exists ss_sub_to_host on sip_subscriptions (sub_to_host)", NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists sd_uuid on sip_dialogs (uuid)", NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists sd_hostname on sip_dialogs (hostname)", NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists sd_hostname on sip_dialogs (contact)", NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists sd_hostname on sip_dialogs (presence_id)", NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists sd_hostname on sip_dialogs (presence_data)", NULL, NULL, NULL);
switch_core_db_exec(db, "create index if not exists sd_uuid on sip_dialogs (uuid)", NULL, NULL, NULL);
switch_core_db_exec(db, "create index if not exists sd_hostname on sip_dialogs (hostname)", NULL, NULL, NULL);
switch_core_db_exec(db, "create index if not exists sd_hostname on sip_dialogs (contact)", NULL, NULL, NULL);
switch_core_db_exec(db, "create index if not exists sd_hostname on sip_dialogs (presence_id)", NULL, NULL, NULL);
switch_core_db_exec(db, "create index if not exists sd_hostname on sip_dialogs (presence_data)", NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists sp_hostname on sip_presence (hostname)", NULL, NULL, NULL);
switch_core_db_exec(db, "create index if not exists sp_hostname on sip_presence (hostname)", NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists sa_nonce on sip_authentication (nonce)", NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists sa_hostname on sip_authentication (hostname)", NULL, NULL, NULL);
switch_core_db_exec(db, "create index if not exists sa_nonce on sip_authentication (nonce)", NULL, NULL, NULL);
switch_core_db_exec(db, "create index if not exists sa_hostname on sip_authentication (hostname)", NULL, NULL, NULL);
}
if (switch_odbc_available() && profile->odbc_dsn) {
return profile->master_odbc ? 1 : 0;
}
if (db) {
switch_core_db_close(db);
return 1;
} else {
return 0;
}
return profile->master_db ? 1 : 0;
}
void sofia_glue_sql_close(sofia_profile_t *profile)
@ -3959,8 +3970,25 @@ void sofia_glue_sql_close(sofia_profile_t *profile)
if (switch_odbc_available() && profile->master_odbc) {
switch_odbc_handle_destroy(&profile->master_odbc);
} else {
switch_core_db_close(profile->master_db);
profile->master_db = NULL;
switch_hash_index_t *hi;
const void *var;
void *val;
sofia_cache_db_handle_t *dbh = NULL;
switch_mutex_lock(profile->ireg_mutex);
top:
for (hi = switch_hash_first(NULL, profile->db_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, &var, NULL, &val);
if ((dbh = (sofia_cache_db_handle_t *) val)) {
switch_core_db_close(dbh->db);
dbh->db = NULL;
switch_core_hash_delete(profile->db_hash, (char *)var);
goto top;
}
}
switch_mutex_unlock(profile->ireg_mutex);
}
}
@ -3988,7 +4016,7 @@ void sofia_glue_execute_sql(sofia_profile_t *profile, char **sqlp, switch_bool_t
}
if (status != SWITCH_STATUS_SUCCESS) {
sofia_glue_actually_execute_sql(profile, SWITCH_FALSE, sql, profile->ireg_mutex);
sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex);
}
switch_safe_free(d_sql);
@ -3998,7 +4026,33 @@ void sofia_glue_execute_sql(sofia_profile_t *profile, char **sqlp, switch_bool_t
}
}
void sofia_glue_actually_execute_sql(sofia_profile_t *profile, switch_bool_t master, char *sql, switch_mutex_t *mutex)
switch_core_db_t *sofia_glue_get_db_handle(sofia_profile_t *profile)
{
switch_thread_id_t self = switch_thread_self();
char thread_str[256] = "";
switch_core_db_t *db = NULL;
sofia_cache_db_handle_t *dbh = NULL;
snprintf(thread_str, sizeof(thread_str) - 1, "%lu", (unsigned long)(intptr_t)self);
switch_mutex_lock(profile->ireg_mutex);
if ((dbh = switch_core_hash_find(profile->db_hash, thread_str))) {
db = dbh->db;
} else {
dbh = switch_core_alloc(profile->pool, sizeof(*dbh));
dbh->db = switch_core_db_open_file(profile->dbname);
dbh->last_used = switch_epoch_time_now(NULL);
switch_core_hash_insert(profile->db_hash, thread_str, dbh);
db = dbh->db;
}
switch_mutex_unlock(profile->ireg_mutex);
return db;
}
void sofia_glue_actually_execute_sql(sofia_profile_t *profile, char *sql, switch_mutex_t *mutex)
{
switch_core_db_t *db;
@ -4022,24 +4076,18 @@ void sofia_glue_actually_execute_sql(sofia_profile_t *profile, switch_bool_t mas
} else {
char *errmsg;
if (master) {
db = profile->master_db;
} else {
if (!(db = switch_core_db_open_file(profile->dbname))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB %s\n", profile->dbname);
goto end;
}
if (!(db = sofia_glue_get_db_handle(profile))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB %s\n", profile->dbname);
goto end;
}
switch_core_db_exec(db, sql, NULL, NULL, &errmsg);
if (errmsg) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR [%s]\n%s\n", errmsg, sql);
switch_core_db_free(errmsg);
}
if (!master) {
switch_core_db_close(db);
}
}
end:
@ -4049,7 +4097,7 @@ void sofia_glue_actually_execute_sql(sofia_profile_t *profile, switch_bool_t mas
}
switch_bool_t sofia_glue_execute_sql_callback(sofia_profile_t *profile,
switch_bool_t master, switch_mutex_t *mutex, char *sql, switch_core_db_callback_func_t callback, void *pdata)
switch_mutex_t *mutex, char *sql, switch_core_db_callback_func_t callback, void *pdata)
{
switch_bool_t ret = SWITCH_FALSE;
switch_core_db_t *db;
@ -4066,25 +4114,18 @@ switch_bool_t sofia_glue_execute_sql_callback(sofia_profile_t *profile,
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC IS NOT AVAILABLE!\n");
} else {
if (master) {
db = profile->master_db;
} else {
if (!(db = switch_core_db_open_file(profile->dbname))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB %s\n", profile->dbname);
goto end;
}
if (!(db = sofia_glue_get_db_handle(profile))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB %s\n", profile->dbname);
goto end;
}
switch_core_db_exec(db, sql, callback, pdata, &errmsg);
if (errmsg) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR: [%s] %s\n", sql, errmsg);
free(errmsg);
}
if (!master && db) {
switch_core_db_close(db);
}
}
end:

View File

@ -190,7 +190,7 @@ void sofia_presence_cancel(void)
}
helper.profile = profile;
helper.event = NULL;
if (sofia_glue_execute_sql_callback(profile, SWITCH_FALSE, profile->ireg_mutex, sql, sofia_presence_sub_callback, &helper) != SWITCH_TRUE) {
if (sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_sub_callback, &helper) != SWITCH_TRUE) {
continue;
}
}
@ -202,13 +202,13 @@ void sofia_presence_cancel(void)
void sofia_presence_establish_presence(sofia_profile_t *profile)
{
if (sofia_glue_execute_sql_callback(profile, SWITCH_FALSE, profile->ireg_mutex,
if (sofia_glue_execute_sql_callback(profile, profile->ireg_mutex,
"select sip_user,sip_host,'Registered','unknown','' from sip_registrations",
sofia_presence_resub_callback, profile) != SWITCH_TRUE) {
return;
}
if (sofia_glue_execute_sql_callback(profile, SWITCH_FALSE, profile->ireg_mutex,
if (sofia_glue_execute_sql_callback(profile, profile->ireg_mutex,
"select sub_to_user,sub_to_host,'Online','unknown',proto from sip_subscriptions "
"where proto='ext' or proto='user' or proto='conf'", sofia_presence_resub_callback, profile) != SWITCH_TRUE) {
return;
@ -337,7 +337,7 @@ static void actual_sofia_presence_mwi_event_handler(switch_event_t *event)
if (sql) {
sofia_glue_execute_sql_callback(profile, SWITCH_FALSE, profile->ireg_mutex, sql, sofia_presence_mwi_callback, &h);
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_mwi_callback, &h);
free(sql);
sql = NULL;
@ -355,7 +355,7 @@ static void actual_sofia_presence_mwi_event_handler(switch_event_t *event)
if (sql) {
switch_assert(sql != NULL);
sofia_glue_execute_sql_callback(profile, SWITCH_FALSE, profile->ireg_mutex, sql, sofia_presence_mwi_callback2, &h);
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_mwi_callback2, &h);
free(sql);
sql = NULL;
}
@ -456,7 +456,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
}
helper.profile = profile;
helper.event = NULL;
sofia_glue_execute_sql_callback(profile, SWITCH_FALSE, profile->ireg_mutex, sql, sofia_presence_sub_callback, &helper);
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_sub_callback, &helper);
}
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
free(sql);
@ -534,7 +534,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s DUMP PRESENCE_PROBE_SQL:\n%s\n", profile->name, sql);
}
sofia_glue_execute_sql_callback(profile, SWITCH_FALSE, profile->ireg_mutex, sql, sofia_presence_resub_callback, profile);
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_resub_callback, profile);
if (mod_sofia_globals.debug_presence > 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s END_PRESENCE_PROBE_SQL\n\n", profile->name);
}
@ -573,7 +573,6 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
}
continue;
}
if ((sql = switch_mprintf(
@ -615,7 +614,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
free(buf);
}
sofia_glue_execute_sql_callback(profile, SWITCH_FALSE,
sofia_glue_execute_sql_callback(profile,
NULL, sql, sofia_presence_sub_callback, &helper);
if (mod_sofia_globals.debug_presence > 0) {
@ -1764,7 +1763,7 @@ void sofia_presence_handle_sip_i_subscribe(int status,
"full_via,expires,user_agent,accept,profile_name,network_ip"
" from sip_subscriptions where sip_user='%q' and (sip_host='%q' or presence_hosts like '%%%q%%')",
to_host, to_user, to_host, to_host))) {
sofia_glue_execute_sql_callback(profile, SWITCH_FALSE, profile->ireg_mutex, sql, sofia_presence_sub_reg_callback, profile);
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_sub_reg_callback, profile);
switch_safe_free(sql);
}

View File

@ -521,7 +521,7 @@ void sofia_reg_expire_call_id(sofia_profile_t *profile, const char *call_id, int
switch_safe_free(sqlextra);
switch_mutex_lock(profile->ireg_mutex);
sofia_glue_execute_sql_callback(profile, SWITCH_TRUE, NULL, sql, sofia_reg_del_callback, profile);
sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_reg_del_callback, profile);
switch_mutex_unlock(profile->ireg_mutex);
switch_safe_free(sql);
@ -543,11 +543,6 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB %s\n", profile->dbname);
return;
}
} else {
if (!profile->master_db) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB %s\n", profile->dbname);
return;
}
}
switch_mutex_lock(profile->ireg_mutex);
@ -562,7 +557,7 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot)
",%d from sip_registrations where expires > 0", reboot);
}
sofia_glue_execute_sql_callback(profile, SWITCH_TRUE, NULL, sql, sofia_reg_del_callback, profile);
sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_reg_del_callback, profile);
if (now) {
switch_snprintf(sql, sizeof(sql), "delete from sip_registrations where expires > 0 and expires <= %ld and hostname='%s'",
(long) now, mod_sofia_globals.hostname);
@ -570,7 +565,7 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot)
switch_snprintf(sql, sizeof(sql), "delete from sip_registrations where expires > 0 and hostname='%s'", mod_sofia_globals.hostname);
}
sofia_glue_actually_execute_sql(profile, SWITCH_FALSE, sql, NULL);
sofia_glue_actually_execute_sql(profile, sql, NULL);
@ -579,12 +574,12 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot)
"and profile_name='%s' and expires <= %ld",
mod_sofia_globals.hostname, profile->name, (long) now);
sofia_glue_execute_sql_callback(profile, SWITCH_TRUE, NULL, sql, sofia_sla_dialog_del_callback, profile);
sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_sla_dialog_del_callback, profile);
switch_snprintf(sql, sizeof(sql), "delete from sip_registrations where expires > 0 and hostname='%s' and expires <= %ld",
mod_sofia_globals.hostname, (long) now);
sofia_glue_actually_execute_sql(profile, SWITCH_FALSE, sql, NULL);
sofia_glue_actually_execute_sql(profile, sql, NULL);
}
@ -595,7 +590,7 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot)
switch_snprintf(sql, sizeof(sql), "delete from sip_presence where expires > 0 and hostname='%s'", mod_sofia_globals.hostname);
}
sofia_glue_actually_execute_sql(profile, SWITCH_FALSE, sql, NULL);
sofia_glue_actually_execute_sql(profile, sql, NULL);
if (now) {
switch_snprintf(sql, sizeof(sql), "delete from sip_authentication where expires > 0 and expires <= %ld and hostname='%s'",
@ -604,7 +599,7 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot)
switch_snprintf(sql, sizeof(sql), "delete from sip_authentication where expires > 0 and hostname='%s'", mod_sofia_globals.hostname);
}
sofia_glue_actually_execute_sql(profile, SWITCH_FALSE, sql, NULL);
sofia_glue_actually_execute_sql(profile, sql, NULL);
@ -615,7 +610,7 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot)
switch_snprintf(sql, sizeof(sql), "select call_id from sip_subscriptions where expires > 0 and hostname='%s'", mod_sofia_globals.hostname);
}
sofia_glue_execute_sql_callback(profile, SWITCH_TRUE, NULL, sql, sofia_sub_del_callback, profile);
sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_sub_del_callback, profile);
if (now) {
switch_snprintf(sql, sizeof(sql), "delete from sip_subscriptions where expires > 0 and expires <= %ld and hostname='%s'",
@ -624,7 +619,7 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot)
switch_snprintf(sql, sizeof(sql), "delete from sip_subscriptions where expires > 0 and hostname='%s'", mod_sofia_globals.hostname);
}
sofia_glue_actually_execute_sql(profile, SWITCH_FALSE, sql, NULL);
sofia_glue_actually_execute_sql(profile, sql, NULL);
if (now && sofia_test_pflag(profile, PFLAG_NAT_OPTIONS_PING)) {
@ -633,7 +628,7 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot)
" from sip_registrations where (status like '%%AUTO-NAT%%' "
"or status like '%%UDP-NAT%%') and hostname='%s'", mod_sofia_globals.hostname);
sofia_glue_execute_sql_callback(profile, SWITCH_TRUE, NULL, sql, sofia_reg_nat_callback, profile);
sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_reg_nat_callback, profile);
}
switch_mutex_unlock(profile->ireg_mutex);
@ -661,7 +656,7 @@ char *sofia_reg_find_reg_url(sofia_profile_t *profile, const char *user, const c
}
sofia_glue_execute_sql_callback(profile, SWITCH_FALSE, profile->ireg_mutex, sql, sofia_reg_find_callback, &cbt);
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_reg_find_callback, &cbt);
if (cbt.matches) {
@ -686,9 +681,10 @@ void sofia_reg_auth_challenge(nua_t *nua, sofia_profile_t *profile, nua_handle_t
switch_epoch_time_now(NULL) + (profile->nonce_ttl ? profile->nonce_ttl : DEFAULT_NONCE_TTL),
profile->name, mod_sofia_globals.hostname);
switch_assert(sql != NULL);
sofia_glue_actually_execute_sql(profile, SWITCH_FALSE, sql, profile->ireg_mutex);
sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex);
switch_safe_free(sql);
//auth_str = switch_mprintf("Digest realm=\"%q\", nonce=\"%q\",%s algorithm=MD5, qop=\"auth\"", realm, uuid_str, stale ? " stale=true," : "");
auth_str = switch_mprintf("Digest realm=\"%q\", nonce=\"%q\",%s algorithm=MD5, qop=\"auth\"", realm, uuid_str, stale ? " stale=\"true\"," : "");
if (regtype == REG_REGISTER) {
@ -741,6 +737,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
char *path_val = NULL;
switch_event_t *auth_params = NULL;
int r = 0;
long reg_count = 0;
/* all callers must confirm that sip, sip->sip_request and sip->sip_contact are not NULL */
switch_assert(sip != NULL && sip->sip_contact != NULL && sip->sip_request != NULL);
@ -896,7 +893,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
if (authorization) {
char *v_contact_str;
if ((auth_res = sofia_reg_parse_auth(profile, authorization, sip, sip->sip_request->rq_method_name,
key, keylen, network_ip, v_event, exptime, regtype, to_user, &auth_params)) == AUTH_STALE) {
key, keylen, network_ip, v_event, exptime, regtype, to_user, &auth_params, &reg_count)) == AUTH_STALE) {
stale = 1;
}
@ -1131,16 +1128,21 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
switch_event_fire(&event);
}
#else
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_PROBE) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", "sip");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", profile->url);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", rpid);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", to_user, reg_host);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "to", "%s@%s", to_user, reg_host);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", "Registered");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_subtype", "probe");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
switch_event_fire(&event);
if (sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER) ||
(reg_count == 1 && sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER))) {
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_PROBE) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", "sip");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", profile->url);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", rpid);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", to_user, reg_host);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "to", "%s@%s", to_user, reg_host);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", "Registered");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_subtype", "probe");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
switch_event_fire(&event);
}
}
#endif
@ -1213,28 +1215,15 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
if (regtype == REG_REGISTER) {
char exp_param[128] = "";
char date[80] = "";
long nc_long = 0;
s_event = NULL;
if (exptime) {
switch_snprintf(exp_param, sizeof(exp_param), "expires=%ld", exptime);
sip_contact_add_param(nua_handle_home(nh), sip->sip_contact, exp_param);
if (auth_params && sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER)) {
const char *nc = NULL;
if ((nc = switch_event_get_header(auth_params, "sip_auth_nc"))) {
nc_long = strtoul(nc, 0, 16);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"No nonce count, cannot determine if this was the first register, sending notify implicitly.\n");
nc_long = 1;
}
}
if (sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER) ||
(nc_long == 1 && sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER))) {
(reg_count == 1 && sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER))) {
if (switch_event_create(&s_event, SWITCH_EVENT_MESSAGE_QUERY) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "Message-Account", "sip:%s@%s", mwi_user, mwi_host);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "VM-Sofia-Profile", profile->name);
@ -1263,13 +1252,9 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
if (s_event) {
switch_event_fire(&s_event);
}
if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)) {
char *full_contact = sip_header_as_string(nua_handle_home(nh), (void *) sip->sip_contact);
if (full_contact && switch_stristr("SUBSCRIBE", full_contact)) {
sofia_sla_handle_register(nua, profile, sip, exptime, full_contact);
su_free(nua_handle_home(nh), full_contact);
}
if (contact_str && sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE) && sofia_sla_supported(sip)) {
sofia_sla_handle_register(nua, profile, sip, exptime, contact_str);
}
switch_goto_int(r, 1, end);
@ -1594,6 +1579,20 @@ void sofia_reg_handle_sip_r_challenge(int status,
}
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);
cb->last_nc = zstr(argv[1]) ? 0 : atoi(argv[1]);
return 0;
}
auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
sip_authorization_t const *authorization,
sip_t const *sip,
@ -1606,7 +1605,8 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
sofia_regtype_t
regtype,
const char *to_user,
switch_event_t **auth_params)
switch_event_t **auth_params,
long *reg_count)
{
int indexnum;
const char *cur;
@ -1626,6 +1626,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
char *domain_name = NULL;
switch_event_t *params = NULL;
const char *auth_acl = NULL;
long ncl = 0;
username = realm = nonce = uri = qop = cnonce = nc = response = NULL;
@ -1684,20 +1685,35 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
}
if (zstr(np)) {
nonce_cb_t cb = { 0 };
long nc_long = 0;
first = 1;
if (nc) {
sql = switch_mprintf("select nonce from sip_authentication where nonce='%q' and last_nc < %lu", nonce, strtoul(nc, 0, 16));
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);
} else {
sql = switch_mprintf("select nonce from sip_authentication where nonce='%q'", nonce);
}
cb.nonce = np;
cb.nplen = nplen;
switch_assert(sql != NULL);
if (!sofia_glue_execute_sql2str(profile, profile->ireg_mutex, sql, np, nplen)) {
free(sql);
sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_reg_nonce_callback, &cb);
free(sql);
//if (!sofia_glue_execute_sql2str(profile, profile->ireg_mutex, sql, np, nplen)) {
if (zstr(np)) {
sql = switch_mprintf("delete from sip_authentication where nonce='%q'", nonce);
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
ret = AUTH_STALE;
goto end;
}
free(sql);
if (reg_count) {
*reg_count = cb.last_nc + 1;
}
}
switch_event_create(&params, SWITCH_EVENT_REQUEST_PARAMS);
@ -2082,6 +2098,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
if (nc && cnonce && qop) {
ncl = strtoul(nc, 0, 16);
#if defined(_WIN32) && !defined(_WIN64)
#define LL_FMT "ll"
@ -2089,10 +2106,10 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
#define LL_FMT "l"
#endif
sql = switch_mprintf("update sip_authentication set expires='%"LL_FMT"u',last_nc=%lu where nonce='%s'",
switch_epoch_time_now(NULL) + (profile->nonce_ttl ? profile->nonce_ttl : exptime + 10), strtoul(nc, 0, 16), nonce);
switch_epoch_time_now(NULL) + (profile->nonce_ttl ? profile->nonce_ttl : exptime + 10), ncl, nonce);
switch_assert(sql != NULL);
sofia_glue_actually_execute_sql(profile, SWITCH_FALSE, sql, profile->ireg_mutex);
sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex);
switch_safe_free(sql);
}
@ -2112,6 +2129,18 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
switch_safe_free(nc);
switch_safe_free(response);
if (reg_count && !*reg_count) {
if (ret == AUTH_OK) {
if (ncl) {
*reg_count = ncl;
} else {
*reg_count = 1;
}
} else {
*reg_count = 0;
}
}
return ret;
}

View File

@ -49,6 +49,25 @@ static int get_call_id_callback(void *pArg, int argc, char **argv, char **column
return 0;
}
int sofia_sla_supported(sip_t const *sip)
{
if (sip && sip->sip_user_agent && sip->sip_user_agent->g_string) {
const char *ua = sip->sip_user_agent->g_string;
if (switch_stristr("polycom", ua)) {
return 1;
}
if (switch_stristr("snom", ua)) {
return 1;
}
}
return 0;
}
void sofia_sla_handle_register(nua_t *nua, sofia_profile_t *profile, sip_t const *sip, long exptime, const char *full_contact)
{
nua_handle_t *nh = NULL;
@ -60,12 +79,15 @@ void sofia_sla_handle_register(nua_t *nua, sofia_profile_t *profile, sip_t const
sofia_transport_t transport = sofia_glue_url2transport(sip->sip_contact->m_url);
char network_ip[80];
int network_port = 0;
sofia_destination_t *dst;
char *route_uri = NULL;
char port_str[25] = "";
sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), &network_port);
sql = switch_mprintf("select call_id from sip_shared_appearance_dialogs where hostname='%q' and profile_name='%q' and contact_str='%q'",
mod_sofia_globals.hostname, profile->name, contact_str);
sofia_glue_execute_sql_callback(profile, SWITCH_FALSE, profile->ireg_mutex, sql, get_call_id_callback, &sh);
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, get_call_id_callback, &sh);
free(sql);
@ -85,21 +107,35 @@ void sofia_sla_handle_register(nua_t *nua, sofia_profile_t *profile, sip_t const
nua_handle_bind(nh, &mod_sofia_globals.keep_private);
switch_snprintf(exp_str, sizeof(exp_str), "%ld", exptime + 30);
switch_snprintf(port_str, sizeof(port_str), ":%ld", sofia_glue_transport_has_tls(transport) ? profile->tls_sip_port : profile->sip_port);
if (sofia_glue_check_nat(profile, network_ip)) {
switch_snprintf(my_contact, sizeof(my_contact), "<sip:%s@%s;transport=%s>;expires=%s", profile->sla_contact,
profile->extsipip, sofia_glue_transport2str(transport), exp_str);
switch_snprintf(my_contact, sizeof(my_contact), "<sip:%s@%s%s;transport=%s>;expires=%s", profile->sla_contact,
profile->extsipip, port_str, sofia_glue_transport2str(transport), exp_str);
} else {
switch_snprintf(my_contact, sizeof(my_contact), "<sip:%s@%s;transport=%s>;expires=%s", profile->sla_contact,
profile->sipip, sofia_glue_transport2str(transport), exp_str);
switch_snprintf(my_contact, sizeof(my_contact), "<sip:%s@%s%s;transport=%s>;expires=%s", profile->sla_contact,
profile->sipip, port_str, sofia_glue_transport2str(transport), exp_str);
}
dst = sofia_glue_get_destination((char*) full_contact);
if(dst->route_uri) {
route_uri = sofia_glue_strip_uri(dst->route_uri);
}
nua_subscribe(nh,
TAG_IF(dst->route_uri, NUTAG_PROXY(route_uri)), TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)),
SIPTAG_TO(sip->sip_to),
SIPTAG_FROM(sip->sip_to),
SIPTAG_CONTACT_STR(my_contact),
SIPTAG_EXPIRES_STR(exp_str),
SIPTAG_EVENT_STR("dialog;sla"), /* some phones want ;include-session-description too? */
SIPTAG_EVENT_STR("dialog;sla;include-session-description"),
SIPTAG_ACCEPT_STR("application/dialog-info+xml"),
TAG_NULL());
sofia_glue_free_destination(dst);
free(contact_str);
}
@ -119,6 +155,7 @@ void sofia_sla_handle_sip_i_subscribe(nua_t *nua, const char *contact_str, sofia
char network_ip[80];
int network_port = 0;
sofia_transport_t transport = sofia_glue_url2transport(sip->sip_contact->m_url);
char *pl;
sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), &network_port);
/*
@ -194,6 +231,21 @@ void sofia_sla_handle_sip_i_subscribe(nua_t *nua, const char *contact_str, sofia
/* sofia_presence says something about needing TAG_IF(sticky, NUTAG_PROXY(sticky)) for NAT stuff? */
TAG_END());
pl = switch_mprintf("<?xml version=\"1.0\"?>\n"
"<dialog-info xmlns=\"urn:ietf:params:xml:ns:dialog-info\" "
"version=\"0\" state=\"full\" entity=\"%s\"></dialog-info>\n", aor);
nua_notify(nh,
SIPTAG_SUBSCRIPTION_STATE_STR("active;expires=300"), /* XXX MTK FIXME - this is totally fake calculation */
TAG_IF(route_uri, NUTAG_PROXY(route_uri)),
SIPTAG_CONTENT_TYPE_STR("application/dialog-info+xml"), /* could've just kept the type from the payload */
SIPTAG_PAYLOAD_STR(pl),
TAG_END());
switch_safe_free(aor);
switch_safe_free(subscriber);
switch_safe_free(route_uri);
@ -295,7 +347,7 @@ void sofia_sla_handle_sip_i_notify(nua_t *nua, sofia_profile_t *profile, nua_han
helper.payload = sip->sip_payload->pl_data; /* could just send the WHOLE payload. you'd get the type that way. */
/* which mutex if any is correct to hold in this callback? XXX MTK FIXME */
sofia_glue_execute_sql_callback(profile, SWITCH_FALSE, profile->ireg_mutex, sql, sofia_sla_sub_callback, &helper);
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_sla_sub_callback, &helper);
switch_safe_free(sql);
switch_safe_free(aor);