tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsNetworkLinkService.cpp (6263B)


      1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim:set et sw=2 ts=4: */
      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
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "nsIObserverService.h"
      8 #include "nsNetworkLinkService.h"
      9 #include "nsString.h"
     10 #include "mozilla/Logging.h"
     11 #include "mozilla/IntegerPrintfMacros.h"
     12 #include "nsNetAddr.h"
     13 
     14 #include "mozilla/StaticPrefs_network.h"
     15 #include "mozilla/Services.h"
     16 
     17 using namespace mozilla;
     18 
     19 static LazyLogModule gNotifyAddrLog("nsNetworkLinkService");
     20 #define LOG(args) MOZ_LOG(gNotifyAddrLog, mozilla::LogLevel::Debug, args)
     21 
     22 NS_IMPL_ISUPPORTS(nsNetworkLinkService, nsINetworkLinkService, nsIObserver)
     23 
     24 nsNetworkLinkService::nsNetworkLinkService() : mStatusIsKnown(false) {}
     25 
     26 NS_IMETHODIMP
     27 nsNetworkLinkService::GetIsLinkUp(bool* aIsUp) {
     28  if (!mNetlinkSvc) {
     29    return NS_ERROR_NOT_AVAILABLE;
     30  }
     31 
     32  mNetlinkSvc->GetIsLinkUp(aIsUp);
     33  return NS_OK;
     34 }
     35 
     36 NS_IMETHODIMP
     37 nsNetworkLinkService::GetLinkStatusKnown(bool* aIsKnown) {
     38  *aIsKnown = mStatusIsKnown;
     39  return NS_OK;
     40 }
     41 
     42 NS_IMETHODIMP
     43 nsNetworkLinkService::GetLinkType(uint32_t* aLinkType) {
     44  NS_ENSURE_ARG_POINTER(aLinkType);
     45 
     46  // XXX This function has not yet been implemented for this platform
     47  *aLinkType = nsINetworkLinkService::LINK_TYPE_UNKNOWN;
     48  return NS_OK;
     49 }
     50 
     51 NS_IMETHODIMP
     52 nsNetworkLinkService::GetNetworkID(nsACString& aNetworkID) {
     53 #ifdef BASE_BROWSER_VERSION
     54  aNetworkID.Truncate();
     55 #else
     56  if (!mNetlinkSvc) {
     57    return NS_ERROR_NOT_AVAILABLE;
     58  }
     59 
     60  mNetlinkSvc->GetNetworkID(aNetworkID);
     61 #endif
     62  return NS_OK;
     63 }
     64 
     65 NS_IMETHODIMP
     66 nsNetworkLinkService::GetDnsSuffixList(nsTArray<nsCString>& aDnsSuffixList) {
     67  if (!mNetlinkSvc) {
     68    return NS_ERROR_NOT_AVAILABLE;
     69  }
     70 
     71  return mNetlinkSvc->GetDnsSuffixList(aDnsSuffixList);
     72 }
     73 
     74 NS_IMETHODIMP
     75 nsNetworkLinkService::GetResolvers(nsTArray<RefPtr<nsINetAddr>>& aResolvers) {
     76  nsTArray<mozilla::net::NetAddr> addresses;
     77  nsresult rv = GetNativeResolvers(addresses);
     78  if (NS_FAILED(rv)) {
     79    return rv;
     80  }
     81 
     82  for (const auto& addr : addresses) {
     83    aResolvers.AppendElement(MakeRefPtr<nsNetAddr>(&addr));
     84  }
     85  return NS_OK;
     86 }
     87 
     88 NS_IMETHODIMP
     89 nsNetworkLinkService::GetNativeResolvers(
     90    nsTArray<mozilla::net::NetAddr>& aResolvers) {
     91  if (!mNetlinkSvc) {
     92    return NS_ERROR_NOT_AVAILABLE;
     93  }
     94  return mNetlinkSvc->GetResolvers(aResolvers);
     95 }
     96 
     97 NS_IMETHODIMP
     98 nsNetworkLinkService::GetPlatformDNSIndications(
     99    uint32_t* aPlatformDNSIndications) {
    100  return NS_ERROR_NOT_IMPLEMENTED;
    101 }
    102 
    103 NS_IMETHODIMP
    104 nsNetworkLinkService::Observe(nsISupports* subject, const char* topic,
    105                              const char16_t* data) {
    106  if (!strcmp("xpcom-shutdown-threads", topic)) {
    107    Shutdown();
    108  }
    109 
    110  return NS_OK;
    111 }
    112 
    113 nsresult nsNetworkLinkService::Init() {
    114  nsCOMPtr<nsIObserverService> observerService =
    115      mozilla::services::GetObserverService();
    116  if (!observerService) {
    117    return NS_ERROR_FAILURE;
    118  }
    119 
    120  nsresult rv;
    121  rv = observerService->AddObserver(this, "xpcom-shutdown-threads", false);
    122  NS_ENSURE_SUCCESS(rv, rv);
    123 
    124  mNetlinkSvc = new mozilla::net::NetlinkService();
    125  rv = mNetlinkSvc->Init(this);
    126  if (NS_FAILED(rv)) {
    127    mNetlinkSvc = nullptr;
    128    LOG(("Cannot initialize NetlinkService [rv=0x%08" PRIx32 "]",
    129         static_cast<uint32_t>(rv)));
    130    return rv;
    131  }
    132  NS_ENSURE_SUCCESS(rv, rv);
    133 
    134  return NS_OK;
    135 }
    136 
    137 nsresult nsNetworkLinkService::Shutdown() {
    138  // remove xpcom shutdown observer
    139  nsCOMPtr<nsIObserverService> observerService =
    140      mozilla::services::GetObserverService();
    141  if (observerService) {
    142    observerService->RemoveObserver(this, "xpcom-shutdown-threads");
    143  }
    144 
    145  if (mNetlinkSvc) {
    146    mNetlinkSvc->Shutdown();
    147    mNetlinkSvc = nullptr;
    148  }
    149 
    150  return NS_OK;
    151 }
    152 
    153 void nsNetworkLinkService::OnNetworkChanged() {
    154  if (StaticPrefs::network_notify_changed()) {
    155    RefPtr<nsNetworkLinkService> self = this;
    156    NS_DispatchToMainThread(NS_NewRunnableFunction(
    157        "nsNetworkLinkService::OnNetworkChanged", [self]() {
    158          self->NotifyObservers(NS_NETWORK_LINK_TOPIC,
    159                                NS_NETWORK_LINK_DATA_CHANGED);
    160        }));
    161  }
    162 }
    163 
    164 void nsNetworkLinkService::OnNetworkIDChanged() {
    165  RefPtr<nsNetworkLinkService> self = this;
    166  NS_DispatchToMainThread(NS_NewRunnableFunction(
    167      "nsNetworkLinkService::OnNetworkIDChanged", [self]() {
    168        self->NotifyObservers(NS_NETWORK_ID_CHANGED_TOPIC, nullptr);
    169      }));
    170 }
    171 
    172 void nsNetworkLinkService::OnLinkUp() {
    173  RefPtr<nsNetworkLinkService> self = this;
    174  NS_DispatchToMainThread(
    175      NS_NewRunnableFunction("nsNetworkLinkService::OnLinkUp", [self]() {
    176        self->NotifyObservers(NS_NETWORK_LINK_TOPIC, NS_NETWORK_LINK_DATA_UP);
    177      }));
    178 }
    179 
    180 void nsNetworkLinkService::OnLinkDown() {
    181  RefPtr<nsNetworkLinkService> self = this;
    182  NS_DispatchToMainThread(
    183      NS_NewRunnableFunction("nsNetworkLinkService::OnLinkDown", [self]() {
    184        self->NotifyObservers(NS_NETWORK_LINK_TOPIC, NS_NETWORK_LINK_DATA_DOWN);
    185      }));
    186 }
    187 
    188 void nsNetworkLinkService::OnLinkStatusKnown() { mStatusIsKnown = true; }
    189 
    190 void nsNetworkLinkService::OnDnsSuffixListUpdated() {
    191  RefPtr<nsNetworkLinkService> self = this;
    192  NS_DispatchToMainThread(NS_NewRunnableFunction(
    193      "nsNetworkLinkService::OnDnsSuffixListUpdated", [self]() {
    194        self->NotifyObservers(NS_DNS_SUFFIX_LIST_UPDATED_TOPIC, nullptr);
    195      }));
    196 }
    197 
    198 /* Sends the given event. Assumes aTopic/aData never goes out of scope (static
    199 * strings are ideal).
    200 */
    201 void nsNetworkLinkService::NotifyObservers(const char* aTopic,
    202                                           const char* aData) {
    203  MOZ_ASSERT(NS_IsMainThread());
    204 
    205  LOG(("nsNetworkLinkService::NotifyObservers: topic:%s data:%s\n", aTopic,
    206       aData ? aData : ""));
    207 
    208  nsCOMPtr<nsIObserverService> observerService =
    209      mozilla::services::GetObserverService();
    210 
    211  if (observerService) {
    212    observerService->NotifyObservers(
    213        static_cast<nsINetworkLinkService*>(this), aTopic,
    214        aData ? NS_ConvertASCIItoUTF16(aData).get() : nullptr);
    215  }
    216 }
    217 
    218 // static
    219 bool nsINetworkLinkService::HasNonLocalIPv6Address() {
    220  return mozilla::net::NetlinkService::HasNonLocalIPv6Address();
    221 }