From f7f1784fc1ddb6d8cbcedf989df424ae82efa202 Mon Sep 17 00:00:00 2001 From: mom040267 Date: Wed, 16 Jul 2014 07:04:11 +0000 Subject: [PATCH] working on dual allocation --- README.turnutils | 2 + man/man1/turnadmin.1 | 2 +- man/man1/turnserver.1 | 2 +- man/man1/turnutils.1 | 6 ++- src/apps/common/stun_buffer.c | 9 ++-- src/apps/common/stun_buffer.h | 5 +- src/apps/uclient/mainuclient.c | 8 ++- src/apps/uclient/startuclient.c | 7 ++- src/apps/uclient/uclient.h | 1 + src/client++/TurnMsgLib.h | 9 ++-- src/client/ns_turn_msg.c | 34 ++++++------ src/client/ns_turn_msg.h | 4 +- src/server/ns_turn_server.c | 91 ++++++++++++++++++++++++--------- 13 files changed, 123 insertions(+), 57 deletions(-) diff --git a/README.turnutils b/README.turnutils index a9462d5e..e1e1901f 100644 --- a/README.turnutils +++ b/README.turnutils @@ -115,6 +115,8 @@ Flags: -B Random disconnect after a few initial packets. +-Z Dual allocation. + Options with required values: -l Message length (Default: 100 Bytes). diff --git a/man/man1/turnadmin.1 b/man/man1/turnadmin.1 index 127c3eb5..7eb719d0 100644 --- a/man/man1/turnadmin.1 +++ b/man/man1/turnadmin.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "11 July 2014" "" "" +.TH TURN 1 "15 July 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 47af6d2b..46fe5c28 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "11 July 2014" "" "" +.TH TURN 1 "15 July 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 d507b920..68f1c3d5 100644 --- a/man/man1/turnutils.1 +++ b/man/man1/turnutils.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "11 July 2014" "" "" +.TH TURN 1 "15 July 2014" "" "" .SH GENERAL INFORMATION A set of turnutils_* programs provides some utility functionality to be used @@ -173,6 +173,10 @@ Generate extra requests (create permissions, channel bind). Random disconnect after a few initial packets. .TP .B +\fB\-Z\fP +Dual allocation. +.TP +.B Options with required values: .TP .B diff --git a/src/apps/common/stun_buffer.c b/src/apps/common/stun_buffer.c index eac2fc01..09990e65 100644 --- a/src/apps/common/stun_buffer.c +++ b/src/apps/common/stun_buffer.c @@ -153,17 +153,18 @@ int stun_is_channel_message(stun_buffer* buf, u16bits* chnumber, int is_padding_ /////////////////////////////////////////////////////////////////////////////// -int stun_set_allocate_request(stun_buffer* buf, u32bits lifetime, int address_family, u08bits transport, int mobile) { - return stun_set_allocate_request_str(buf->buf, (size_t*)(&(buf->len)), lifetime, address_family, transport, mobile); +int stun_set_allocate_request(stun_buffer* buf, u32bits lifetime, int af4, int af6, u08bits transport, int mobile) { + return stun_set_allocate_request_str(buf->buf, (size_t*)(&(buf->len)), lifetime, af4, af6, transport, mobile); } int stun_set_allocate_response(stun_buffer* buf, stun_tid* tid, - const ioa_addr *relayed_addr, const ioa_addr *reflexive_addr, + const ioa_addr *relayed_addr1, const ioa_addr *relayed_addr2, + const ioa_addr *reflexive_addr, u32bits lifetime, int error_code, const u08bits *reason, u64bits reservation_token, char *mobile_id) { return stun_set_allocate_response_str(buf->buf, (size_t*)(&(buf->len)), tid, - relayed_addr, reflexive_addr, + relayed_addr1, relayed_addr2, reflexive_addr, lifetime, error_code, reason, reservation_token, mobile_id); diff --git a/src/apps/common/stun_buffer.h b/src/apps/common/stun_buffer.h index 7a4e0fe5..0d3e3608 100644 --- a/src/apps/common/stun_buffer.h +++ b/src/apps/common/stun_buffer.h @@ -101,9 +101,10 @@ int stun_is_channel_message(stun_buffer* buf, u16bits* chnumber, int is_padding_ /////////////////////////////////////////////////////////////// -int stun_set_allocate_request(stun_buffer* buf, u32bits lifetime, int address_family, u08bits transport, int mobile); +int stun_set_allocate_request(stun_buffer* buf, u32bits lifetime, int af4, int af6, u08bits transport, int mobile); int stun_set_allocate_response(stun_buffer* buf, stun_tid* tid, - const ioa_addr *relayed_addr, const ioa_addr *reflexive_addr, + const ioa_addr *relayed_addr1, const ioa_addr *relayed_addr2, + const ioa_addr *reflexive_addr, u32bits lifetime, int error_code, const u08bits *reason, u64bits reservation_token, char *mobile_id); diff --git a/src/apps/uclient/mainuclient.c b/src/apps/uclient/mainuclient.c index 437c69cb..37566b95 100644 --- a/src/apps/uclient/mainuclient.c +++ b/src/apps/uclient/mainuclient.c @@ -95,6 +95,8 @@ char origin[STUN_MAX_ORIGIN_SIZE+1] = "\0"; band_limit_t bps = 0; +int dual_allocation = 0; + //////////////// local definitions ///////////////// static char Usage[] = @@ -127,6 +129,7 @@ static char Usage[] = " (for testing the non-standard server relay functionality).\n" " -G Generate extra requests (create permissions, channel bind).\n" " -B Random disconnect after a few initial packets.\n" + " -Z Dual allocation.\n" "Options:\n" " -l Message length (Default: 100 Bytes).\n" " -i Certificate file (for secure connections only, optional).\n" @@ -201,7 +204,7 @@ int main(int argc, char **argv) ns_bzero(local_addr, sizeof(local_addr)); - 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) { + while ((c = getopt(argc, argv, "a:d:p:l:n:L:m:e:r:u:w:i:k:z:W:C:E:F:o:ZvsyhcxXgtTSAPDNOUHMRIGB")) != -1) { switch (c){ case 'a': bps = (band_limit_t)atol(optarg); @@ -255,6 +258,9 @@ int main(int argc, char **argv) case 'z': RTP_PACKET_INTERVAL = atoi(optarg); break; + case 'Z': + dual_allocation = 1; + break; case 'A': use_short_term = 1; break; diff --git a/src/apps/uclient/startuclient.c b/src/apps/uclient/startuclient.c index d4c35229..e9251aa5 100644 --- a/src/apps/uclient/startuclient.c +++ b/src/apps/uclient/startuclient.c @@ -338,10 +338,13 @@ static int clnet_allocate(int verbose, af = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_DEFAULT; } + int af4 = dual_allocation || (af == STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4); + int af6 = dual_allocation || (af == STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6); + if(!dos) - stun_set_allocate_request(&message, 800, af, relay_transport, mobility); + stun_set_allocate_request(&message, 800, af4, af6, relay_transport, mobility); else - stun_set_allocate_request(&message, 300, af, relay_transport, mobility); + stun_set_allocate_request(&message, 300, af4, af6, relay_transport, mobility); if(bps) stun_attr_add_bandwidth_str(message.buf, (size_t*)(&(message.len)), bps); diff --git a/src/apps/uclient/uclient.h b/src/apps/uclient/uclient.h index 6c3bad3d..ab56bf8b 100644 --- a/src/apps/uclient/uclient.h +++ b/src/apps/uclient/uclient.h @@ -82,6 +82,7 @@ extern int mobility; extern int no_permissions; extern int extra_requests; extern band_limit_t bps; +extern int dual_allocation; extern char origin[STUN_MAX_ORIGIN_SIZE+1]; diff --git a/src/client++/TurnMsgLib.h b/src/client++/TurnMsgLib.h index db97acc6..b5b46abb 100644 --- a/src/client++/TurnMsgLib.h +++ b/src/client++/TurnMsgLib.h @@ -848,8 +848,8 @@ public: /** * Construct allocate request */ - void constructAllocateRequest(u32bits lifetime, int address_family, u08bits transport, int mobile) { - stun_set_allocate_request_str(_buffer, &_sz, lifetime, address_family, transport, mobile); + void constructAllocateRequest(u32bits lifetime, int af4, int af6, u08bits transport, int mobile) { + stun_set_allocate_request_str(_buffer, &_sz, lifetime, af4, af6, transport, mobile); } /** @@ -1011,13 +1011,14 @@ public: * Construct allocate response */ void constructAllocateResponse(stun_tid &tid, - const ioa_addr &relayed_addr, + const ioa_addr &relayed_addr1, + const ioa_addr &relayed_addr2, const ioa_addr &reflexive_addr, u32bits lifetime, int error_code, const u08bits *reason, u64bits reservation_token, char *mobile_id) { stun_set_allocate_response_str(_buffer, &_sz, &tid, - &relayed_addr, + &relayed_addr1, &relayed_addr2, &reflexive_addr, lifetime, error_code, reason, reservation_token, mobile_id); diff --git a/src/client/ns_turn_msg.c b/src/client/ns_turn_msg.c index b5d69d91..19349b6e 100644 --- a/src/client/ns_turn_msg.c +++ b/src/client/ns_turn_msg.c @@ -644,7 +644,7 @@ int stun_get_message_len_str(u08bits *buf, size_t blen, int padding, size_t *app ////////// ALLOCATE /////////////////////////////////// -int stun_set_allocate_request_str(u08bits* buf, size_t *len, u32bits lifetime, int address_family, +int stun_set_allocate_request_str(u08bits* buf, size_t *len, u32bits lifetime, int af4, int af6, u08bits transport, int mobile) { stun_init_request_str(STUN_METHOD_ALLOCATE, buf, len); @@ -671,30 +671,30 @@ int stun_set_allocate_request_str(u08bits* buf, size_t *len, u32bits lifetime, i } //ADRESS-FAMILY - switch (address_family) { - case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4: - case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6: - { + if (af4) { u08bits field[4]; - field[0] = (u08bits)address_family; + field[0] = (u08bits)STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4; field[1]=0; field[2]=0; field[3]=0; if(stun_attr_add_str(buf,len,STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY,field,sizeof(field))<0) return -1; - break; } - case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_DEFAULT: - /* ignore */ - break; - default: - return -1; + + if (af6) { + u08bits field[4]; + field[0] = (u08bits)STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6; + field[1]=0; + field[2]=0; + field[3]=0; + if(stun_attr_add_str(buf,len,STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY,field,sizeof(field))<0) return -1; }; return 0; } int stun_set_allocate_response_str(u08bits* buf, size_t *len, stun_tid* tid, - const ioa_addr *relayed_addr, const ioa_addr *reflexive_addr, + const ioa_addr *relayed_addr1, const ioa_addr *relayed_addr2, + const ioa_addr *reflexive_addr, u32bits lifetime, int error_code, const u08bits *reason, u64bits reservation_token, char* mobile_id) { @@ -702,8 +702,12 @@ int stun_set_allocate_response_str(u08bits* buf, size_t *len, stun_tid* tid, stun_init_success_response_str(STUN_METHOD_ALLOCATE, buf, len, tid); - if(relayed_addr) { - if(stun_attr_add_addr_str(buf,len,STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS,relayed_addr)<0) return -1; + if(relayed_addr1) { + if(stun_attr_add_addr_str(buf,len,STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS,relayed_addr1)<0) return -1; + } + + if(relayed_addr2) { + if(stun_attr_add_addr_str(buf,len,STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS,relayed_addr2)<0) return -1; } if(reflexive_addr) { diff --git a/src/client/ns_turn_msg.h b/src/client/ns_turn_msg.h index 33cb9561..04f6d170 100644 --- a/src/client/ns_turn_msg.h +++ b/src/client/ns_turn_msg.h @@ -155,9 +155,9 @@ 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); +int stun_set_allocate_request_str(u08bits* buf, size_t *len, u32bits lifetime, int af4, int af6, u08bits transport, int mobile); int stun_set_allocate_response_str(u08bits* buf, size_t *len, stun_tid* tid, - const ioa_addr *relayed_addr, + const ioa_addr *relayed_addr1, const ioa_addr *relayed_addr2, const ioa_addr *reflexive_addr, u32bits lifetime, int error_code, const u08bits *reason, u64bits reservation_token, char *mobile_id); diff --git a/src/server/ns_turn_server.c b/src/server/ns_turn_server.c index fb31db19..5257dde4 100644 --- a/src/server/ns_turn_server.c +++ b/src/server/ns_turn_server.c @@ -899,22 +899,43 @@ static int handle_turn_allocate(turn_turnserver *server, *reason = (const u08bits *)"Wrong TID"; } else { size_t len = ioa_network_buffer_get_size(nbh); - ioa_addr xor_relayed_addr; - ioa_addr *relayed_addr = get_local_addr_from_ioa_socket(get_relay_socket_ss(ss,AF_INET)); - if(!relayed_addr) - relayed_addr = get_local_addr_from_ioa_socket(get_relay_socket_ss(ss,AF_INET6)); - if(relayed_addr) { + ioa_addr xor_relayed_addr1, *pxor_relayed_addr1=NULL; + ioa_addr xor_relayed_addr2, *pxor_relayed_addr2=NULL; + ioa_addr *relayed_addr1 = get_local_addr_from_ioa_socket(get_relay_socket_ss(ss,AF_INET)); + ioa_addr *relayed_addr2 = get_local_addr_from_ioa_socket(get_relay_socket_ss(ss,AF_INET6)); + + if(relayed_addr1) { if(server->external_ip_set) { - addr_cpy(&xor_relayed_addr, &(server->external_ip)); - addr_set_port(&xor_relayed_addr,addr_get_port(relayed_addr)); + addr_cpy(&xor_relayed_addr1, &(server->external_ip)); + addr_set_port(&xor_relayed_addr1,addr_get_port(relayed_addr1)); } else { - addr_cpy(&xor_relayed_addr, relayed_addr); + addr_cpy(&xor_relayed_addr1, relayed_addr1); + } + pxor_relayed_addr1 = &xor_relayed_addr1; + } + + if(relayed_addr2) { + if(server->external_ip_set) { + addr_cpy(&xor_relayed_addr2, &(server->external_ip)); + addr_set_port(&xor_relayed_addr2,addr_get_port(relayed_addr2)); + } else { + addr_cpy(&xor_relayed_addr2, relayed_addr2); + } + pxor_relayed_addr2 = &xor_relayed_addr2; + } + + if(pxor_relayed_addr1 || pxor_relayed_addr2) { + u32bits lifetime = 0; + if(pxor_relayed_addr1) { + lifetime = (get_relay_session(a,pxor_relayed_addr1->ss.sa_family)->expiration_time - server->ctime); + } else if(pxor_relayed_addr2) { + lifetime = (get_relay_session(a,pxor_relayed_addr2->ss.sa_family)->expiration_time - server->ctime); } stun_set_allocate_response_str(ioa_network_buffer_data(nbh), &len, tid, - &xor_relayed_addr, + pxor_relayed_addr1, pxor_relayed_addr2, get_remote_addr_from_ioa_socket(ss->client_socket), - (get_relay_session(a,relayed_addr->ss.sa_family)->expiration_time - server->ctime), 0, NULL, 0, + lifetime, 0, NULL, 0, ss->s_mobile_id); ioa_network_buffer_set_size(nbh,len); *resp_constructed = 1; @@ -930,7 +951,8 @@ static int handle_turn_allocate(turn_turnserver *server, int even_port = -1; int dont_fragment = 0; u64bits in_reservation_token = 0; - int af = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_DEFAULT; + int af4 = 0; + int af6 = 0; u08bits username[STUN_MAX_USERNAME_SIZE+1]="\0"; size_t ulen = 0; band_limit_t bps = 0; @@ -1047,7 +1069,7 @@ static int handle_turn_allocate(turn_turnserver *server, if (len != 8) { *err_code = 400; *reason = (const u08bits *)"Wrong Format of Reservation Token"; - } else if(af != STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_DEFAULT) { + } else if(af4 || af6) { *err_code = 400; *reason = (const u08bits *)"Address family attribute can not be used with reservation token request"; } else { @@ -1069,11 +1091,13 @@ static int handle_turn_allocate(turn_turnserver *server, *reason = (const u08bits *)"Address family attribute can not be used with reservation token request"; } else { int af_req = stun_get_requested_address_family(sar); - if(af == STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_DEFAULT) { + if(!af4 && !af6) { switch (af_req) { case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4: + af4 = 1; + break; case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6: - af = af_req; + af6 = 1; break; default: *err_code = 440; @@ -1149,6 +1173,10 @@ static int handle_turn_allocate(turn_turnserver *server, } } + int af = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_DEFAULT; + if(af4) af = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4; + else if(af6) af = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6; + if (*err_code || create_relay_connection(server, ss, lifetime, af, transport, even_port, in_reservation_token, &out_reservation_token, @@ -1173,20 +1201,35 @@ static int handle_turn_allocate(turn_turnserver *server, size_t len = ioa_network_buffer_get_size(nbh); - ioa_addr xor_relayed_addr; - ioa_addr *relayed_addr = get_local_addr_from_ioa_socket(get_relay_socket_ss(ss,AF_INET)); - if(!relayed_addr) - relayed_addr = get_local_addr_from_ioa_socket(get_relay_socket_ss(ss,AF_INET6)); - if(relayed_addr) { + ioa_addr xor_relayed_addr1, *pxor_relayed_addr1=NULL; + ioa_addr xor_relayed_addr2, *pxor_relayed_addr2=NULL; + ioa_addr *relayed_addr1 = get_local_addr_from_ioa_socket(get_relay_socket_ss(ss,AF_INET)); + ioa_addr *relayed_addr2 = get_local_addr_from_ioa_socket(get_relay_socket_ss(ss,AF_INET6)); + + if(relayed_addr1) { if(server->external_ip_set) { - addr_cpy(&xor_relayed_addr, &(server->external_ip)); - addr_set_port(&xor_relayed_addr,addr_get_port(relayed_addr)); + addr_cpy(&xor_relayed_addr1, &(server->external_ip)); + addr_set_port(&xor_relayed_addr1,addr_get_port(relayed_addr1)); } else { - addr_cpy(&xor_relayed_addr, relayed_addr); + addr_cpy(&xor_relayed_addr1, relayed_addr1); } + pxor_relayed_addr1 = &xor_relayed_addr1; + } + + if(relayed_addr2) { + if(server->external_ip_set) { + addr_cpy(&xor_relayed_addr2, &(server->external_ip)); + addr_set_port(&xor_relayed_addr2,addr_get_port(relayed_addr2)); + } else { + addr_cpy(&xor_relayed_addr2, relayed_addr2); + } + pxor_relayed_addr2 = &xor_relayed_addr2; + } + + if(pxor_relayed_addr1 || pxor_relayed_addr2) { stun_set_allocate_response_str(ioa_network_buffer_data(nbh), &len, tid, - &xor_relayed_addr, + pxor_relayed_addr1, pxor_relayed_addr2, get_remote_addr_from_ioa_socket(ss->client_socket), lifetime, 0,NULL, out_reservation_token, @@ -1213,7 +1256,7 @@ static int handle_turn_allocate(turn_turnserver *server, } size_t len = ioa_network_buffer_get_size(nbh); - stun_set_allocate_response_str(ioa_network_buffer_data(nbh), &len, tid, NULL, NULL, 0, *err_code, *reason, 0, ss->s_mobile_id); + stun_set_allocate_response_str(ioa_network_buffer_data(nbh), &len, tid, NULL, NULL, NULL, 0, *err_code, *reason, 0, ss->s_mobile_id); ioa_network_buffer_set_size(nbh,len); *resp_constructed = 1; }