Bug 1361894 - ignore STUN/TURN servers with mis-matched link local addr. r=bwc draft
authorMichael Froman <mfroman@mozilla.com>
Fri, 29 Sep 2017 09:20:07 -0500
changeset 673453 98d3100010c50a21bd48c474aac140e8e1636271
parent 673329 97efdde466f18cf580fda9673cf4c38ee21fc7b7
child 734115 94a26793bf636636f0fcd2b7b6b07b556467f862
push id82589
push userbmo:mfroman@nostrum.com
push dateMon, 02 Oct 2017 16:40:32 +0000
reviewersbwc
bugs1361894
milestone58.0a1
Bug 1361894 - ignore STUN/TURN servers with mis-matched link local addr. r=bwc MozReview-Commit-ID: FMRWMHCROUf
media/mtransport/third_party/nICEr/src/ice/ice_candidate.c
media/mtransport/third_party/nICEr/src/ice/ice_component.c
media/mtransport/third_party/nICEr/src/net/transport_addr.c
media/mtransport/third_party/nICEr/src/net/transport_addr.h
--- a/media/mtransport/third_party/nICEr/src/ice/ice_candidate.c
+++ b/media/mtransport/third_party/nICEr/src/ice/ice_candidate.c
@@ -671,16 +671,21 @@ static int nr_ice_candidate_resolved_cb(
             cand->ctx->label,cand->label,addr->as_string);
     }
     else {
       r_log(LOG_ICE,LOG_WARNING,"ICE(%s): failed to resolve candidate %s.",
             cand->ctx->label,cand->label);
       ABORT(R_NOT_FOUND);
     }
 
+    if (nr_transport_addr_check_compatibility(addr, &cand->base)) {
+      r_log(LOG_ICE,LOG_WARNING,"ICE(%s): Skipping STUN server because of link local mis-match for candidate %s",cand->ctx->label,cand->label);
+      ABORT(R_NOT_FOUND);
+    }
+
     /* Copy the address */
     if(r=nr_transport_addr_copy(&cand->stun_server_addr,addr))
       ABORT(r);
 
     if (cand->tcp_type == TCP_TYPE_PASSIVE || cand->tcp_type == TCP_TYPE_SO){
       if (r=nr_socket_multi_tcp_stun_server_connect(cand->osock, addr))
         ABORT(r);
     }
