Project "FreeSWITCH Source" received a push.

branch: master updated

       via: a2c0da53f368f0b11340c3a72814c93b182753b7 (commit)
      from: 88d410d31485d13911f0958af5a73f1f6f49a454 (commit)


= COMMIT LOG ===========================================================
committer: Anthony Minessale
comments: 
add centralized registration db to core db and use it from mod_sofia

diff --git a/src/include/switch_core.h b/src/include/switch_core.h
index 69b0642..984b54f 100644
--- a/src/include/switch_core.h
+++ b/src/include/switch_core.h
@@ -2227,6 +2227,11 @@ SWITCH_DECLARE(const char *) switch_core_banner(void);
 SWITCH_DECLARE(switch_bool_t) switch_core_session_in_thread(switch_core_session_t *session);
 SWITCH_DECLARE(uint32_t) switch_default_ptime(const char *name, uint32_t number);
 
+SWITCH_DECLARE(switch_status_t) switch_core_add_registration(const char *user, const char *realm, const char *token, const char *url, uint32_t expires, 
+															 const char *network_ip, const char *network_port, const char *network_proto);
+SWITCH_DECLARE(switch_status_t) switch_core_del_registration(const char *user, const char *realm, const char *token);
+SWITCH_DECLARE(switch_status_t) switch_core_expire_registration(int force);
+
 SWITCH_END_EXTERN_C
 #endif
 /* For Emacs:
diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c
index f34042a..030cb8e 100644
--- a/src/mod/applications/mod_commands/mod_commands.c
+++ b/src/mod/applications/mod_commands/mod_commands.c
@@ -45,6 +45,149 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load);
 SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_commands_shutdown);
 SWITCH_MODULE_DEFINITION(mod_commands, mod_commands_load, mod_commands_shutdown, NULL);
 
+
+struct cb_helper {
+	uint32_t row_process;
+	switch_stream_handle_t *stream;
+};
+
+static int url_callback(void *pArg, int argc, char **argv, char **columnNames)
+{
+	struct cb_helper *cb = (struct cb_helper *) pArg;
+
+	cb->row_process++;
+
+	if (!zstr(argv[0])) {
+		cb->stream->write_function(cb->stream, "%s,", argv[0]);
+	}
+
+	return 0;
+}
+
+static switch_status_t select_url(const char *user,
+					   const char *domain,
+					   const char *concat,
+					   const char *exclude_contact, 
+					   switch_stream_handle_t *stream)
+{
+	struct cb_helper cb;
+	char *sql, *errmsg = NULL;
+	switch_core_flag_t cflags = switch_core_flags();
+	switch_cache_db_handle_t *db = NULL;
+
+	if (!(cflags & SCF_USE_SQL)) {
+		stream->write_function(stream, "-ERR SQL DISABLED NO DATA AVAILABLE!\n");
+		return SWITCH_STATUS_SUCCESS;
+	}
+
+	if (switch_core_db_handle(&db) != SWITCH_STATUS_SUCCESS) {
+		stream->write_function(stream, "%s", "-ERR Databse Error!\n");
+		return SWITCH_STATUS_SUCCESS;
+	}
+
+	cb.row_process = 0;
+	cb.stream = stream;
+
+	if (exclude_contact) {
+		sql = switch_mprintf("select url, '%q' "
+							 "from registrations where user='%q' and realm='%q' "
+							 "and url not like '%%%s%%'", (concat != NULL) ? concat : "", user, domain, exclude_contact);
+	} else {
+		sql = switch_mprintf("select url, '%q' "
+							 "from registrations where user='%q' and realm='%q'",
+							 (concat != NULL) ? concat : "", user, domain);
+	}
+
+	switch_assert(sql);
+	switch_cache_db_execute_sql_callback(db, sql, url_callback, &cb, &errmsg);
+
+	if (errmsg) {
+		stream->write_function(stream, "-ERR SQL Error [%s]\n", errmsg);
+		free(errmsg);
+		errmsg = NULL;
+	}	
+
+	switch_safe_free(sql);
+
+	if (db) {
+		switch_cache_db_release_db_handle(&db);
+	}
+
+	return SWITCH_STATUS_SUCCESS;
+}
+
+SWITCH_STANDARD_API(reg_url_function)
+{
+	char *data;
+	char *user = NULL;
+	char *domain = NULL, *dup_domain = NULL;
+	char *concat = NULL;
+	const char *exclude_contact = NULL;
+	char *reply = "error/facility_not_subscribed";
+	switch_stream_handle_t mystream = { 0 };
+
+
+	if (!cmd) {
+		stream->write_function(stream, "%s", "");
+		return SWITCH_STATUS_SUCCESS;
+	}
+
+	if (session) {
+		switch_channel_t *channel = switch_core_session_get_channel(session);
+		exclude_contact = switch_channel_get_variable(channel, "sip_exclude_contact");
+	}
+
+	
+	data = strdup(cmd);
+	switch_assert(data);
+
+	user = data;
+	
+	if ((domain = strchr(user, '@'))) {
+		*domain++ = '\0';
+		if ((concat = strchr(domain, '/'))) {
+			*concat++ = '\0';
+		}
+	} else {
+		if ((concat = strchr(user, '/'))) {
+			*concat++ = '\0';
+		}
+	}
+
+	if (zstr(domain)) {
+		dup_domain = switch_core_get_variable_dup("domain");
+		domain = dup_domain;
+	}
+
+	if (!user) goto end;
+
+	
+	SWITCH_STANDARD_STREAM(mystream);
+	switch_assert(mystream.data);
+
+	select_url(user, domain, concat, exclude_contact, &mystream);
+	reply = mystream.data;
+
+
+ end:
+	
+	if (zstr(reply)) {
+		reply = "error/user_not_registered";
+	} else if (end_of(reply) == ',') {
+		end_of(reply) = '\0';
+	}
+
+	stream->write_function(stream, "%s", reply);
+	reply = NULL;
+
+	switch_safe_free(mystream.data);					
+
+	switch_safe_free(data);
+	switch_safe_free(dup_domain);
+
+	return SWITCH_STATUS_SUCCESS;
+}
+
 SWITCH_STANDARD_API(banner_function)
 {
 	stream->write_function(stream, "%s", switch_core_banner());
@@ -3738,6 +3881,14 @@ SWITCH_STANDARD_API(show_function)
 				as = argv[3];
 			}
 		}
+	} else if (!strcasecmp(command, "registrations")) {
+		sprintf(sql, "select * from registrations where hostname='%s'", hostname);
+		if (argv[1] && !strcasecmp(argv[1], "count")) {
+			holder.justcount = 1;
+			if (argv[3] && !strcasecmp(argv[2], "as")) {
+				as = argv[3];
+			}
+		}
 	} else if (!strcasecmp(command, "channels") && argv[1] && !strcasecmp(argv[1], "like")) {
 		if (argv[2]) {
 			char *p;
@@ -4890,6 +5041,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
 	SWITCH_ADD_API(commands_api_interface, "tone_detect", "Start Tone Detection on a channel", tone_detect_session_function, TONE_DETECT_SYNTAX);
 	SWITCH_ADD_API(commands_api_interface, "unload", "Unload Module", unload_function, UNLOAD_SYNTAX);
 	SWITCH_ADD_API(commands_api_interface, "unsched_api", "Unschedule an api command", unsched_api_function, UNSCHED_SYNTAX);
+	SWITCH_ADD_API(commands_api_interface, "reg_url", "", reg_url_function, "<user>@<realm>");
 	SWITCH_ADD_API(commands_api_interface, "url_decode", "url decode a string", url_decode_function, "<string>");
 	SWITCH_ADD_API(commands_api_interface, "url_encode", "url encode a string", url_encode_function, "<string>");
 	SWITCH_ADD_API(commands_api_interface, "user_data", "find user data", user_data_function, "<user>@<domain> [var|param|attr] <name>");
@@ -5000,6 +5152,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
 	switch_console_set_complete("add show management");
 	switch_console_set_complete("add show modules");
 	switch_console_set_complete("add show nat_map");
+	switch_console_set_complete("add show registrations");
 	switch_console_set_complete("add show say");
 	switch_console_set_complete("add show timer");
 	switch_console_set_complete("add shutdown");
diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c
index 07c285f..4853dff 100644
--- a/src/mod/endpoints/mod_sofia/mod_sofia.c
+++ b/src/mod/endpoints/mod_sofia/mod_sofia.c
@@ -3314,6 +3314,7 @@ static int contact_callback(void *pArg, int argc, char **argv, char **columnName
 
 	return 0;
 }
+
 static int sql2str_callback(void *pArg, int argc, char **argv, char **columnNames)
 {
 	struct cb_helper_sql2str *cbt = (struct cb_helper_sql2str *) pArg;
diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c
index 631cbdb..76b1dcc 100644
--- a/src/mod/endpoints/mod_sofia/sofia_reg.c
+++ b/src/mod/endpoints/mod_sofia/sofia_reg.c
@@ -877,6 +877,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
 	const char *agent = "unknown";
 	const char *pres_on_reg = NULL;
 	int send_pres = 0;
+	int is_tls = 0, is_tcp = 0;
 
 	delete_subs = sofia_test_pflag(profile, PFLAG_DEL_SUBS_ON_REG);
 
@@ -944,8 +945,6 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
 		char *path_encoded = NULL;
 		int path_encoded_len = 0;
 		const char *proto = "sip";
-		int is_tls = 0, is_tcp = 0;
-
 
 		if (switch_stristr("transport=tls", sip->sip_contact->m_url->url_params)) {
 			is_tls += 1;
@@ -1292,6 +1291,8 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
 		char guess_ip4[256];
 		const char *username = "unknown";
 		const char *realm = reg_host;
+		char *url = NULL;
+		char *contact = NULL;
 
 		if (auth_params) {
 			username = switch_event_get_header(auth_params, "sip_auth_username");
@@ -1327,7 +1328,15 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
 
 		switch_find_local_ip(guess_ip4, sizeof(guess_ip4), NULL, AF_INET);
 
+		contact = sofia_glue_get_url_from_contact(contact_str, 1);
+		url = switch_mprintf("sofia/%q/sip:%q", profile->name, sofia_glue_strip_proto(contact));
 		
+		switch_core_add_registration(to_user, reg_host, call_id, url, (long) switch_epoch_time_now(NULL) + (long) exptime + 60,
+									 network_ip, network_port_c, is_tls ? "tls" : is_tcp ? "tcp" : "udp");
+
+		switch_safe_free(url);
+		switch_safe_free(contact);
+
 		sql = switch_mprintf("insert into sip_registrations "
 							 "(call_id,sip_user,sip_host,presence_hosts,contact,status,rpid,expires,"
 							 "user_agent,server_user,server_host,profile_name,hostname,network_ip,network_port,sip_username,sip_realm,"
diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c
index 73890a1..ba92ebc 100644
--- a/src/switch_core_sqldb.c
+++ b/src/switch_core_sqldb.c
@@ -87,6 +87,7 @@ SWITCH_DECLARE(switch_status_t) _switch_core_db_handle(switch_cache_db_handle_t
 
 
 #define SQL_CACHE_TIMEOUT 120
+#define SQL_REG_TIMEOUT 15
 
 static void sql_close(time_t prune)
 {
@@ -906,7 +907,7 @@ SWITCH_DECLARE(switch_bool_t) switch_cache_db_test_reactive(switch_cache_db_hand
 
 static void *SWITCH_THREAD_FUNC switch_core_sql_db_thread(switch_thread_t *thread, void *obj)
 {
-	int sec = 0;
+	int sec = 0, reg_sec = 0;;
 
 	sql_manager.db_thread_running = 1;
 
@@ -916,6 +917,11 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_db_thread(switch_thread_t *threa
 			wake_thread(0);
 			sec = 0;
 		}
+
+		if (++reg_sec == SQL_REG_TIMEOUT) {
+			switch_core_expire_registration(0);
+			reg_sec = 0;
+		}
 		switch_yield(1000000);
 	}
 
@@ -1616,6 +1622,108 @@ static char create_nat_sql[] =
 	"   hostname VARCHAR(256)\n"
 	");\n";
 
+
+static char create_registrations_sql[] =
+	"CREATE TABLE registrations (\n"
+	"   user      VARCHAR(256),\n"
+	"   realm     VARCHAR(256),\n"
+	"   token     VARCHAR(256),\n"
+	"   url      TEXT,\n"
+	"   expires  INTEGER,\n"
+	"   network_ip VARCHAR(256),\n"
+	"   network_port VARCHAR(256),\n"
+	"   network_proto VARCHAR(256),\n"
+	"   hostname VARCHAR(256)\n"
+	");\n"
+	"create index regindex1 on registrations (user,real,hostname);\n";
+	
+
+SWITCH_DECLARE(switch_status_t) switch_core_add_registration(const char *user, const char *realm, const char *token, const char *url, uint32_t expires, 
+															 const char *network_ip, const char *network_port, const char *network_proto)
+{
+	switch_cache_db_handle_t *dbh;
+	char *sql;
+
+	if (switch_core_db_handle(&dbh) != SWITCH_STATUS_SUCCESS) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB!\n");
+		return SWITCH_STATUS_FALSE;
+	}
+
+	sql = switch_mprintf("delete from registrations where hostname='%q' and (url='%q' or token='%q')", switch_core_get_hostname(), url, switch_str_nil(token));
+	switch_cache_db_execute_sql(dbh, sql, NULL);
+	free(sql);
+
+	sql = switch_mprintf("insert into registrations (user,realm,token,url,expires,network_ip,network_port,network_proto,hostname) "
+						 "values ('%q','%q','%q','%q',%ld,'%q','%q','%q','%q')",
+						 switch_str_nil(user),
+						 switch_str_nil(realm),
+						 switch_str_nil(token),
+						 switch_str_nil(url),
+						 expires,
+						 switch_str_nil(network_ip),
+						 switch_str_nil(network_port),
+						 switch_str_nil(network_proto),
+						 switch_core_get_hostname()
+						 );
+	
+	switch_cache_db_execute_sql(dbh, sql, NULL);
+	switch_cache_db_release_db_handle(&dbh);
+
+	free(sql);
+
+	return SWITCH_STATUS_SUCCESS;
+}
+
+SWITCH_DECLARE(switch_status_t) switch_core_del_registration(const char *user, const char *realm, const char *token)
+{
+
+	switch_cache_db_handle_t *dbh;
+	char *sql;
+
+	if (switch_core_db_handle(&dbh) != SWITCH_STATUS_SUCCESS) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB!\n");
+		return SWITCH_STATUS_FALSE;
+	}
+
+	sql = switch_mprintf("delete from registrations where user='%q' and realm='%q' and hostname='%q'", user, realm, switch_core_get_hostname());
+
+	switch_cache_db_execute_sql(dbh, sql, NULL);
+	switch_cache_db_release_db_handle(&dbh);
+
+	free(sql);
+
+	return SWITCH_STATUS_SUCCESS;
+}
+
+SWITCH_DECLARE(switch_status_t) switch_core_expire_registration(int force)
+{
+	
+	switch_cache_db_handle_t *dbh;
+	char *sql;
+	switch_time_t now;
+
+	if (switch_core_db_handle(&dbh) != SWITCH_STATUS_SUCCESS) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB!\n");
+		return SWITCH_STATUS_FALSE;
+	}
+
+	now = switch_epoch_time_now(NULL);
+
+	if (force) {
+		sql = switch_mprintf("delete from registrations where hostname='%q'", switch_core_get_hostname());
+	} else {
+		sql = switch_mprintf("delete from registrations where expires <= %ld and hostname='%q'", now, switch_core_get_hostname());
+	}
+
+	switch_cache_db_execute_sql(dbh, sql, NULL);
+	switch_cache_db_release_db_handle(&dbh);
+
+	free(sql);
+
+	return SWITCH_STATUS_SUCCESS;
+
+}
+
 switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_t manage)
 {
 	switch_threadattr_t *thd_attr;
@@ -1690,6 +1798,8 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_
 	switch_cache_db_test_reactive(dbh, "select hostname from complete", "DROP TABLE complete", create_complete_sql);
 	switch_cache_db_test_reactive(dbh, "select hostname from aliases", "DROP TABLE aliases", create_alias_sql);
 	switch_cache_db_test_reactive(dbh, "select hostname from nat", "DROP TABLE nat", create_nat_sql);
+	switch_cache_db_test_reactive(dbh, "delete from registrations where network_proto='tcp' or network_proto='tls'", 
+								  "DROP TABLE registrations", create_registrations_sql);
 
 
 	switch (dbh->type) {
@@ -1706,6 +1816,8 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_
 			}
 			switch_cache_db_test_reactive(dbh, "select ikey from interfaces", "DROP TABLE interfaces", create_interfaces_sql);
 			switch_cache_db_test_reactive(dbh, "select hostname from tasks", "DROP TABLE tasks", create_tasks_sql);
+			switch_cache_db_test_reactive(dbh, "delete from registrations where network_proto='tcp' or network_proto='tls'", 
+										  "DROP TABLE registrations", create_registrations_sql);
 
 			if (runtime.odbc_dbtype == DBTYPE_DEFAULT) {
 				switch_cache_db_execute_sql(dbh, "begin;delete from channels where hostname='';delete from channels where hostname='';commit;", &err);
========================================================================

Summary of changes:
 src/include/switch_core.h                        |    5 +
 src/mod/applications/mod_commands/mod_commands.c |  153 ++++++++++++++++++++++
 src/mod/endpoints/mod_sofia/mod_sofia.c          |    1 +
 src/mod/endpoints/mod_sofia/sofia_reg.c          |   13 ++-
 src/switch_core_sqldb.c                          |  114 ++++++++++++++++-
 5 files changed, 283 insertions(+), 3 deletions(-)

this email was generated because of /git/your-repo.git/hooks/post-receive by the file /git-core/contrib/hooks/post-receive-email
For more info, see http://blog.chomperstomp.com/?p=630 --
FreeSWITCH Source