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