Bug 1408218: ignore EUI 64 and Teredo addresses if not needed. r?bwc
MozReview-Commit-ID: 5QHi9iC2e7y
--- a/media/mtransport/nrinterfaceprioritizer.cpp
+++ b/media/mtransport/nrinterfaceprioritizer.cpp
@@ -106,16 +106,20 @@ private:
return 1;
}
if (type & NR_INTERFACE_TYPE_WIFI) {
return 2;
}
if (type & NR_INTERFACE_TYPE_MOBILE) {
return 3;
}
+ if (type & NR_INTERFACE_TYPE_TEREDO) {
+ // Teredo gets penalty because it's IP relayed
+ return 5;
+ }
return 4;
}
// TODO(bug 895790): Once we can get useful interface properties on Darwin,
// we should remove this stuff.
static const std::vector<std::string>& interface_preference_list()
{
static std::vector<std::string> list(build_interface_preference_list());
--- a/media/mtransport/third_party/nICEr/src/net/local_addr.h
+++ b/media/mtransport/third_party/nICEr/src/net/local_addr.h
@@ -40,16 +40,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE
typedef struct nr_interface_ {
int type;
#define NR_INTERFACE_TYPE_UNKNOWN 0x0
#define NR_INTERFACE_TYPE_WIRED 0x1
#define NR_INTERFACE_TYPE_WIFI 0x2
#define NR_INTERFACE_TYPE_MOBILE 0x4
#define NR_INTERFACE_TYPE_VPN 0x8
+#define NR_INTERFACE_TYPE_TEREDO 0x16
int estimated_speed; /* Speed in kbps */
} nr_interface;
typedef struct nr_local_addr_ {
nr_transport_addr addr;
nr_interface interface;
} nr_local_addr;
--- 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,59 @@ int nr_transport_addr_is_link_local(nr_t
break;
default:
UNIMPLEMENTED;
}
return(0);
}
+int nr_transport_addr_is_mac_based(nr_transport_addr *addr)
+ {
+ switch(addr->ip_version){
+ case NR_IPV4:
+ // IPv4 has no MAC based self assigned IP addresses
+ return(0);
+ case NR_IPV6:
+ {
+ // RFC 2373, Appendix A: lower 64bit 0x020000FFFE000000
+ // indicates a MAC based IPv6 address
+ UINT4* macCom = (UINT4*)(addr->u.addr6.sin6_addr.s6_addr + 8);
+ UINT4* macExt = (UINT4*)(addr->u.addr6.sin6_addr.s6_addr + 12);
+ if ((*macCom & htonl(0x020000FF)) == htonl(0x020000FF) &&
+ (*macExt & htonl(0xFF000000)) == htonl(0xFE000000)) {
+ return(1);
+ }
+ }
+ break;
+ default:
+ UNIMPLEMENTED;
+ }
+ return(0);
+ }
+
+int nr_transport_addr_is_teredo(nr_transport_addr *addr)
+ {
+ switch(addr->ip_version){
+ case NR_IPV4:
+ return(0);
+ case NR_IPV6:
+ {
+ UINT4* addrTop = (UINT4*)(addr->u.addr6.sin6_addr.s6_addr);
+ if ((*addrTop & htonl(0xFFFF0000)) == htonl(0x20010000))
+ return(1);
+ }
+ 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
--- 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,18 @@ 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_is_mac_based(nr_transport_addr *addr);
+int nr_transport_addr_is_teredo(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);
--- a/media/mtransport/third_party/nICEr/src/stun/addrs.c
+++ b/media/mtransport/third_party/nICEr/src/stun/addrs.c
@@ -367,34 +367,57 @@ nr_stun_is_duplicate_addr(nr_local_addr
int
nr_stun_remove_duplicate_addrs(nr_local_addr addrs[], int remove_loopback, int remove_link_local, int *count)
{
int r, _status;
nr_local_addr *tmp = 0;
int i;
int n;
+ int contains_mac_based_ipv6 = 0;
+ int contains_teredo_ipv6 = 0;
+ int contains_regular_ipv6 = 0;
tmp = RMALLOC(*count * sizeof(*tmp));
if (!tmp)
ABORT(R_NO_MEMORY);
+ for (i = 0; i < *count; ++i) {
+ if (nr_transport_addr_is_mac_based(&addrs[i].addr)) {
+ contains_mac_based_ipv6 = 1;
+ }
+ else if (nr_transport_addr_is_teredo(&addrs[i].addr)) {
+ addrs[i].interface.type |= NR_INTERFACE_TYPE_TEREDO;
+ contains_teredo_ipv6 = 1;
+ }
+ else if (addrs[i].addr.ip_version == NR_IPV6) {
+ contains_regular_ipv6 = 1;
+ }
+ }
+
n = 0;
for (i = 0; i < *count; ++i) {
if (nr_stun_is_duplicate_addr(tmp, n, &addrs[i])) {
/* skip addrs[i], it's a duplicate */
}
else if (remove_loopback && nr_transport_addr_is_loopback(&addrs[i].addr)) {
/* skip addrs[i], it's a loopback */
}
else if (remove_link_local &&
- addrs[i].addr.ip_version == NR_IPV6 &&
nr_transport_addr_is_link_local(&addrs[i].addr)) {
/* skip addrs[i], it's a link-local address */
}
+ else if (contains_regular_ipv6 &&
+ nr_transport_addr_is_mac_based(&addrs[i].addr)) {
+ /* skip addrs[i], it's MAC based */
+ }
+ else if (contains_regular_ipv6 &&
+ nr_transport_addr_is_teredo(&addrs[i].addr)) {
+ /* skip addrs[i], it's a Teredo address */
+ }
else {
/* otherwise, copy it to the temporary array */
if ((r=nr_local_addr_copy(&tmp[n], &addrs[i])))
ABORT(r);
++n;
}
}