Browse Source

working on new dual-allocation implementation

mom040267 11 years ago
parent
commit
3c40c14f40

+ 2 - 0
ChangeLog

@@ -1,6 +1,8 @@
 1/31/2015 Oleg Moskalenko <[email protected]>
 Version 4.4.1.2 'Ardee West':
 	- hostname-to-IP-address resolution fix;
+	- SSODA updates according to turnbis specs;
+	- TRANSPORT attribute handling fixed;
 
 1/24/2015 Oleg Moskalenko <[email protected]>
 Version 4.4.1.1 'Ardee West':

+ 2 - 2
TODO

@@ -4,7 +4,7 @@
 
 ==================================================================
 
-1) Fedora official package (turnserver or coturn ? TBD).
+1) Fedora official package.
 
 2) MS Windows support.
 
@@ -90,7 +90,7 @@
 
 ==================================================================
 
-nope
+1) Peer for TCP relay.
 
 ==================================================================
 

+ 2 - 2
src/apps/common/stun_buffer.c

@@ -153,8 +153,8 @@ int stun_is_channel_message(stun_buffer* buf, u16bits* chnumber, int is_padding_
 
 ///////////////////////////////////////////////////////////////////////////////
 
-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_request(stun_buffer* buf, u32bits lifetime, int af4, int af6, u08bits transport, int mobile, const char *rt, int ep) {
+  return stun_set_allocate_request_str(buf->buf, (size_t*)(&(buf->len)), lifetime, af4, af6, transport, mobile, rt, ep);
 }
 
 int stun_set_allocate_response(stun_buffer* buf, stun_tid* tid, 

+ 1 - 1
src/apps/common/stun_buffer.h

@@ -101,7 +101,7 @@ int stun_is_channel_message(stun_buffer* buf, u16bits* chnumber, int is_padding_
 
 ///////////////////////////////////////////////////////////////
 
-int stun_set_allocate_request(stun_buffer* buf, u32bits lifetime, int af4, int af6, u08bits transport, int mobile);
+int stun_set_allocate_request(stun_buffer* buf, u32bits lifetime, int af4, int af6, u08bits transport, int mobile, const char* rt, int ep);
 int stun_set_allocate_response(stun_buffer* buf, stun_tid* tid, 
 			       const ioa_addr *relayed_addr1, const ioa_addr *relayed_addr2,
 			       const ioa_addr *reflexive_addr,

+ 4 - 0
src/apps/uclient/mainuclient.c

@@ -392,6 +392,10 @@ int main(int argc, char **argv)
 		}
 	}
 
+	if(dual_allocation) {
+		no_rtcp = 1;
+	}
+
 	if(g_use_auth_secret_with_timestamp) {
 
 		{

+ 8 - 17
src/apps/uclient/startuclient.c

@@ -370,39 +370,30 @@ static int clnet_allocate(int verbose,
 			reopen_socket = 0;
 		}
 
-		if(current_reservation_token) {
-			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);
 
+		uint64_t reservation_token = 0;
+		char* rt = NULL;
+		int ep = !no_rtcp;
+
 		if(!no_rtcp) {
 			if (!never_allocate_rtcp && allocate_rtcp) {
-				af4 = 0;
-				af6 = 0;
+				reservation_token = ioa_ntoh64(current_reservation_token);
+				rt = (char*) (&reservation_token);
 			}
 		}
 
 		if(!dos)
-			stun_set_allocate_request(&request_message, UCLIENT_SESSION_LIFETIME, af4, af6, relay_transport, mobility);
+			stun_set_allocate_request(&request_message, UCLIENT_SESSION_LIFETIME, af4, af6, relay_transport, mobility, rt, ep);
 		else
-			stun_set_allocate_request(&request_message, UCLIENT_SESSION_LIFETIME/3, af4, af6, relay_transport, mobility);
+			stun_set_allocate_request(&request_message, UCLIENT_SESSION_LIFETIME/3, af4, af6, relay_transport, mobility, rt, ep);
 
 		if(bps)
 			stun_attr_add_bandwidth_str(request_message.buf, (size_t*)(&(request_message.len)), bps);
 
 		if(dont_fragment)
 			stun_attr_add(&request_message, STUN_ATTRIBUTE_DONT_FRAGMENT, NULL, 0);
-		if(!no_rtcp) {
-		  if (!never_allocate_rtcp && allocate_rtcp) {
-		    uint64_t reservation_token = ioa_ntoh64(current_reservation_token);
-		    stun_attr_add(&request_message, STUN_ATTRIBUTE_RESERVATION_TOKEN,
-				  (char*) (&reservation_token), 8);
-		  } else {
-		    stun_attr_add_even_port(&request_message, 1);
-		  }
-		}
 
 		add_origin(&request_message);
 

+ 2 - 2
src/client++/TurnMsgLib.h

@@ -849,8 +849,8 @@ public:
 	/**
 	 * Construct allocate request
 	 */
-	void constructAllocateRequest(u32bits lifetime, int af4, int af6, u08bits transport, int mobile) {
-		stun_set_allocate_request_str(_buffer, &_sz, lifetime, af4, af6, transport, mobile);
+	void constructAllocateRequest(u32bits lifetime, int af4, int af6, u08bits transport, int mobile, const char* rt, int ep) {
+		stun_set_allocate_request_str(_buffer, &_sz, lifetime, af4, af6, transport, mobile, rt, ep);
 	}
 
 	/**

+ 86 - 23
src/client/ns_turn_msg.c

@@ -737,7 +737,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 af4, int af6,
-				u08bits transport, int mobile) {
+				u08bits transport, int mobile, const char* rt, int ep) {
 
   stun_init_request_str(STUN_METHOD_ALLOCATE, buf, len);
 
@@ -758,28 +758,49 @@ int stun_set_allocate_request_str(u08bits* buf, size_t *len, u32bits lifetime, i
     if(stun_attr_add_str(buf,len,STUN_ATTRIBUTE_LIFETIME,(u08bits*)(&field),sizeof(field))<0) return -1;
   }
 
-  if(mobile) {
-	  if(stun_attr_add_str(buf,len,STUN_ATTRIBUTE_MOBILITY_TICKET,(const u08bits*)"",0)<0) return -1;
-  }
+  if(rt) {
 
-  //ADRESS-FAMILY
-  if (af4) {
-	  u08bits field[4];
-	  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;
-  }
+	  stun_attr_add_str(buf,len, STUN_ATTRIBUTE_RESERVATION_TOKEN, (const u08bits*) rt, 8);
 
-  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;
-  };
+  } else {
+
+	  if(mobile) {
+		  if(stun_attr_add_str(buf,len,STUN_ATTRIBUTE_MOBILITY_TICKET,(const u08bits*)"",0)<0) return -1;
+	  }
+
+	  if(ep) {
+		  uint8_t value = 0x80;
+		  if(stun_attr_add_str(buf,len,STUN_ATTRIBUTE_EVEN_PORT,(const u08bits*)&value,1)<0) return -1;
+	  }
+
+	  //ADRESS-FAMILY
+	  if (af4 && !af6) {
+		  u08bits field[4];
+		  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;
+	  }
+
+	  if (af6 && !af4) {
+		  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;
+	  }
+
+	  if (af4 && 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_ADDITIONAL_ADDRESS_FAMILY,field,sizeof(field))<0) return -1;
+	  }
+  }
 
   return 0;
 }
@@ -1246,7 +1267,7 @@ int stun_attr_get_first_addr_str(const u08bits *buf, size_t len, u16bits attr_ty
   while(attr) {
     if(stun_attr_is_addr(attr) && (attr_type == stun_attr_get_type(attr))) {
       if(stun_attr_get_addr_str(buf,len,attr,ca,default_addr)==0) {
-	return 0;
+    	  return 0;
       }
     }
     attr=stun_attr_get_next_str(buf,len,attr);
@@ -1273,6 +1294,48 @@ int stun_attr_add_bandwidth_str(u08bits* buf, size_t *len, band_limit_t bps0) {
 	return stun_attr_add_str(buf,len,STUN_ATTRIBUTE_NEW_BANDWIDTH,(u08bits*)(&field),sizeof(field));
 }
 
+int stun_attr_add_address_error_code(u08bits* buf, size_t *len, int requested_address_family, u08bits error_code)
+{
+	u08bits field[4];
+	field[0]=(u08bits)requested_address_family;
+	field[1]=error_code;
+	field[2]=0;
+	field[3]=0;
+	return stun_attr_add_str(buf,len,STUN_ATTRIBUTE_ADDRESS_ERROR_CODE,field,sizeof(field));
+}
+
+int stun_attr_get_address_error_code(u08bits* buf, size_t len, int *requested_address_family, u08bits *error_code)
+{
+	if(requested_address_family) {
+		*requested_address_family = 0;
+	}
+	if(error_code) {
+		*error_code = 0;
+	}
+	if(buf && len) {
+		stun_attr_ref sar = stun_attr_get_first_by_type_str(buf, len, STUN_ATTRIBUTE_ADDRESS_ERROR_CODE);
+		if(sar) {
+			const u08bits* value = stun_attr_get_value(sar);
+			if(!value) {
+				return -1;
+			} else {
+				int alen = stun_attr_get_len(sar);
+				if(alen != 4) {
+					return -1;
+				}
+				if(requested_address_family) {
+					*requested_address_family = value[0];
+				}
+				if(error_code) {
+					*error_code = value[1];
+				}
+				return 0;
+			}
+		}
+	}
+	return 0;
+}
+
 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);
@@ -1280,7 +1343,7 @@ u16bits stun_attr_get_first_channel_number_str(const u08bits *buf, size_t len) {
     if(stun_attr_get_type(attr) == STUN_ATTRIBUTE_CHANNEL_NUMBER) {
       u16bits ret = stun_attr_get_channel_number(attr);
       if(STUN_VALID_CHANNEL(ret)) {
-	return ret;
+    	  return ret;
       }
     }
     attr=stun_attr_get_next_str(buf,len,attr);

+ 4 - 1
src/client/ns_turn_msg.h

@@ -151,9 +151,12 @@ int stun_attr_get_addr_str(const u08bits *buf, size_t len, stun_attr_ref attr, i
 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);
+int stun_attr_add_address_error_code(u08bits* buf, size_t *len, int requested_address_family, u08bits error_code);
+/* return +1 if present, 0 if not, -1 if error: */
+int stun_attr_get_address_error_code(u08bits* buf, size_t len, int *requested_address_family, u08bits *error_code);
 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 af4, int af6, 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, const char* rt, int ep);
 int stun_set_allocate_response_str(u08bits* buf, size_t *len, stun_tid* tid, 
 				   const ioa_addr *relayed_addr1, const ioa_addr *relayed_addr2,
 				   const ioa_addr *reflexive_addr,

+ 3 - 3
src/client/ns_turn_msg_defs.h

@@ -123,11 +123,11 @@
 /* RFC 5780 */
 #define STUN_ATTRIBUTE_PADDING (0x0026)
 #define STUN_ATTRIBUTE_RESPONSE_PORT (0x0027)
-#define STUN_ATTRIBUTE_RESPONSE_ORIGIN (0x802b)
-#define STUN_ATTRIBUTE_OTHER_ADDRESS (0x802c)
+#define STUN_ATTRIBUTE_RESPONSE_ORIGIN (0x802B)
+#define STUN_ATTRIBUTE_OTHER_ADDRESS (0x802C)
 
 /* RFC 6062 ==>> */
-#define STUN_ATTRIBUTE_CONNECTION_ID (0x002a)
+#define STUN_ATTRIBUTE_CONNECTION_ID (0x002A)
 /* <<== RFC 6062 */
 
 #define STUN_VALID_CHANNEL(chn) ((chn)>=0x4000 && (chn)<=0x7FFF)

+ 5 - 0
src/client/ns_turn_msg_defs_new.h

@@ -175,4 +175,9 @@ struct _encoded_oauth_token {
 
 typedef struct _encoded_oauth_token encoded_oauth_token;
 
+////////////// SSODA ///////////////////
+
+#define STUN_ATTRIBUTE_ADDITIONAL_ADDRESS_FAMILY (0x8032)
+#define STUN_ATTRIBUTE_ADDRESS_ERROR_CODE (0x8033)
+
 #endif //__LIB_TURN_MSG_DEFS_NEW__

+ 36 - 9
src/server/ns_turn_server.c

@@ -914,6 +914,10 @@ static int handle_turn_allocate(turn_turnserver *server,
 				int *err_code, 	const u08bits **reason, u16bits *unknown_attrs, u16bits *ua_num,
 				ioa_net_data *in_buffer, ioa_network_buffer_handle nbh) {
 
+
+	int err_code4 = 0;
+	int err_code6 = 0;
+
 	allocation* alloc = get_allocation_ss(ss);
 
 	if (is_allocation_valid(alloc)) {
@@ -1033,15 +1037,15 @@ static int handle_turn_allocate(turn_turnserver *server,
 					const u08bits* value = stun_attr_get_value(sar);
 					if (value) {
 						transport = get_transport_value(value);
-						if (!transport || value[1] || value[2] || value[3]) {
+						if (!transport) {
 							*err_code = 442;
 							*reason = (const u08bits *)"Unsupported Transport Protocol";
 						}
 						if((transport == STUN_ATTRIBUTE_TRANSPORT_TCP_VALUE) && *(server->no_tcp_relay)) {
-							*err_code = 403;
+							*err_code = 442;
 							*reason = (const u08bits *)"TCP Transport is not allowed by the TURN Server configuration";
 						} else if((transport == STUN_ATTRIBUTE_TRANSPORT_UDP_VALUE) && *(server->no_udp_relay)) {
-							*err_code = 403;
+							*err_code = 442;
 							*reason = (const u08bits *)"UDP Transport is not allowed by the TURN Server configuration";
 						} else if(ss->client_socket) {
 							SOCKET_TYPE cst = get_ioa_socket_type(ss->client_socket);
@@ -1113,17 +1117,29 @@ static int handle_turn_allocate(turn_turnserver *server,
 			  }
 			}
 			  break;
+			case STUN_ATTRIBUTE_ADDITIONAL_ADDRESS_FAMILY:
 			case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY: {
 				if(in_reservation_token) {
 					*err_code = 400;
 					*reason = (const u08bits *)"Address family attribute can not be used with reservation token request";
+				} else if(af4 || af6) {
+					*err_code = 400;
+					*reason = (const u08bits *)"Extra address family attribute can not be used in the request";
 				} else {
 					int af_req = stun_get_requested_address_family(sar);
 					switch (af_req) {
 					case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4:
-						af4 = af_req;
+						if(attr_type == STUN_ATTRIBUTE_ADDITIONAL_ADDRESS_FAMILY) {
+							*err_code = 400;
+							*reason = (const u08bits *)"Invalid value of the additional address family attribute";
+						} else {
+							af4 = af_req;
+						}
 						break;
 					case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6:
+						if(attr_type == STUN_ATTRIBUTE_ADDITIONAL_ADDRESS_FAMILY) {
+							af4 = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4;
+						}
 						af6 = af_req;
 						break;
 					default:
@@ -1248,9 +1264,9 @@ static int handle_turn_allocate(turn_turnserver *server,
 							}
 						}
 					} else {
-						int err_code4 = 0;
 						const u08bits *reason4 = NULL;
-						if(af4) {
+						const u08bits *reason6 = NULL;
+						{
 							int af4res = create_relay_connection(server, ss, lifetime,
 									af4, transport,
 									even_port, in_reservation_token, &out_reservation_token,
@@ -1263,9 +1279,7 @@ static int handle_turn_allocate(turn_turnserver *server,
 								}
 							}
 						}
-						int err_code6 = 0;
-						const u08bits *reason6 = NULL;
-						if(af6) {
+						{
 							int af6res = create_relay_connection(server, ss, lifetime,
 												af6, transport,
 												even_port, in_reservation_token, &out_reservation_token,
@@ -1373,6 +1387,19 @@ static int handle_turn_allocate(turn_turnserver *server,
 		*resp_constructed = 1;
 	}
 
+	if(*resp_constructed && !(*err_code)) {
+		if(err_code4) {
+			size_t len = ioa_network_buffer_get_size(nbh);
+			stun_attr_add_address_error_code(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4, (u08bits)err_code4);
+			ioa_network_buffer_set_size(nbh,len);
+		}
+		if(err_code6) {
+			size_t len = ioa_network_buffer_get_size(nbh);
+			stun_attr_add_address_error_code(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6, (u08bits)err_code6);
+			ioa_network_buffer_set_size(nbh,len);
+		}
+	}
+
 	return 0;
 }