From 397ef741c17f9b14f95fa9555eacbff952624bc6 Mon Sep 17 00:00:00 2001
From: Anthony Minessale <anthony.minessale@gmail.com>
Date: Thu, 12 Nov 2009 03:52:07 +0000
Subject: [PATCH] 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
---
 src/mod/endpoints/mod_sofia/mod_sofia.c      |   8 +-
 src/mod/endpoints/mod_sofia/mod_sofia.h      |  14 +-
 src/mod/endpoints/mod_sofia/sofia.c          |  17 +-
 src/mod/endpoints/mod_sofia/sofia_glue.c     | 213 +++++++++++--------
 src/mod/endpoints/mod_sofia/sofia_presence.c |  19 +-
 src/mod/endpoints/mod_sofia/sofia_reg.c      | 143 ++++++++-----
 src/mod/endpoints/mod_sofia/sofia_sla.c      |  66 +++++-
 7 files changed, 307 insertions(+), 173 deletions(-)

diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c
index 770ae67ce5..6c9f2a4310 100644
--- a/src/mod/endpoints/mod_sofia/mod_sofia.c
+++ b/src/mod/endpoints/mod_sofia/mod_sofia.c
@@ -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);
 
diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h
index 03132cceb6..e6c5e958f8 100644
--- a/src/mod/endpoints/mod_sofia/mod_sofia.h
+++ b/src/mod/endpoints/mod_sofia/mod_sofia.h
@@ -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);
diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c
index 1645880e84..ba08175299 100644
--- a/src/mod/endpoints/mod_sofia/sofia.c
+++ b/src/mod/endpoints/mod_sofia/sofia.c
@@ -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")) {
diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c
index 7e64e91b53..d34272cdb3 100644
--- a/src/mod/endpoints/mod_sofia/sofia_glue.c
+++ b/src/mod/endpoints/mod_sofia/sofia_glue.c
@@ -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:
diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c
index 7502ad2768..3108930595 100644
--- a/src/mod/endpoints/mod_sofia/sofia_presence.c
+++ b/src/mod/endpoints/mod_sofia/sofia_presence.c
@@ -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);
 		}
diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c
index 0c41a39192..4d5c65252a 100644
--- a/src/mod/endpoints/mod_sofia/sofia_reg.c
+++ b/src/mod/endpoints/mod_sofia/sofia_reg.c
@@ -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;
 
 }
diff --git a/src/mod/endpoints/mod_sofia/sofia_sla.c b/src/mod/endpoints/mod_sofia/sofia_sla.c
index 9ae56e10fc..afec5e5a12 100644
--- a/src/mod/endpoints/mod_sofia/sofia_sla.c
+++ b/src/mod/endpoints/mod_sofia/sofia_sla.c
@@ -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);