diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index c08b09b..c0c0724 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -1338,7 +1338,7 @@ static int adminmain(int argc, char **argv) u08bits pwd[STUN_MAX_PWD_SIZE+1]=""; u08bits secret[AUTH_SECRET_SIZE+1]=""; u08bits origin[STUN_MAX_ORIGIN_SIZE+1]=""; - perf_options_t po = {-1,-1,-1}; + perf_options_t po = {(band_limit_t)-1,-1,-1}; while (((c = getopt_long(argc, argv, ADMIN_OPTIONS, admin_long_options, NULL)) != -1)) { switch (c){ diff --git a/src/apps/relay/netengine.c b/src/apps/relay/netengine.c index 502a89d..9420811 100644 --- a/src/apps/relay/netengine.c +++ b/src/apps/relay/netengine.c @@ -81,13 +81,13 @@ static void barrier_wait_func(const char* func, int line) static pthread_mutex_t mutex_bps; -static band_limit_t allocate_bps(band_limit_t bps, int negative) +static band_limit_t allocate_bps(band_limit_t bps, int positive) { band_limit_t ret = 0; if(bps>0) { pthread_mutex_lock(&mutex_bps); - if(!negative) { + if(positive) { if(turn_params.bps_capacity_allocated < turn_params.bps_capacity) { band_limit_t reserve = turn_params.bps_capacity - turn_params.bps_capacity_allocated; @@ -96,11 +96,12 @@ static band_limit_t allocate_bps(band_limit_t bps, int negative) turn_params.bps_capacity_allocated = turn_params.bps_capacity; } else { ret = bps; - turn_params.bps_capacity_allocated -= ret; + turn_params.bps_capacity_allocated += ret; } } } else { + if(turn_params.bps_capacity_allocated >= bps) { turn_params.bps_capacity_allocated -= bps; ret = turn_params.bps_capacity_allocated; diff --git a/src/apps/relay/ns_ioalib_engine_impl.c b/src/apps/relay/ns_ioalib_engine_impl.c index a797b06..7373ada 100644 --- a/src/apps/relay/ns_ioalib_engine_impl.c +++ b/src/apps/relay/ns_ioalib_engine_impl.c @@ -624,9 +624,11 @@ void delete_ioa_timer(ioa_timer_handle th) static int ioa_socket_check_bandwidth(ioa_socket_handle s, size_t sz, int read) { - if(s && (s->e) && sz && (s->sat == CLIENT_SOCKET) && (s->session)) { + if(s && (s->e) && sz && + ((s->sat == CLIENT_SOCKET) || (s->sat == RELAY_SOCKET) || (s->sat == RELAY_RTCP_SOCKET)) && + (s->session)) { - band_limit_t max_bps = s->session->realm_options.perf_options.max_bps; + band_limit_t max_bps = s->session->bps; if(max_bps<1) return 1; diff --git a/src/apps/relay/turncli.c b/src/apps/relay/turncli.c index 785f54d..6645add 100644 --- a/src/apps/relay/turncli.c +++ b/src/apps/relay/turncli.c @@ -506,6 +506,8 @@ static int print_session(ur_map_key_type key, ur_map_value_type value, void *arg myprintf(cs," TLS method: %s\n",tsi->tls_method); myprintf(cs," TLS cipher: %s\n",tsi->tls_cipher); } + if(tsi->bps) + myprintf(cs," Max throughput: %lu bytes per second\n",(unsigned long)tsi->bps); myprintf(cs," usage: rp=%lu, rb=%lu, sp=%lu, sb=%lu\n",(unsigned long)(tsi->received_packets), (unsigned long)(tsi->received_bytes),(unsigned long)(tsi->sent_packets),(unsigned long)(tsi->sent_bytes)); myprintf(cs," rate: r=%lu, s=%lu, total=%lu (bytes per sec)\n",(unsigned long)(tsi->received_rate), (unsigned long)(tsi->sent_rate),(unsigned long)(tsi->total_rate)); if(tsi->main_peers_size) { diff --git a/src/apps/relay/userdb.c b/src/apps/relay/userdb.c index 12b16d1..7325113 100644 --- a/src/apps/relay/userdb.c +++ b/src/apps/relay/userdb.c @@ -2343,12 +2343,12 @@ static int list_origins(u08bits *realm) return 0; } -static int set_realm_option_one(u08bits *realm, vint value, const char* opt) +static int set_realm_option_one(u08bits *realm, unsigned long value, const char* opt) { UNUSED_ARG(realm); UNUSED_ARG(value); UNUSED_ARG(opt); - if(value<0) + if(value == (unsigned long)-1) return 0; #if !defined(TURN_NO_PQ) if(is_pqsql_userdb()) { @@ -2363,7 +2363,7 @@ static int set_realm_option_one(u08bits *realm, vint value, const char* opt) } } if(value>0) { - snprintf(statement,sizeof(statement),"insert into turn_realm_option (realm,opt,value) values('%s','%s','%d')",realm,opt,(int)value); + snprintf(statement,sizeof(statement),"insert into turn_realm_option (realm,opt,value) values('%s','%s','%lu')",realm,opt,(unsigned long)value); PGresult *res = PQexec(pqc, statement); if(!res || (PQresultStatus(res) != PGRES_COMMAND_OK)) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting realm option information: %s\n",PQerrorMessage(pqc)); @@ -2386,7 +2386,7 @@ static int set_realm_option_one(u08bits *realm, vint value, const char* opt) mysql_query(myc, statement); } if(value>0) { - snprintf(statement,sizeof(statement),"insert into turn_realm_option (realm,opt,value) values('%s','%s','%d')",realm,opt,(int)value); + snprintf(statement,sizeof(statement),"insert into turn_realm_option (realm,opt,value) values('%s','%s','%lu')",realm,opt,(unsigned long)value); int res = mysql_query(myc, statement); if (res) { TURN_LOG_FUNC( @@ -2406,7 +2406,7 @@ static int set_realm_option_one(u08bits *realm, vint value, const char* opt) char s[LONG_STRING_SIZE]; if(value>0) - snprintf(s,sizeof(s),"set turn/realm/%s/%s %d", (char*)realm, opt, (int)value); + snprintf(s,sizeof(s),"set turn/realm/%s/%s %lu", (char*)realm, opt, (unsigned long)value); else snprintf(s,sizeof(s),"del turn/realm/%s/%s", (char*)realm, opt); @@ -2420,9 +2420,9 @@ static int set_realm_option_one(u08bits *realm, vint value, const char* opt) static int set_realm_option(u08bits *realm, perf_options_t *po) { - set_realm_option_one(realm,po->max_bps,"max-bps"); - set_realm_option_one(realm,po->user_quota,"user-quota"); - set_realm_option_one(realm,po->total_quota,"total-quota"); + set_realm_option_one(realm,(unsigned long)po->max_bps,"max-bps"); + set_realm_option_one(realm,(unsigned long)po->user_quota,"user-quota"); + set_realm_option_one(realm,(unsigned long)po->total_quota,"total-quota"); return 0; } @@ -2612,7 +2612,7 @@ int adminuser(u08bits *user, u08bits *realm, u08bits *pwd, u08bits *secret, u08b if(ct == TA_SET_REALM_OPTION) { must_set_admin_realm(realm); - if(!(po && (po->max_bps>=0 || po->total_quota>=0 || po->user_quota>=0))) { + if(!(po && (po->max_bps!=((band_limit_t)-1) || po->total_quota>=0 || po->user_quota>=0))) { fprintf(stderr, "The operation cannot be completed: a realm option must be set.\n"); exit(-1); } @@ -3246,7 +3246,7 @@ int add_ip_list_range(char* range, ip_range_list_t * list) /////////// REALM ////////////// #if !defined(TURN_NO_HIREDIS) -static int set_redis_realm_opt(char *realm, const char* key, vint *value) +static int set_redis_realm_opt(char *realm, const char* key, unsigned long *value) { int found = 0; @@ -3268,7 +3268,7 @@ static int set_redis_realm_opt(char *realm, const char* key, vint *value) TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", rget->type); } else { ur_string_map_lock(realms); - *value = atoi(rget->str); + *value = (unsigned long)atol(rget->str); ur_string_map_unlock(realms); found = 1; } @@ -3371,7 +3371,7 @@ void reread_realms(void) if(rval && oval && vval) { realm_params_t* rp = get_realm(rval); if(!strcmp(oval,"max-bps")) - rp->options.perf_options.max_bps = (vint)atoi(vval); + rp->options.perf_options.max_bps = (band_limit_t)atol(vval); else if(!strcmp(oval,"total-quota")) rp->options.perf_options.total_quota = (vint)atoi(vval); else if(!strcmp(oval,"user-quota")) @@ -3491,7 +3491,7 @@ void reread_realms(void) vval[sz]=0; realm_params_t* rp = get_realm(rval); if(!strcmp(oval,"max-bps")) - rp->options.perf_options.max_bps = (vint)atoi(vval); + rp->options.perf_options.max_bps = (band_limit_t)atol(vval); else if(!strcmp(oval,"total-quota")) rp->options.perf_options.total_quota = (vint)atoi(vval); else if(!strcmp(oval,"user-quota")) @@ -3583,21 +3583,25 @@ void reread_realms(void) for (i = 0; ioptions.perf_options.max_bps))) { + unsigned long value = 0; + if(!set_redis_realm_opt(realm,"max-bps",&value)) { ur_string_map_lock(realms); rp->options.perf_options.max_bps = turn_params.max_bps; ur_string_map_unlock(realms); } - if(!set_redis_realm_opt(realm,"total-quota",&(rp->options.perf_options.total_quota))) { + rp->options.perf_options.max_bps = (band_limit_t)value; + if(!set_redis_realm_opt(realm,"total-quota",&value)) { ur_string_map_lock(realms); rp->options.perf_options.total_quota = turn_params.total_quota; ur_string_map_unlock(realms); } - if(!set_redis_realm_opt(realm,"user-quota",&(rp->options.perf_options.user_quota))) { + rp->options.perf_options.total_quota = (vint)value; + if(!set_redis_realm_opt(realm,"user-quota",&value)) { ur_string_map_lock(realms); rp->options.perf_options.user_quota = turn_params.user_quota; ur_string_map_unlock(realms); } + rp->options.perf_options.user_quota = (vint)value; } } } diff --git a/src/client/ns_turn_msg_defs_new.h b/src/client/ns_turn_msg_defs_new.h index 4ec2a16..57b64c2 100644 --- a/src/client/ns_turn_msg_defs_new.h +++ b/src/client/ns_turn_msg_defs_new.h @@ -58,4 +58,10 @@ typedef enum _SHATYPE SHATYPE; /* <<== SHA AGILITY */ +/* Bandwidth */ + +#define STUN_ATTRIBUTE_NEW_BANDWIDTH (0x8000 + STUN_ATTRIBUTE_BANDWIDTH) + +/* <<== Bandwidth */ + #endif //__LIB_TURN_MSG_DEFS_NEW__ diff --git a/src/server/ns_turn_server.c b/src/server/ns_turn_server.c index 0b345ad..53d996d 100644 --- a/src/server/ns_turn_server.c +++ b/src/server/ns_turn_server.c @@ -132,6 +132,13 @@ static void dec_quota(ts_ur_super_session* ss) ss->quota_used = 0; + if(ss->bps) { + if(((turn_turnserver*)ss->server)->allocate_bps_func) { + ((turn_turnserver*)ss->server)->allocate_bps_func(ss->bps,0); + } + ss->bps = 0; + } + (((turn_turnserver*)ss->server)->raqcb)(ss->username, (u08bits*)ss->realm_options.name); } } @@ -361,6 +368,7 @@ int turn_session_info_copy_from(struct turn_session_info* tsi, ts_ur_super_sessi if(tsi && ss) { tsi->id = ss->id; + tsi->bps = ss->bps; tsi->start_time = ss->start_time; tsi->valid = is_allocation_valid(&(ss->alloc)) && !(ss->to_be_closed) && (ss->quota_used); if(tsi->valid) { @@ -1057,6 +1065,11 @@ static int handle_turn_allocate(turn_turnserver *server, } else { + band_limit_t max_bps = ss->realm_options.perf_options.max_bps; + if(max_bps && server->allocate_bps_func) { + ss->bps = server->allocate_bps_func(max_bps,1); + } + if (create_relay_connection(server, ss, lifetime, af, transport, even_port, in_reservation_token, &out_reservation_token, diff --git a/src/server/ns_turn_server.h b/src/server/ns_turn_server.h index 20fc9de..da24b32 100644 --- a/src/server/ns_turn_server.h +++ b/src/server/ns_turn_server.h @@ -92,7 +92,7 @@ typedef void (*release_allocation_quota_cb)(u08bits *username, u08bits *realm); typedef int (*send_socket_to_relay_cb)(turnserver_id id, u64bits cid, stun_tid *tid, ioa_socket_handle s, int message_integrity, MESSAGE_TO_RELAY_TYPE rmt, ioa_net_data *nd); typedef int (*send_turn_session_info_cb)(struct turn_session_info *tsi); -typedef band_limit_t (*allocate_bps_cb)(band_limit_t bps, int negative); +typedef band_limit_t (*allocate_bps_cb)(band_limit_t bps, int positive); struct _turn_turnserver { diff --git a/src/server/ns_turn_session.h b/src/server/ns_turn_session.h index cd9a8fc..b5e4207 100644 --- a/src/server/ns_turn_session.h +++ b/src/server/ns_turn_session.h @@ -42,9 +42,11 @@ extern "C" { ////////// REALM //////////// +typedef unsigned int band_limit_t; + typedef struct _perf_options_t { - vint max_bps; + band_limit_t max_bps; vint total_quota; vint user_quota; @@ -60,7 +62,6 @@ struct _realm_options_t { //////////////// session info ////////////////////// typedef u64bits turnsession_id; -typedef unsigned int band_limit_t; #define NONCE_MAX_SIZE (NONCE_LENGTH_32BITS*4+1) @@ -150,6 +151,8 @@ struct turn_session_info { /* Realm */ char realm[STUN_MAX_REALM_SIZE+1]; char origin[STUN_MAX_ORIGIN_SIZE + 1]; +/* Bandwidth */ + band_limit_t bps; }; void turn_session_info_init(struct turn_session_info* tsi);