Add support for ice-tcp priorities, udp-tunneled and nat-assisted priorities
authorYouness Alaoui <youness.alaoui@collabora.co.uk>
Wed, 9 Apr 2014 00:21:55 +0000 (20:21 -0400)
committerOlivier CrĂȘte <olivier.crete@ocrete.ca>
Thu, 15 May 2014 13:43:59 +0000 (09:43 -0400)
agent/agent.c
agent/candidate.c
agent/candidate.h
agent/conncheck.c
agent/discovery.c
agent/discovery.h
tests/test-priority.c

index 5138597..5a33c0d 100644 (file)
@@ -2084,7 +2084,8 @@ static void _upnp_mapped_external_port (GUPnPSimpleIgd *self, gchar *proto,
               component->id,
               &externaddr,
               transport,
-              local_candidate->sockptr);
+              local_candidate->sockptr,
+              TRUE);
           goto end;
         }
       }
index f326482..06d3894 100644 (file)
@@ -133,28 +133,89 @@ nice_candidate_ice_priority_full (
       (0x100 - component_id));
 }
 
+static guint32
+nice_candidate_ice_local_priority_full (guint direction_preference,
+    guint other_preference)
+{
+  return (0x2000 * direction_preference +
+      other_preference);
+}
+
+static guint16
+nice_candidate_ice_local_priority (const NiceCandidate *candidate)
+{
+  guint direction_preference;
+
+  switch (candidate->transport)
+    {
+      case NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE:
+        if (candidate->type == NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE ||
+            candidate->type == NICE_CANDIDATE_TYPE_PREF_NAT_ASSISTED)
+          direction_preference = 4;
+        else
+          direction_preference = 6;
+        break;
+      case NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE:
+        if (candidate->type == NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE ||
+            candidate->type == NICE_CANDIDATE_TYPE_PREF_NAT_ASSISTED)
+          direction_preference = 2;
+        else
+          direction_preference = 4;
+        break;
+      case NICE_CANDIDATE_TRANSPORT_TCP_SO:
+        if (candidate->type == NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE ||
+            candidate->type == NICE_CANDIDATE_TYPE_PREF_NAT_ASSISTED)
+          direction_preference = 6;
+        else
+          direction_preference = 2;
+        break;
+      case NICE_CANDIDATE_TRANSPORT_UDP:
+      default:
+        return 1;
+        break;
+    }
+
+  return nice_candidate_ice_local_priority_full (direction_preference, 1);
+}
 
 guint32
-nice_candidate_ice_priority (const NiceCandidate *candidate)
+nice_candidate_ice_priority (const NiceCandidate *candidate,
+    gboolean reliable, gboolean nat_assisted)
 {
   guint8 type_preference;
+  guint16 local_preference;
 
   switch (candidate->type)
     {
     case NICE_CANDIDATE_TYPE_HOST:
-      type_preference = NICE_CANDIDATE_TYPE_PREF_HOST; break;
+      type_preference = NICE_CANDIDATE_TYPE_PREF_HOST;
+      break;
     case NICE_CANDIDATE_TYPE_PEER_REFLEXIVE:
-      type_preference = NICE_CANDIDATE_TYPE_PREF_PEER_REFLEXIVE; break;
+      type_preference = NICE_CANDIDATE_TYPE_PREF_PEER_REFLEXIVE;
+      break;
     case NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE:
-      type_preference = NICE_CANDIDATE_TYPE_PREF_SERVER_REFLEXIVE; break;
+      if (nat_assisted)
+        type_preference = NICE_CANDIDATE_TYPE_PREF_NAT_ASSISTED;
+      else
+        type_preference = NICE_CANDIDATE_TYPE_PREF_SERVER_REFLEXIVE;
+      break;
     case NICE_CANDIDATE_TYPE_RELAYED:
-      type_preference = NICE_CANDIDATE_TYPE_PREF_RELAYED; break;
+      type_preference = NICE_CANDIDATE_TYPE_PREF_RELAYED;
+      break;
     default:
-      type_preference = 0; break;
+      type_preference = 0;
+      break;
     }
 
-  /* return _candidate_ice_priority (type_preference, 1, candidate->component_id); */
-  return nice_candidate_ice_priority_full (type_preference, 1, candidate->component_id);
+  if (reliable && candidate->transport == NICE_CANDIDATE_TRANSPORT_UDP) {
+    type_preference = NICE_CANDIDATE_TYPE_PREF_UDP_TUNNELED;
+  } else if (!reliable && candidate->transport != NICE_CANDIDATE_TRANSPORT_UDP) {
+    type_preference = type_preference / 2 - 1;
+  }
+  local_preference = nice_candidate_ice_local_priority (candidate);
+
+  return nice_candidate_ice_priority_full (type_preference, local_preference,
+      candidate->component_id);
 }
 
 /*
index d492e5c..006e377 100644 (file)
@@ -59,7 +59,9 @@ G_BEGIN_DECLS
 
 #define NICE_CANDIDATE_TYPE_PREF_HOST                 120
 #define NICE_CANDIDATE_TYPE_PREF_PEER_REFLEXIVE       110
+#define NICE_CANDIDATE_TYPE_PREF_NAT_ASSISTED         105
 #define NICE_CANDIDATE_TYPE_PREF_SERVER_REFLEXIVE     100
+#define NICE_CANDIDATE_TYPE_PREF_UDP_TUNNELED          75
 #define NICE_CANDIDATE_TYPE_PREF_RELAYED               60
 
 /* Max foundation size '1*32ice-char' plus terminating NULL, ICE ID-19  */
