diff --git a/README.turnutils b/README.turnutils index 17550fb..89b592a 100644 --- a/README.turnutils +++ b/README.turnutils @@ -153,6 +153,8 @@ Options with required values: -F Cipher suite for TLS/DTLS. Default value is DEFAULT. +-a Bandwidth for the bandwidth request in ALLOCATE. The default value is zero. + See the examples in the "examples/scripts" directory. ====================================== diff --git a/man/man1/turnadmin.1 b/man/man1/turnadmin.1 index 4151f84..029151f 100644 --- a/man/man1/turnadmin.1 +++ b/man/man1/turnadmin.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "26 May 2014" "" "" +.TH TURN 1 "29 May 2014" "" "" .SH GENERAL INFORMATION \fIturnadmin\fP is a TURN administration tool. This tool can be used to manage diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index ba47a97..395b2df 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "26 May 2014" "" "" +.TH TURN 1 "29 May 2014" "" "" .SH GENERAL INFORMATION The \fBTURN Server\fP project contains the source code of a TURN server and TURN client diff --git a/man/man1/turnutils.1 b/man/man1/turnutils.1 index 20a7235..5e4f324 100644 --- a/man/man1/turnutils.1 +++ b/man/man1/turnutils.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "26 May 2014" "" "" +.TH TURN 1 "29 May 2014" "" "" .SH GENERAL INFORMATION A set of turnutils_* programs provides some utility functionality to be used @@ -244,6 +244,10 @@ TURN REST API. The default value is :. .B \fB\-F\fP Cipher suite for TLS/DTLS. Default value is DEFAULT. +.TP +.B +\fB\-a\fP +Bandwidth for the bandwidth request in ALLOCATE. The default value is zero. .PP See the examples in the "examples/scripts" directory. .PP diff --git a/src/apps/relay/ns_ioalib_engine_impl.c b/src/apps/relay/ns_ioalib_engine_impl.c index 7373ada..ebed646 100644 --- a/src/apps/relay/ns_ioalib_engine_impl.c +++ b/src/apps/relay/ns_ioalib_engine_impl.c @@ -624,7 +624,7 @@ 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 && + if(read && s && (s->e) && sz && ((s->sat == CLIENT_SOCKET) || (s->sat == RELAY_SOCKET) || (s->sat == RELAY_RTCP_SOCKET)) && (s->session)) { diff --git a/src/apps/uclient/mainuclient.c b/src/apps/uclient/mainuclient.c index 8d7e77b..9afa477 100644 --- a/src/apps/uclient/mainuclient.c +++ b/src/apps/uclient/mainuclient.c @@ -93,6 +93,8 @@ int extra_requests = 0; char origin[STUN_MAX_ORIGIN_SIZE+1] = "\0"; +band_limit_t bps = 0; + //////////////// local definitions ///////////////// static char Usage[] = @@ -145,6 +147,7 @@ static char Usage[] = " -W TURN REST API authentication secret. Is not compatible with -A option.\n" " -C TURN REST API timestamp/username separator symbol (character). The default value is ':'.\n" " -F Cipher suite for TLS/DTLS. Default value is DEFAULT.\n" + " -a Bandwidth for the bandwidth request in ALLOCATE. The default value is zero.\n" " -o - the ORIGIN STUN attribute value.\n"; ////////////////////////////////////////////////// @@ -198,8 +201,11 @@ int main(int argc, char **argv) ns_bzero(local_addr, sizeof(local_addr)); - while ((c = getopt(argc, argv, "d:p:l:n:L:m:e:r:u:w:i:k:z:W:C:E:F:o:vsyhcxXgtTSAPDNOUHMRIGB")) != -1) { + while ((c = getopt(argc, argv, "a:d:p:l:n:L:m:e:r:u:w:i:k:z:W:C:E:F:o:vsyhcxXgtTSAPDNOUHMRIGB")) != -1) { switch (c){ + case 'a': + bps = (band_limit_t)atol(optarg); + break; case 'o': STRCPY(origin,optarg); break; diff --git a/src/apps/uclient/startuclient.c b/src/apps/uclient/startuclient.c index 825478e..171ad97 100644 --- a/src/apps/uclient/startuclient.c +++ b/src/apps/uclient/startuclient.c @@ -339,6 +339,10 @@ static int clnet_allocate(int verbose, stun_set_allocate_request(&message, 800, af, relay_transport, mobility); else stun_set_allocate_request(&message, 300, af, relay_transport, mobility); + + if(bps) + stun_attr_add_bandwidth_str(message.buf, (size_t*)(&(message.len)), bps); + if(dont_fragment) stun_attr_add(&message, STUN_ATTRIBUTE_DONT_FRAGMENT, NULL, 0); if(!no_rtcp) { diff --git a/src/apps/uclient/uclient.h b/src/apps/uclient/uclient.h index 93e595b..6c3bad3 100644 --- a/src/apps/uclient/uclient.h +++ b/src/apps/uclient/uclient.h @@ -81,6 +81,7 @@ extern SHATYPE shatype; extern int mobility; extern int no_permissions; extern int extra_requests; +extern band_limit_t bps; extern char origin[STUN_MAX_ORIGIN_SIZE+1]; diff --git a/src/client/ns_turn_msg.c b/src/client/ns_turn_msg.c index 955a240..b5d69d9 100644 --- a/src/client/ns_turn_msg.c +++ b/src/client/ns_turn_msg.c @@ -944,6 +944,17 @@ u16bits stun_attr_get_channel_number(stun_attr_ref attr) { return 0; } +band_limit_t stun_attr_get_bandwidth(stun_attr_ref attr) { + if(attr) { + const u08bits* value = stun_attr_get_value(attr); + if(value && (stun_attr_get_len(attr) >= 4)) { + u32bits bps=nswap32(((const u32bits*)value)[0]); + return (band_limit_t)(bps << 7); + } + } + return 0; +} + u64bits stun_attr_get_reservation_token_value(stun_attr_ref attr) { if(attr) { const u08bits* value = stun_attr_get_value(attr); @@ -1150,6 +1161,15 @@ int stun_attr_add_channel_number_str(u08bits* buf, size_t *len, u16bits chnumber return stun_attr_add_str(buf,len,STUN_ATTRIBUTE_CHANNEL_NUMBER,(u08bits*)(field),sizeof(field)); } +int stun_attr_add_bandwidth_str(u08bits* buf, size_t *len, band_limit_t bps0) { + + u32bits bps = (band_limit_t)(bps0 >> 7); + + u32bits field=nswap32(bps); + + return stun_attr_add_str(buf,len,STUN_ATTRIBUTE_NEW_BANDWIDTH,(u08bits*)(&field),sizeof(field)); +} + u16bits stun_attr_get_first_channel_number_str(const u08bits *buf, size_t len) { stun_attr_ref attr=stun_attr_get_first_str(buf,len); diff --git a/src/client/ns_turn_msg.h b/src/client/ns_turn_msg.h index 4a684f5..33cb956 100644 --- a/src/client/ns_turn_msg.h +++ b/src/client/ns_turn_msg.h @@ -68,6 +68,7 @@ typedef u08bits hmackey_t[64]; */ #define SHORT_TERM_PASSWORD_SIZE (512) typedef u08bits st_password_t[SHORT_TERM_PASSWORD_SIZE+1]; +typedef unsigned int band_limit_t; /////////////////////////////////// @@ -140,6 +141,7 @@ int stun_attr_get_type(stun_attr_ref attr); int stun_attr_get_len(stun_attr_ref attr); const u08bits* stun_attr_get_value(stun_attr_ref attr); u16bits stun_attr_get_channel_number(stun_attr_ref attr); +band_limit_t stun_attr_get_bandwidth(stun_attr_ref attr); u08bits stun_attr_get_even_port(stun_attr_ref attr); u64bits stun_attr_get_reservation_token_value(stun_attr_ref attr); stun_attr_ref stun_attr_get_first_by_type_str(const u08bits* buf, size_t len, u16bits attr_type); @@ -150,6 +152,7 @@ int stun_attr_add_addr_str(u08bits *buf, size_t *len, u16bits attr_type, const i int stun_attr_get_addr_str(const u08bits *buf, size_t len, stun_attr_ref attr, ioa_addr* ca, const ioa_addr *default_addr); int stun_attr_get_first_addr_str(const u08bits *buf, size_t len, u16bits attr_type, ioa_addr* ca, const ioa_addr *default_addr); int stun_attr_add_channel_number_str(u08bits* buf, size_t *len, u16bits chnumber); +int stun_attr_add_bandwidth_str(u08bits* buf, size_t *len, band_limit_t bps); u16bits stun_attr_get_first_channel_number_str(const u08bits *buf, size_t len); int stun_set_allocate_request_str(u08bits* buf, size_t *len, u32bits lifetime, int address_family, u08bits transport, int mobile); diff --git a/src/server/ns_turn_server.c b/src/server/ns_turn_server.c index 53d996d..a3cf027 100644 --- a/src/server/ns_turn_server.c +++ b/src/server/ns_turn_server.c @@ -868,6 +868,8 @@ static int handle_turn_allocate(turn_turnserver *server, int af = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_DEFAULT; u08bits username[STUN_MAX_USERNAME_SIZE+1]="\0"; size_t ulen = 0; + band_limit_t bps = 0; + band_limit_t max_bps = 0; stun_attr_ref sar = stun_attr_get_first_str(ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh)); @@ -891,6 +893,9 @@ static int handle_turn_allocate(turn_turnserver *server, switch (attr_type) { SKIP_ATTRIBUTES; + case STUN_ATTRIBUTE_NEW_BANDWIDTH: + bps = stun_attr_get_bandwidth(sar); + break; case STUN_ATTRIBUTE_MOBILITY_TICKET: if(!(*(server->mobility))) { *err_code = 501; @@ -1065,12 +1070,21 @@ 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(server->allocate_bps_func) { + max_bps = ss->realm_options.perf_options.max_bps; + if(max_bps && (!bps || (bps && (bps>max_bps)))) { + bps = max_bps; + } + if(bps) { + ss->bps = server->allocate_bps_func(bps,1); + if(!(ss->bps)) { + *err_code = 486; + *reason = (const u08bits *)"Allocation Bandwidth Quota Reached"; + } + } } - if (create_relay_connection(server, ss, lifetime, + if (*err_code || create_relay_connection(server, ss, lifetime, af, transport, even_port, in_reservation_token, &out_reservation_token, err_code, reason, @@ -1110,6 +1124,11 @@ static int handle_turn_allocate(turn_turnserver *server, 0,NULL, out_reservation_token, ss->s_mobile_id); + + if(ss->bps) { + stun_attr_add_bandwidth_str(ioa_network_buffer_data(nbh), &len, ss->bps); + } + ioa_network_buffer_set_size(nbh,len); *resp_constructed = 1; diff --git a/src/server/ns_turn_session.h b/src/server/ns_turn_session.h index b5e4207..60366f4 100644 --- a/src/server/ns_turn_session.h +++ b/src/server/ns_turn_session.h @@ -42,8 +42,6 @@ extern "C" { ////////// REALM //////////// -typedef unsigned int band_limit_t; - typedef struct _perf_options_t { band_limit_t max_bps;