Bug 1361894 - ignore STUN/TURN servers with mis-matched link local addr. r=bwc
MozReview-Commit-ID: FMRWMHCROUf
--- 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