--- 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