add core ODBC

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@4846 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale
2007-04-04 03:08:17 +00:00
parent ed0cfa9f15
commit 4d62a1adb2
13 changed files with 1013 additions and 455 deletions
+2
View File
@@ -12,6 +12,8 @@ LOCAL_CFLAGS += -I$(SOFIAUA_DIR)/sdp -I$(SOFIAUA_DIR)/sip
LOCAL_CFLAGS += -I$(SOFIAUA_DIR)/soa -I$(SOFIAUA_DIR)/sresolv
LOCAL_CFLAGS += -I$(SOFIAUA_DIR)/stun -I$(SOFIAUA_DIR)/su
LOCAL_CFLAGS += -I$(SOFIAUA_DIR)/tport -I$(SOFIAUA_DIR)/url
LOCAL_CFLAGS += `if test -f $(BASE)/.libs/libfreeswitch_la-switch_odbc.o ; then echo -DSWITCH_HAVE_ODBC; fi ;`
LOCAL_OBJS=sofia.o sofia_glue.o sofia_presence.o sofia_reg.o
LOCAL_SOURCES=sofia.c sofia_glue.c sofia_presense.c sofia_reg.c mod_sofia.c
+21 -4
View File
@@ -40,6 +40,9 @@
#define HAVE_APR
#include <switch.h>
#ifdef SWITCH_HAVE_ODBC
#include <switch_odbc.h>
#endif
static const char modname[] = "mod_sofia";
static const switch_state_handler_table_t noop_state_handler = { 0 };
@@ -221,6 +224,13 @@ struct sofia_profile {
su_home_t *home;
switch_hash_t *profile_hash;
switch_hash_t *chat_hash;
switch_core_db_t *master_db;
#ifdef SWITCH_HAVE_ODBC
char *odbc_dsn;
char *odbc_user;
char *odbc_pass;
switch_odbc_handle_t *master_odbc;
#endif
};
@@ -328,8 +338,6 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session);
uint8_t negotiate_sdp(switch_core_session_t *session, sdp_session_t * sdp);
char *sofia_reg_get_auth_data(char *dbname, char *nonce, char *npassword, size_t len, switch_mutex_t * mutex);
void sofia_presence_establish_presence(sofia_profile_t * profile);
void sofia_handle_sip_i_state(int status,
@@ -387,8 +395,8 @@ void sofia_presence_handle_sip_i_subscribe(int status,
sofia_profile_t *sofia_glue_find_profile(char *key);
void sofia_glue_add_profile(char *key, sofia_profile_t * profile);
void sofia_glue_execute_sql(char *dbname, char *sql, switch_mutex_t * mutex);
void sofia_reg_check_expire(switch_core_db_t *db, sofia_profile_t * profile, time_t now);
void sofia_glue_execute_sql(sofia_profile_t *profile, switch_bool_t master, char *sql, switch_mutex_t *mutex);
void sofia_reg_check_expire(sofia_profile_t * profile, time_t now);
void sofia_reg_check_gateway(sofia_profile_t * profile, time_t now);
void sofia_reg_unregister(sofia_profile_t * profile);
switch_status_t sofia_glue_ext_address_lookup(char **ip, switch_port_t *port, char *sourceip, switch_memory_pool_t *pool);
@@ -404,3 +412,12 @@ void sofia_presence_set_chat_hash(private_object_t * tech_pvt, sip_t const *sip)
switch_status_t sofia_on_hangup(switch_core_session_t *session);
char *sofia_glue_get_url_from_contact(char *buf, uint8_t to_dup);
void sofia_presence_set_hash_key(char *hash_key, int32_t len, sip_t const *sip);
void sofia_glue_sql_close(sofia_profile_t *profile);
int sofia_glue_init_sql(sofia_profile_t *profile);
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);
char *sofia_glue_execute_sql2str(sofia_profile_t *profile, switch_mutex_t *mutex, char *sql, char *resbuf, size_t len);
+22 -44
View File
@@ -36,41 +36,6 @@
extern su_log_t tport_log[];
static char reg_sql[] =
"CREATE TABLE sip_registrations (\n"
" user VARCHAR(255),\n"
" host VARCHAR(255),\n"
" contact VARCHAR(1024),\n"
" status VARCHAR(255),\n"
" rpid VARCHAR(255),\n"
" expires INTEGER(8)" ");\n";
static char sub_sql[] =
"CREATE TABLE sip_subscriptions (\n"
" proto VARCHAR(255),\n"
" user VARCHAR(255),\n"
" host VARCHAR(255),\n"
" sub_to_user VARCHAR(255),\n"
" sub_to_host VARCHAR(255),\n"
" event VARCHAR(255),\n"
" contact VARCHAR(1024),\n"
" call_id VARCHAR(255),\n"
" full_from VARCHAR(255),\n"
" full_via VARCHAR(255),\n"
" expires INTEGER(8)" ");\n";
static char auth_sql[] =
"CREATE TABLE sip_authentication (\n"
" user VARCHAR(255),\n"
" host VARCHAR(255),\n"
" passwd VARCHAR(255),\n"
" nonce VARCHAR(255),\n"
" expires INTEGER(8)"
");\n";
void sofia_event_callback(nua_event_t event,
int status,
char const *phrase,
@@ -253,7 +218,7 @@ void event_handler(switch_event_t *event)
}
if (sql) {
sofia_glue_execute_sql(profile->dbname, sql, profile->ireg_mutex);
sofia_glue_execute_sql(profile, SWITCH_FALSE, sql, profile->ireg_mutex);
switch_safe_free(sql);
sql = NULL;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Propagating registration for %s@%s->%s\n", from_user, from_host, contact_str);
@@ -272,7 +237,6 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t * thread, void
sip_alias_node_t *node;
uint32_t ireg_loops = 0;
uint32_t gateway_loops = 0;
switch_core_db_t *db;
switch_event_t *s_event;
profile->s_root = su_root_create(NULL);
@@ -320,11 +284,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t * thread, void
}
if ((db = switch_core_db_open_file(profile->dbname))) {
switch_core_db_test_reactive(db, "select contact from sip_registrations", reg_sql);
switch_core_db_test_reactive(db, "select contact from sip_subscriptions", sub_sql);
switch_core_db_test_reactive(db, "select * from sip_authentication", auth_sql);
} else {
if (!sofia_glue_init_sql(profile)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open SQL Database!\n");
return NULL;
}
@@ -362,7 +322,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t * thread, void
while (mod_sofia_globals.running == 1) {
if (++ireg_loops >= IREG_SECONDS) {
sofia_reg_check_expire(db, profile, time(NULL));
sofia_reg_check_expire(profile, time(NULL));
ireg_loops = 0;
}
@@ -373,8 +333,9 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t * thread, void
su_root_step(profile->s_root, 1000);
}
sofia_glue_sql_close(profile);
switch_core_db_close(db);
sofia_reg_unregister(profile);
su_home_unref(profile->home);
@@ -496,6 +457,7 @@ switch_status_t config_sofia(int reload)
profile->name = switch_core_strdup(profile->pool, xprofilename);
snprintf(url, sizeof(url), "sofia_reg_%s", xprofilename);
profile->dbname = switch_core_strdup(profile->pool, url);
switch_core_hash_init(&profile->chat_hash, profile->pool);
@@ -510,6 +472,22 @@ switch_status_t config_sofia(int reload)
profile->debug = atoi(val);
} else if (!strcasecmp(var, "use-rtp-timer") && switch_true(val)) {
switch_set_flag(profile, TFLAG_TIMER);
} else if (!strcasecmp(var, "odbc-dsn")) {
#ifdef SWITCH_HAVE_ODBC
profile->odbc_dsn = switch_core_strdup(profile->pool, val);
if ((profile->odbc_user = strchr(profile->odbc_dsn, ':'))) {
*profile->odbc_user++ = '\0';
}
if ((profile->odbc_pass = strchr(profile->odbc_user, ':'))) {
*profile->odbc_pass++ = '\0';
}
#else
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC IS NOT AVAILABLE!\n");
#endif
} else if (!strcasecmp(var, "inbound-no-media") && switch_true(val)) {
switch_set_flag(profile, TFLAG_INB_NOMEDIA);
} else if (!strcasecmp(var, "inbound-late-negotiation") && switch_true(val)) {
+268 -5
View File
@@ -1119,7 +1119,91 @@ void sofia_glue_add_profile(char *key, sofia_profile_t * profile)
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
}
void sofia_glue_execute_sql(char *dbname, char *sql, switch_mutex_t * mutex)
int sofia_glue_init_sql(sofia_profile_t *profile)
{
char reg_sql[] =
"CREATE TABLE sip_registrations (\n"
" user VARCHAR(255),\n"
" host VARCHAR(255),\n"
" contact VARCHAR(1024),\n"
" status VARCHAR(255),\n"
" rpid VARCHAR(255),\n"
" expires INTEGER(8)" ");\n";
char sub_sql[] =
"CREATE TABLE sip_subscriptions (\n"
" proto VARCHAR(255),\n"
" user VARCHAR(255),\n"
" host VARCHAR(255),\n"
" sub_to_user VARCHAR(255),\n"
" sub_to_host VARCHAR(255),\n"
" event VARCHAR(255),\n"
" contact VARCHAR(1024),\n"
" call_id VARCHAR(255),\n"
" full_from VARCHAR(255),\n"
" full_via VARCHAR(255),\n"
" expires INTEGER(8)" ");\n";
char auth_sql[] =
"CREATE TABLE sip_authentication (\n"
" user VARCHAR(255),\n"
" host VARCHAR(255),\n"
" passwd VARCHAR(255),\n"
" nonce VARCHAR(255),\n"
" expires INTEGER(8)"
");\n";
#ifdef SWITCH_HAVE_ODBC
if (profile->odbc_dsn) {
if (!(profile->master_odbc = switch_odbc_handle_new(profile->odbc_dsn, profile->odbc_user, profile->odbc_pass))) {
return 0;
}
if (switch_odbc_handle_connect(profile->master_odbc) != SWITCH_ODBC_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Connecting ODBC DSN: %s\n", profile->odbc_dsn);
return 0;
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Connected ODBC DSN: %s\n", profile->odbc_dsn);
switch_odbc_handle_exec(profile->master_odbc, reg_sql, NULL);
switch_odbc_handle_exec(profile->master_odbc, sub_sql, NULL);
switch_odbc_handle_exec(profile->master_odbc, auth_sql, NULL);
} else {
#endif
if (!(profile->master_db = switch_core_db_open_file(profile->dbname))) {
return 0;
}
switch_core_db_test_reactive(profile->master_db, "select contact from sip_registrations", reg_sql);
switch_core_db_test_reactive(profile->master_db, "select contact from sip_subscriptions", sub_sql);
switch_core_db_test_reactive(profile->master_db, "select * from sip_authentication", auth_sql);
#ifdef SWITCH_HAVE_ODBC
}
#endif
return 1;
}
void sofia_glue_sql_close(sofia_profile_t *profile)
{
#ifdef SWITCH_HAVE_ODBC
if (profile->odbc_dsn) {
switch_odbc_handle_destroy(&profile->master_odbc);
} else {
#endif
switch_core_db_close(profile->master_db);
#ifdef SWITCH_HAVE_ODBC
}
#endif
}
void sofia_glue_execute_sql(sofia_profile_t *profile, switch_bool_t master, char *sql, switch_mutex_t *mutex)
{
switch_core_db_t *db;
@@ -1127,12 +1211,38 @@ void sofia_glue_execute_sql(char *dbname, char *sql, switch_mutex_t * mutex)
switch_mutex_lock(mutex);
}
if (!(db = switch_core_db_open_file(dbname))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB %s\n", dbname);
goto end;
#ifdef SWITCH_HAVE_ODBC
if (profile->odbc_dsn) {
SQLHSTMT stmt;
if (switch_odbc_handle_exec(profile->master_odbc, sql, &stmt) != SWITCH_ODBC_SUCCESS) {
char *err_str;
err_str = switch_odbc_handle_get_error(profile->master_odbc, stmt);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERR: [%s]\n[%s]\n", sql, switch_str_nil(err_str));
switch_safe_free(err_str);
}
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
} else {
#endif
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;
}
}
switch_core_db_persistant_execute(db, sql, 25);
switch_core_db_close(db);
if (!master) {
switch_core_db_close(db);
}
#ifdef SWITCH_HAVE_ODBC
}
#endif
end:
if (mutex) {
@@ -1141,6 +1251,159 @@ void sofia_glue_execute_sql(char *dbname, char *sql, switch_mutex_t * mutex)
}
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_bool_t ret = SWITCH_FALSE;
switch_core_db_t *db;
char *errmsg = NULL;
if (mutex) {
switch_mutex_lock(mutex);
}
#ifdef SWITCH_HAVE_ODBC
if (profile->odbc_dsn) {
switch_odbc_handle_callback_exec(profile->master_odbc, sql, callback, pdata);
} else {
#endif
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;
}
}
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);
}
#ifdef SWITCH_HAVE_ODBC
}
#endif
end:
if (mutex) {
switch_mutex_unlock(mutex);
}
return ret;
}
#ifdef SWITCH_HAVE_ODBC
static char *sofia_glue_execute_sql2str_odbc(sofia_profile_t *profile, switch_mutex_t *mutex, char *sql, char *resbuf, size_t len)
{
char *ret = NULL;
SQLHSTMT stmt;
SQLCHAR name[1024];
SQLINTEGER m = 0;
if (switch_odbc_handle_exec(profile->master_odbc, sql, &stmt) == SWITCH_ODBC_SUCCESS) {
SQLSMALLINT NameLength, DataType, DecimalDigits, Nullable;
SQLUINTEGER ColumnSize;
SQLRowCount(stmt, &m);
if (m <= 0) {
return NULL;
}
if (SQLFetch(stmt) != SQL_SUCCESS) {
return NULL;
}
SQLDescribeCol(stmt, 1, name, sizeof(name), &NameLength, &DataType, &ColumnSize, &DecimalDigits, &Nullable);
SQLGetData(stmt, 1, SQL_C_CHAR, (SQLCHAR *)resbuf, len, NULL);
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
ret = resbuf;
}
return ret;
}
#endif
char *sofia_glue_execute_sql2str(sofia_profile_t *profile, switch_mutex_t *mutex, char *sql, char *resbuf, size_t len)
{
switch_core_db_t *db;
switch_core_db_stmt_t *stmt;
char *ret = NULL;
#ifdef SWITCH_HAVE_ODBC
if (profile->odbc_dsn) {
return sofia_glue_execute_sql2str_odbc(profile, mutex, sql, resbuf, len);
}
#endif
if (mutex) {
switch_mutex_lock(mutex);
}
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 (switch_core_db_prepare(db, sql, -1, &stmt, 0)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Statement Error!\n");
goto fail;
} else {
int running = 1;
int colcount;
while (running < 5000) {
int result = switch_core_db_step(stmt);
if (result == SWITCH_CORE_DB_ROW) {
if ((colcount = switch_core_db_column_count(stmt))) {
switch_copy_string(resbuf, (char *) switch_core_db_column_text(stmt, 0), len);
ret = resbuf;
}
break;
} else if (result == SWITCH_CORE_DB_BUSY) {
running++;
switch_yield(1000);
continue;
}
break;
}
switch_core_db_finalize(stmt);
}
fail:
switch_core_db_close(db);
end:
if (mutex) {
switch_mutex_unlock(mutex);
}
return ret;
}
int sofia_glue_get_user_host(char *in, char **user, char **host)
{
char *p, *h, *u = in;
+77 -103
View File
@@ -105,8 +105,7 @@ switch_status_t sofia_presence_chat_send(char *proto, char *from, char *to, char
void sofia_presence_cancel(void)
{
char *sql, *errmsg = NULL;
switch_core_db_t *db;
char *sql;
sofia_profile_t *profile;
switch_hash_index_t *hi;
void *val;
@@ -120,47 +119,30 @@ void sofia_presence_cancel(void)
continue;
}
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);
if (sofia_glue_execute_sql_callback(profile, SWITCH_FALSE, profile->ireg_mutex, sql, sofia_presence_sub_callback, profile) != SWITCH_TRUE) {
continue;
}
switch_mutex_lock(profile->ireg_mutex);
switch_core_db_exec(db, sql, sofia_presence_sub_callback, profile, &errmsg);
switch_mutex_unlock(profile->ireg_mutex);
switch_core_db_close(db);
}
switch_safe_free(sql);
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
}
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
}
void sofia_presence_establish_presence(sofia_profile_t * profile)
{
char *sql, *errmsg = NULL;
switch_core_db_t *db;
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);
if (sofia_glue_execute_sql_callback(profile, SWITCH_FALSE, profile->ireg_mutex,
"select user,host,'Registered','unknown','' from sip_registrations",
sofia_presence_resub_callback, profile) != SWITCH_TRUE) {
return;
}
if ((sql = switch_mprintf("select user,host,'Registered','unknown','' sip_registrations"))) {
switch_mutex_lock(profile->ireg_mutex);
switch_core_db_exec(db, sql, sofia_presence_resub_callback, profile, &errmsg);
switch_mutex_unlock(profile->ireg_mutex);
switch_safe_free(sql);
if (sofia_glue_execute_sql_callback(profile, SWITCH_FALSE, 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;
}
if ((sql = switch_mprintf("select sub_to_user,sub_to_host,'Online','unknown',proto from sip_subscriptions "
"where proto='ext' or proto='user' or proto='conf'"))) {
switch_mutex_lock(profile->ireg_mutex);
switch_core_db_exec(db, sql, sofia_presence_resub_callback, profile, &errmsg);
switch_mutex_unlock(profile->ireg_mutex);
switch_safe_free(sql);
}
switch_core_db_close(db);
}
@@ -196,9 +178,7 @@ void sofia_presence_mwi_event_handler(switch_event_t *event)
{
char *account, *dup_account, *yn, *host, *user;
char *sql;
switch_core_db_t *db;
sofia_profile_t *profile;
char *errmsg = NULL;
switch_stream_handle_t stream = { 0 };
switch_event_header_t *hp;
@@ -222,13 +202,7 @@ void sofia_presence_mwi_event_handler(switch_event_t *event)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find profile for host %s\n", switch_str_nil(host));
return;
}
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);
return;
}
SWITCH_STANDARD_STREAM(stream);
for (hp = event->headers; hp; hp = hp->next) {
@@ -246,12 +220,14 @@ void sofia_presence_mwi_event_handler(switch_event_t *event)
assert (sql != NULL);
switch_mutex_lock(profile->ireg_mutex);
switch_core_db_exec(db, sql, sofia_presence_mwi_callback, profile, &errmsg);
if (errmsg) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR: %s\n", errmsg);
}
switch_mutex_unlock(profile->ireg_mutex);
sofia_glue_execute_sql_callback(profile,
SWITCH_FALSE,
profile->ireg_mutex,
sql,
sofia_presence_mwi_callback,
profile);
switch_safe_free(sql);
switch_safe_free(dup_account);
}
@@ -269,8 +245,6 @@ void sofia_presence_event_handler(switch_event_t *event)
//char *event_subtype = switch_event_get_header(event, "event_subtype");
char *sql = NULL;
char *euser = NULL, *user = NULL, *host = NULL;
char *errmsg;
switch_core_db_t *db;
if (rpid && !strcasecmp(rpid, "n/a")) {
@@ -310,7 +284,8 @@ void sofia_presence_event_handler(switch_event_t *event)
} else {
sql = switch_mprintf("select 1,'%q','%q',* from sip_subscriptions where event='presence'", status, rpid);
}
assert(sql != NULL);
switch_mutex_lock(mod_sofia_globals.hash_mutex);
for (hi = switch_hash_first(switch_hash_pool_get(mod_sofia_globals.profile_hash), mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, NULL, NULL, &val);
@@ -319,20 +294,18 @@ void sofia_presence_event_handler(switch_event_t *event)
continue;
}
if (sql) {
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);
continue;
}
switch_mutex_lock(profile->ireg_mutex);
switch_core_db_exec(db, sql, sofia_presence_sub_callback, profile, &errmsg);
switch_mutex_unlock(profile->ireg_mutex);
switch_core_db_close(db);
}
sofia_glue_execute_sql_callback(profile,
SWITCH_FALSE,
profile->ireg_mutex,
sql,
sofia_presence_sub_callback,
profile);
}
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
free(sql);
return;
}
@@ -365,7 +338,6 @@ void sofia_presence_event_handler(switch_event_t *event)
switch (event->event_id) {
case SWITCH_EVENT_PRESENCE_PROBE:
if (proto) {
switch_core_db_t *db = NULL;
char *to = switch_event_get_header(event, "to");
char *user, *euser, *host, *p;
@@ -382,23 +354,19 @@ void sofia_presence_event_handler(switch_event_t *event)
}
if (euser && host &&
(sql =
switch_mprintf("select user,host,status,rpid,'' from sip_registrations where user='%q' and host='%q'",
euser, host)) && (profile = sofia_glue_find_profile(host))) {
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);
switch_safe_free(user);
switch_safe_free(sql);
return;
}
(sql = switch_mprintf("select user,host,status,rpid,'' from sip_registrations where user='%q' and host='%q'",
euser, host)) && (profile = sofia_glue_find_profile(host))) {
sofia_glue_execute_sql_callback(profile,
SWITCH_FALSE,
profile->ireg_mutex,
sql,
sofia_presence_resub_callback,
profile);
switch_mutex_lock(profile->ireg_mutex);
switch_core_db_exec(db, sql, sofia_presence_resub_callback, profile, &errmsg);
switch_mutex_unlock(profile->ireg_mutex);
switch_safe_free(sql);
}
switch_safe_free(user);
switch_core_db_close(db);
}
return;
case SWITCH_EVENT_PRESENCE_IN:
@@ -426,15 +394,13 @@ void sofia_presence_event_handler(switch_event_t *event)
}
if (sql) {
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);
continue;
}
switch_mutex_lock(profile->ireg_mutex);
switch_core_db_exec(db, sql, sofia_presence_sub_callback, profile, &errmsg);
switch_mutex_unlock(profile->ireg_mutex);
sofia_glue_execute_sql_callback(profile,
SWITCH_FALSE,
profile->ireg_mutex,
sql,
sofia_presence_sub_callback,
profile);
switch_core_db_close(db);
}
}
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
@@ -665,8 +631,6 @@ void sofia_presence_handle_sip_i_subscribe(int status,
char *to_str = NULL;
char *full_from = NULL;
char *full_via = NULL;
switch_core_db_t *db;
char *errmsg;
char *sstr;
const char *display = "\"user\"";
switch_event_t *sevent;
@@ -762,17 +726,28 @@ void sofia_presence_handle_sip_i_subscribe(int status,
from_host = "n/a";
}
if ((sql = switch_mprintf("delete from sip_subscriptions where "
"proto='%q' and user='%q' and host='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q';\n"
"insert into sip_subscriptions values ('%q','%q','%q','%q','%q','%q','%q','%q','%q','%q',%ld)",
proto,
from_user,
from_host,
to_user,
to_host, event, proto, from_user, from_host, to_user, to_host, event, contact_str, call_id, full_from, full_via, exp))) {
sofia_glue_execute_sql(profile->dbname, sql, profile->ireg_mutex);
switch_safe_free(sql);
}
switch_mutex_lock(profile->ireg_mutex);
sql = switch_mprintf("delete from sip_subscriptions where "
"proto='%q' and user='%q' and host='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q'",
proto,
from_user,
from_host,
to_user,
to_host, event, proto
);
assert(sql != NULL);
sofia_glue_execute_sql(profile, SWITCH_FALSE, sql, NULL);
free(sql);
sql = switch_mprintf("insert into sip_subscriptions values ('%q','%q','%q','%q','%q','%q','%q','%q','%q','%q',%ld)",
proto, from_user, from_host, to_user, to_host, event, contact_str, call_id, full_from, full_via, exp);
assert(sql != NULL);
sofia_glue_execute_sql(profile, SWITCH_FALSE, sql, NULL);
free(sql);
switch_mutex_unlock(profile->ireg_mutex);
sstr = switch_mprintf("active;expires=%ld", exp_raw);
@@ -784,18 +759,17 @@ void sofia_presence_handle_sip_i_subscribe(int status,
switch_safe_free(sstr);
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 ((sql = switch_mprintf("select * from sip_subscriptions where user='%q' and host='%q'", to_user, to_host, to_user, to_host))) {
switch_mutex_lock(profile->ireg_mutex);
switch_core_db_exec(db, sql, sofia_presence_sub_reg_callback, profile, &errmsg);
switch_mutex_unlock(profile->ireg_mutex);
sofia_glue_execute_sql_callback(profile,
SWITCH_FALSE,
profile->ireg_mutex,
sql,
sofia_presence_sub_reg_callback,
profile);
switch_safe_free(sql);
}
switch_core_db_close(db);
end:
end:
if (event) {
su_free(profile->home, event);
@@ -878,7 +852,7 @@ void sofia_presence_handle_sip_i_publish(nua_t * nua, sofia_profile_t * profile,
if ((sql =
switch_mprintf("update sip_registrations set status='%q',rpid='%q' where user='%q' and host='%q'",
note_txt, rpid, from_user, from_host))) {
sofia_glue_execute_sql(profile->dbname, sql, profile->ireg_mutex);
sofia_glue_execute_sql(profile, SWITCH_FALSE, sql, profile->ireg_mutex);
switch_safe_free(sql);
}
+64 -109
View File
@@ -35,7 +35,7 @@
#include "mod_sofia.h"
void sofia_reg_unregister(sofia_profile_t * profile)
void sofia_reg_unregister(sofia_profile_t *profile)
{
outbound_reg_t *gateway_ptr;
for (gateway_ptr = profile->gateways; gateway_ptr; gateway_ptr = gateway_ptr->next) {
@@ -48,7 +48,7 @@ void sofia_reg_unregister(sofia_profile_t * profile)
}
}
void sofia_reg_check_gateway(sofia_profile_t * profile, time_t now)
void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now)
{
outbound_reg_t *gateway_ptr;
for (gateway_ptr = profile->gateways; gateway_ptr; gateway_ptr = gateway_ptr->next) {
@@ -133,73 +133,74 @@ int sofia_reg_del_callback(void *pArg, int argc, char **argv, char **columnNames
return 0;
}
void sofia_reg_check_expire(switch_core_db_t *db, sofia_profile_t * profile, time_t now)
void sofia_reg_check_expire(sofia_profile_t *profile, time_t now)
{
char sql[1024];
char *errmsg;
if (!db) {
#ifdef SWITCH_HAVE_ODBC
if (profile->odbc_dsn) {
if (!profile->master_odbc) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB %s\n", profile->dbname);
return;
}
} else {
#endif
if (!profile->master_db) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB %s\n", profile->dbname);
return;
}
#ifdef SWITCH_HAVE_ODBC
}
#endif
snprintf(sql, sizeof(sql), "select '%s',* from sip_registrations where expires > 0 and expires <= %ld", profile->name, (long) now);
switch_mutex_lock(profile->ireg_mutex);
snprintf(sql, sizeof(sql), "select '%s',* from sip_registrations where expires > 0 and expires < %ld", profile->name, (long) now);
switch_core_db_exec(db, sql, sofia_reg_del_callback, NULL, &errmsg);
if (errmsg) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR [%s][%s]\n", sql, errmsg);
switch_safe_free(errmsg);
errmsg = NULL;
}
snprintf(sql, sizeof(sql), "delete from sip_registrations where expires > 0 and expires < %ld", (long) now);
switch_core_db_persistant_execute(db, sql, 1000);
snprintf(sql, sizeof(sql), "delete from sip_authentication where expires > 0 and expires < %ld", (long) now);
switch_core_db_persistant_execute(db, sql, 1000);
snprintf(sql, sizeof(sql), "delete from sip_subscriptions where expires > 0 and expires < %ld", (long) now);
switch_core_db_persistant_execute(db, sql, 1000);
sofia_glue_execute_sql_callback(profile,
SWITCH_TRUE,
NULL,
sql,
sofia_reg_del_callback,
NULL);
snprintf(sql, sizeof(sql), "delete from sip_registrations where expires > 0 and expires <= %ld", (long) now);
sofia_glue_execute_sql(profile, SWITCH_TRUE, sql, NULL);
snprintf(sql, sizeof(sql), "delete from sip_authentication where expires > 0 and expires <= %ld", (long) now);
sofia_glue_execute_sql(profile, SWITCH_TRUE, sql, NULL);
snprintf(sql, sizeof(sql), "delete from sip_subscriptions where expires > 0 and expires <= %ld", (long) now);
sofia_glue_execute_sql(profile, SWITCH_TRUE, sql, NULL);
switch_mutex_unlock(profile->ireg_mutex);
}
char *sofia_reg_find_reg_url(sofia_profile_t * profile, const char *user, const char *host, char *val, switch_size_t len)
char *sofia_reg_find_reg_url(sofia_profile_t *profile, const char *user, const char *host, char *val, switch_size_t len)
{
char *errmsg;
struct callback_t cbt = { 0 };
switch_core_db_t *db;
if (!user) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Called with null user!\n");
return NULL;
}
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);
return NULL;
}
cbt.val = val;
cbt.len = len;
switch_mutex_lock(profile->ireg_mutex);
if (host) {
snprintf(val, len, "select contact from sip_registrations where user='%s' and host='%s'", user, host);
} else {
snprintf(val, len, "select contact from sip_registrations where user='%s'", user);
}
switch_core_db_exec(db, val, sofia_reg_find_callback, &cbt, &errmsg);
if (errmsg) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR [%s][%s]\n", val, errmsg);
switch_safe_free(errmsg);
errmsg = NULL;
}
sofia_glue_execute_sql_callback(profile,
SWITCH_FALSE,
profile->ireg_mutex,
val,
sofia_reg_find_callback,
&cbt);
switch_mutex_unlock(profile->ireg_mutex);
switch_core_db_close(db);
if (cbt.matches) {
return val;
} else {
@@ -207,73 +208,20 @@ char *sofia_reg_find_reg_url(sofia_profile_t * profile, const char *user, const
}
}
char *sofia_reg_get_auth_data(char *dbname, char *nonce, char *npassword, size_t len, switch_mutex_t * mutex)
static char *sofia_reg_get_auth_data(sofia_profile_t *profile, char *nonce, char *npassword, size_t len, switch_mutex_t *mutex)
{
switch_core_db_t *db;
switch_core_db_stmt_t *stmt;
char *sql = NULL, *ret = NULL;
if (mutex) {
switch_mutex_lock(mutex);
}
if (!dbname) {
goto end;
}
if (!(db = switch_core_db_open_file(dbname))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB %s\n", dbname);
goto end;
}
char *sql, *ret;
sql = switch_mprintf("select passwd from sip_authentication where nonce='%q'", nonce);
if (switch_core_db_prepare(db, sql, -1, &stmt, 0)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Statement Error!\n");
goto fail;
} else {
int running = 1;
int colcount;
assert(sql != NULL);
while (running < 5000) {
int result = switch_core_db_step(stmt);
if (result == SWITCH_CORE_DB_ROW) {
if ((colcount = switch_core_db_column_count(stmt))) {
switch_copy_string(npassword, (char *) switch_core_db_column_text(stmt, 0), len);
ret = npassword;
}
break;
} else if (result == SWITCH_CORE_DB_BUSY) {
running++;
switch_yield(1000);
continue;
}
break;
}
switch_core_db_finalize(stmt);
}
fail:
switch_core_db_close(db);
end:
if (mutex) {
switch_mutex_unlock(mutex);
}
if (sql) {
switch_safe_free(sql);
}
ret = sofia_glue_execute_sql2str(profile, mutex, sql, npassword, len);
free(sql);
return ret;
}
uint8_t sofia_reg_handle_register(nua_t * nua, sofia_profile_t * profile, nua_handle_t * nh, sip_t const *sip, sofia_regtype_t regtype, char *key,
uint8_t sofia_reg_handle_register(nua_t * nua, sofia_profile_t *profile, nua_handle_t * nh, sip_t const *sip, sofia_regtype_t regtype, char *key,
uint32_t keylen)
{
sip_from_t const *from = NULL;
@@ -433,9 +381,18 @@ uint8_t sofia_reg_handle_register(nua_t * nua, sofia_profile_t * profile, nua_ha
a1_hash = hexdigest;
}
sql = switch_mprintf("delete from sip_authentication where user='%q' and host='%q';\n"
"insert into sip_authentication values('%q','%q','%q','%q', %ld)",
from_user, from_host, from_user, from_host, a1_hash, uuid_str, time(NULL) + profile->nonce_ttl);
switch_mutex_lock(profile->ireg_mutex);
sql = switch_mprintf("delete from sip_authentication where user='%q' and host='%q';", from_user, from_host);
assert(sql != NULL);
sofia_glue_execute_sql(profile, SWITCH_FALSE, sql, NULL);
switch_safe_free(sql);
sql = switch_mprintf("insert into sip_authentication values('%q','%q','%q','%q', %ld)",
from_user, from_host, a1_hash, uuid_str, time(NULL) + profile->nonce_ttl);
assert(sql != NULL);
sofia_glue_execute_sql(profile, SWITCH_FALSE, sql, NULL);
switch_safe_free(sql);
switch_mutex_unlock(profile->ireg_mutex);
auth_str =
switch_mprintf("Digest realm=\"%q\", nonce=\"%q\",%s algorithm=MD5, qop=\"auth\"", from_host, uuid_str, stale ? " stale=\"true\"," : "");
@@ -448,8 +405,6 @@ uint8_t sofia_reg_handle_register(nua_t * nua, sofia_profile_t * profile, nua_ha
}
sofia_glue_execute_sql(profile->dbname, sql, profile->ireg_mutex);
switch_safe_free(sql);
switch_safe_free(auth_str);
ret = 1;
} else {
@@ -488,7 +443,7 @@ uint8_t sofia_reg_handle_register(nua_t * nua, sofia_profile_t * profile, nua_ha
}
if (sql) {
sofia_glue_execute_sql(profile->dbname, sql, profile->ireg_mutex);
sofia_glue_execute_sql(profile, SWITCH_FALSE, sql, profile->ireg_mutex);
switch_safe_free(sql);
sql = NULL;
}
@@ -509,7 +464,7 @@ uint8_t sofia_reg_handle_register(nua_t * nua, sofia_profile_t * profile, nua_ha
}
} else {
if ((sql = switch_mprintf("delete from sip_subscriptions where user='%q' and host='%q'", from_user, from_host))) {
sofia_glue_execute_sql(profile->dbname, sql, profile->ireg_mutex);
sofia_glue_execute_sql(profile, SWITCH_FALSE, sql, profile->ireg_mutex);
switch_safe_free(sql);
sql = NULL;
}
@@ -542,7 +497,7 @@ uint8_t sofia_reg_handle_register(nua_t * nua, sofia_profile_t * profile, nua_ha
void sofia_reg_handle_sip_i_register(nua_t * nua, sofia_profile_t * profile, nua_handle_t * nh, sofia_private_t * sofia_private, sip_t const *sip, tagi_t tags[])
void sofia_reg_handle_sip_i_register(nua_t * nua, sofia_profile_t *profile, nua_handle_t * nh, sofia_private_t * sofia_private, sip_t const *sip, tagi_t tags[])
{
char key[128] = "";
@@ -564,7 +519,7 @@ void sofia_reg_handle_sip_i_register(nua_t * nua, sofia_profile_t * profile, nua
void sofia_reg_handle_sip_r_register(int status,
char const *phrase,
nua_t * nua, sofia_profile_t * profile, nua_handle_t * nh, sofia_private_t * sofia_private, sip_t const *sip, tagi_t tags[])
nua_t * nua, sofia_profile_t *profile, nua_handle_t * nh, sofia_private_t * sofia_private, sip_t const *sip, tagi_t tags[])
{
if (sofia_private && sofia_private->gateway) {
switch (status) {
@@ -594,7 +549,7 @@ void sofia_reg_handle_sip_r_register(int status,
void sofia_reg_handle_sip_r_challenge(int status,
char const *phrase,
nua_t * nua, sofia_profile_t * profile, nua_handle_t * nh, switch_core_session_t *session, sip_t const *sip, tagi_t tags[])
nua_t * nua, sofia_profile_t *profile, nua_handle_t * nh, switch_core_session_t *session, sip_t const *sip, tagi_t tags[])
{
outbound_reg_t *gateway = NULL;
sip_www_authenticate_t const *authenticate = NULL;
@@ -698,7 +653,7 @@ void sofia_reg_handle_sip_r_challenge(int status,
}
auth_res_t parse_auth(sofia_profile_t * profile, sip_authorization_t const *authorization, const char *regstr, char *np, size_t nplen)
auth_res_t parse_auth(sofia_profile_t *profile, sip_authorization_t const *authorization, const char *regstr, char *np, size_t nplen)
{
int indexnum;
const char *cur;
@@ -758,7 +713,7 @@ auth_res_t parse_auth(sofia_profile_t * profile, sip_authorization_t const *auth
}
if (switch_strlen_zero(np)) {
if (!sofia_reg_get_auth_data(profile->dbname, nonce, np, nplen, profile->ireg_mutex)) {
if (!sofia_reg_get_auth_data(profile, nonce, np, nplen, profile->ireg_mutex)) {
ret = AUTH_STALE;
goto end;
}