@@ -230,7 +232,8 @@ nice_candidate_ice_priority_full (guint type_pref, guint local_pref,
     guint component_id);
 
 guint32
-nice_candidate_ice_priority (const NiceCandidate *candidate);
+nice_candidate_ice_priority (const NiceCandidate *candidate,
+    gboolean reliable, gboolean nat_assisted);
 
 guint64
 nice_candidate_pair_priority (guint32 o_prio, guint32 a_prio);
index bfbf30d..66142be 100644 (file)
@@ -2335,7 +2335,8 @@ static gboolean priv_map_reply_to_discovery_request (NiceAgent *agent, StunMessa
               d->component->id,
               &niceaddr,
               NICE_CANDIDATE_TRANSPORT_UDP,
-              d->nicesock);
+              d->nicesock,
+              FALSE);
 
           d->stun_message.buffer = NULL;
           d->stun_message.buffer_len = 0;
@@ -2473,7 +2474,8 @@ static gboolean priv_map_reply_to_relay_request (NiceAgent *agent, StunMessage *
                 d->component->id,
                 &niceaddr,
                 NICE_CANDIDATE_TRANSPORT_UDP,
-                d->nicesock);
+                d->nicesock,
+                FALSE);
           }
 
           nice_address_set_from_sockaddr (&niceaddr, &relayaddr.addr);
index 3aeeccc..f63d3dc 100644 (file)
@@ -486,7 +486,8 @@ NiceCandidate *discovery_add_local_host_candidate (
              agent->compatibility == NICE_COMPATIBILITY_OC2007)  {
     candidate->priority = nice_candidate_msn_priority (candidate);
   } else {
-    candidate->priority = nice_candidate_ice_priority (candidate);
+    candidate->priority = nice_candidate_ice_priority (candidate,
+        agent->reliable, FALSE);
   }
 
   priv_generate_candidate_credentials (agent, candidate);
@@ -534,7 +535,8 @@ discovery_add_server_reflexive_candidate (
   guint component_id,
   NiceAddress *address,
   NiceCandidateTransport transport,
-  NiceSocket *base_socket)
+  NiceSocket *base_socket,
+  gboolean nat_assisted)
 {
   NiceCandidate *candidate;
   Component *component;
@@ -556,7 +558,8 @@ discovery_add_server_reflexive_candidate (
              agent->compatibility == NICE_COMPATIBILITY_OC2007)  {
     candidate->priority = nice_candidate_msn_priority (candidate);
   } else {
-    candidate->priority =  nice_candidate_ice_priority (candidate);
+    candidate->priority =  nice_candidate_ice_priority (candidate,
+        agent->reliable, nat_assisted);
   }
 
   /* step: link to the base candidate+socket */
@@ -616,7 +619,8 @@ discovery_add_relay_candidate (
              agent->compatibility == NICE_COMPATIBILITY_OC2007)  {
     candidate->priority = nice_candidate_msn_priority (candidate);
   } else {
-    candidate->priority =  nice_candidate_ice_priority (candidate);
+    candidate->priority =  nice_candidate_ice_priority (candidate,
+        agent->reliable, FALSE);
   }
 
   /* step: link to the base candidate+socket */
@@ -692,7 +696,8 @@ discovery_add_peer_reflexive_candidate (
              agent->compatibility == NICE_COMPATIBILITY_OC2007)  {
     candidate->priority = nice_candidate_msn_priority (candidate);
   } else {
-    candidate->priority = nice_candidate_ice_priority (candidate);
+    candidate->priority = nice_candidate_ice_priority (candidate,
+        agent->reliable, FALSE);
   }
 
   priv_assign_foundation (agent, candidate);
@@ -785,7 +790,8 @@ NiceCandidate *discovery_learn_remote_peer_reflexive_candidate (
              agent->compatibility == NICE_COMPATIBILITY_OC2007)  {
     candidate->priority = nice_candidate_msn_priority (candidate);
   } else {
-    candidate->priority = nice_candidate_ice_priority (candidate);
+    candidate->priority = nice_candidate_ice_priority (candidate,
+        agent->reliable, FALSE);
   }
 
   priv_assign_remote_foundation (agent, candidate);
index 6befb54..5afed71 100644 (file)
@@ -117,7 +117,8 @@ discovery_add_server_reflexive_candidate (
   guint component_id,
   NiceAddress *address,
   NiceCandidateTransport transport,
-  NiceSocket *base_socket);
+  NiceSocket *base_socket,
+  gboolean nat_assisted);
 
 NiceCandidate* 
 discovery_add_peer_reflexive_candidate (
index 72f1277..7a52c3c 100644 (file)
@@ -47,7 +47,9 @@ main (void)
 
   /* test 1 */
   candidate = nice_candidate_new (NICE_CANDIDATE_TYPE_HOST);
-  g_assert (nice_candidate_ice_priority (candidate) == 0x78000200);
+  candidate->transport = NICE_CANDIDATE_TRANSPORT_UDP;
+  candidate->component_id = 1;
+  g_assert (nice_candidate_ice_priority (candidate, FALSE, FALSE) == 0x780001FF);
   g_assert (nice_candidate_jingle_priority (candidate) == 1000);
   nice_candidate_free (candidate);