--- a/media/mtransport/third_party/nICEr/src/ice/ice_component.c
+++ b/media/mtransport/third_party/nICEr/src/ice/ice_component.c
@@ -244,16 +244,25 @@ static int nr_ice_component_initialize_u
         cand=0;
 
         /* And a srvrflx candidate for each STUN server */
         for(j=0;j<ctx->stun_server_ct;j++){
           /* Skip non-UDP */
           if(ctx->stun_servers[j].transport!=IPPROTO_UDP)
             continue;
 
+          if (ctx->stun_servers[j].type == NR_ICE_STUN_SERVER_TYPE_ADDR) {
+            if (nr_transport_addr_check_compatibility(
+                  &addrs[i].addr,
+                  &ctx->stun_servers[j].u.addr)) {
+              r_log(LOG_ICE,LOG_INFO,"ICE(%s): Skipping STUN server because of link local mis-match",ctx->label);
+              continue;
+            }
+          }
+
           /* Ensure id is set (nr_ice_ctx_set_stun_servers does not) */
           ctx->stun_servers[j].id = j;
           if(r=nr_ice_candidate_create(ctx,component,
             isock,sock,SERVER_REFLEXIVE,0,
             &ctx->stun_servers[j],component->component_id,&cand))
             ABORT(r);
           TAILQ_INSERT_TAIL(&component->candidates,cand,entry_comp);
           component->candidate_ct++;
@@ -274,16 +283,25 @@ static int nr_ice_component_initialize_u
       for(j=0;j<ctx->turn_server_ct;j++){
         nr_socket *turn_sock;
         nr_ice_candidate *srvflx_cand=0;
 
         /* Skip non-UDP */
         if (ctx->turn_servers[j].turn_server.transport != IPPROTO_UDP)
           continue;
 
+        if (ctx->turn_servers[j].turn_server.type == NR_ICE_STUN_SERVER_TYPE_ADDR) {
+          if (nr_transport_addr_check_compatibility(
+                &addrs[i].addr,
+                &ctx->turn_servers[j].turn_server.u.addr)) {
+            r_log(LOG_ICE,LOG_INFO,"ICE(%s): Skipping TURN server because of link local mis-match",ctx->label);
+            continue;
+          }
+        }
+
         if (!(ctx->flags & NR_ICE_CTX_FLAGS_RELAY_ONLY)) {
           /* Ensure id is set with a unique value */
           ctx->turn_servers[j].turn_server.id = j + ctx->stun_server_ct;
           /* srvrflx */
           if(r=nr_ice_candidate_create(ctx,component,
             isock,sock,SERVER_REFLEXIVE,0,
             &ctx->turn_servers[j].turn_server,component->component_id,&cand))
             ABORT(r);
@@ -509,22 +527,23 @@ static int nr_ice_component_initialize_t
         nr_socket *buffered_sock;
         nr_socket *turn_sock;
         nr_ice_socket *turn_isock;
 
         /* Skip non-TCP */
         if (ctx->turn_servers[j].turn_server.transport != IPPROTO_TCP)
           continue;
 
-        if (ctx->turn_servers[j].turn_server.type == NR_ICE_STUN_SERVER_TYPE_ADDR &&
-            nr_transport_addr_cmp(&ctx->turn_servers[j].turn_server.u.addr,
-                                  &addrs[i].addr,
-                                  NR_TRANSPORT_ADDR_CMP_MODE_VERSION)) {
-          r_log(LOG_ICE,LOG_INFO,"ICE(%s): Skipping TURN server because of IP version mis-match (%u - %u)",ctx->label,addrs[i].addr.ip_version,ctx->turn_servers[j].turn_server.u.addr.ip_version);
-          continue;
+        if (ctx->turn_servers[j].turn_server.type == NR_ICE_STUN_SERVER_TYPE_ADDR) {
+          if (nr_transport_addr_check_compatibility(
+                &addrs[i].addr,
+                &ctx->turn_servers[j].turn_server.u.addr)) {
+            r_log(LOG_ICE,LOG_INFO,"ICE(%s): Skipping TURN server because of link local mis-match",ctx->label);
+            continue;
+          }
         }
 
         if (!ice_tcp_disabled) {
           /* Use TURN server to get srflx candidates */
           if (isock_psv) {
             if(r=nr_ice_candidate_create(ctx,component,
               isock_psv,isock_psv->sock,SERVER_REFLEXIVE,TCP_TYPE_PASSIVE,
               &ctx->turn_servers[j].turn_server,component->component_id,&cand))
--- a/media/mtransport/third_party/nICEr/src/net/transport_addr.c
+++ b/media/mtransport/third_party/nICEr/src/net/transport_addr.c
@@ -431,16 +431,31 @@ int nr_transport_addr_is_link_local(nr_t
         break;
       default:
         UNIMPLEMENTED;
     }
 
     return(0);
   }
 
+int nr_transport_addr_check_compatibility(nr_transport_addr *addr1, nr_transport_addr *addr2)
+  {
+    // first make sure we're comparing the same ip versions and protocols
+    if ((addr1->ip_version != addr2->ip_version) ||
+        (addr1->protocol != addr2->protocol)) {
+      return(1);
+    }
+    // now make sure the link local status matches
+    if (nr_transport_addr_is_link_local(addr1) !=
+        nr_transport_addr_is_link_local(addr2)) {
+      return(1);
+    }
+    return(0);
+  }
+
 int nr_transport_addr_is_wildcard(nr_transport_addr *addr)
   {
     switch(addr->ip_version){
       case NR_IPV4:
         if(addr->u.addr4.sin_addr.s_addr==INADDR_ANY)
           return(1);
         if(addr->u.addr4.sin_port==0)
           return(1);
--- a/media/mtransport/third_party/nICEr/src/net/transport_addr.h
+++ b/media/mtransport/third_party/nICEr/src/net/transport_addr.h
@@ -88,16 +88,17 @@ int nr_transport_addr_cmp(nr_transport_a
 #define NR_TRANSPORT_ADDR_CMP_MODE_PROTOCOL  2
 #define NR_TRANSPORT_ADDR_CMP_MODE_ADDR      3
 #define NR_TRANSPORT_ADDR_CMP_MODE_ALL       4
 
 int nr_transport_addr_is_wildcard(nr_transport_addr *addr);
 int nr_transport_addr_is_loopback(nr_transport_addr *addr);
 int nr_transport_addr_get_private_addr_range(nr_transport_addr *addr);
 int nr_transport_addr_is_link_local(nr_transport_addr *addr);
+int nr_transport_addr_check_compatibility(nr_transport_addr *addr1, nr_transport_addr *addr2);
 int nr_transport_addr_copy(nr_transport_addr *to, nr_transport_addr *from);
 int nr_transport_addr_copy_keep_ifname(nr_transport_addr *to, nr_transport_addr *from);
 int nr_transport_addr_fmt_addr_string(nr_transport_addr *addr);
 int nr_transport_addr_fmt_ifname_addr_string(const nr_transport_addr *addr, char *buf, int len);
 int nr_transport_addr_set_port(nr_transport_addr *addr, int port);
 int nr_transport_addr_is_reliable_transport(nr_transport_addr *addr);
 
 #endif