Jelajahi Sumber

allocation mismatch fix merged from rfc5766-turn-server

mom040267 11 tahun lalu
induk
melakukan
48537e9624
3 mengubah file dengan 72 tambahan dan 31 penghapusan
  1. 1 0
      ChangeLog
  2. 34 14
      src/apps/uclient/startuclient.c
  3. 37 17
      src/server/ns_turn_server.c

+ 1 - 0
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 <[email protected]>
 Version 4.0.1.3 'Severard':

+ 34 - 14
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;

+ 37 - 17
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));
+					}
 				}
 			}