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/. */
7 #include "mozilla/net/DNSRequestParent.h"
8 #include "mozilla/net/DNSRequestChild.h"
9 #include "nsIDNSService.h"
11 #include "nsThreadUtils.h"
12 #include "nsICancelable.h"
13 #include "nsIDNSRecord.h"
14 #include "nsHostResolver.h"
15 #include "mozilla/Unused.h"
16 #include "DNSAdditionalInfo.h"
17 #include "nsServiceManagerUtils.h"
19 using namespace mozilla::ipc
;
24 //-----------------------------------------------------------------------------
25 // DNSRequestHandler::nsISupports
26 //-----------------------------------------------------------------------------
28 NS_IMPL_ISUPPORTS(DNSRequestHandler
, nsIDNSListener
)
30 static void SendLookupCompletedHelper(DNSRequestActor
* aActor
,
31 const DNSRequestResponse
& aReply
) {
32 if (DNSRequestParent
* parent
= aActor
->AsDNSRequestParent()) {
33 Unused
<< parent
->SendLookupCompleted(aReply
);
34 } else if (DNSRequestChild
* child
= aActor
->AsDNSRequestChild()) {
35 Unused
<< child
->SendLookupCompleted(aReply
);
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
) {
46 nsCOMPtr
<nsIDNSService
> dns
= do_GetService(NS_DNSSERVICE_CONTRACTID
, &rv
);
47 if (NS_SUCCEEDED(rv
)) {
48 nsCOMPtr
<nsIEventTarget
> main
= GetMainThreadSerialEventTarget();
49 nsCOMPtr
<nsICancelable
> unused
;
50 RefPtr
<DNSAdditionalInfo
> info
;
51 if (!trrServer
.IsEmpty() || port
!= -1) {
52 info
= new DNSAdditionalInfo(trrServer
, port
);
54 rv
= dns
->AsyncResolveNative(
55 hostname
, static_cast<nsIDNSService::ResolveType
>(type
), flags
, info
,
56 this, main
, originAttributes
, getter_AddRefs(unused
));
59 if (NS_FAILED(rv
) && mIPCActor
->CanSend()) {
60 SendLookupCompletedHelper(mIPCActor
, DNSRequestResponse(rv
));
64 void DNSRequestHandler::OnRecvCancelDNSRequest(
65 const nsCString
& hostName
, const nsCString
& aTrrServer
, const int32_t& port
,
66 const uint16_t& type
, const OriginAttributes
& originAttributes
,
67 const nsIDNSService::DNSFlags
& flags
, const nsresult
& reason
) {
69 nsCOMPtr
<nsIDNSService
> dns
= do_GetService(NS_DNSSERVICE_CONTRACTID
, &rv
);
70 if (NS_SUCCEEDED(rv
)) {
71 RefPtr
<DNSAdditionalInfo
> info
;
72 if (!aTrrServer
.IsEmpty() || port
!= -1) {
73 info
= new DNSAdditionalInfo(aTrrServer
, port
);
75 rv
= dns
->CancelAsyncResolveNative(
76 hostName
, static_cast<nsIDNSService::ResolveType
>(type
), flags
, info
,
77 this, reason
, originAttributes
);
81 bool DNSRequestHandler::OnRecvLookupCompleted(const DNSRequestResponse
& reply
) {
85 //-----------------------------------------------------------------------------
86 // nsIDNSListener functions
87 //-----------------------------------------------------------------------------
90 DNSRequestHandler::OnLookupComplete(nsICancelable
* request
,
91 nsIDNSRecord
* aRecord
, nsresult status
) {
92 if (!mIPCActor
|| !mIPCActor
->CanSend()) {
93 // nothing to do: child probably crashed
97 if (NS_SUCCEEDED(status
)) {
100 nsCOMPtr
<nsIDNSByTypeRecord
> byTypeRec
= do_QueryInterface(aRecord
);
102 IPCTypeRecord result
;
103 byTypeRec
->GetResults(&result
.mData
);
104 if (nsCOMPtr
<nsIDNSHTTPSSVCRecord
> rec
= do_QueryInterface(aRecord
)) {
105 rec
->GetTtl(&result
.mTTL
);
107 SendLookupCompletedHelper(mIPCActor
, DNSRequestResponse(result
));
111 nsCOMPtr
<nsIDNSAddrRecord
> rec
= do_QueryInterface(aRecord
);
114 if (mFlags
& nsHostResolver::RES_CANON_NAME
) {
115 rec
->GetCanonicalName(cname
);
118 // Get IP addresses for hostname (use port 80 as dummy value for NetAddr)
119 nsTArray
<NetAddr
> array
;
121 while (NS_SUCCEEDED(rec
->GetNextAddr(80, &addr
))) {
122 array
.AppendElement(addr
);
125 double trrFetchDuration
;
126 rec
->GetTrrFetchDuration(&trrFetchDuration
);
128 double trrFetchDurationNetworkOnly
;
129 rec
->GetTrrFetchDurationNetworkOnly(&trrFetchDurationNetworkOnly
);
134 nsIRequest::TRRMode effectiveTRRMode
= nsIRequest::TRR_DEFAULT_MODE
;
135 rec
->GetEffectiveTRRMode(&effectiveTRRMode
);
140 SendLookupCompletedHelper(
141 mIPCActor
, DNSRequestResponse(DNSRecord(cname
, array
, trrFetchDuration
,
142 trrFetchDurationNetworkOnly
,
143 isTRR
, effectiveTRRMode
, ttl
)));
145 SendLookupCompletedHelper(mIPCActor
, DNSRequestResponse(status
));
151 void DNSRequestHandler::OnIPCActorDestroy() { mIPCActor
= nullptr; }
153 //-----------------------------------------------------------------------------
154 // DNSRequestParent functions
155 //-----------------------------------------------------------------------------
157 DNSRequestParent::DNSRequestParent(DNSRequestBase
* aRequest
)
158 : DNSRequestActor(aRequest
) {
159 aRequest
->SetIPCActor(this);
162 mozilla::ipc::IPCResult
DNSRequestParent::RecvCancelDNSRequest(
163 const nsCString
& hostName
, const nsCString
& trrServer
, const int32_t& port
,
164 const uint16_t& type
, const OriginAttributes
& originAttributes
,
165 const nsIDNSService::DNSFlags
& flags
, const nsresult
& reason
) {
166 mDNSRequest
->OnRecvCancelDNSRequest(hostName
, trrServer
, port
, type
,
167 originAttributes
, flags
, reason
);
171 mozilla::ipc::IPCResult
DNSRequestParent::RecvLookupCompleted(
172 const DNSRequestResponse
& reply
) {
173 return mDNSRequest
->OnRecvLookupCompleted(reply
) ? IPC_OK()
174 : IPC_FAIL_NO_REASON(this);
177 void DNSRequestParent::ActorDestroy(ActorDestroyReason
) {
178 mDNSRequest
->OnIPCActorDestroy();
179 mDNSRequest
= nullptr;
183 } // namespace mozilla