Bug 1309641: only store a single pre-answer request per 5 tuple. r=bwc
authorNils Ohlmeier [:drno] <drno@ohlmeier.org>
Wed, 26 Oct 2016 21:43:27 -0700
changeset 320117 bcccdc43232ba3b6b44924605e98bff5e04af64f
parent 320116 b3a08a040c8a870eb9902998d7909918cff32e2a
child 320118 b7e94b82004ec38beaf69fce2176433745b277c7
push id30883
push userryanvm@gmail.com
push dateSat, 29 Oct 2016 13:12:57 +0000
treeherdermozilla-central@dc422956242b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbwc
bugs1309641
milestone52.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1309641: only store a single pre-answer request per 5 tuple. r=bwc MozReview-Commit-ID: KzrGGRRU28J
media/mtransport/third_party/nICEr/src/ice/ice_component.c
--- a/media/mtransport/third_party/nICEr/src/ice/ice_component.c
+++ b/media/mtransport/third_party/nICEr/src/ice/ice_component.c
@@ -52,29 +52,29 @@ static char *RCSSTRING __UNUSED__="$Id: 
 #include "r_time.h"
 
 static int nr_ice_component_stun_server_default_cb(void *cb_arg,nr_stun_server_ctx *stun_ctx,nr_socket *sock, nr_stun_server_request *req, int *dont_free, int *error);
 static int nr_ice_pre_answer_request_destroy(nr_ice_pre_answer_request **parp);
 void nr_ice_component_consent_schedule_consent_timer(nr_ice_component *comp);
 void nr_ice_component_consent_destroy(nr_ice_component *comp);
 
 /* This function takes ownership of the contents of req (but not req itself) */
-static int nr_ice_pre_answer_request_create(nr_socket *sock, nr_stun_server_request *req, nr_ice_pre_answer_request **parp)
+static int nr_ice_pre_answer_request_create(nr_transport_addr *dst, nr_stun_server_request *req, nr_ice_pre_answer_request **parp)
   {
     int r, _status;
     nr_ice_pre_answer_request *par = 0;
     nr_stun_message_attribute *attr;
 
     if (!(par = RCALLOC(sizeof(nr_ice_pre_answer_request))))
       ABORT(R_NO_MEMORY);
 
     par->req = *req; /* Struct assignment */
     memset(req, 0, sizeof(*req)); /* Zero contents to avoid confusion */
 
-    if (r=nr_socket_getaddr(sock, &par->local_addr))
+    if (r=nr_transport_addr_copy(&par->local_addr, dst))
       ABORT(r);
     if (!nr_stun_message_has_attribute(par->req.request, NR_STUN_ATTR_USERNAME, &attr))
       ABORT(R_INTERNAL);
     if (!(par->username = r_strdup(attr->u.username)))
       ABORT(R_NO_MEMORY);
 
     *parp=par;
     _status=0;
@@ -1136,34 +1136,71 @@ int nr_ice_component_pair_candidates(nr_
 
     pcomp->state = NR_ICE_COMPONENT_RUNNING;
 
     _status=0;
   abort:
     return(_status);
   }
 
+int nr_ice_pre_answer_enqueue(nr_ice_component *comp, nr_socket *sock, nr_stun_server_request *req, int *dont_free)
+  {
+    int r = 0;
+    int _status;
+    nr_ice_pre_answer_request *r1, *r2;
+    nr_transport_addr dst_addr;
+    nr_ice_pre_answer_request *par = 0;
+
+    if (r=nr_socket_getaddr(sock, &dst_addr))
+      ABORT(r);
+
+    STAILQ_FOREACH_SAFE(r1, &comp->pre_answer_reqs, entry, r2) {
+      if (!nr_transport_addr_cmp(&r1->local_addr, &dst_addr,
+                                 NR_TRANSPORT_ADDR_CMP_MODE_ALL) &&
+          !nr_transport_addr_cmp(&r1->req.src_addr, &req->src_addr,
+                                 NR_TRANSPORT_ADDR_CMP_MODE_ALL)) {
+        return(0);
+      }
+    }
+
+    if (r=nr_ice_pre_answer_request_create(&dst_addr, req, &par))
+      ABORT(r);
+
+    r_log(LOG_ICE,LOG_DEBUG, "ICE(%s)/STREAM(%s)/COMP(%d): Enqueuing STUN request pre-answer from %s",
+          comp->ctx->label, comp->stream->label, comp->component_id,
+          req->src_addr.as_string);
+
+    *dont_free = 1;
+    STAILQ_INSERT_TAIL(&comp->pre_answer_reqs, par, entry);
+
+    _status=0;
+abort:
+    return(_status);
+  }
+
 /* Fires when we have an incoming candidate that doesn't correspond to an existing
    remote peer. This is either pre-answer or just spurious. Store it in the
    component for use when we see the actual answer, at which point we need
    to do the procedures from S 7.2.1 in nr_ice_component_stun_server_cb.
  */
 static int nr_ice_component_stun_server_default_cb(void *cb_arg,nr_stun_server_ctx *stun_ctx,nr_socket *sock, nr_stun_server_request *req, int *dont_free, int *error)
   {
     int r, _status;
     nr_ice_component *comp = (nr_ice_component *)cb_arg;
-    nr_ice_pre_answer_request *par = 0;
+
     r_log(LOG_ICE,LOG_DEBUG,"ICE(%s)/STREAM(%s)/COMP(%d): Received STUN request pre-answer from %s",
-          comp->ctx->label, comp->stream->label, comp->component_id, req->src_addr.as_string);
+          comp->ctx->label, comp->stream->label, comp->component_id,
+          req->src_addr.as_string);
 
-    if (r=nr_ice_pre_answer_request_create(sock, req, &par))
+    if (r=nr_ice_pre_answer_enqueue(comp, sock, req, dont_free)) {
+      r_log(LOG_ICE,LOG_ERR,"ICE(%s)/STREAM(%s)/COMP(%d): Failed (%d) to enque pre-answer request from %s",
+          comp->ctx->label, comp->stream->label, comp->component_id, r,
+          req->src_addr.as_string);
       ABORT(r);
-
-    *dont_free = 1;
-    STAILQ_INSERT_TAIL(&comp->pre_answer_reqs, par, entry);
+    }
 
     _status=0;
  abort:
     return(_status);
   }
 
 #define NR_ICE_CONSENT_TIMER_DEFAULT 5000
 #define NR_ICE_CONSENT_TIMEOUT_DEFAULT 30000