Bug 1183145: Move platform-specific code from addrs.c into separate files. r=mjf
authorByron Campen [:bwc] <docfaraday@gmail.com>
Tue, 26 May 2020 15:26:27 +0000
changeset 533703 24a4472452b8e0f24416db3e889e171c0206e695
parent 533702 a74c4666960646f2d6cf4b4e7822e082e963b179
child 533704 99cce372d20cc3cc99df7728b950fa8fcc234bc1
push id37476
push userccoroiu@mozilla.com
push dateWed, 03 Jun 2020 21:49:22 +0000
treeherdermozilla-central@66d3efe9fc7a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmjf
bugs1183145
milestone79.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 1183145: Move platform-specific code from addrs.c into separate files. r=mjf Differential Revision: https://phabricator.services.mozilla.com/D75947
media/mtransport/third_party/nICEr/IMPORT_FILES
media/mtransport/third_party/nICEr/nicer.gyp
media/mtransport/third_party/nICEr/src/stun/addrs-bsd.c
media/mtransport/third_party/nICEr/src/stun/addrs-bsd.h
media/mtransport/third_party/nICEr/src/stun/addrs-netlink.c
media/mtransport/third_party/nICEr/src/stun/addrs-netlink.h
media/mtransport/third_party/nICEr/src/stun/addrs-win32.c
media/mtransport/third_party/nICEr/src/stun/addrs-win32.h
media/mtransport/third_party/nICEr/src/stun/addrs.c
media/mtransport/third_party/nICEr/src/stun/ifaddrs-android.c
media/mtransport/third_party/nICEr/src/stun/ifaddrs-android.h
--- a/media/mtransport/third_party/nICEr/IMPORT_FILES
+++ b/media/mtransport/third_party/nICEr/IMPORT_FILES
@@ -32,18 +32,22 @@
                 ./src/net/transport_addr.c
                 ./src/net/transport_addr.h
                 ./src/net/transport_addr_reg.c
                 ./src/net/transport_addr_reg.h
 
                 # STUN
                 ./src/stun/addrs.c
                 ./src/stun/addrs.h
-                ./src/stun/ifaddrs-android.c
-                ./src/stun/ifaddrs-android.h
+                ./src/stun/addrs-bsd.c
+                ./src/stun/addrs-bsd.h
+                ./src/stun/addrs-netlink.c
+                ./src/stun/addrs-netlink.h
+                ./src/stun/addrs-win32.c
+                ./src/stun/addrs-win32.h
                 ./src/stun/nr_socket_turn.c
                 ./src/stun/nr_socket_turn.h
                 ./src/stun/stun.h
                 ./src/stun/stun_build.c
                 ./src/stun/stun_build.h
                 ./src/stun/stun_client_ctx.c
                 ./src/stun/stun_client_ctx.h
                 ./src/stun/stun_codec.c
--- a/media/mtransport/third_party/nICEr/nicer.gyp
+++ b/media/mtransport/third_party/nICEr/nicer.gyp
@@ -80,18 +80,22 @@
                 "./src/net/local_addr.c",
                 "./src/net/local_addr.h",
                 "./src/net/nr_interface_prioritizer.c",
                 "./src/net/nr_interface_prioritizer.h",
 
                 # STUN
                 "./src/stun/addrs.c",
                 "./src/stun/addrs.h",
-                "./src/stun/ifaddrs-android.c",
-                "./src/stun/ifaddrs-android.h",
+                "./src/stun/addrs-bsd.c",
+                "./src/stun/addrs-bsd.h",
+                "./src/stun/addrs-netlink.c",
+                "./src/stun/addrs-netlink.h",
+                "./src/stun/addrs-win32.c",
+                "./src/stun/addrs-win32.h",
                 "./src/stun/nr_socket_turn.c",
                 "./src/stun/nr_socket_turn.h",
                 "./src/stun/nr_socket_buffered_stun.c",
                 "./src/stun/nr_socket_buffered_stun.h",
                 "./src/stun/stun.h",
                 "./src/stun/stun_build.c",
                 "./src/stun/stun_build.h",
                 "./src/stun/stun_client_ctx.c",
new file mode 100644
--- /dev/null
+++ b/media/mtransport/third_party/nICEr/src/stun/addrs-bsd.c
@@ -0,0 +1,68 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#if defined(BSD) || defined(DARWIN)
+#include "addrs-bsd.h"
+#include <csi_platform.h>
+#include <assert.h>
+#include <string.h>
+#include "util.h"
+#include "stun_util.h"
+#include "util.h"
+#include <r_macros.h>
+
+#include <sys/types.h> /* getifaddrs */
+#include <ifaddrs.h> /* getifaddrs */
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <netinet/in.h>
+
+int stun_getaddrs_filtered(nr_local_addr addrs[], int maxaddrs, int *count)
+{
+  int r,_status;
+  struct ifaddrs* if_addrs_head=NULL;
+  struct ifaddrs* if_addr;
+
+  *count = 0;
+
+  if (maxaddrs <= 0)
+    ABORT(R_BAD_ARGS);
+
+  if (getifaddrs(&if_addrs_head) == -1) {
+    r_log(NR_LOG_STUN, LOG_ERR, "getifaddrs error e = %d", errno);
+    ABORT(R_INTERNAL);
+  }
+
+  if_addr = if_addrs_head;
+
+  while (if_addr && *count < maxaddrs) {
+    /* This can be null */
+    if (if_addr->ifa_addr) {
+      switch (if_addr->ifa_addr->sa_family) {
+        case AF_INET:
+        case AF_INET6:
+          if (r=nr_sockaddr_to_transport_addr(if_addr->ifa_addr, IPPROTO_UDP, 0, &(addrs[*count].addr))) {
+            r_log(NR_LOG_STUN, LOG_ERR, "nr_sockaddr_to_transport_addr error r = %d", r);
+          } else {
+            (void)strlcpy(addrs[*count].addr.ifname, if_addr->ifa_name, sizeof(addrs[*count].addr.ifname));
+            ++(*count);
+          }
+          break;
+        default:
+          ;
+      }
+    }
+
+    if_addr = if_addr->ifa_next;
+  }
+
+  _status=0;
+abort:
+  if (if_addrs_head) {
+    freeifaddrs(if_addrs_head);
+  }
+  return(_status);
+}
+#endif
new file mode 100644
--- /dev/null
+++ b/media/mtransport/third_party/nICEr/src/stun/addrs-bsd.h
@@ -0,0 +1,13 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef STUN_IFADDRS_BSD_H_
+#define STUN_IFADDRS_BSD_H_
+
+#include "local_addr.h"
+
+int stun_getaddrs_filtered(nr_local_addr addrs[], int maxaddrs, int *count);
+
+#endif  /* STUN_IFADDRS_BSD_H_ */
+
rename from media/mtransport/third_party/nICEr/src/stun/ifaddrs-android.c
rename to media/mtransport/third_party/nICEr/src/stun/addrs-netlink.c
--- a/media/mtransport/third_party/nICEr/src/stun/ifaddrs-android.c
+++ b/media/mtransport/third_party/nICEr/src/stun/addrs-netlink.c
@@ -25,218 +25,235 @@ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-#if defined(ANDROID)
-#include "ifaddrs-android.h"
+#if defined(LINUX)
+#include "addrs-netlink.h"
+#include <csi_platform.h>
+#include <assert.h>
+#include <string.h>
+#include "util.h"
+#include "stun_util.h"
+#include "util.h"
+#include <r_macros.h>
+
 #include <stdlib.h>
