tor-browser

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

DNSRequestParent.cpp (6639B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set sw=2 ts=8 et 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
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "mozilla/net/DNSRequestParent.h"
      8 #include "mozilla/net/DNSRequestChild.h"
      9 #include "nsIDNSService.h"
     10 #include "nsNetCID.h"
     11 #include "nsThreadUtils.h"
     12 #include "nsICancelable.h"
     13 #include "nsIDNSRecord.h"
     14 #include "nsHostResolver.h"
     15 #include "mozilla/Components.h"
     16 #include "DNSAdditionalInfo.h"
     17 #include "nsServiceManagerUtils.h"
     18 
     19 using namespace mozilla::ipc;
     20 
     21 namespace mozilla {
     22 namespace net {
     23 
     24 //-----------------------------------------------------------------------------
     25 // DNSRequestHandler::nsISupports
     26 //-----------------------------------------------------------------------------
     27 
     28 NS_IMPL_ISUPPORTS(DNSRequestHandler, nsIDNSListener)
     29 
     30 static void SendLookupCompletedHelper(DNSRequestActor* aActor,
     31                                      const DNSRequestResponse& aReply) {
     32  if (DNSRequestParent* parent = aActor->AsDNSRequestParent()) {
     33    (void)parent->SendLookupCompleted(aReply);
     34  } else if (DNSRequestChild* child = aActor->AsDNSRequestChild()) {
     35    (void)child->SendLookupCompleted(aReply);
     36  }
     37 }
     38 
     39 void DNSRequestHandler::DoAsyncResolve(const nsACString& hostname,
     40                                       const nsACString& trrServer,
     41                                       int32_t port, uint16_t type,
     42                                       const OriginAttributes& originAttributes,
     43                                       nsIDNSService::DNSFlags flags) {
     44  nsresult rv;
     45  mFlags = flags;
     46  nsCOMPtr<nsIDNSService> dns;
     47  dns = mozilla::components::DNS::Service(&rv);
     48  if (NS_SUCCEEDED(rv)) {
     49    nsCOMPtr<nsIEventTarget> main = GetMainThreadSerialEventTarget();
     50    nsCOMPtr<nsICancelable> unused;
     51    RefPtr<DNSAdditionalInfo> info;
     52    if (!trrServer.IsEmpty() || port != -1) {
     53      info = new DNSAdditionalInfo(trrServer, port);
     54    }
     55    rv = dns->AsyncResolveNative(
     56        hostname, static_cast<nsIDNSService::ResolveType>(type), flags, info,
     57        this, main, originAttributes, getter_AddRefs(unused));
     58  }
     59 
     60  if (NS_FAILED(rv) && mIPCActor->CanSend()) {
     61    SendLookupCompletedHelper(mIPCActor, DNSRequestResponse(rv));
     62  }
     63 }
     64 
     65 void DNSRequestHandler::OnRecvCancelDNSRequest(
     66    const nsCString& hostName, const nsCString& aTrrServer, const int32_t& port,
     67    const uint16_t& type, const OriginAttributes& originAttributes,
     68    const nsIDNSService::DNSFlags& flags, const nsresult& reason) {
     69  nsresult rv;
     70  nsCOMPtr<nsIDNSService> dns;
     71  dns = mozilla::components::DNS::Service(&rv);
     72  if (NS_SUCCEEDED(rv)) {
     73    RefPtr<DNSAdditionalInfo> info;
     74    if (!aTrrServer.IsEmpty() || port != -1) {
     75      info = new DNSAdditionalInfo(aTrrServer, port);
     76    }
     77    rv = dns->CancelAsyncResolveNative(
     78        hostName, static_cast<nsIDNSService::ResolveType>(type), flags, info,
     79        this, reason, originAttributes);
     80  }
     81 }
     82 
     83 bool DNSRequestHandler::OnRecvLookupCompleted(const DNSRequestResponse& reply) {
     84  return true;
     85 }
     86 
     87 //-----------------------------------------------------------------------------
     88 // nsIDNSListener functions
     89 //-----------------------------------------------------------------------------
     90 
     91 NS_IMETHODIMP
     92 DNSRequestHandler::OnLookupComplete(nsICancelable* request,
     93                                    nsIDNSRecord* aRecord, nsresult status) {
     94  if (!mIPCActor || !mIPCActor->CanSend()) {
     95    // nothing to do: child probably crashed
     96    return NS_OK;
     97  }
     98 
     99  if (NS_SUCCEEDED(status)) {
    100    MOZ_ASSERT(aRecord);
    101 
    102    nsCOMPtr<nsIDNSByTypeRecord> byTypeRec = do_QueryInterface(aRecord);
    103    if (byTypeRec) {
    104      IPCTypeRecord result;
    105      byTypeRec->GetResults(&result.mData);
    106      if (nsCOMPtr<nsIDNSHTTPSSVCRecord> rec = do_QueryInterface(aRecord)) {
    107        rec->GetTtl(&result.mTTL);
    108        rec->IsTRR(&result.mIsTRR);
    109      }
    110      SendLookupCompletedHelper(mIPCActor, DNSRequestResponse(result));
    111      return NS_OK;
    112    }
    113 
    114    nsCOMPtr<nsIDNSAddrRecord> rec = do_QueryInterface(aRecord);
    115    MOZ_ASSERT(rec);
    116    nsAutoCString cname;
    117    if (mFlags & nsIDNSService::RESOLVE_CANONICAL_NAME) {
    118      rec->GetCanonicalName(cname);
    119    }
    120 
    121    // Get IP addresses for hostname (use port 80 as dummy value for NetAddr)
    122    nsTArray<NetAddr> array;
    123    NetAddr addr;
    124    while (NS_SUCCEEDED(rec->GetNextAddr(80, &addr))) {
    125      array.AppendElement(addr);
    126    }
    127 
    128    double trrFetchDuration;
    129    rec->GetTrrFetchDuration(&trrFetchDuration);
    130 
    131    double trrFetchDurationNetworkOnly;
    132    rec->GetTrrFetchDurationNetworkOnly(&trrFetchDurationNetworkOnly);
    133 
    134    bool isTRR = false;
    135    rec->IsTRR(&isTRR);
    136 
    137    nsIRequest::TRRMode effectiveTRRMode = nsIRequest::TRR_DEFAULT_MODE;
    138    rec->GetEffectiveTRRMode(&effectiveTRRMode);
    139 
    140    uint32_t ttl = 0;
    141    rec->GetTtl(&ttl);
    142 
    143    TimeStamp lastUpdate;
    144    rec->GetLastUpdate(&lastUpdate);
    145 
    146    SendLookupCompletedHelper(
    147        mIPCActor,
    148        DNSRequestResponse(DNSRecord(cname, array, trrFetchDuration,
    149                                     trrFetchDurationNetworkOnly, isTRR,
    150                                     effectiveTRRMode, ttl, lastUpdate)));
    151  } else {
    152    SendLookupCompletedHelper(mIPCActor, DNSRequestResponse(status));
    153  }
    154 
    155  return NS_OK;
    156 }
    157 
    158 void DNSRequestHandler::OnIPCActorDestroy() { mIPCActor = nullptr; }
    159 
    160 //-----------------------------------------------------------------------------
    161 // DNSRequestParent functions
    162 //-----------------------------------------------------------------------------
    163 
    164 DNSRequestParent::DNSRequestParent(DNSRequestBase* aRequest)
    165    : DNSRequestActor(aRequest) {
    166  aRequest->SetIPCActor(this);
    167 }
    168 
    169 mozilla::ipc::IPCResult DNSRequestParent::RecvCancelDNSRequest(
    170    const nsCString& hostName, const nsCString& trrServer, const int32_t& port,
    171    const uint16_t& type, const OriginAttributes& originAttributes,
    172    const nsIDNSService::DNSFlags& flags, const nsresult& reason) {
    173  mDNSRequest->OnRecvCancelDNSRequest(hostName, trrServer, port, type,
    174                                      originAttributes, flags, reason);
    175  return IPC_OK();
    176 }
    177 
    178 mozilla::ipc::IPCResult DNSRequestParent::RecvLookupCompleted(
    179    const DNSRequestResponse& reply) {
    180  return mDNSRequest->OnRecvLookupCompleted(reply) ? IPC_OK()
    181                                                   : IPC_FAIL_NO_REASON(this);
    182 }
    183 
    184 void DNSRequestParent::ActorDestroy(ActorDestroyReason) {
    185  mDNSRequest->OnIPCActorDestroy();
    186  mDNSRequest = nullptr;
    187 }
    188 
    189 }  // namespace net
    190 }  // namespace mozilla