diff --git a/ChangeLog b/ChangeLog index 8b07655c..60c00cd8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +12/24/2014 Oleg Moskalenko +Version 4.3.3.1 'Tolomei': + - multiple authentication threads; + - database code cleaned; + 12/14/2014 Oleg Moskalenko Version 4.3.2.2 'Tolomei': - Redis read message queue bug fixed; diff --git a/rpm/build.settings.sh b/rpm/build.settings.sh index 096912ff..ffff3cb7 100755 --- a/rpm/build.settings.sh +++ b/rpm/build.settings.sh @@ -2,7 +2,7 @@ # Common settings script. -TURNVERSION=4.3.2.2 +TURNVERSION=4.3.3.1 BUILDDIR=~/rpmbuild ARCH=`uname -p` TURNSERVER_SVN_URL=http://coturn.googlecode.com/svn diff --git a/rpm/turnserver.spec b/rpm/turnserver.spec index 3b26a4be..f83d4c98 100644 --- a/rpm/turnserver.spec +++ b/rpm/turnserver.spec @@ -1,5 +1,5 @@ Name: turnserver -Version: 4.3.2.2 +Version: 4.3.3.1 Release: 0%{dist} Summary: Coturn TURN Server @@ -294,6 +294,8 @@ fi %{_includedir}/turn/client/TurnMsgLib.h %changelog +* Wed Dec 24 2014 Oleg Moskalenko + - Sync to 4.3.3.1 * Sun Dec 14 2014 Oleg Moskalenko - Sync to 4.3.2.2 * Sat Nov 29 2014 Oleg Moskalenko diff --git a/src/apps/relay/dbdrivers/dbd_mongo.c b/src/apps/relay/dbdrivers/dbd_mongo.c index cb4d6ad1..f5d4f998 100644 --- a/src/apps/relay/dbdrivers/dbd_mongo.c +++ b/src/apps/relay/dbdrivers/dbd_mongo.c @@ -82,7 +82,7 @@ static MONGO * get_mongodb_connection(void) { persistent_users_db_t * pud = get_persistent_users_db(); - MONGO * mydbconnection = (MONGO *) (pud->connection); + MONGO * mydbconnection = (MONGO *) pthread_getspecific(connection_key); if (!mydbconnection) { mongoc_init(); @@ -111,7 +111,9 @@ static MONGO * get_mongodb_connection(void) { mydbconnection->uri); if (!mydbconnection->database) mydbconnection->database = MONGO_DEFAULT_DB; - pud->connection = mydbconnection; + if(mydbconnection) { + (void) pthread_setspecific(connection_key, mydbconnection); + } TURN_LOG_FUNC( TURN_LOG_LEVEL_INFO, "Opened MongoDB URI <%s>\n", @@ -1172,7 +1174,7 @@ static void mongo_reread_realms(secrets_list_t * realms_list) { /////////////////////////////////////////////////////////////////////////////////////////////////////////// -static turn_dbdriver_t driver = { +static const turn_dbdriver_t driver = { &mongo_get_auth_secrets, &mongo_get_user_key, &mongo_get_user_pwd, @@ -1197,7 +1199,7 @@ static turn_dbdriver_t driver = { &mongo_list_oauth_keys }; -turn_dbdriver_t * get_mongo_dbdriver(void) { +const turn_dbdriver_t * get_mongo_dbdriver(void) { return &driver; } @@ -1205,7 +1207,7 @@ turn_dbdriver_t * get_mongo_dbdriver(void) { #else -turn_dbdriver_t * get_mongo_dbdriver(void) { +const turn_dbdriver_t * get_mongo_dbdriver(void) { return NULL; } diff --git a/src/apps/relay/dbdrivers/dbd_mongo.h b/src/apps/relay/dbdrivers/dbd_mongo.h index 66ed0a07..862881b4 100644 --- a/src/apps/relay/dbdrivers/dbd_mongo.h +++ b/src/apps/relay/dbdrivers/dbd_mongo.h @@ -38,7 +38,7 @@ extern "C" { #endif -turn_dbdriver_t * get_mongo_dbdriver(void); +const turn_dbdriver_t * get_mongo_dbdriver(void); #ifdef __cplusplus } diff --git a/src/apps/relay/dbdrivers/dbd_mysql.c b/src/apps/relay/dbdrivers/dbd_mysql.c index cd5e65f5..37b705b1 100644 --- a/src/apps/relay/dbdrivers/dbd_mysql.c +++ b/src/apps/relay/dbdrivers/dbd_mysql.c @@ -189,14 +189,16 @@ static Myconninfo *MyconninfoParse(char *userdb, char **errmsg) { } static MYSQL *get_mydb_connection(void) { + persistent_users_db_t *pud = get_persistent_users_db(); - MYSQL *mydbconnection = (MYSQL*)(pud->connection); + MYSQL *mydbconnection = (MYSQL*)pthread_getspecific(connection_key); if(mydbconnection) { if(mysql_ping(mydbconnection)) { mysql_close(mydbconnection); mydbconnection=NULL; + (void) pthread_setspecific(connection_key, mydbconnection); } } @@ -238,11 +240,14 @@ static MYSQL *get_mydb_connection(void) { mydbconnection=NULL; } else if(!donot_print_connection_success) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "MySQL DB connection success: %s\n",pud->userdb); + donot_print_connection_success = 1; } } MyconninfoFree(co); } - pud->connection = mydbconnection; + if(mydbconnection) { + (void) pthread_setspecific(connection_key, mydbconnection); + } } return mydbconnection; } @@ -872,7 +877,6 @@ static int mysql_list_realm_options(u08bits *realm) { static void mysql_auth_ping(void * rch) { UNUSED_ARG(rch); - donot_print_connection_success = 1; MYSQL * myc = get_mydb_connection(); if(myc) { char statement[TURN_LONG_STRING_SIZE]; @@ -1063,7 +1067,7 @@ static void mysql_reread_realms(secrets_list_t * realms_list) { /////////////////////////////////////////////////////////////////////////////////////////////////////////// -static turn_dbdriver_t driver = { +static const turn_dbdriver_t driver = { &mysql_get_auth_secrets, &mysql_get_user_key, &mysql_get_user_pwd, @@ -1088,7 +1092,7 @@ static turn_dbdriver_t driver = { &mysql_list_oauth_keys }; -turn_dbdriver_t * get_mysql_dbdriver(void) { +const turn_dbdriver_t * get_mysql_dbdriver(void) { return &driver; } @@ -1096,7 +1100,7 @@ turn_dbdriver_t * get_mysql_dbdriver(void) { #else -turn_dbdriver_t * get_mysql_dbdriver(void) { +const turn_dbdriver_t * get_mysql_dbdriver(void) { return NULL; } diff --git a/src/apps/relay/dbdrivers/dbd_mysql.h b/src/apps/relay/dbdrivers/dbd_mysql.h index 91b15906..b7ba5b89 100644 --- a/src/apps/relay/dbdrivers/dbd_mysql.h +++ b/src/apps/relay/dbdrivers/dbd_mysql.h @@ -38,7 +38,7 @@ extern "C" { #endif -turn_dbdriver_t * get_mysql_dbdriver(void); +const turn_dbdriver_t * get_mysql_dbdriver(void); #ifdef __cplusplus } diff --git a/src/apps/relay/dbdrivers/dbd_pgsql.c b/src/apps/relay/dbdrivers/dbd_pgsql.c index 21e6ff98..c35a3f85 100644 --- a/src/apps/relay/dbdrivers/dbd_pgsql.c +++ b/src/apps/relay/dbdrivers/dbd_pgsql.c @@ -40,14 +40,16 @@ static int donot_print_connection_success = 0; static PGconn *get_pqdb_connection(void) { + persistent_users_db_t *pud = get_persistent_users_db(); - PGconn *pqdbconnection = (PGconn*)(pud->connection); + PGconn *pqdbconnection = (PGconn*)pthread_getspecific(connection_key); if(pqdbconnection) { ConnStatusType status = PQstatus(pqdbconnection); if(status != CONNECTION_OK) { PQfinish(pqdbconnection); pqdbconnection = NULL; + (void) pthread_setspecific(connection_key, pqdbconnection); } } if(!pqdbconnection) { @@ -75,10 +77,14 @@ static PGconn *get_pqdb_connection(void) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open PostgreSQL DB connection: <%s>, runtime error\n",pud->userdb); } else if(!donot_print_connection_success){ TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "PostgreSQL DB connection success: %s\n",pud->userdb); + donot_print_connection_success = 1; } } } - pud->connection = pqdbconnection; + + if(pqdbconnection) { + (void) pthread_setspecific(connection_key, pqdbconnection); + } } return pqdbconnection; } @@ -628,7 +634,6 @@ static int pgsql_list_realm_options(u08bits *realm) { static void pgsql_auth_ping(void * rch) { UNUSED_ARG(rch); - donot_print_connection_success = 1; PGconn * pqc = get_pqdb_connection(); if(pqc) { char statement[TURN_LONG_STRING_SIZE]; @@ -782,7 +787,7 @@ static void pgsql_reread_realms(secrets_list_t * realms_list) { /////////////////////////////////////////////////////////////////////////////////////////////////////////// -static turn_dbdriver_t driver = { +static const turn_dbdriver_t driver = { &pgsql_get_auth_secrets, &pgsql_get_user_key, &pgsql_get_user_pwd, @@ -807,7 +812,7 @@ static turn_dbdriver_t driver = { &pgsql_list_oauth_keys }; -turn_dbdriver_t * get_pgsql_dbdriver(void) { +const turn_dbdriver_t * get_pgsql_dbdriver(void) { return &driver; } @@ -815,7 +820,7 @@ turn_dbdriver_t * get_pgsql_dbdriver(void) { #else -turn_dbdriver_t * get_pgsql_dbdriver(void) { +const turn_dbdriver_t * get_pgsql_dbdriver(void) { return NULL; } diff --git a/src/apps/relay/dbdrivers/dbd_pgsql.h b/src/apps/relay/dbdrivers/dbd_pgsql.h index 7c36e66e..4ebea436 100644 --- a/src/apps/relay/dbdrivers/dbd_pgsql.h +++ b/src/apps/relay/dbdrivers/dbd_pgsql.h @@ -38,7 +38,7 @@ extern "C" { #endif -turn_dbdriver_t * get_pgsql_dbdriver(void); +const turn_dbdriver_t * get_pgsql_dbdriver(void); #ifdef __cplusplus } diff --git a/src/apps/relay/dbdrivers/dbd_redis.c b/src/apps/relay/dbdrivers/dbd_redis.c index 10feb342..eb54c940 100644 --- a/src/apps/relay/dbdrivers/dbd_redis.c +++ b/src/apps/relay/dbdrivers/dbd_redis.c @@ -161,6 +161,7 @@ static Ryconninfo *RyconninfoParse(const char *userdb, char **errmsg) { } redis_context_handle get_redis_async_connection(struct event_base *base, const char* connection_string, int delete_keys) { + redis_context_handle ret = NULL; char *errmsg = NULL; @@ -253,6 +254,7 @@ redis_context_handle get_redis_async_connection(struct event_base *base, const c TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot initialize Redis DB connection\n"); } else if (is_redis_asyncconn_good(ret) && !donot_print_connection_success) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Redis DB async connection to be used: %s\n", connection_string); + donot_print_connection_success = 1; } RyconninfoFree(co); } @@ -264,14 +266,14 @@ redis_context_handle get_redis_async_connection(struct event_base *base, const c static redisContext *get_redis_connection(void) { persistent_users_db_t *pud = get_persistent_users_db(); - redisContext *redisconnection = (redisContext*)(pud->connection); + redisContext *redisconnection = (redisContext*)pthread_getspecific(connection_key); if(redisconnection) { if(redisconnection->err) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Cannot connect to redis, err=%d, flags=0x%lx\n", __FUNCTION__,(int)redisconnection->err,(unsigned long)redisconnection->flags); redisFree(redisconnection); - pud->connection = NULL; redisconnection = NULL; + (void) pthread_setspecific(connection_key, redisconnection); } } @@ -347,15 +349,14 @@ static redisContext *get_redis_connection(void) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot initialize Redis DB connection\n"); } else if (!donot_print_connection_success) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Redis DB sync connection success: %s\n", pud->userdb); + donot_print_connection_success = 1; } RyconninfoFree(co); } - pud->connection = redisconnection; - - pud = get_persistent_users_db(); - - redisconnection = (redisContext*)(pud->connection); + if(redisconnection) { + (void) pthread_setspecific(connection_key, redisconnection); + } } return redisconnection; @@ -1025,7 +1026,6 @@ static int redis_list_realm_options(u08bits *realm) { } static void redis_auth_ping(void * rch) { - donot_print_connection_success = 1; redisContext *rc = get_redis_connection(); if(rc) { turnFreeRedisReply(redisCommand(rc, "keys turn/origin/*")); @@ -1205,7 +1205,7 @@ static void redis_reread_realms(secrets_list_t * realms_list) { /////////////////////////////////////////////////////////////////////////////////////////////////////////// -static turn_dbdriver_t driver = { +static const turn_dbdriver_t driver = { &redis_get_auth_secrets, &redis_get_user_key, &redis_get_user_pwd, @@ -1230,7 +1230,7 @@ static turn_dbdriver_t driver = { &redis_list_oauth_keys }; -turn_dbdriver_t * get_redis_dbdriver(void) { +const turn_dbdriver_t * get_redis_dbdriver(void) { return &driver; } @@ -1238,7 +1238,7 @@ turn_dbdriver_t * get_redis_dbdriver(void) { #else -turn_dbdriver_t * get_redis_dbdriver(void) { +const turn_dbdriver_t * get_redis_dbdriver(void) { return NULL; } diff --git a/src/apps/relay/dbdrivers/dbd_redis.h b/src/apps/relay/dbdrivers/dbd_redis.h index 6ba27b9f..85cc2ab8 100644 --- a/src/apps/relay/dbdrivers/dbd_redis.h +++ b/src/apps/relay/dbdrivers/dbd_redis.h @@ -38,7 +38,7 @@ extern "C" { #endif -turn_dbdriver_t * get_redis_dbdriver(void); +const turn_dbdriver_t * get_redis_dbdriver(void); #ifdef __cplusplus } diff --git a/src/apps/relay/dbdrivers/dbd_sqlite.c b/src/apps/relay/dbdrivers/dbd_sqlite.c index 0646bfaa..dff544d8 100644 --- a/src/apps/relay/dbdrivers/dbd_sqlite.c +++ b/src/apps/relay/dbdrivers/dbd_sqlite.c @@ -40,17 +40,73 @@ #include #include -/////////////////////////////////////////////////////////////////////////////////////////////////////////// +#include + +////////////////////////////////////////////////// + +static pthread_mutex_t rc_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t rc_cond = PTHREAD_COND_INITIALIZER; + +static int read_threads = 0; +static int write_level = 0; +static pthread_t write_thread = 0; + +static void sqlite_lock(int write) +{ + pthread_t pths = pthread_self(); + + int can_move = 0; + while (!can_move) { + pthread_mutex_lock(&rc_mutex); + if (write) { + if (((write_thread == 0) && (read_threads < 1)) || (write_thread == pths)) { + can_move = 1; + ++write_level; + write_thread = pths; + } + } else { + if ((!write_thread) || (write_thread == pths)) { + can_move = 1; + ++read_threads; + } + } + if (!can_move) { + pthread_cond_wait(&rc_cond, &rc_mutex); + } + pthread_mutex_unlock(&rc_mutex); + } +} + +static void sqlite_unlock(int write) +{ + pthread_mutex_lock(&rc_mutex); + if (write) { + if (!(--write_level)) { + write_thread = 0; + pthread_cond_broadcast(&rc_cond); + } + } else { + if (!(--read_threads)) { + pthread_cond_broadcast(&rc_cond); + } + } + pthread_mutex_unlock(&rc_mutex); +} + +////////////////////////////////////////////////// static int sqlite_init_multithreaded(void) { sqlite3_shutdown(); if (sqlite3_threadsafe() > 0) { - int retCode = sqlite3_config(SQLITE_CONFIG_SERIALIZED); + int retCode = sqlite3_config(SQLITE_CONFIG_MULTITHREAD); if (retCode != SQLITE_OK) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "setting sqlite thread safe mode to serialized failed!!! return code: %d\n", retCode); - return -1; + retCode = sqlite3_config(SQLITE_CONFIG_SERIALIZED); + if (retCode != SQLITE_OK) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "setting sqlite thread safe mode to serialized failed!!! return code: %d\n", retCode); + return -1; + } } } else { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Your SQLite database is not compiled to be threadsafe.\n"); @@ -119,7 +175,7 @@ static sqlite3 * get_sqlite_connection(void) { persistent_users_db_t *pud = get_persistent_users_db(); - sqlite3 *sqliteconnection = (sqlite3 *)(pud->connection); + sqlite3 *sqliteconnection = (sqlite3 *)pthread_getspecific(connection_key); if(!sqliteconnection) { fix_user_directory(pud->userdb); sqlite_init_multithreaded(); @@ -135,8 +191,11 @@ static sqlite3 * get_sqlite_connection(void) { } else if(!donot_print_connection_success){ init_sqlite_database(sqliteconnection); TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "SQLite DB connection success: %s\n",pud->userdb); + donot_print_connection_success = 1; + } + if(sqliteconnection) { + (void) pthread_setspecific(connection_key, sqliteconnection); } - pud->connection = sqliteconnection; } return sqliteconnection; } @@ -152,6 +211,9 @@ static int sqlite_get_auth_secrets(secrets_list_t *sl, u08bits *realm) sqlite3_stmt *st = NULL; int rc = 0; snprintf(statement, sizeof(statement) - 1, "select value from turn_secret where realm='%s'", realm); + + sqlite_lock(0); + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { int ctotal = sqlite3_column_count(st); @@ -180,6 +242,8 @@ static int sqlite_get_auth_secrets(secrets_list_t *sl, u08bits *realm) TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); } sqlite3_finalize(st); + + sqlite_unlock(0); } return ret; } @@ -193,6 +257,9 @@ static int sqlite_get_user_key(u08bits *usname, u08bits *realm, hmackey_t key) sqlite3_stmt *st = NULL; int rc = 0; snprintf(statement, sizeof(statement), "select hmackey from turnusers_lt where name='%s' and realm='%s'", usname, realm); + + sqlite_lock(0); + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { int res = sqlite3_step(st); if (res == SQLITE_ROW) { @@ -211,6 +278,8 @@ static int sqlite_get_user_key(u08bits *usname, u08bits *realm, hmackey_t key) } sqlite3_finalize(st); + + sqlite_unlock(0); } return ret; } @@ -225,6 +294,9 @@ static int sqlite_get_user_pwd(u08bits *usname, st_password_t pwd) sqlite3 *sqliteconnection = get_sqlite_connection(); if (sqliteconnection) { + + sqlite_lock(0); + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { int res = sqlite3_step(st); if (res == SQLITE_ROW) { @@ -242,6 +314,8 @@ static int sqlite_get_user_pwd(u08bits *usname, st_password_t pwd) } sqlite3_finalize(st); + + sqlite_unlock(0); } return ret; } @@ -258,6 +332,8 @@ static int sqlite_get_oauth_key(const u08bits *kid, oauth_key_data_raw *key) { sqlite3 *sqliteconnection = get_sqlite_connection(); if(sqliteconnection) { + sqlite_lock(0); + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { int res = sqlite3_step(st); @@ -280,6 +356,8 @@ static int sqlite_get_oauth_key(const u08bits *kid, oauth_key_data_raw *key) { } sqlite3_finalize(st); + + sqlite_unlock(0); } return ret; @@ -302,6 +380,8 @@ static int sqlite_list_oauth_keys(void) { sqlite3 *sqliteconnection = get_sqlite_connection(); if(sqliteconnection) { + sqlite_lock(0); + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { ret = 0; @@ -338,6 +418,8 @@ static int sqlite_list_oauth_keys(void) { } sqlite3_finalize(st); + + sqlite_unlock(0); } return ret; @@ -355,6 +437,8 @@ static int sqlite_set_user_key(u08bits *usname, u08bits *realm, const char *key) sqlite3 *sqliteconnection = get_sqlite_connection(); if (sqliteconnection) { + sqlite_lock(1); + snprintf(statement, sizeof(statement), "insert or replace into turnusers_lt (realm,name,hmackey) values('%s','%s','%s')", realm, usname, key); if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { @@ -365,6 +449,8 @@ static int sqlite_set_user_key(u08bits *usname, u08bits *realm, const char *key) TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); } sqlite3_finalize(st); + + sqlite_unlock(1); } return ret; } @@ -388,6 +474,8 @@ static int sqlite_set_oauth_key(oauth_key_data_raw *key) key->kid, key->ikm_key, (unsigned long long) key->timestamp, (unsigned long) key->lifetime, key->hkdf_hash_func, key->as_rs_alg, key->as_rs_key, key->auth_alg, key->auth_key); + sqlite_lock(1); + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { sqlite3_step(st); ret = 0; @@ -396,6 +484,8 @@ static int sqlite_set_oauth_key(oauth_key_data_raw *key) TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); } sqlite3_finalize(st); + + sqlite_unlock(1); } return ret; } @@ -412,6 +502,9 @@ static int sqlite_set_user_pwd(u08bits *usname, st_password_t pwd) sqlite3 *sqliteconnection = get_sqlite_connection(); if (sqliteconnection) { snprintf(statement, sizeof(statement), "insert or replace into turnusers_st values('%s','%s')", usname, pwd); + + sqlite_lock(1); + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { sqlite3_step(st); ret = 0; @@ -420,6 +513,8 @@ static int sqlite_set_user_pwd(u08bits *usname, st_password_t pwd) TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); } sqlite3_finalize(st); + + sqlite_unlock(1); } return ret; } @@ -440,6 +535,9 @@ static int sqlite_del_user(u08bits *usname, int is_st, u08bits *realm) } else { snprintf(statement, sizeof(statement), "delete from turnusers_lt where name='%s' and realm='%s'", usname, realm); } + + sqlite_lock(1); + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { sqlite3_step(st); ret = 0; @@ -448,6 +546,8 @@ static int sqlite_del_user(u08bits *usname, int is_st, u08bits *realm) TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); } sqlite3_finalize(st); + + sqlite_unlock(1); } return ret; } @@ -463,8 +563,11 @@ static int sqlite_del_oauth_key(const u08bits *kid) sqlite3 *sqliteconnection = get_sqlite_connection(); if (sqliteconnection) { + snprintf(statement, sizeof(statement), "delete from oauth_key where kid = '%s'", (const char*) kid); + sqlite_lock(1); + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { sqlite3_step(st); ret = 0; @@ -473,6 +576,8 @@ static int sqlite_del_oauth_key(const u08bits *kid) TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); } sqlite3_finalize(st); + + sqlite_unlock(1); } return ret; } @@ -496,6 +601,9 @@ static int sqlite_list_users(int is_st, u08bits *realm) } else { snprintf(statement, sizeof(statement), "select name,realm from turnusers_lt order by name"); } + + sqlite_lock(0); + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { ret = 0; @@ -526,6 +634,8 @@ static int sqlite_list_users(int is_st, u08bits *realm) TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); } sqlite3_finalize(st); + + sqlite_unlock(0); } return ret; } @@ -542,6 +652,9 @@ static int sqlite_show_secret(u08bits *realm) sqlite3 *sqliteconnection = get_sqlite_connection(); if(sqliteconnection) { + + sqlite_lock(0); + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { int res = sqlite3_step(st); if (res == SQLITE_ROW) { @@ -556,6 +669,8 @@ static int sqlite_show_secret(u08bits *realm) TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); } sqlite3_finalize(st); + + sqlite_unlock(0); } return ret; } @@ -575,6 +690,8 @@ static int sqlite_del_secret(u08bits *secret, u08bits *realm) else snprintf(statement,sizeof(statement),"delete from turn_secret where value='%s' and realm='%s'",secret,realm); + sqlite_lock(1); + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { sqlite3_step(st); ret = 0; @@ -583,6 +700,8 @@ static int sqlite_del_secret(u08bits *secret, u08bits *realm) TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); } sqlite3_finalize(st); + + sqlite_unlock(1); } return ret; } @@ -597,7 +716,11 @@ static int sqlite_set_secret(u08bits *secret, u08bits *realm) sqlite3 *sqliteconnection = get_sqlite_connection(); if (sqliteconnection) { + snprintf(statement,sizeof(statement),"insert or replace into turn_secret (realm,value) values('%s','%s')",realm,secret); + + sqlite_lock(1); + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { sqlite3_step(st); ret = 0; @@ -606,6 +729,8 @@ static int sqlite_set_secret(u08bits *secret, u08bits *realm) TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); } sqlite3_finalize(st); + + sqlite_unlock(1); } return ret; } @@ -621,6 +746,9 @@ static int sqlite_add_origin(u08bits *origin, u08bits *realm) sqlite3 *sqliteconnection = get_sqlite_connection(); if(sqliteconnection) { snprintf(statement,sizeof(statement),"insert or replace into turn_origin_to_realm (origin,realm) values('%s','%s')",origin,realm); + + sqlite_lock(1); + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { sqlite3_step(st); ret = 0; @@ -629,6 +757,8 @@ static int sqlite_add_origin(u08bits *origin, u08bits *realm) TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); } sqlite3_finalize(st); + + sqlite_unlock(1); } return ret; } @@ -644,6 +774,9 @@ static int sqlite_del_origin(u08bits *origin) sqlite3 *sqliteconnection = get_sqlite_connection(); if(sqliteconnection) { snprintf(statement,sizeof(statement),"delete from turn_origin_to_realm where origin='%s'",origin); + + sqlite_lock(1); + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { sqlite3_step(st); ret = 0; @@ -652,6 +785,8 @@ static int sqlite_del_origin(u08bits *origin) TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); } sqlite3_finalize(st); + + sqlite_unlock(1); } return ret; } @@ -671,6 +806,9 @@ static int sqlite_list_origins(u08bits *realm) } else { snprintf(statement, sizeof(statement), "select origin,realm from turn_origin_to_realm order by origin,realm"); } + + sqlite_lock(0); + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { ret = 0; @@ -697,6 +835,8 @@ static int sqlite_list_origins(u08bits *realm) TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); } sqlite3_finalize(st); + + sqlite_unlock(0); } return ret; } @@ -713,6 +853,9 @@ static int sqlite_set_realm_option_one(u08bits *realm, unsigned long value, cons if(sqliteconnection) { if(value>0) { snprintf(statement,sizeof(statement),"insert or replace into turn_realm_option (realm,opt,value) values('%s','%s','%lu')",realm,opt,(unsigned long)value); + + sqlite_lock(1); + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { sqlite3_step(st); ret = 0; @@ -721,6 +864,8 @@ static int sqlite_set_realm_option_one(u08bits *realm, unsigned long value, cons TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); } sqlite3_finalize(st); + + sqlite_unlock(1); } } return ret; @@ -741,6 +886,9 @@ static int sqlite_list_realm_options(u08bits *realm) } else { snprintf(statement, sizeof(statement), "select realm,opt,value from turn_realm_option order by realm,opt"); } + + sqlite_lock(0); + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { ret = 0; @@ -769,6 +917,8 @@ static int sqlite_list_realm_options(u08bits *realm) TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); } sqlite3_finalize(st); + + sqlite_unlock(0); } return ret; } @@ -788,6 +938,9 @@ static int sqlite_get_ip_list(const char *kind, ip_range_list_t * list) sqlite3_stmt *st = NULL; int rc = 0; snprintf(statement, sizeof(statement), "select ip_range,realm from %s_peer_ip", kind); + + sqlite_lock(0); + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { ret = 0; @@ -815,6 +968,8 @@ static int sqlite_get_ip_list(const char *kind, ip_range_list_t * list) TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); } sqlite3_finalize(st); + + sqlite_unlock(0); } return ret; } @@ -828,6 +983,9 @@ static void sqlite_reread_realms(secrets_list_t * realms_list) int rc = 0; { snprintf(statement,sizeof(statement),"select origin,realm from turn_origin_to_realm"); + + sqlite_lock(0); + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { ur_string_map *o_to_realm_new = ur_string_map_create(turn_free_simple); @@ -861,6 +1019,8 @@ static void sqlite_reread_realms(secrets_list_t * realms_list) TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); } sqlite3_finalize(st); + + sqlite_unlock(0); } { @@ -893,6 +1053,8 @@ static void sqlite_reread_realms(secrets_list_t * realms_list) } } + sqlite_lock(0); + snprintf(statement,sizeof(statement),"select realm,opt,value from turn_realm_option"); if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { @@ -930,13 +1092,15 @@ static void sqlite_reread_realms(secrets_list_t * realms_list) TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); } sqlite3_finalize(st); + + sqlite_unlock(0); } } } /////////////////////////////////////////////////////////////////////////////////////////////////////////// -static turn_dbdriver_t driver = { +static const turn_dbdriver_t driver = { &sqlite_get_auth_secrets, &sqlite_get_user_key, &sqlite_get_user_pwd, @@ -963,10 +1127,16 @@ static turn_dbdriver_t driver = { ////////////////////////////////////////////////// -turn_dbdriver_t * get_sqlite_dbdriver(void) { +const turn_dbdriver_t * get_sqlite_dbdriver(void) { return &driver; } ////////////////////////////////////////////////// +#else + +const turn_dbdriver_t * get_sqlite_dbdriver(void) { + return NULL; +} + #endif diff --git a/src/apps/relay/dbdrivers/dbd_sqlite.h b/src/apps/relay/dbdrivers/dbd_sqlite.h index c1e95487..69d4269f 100644 --- a/src/apps/relay/dbdrivers/dbd_sqlite.h +++ b/src/apps/relay/dbdrivers/dbd_sqlite.h @@ -38,7 +38,7 @@ extern "C" { #endif -turn_dbdriver_t * get_sqlite_dbdriver(void); +const turn_dbdriver_t * get_sqlite_dbdriver(void); #ifdef __cplusplus } diff --git a/src/apps/relay/dbdrivers/dbdriver.c b/src/apps/relay/dbdrivers/dbdriver.c index f51ac72a..987666e3 100644 --- a/src/apps/relay/dbdrivers/dbdriver.c +++ b/src/apps/relay/dbdrivers/dbdriver.c @@ -40,7 +40,14 @@ #include "dbd_mongo.h" #include "dbd_redis.h" -static turn_dbdriver_t * _driver; +static void make_connection_key(void) +{ + (void) pthread_key_create(&connection_key, NULL); +} + + +pthread_key_t connection_key; +pthread_once_t connection_key_once = PTHREAD_ONCE_INIT; int convert_string_key_to_binary(char* keysource, hmackey_t key, size_t sz) { char is[3]; @@ -60,13 +67,17 @@ persistent_users_db_t * get_persistent_users_db(void) { return &(turn_params.default_users_db.persistent_users_db); } -turn_dbdriver_t * get_dbdriver() +const turn_dbdriver_t * get_dbdriver() { - if (turn_params.default_users_db.userdb_type == TURN_USERDB_TYPE_UNKNOWN) return NULL; - if (!_driver) { + (void) pthread_once(&connection_key_once, make_connection_key); + + static const turn_dbdriver_t * _driver = NULL; + + if (_driver == NULL) { + switch (turn_params.default_users_db.userdb_type){ #if !defined(TURN_NO_SQLITE) case TURN_USERDB_TYPE_SQLITE: diff --git a/src/apps/relay/dbdrivers/dbdriver.h b/src/apps/relay/dbdrivers/dbdriver.h index 29e8ef20..5118313d 100644 --- a/src/apps/relay/dbdrivers/dbdriver.h +++ b/src/apps/relay/dbdrivers/dbdriver.h @@ -36,12 +36,17 @@ #include "ns_turn_msg_defs_new.h" +#include + #ifdef __cplusplus extern "C" { #endif //////////////////////////////////////////// +extern pthread_key_t connection_key; +extern pthread_once_t connection_key_once; + typedef struct _turn_dbdriver_t { int (*get_auth_secrets)(secrets_list_t *sl, u08bits *realm); int (*get_user_key)(u08bits *usname, u08bits *realm, hmackey_t key); @@ -71,7 +76,7 @@ typedef struct _turn_dbdriver_t { int convert_string_key_to_binary(char* keysource, hmackey_t key, size_t sz); persistent_users_db_t * get_persistent_users_db(void); -turn_dbdriver_t * get_dbdriver(void); +const turn_dbdriver_t * get_dbdriver(void); //////////////////////////////////////////// diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 61768132..26629557 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -110,7 +110,6 @@ NEV_UNKNOWN, LOW_DEFAULT_PORTS_BOUNDARY,HIGH_DEFAULT_PORTS_BOUNDARY,0,0,0,"", 0,NULL,0,NULL,DEFAULT_GENERAL_RELAY_SERVERS_NUMBER,0, ////////////// Auth server ///////////////////////////////////// -{NULL,NULL,NULL,0,NULL}, "","",0, /////////////// AUX SERVERS //////////////// {NULL,0,{0,NULL}},0, @@ -121,8 +120,9 @@ LOW_DEFAULT_PORTS_BOUNDARY,HIGH_DEFAULT_PORTS_BOUNDARY,0,0,0,"", /////////////// MISC PARAMS //////////////// 0,0,0,0,0,SHATYPE_SHA1,':',0,0,TURN_CREDENTIALS_NONE,0,0,0,0,0,0, ///////////// Users DB ////////////// -{ (TURN_USERDB_TYPE)0, {"\0",NULL}, {0,NULL,NULL, {NULL,0}} } - +{ (TURN_USERDB_TYPE)0, {"\0"}, {0,NULL,NULL, {NULL,0}} }, +///////////// CPUs ////////////////// +DEFAULT_CPUS_NUMBER }; //////////////// OpenSSL Init ////////////////////// @@ -1802,14 +1802,14 @@ int main(int argc, char **argv) #if defined(_SC_NPROCESSORS_ONLN) { - long cpus = (long)sysconf(_SC_NPROCESSORS_CONF); + turn_params.cpus = (long)sysconf(_SC_NPROCESSORS_CONF); - if(cpus<1) - cpus = 1; - else if(cpus>MAX_NUMBER_OF_GENERAL_RELAY_SERVERS) - cpus = MAX_NUMBER_OF_GENERAL_RELAY_SERVERS; + if(turn_params.cpusMAX_NUMBER_OF_GENERAL_RELAY_SERVERS) + turn_params.cpus = MAX_NUMBER_OF_GENERAL_RELAY_SERVERS; - turn_params.general_relay_servers_number = (turnserver_id)cpus; + turn_params.general_relay_servers_number = (turnserver_id)turn_params.cpus; } #endif @@ -1884,8 +1884,6 @@ int main(int argc, char **argv) STRCPY(turn_params.default_users_db.persistent_users_db.userdb,DEFAULT_USERDB_FILE); #endif - update_white_and_black_lists(); - argc -= optind; argv += optind; @@ -2336,14 +2334,14 @@ static int pem_password_func(char *buf, int size, int rwflag, void *password) #if ALPN_SUPPORTED -static int ServerALPNCallback(SSL *s, +static int ServerALPNCallback(SSL *ssl, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg) { - UNUSED_ARG(s); + UNUSED_ARG(ssl); UNUSED_ARG(arg); unsigned char sa_len = (unsigned char)strlen(STUN_ALPN); @@ -2360,21 +2358,26 @@ static int ServerALPNCallback(SSL *s, if((!turn_params.no_stun) && (current_len == sa_len) && (memcmp(ptr+1,STUN_ALPN,sa_len)==0)) { *out = ptr+1; *outlen = sa_len; + SSL_set_app_data(ssl,STUN_ALPN); return SSL_TLSEXT_ERR_OK; } if((!turn_params.stun_only) && (current_len == ta_len) && (memcmp(ptr+1,TURN_ALPN,ta_len)==0)) { *out = ptr+1; *outlen = ta_len; + SSL_set_app_data(ssl,TURN_ALPN); return SSL_TLSEXT_ERR_OK; } if((current_len == ha_len) && (memcmp(ptr+1,HTTP_ALPN,ha_len)==0)) { + *out = ptr+1; + *outlen = ta_len; + SSL_set_app_data(ssl,HTTP_ALPN); found_http = 1; } ptr += 1 + current_len; } if(found_http) - return SSL_TLSEXT_ERR_NOACK; + return SSL_TLSEXT_ERR_OK; return SSL_TLSEXT_ERR_NOACK; //??? } diff --git a/src/apps/relay/mainrelay.h b/src/apps/relay/mainrelay.h index b1e7ea42..be020acb 100644 --- a/src/apps/relay/mainrelay.h +++ b/src/apps/relay/mainrelay.h @@ -100,6 +100,8 @@ extern "C" { #define TURNSERVER_ID_BOUNDARY_BETWEEN_TCP_AND_UDP MAX_NUMBER_OF_GENERAL_RELAY_SERVERS #define TURNSERVER_ID_BOUNDARY_BETWEEN_UDP_AND_TCP TURNSERVER_ID_BOUNDARY_BETWEEN_TCP_AND_UDP +#define DEFAULT_CPUS_NUMBER (2) + /////////// TYPES /////////////////////////////////// enum _DH_KEY_SIZE { @@ -160,16 +162,6 @@ enum _NET_ENG_VERSION { typedef enum _NET_ENG_VERSION NET_ENG_VERSION; -////////////// Auth Server Types //////////////// - -struct auth_server { - struct event_base* event_base; - struct bufferevent *in_buf; - struct bufferevent *out_buf; - pthread_t thr; - redis_context_handle rch; -}; - /////////// PARAMS ////////////////////////////////// typedef struct _turn_params_ { @@ -275,7 +267,6 @@ typedef struct _turn_params_ { ////////////// Auth server //////////////// - struct auth_server authserver; char oauth_server_name[1025]; char domain[1025]; int oauth; @@ -315,6 +306,10 @@ typedef struct _turn_params_ { default_users_db_t default_users_db; +/////// CPUs ////////////// + + unsigned long cpus; + } turn_params_t; extern turn_params_t turn_params; diff --git a/src/apps/relay/netengine.c b/src/apps/relay/netengine.c index 081cd77b..7bd1d602 100644 --- a/src/apps/relay/netengine.c +++ b/src/apps/relay/netengine.c @@ -37,6 +37,23 @@ static unsigned int barrier_count = 0; static pthread_barrier_t barrier; #endif +////////////// Auth Server //////////////// + +typedef unsigned char authserver_id; + +struct auth_server { + authserver_id id; + struct event_base* event_base; + struct bufferevent *in_buf; + struct bufferevent *out_buf; + pthread_t thr; + redis_context_handle rch; +}; + +#define MIN_AUTHSERVER_NUMBER (3) +static authserver_id authserver_number = MIN_AUTHSERVER_NUMBER; +static struct auth_server authserver[256]; + ////////////////////////////////////////////// #define get_real_general_relay_servers_number() (turn_params.general_relay_servers_number > 1 ? turn_params.general_relay_servers_number : 1) @@ -354,9 +371,18 @@ static void allocate_relay_addrs_ports(void) { static int handle_relay_message(relay_server_handle rs, struct message_to_relay *sm); +static pthread_mutex_t auth_message_counter_mutex = PTHREAD_MUTEX_INITIALIZER; +static authserver_id auth_message_counter = 1; + void send_auth_message_to_auth_server(struct auth_message *am) { - struct evbuffer *output = bufferevent_get_output(turn_params.authserver.out_buf); + pthread_mutex_lock(&auth_message_counter_mutex); + if(auth_message_counter>=authserver_number) auth_message_counter = 1; + else if(auth_message_counter<1) auth_message_counter = 1; + authserver_id sn = auth_message_counter++; + pthread_mutex_unlock(&auth_message_counter_mutex); + + struct evbuffer *output = bufferevent_get_output(authserver[sn].out_buf); if(evbuffer_add(output,am,sizeof(struct auth_message))<0) { fprintf(stderr,"%s: Weird buffer error\n",__FUNCTION__); } @@ -1689,48 +1715,65 @@ static void* run_auth_server_thread(void *arg) { ignore_sigpipe(); - ns_bzero(&turn_params.authserver,sizeof(struct auth_server)); + struct auth_server *as = (struct auth_server*)arg; - turn_params.authserver.event_base = turn_event_base_new(); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"IO method (auth thread): %s\n",event_base_get_method(turn_params.authserver.event_base)); + authserver_id id = as->id; - struct bufferevent *pair[2]; + if(id == 0) { - bufferevent_pair_new(turn_params.authserver.event_base, TURN_BUFFEREVENTS_OPTIONS, pair); - turn_params.authserver.in_buf = pair[0]; - turn_params.authserver.out_buf = pair[1]; - bufferevent_setcb(turn_params.authserver.in_buf, auth_server_receive_message, NULL, NULL, &turn_params.authserver); - bufferevent_enable(turn_params.authserver.in_buf, EV_READ); + reread_realms(); + update_white_and_black_lists(); + + barrier_wait(); + + while(run_auth_server_flag) { +#if defined(DB_TEST) + run_db_test(); +#endif + sleep(5); + reread_realms(); + update_white_and_black_lists(); + } + + } else { + + ns_bzero(as,sizeof(struct auth_server)); + + as->id = id; + + as->event_base = turn_event_base_new(); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"IO method (auth thread): %s\n",event_base_get_method(as->event_base)); + + struct bufferevent *pair[2]; + + bufferevent_pair_new(as->event_base, TURN_BUFFEREVENTS_OPTIONS, pair); + as->in_buf = pair[0]; + as->out_buf = pair[1]; + bufferevent_setcb(as->in_buf, auth_server_receive_message, NULL, NULL, as); + bufferevent_enable(as->in_buf, EV_READ); #if !defined(TURN_NO_HIREDIS) - turn_params.authserver.rch = get_redis_async_connection(turn_params.authserver.event_base, turn_params.redis_statsdb, 1); + as->rch = get_redis_async_connection(as->event_base, turn_params.redis_statsdb, 1); #endif - struct auth_server *authserver = &turn_params.authserver; - struct event_base *eb = authserver->event_base; + barrier_wait(); - barrier_wait(); - - while(run_auth_server_flag) { - reread_realms(); - run_events(eb,NULL); - update_white_and_black_lists(); - auth_ping(authserver->rch); -#if defined(DB_TEST) - run_db_test(); -#endif + while(run_auth_server_flag) { + auth_ping(as->rch); + run_events(as->event_base,NULL); + } } return arg; } -static void setup_auth_server(void) +static void setup_auth_server(struct auth_server *as) { - if(pthread_create(&(turn_params.authserver.thr), NULL, run_auth_server_thread, NULL)<0) { + if(pthread_create(&(as->thr), NULL, run_auth_server_thread, as)<0) { perror("Cannot create auth thread\n"); exit(-1); } - pthread_detach(turn_params.authserver.thr); + pthread_detach(as->thr); } static void* run_cli_server_thread(void *arg) @@ -1768,11 +1811,15 @@ void setup_server(void) pthread_mutex_init(&mutex_bps, NULL); + authserver_number = 1 + (authserver_id)(turn_params.cpus / 2); + + if(authserver_number < MIN_AUTHSERVER_NUMBER) authserver_number = MIN_AUTHSERVER_NUMBER; + #if !defined(TURN_NO_THREAD_BARRIERS) - /* relay threads plus auth thread plus main listener thread */ + /* relay threads plus auth threads plus main listener thread */ /* udp address listener thread(s) will start later */ - barrier_count = turn_params.general_relay_servers_number+2; + barrier_count = turn_params.general_relay_servers_number+authserver_number+1; if(use_cli) { barrier_count += 1; @@ -1815,7 +1862,14 @@ void setup_server(void) } } - setup_auth_server(); + { + authserver_id sn = 0; + for(sn = 0; sn < authserver_number;++sn) { + authserver[sn].id = sn; + setup_auth_server(&(authserver[sn])); + } + } + if(use_cli) setup_cli_server(); diff --git a/src/apps/relay/userdb.c b/src/apps/relay/userdb.c index 816a99a0..21783953 100644 --- a/src/apps/relay/userdb.c +++ b/src/apps/relay/userdb.c @@ -108,37 +108,37 @@ void create_default_realm() o_to_realm = ur_string_map_create(turn_free_simple); default_realm_params_ptr = &_default_realm_params; realms = ur_string_map_create(NULL); - ur_string_map_lock(realms); + lock_realms(); default_realm_params_ptr->status.alloc_counters = ur_string_map_create(NULL); - ur_string_map_unlock(realms); + unlock_realms(); } void get_default_realm_options(realm_options_t* ro) { if(ro) { - ur_string_map_lock(realms); + lock_realms(); ns_bcopy(&(default_realm_params_ptr->options),ro,sizeof(realm_options_t)); - ur_string_map_unlock(realms); + unlock_realms(); } } void set_default_realm_name(char *realm) { - ur_string_map_lock(realms); + lock_realms(); ur_string_map_value_type value = (ur_string_map_value_type)default_realm_params_ptr; STRCPY(default_realm_params_ptr->options.name,realm); ur_string_map_put(realms, (ur_string_map_key_type)default_realm_params_ptr->options.name, value); add_to_secrets_list(&realms_list, realm); - ur_string_map_unlock(realms); + unlock_realms(); } realm_params_t* get_realm(char* name) { if(name && name[0]) { - ur_string_map_lock(realms); + lock_realms(); ur_string_map_value_type value = 0; ur_string_map_key_type key = (ur_string_map_key_type)name; if (ur_string_map_get(realms, key, &value)) { - ur_string_map_unlock(realms); + unlock_realms(); return (realm_params_t*)value; } else { realm_params_t *ret = (realm_params_t*)turn_malloc(sizeof(realm_params_t)); @@ -148,7 +148,7 @@ realm_params_t* get_realm(char* name) ur_string_map_put(realms, key, value); ret->status.alloc_counters = ur_string_map_create(NULL); add_to_secrets_list(&realms_list, name); - ur_string_map_unlock(realms); + unlock_realms(); return ret; } } @@ -158,9 +158,9 @@ realm_params_t* get_realm(char* name) int get_realm_data(char* name, realm_params_t* rp) { - ur_string_map_lock(realms); + lock_realms(); ns_bcopy(get_realm(name),rp,sizeof(realm_params_t)); - ur_string_map_unlock(realms); + unlock_realms(); return 0; } @@ -193,20 +193,20 @@ void get_realm_options_by_name(char *realm, realm_options_t* ro) int change_total_quota(char *realm, int value) { int ret = value; - ur_string_map_lock(realms); + lock_realms(); realm_params_t* rp = get_realm(realm); rp->options.perf_options.total_quota = value; - ur_string_map_unlock(realms); + unlock_realms(); return ret; } int change_user_quota(char *realm, int value) { int ret = value; - ur_string_map_lock(realms); + lock_realms(); realm_params_t* rp = get_realm(realm); rp->options.perf_options.user_quota = value; - ur_string_map_unlock(realms); + unlock_realms(); return ret; } @@ -302,7 +302,7 @@ void add_to_secrets_list(secrets_list_t *sl, const char* elem) static int get_auth_secrets(secrets_list_t *sl, u08bits *realm) { int ret = -1; - turn_dbdriver_t * dbd = get_dbdriver(); + const turn_dbdriver_t * dbd = get_dbdriver(); clean_secrets_list(sl); @@ -419,7 +419,7 @@ int get_user_key(int in_oauth, int *out_oauth, int *max_session_time, u08bits *u if(len>0 && value) { - turn_dbdriver_t * dbd = get_dbdriver(); + const turn_dbdriver_t * dbd = get_dbdriver(); if (dbd && dbd->get_oauth_key) { @@ -635,7 +635,7 @@ int get_user_key(int in_oauth, int *out_oauth, int *max_session_time, u08bits *u return 0; } - turn_dbdriver_t * dbd = get_dbdriver(); + const turn_dbdriver_t * dbd = get_dbdriver(); if (dbd && dbd->get_user_key) { ret = (*(dbd->get_user_key))(usname, realm, key); } @@ -650,12 +650,12 @@ int get_user_pwd(u08bits *usname, st_password_t pwd) { int ret = -1; - turn_dbdriver_t * dbd = get_dbdriver(); - if (dbd && dbd->get_user_pwd) { - ret = (*dbd->get_user_pwd)(usname, pwd); - } + const turn_dbdriver_t * dbd = get_dbdriver(); + if (dbd && dbd->get_user_pwd) { + ret = (*dbd->get_user_pwd)(usname, pwd); + } - return ret; + return ret; } u08bits *start_user_check(turnserver_id id, turn_credential_type ct, int in_oauth, int *out_oauth, u08bits *usname, u08bits *realm, get_username_resume_cb resume, ioa_net_data *in_buffer, u64bits ctxkey, int *postpone_reply) @@ -792,7 +792,7 @@ int add_user_account(char *user, int dynamic) static int list_users(int is_st, u08bits *realm) { - turn_dbdriver_t * dbd = get_dbdriver(); + const turn_dbdriver_t * dbd = get_dbdriver(); if (dbd && dbd->list_users) { (*dbd->list_users)(is_st, realm); } @@ -804,7 +804,7 @@ static int show_secret(u08bits *realm) { must_set_admin_realm(realm); - turn_dbdriver_t * dbd = get_dbdriver(); + const turn_dbdriver_t * dbd = get_dbdriver(); if (dbd && dbd->show_secret) { (*dbd->show_secret)(realm); } @@ -816,7 +816,7 @@ static int del_secret(u08bits *secret, u08bits *realm) { must_set_admin_realm(realm); - turn_dbdriver_t * dbd = get_dbdriver(); + const turn_dbdriver_t * dbd = get_dbdriver(); if (dbd && dbd->del_secret) { (*dbd->del_secret)(secret, realm); } @@ -833,7 +833,7 @@ static int set_secret(u08bits *secret, u08bits *realm) { del_secret(secret, realm); - turn_dbdriver_t * dbd = get_dbdriver(); + const turn_dbdriver_t * dbd = get_dbdriver(); if (dbd && dbd->set_secret) { (*dbd->set_secret)(secret, realm); } @@ -847,7 +847,7 @@ static int add_origin(u08bits *origin0, u08bits *realm) get_canonic_origin((const char *)origin0, (char *)origin, sizeof(origin)-1); - turn_dbdriver_t * dbd = get_dbdriver(); + const turn_dbdriver_t * dbd = get_dbdriver(); if (dbd && dbd->add_origin) { (*dbd->add_origin)(origin, realm); } @@ -861,7 +861,7 @@ static int del_origin(u08bits *origin0) get_canonic_origin((const char *)origin0, (char *)origin, sizeof(origin)-1); - turn_dbdriver_t * dbd = get_dbdriver(); + const turn_dbdriver_t * dbd = get_dbdriver(); if (dbd && dbd->del_origin) { (*dbd->del_origin)(origin); } @@ -871,7 +871,7 @@ static int del_origin(u08bits *origin0) static int list_origins(u08bits *realm) { - turn_dbdriver_t * dbd = get_dbdriver(); + const turn_dbdriver_t * dbd = get_dbdriver(); if (dbd && dbd->list_origins) { (*dbd->list_origins)(realm); } @@ -884,7 +884,7 @@ static int set_realm_option_one(u08bits *realm, unsigned long value, const char* if(value == (unsigned long)-1) return 0; - turn_dbdriver_t * dbd = get_dbdriver(); + const turn_dbdriver_t * dbd = get_dbdriver(); if (dbd && dbd->set_realm_option_one) { (*dbd->set_realm_option_one)(realm, value, opt); } @@ -902,7 +902,7 @@ static int set_realm_option(u08bits *realm, perf_options_t *po) static int list_realm_options(u08bits *realm) { - turn_dbdriver_t * dbd = get_dbdriver(); + const turn_dbdriver_t * dbd = get_dbdriver(); if (dbd && dbd->list_realm_options) { (*dbd->list_realm_options)(realm); } @@ -984,7 +984,7 @@ int adminuser(u08bits *user, u08bits *realm, u08bits *pwd, u08bits *secret, u08b } } - turn_dbdriver_t * dbd = get_dbdriver(); + const turn_dbdriver_t * dbd = get_dbdriver(); if (ct == TA_PRINT_KEY) { @@ -1020,10 +1020,10 @@ int adminuser(u08bits *user, u08bits *realm, u08bits *pwd, u08bits *secret, u08b void auth_ping(redis_context_handle rch) { - turn_dbdriver_t * dbd = get_dbdriver(); + const turn_dbdriver_t * dbd = get_dbdriver(); if (dbd && dbd->auth_ping) { (*dbd->auth_ping)(rch); - } + } } ///////////////// TEST ///////////////// @@ -1193,7 +1193,7 @@ ip_range_list_t* get_ip_list(const char *kind) ip_range_list_t *ret = (ip_range_list_t*) turn_malloc(sizeof(ip_range_list_t)); ns_bzero(ret,sizeof(ip_range_list_t)); - turn_dbdriver_t * dbd = get_dbdriver(); + const turn_dbdriver_t * dbd = get_dbdriver(); if (dbd && dbd->get_ip_list) { (*dbd->get_ip_list)(kind, ret); } @@ -1285,16 +1285,16 @@ void reread_realms(void) { { realm_params_t* defrp = get_realm(NULL); - ur_string_map_lock(realms); + lock_realms(); defrp->options.perf_options.max_bps = turn_params.max_bps; defrp->options.perf_options.total_quota = turn_params.total_quota; defrp->options.perf_options.user_quota = turn_params.user_quota; - ur_string_map_unlock(realms); + unlock_realms(); } - turn_dbdriver_t * dbd = get_dbdriver(); - if (dbd && dbd->reread_realms) { - (*dbd->reread_realms)(&realms_list); + const turn_dbdriver_t * dbd = get_dbdriver(); + if (dbd && dbd->reread_realms) { + (*dbd->reread_realms)(&realms_list); } } diff --git a/src/apps/relay/userdb.h b/src/apps/relay/userdb.h index 41d37915..1d66a710 100644 --- a/src/apps/relay/userdb.h +++ b/src/apps/relay/userdb.h @@ -158,10 +158,7 @@ typedef struct _ram_users_db_t { } ram_users_db_t; typedef struct _persistent_users_db_t { - char userdb[TURN_LONG_STRING_SIZE]; - void *connection; - } persistent_users_db_t; typedef struct _default_users_db_t diff --git a/src/ns_turn_defs.h b/src/ns_turn_defs.h index bceccf5d..5f591681 100644 --- a/src/ns_turn_defs.h +++ b/src/ns_turn_defs.h @@ -31,7 +31,7 @@ #ifndef __IOADEFS__ #define __IOADEFS__ -#define TURN_SERVER_VERSION "4.3.2.2" +#define TURN_SERVER_VERSION "4.3.3.1" #define TURN_SERVER_VERSION_NAME "Tolomei" #define TURN_SOFTWARE "Coturn-" TURN_SERVER_VERSION " '" TURN_SERVER_VERSION_NAME "'"