From 48537e96249f50fa38e4977b67655cd57686429d Mon Sep 17 00:00:00 2001 From: mom040267 Date: Fri, 11 Jul 2014 06:21:02 +0000 Subject: [PATCH] allocation mismatch fix merged from rfc5766-turn-server --- ChangeLog | 1 + src/apps/uclient/startuclient.c | 48 ++++++++++++++++++++--------- src/server/ns_turn_server.c | 54 ++++++++++++++++++++++----------- 3 files changed, 72 insertions(+), 31 deletions(-) diff --git a/ChangeLog b/ChangeLog index db1f63c..caadd49 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,7 @@ Version 4.0.1.4 'Severard': - multiple origins supported. - working on compilation warnings. + - "allocation mismatch" condition fixed (merged from rfc5766-turn-server). 06/13/2014 Oleg Moskalenko Version 4.0.1.3 'Severard': diff --git a/src/apps/uclient/startuclient.c b/src/apps/uclient/startuclient.c index 1593d28..d4c3522 100644 --- a/src/apps/uclient/startuclient.c +++ b/src/apps/uclient/startuclient.c @@ -306,7 +306,9 @@ static int clnet_allocate(int verbose, app_ur_conn_info *clnet_info, ioa_addr *relay_addr, int af, - char *turn_addr, u16bits *turn_port) { + char *turn_addr, u16bits *turn_port, + stun_tid *in_tid, + stun_tid *out_tid) { int af_cycle = 0; int reopen_socket = 0; @@ -332,8 +334,9 @@ static int clnet_allocate(int verbose, } stun_buffer message; - if(current_reservation_token) + if(!in_tid && current_reservation_token) { af = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_DEFAULT; + } if(!dos) stun_set_allocate_request(&message, 800, af, relay_transport, mobility); @@ -343,9 +346,13 @@ static int clnet_allocate(int verbose, if(bps) stun_attr_add_bandwidth_str(message.buf, (size_t*)(&(message.len)), bps); + if(in_tid) { + stun_tid_message_cpy(message.buf, in_tid); + } + if(dont_fragment) stun_attr_add(&message, STUN_ATTRIBUTE_DONT_FRAGMENT, NULL, 0); - if(!no_rtcp) { + if(!no_rtcp && !in_tid) { if (!never_allocate_rtcp && allocate_rtcp) { uint64_t reservation_token = ioa_ntoh64(current_reservation_token); stun_attr_add(&message, STUN_ATTRIBUTE_RESERVATION_TOKEN, @@ -367,6 +374,10 @@ static int clnet_allocate(int verbose, stun_attr_add_fingerprint_str(message.buf,(size_t*)&(message.len)); + if(out_tid) { + stun_tid_from_message_str(message.buf, (size_t)message.len, out_tid); + } + while (!allocate_sent) { int len = send_buffer(clnet_info, &message,0,0); @@ -519,7 +530,9 @@ static int clnet_allocate(int verbose, exit(-1); } - allocate_rtcp = !allocate_rtcp; + if(!in_tid) { + allocate_rtcp = !allocate_rtcp; + } if (1) { @@ -900,7 +913,9 @@ int start_connection(uint16_t clnet_remote_port0, char remote_address[1025]; STRCPY(remote_address,remote_address0); - clnet_allocate(verbose, clnet_info_probe, &relay_addr, default_address_family, remote_address, &clnet_remote_port); + stun_tid tid; + + clnet_allocate(verbose, clnet_info_probe, &relay_addr, default_address_family, remote_address, &clnet_remote_port,NULL,NULL); /* Real: */ @@ -920,15 +935,20 @@ int start_connection(uint16_t clnet_remote_port0, } int af = default_address_family ? default_address_family : get_allocate_address_family(&peer_addr); - if (clnet_allocate(verbose, clnet_info, &relay_addr, af, NULL,NULL) < 0) { + if (clnet_allocate(verbose, clnet_info, &relay_addr, af, NULL,NULL,NULL,&tid) < 0) { exit(-1); } + //strcpy((char*)g_uname,"qqq"); + //if (clnet_allocate(verbose, clnet_info, &relay_addr, af, NULL,NULL,&tid,NULL) < 0) { + // exit(-1); + //} + if(rare_event()) return 0; if(!no_rtcp) { af = default_address_family ? default_address_family : get_allocate_address_family(&peer_addr_rtcp); - if (clnet_allocate(verbose, clnet_info_rtcp, &relay_addr_rtcp, af,NULL,NULL) < 0) { + if (clnet_allocate(verbose, clnet_info_rtcp, &relay_addr_rtcp, af,NULL,NULL,NULL,NULL) < 0) { exit(-1); } if(rare_event()) return 0; @@ -1115,7 +1135,7 @@ int start_c2c_connection(uint16_t clnet_remote_port0, char remote_address[1025]; STRCPY(remote_address,remote_address0); - clnet_allocate(verbose, clnet_info_probe, &relay_addr1, default_address_family, remote_address, &clnet_remote_port); + clnet_allocate(verbose, clnet_info_probe, &relay_addr1, default_address_family, remote_address, &clnet_remote_port,NULL,NULL); if(rare_event()) return 0; @@ -1148,7 +1168,7 @@ int start_c2c_connection(uint16_t clnet_remote_port0, if(!no_rtcp) { - if (clnet_allocate(verbose, clnet_info1, &relay_addr1, default_address_family,NULL,NULL) + if (clnet_allocate(verbose, clnet_info1, &relay_addr1, default_address_family,NULL,NULL,NULL,NULL) < 0) { exit(-1); } @@ -1156,13 +1176,13 @@ int start_c2c_connection(uint16_t clnet_remote_port0, if(rare_event()) return 0; if (clnet_allocate(verbose, clnet_info1_rtcp, - &relay_addr1_rtcp, default_address_family,NULL,NULL) < 0) { + &relay_addr1_rtcp, default_address_family,NULL,NULL,NULL,NULL) < 0) { exit(-1); } if(rare_event()) return 0; - if (clnet_allocate(verbose, clnet_info2, &relay_addr2, default_address_family,NULL,NULL) + if (clnet_allocate(verbose, clnet_info2, &relay_addr2, default_address_family,NULL,NULL,NULL,NULL) < 0) { exit(-1); } @@ -1170,20 +1190,20 @@ int start_c2c_connection(uint16_t clnet_remote_port0, if(rare_event()) return 0; if (clnet_allocate(verbose, clnet_info2_rtcp, - &relay_addr2_rtcp, default_address_family,NULL,NULL) < 0) { + &relay_addr2_rtcp, default_address_family,NULL,NULL,NULL,NULL) < 0) { exit(-1); } if(rare_event()) return 0; } else { - if (clnet_allocate(verbose, clnet_info1, &relay_addr1, default_address_family,NULL,NULL) + if (clnet_allocate(verbose, clnet_info1, &relay_addr1, default_address_family,NULL,NULL,NULL,NULL) < 0) { exit(-1); } if(rare_event()) return 0; if(!(clnet_info2->is_peer)) { - if (clnet_allocate(verbose, clnet_info2, &relay_addr2, default_address_family,NULL,NULL) < 0) { + if (clnet_allocate(verbose, clnet_info2, &relay_addr2, default_address_family,NULL,NULL,NULL,NULL) < 0) { exit(-1); } if(rare_event()) return 0; diff --git a/src/server/ns_turn_server.c b/src/server/ns_turn_server.c index c25d729..fb31db1 100644 --- a/src/server/ns_turn_server.c +++ b/src/server/ns_turn_server.c @@ -3035,8 +3035,13 @@ static int check_stun_auth(turn_turnserver *server, get_realm_options_by_name((char *)realm, &(ss->realm_options)); } else if(strcmp((char*)realm, (char*)(ss->realm_options.name))) { - *err_code = 441; - *reason = (const u08bits*)"Wrong credentials: the realm value incorrect"; + if(method == STUN_METHOD_ALLOCATE) { + *err_code = 437; + *reason = (const u08bits*)"Allocation mismatch: wrong credentials: the realm value is incorrect"; + } else { + *err_code = 441; + *reason = (const u08bits*)"Wrong credentials: the realm value is incorrect"; + } return -1; } } @@ -3059,8 +3064,13 @@ static int check_stun_auth(turn_turnserver *server, if(ss->username[0]) { if(strcmp((char*)ss->username,(char*)usname)) { - *err_code = 441; - *reason = (const u08bits*)"Wrong credentials"; + if(method == STUN_METHOD_ALLOCATE) { + *err_code = 437; + *reason = (const u08bits*)"Allocation mismatch: wrong credentials"; + } else { + *err_code = 441; + *reason = (const u08bits*)"Wrong credentials"; + } return -1; } } else { @@ -3259,21 +3269,31 @@ static int handle_turn_command(turn_turnserver *server, ts_ur_super_session *ss, if(method == STUN_METHOD_ALLOCATE) { - SOCKET_TYPE cst = get_ioa_socket_type(ss->client_socket); - turn_server_addrs_list_t *asl = server->alternate_servers_list; - - if(((cst == UDP_SOCKET)||(cst == DTLS_SOCKET)) && server->self_udp_balance && - server->aux_servers_list && server->aux_servers_list->size) { - asl = server->aux_servers_list; - } else if(((cst == TLS_SOCKET) || (cst == DTLS_SOCKET)) && - server->tls_alternate_servers_list && server->tls_alternate_servers_list->size) { - asl = server->tls_alternate_servers_list; + allocation *a = get_allocation_ss(ss); + if(is_allocation_valid(a)) { + if(!stun_tid_equals(&(a->tid), &tid)) { + err_code = 437; + reason = (const u08bits *)"Mismatched allocation: wrong transaction ID"; + } } - if(asl && asl->size) { - turn_mutex_lock(&(asl->m)); - set_alternate_server(asl,get_local_addr_from_ioa_socket(ss->client_socket),&(server->as_counter),method,&tid,resp_constructed,&err_code,&reason,nbh); - turn_mutex_unlock(&(asl->m)); + if(!err_code) { + SOCKET_TYPE cst = get_ioa_socket_type(ss->client_socket); + turn_server_addrs_list_t *asl = server->alternate_servers_list; + + if(((cst == UDP_SOCKET)||(cst == DTLS_SOCKET)) && server->self_udp_balance && + server->aux_servers_list && server->aux_servers_list->size) { + asl = server->aux_servers_list; + } else if(((cst == TLS_SOCKET) || (cst == DTLS_SOCKET)) && + server->tls_alternate_servers_list && server->tls_alternate_servers_list->size) { + asl = server->tls_alternate_servers_list; + } + + if(asl && asl->size) { + turn_mutex_lock(&(asl->m)); + set_alternate_server(asl,get_local_addr_from_ioa_socket(ss->client_socket),&(server->as_counter),method,&tid,resp_constructed,&err_code,&reason,nbh); + turn_mutex_unlock(&(asl->m)); + } } }