tor-browser

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

PlatformDNSUnix.cpp (2938B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim:set ts=4 sw=2 sts=2 et cin: */
      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 "GetAddrInfo.h"
      8 #include "mozilla/glean/NetwerkMetrics.h"
      9 #include "mozilla/net/DNSPacket.h"
     10 #include "nsIDNSService.h"
     11 #include "mozilla/Mutex.h"
     12 #include "mozilla/StaticPrefs_network.h"
     13 #include "mozilla/ThreadLocal.h"
     14 
     15 #include <stdlib.h>
     16 #include <string.h>
     17 #include <netinet/in.h>
     18 #include <resolv.h>
     19 
     20 namespace mozilla::net {
     21 
     22 #if defined(HAVE_RES_NINIT)
     23 MOZ_THREAD_LOCAL(struct __res_state*) sThreadRes;
     24 mozilla::StaticMutex sMutex MOZ_UNANNOTATED;
     25 #endif
     26 
     27 #define LOG(msg, ...) \
     28  MOZ_LOG(gGetAddrInfoLog, LogLevel::Debug, ("[DNS]: " msg, ##__VA_ARGS__))
     29 
     30 nsresult ResolveHTTPSRecordImpl(const nsACString& aHost,
     31                                nsIDNSService::DNSFlags aFlags,
     32                                TypeRecordResultType& aResult, uint32_t& aTTL) {
     33  DNSPacket packet;
     34  nsAutoCString host(aHost);
     35  nsAutoCString cname;
     36  nsresult rv;
     37 
     38  if (xpc::IsInAutomation() &&
     39      !StaticPrefs::network_dns_native_https_query_in_automation()) {
     40    return NS_ERROR_UNKNOWN_HOST;
     41  }
     42 
     43 #if defined(HAVE_RES_NINIT)
     44  if (!sThreadRes.get()) {
     45    UniquePtr<struct __res_state> resState(new struct __res_state);
     46    memset(resState.get(), 0, sizeof(struct __res_state));
     47    {
     48      StaticMutexAutoLock lock(sMutex);
     49      if (int ret = res_ninit(resState.get())) {
     50        LOG("res_ninit failed: %d", ret);
     51        return NS_ERROR_UNKNOWN_HOST;
     52      }
     53    }
     54    sThreadRes.set(resState.release());
     55  }
     56 #endif
     57 
     58  LOG("resolving %s\n", host.get());
     59  // Perform the query
     60  rv = packet.FillBuffer(
     61      [&](unsigned char response[DNSPacket::MAX_SIZE]) -> int {
     62        int len = 0;
     63        TimeStamp startTime = TimeStamp::Now();
     64 #if defined(HAVE_RES_NINIT)
     65        len = res_nquery(sThreadRes.get(), host.get(), ns_c_in,
     66                         nsIDNSService::RESOLVE_TYPE_HTTPSSVC, response,
     67                         DNSPacket::MAX_SIZE);
     68 #else
     69        len =
     70            res_query(host.get(), ns_c_in, nsIDNSService::RESOLVE_TYPE_HTTPSSVC,
     71                      response, DNSPacket::MAX_SIZE);
     72 #endif
     73 
     74        mozilla::glean::networking::dns_native_https_call_time
     75            .AccumulateRawDuration(TimeStamp::Now() - startTime);
     76        if (len < 0) {
     77          LOG("DNS query failed");
     78        }
     79        return len;
     80      });
     81  if (NS_FAILED(rv)) {
     82    return rv;
     83  }
     84 
     85  return ParseHTTPSRecord(host, packet, aResult, aTTL);
     86 }
     87 
     88 void DNSThreadShutdown() {
     89 #if defined(HAVE_RES_NINIT)
     90  auto* res = sThreadRes.get();
     91  if (!res) {
     92    return;
     93  }
     94 
     95  sThreadRes.set(nullptr);
     96  {
     97    StaticMutexAutoLock lock(sMutex);
     98    res_nclose(res);
     99  }
    100  free(res);
    101 #endif
    102 }
    103 
    104 }  // namespace mozilla::net