-#include <string.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/utsname.h>
 #include <sys/ioctl.h>
 #include <netinet/in.h>
 #include <net/if.h>
 #include <unistd.h>
 #include <errno.h>
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>
 
+#ifdef ANDROID
+/* Work around an Android NDK < r8c bug */
+#undef __unused
+#else
+#include <linux/if.h> /* struct ifreq, IFF_POINTTOPOINT */
+#include <linux/wireless.h> /* struct iwreq */
+#include <linux/ethtool.h> /* struct ethtool_cmd */
+#include <linux/sockios.h> /* SIOCETHTOOL */
+#endif /* ANDROID */
+
+
 struct netlinkrequest {
   struct nlmsghdr header;
   struct ifaddrmsg msg;
 };
 
 static const int kMaxReadSize = 4096;
 
-static int set_ifname(struct ifaddrs* ifaddr, int interface) {
-  char buf[IFNAMSIZ] = {0};
-  char* name = if_indextoname(interface, buf);
-  if (name == NULL) {
-    return -1;
-  }
-  ifaddr->ifa_name = malloc(strlen(name) + 1);
-  strncpy(ifaddr->ifa_name, name, strlen(name) + 1);
-  return 0;
+static void set_ifname(nr_local_addr *addr, struct ifaddrmsg* msg) {
+  assert(sizeof(addr->addr.ifname) > IF_NAMESIZE);
+  if_indextoname(msg->ifa_index, addr->addr.ifname);
 }
 
-static int set_flags(struct ifaddrs* ifaddr) {
+static int get_siocgifflags(nr_local_addr *addr) {
   int fd = socket(AF_INET, SOCK_DGRAM, 0);
   if (fd == -1) {
-    return -1;
+    assert(0);
+    return 0;
   }
   struct ifreq ifr;
   memset(&ifr, 0, sizeof(ifr));
-  strncpy(ifr.ifr_name, ifaddr->ifa_name, IFNAMSIZ - 1);
+  strncpy(ifr.ifr_name, addr->addr.ifname, IFNAMSIZ - 1);
   int rc = ioctl(fd, SIOCGIFFLAGS, &ifr);
   close(fd);
   if (rc == -1) {
-    return -1;
+    assert(0);
+    return 0;
   }
-  ifaddr->ifa_flags = ifr.ifr_flags;
-  return 0;
+  return ifr.ifr_flags;
 }
 
-static int set_addresses(struct ifaddrs* ifaddr, struct ifaddrmsg* msg, void* data,
-                  size_t len) {
+static int set_sockaddr(nr_local_addr *addr, struct ifaddrmsg* msg, struct rtattr* rta) {
+  assert(rta->rta_type == IFA_ADDRESS);
+  void *data = RTA_DATA(rta);
+  size_t len = RTA_PAYLOAD(rta);
   if (msg->ifa_family == AF_INET) {
-    struct sockaddr_in* sa = malloc(sizeof(struct sockaddr_in));
-    memset(sa, 0, sizeof(struct sockaddr_in));
-    sa->sin_family = AF_INET;
-    memcpy(&sa->sin_addr, data, len);
-    ifaddr->ifa_addr = (struct sockaddr*)sa;
+    struct sockaddr_in sa;
+    memset(&sa, 0, sizeof(struct sockaddr_in));
+    sa.sin_family = AF_INET;
+    memcpy(&sa.sin_addr, data, len);
+    return nr_sockaddr_to_transport_addr((struct sockaddr*)&sa, IPPROTO_UDP, 0, &(addr->addr));
   } else if (msg->ifa_family == AF_INET6) {
-    struct sockaddr_in6* sa = malloc(sizeof(struct sockaddr_in6));
-    memset(sa, 0, sizeof(struct sockaddr_in6));
-    sa->sin6_family = AF_INET6;
-    sa->sin6_scope_id = msg->ifa_index;
-    memcpy(&sa->sin6_addr, data, len);
-    ifaddr->ifa_addr = (struct sockaddr*)sa;
-  } else {
-    return -1;
+    struct sockaddr_in6 sa;
+    memset(&sa, 0, sizeof(struct sockaddr_in6));
+    sa.sin6_family = AF_INET6;
+    /* We do not set sin6_scope_id to ifa_index, because that is only valid for
+     * link local addresses, and we don't use those anyway */
+    memcpy(&sa.sin6_addr, data, len);
+    return nr_sockaddr_to_transport_addr((struct sockaddr*)&sa, IPPROTO_UDP, 0, &(addr->addr));
   }
-  return 0;
+
+  return R_BAD_ARGS;
 }
 
-static int make_prefixes(struct ifaddrs* ifaddr, int family, int prefixlen) {
-  char* prefix = NULL;
-  if (family == AF_INET) {
-    struct sockaddr_in* mask = malloc(sizeof(struct sockaddr_in));
-    memset(mask, 0, sizeof(struct sockaddr_in));
-    mask->sin_family = AF_INET;
-    memset(&mask->sin_addr, 0, sizeof(struct in_addr));
-    ifaddr->ifa_netmask = (struct sockaddr*)mask;
-    if (prefixlen > 32) {
-      prefixlen = 32;
-    }
-    prefix = (char*)&mask->sin_addr;
-  } else if (family == AF_INET6) {
-    struct sockaddr_in6* mask = malloc(sizeof(struct sockaddr_in6));
-    memset(mask, 0, sizeof(struct sockaddr_in6));
-    mask->sin6_family = AF_INET6;
-    memset(&mask->sin6_addr, 0, sizeof(struct in6_addr));
-    ifaddr->ifa_netmask = (struct sockaddr*)mask;
-    if (prefixlen > 128) {
-      prefixlen = 128;
-    }
-    prefix = (char*)&mask->sin6_addr;
-  } else {
-    return -1;
+static int
+stun_convert_netlink(nr_local_addr *addr, struct ifaddrmsg *address_msg, struct rtattr* rta)
+{
+  int r = set_sockaddr(addr, address_msg, rta);
+  if (r) {
+    r_log(NR_LOG_STUN, LOG_ERR, "set_sockaddr error r = %d", r);
+    return r;
+  }
+
+  set_ifname(addr, address_msg);
+
+  int flags = get_siocgifflags(addr);
+  if (flags & IFF_POINTOPOINT)
+  {
+    addr->interface.type = NR_INTERFACE_TYPE_UNKNOWN | NR_INTERFACE_TYPE_VPN;
+    /* TODO (Bug 896913): find backend network type of this VPN */
   }
-  for (int i = 0; i < (prefixlen / 8); i++) {
-    *prefix++ = 0xFF;
+
+#if defined(LINUX) && !defined(ANDROID)
+  struct ethtool_cmd ecmd;
+  struct ifreq ifr;
+  struct iwreq wrq;
+  int e;
+  int s = socket(AF_INET, SOCK_DGRAM, 0);
+
+  strncpy(ifr.ifr_name, addr->addr.ifname, sizeof(ifr.ifr_name));
+  /* TODO (Bug 896851): interface property for Android */
+  /* Getting ethtool for ethernet information. */
+  ecmd.cmd = ETHTOOL_GSET;
+  /* In/out param */
+  ifr.ifr_data = (void*)&ecmd;
+
+  e = ioctl(s, SIOCETHTOOL, &ifr);
+  if (e == 0)
+  {
+    /* For wireless network, we won't get ethtool, it's a wired
+     * connection */
+    addr->interface.type = NR_INTERFACE_TYPE_WIRED;
+#ifdef DONT_HAVE_ETHTOOL_SPEED_HI
+    addr->interface.estimated_speed = ecmd.speed;
+#else
+    addr->interface.estimated_speed = ((ecmd.speed_hi << 16) | ecmd.speed) * 1000;
+#endif
   }
-  char remainder = 0xff;
-  remainder <<= (8 - prefixlen % 8);
-  *prefix = remainder;
+
+  strncpy(wrq.ifr_name, addr->addr.ifname, sizeof(wrq.ifr_name));
+  e = ioctl(s, SIOCGIWRATE, &wrq);
+  if (e == 0)
+  {
+    addr->interface.type = NR_INTERFACE_TYPE_WIFI;
+    addr->interface.estimated_speed = wrq.u.bitrate.value / 1000;
+  }
+
+  close(s);
+
+#else
+  addr->interface.type = NR_INTERFACE_TYPE_UNKNOWN;
+  addr->interface.estimated_speed = 0;
+#endif
   return 0;
 }
 
-static int populate_ifaddrs(struct ifaddrs* ifaddr, struct ifaddrmsg* msg, void* bytes,
-                     size_t len) {
-  if (set_ifname(ifaddr, msg->ifa_index) != 0) {
-    return -1;
-  }
-  if (set_flags(ifaddr) != 0) {
-    return -1;
-  }
-  if (set_addresses(ifaddr, msg, bytes, len) != 0) {
-    return -1;
-  }
-  if (make_prefixes(ifaddr, msg->ifa_family, msg->ifa_prefixlen) != 0) {
-    return -1;
-  }
-  return 0;
-}
+int
+stun_getaddrs_filtered(nr_local_addr addrs[], int maxaddrs, int *count)
+{
+  int _status;
+  int fd = 0;
+
+  /* Scope everything else since we're using ABORT. */
+  {
+    *count = 0;
+
+    if (maxaddrs <= 0)
+      ABORT(R_BAD_ARGS);
+
+    fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+    if (fd < 0) {
+      ABORT(R_INTERNAL);
+    }
+
+    struct netlinkrequest ifaddr_request;
+    memset(&ifaddr_request, 0, sizeof(ifaddr_request));
+    ifaddr_request.header.nlmsg_flags = NLM_F_ROOT | NLM_F_REQUEST;
+    ifaddr_request.header.nlmsg_type = RTM_GETADDR;
+    ifaddr_request.header.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
+
+    ssize_t bytes = send(fd, &ifaddr_request, ifaddr_request.header.nlmsg_len, 0);
+    if ((size_t)bytes != ifaddr_request.header.nlmsg_len) {
+      ABORT(R_INTERNAL);
+    }
 
-int android_getifaddrs(struct ifaddrs** result) {
-  int fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
-  if (fd < 0) {
-    return -1;
+    char buf[kMaxReadSize];
+    ssize_t amount_read = recv(fd, &buf, kMaxReadSize, 0);
+    while ((amount_read > 0) && (*count != maxaddrs)) {
+      struct nlmsghdr* header = (struct nlmsghdr*)&buf[0];
+      size_t header_size = (size_t)amount_read;
+      for ( ; NLMSG_OK(header, header_size) && (*count != maxaddrs);
+            header = NLMSG_NEXT(header, header_size)) {
+        switch (header->nlmsg_type) {
+          case NLMSG_DONE:
+            /* Success. Return. */
+            close(fd);
+            return 0;
+          case NLMSG_ERROR:
+            ABORT(R_INTERNAL);
+          case RTM_NEWADDR: {
+            struct ifaddrmsg* address_msg =
+                (struct ifaddrmsg*)NLMSG_DATA(header);
+            struct rtattr* rta = IFA_RTA(address_msg);
+            ssize_t payload_len = IFA_PAYLOAD(header);
+            while (RTA_OK(rta, payload_len)) {
+              if (rta->rta_type == IFA_ADDRESS) {
+                int family = address_msg->ifa_family;
+                if (family == AF_INET || family == AF_INET6) {
+                  if (stun_convert_netlink(&addrs[*count], address_msg, rta)) {
+                    assert(0);
+                  } else {
+                    ++(*count);
+                  }
+                }
+              }
+              /* TODO: Use IFA_LABEL instead of if_indextoname? We would need
+               * to remember how many nr_local_addr we've converted for this
+               * ifaddrmsg, and set the label on all of them. */
+              rta = RTA_NEXT(rta, payload_len);
+            }
+            break;
+          }
+        }
+      }
+      amount_read = recv(fd, &buf, kMaxReadSize, 0);
+    }
   }
 
-  struct netlinkrequest ifaddr_request;
-  memset(&ifaddr_request, 0, sizeof(ifaddr_request));
-  ifaddr_request.header.nlmsg_flags = NLM_F_ROOT | NLM_F_REQUEST;
-  ifaddr_request.header.nlmsg_type = RTM_GETADDR;
-  ifaddr_request.header.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
-
-  ssize_t count = send(fd, &ifaddr_request, ifaddr_request.header.nlmsg_len, 0);
-  if ((size_t)count != ifaddr_request.header.nlmsg_len) {
-    close(fd);
-    return -1;
-  }
-  struct ifaddrs* start = NULL;
-  struct ifaddrs* current = NULL;
-  char buf[kMaxReadSize];
-  ssize_t amount_read = recv(fd, &buf, kMaxReadSize, 0);
-  while (amount_read > 0) {
-    struct nlmsghdr* header = (struct nlmsghdr*)&buf[0];
-    size_t header_size = (size_t)amount_read;
-    for ( ; NLMSG_OK(header, header_size);
-          header = NLMSG_NEXT(header, header_size)) {
-      switch (header->nlmsg_type) {
-        case NLMSG_DONE:
-          /* Success. Return. */
-          *result = start;
-          close(fd);
-          return 0;
-        case NLMSG_ERROR:
-          close(fd);
-          android_freeifaddrs(start);
-          return -1;
-        case RTM_NEWADDR: {
-          struct ifaddrmsg* address_msg =
-              (struct ifaddrmsg*)NLMSG_DATA(header);
-          struct rtattr* rta = IFA_RTA(address_msg);
-          ssize_t payload_len = IFA_PAYLOAD(header);
-          while (RTA_OK(rta, payload_len)) {
-            if (rta->rta_type == IFA_ADDRESS) {
-              int family = address_msg->ifa_family;
-              if (family == AF_INET || family == AF_INET6) {
-                struct ifaddrs* newest = malloc(sizeof(struct ifaddrs));
-                memset(newest, 0, sizeof(struct ifaddrs));
-                if (current) {
-                  current->ifa_next = newest;
-                } else {
-                  start = newest;
-                }
-                if (populate_ifaddrs(newest, address_msg, RTA_DATA(rta),
-                                     RTA_PAYLOAD(rta)) != 0) {
-                  android_freeifaddrs(start);
-                  *result = NULL;
-                  return -1;
-                }
-                current = newest;
-              }
-            }
-            rta = RTA_NEXT(rta, payload_len);
-          }
-          break;
-        }
-      }
-    }
-    amount_read = recv(fd, &buf, kMaxReadSize, 0);
-  }
+  _status=0;
+abort:
   close(fd);
-  android_freeifaddrs(start);
-  return -1;
+  return(_status);
 }
 
-void android_freeifaddrs(struct ifaddrs* addrs) {
-  struct ifaddrs* last = NULL;
-  struct ifaddrs* cursor = addrs;
-  while (cursor) {
-    free(cursor->ifa_name);
-    free(cursor->ifa_addr);
-    free(cursor->ifa_netmask);
-    last = cursor;
-    cursor = cursor->ifa_next;
-    free(last);
-  }
-}
-
-#endif  /* defined(ANDROID) */
+#endif  /* defined(LINUX) */
rename from media/mtransport/third_party/nICEr/src/stun/ifaddrs-android.h
rename to media/mtransport/third_party/nICEr/src/stun/addrs-netlink.h
--- a/media/mtransport/third_party/nICEr/src/stun/ifaddrs-android.h
+++ b/media/mtransport/third_party/nICEr/src/stun/addrs-netlink.h
@@ -25,33 +25,21 @@ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-#ifndef WEBRTC_BASE_IFADDRS_ANDROID_H_
-#define WEBRTC_BASE_IFADDRS_ANDROID_H_
+#ifndef WEBRTC_BASE_IFADDRS_NETLINK_H_
+#define WEBRTC_BASE_IFADDRS_NETLINK_H_
 
 #include <stdio.h>
 #include <sys/socket.h>
+#include "local_addr.h"
 
-/* Implementation of getifaddrs for Android.
- * Fills out a list of ifaddr structs (see below) which contain information
- * about every network interface available on the host.
- * See 'man getifaddrs' on Linux or OS X (nb: it is not a POSIX function). */
-struct ifaddrs {
-  struct ifaddrs* ifa_next;
-  char* ifa_name;
-  unsigned int ifa_flags;
-  struct sockaddr* ifa_addr;
-  struct sockaddr* ifa_netmask;
-  /* Real ifaddrs has broadcast, point to point and data members.
-   * We don't need them (yet?). */
-};
+/* for platforms with netlink (android and linux) */
+/* Filters out things like deprecated addresses, and stuff that doesn't pass
+ * IPv6 duplicate address detection */
+int stun_getaddrs_filtered(nr_local_addr addrs[], int maxaddrs, int *count);
+#endif  /* WEBRTC_BASE_IFADDRS_NETLINK_H_ */
 
-int android_getifaddrs(struct ifaddrs** result);
-void android_freeifaddrs(struct ifaddrs* addrs);
-
-#endif  /* WEBRTC_BASE_IFADDRS_ANDROID_H_ */
-
new file mode 100644
--- /dev/null
+++ b/media/mtransport/third_party/nICEr/src/stun/addrs-win32.c
@@ -0,0 +1,190 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifdef WIN32
+
+#include "addrs-win32.h"
+#include <csi_platform.h>
+#include <assert.h>
+#include <string.h>
+#include "util.h"
+#include "stun_util.h"
+#include "util.h"
+#include <r_macros.h>
+#include "nr_crypto.h"
+
+#include <winsock2.h>
+#include <iphlpapi.h>
+#include <tchar.h>
+
+#define WIN32_MAX_NUM_INTERFACES  20
+
+#define NR_MD5_HASH_LENGTH 16
+
+#define _NR_MAX_KEY_LENGTH 256
+#define _NR_MAX_NAME_LENGTH 512
+
+#define _ADAPTERS_BASE_REG "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}"
+
+static int nr_win32_get_adapter_friendly_name(char *adapter_GUID, char **friendly_name)
+{
+    int r,_status;
+    HKEY adapter_reg;
+    TCHAR adapter_key[_NR_MAX_KEY_LENGTH];
+    TCHAR keyval_buf[_NR_MAX_KEY_LENGTH];
+    TCHAR adapter_GUID_tchar[_NR_MAX_NAME_LENGTH];
+    DWORD keyval_len, key_type;
+    size_t converted_chars, newlen;
+    char *my_fn = 0;
+
+#ifdef _UNICODE
+    mbstowcs_s(&converted_chars, adapter_GUID_tchar, strlen(adapter_GUID)+1,
+               adapter_GUID, _TRUNCATE);
+#else
+    strlcpy(adapter_GUID_tchar, adapter_GUID, _NR_MAX_NAME_LENGTH);
+#endif
+
+    _tcscpy_s(adapter_key, _NR_MAX_KEY_LENGTH, TEXT(_ADAPTERS_BASE_REG));
+    _tcscat_s(adapter_key, _NR_MAX_KEY_LENGTH, TEXT("\\"));
+    _tcscat_s(adapter_key, _NR_MAX_KEY_LENGTH, adapter_GUID_tchar);
+    _tcscat_s(adapter_key, _NR_MAX_KEY_LENGTH, TEXT("\\Connection"));
+
+    r = RegOpenKeyEx(HKEY_LOCAL_MACHINE, adapter_key, 0, KEY_READ, &adapter_reg);
+
+    if (r != ERROR_SUCCESS) {
+      r_log(NR_LOG_STUN, LOG_ERR, "Got error %d opening adapter reg key\n", r);
+      ABORT(R_INTERNAL);
+    }
+
+    keyval_len = sizeof(keyval_buf);
+    r = RegQueryValueEx(adapter_reg, TEXT("Name"), NULL, &key_type,
+                        (BYTE *)keyval_buf, &keyval_len);
+
+    RegCloseKey(adapter_reg);
+
+#ifdef UNICODE
+    newlen = wcslen(keyval_buf)+1;
+    my_fn = (char *) RCALLOC(newlen);
+    if (!my_fn) {
+      ABORT(R_NO_MEMORY);
+    }
+    wcstombs_s(&converted_chars, my_fn, newlen, keyval_buf, _TRUNCATE);
+#else
+    my_fn = r_strdup(keyval_buf);
+#endif
+
+    *friendly_name = my_fn;
+    _status=0;
+
+abort:
+    if (_status) {
+      if (my_fn) free(my_fn);
+    }
+    return(_status);
+}
+
+int
+stun_getaddrs_filtered(nr_local_addr addrs[], int maxaddrs, int *count)
+{
+    int r, _status;
+    PIP_ADAPTER_ADDRESSES AdapterAddresses = NULL, tmpAddress = NULL;
+    // recomended per https://msdn.microsoft.com/en-us/library/windows/desktop/aa365915(v=vs.85).aspx
+    static const ULONG initialBufLen = 15000;
+    ULONG buflen = initialBufLen;
+    char bin_hashed_ifname[NR_MD5_HASH_LENGTH];
+    char hex_hashed_ifname[MAXIFNAME];
+    int n = 0;
+
+    *count = 0;
+
+    if (maxaddrs <= 0)
+      ABORT(R_BAD_ARGS);
+
+    /* According to MSDN (see above) we have try GetAdapterAddresses() multiple times */
+    for (n = 0; n < 5; n++) {
+      AdapterAddresses = (PIP_ADAPTER_ADDRESSES) RMALLOC(buflen);
+      if (AdapterAddresses == NULL) {
+        r_log(NR_LOG_STUN, LOG_ERR, "Error allocating buf for GetAdaptersAddresses()");
+        ABORT(R_NO_MEMORY);
+      }
+
+      r = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER, NULL, AdapterAddresses, &buflen);
+      if (r == NO_ERROR) {
+        break;
+      }
+      r_log(NR_LOG_STUN, LOG_ERR, "GetAdaptersAddresses() returned error (%d)", r);
+      RFREE(AdapterAddresses);
+      AdapterAddresses = NULL;
+    }
+
+    if (n >= 5) {
+      r_log(NR_LOG_STUN, LOG_ERR, "5 failures calling GetAdaptersAddresses()");
+      ABORT(R_INTERNAL);
+    }
+
+    n = 0;
+
+    /* Loop through the adapters */
+
+    for (tmpAddress = AdapterAddresses; tmpAddress != NULL; tmpAddress = tmpAddress->Next) {
+
+      if (tmpAddress->OperStatus != IfOperStatusUp)
+        continue;
+
+      if ((tmpAddress->IfIndex != 0) || (tmpAddress->Ipv6IfIndex != 0)) {
+        IP_ADAPTER_UNICAST_ADDRESS *u = 0;
+
+        if(r=nr_crypto_md5((UCHAR *)tmpAddress->FriendlyName,
+                           wcslen(tmpAddress->FriendlyName) * sizeof(wchar_t),
+                           bin_hashed_ifname))
+          ABORT(r);
+        if(r=nr_bin2hex(bin_hashed_ifname, sizeof(bin_hashed_ifname),
+          hex_hashed_ifname))
+          ABORT(r);
+
+        for (u = tmpAddress->FirstUnicastAddress; u != 0; u = u->Next) {
+          SOCKET_ADDRESS *sa_addr = &u->Address;
+
+          if ((sa_addr->lpSockaddr->sa_family == AF_INET) ||
+              (sa_addr->lpSockaddr->sa_family == AF_INET6)) {
+            if ((r=nr_sockaddr_to_transport_addr((struct sockaddr*)sa_addr->lpSockaddr, IPPROTO_UDP, 0, &(addrs[n].addr))))
+                ABORT(r);
+          }
+          else {
+            r_log(NR_LOG_STUN, LOG_DEBUG, "Unrecognized sa_family for address on adapter %lu", tmpAddress->IfIndex);
+            continue;
+          }
+
+          strlcpy(addrs[n].addr.ifname, hex_hashed_ifname, sizeof(addrs[n].addr.ifname));
+          if (tmpAddress->IfType == IF_TYPE_ETHERNET_CSMACD) {
+            addrs[n].interface.type = NR_INTERFACE_TYPE_WIRED;
+          } else if (tmpAddress->IfType == IF_TYPE_IEEE80211) {
+            /* Note: this only works for >= Win Vista */
+            addrs[n].interface.type = NR_INTERFACE_TYPE_WIFI;
+          } else {
+            addrs[n].interface.type = NR_INTERFACE_TYPE_UNKNOWN;
+          }
+#if (_WIN32_WINNT >= 0x0600)
+          /* Note: only >= Vista provide link speed information */
+          addrs[n].interface.estimated_speed = tmpAddress->TransmitLinkSpeed / 1000;
+#else
+          addrs[n].interface.estimated_speed = 0;
+#endif
+          if (++n >= maxaddrs)
+            goto done;
+        }
+      }
+    }
+
+   done:
+    *count = n;
+    _status = 0;
+
+  abort:
+    RFREE(AdapterAddresses);
+    return _status;
+}
+
+#endif //WIN32
+
new file mode 100644
--- /dev/null
+++ b/media/mtransport/third_party/nICEr/src/stun/addrs-win32.h
@@ -0,0 +1,13 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef STUN_IFADDRS_WIN32_H_
+#define STUN_IFADDRS_WIN32_H_
+
+#include "local_addr.h"
+
+int stun_getaddrs_filtered(nr_local_addr addrs[], int maxaddrs, int *count);
+
+#endif  /* STUN_IFADDRS_WIN32_H_ */
+
--- a/media/mtransport/third_party/nICEr/src/stun/addrs.c
+++ b/media/mtransport/third_party/nICEr/src/stun/addrs.c
@@ -30,327 +30,27 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
 #include <csi_platform.h>
 #include <assert.h>
 #include <string.h>
 
 #ifdef WIN32
-#include <winsock2.h>
-#include <iphlpapi.h>
-#include <tchar.h>
-#else   /* !WIN32 */
-
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <errno.h>
-
-#ifndef ANDROID
-/* This works on linux and BSD, but not android */
-#include <sys/types.h> /* getifaddrs */
-#include <ifaddrs.h> /* getifaddrs */
+#include "addrs-win32.h"
+#elif defined(BSD) || defined(DARWIN)
+#include "addrs-bsd.h"
 #else
-#include "ifaddrs-android.h"
-#define getifaddrs android_getifaddrs
-#define freeifaddrs android_freeifaddrs
+#include "addrs-netlink.h"
 #endif
 
-#ifdef LINUX
-
-#ifdef ANDROID
-/* Work around an Android NDK < r8c bug */
-#undef __unused
-#else
-#include <linux/if.h> /* struct ifreq, IFF_POINTTOPOINT */
-#include <linux/wireless.h> /* struct iwreq */
-#include <linux/ethtool.h> /* struct ethtool_cmd */
-#include <linux/sockios.h> /* SIOCETHTOOL */
-#endif /* ANDROID */
-
-#endif /* LINUX */
-
-#endif  /* !WIN32 */
-
 #include "stun.h"
 #include "addrs.h"
-#include "nr_crypto.h"
 #include "util.h"
 
-#if defined(WIN32)
-
-#define WIN32_MAX_NUM_INTERFACES  20
-
-#define NR_MD5_HASH_LENGTH 16
-
-#define _NR_MAX_KEY_LENGTH 256
-#define _NR_MAX_NAME_LENGTH 512
-
-#define _ADAPTERS_BASE_REG "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}"
-
-static int nr_win32_get_adapter_friendly_name(char *adapter_GUID, char **friendly_name)
-{
-    int r,_status;
-    HKEY adapter_reg;
-    TCHAR adapter_key[_NR_MAX_KEY_LENGTH];
-    TCHAR keyval_buf[_NR_MAX_KEY_LENGTH];
-    TCHAR adapter_GUID_tchar[_NR_MAX_NAME_LENGTH];
-    DWORD keyval_len, key_type;
-    size_t converted_chars, newlen;
-    char *my_fn = 0;
-
-#ifdef _UNICODE
-    mbstowcs_s(&converted_chars, adapter_GUID_tchar, strlen(adapter_GUID)+1,
-               adapter_GUID, _TRUNCATE);
-#else
-    strlcpy(adapter_GUID_tchar, adapter_GUID, _NR_MAX_NAME_LENGTH);
-#endif
-
-    _tcscpy_s(adapter_key, _NR_MAX_KEY_LENGTH, TEXT(_ADAPTERS_BASE_REG));
-    _tcscat_s(adapter_key, _NR_MAX_KEY_LENGTH, TEXT("\\"));
-    _tcscat_s(adapter_key, _NR_MAX_KEY_LENGTH, adapter_GUID_tchar);
-    _tcscat_s(adapter_key, _NR_MAX_KEY_LENGTH, TEXT("\\Connection"));
-
-    r = RegOpenKeyEx(HKEY_LOCAL_MACHINE, adapter_key, 0, KEY_READ, &adapter_reg);
-
-    if (r != ERROR_SUCCESS) {
-      r_log(NR_LOG_STUN, LOG_ERR, "Got error %d opening adapter reg key\n", r);
-      ABORT(R_INTERNAL);
-    }
-
-    keyval_len = sizeof(keyval_buf);
-    r = RegQueryValueEx(adapter_reg, TEXT("Name"), NULL, &key_type,
-                        (BYTE *)keyval_buf, &keyval_len);
-
-    RegCloseKey(adapter_reg);
-
-#ifdef UNICODE
-    newlen = wcslen(keyval_buf)+1;
-    my_fn = (char *) RCALLOC(newlen);
-    if (!my_fn) {
-      ABORT(R_NO_MEMORY);
-    }
-    wcstombs_s(&converted_chars, my_fn, newlen, keyval_buf, _TRUNCATE);
-#else
-    my_fn = r_strdup(keyval_buf);
-#endif
-
-    *friendly_name = my_fn;
-    _status=0;
-
-abort:
-    if (_status) {
-      if (my_fn) free(my_fn);
-    }
-    return(_status);
-}
-
-static int
-stun_get_win32_addrs(nr_local_addr addrs[], int maxaddrs, int *count)
-{
-    int r, _status;
-    PIP_ADAPTER_ADDRESSES AdapterAddresses = NULL, tmpAddress = NULL;
-    // recomended per https://msdn.microsoft.com/en-us/library/windows/desktop/aa365915(v=vs.85).aspx
-    static const ULONG initialBufLen = 15000;
-    ULONG buflen = initialBufLen;
-    char bin_hashed_ifname[NR_MD5_HASH_LENGTH];
-    char hex_hashed_ifname[MAXIFNAME];
-    int n = 0;
-
-    *count = 0;
-
-    if (maxaddrs <= 0)
-      ABORT(R_BAD_ARGS);
-
-    /* According to MSDN (see above) we have try GetAdapterAddresses() multiple times */
-    for (n = 0; n < 5; n++) {
-      AdapterAddresses = (PIP_ADAPTER_ADDRESSES) RMALLOC(buflen);
-      if (AdapterAddresses == NULL) {
-        r_log(NR_LOG_STUN, LOG_ERR, "Error allocating buf for GetAdaptersAddresses()");
-        ABORT(R_NO_MEMORY);
-      }
-
-      r = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER, NULL, AdapterAddresses, &buflen);
-      if (r == NO_ERROR) {
-        break;
-      }
-      r_log(NR_LOG_STUN, LOG_ERR, "GetAdaptersAddresses() returned error (%d)", r);
-      RFREE(AdapterAddresses);
-      AdapterAddresses = NULL;
-    }
-
-    if (n >= 5) {
-      r_log(NR_LOG_STUN, LOG_ERR, "5 failures calling GetAdaptersAddresses()");
-      ABORT(R_INTERNAL);
-    }
-
-    n = 0;
-
-    /* Loop through the adapters */
-
-    for (tmpAddress = AdapterAddresses; tmpAddress != NULL; tmpAddress = tmpAddress->Next) {
-
-      if (tmpAddress->OperStatus != IfOperStatusUp)
-        continue;
-
-      if ((tmpAddress->IfIndex != 0) || (tmpAddress->Ipv6IfIndex != 0)) {
-        IP_ADAPTER_UNICAST_ADDRESS *u = 0;
-
-        if(r=nr_crypto_md5((UCHAR *)tmpAddress->FriendlyName,
-                           wcslen(tmpAddress->FriendlyName) * sizeof(wchar_t),
-                           bin_hashed_ifname))
-          ABORT(r);
-        if(r=nr_bin2hex(bin_hashed_ifname, sizeof(bin_hashed_ifname),
-          hex_hashed_ifname))
-          ABORT(r);
-
-        for (u = tmpAddress->FirstUnicastAddress; u != 0; u = u->Next) {
-          SOCKET_ADDRESS *sa_addr = &u->Address;
-
-          if ((sa_addr->lpSockaddr->sa_family == AF_INET) ||
-              (sa_addr->lpSockaddr->sa_family == AF_INET6)) {
-            if ((r=nr_sockaddr_to_transport_addr((struct sockaddr*)sa_addr->lpSockaddr, IPPROTO_UDP, 0, &(addrs[n].addr))))
-                ABORT(r);
-          }
-          else {
-            r_log(NR_LOG_STUN, LOG_DEBUG, "Unrecognized sa_family for address on adapter %lu", tmpAddress->IfIndex);
-            continue;
-          }
-
-          strlcpy(addrs[n].addr.ifname, hex_hashed_ifname, sizeof(addrs[n].addr.ifname));
-          if (tmpAddress->IfType == IF_TYPE_ETHERNET_CSMACD) {
-            addrs[n].interface.type = NR_INTERFACE_TYPE_WIRED;
-          } else if (tmpAddress->IfType == IF_TYPE_IEEE80211) {
-            /* Note: this only works for >= Win Vista */
-            addrs[n].interface.type = NR_INTERFACE_TYPE_WIFI;
-          } else {
-            addrs[n].interface.type = NR_INTERFACE_TYPE_UNKNOWN;
-          }
-#if (_WIN32_WINNT >= 0x0600)
-          /* Note: only >= Vista provide link speed information */
-          addrs[n].interface.estimated_speed = tmpAddress->TransmitLinkSpeed / 1000;
-#else
-          addrs[n].interface.estimated_speed = 0;
-#endif
-          if (++n >= maxaddrs)
-            goto done;
-        }
-      }
-    }
-
-   done:
-    *count = n;
-    _status = 0;
-
-  abort:
-    RFREE(AdapterAddresses);
-    return _status;
-}
-
-#else /* WIN32 */
-
-static int
-nr_stun_is_duplicate_addr(nr_local_addr addrs[], int count, nr_local_addr *addr);
-
-static int
-stun_getifaddrs(nr_local_addr addrs[], int maxaddrs, int *count)
-{
-  int r,_status;
-  struct ifaddrs* if_addrs_head=NULL;
-  struct ifaddrs* if_addr;
-
-  *count = 0;
-
-  if (maxaddrs <= 0)
-    ABORT(R_BAD_ARGS);
-
-  if (getifaddrs(&if_addrs_head) == -1) {
-    r_log(NR_LOG_STUN, LOG_ERR, "getifaddrs error e = %d", errno);
-    ABORT(R_INTERNAL);
-  }
-
-  if_addr = if_addrs_head;
-
-  while (if_addr && *count < maxaddrs) {
-    /* This can be null */
-    if (if_addr->ifa_addr) {
-      switch (if_addr->ifa_addr->sa_family) {
-        case AF_INET:
-        case AF_INET6:
-          if (r=nr_sockaddr_to_transport_addr(if_addr->ifa_addr, IPPROTO_UDP, 0, &(addrs[*count].addr))) {
-            r_log(NR_LOG_STUN, LOG_ERR, "nr_sockaddr_to_transport_addr error r = %d", r);
-          } else {
-#if defined(LINUX) && !defined(ANDROID)
-            struct ethtool_cmd ecmd;
-            struct ifreq ifr;
-            struct iwreq wrq;
-            int e;
-            int s = socket(AF_INET, SOCK_DGRAM, 0);
-
-            strncpy(ifr.ifr_name, if_addr->ifa_name, sizeof(ifr.ifr_name));
-            /* TODO (Bug 896851): interface property for Android */
-            /* Getting ethtool for ethernet information. */
-            ecmd.cmd = ETHTOOL_GSET;
-            /* In/out param */
-            ifr.ifr_data = (void*)&ecmd;
-
-            e = ioctl(s, SIOCETHTOOL, &ifr);
-            if (e == 0)
-            {
-               /* For wireless network, we won't get ethtool, it's a wired
-                * connection */
-               addrs[*count].interface.type = NR_INTERFACE_TYPE_WIRED;
-#ifdef DONT_HAVE_ETHTOOL_SPEED_HI
-               addrs[*count].interface.estimated_speed = ecmd.speed;
-#else
-               addrs[*count].interface.estimated_speed = ((ecmd.speed_hi << 16) | ecmd.speed) * 1000;
-#endif
-            }
-
-            strncpy(wrq.ifr_name, if_addr->ifa_name, sizeof(wrq.ifr_name));
-            e = ioctl(s, SIOCGIWRATE, &wrq);
-            if (e == 0)
-            {
-               addrs[*count].interface.type = NR_INTERFACE_TYPE_WIFI;
-               addrs[*count].interface.estimated_speed = wrq.u.bitrate.value / 1000;
-            }
-
-            close(s);
-
-            if (if_addr->ifa_flags & IFF_POINTOPOINT)
-            {
-               addrs[*count].interface.type = NR_INTERFACE_TYPE_UNKNOWN | NR_INTERFACE_TYPE_VPN;
-               /* TODO (Bug 896913): find backend network type of this VPN */
-            }
-#else
-            addrs[*count].interface.type = NR_INTERFACE_TYPE_UNKNOWN;
-            addrs[*count].interface.estimated_speed = 0;
-#endif
-            (void)strlcpy(addrs[*count].addr.ifname, if_addr->ifa_name, sizeof(addrs[*count].addr.ifname));
-            ++(*count);
-          }
-          break;
-        default:
-          ;
-      }
-    }
-
-    if_addr = if_addr->ifa_next;
-  }
-
-  _status=0;
-abort:
-  if (if_addrs_head) {
-    freeifaddrs(if_addrs_head);
-  }
-  return(_status);
-}
-
-#endif
-
 static int
 nr_stun_is_duplicate_addr(nr_local_addr addrs[], int count, nr_local_addr *addr)
 {
     int i;
     int different;
 
     for (i = 0; i < count; ++i) {
         different = nr_transport_addr_cmp(&addrs[i].addr, &(addr->addr),
@@ -457,21 +157,17 @@ nr_stun_get_addrs(nr_local_addr addrs[],
     int i;
     char typestr[100];
 
     // Ensure output records are always fully defined.  See bug 1589990.
     if (maxaddrs > 0) {
        memset(addrs, 0, maxaddrs * sizeof(nr_local_addr));
     }
 
-#ifdef WIN32
-    _status = stun_get_win32_addrs(addrs, maxaddrs, count);
-#else
-    _status = stun_getifaddrs(addrs, maxaddrs, count);
-#endif
+    _status = stun_getaddrs_filtered(addrs, maxaddrs, count);
 
     for (i = 0; i < *count; ++i) {
       nr_local_addr_fmt_info_string(addrs+i,typestr,sizeof(typestr));
       r_log(NR_LOG_STUN, LOG_DEBUG, "Address %d: %s on %s, type: %s\n",
             i,addrs[i].addr.as_string,addrs[i].addr.ifname,typestr);
     }
 
     return _status;