media/mtransport/gonk_addrs.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim: set ts=2 et sw=2 tw=80: */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     5  * You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 extern "C" {
     7 #include <arpa/inet.h>
     8 #include "r_types.h"
     9 #include "stun.h"
    10 #include "addrs.h"
    11 }
    13 #include <vector>
    14 #include <string>
    15 #include "nsINetworkManager.h"
    16 #include "nsINetworkInterfaceListService.h"
    17 #include "runnable_utils.h"
    18 #include "nsCOMPtr.h"
    19 #include "nsMemory.h"
    20 #include "nsThreadUtils.h"
    21 #include "nsServiceManagerUtils.h"
    22 #include "mozilla/SyncRunnable.h"
    24 namespace {
    25 struct NetworkInterface {
    26   struct sockaddr_in addr;
    27   std::string name;
    28   // See NR_INTERFACE_TYPE_* in nICEr/src/net/local_addrs.h
    29   int type;
    30 };
    32 nsresult
    33 GetInterfaces(std::vector<NetworkInterface>* aInterfaces)
    34 {
    35   MOZ_ASSERT(aInterfaces);
    37   // Obtain network interfaces from network manager.
    38   nsresult rv;
    39   nsCOMPtr<nsINetworkInterfaceListService> listService =
    40     do_GetService("@mozilla.org/network/interface-list-service;1", &rv);
    41   NS_ENSURE_SUCCESS(rv, rv);
    43   int32_t flags =
    44     nsINetworkInterfaceListService::LIST_NOT_INCLUDE_SUPL_INTERFACES |
    45     nsINetworkInterfaceListService::LIST_NOT_INCLUDE_MMS_INTERFACES |
    46     nsINetworkInterfaceListService::LIST_NOT_INCLUDE_IMS_INTERFACES |
    47     nsINetworkInterfaceListService::LIST_NOT_INCLUDE_DUN_INTERFACES;
    48   nsCOMPtr<nsINetworkInterfaceList> networkList;
    49   NS_ENSURE_SUCCESS(listService->GetDataInterfaceList(flags,
    50                                                       getter_AddRefs(networkList)),
    51                     NS_ERROR_FAILURE);
    53   // Translate nsINetworkInterfaceList to NetworkInterface.
    54   int32_t listLength;
    55   NS_ENSURE_SUCCESS(networkList->GetNumberOfInterface(&listLength),
    56                     NS_ERROR_FAILURE);
    57   aInterfaces->clear();
    59   for (int32_t i = 0; i < listLength; i++) {
    60     nsCOMPtr<nsINetworkInterface> iface;
    61     if (NS_FAILED(networkList->GetInterface(i, getter_AddRefs(iface)))) {
    62       continue;
    63     }
    65     char16_t **ips = nullptr;
    66     uint32_t *prefixs = nullptr;
    67     uint32_t count = 0;
    68     bool isAddressGot = false;
    69     NetworkInterface interface;
    70     memset(&(interface.addr), 0, sizeof(interface.addr));
    71     interface.addr.sin_family = AF_INET;
    73     if (NS_FAILED(iface->GetAddresses(&ips, &prefixs, &count))) {
    74       continue;
    75     }
    77     for (uint32_t j = 0; j < count; j++) {
    78       nsAutoString ip;
    80       ip.Assign(ips[j]);
    81       if (inet_pton(AF_INET, NS_ConvertUTF16toUTF8(ip).get(),
    82                     &(interface.addr.sin_addr.s_addr)) == 1) {
    83         isAddressGot = true;
    84         break;
    85       }
    86     }
    88     nsMemory::Free(prefixs);
    89     NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count, ips);
    91     if (!isAddressGot) {
    92       continue;
    93     }
    95     nsAutoString ifaceName;
    96     if (NS_FAILED(iface->GetName(ifaceName))) {
    97       continue;
    98     }
    99     interface.name = NS_ConvertUTF16toUTF8(ifaceName).get();
   101     int32_t type;
   102     if (NS_FAILED(iface->GetType(&type))) {
   103       continue;
   104     }
   105     switch (type) {
   106       case nsINetworkInterface::NETWORK_TYPE_WIFI:
   107         interface.type = NR_INTERFACE_TYPE_WIFI;
   108         break;
   109       case nsINetworkInterface::NETWORK_TYPE_MOBILE:
   110         interface.type = NR_INTERFACE_TYPE_MOBILE;
   111         break;
   112     }
   114     aInterfaces->push_back(interface);
   115   }
   116   return NS_OK;
   117 }
   118 } // anonymous namespace
   120 int
   121 nr_stun_get_addrs(nr_local_addr aAddrs[], int aMaxAddrs,
   122                   int aDropLoopback, int* aCount)
   123 {
   124   nsresult rv;
   125   int r;
   127   // Get network interface list.
   128   std::vector<NetworkInterface> interfaces;
   129   nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
   130   mozilla::SyncRunnable::DispatchToThread(
   131     mainThread.get(),
   132     mozilla::WrapRunnableNMRet(&GetInterfaces, &interfaces, &rv),
   133     false);
   134   if (NS_FAILED(rv)) {
   135     return R_FAILED;
   136   }
   138   // Translate to nr_transport_addr.
   139   int32_t n = 0;
   140   size_t num_interface = std::min(interfaces.size(), (size_t)aMaxAddrs);
   141   for (size_t i = 0; i < num_interface; ++i) {
   142     NetworkInterface &interface = interfaces[i];
   143     if (nr_sockaddr_to_transport_addr((sockaddr*)&(interface.addr),
   144                                       sizeof(struct sockaddr_in),
   145                                       IPPROTO_UDP, 0, &(aAddrs[n].addr))) {
   146       r_log(NR_LOG_STUN, LOG_WARNING, "Problem transforming address");
   147       return R_FAILED;
   148     }
   149     strlcpy(aAddrs[n].addr.ifname, interface.name.c_str(),
   150             sizeof(aAddrs[n].addr.ifname));
   151     aAddrs[n].interface.type = interface.type;
   152     aAddrs[n].interface.estimated_speed = 0;
   153     n++;
   154   }
   156   *aCount = n;
   157   r = nr_stun_remove_duplicate_addrs(aAddrs, aDropLoopback, aCount);
   158   if (r != 0) {
   159     return r;
   160   }
   162   for (int i = 0; i < *aCount; ++i) {
   163     char typestr[100];
   164     nr_local_addr_fmt_info_string(aAddrs + i, typestr, sizeof(typestr));
   165     r_log(NR_LOG_STUN, LOG_DEBUG, "Address %d: %s on %s, type: %s\n",
   166           i, aAddrs[i].addr.as_string, aAddrs[i].addr.ifname, typestr);
   167   }
   169   return 0;
   170 }

mercurial