Commits:
-
c1966f06
by Kershaw Chang at 2024-12-17T12:40:47+01:00
Bug 1910593 - Don't prefetch HTTPS RR if proxyDNS is enabled, r=necko-reviewers,valentin
Differential Revision: https://phabricator.services.mozilla.com/D219528
15 changed files:
Changes:
dom/chrome-webidl/NetDashboard.webidl
| ... |
... |
@@ -68,6 +68,7 @@ dictionary DnsCacheEntry { |
|
68
|
68
|
boolean trr = false;
|
|
69
|
69
|
DOMString originAttributesSuffix = "";
|
|
70
|
70
|
DOMString flags = "";
|
|
|
71
|
+ unsigned short type = 0;
|
|
71
|
72
|
};
|
|
72
|
73
|
|
|
73
|
74
|
[GenerateConversionToJS]
|
netwerk/base/Dashboard.cpp
| ... |
... |
@@ -906,10 +906,13 @@ nsresult Dashboard::GetDNSCacheEntries(DnsData* dnsData) { |
|
906
|
906
|
CopyASCIItoUTF16(dnsData->mData[i].hostaddr[j], *addr);
|
|
907
|
907
|
}
|
|
908
|
908
|
|
|
909
|
|
- if (dnsData->mData[i].family == PR_AF_INET6) {
|
|
910
|
|
- entry.mFamily.AssignLiteral(u"ipv6");
|
|
911
|
|
- } else {
|
|
912
|
|
- entry.mFamily.AssignLiteral(u"ipv4");
|
|
|
909
|
+ entry.mType = dnsData->mData[i].resolveType;
|
|
|
910
|
+ if (entry.mType == nsIDNSService::RESOLVE_TYPE_DEFAULT) {
|
|
|
911
|
+ if (dnsData->mData[i].family == PR_AF_INET6) {
|
|
|
912
|
+ entry.mFamily.AssignLiteral(u"ipv6");
|
|
|
913
|
+ } else {
|
|
|
914
|
+ entry.mFamily.AssignLiteral(u"ipv4");
|
|
|
915
|
+ }
|
|
913
|
916
|
}
|
|
914
|
917
|
|
|
915
|
918
|
entry.mOriginAttributesSuffix =
|
netwerk/base/DashboardTypes.h
| ... |
... |
@@ -35,12 +35,12 @@ struct DnsAndConnectSockets { |
|
35
|
35
|
struct DNSCacheEntries {
|
|
36
|
36
|
nsCString hostname;
|
|
37
|
37
|
nsTArray<nsCString> hostaddr;
|
|
38
|
|
- uint16_t family;
|
|
39
|
|
- int64_t expiration;
|
|
40
|
|
- nsCString netInterface;
|
|
41
|
|
- bool TRR;
|
|
|
38
|
+ uint16_t family{0};
|
|
|
39
|
+ int64_t expiration{0};
|
|
|
40
|
+ bool TRR{false};
|
|
42
|
41
|
nsCString originAttributesSuffix;
|
|
43
|
42
|
nsCString flags;
|
|
|
43
|
+ uint16_t resolveType{0};
|
|
44
|
44
|
};
|
|
45
|
45
|
|
|
46
|
46
|
struct HttpConnInfo {
|
| ... |
... |
@@ -99,8 +99,10 @@ struct ParamTraits<mozilla::net::DNSCacheEntries> { |
|
99
|
99
|
WriteParam(aWriter, aParam.hostaddr);
|
|
100
|
100
|
WriteParam(aWriter, aParam.family);
|
|
101
|
101
|
WriteParam(aWriter, aParam.expiration);
|
|
102
|
|
- WriteParam(aWriter, aParam.netInterface);
|
|
103
|
102
|
WriteParam(aWriter, aParam.TRR);
|
|
|
103
|
+ WriteParam(aWriter, aParam.originAttributesSuffix);
|
|
|
104
|
+ WriteParam(aWriter, aParam.flags);
|
|
|
105
|
+ WriteParam(aWriter, aParam.resolveType);
|
|
104
|
106
|
}
|
|
105
|
107
|
|
|
106
|
108
|
static bool Read(MessageReader* aReader, paramType* aResult) {
|
| ... |
... |
@@ -108,8 +110,10 @@ struct ParamTraits<mozilla::net::DNSCacheEntries> { |
|
108
|
110
|
ReadParam(aReader, &aResult->hostaddr) &&
|
|
109
|
111
|
ReadParam(aReader, &aResult->family) &&
|
|
110
|
112
|
ReadParam(aReader, &aResult->expiration) &&
|
|
111
|
|
- ReadParam(aReader, &aResult->netInterface) &&
|
|
112
|
|
- ReadParam(aReader, &aResult->TRR);
|
|
|
113
|
+ ReadParam(aReader, &aResult->TRR) &&
|
|
|
114
|
+ ReadParam(aReader, &aResult->originAttributesSuffix) &&
|
|
|
115
|
+ ReadParam(aReader, &aResult->flags) &&
|
|
|
116
|
+ ReadParam(aReader, &aResult->resolveType);
|
|
113
|
117
|
}
|
|
114
|
118
|
};
|
|
115
|
119
|
|
netwerk/dns/nsHostResolver.cpp
| ... |
... |
@@ -1999,20 +1999,13 @@ void nsHostResolver::GetDNSCacheEntries(nsTArray<DNSCacheEntries>* args) { |
|
1999
|
1999
|
continue;
|
|
2000
|
2000
|
}
|
|
2001
|
2001
|
|
|
2002
|
|
- // For now we only show A/AAAA records.
|
|
2003
|
|
- if (!rec->IsAddrRecord()) {
|
|
2004
|
|
- continue;
|
|
2005
|
|
- }
|
|
2006
|
|
-
|
|
2007
|
|
- RefPtr<AddrHostRecord> addrRec = do_QueryObject(rec);
|
|
2008
|
|
- MOZ_ASSERT(addrRec);
|
|
2009
|
|
- if (!addrRec || !addrRec->addr_info) {
|
|
2010
|
|
- continue;
|
|
2011
|
|
- }
|
|
2012
|
|
-
|
|
2013
|
2002
|
DNSCacheEntries info;
|
|
|
2003
|
+ info.resolveType = rec->type;
|
|
2014
|
2004
|
info.hostname = rec->host;
|
|
2015
|
2005
|
info.family = rec->af;
|
|
|
2006
|
+ if (rec->mValidEnd.IsNull()) {
|
|
|
2007
|
+ continue;
|
|
|
2008
|
+ }
|
|
2016
|
2009
|
info.expiration =
|
|
2017
|
2010
|
(int64_t)(rec->mValidEnd - TimeStamp::NowLoRes()).ToSeconds();
|
|
2018
|
2011
|
if (info.expiration <= 0) {
|
| ... |
... |
@@ -2020,7 +2013,12 @@ void nsHostResolver::GetDNSCacheEntries(nsTArray<DNSCacheEntries>* args) { |
|
2020
|
2013
|
continue;
|
|
2021
|
2014
|
}
|
|
2022
|
2015
|
|
|
2023
|
|
- {
|
|
|
2016
|
+ info.originAttributesSuffix = recordEntry.GetKey().originSuffix;
|
|
|
2017
|
+ info.flags = nsPrintfCString("%u|0x%x|%u|%d|%s", rec->type, rec->flags,
|
|
|
2018
|
+ rec->af, rec->pb, rec->mTrrServer.get());
|
|
|
2019
|
+
|
|
|
2020
|
+ RefPtr<AddrHostRecord> addrRec = do_QueryObject(rec);
|
|
|
2021
|
+ if (addrRec && addrRec->addr_info) {
|
|
2024
|
2022
|
MutexAutoLock lock(addrRec->addr_info_lock);
|
|
2025
|
2023
|
for (const auto& addr : addrRec->addr_info->Addresses()) {
|
|
2026
|
2024
|
char buf[kIPv6CStrBufSize];
|
| ... |
... |
@@ -2031,10 +2029,6 @@ void nsHostResolver::GetDNSCacheEntries(nsTArray<DNSCacheEntries>* args) { |
|
2031
|
2029
|
info.TRR = addrRec->addr_info->IsTRR();
|
|
2032
|
2030
|
}
|
|
2033
|
2031
|
|
|
2034
|
|
- info.originAttributesSuffix = recordEntry.GetKey().originSuffix;
|
|
2035
|
|
- info.flags = nsPrintfCString("%u|0x%x|%u|%d|%s", rec->type, rec->flags,
|
|
2036
|
|
- rec->af, rec->pb, rec->mTrrServer.get());
|
|
2037
|
|
-
|
|
2038
|
2032
|
args->AppendElement(std::move(info));
|
|
2039
|
2033
|
}
|
|
2040
|
2034
|
}
|
netwerk/protocol/http/nsHttp.cpp
| ... |
... |
@@ -35,6 +35,8 @@ |
|
35
|
35
|
namespace mozilla {
|
|
36
|
36
|
namespace net {
|
|
37
|
37
|
|
|
|
38
|
+extern const char kProxyType_SOCKS[];
|
|
|
39
|
+
|
|
38
|
40
|
const uint32_t kHttp3VersionCount = 5;
|
|
39
|
41
|
const nsCString kHttp3Versions[] = {"h3-29"_ns, "h3-30"_ns, "h3-31"_ns,
|
|
40
|
42
|
"h3-32"_ns, "h3"_ns};
|
| ... |
... |
@@ -1165,5 +1167,19 @@ void DisallowHTTPSRR(uint32_t& aCaps) { |
|
1165
|
1167
|
aCaps = (aCaps | NS_HTTP_DISALLOW_HTTPS_RR) & ~NS_HTTP_FORCE_WAIT_HTTP_RR;
|
|
1166
|
1168
|
}
|
|
1167
|
1169
|
|
|
|
1170
|
+ProxyDNSStrategy GetProxyDNSStrategyHelper(const char* aType, uint32_t aFlag) {
|
|
|
1171
|
+ if (!aType) {
|
|
|
1172
|
+ return ProxyDNSStrategy::ORIGIN;
|
|
|
1173
|
+ }
|
|
|
1174
|
+
|
|
|
1175
|
+ if (!(aFlag & nsIProxyInfo::TRANSPARENT_PROXY_RESOLVES_HOST)) {
|
|
|
1176
|
+ if (aType == kProxyType_SOCKS) {
|
|
|
1177
|
+ return ProxyDNSStrategy::ORIGIN;
|
|
|
1178
|
+ }
|
|
|
1179
|
+ }
|
|
|
1180
|
+
|
|
|
1181
|
+ return ProxyDNSStrategy::PROXY;
|
|
|
1182
|
+}
|
|
|
1183
|
+
|
|
1168
|
1184
|
} // namespace net
|
|
1169
|
1185
|
} // namespace mozilla |
netwerk/protocol/http/nsHttp.h
| ... |
... |
@@ -527,6 +527,16 @@ bool PossibleZeroRTTRetryError(nsresult aReason); |
|
527
|
527
|
|
|
528
|
528
|
void DisallowHTTPSRR(uint32_t& aCaps);
|
|
529
|
529
|
|
|
|
530
|
+enum class ProxyDNSStrategy : uint8_t {
|
|
|
531
|
+ // To resolve the origin of the end server we are connecting
|
|
|
532
|
+ // to.
|
|
|
533
|
+ ORIGIN = 1 << 0,
|
|
|
534
|
+ // To resolve the host name of the proxy.
|
|
|
535
|
+ PROXY = 1 << 1
|
|
|
536
|
+};
|
|
|
537
|
+
|
|
|
538
|
+ProxyDNSStrategy GetProxyDNSStrategyHelper(const char* aType, uint32_t aFlag);
|
|
|
539
|
+
|
|
530
|
540
|
} // namespace net
|
|
531
|
541
|
} // namespace mozilla
|
|
532
|
542
|
|
netwerk/protocol/http/nsHttpChannel.cpp
| ... |
... |
@@ -762,6 +762,10 @@ nsresult nsHttpChannel::MaybeUseHTTPSRRForUpgrade(bool aShouldUpgrade, |
|
762
|
762
|
}
|
|
763
|
763
|
|
|
764
|
764
|
auto shouldSkipUpgradeWithHTTPSRR = [&]() -> bool {
|
|
|
765
|
+ if (mCaps & NS_HTTP_DISALLOW_HTTPS_RR) {
|
|
|
766
|
+ return true;
|
|
|
767
|
+ }
|
|
|
768
|
+
|
|
765
|
769
|
// Skip using HTTPS RR to upgrade when this is not a top-level load and the
|
|
766
|
770
|
// loading principal is http.
|
|
767
|
771
|
if ((mLoadInfo->GetExternalContentPolicyType() !=
|
| ... |
... |
@@ -784,6 +788,11 @@ nsresult nsHttpChannel::MaybeUseHTTPSRRForUpgrade(bool aShouldUpgrade, |
|
784
|
788
|
return true;
|
|
785
|
789
|
}
|
|
786
|
790
|
|
|
|
791
|
+ auto dnsStrategy = GetProxyDNSStrategy();
|
|
|
792
|
+ if (dnsStrategy != ProxyDNSStrategy::ORIGIN) {
|
|
|
793
|
+ return true;
|
|
|
794
|
+ }
|
|
|
795
|
+
|
|
787
|
796
|
nsAutoCString uriHost;
|
|
788
|
797
|
mURI->GetAsciiHost(uriHost);
|
|
789
|
798
|
|
| ... |
... |
@@ -808,11 +817,6 @@ nsresult nsHttpChannel::MaybeUseHTTPSRRForUpgrade(bool aShouldUpgrade, |
|
808
|
817
|
return ContinueOnBeforeConnect(hasHTTPSRR, aStatus, hasHTTPSRR);
|
|
809
|
818
|
}
|
|
810
|
819
|
|
|
811
|
|
- auto dnsStrategy = GetProxyDNSStrategy();
|
|
812
|
|
- if (!(dnsStrategy & DNS_PREFETCH_ORIGIN)) {
|
|
813
|
|
- return ContinueOnBeforeConnect(aShouldUpgrade, aStatus);
|
|
814
|
|
- }
|
|
815
|
|
-
|
|
816
|
820
|
LOG(("nsHttpChannel::MaybeUseHTTPSRRForUpgrade [%p] wait for HTTPS RR",
|
|
817
|
821
|
this));
|
|
818
|
822
|
|
| ... |
... |
@@ -1218,13 +1222,13 @@ void nsHttpChannel::SpeculativeConnect() { |
|
1218
|
1222
|
NS_NewNotificationCallbacksAggregation(mCallbacks, mLoadGroup,
|
|
1219
|
1223
|
getter_AddRefs(callbacks));
|
|
1220
|
1224
|
if (!callbacks) return;
|
|
1221
|
|
-
|
|
1222
|
|
- Unused << gHttpHandler->SpeculativeConnect(
|
|
|
1225
|
+ bool httpsRRAllowed = !(mCaps & NS_HTTP_DISALLOW_HTTPS_RR);
|
|
|
1226
|
+ Unused << gHttpHandler->MaybeSpeculativeConnectWithHTTPSRR(
|
|
1223
|
1227
|
mConnectionInfo, callbacks,
|
|
1224
|
1228
|
mCaps & (NS_HTTP_DISALLOW_SPDY | NS_HTTP_TRR_MODE_MASK |
|
|
1225
|
1229
|
NS_HTTP_DISABLE_IPV4 | NS_HTTP_DISABLE_IPV6 |
|
|
1226
|
1230
|
NS_HTTP_DISALLOW_HTTP3 | NS_HTTP_REFRESH_DNS),
|
|
1227
|
|
- gHttpHandler->EchConfigEnabled());
|
|
|
1231
|
+ gHttpHandler->EchConfigEnabled() && httpsRRAllowed);
|
|
1228
|
1232
|
}
|
|
1229
|
1233
|
|
|
1230
|
1234
|
void nsHttpChannel::DoNotifyListenerCleanup() {
|
| ... |
... |
@@ -6538,27 +6542,16 @@ nsHttpChannel::GetOrCreateChannelClassifier() { |
|
6538
|
6542
|
return classifier.forget();
|
|
6539
|
6543
|
}
|
|
6540
|
6544
|
|
|
6541
|
|
-uint16_t nsHttpChannel::GetProxyDNSStrategy() {
|
|
6542
|
|
- // This function currently only supports returning DNS_PREFETCH_ORIGIN.
|
|
6543
|
|
- // Support for the rest of the DNS_* flags will be added later.
|
|
6544
|
|
-
|
|
6545
|
|
- if (!mProxyInfo) {
|
|
6546
|
|
- return DNS_PREFETCH_ORIGIN;
|
|
|
6545
|
+ProxyDNSStrategy nsHttpChannel::GetProxyDNSStrategy() {
|
|
|
6546
|
+ // When network_dns_force_use_https_rr is true, return DNS_PREFETCH_ORIGIN.
|
|
|
6547
|
+ // This ensures that we always perform HTTPS RR query.
|
|
|
6548
|
+ nsCOMPtr<nsProxyInfo> proxyInfo(static_cast<nsProxyInfo*>(mProxyInfo.get()));
|
|
|
6549
|
+ if (!proxyInfo || StaticPrefs::network_dns_force_use_https_rr()) {
|
|
|
6550
|
+ return ProxyDNSStrategy::ORIGIN;
|
|
6547
|
6551
|
}
|
|
6548
|
6552
|
|
|
6549
|
|
- uint32_t flags = 0;
|
|
6550
|
|
- nsAutoCString type;
|
|
6551
|
|
- mProxyInfo->GetFlags(&flags);
|
|
6552
|
|
- mProxyInfo->GetType(type);
|
|
6553
|
|
-
|
|
6554
|
6553
|
// If the proxy is not to perform name resolution itself.
|
|
6555
|
|
- if (!(flags & nsIProxyInfo::TRANSPARENT_PROXY_RESOLVES_HOST)) {
|
|
6556
|
|
- if (type.EqualsLiteral("socks")) {
|
|
6557
|
|
- return DNS_PREFETCH_ORIGIN;
|
|
6558
|
|
- }
|
|
6559
|
|
- }
|
|
6560
|
|
-
|
|
6561
|
|
- return 0;
|
|
|
6554
|
+ return GetProxyDNSStrategyHelper(proxyInfo->Type(), proxyInfo->Flags());
|
|
6562
|
6555
|
}
|
|
6563
|
6556
|
|
|
6564
|
6557
|
// BeginConnect() SHOULD NOT call AsyncAbort(). AsyncAbort will be called by
|
| ... |
... |
@@ -6744,11 +6737,13 @@ nsresult nsHttpChannel::BeginConnect() { |
|
6744
|
6737
|
}
|
|
6745
|
6738
|
|
|
6746
|
6739
|
bool trrEnabled = false;
|
|
|
6740
|
+ auto dnsStrategy = GetProxyDNSStrategy();
|
|
6747
|
6741
|
bool httpsRRAllowed =
|
|
6748
|
6742
|
!LoadBeConservative() && !(mCaps & NS_HTTP_BE_CONSERVATIVE) &&
|
|
6749
|
6743
|
!(mLoadInfo->TriggeringPrincipal()->IsSystemPrincipal() &&
|
|
6750
|
6744
|
mLoadInfo->GetExternalContentPolicyType() !=
|
|
6751
|
6745
|
ExtContentPolicy::TYPE_DOCUMENT) &&
|
|
|
6746
|
+ dnsStrategy == ProxyDNSStrategy::ORIGIN &&
|
|
6752
|
6747
|
!mConnectionInfo->UsingConnect() && canUseHTTPSRRonNetwork(trrEnabled) &&
|
|
6753
|
6748
|
StaticPrefs::network_dns_use_https_rr_as_altsvc();
|
|
6754
|
6749
|
if (!httpsRRAllowed) {
|
| ... |
... |
@@ -6859,16 +6854,7 @@ nsresult nsHttpChannel::BeginConnect() { |
|
6859
|
6854
|
ReEvaluateReferrerAfterTrackingStatusIsKnown();
|
|
6860
|
6855
|
}
|
|
6861
|
6856
|
|
|
6862
|
|
- rv = MaybeStartDNSPrefetch();
|
|
6863
|
|
- if (NS_FAILED(rv)) {
|
|
6864
|
|
- auto dnsStrategy = GetProxyDNSStrategy();
|
|
6865
|
|
- if (dnsStrategy & DNS_BLOCK_ON_ORIGIN_RESOLVE) {
|
|
6866
|
|
- // TODO: Should this be fatal?
|
|
6867
|
|
- return rv;
|
|
6868
|
|
- }
|
|
6869
|
|
- // Otherwise this shouldn't be fatal.
|
|
6870
|
|
- return NS_OK;
|
|
6871
|
|
- }
|
|
|
6857
|
+ MaybeStartDNSPrefetch();
|
|
6872
|
6858
|
|
|
6873
|
6859
|
rv = CallOrWaitForResume(
|
|
6874
|
6860
|
[](nsHttpChannel* self) { return self->PrepareToConnect(); });
|
| ... |
... |
@@ -6888,7 +6874,7 @@ nsresult nsHttpChannel::BeginConnect() { |
|
6888
|
6874
|
return NS_OK;
|
|
6889
|
6875
|
}
|
|
6890
|
6876
|
|
|
6891
|
|
-nsresult nsHttpChannel::MaybeStartDNSPrefetch() {
|
|
|
6877
|
+void nsHttpChannel::MaybeStartDNSPrefetch() {
|
|
6892
|
6878
|
// Start a DNS lookup very early in case the real open is queued the DNS can
|
|
6893
|
6879
|
// happen in parallel. Do not do so in the presence of an HTTP proxy as
|
|
6894
|
6880
|
// all lookups other than for the proxy itself are done by the proxy.
|
| ... |
... |
@@ -6904,7 +6890,7 @@ nsresult nsHttpChannel::MaybeStartDNSPrefetch() { |
|
6904
|
6890
|
// timing we used.
|
|
6905
|
6891
|
if ((mLoadFlags & (LOAD_NO_NETWORK_IO | LOAD_ONLY_FROM_CACHE)) ||
|
|
6906
|
6892
|
LoadAuthRedirectedChannel()) {
|
|
6907
|
|
- return NS_OK;
|
|
|
6893
|
+ return;
|
|
6908
|
6894
|
}
|
|
6909
|
6895
|
|
|
6910
|
6896
|
auto dnsStrategy = GetProxyDNSStrategy();
|
| ... |
... |
@@ -6912,10 +6898,10 @@ nsresult nsHttpChannel::MaybeStartDNSPrefetch() { |
|
6912
|
6898
|
LOG(
|
|
6913
|
6899
|
("nsHttpChannel::MaybeStartDNSPrefetch [this=%p, strategy=%u] "
|
|
6914
|
6900
|
"prefetching%s\n",
|
|
6915
|
|
- this, dnsStrategy,
|
|
|
6901
|
+ this, static_cast<uint32_t>(dnsStrategy),
|
|
6916
|
6902
|
mCaps & NS_HTTP_REFRESH_DNS ? ", refresh requested" : ""));
|
|
6917
|
6903
|
|
|
6918
|
|
- if (dnsStrategy & DNS_PREFETCH_ORIGIN) {
|
|
|
6904
|
+ if (dnsStrategy == ProxyDNSStrategy::ORIGIN) {
|
|
6919
|
6905
|
OriginAttributes originAttributes;
|
|
6920
|
6906
|
StoragePrincipalHelper::GetOriginAttributesForNetworkState(
|
|
6921
|
6907
|
this, originAttributes);
|
| ... |
... |
@@ -6927,20 +6913,8 @@ nsresult nsHttpChannel::MaybeStartDNSPrefetch() { |
|
6927
|
6913
|
if (mCaps & NS_HTTP_REFRESH_DNS) {
|
|
6928
|
6914
|
dnsFlags |= nsIDNSService::RESOLVE_BYPASS_CACHE;
|
|
6929
|
6915
|
}
|
|
6930
|
|
- nsresult rv = mDNSPrefetch->PrefetchHigh(dnsFlags);
|
|
6931
|
6916
|
|
|
6932
|
|
- if (dnsStrategy & DNS_BLOCK_ON_ORIGIN_RESOLVE) {
|
|
6933
|
|
- LOG((" blocking on prefetching origin"));
|
|
6934
|
|
-
|
|
6935
|
|
- if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
6936
|
|
- LOG((" lookup failed with 0x%08" PRIx32 ", aborting request",
|
|
6937
|
|
- static_cast<uint32_t>(rv)));
|
|
6938
|
|
- return rv;
|
|
6939
|
|
- }
|
|
6940
|
|
-
|
|
6941
|
|
- // Resolved in OnLookupComplete.
|
|
6942
|
|
- mDNSBlockingThenable = mDNSBlockingPromise.Ensure(__func__);
|
|
6943
|
|
- }
|
|
|
6917
|
+ Unused << mDNSPrefetch->PrefetchHigh(dnsFlags);
|
|
6944
|
6918
|
|
|
6945
|
6919
|
bool unused;
|
|
6946
|
6920
|
if (StaticPrefs::network_dns_use_https_rr_as_altsvc() && !mHTTPSSVCRecord &&
|
| ... |
... |
@@ -6960,8 +6934,6 @@ nsresult nsHttpChannel::MaybeStartDNSPrefetch() { |
|
6960
|
6934
|
});
|
|
6961
|
6935
|
}
|
|
6962
|
6936
|
}
|
|
6963
|
|
-
|
|
6964
|
|
- return NS_OK;
|
|
6965
|
6937
|
}
|
|
6966
|
6938
|
|
|
6967
|
6939
|
NS_IMETHODIMP
|
netwerk/protocol/http/nsHttpChannel.h
| ... |
... |
@@ -303,23 +303,11 @@ class nsHttpChannel final : public HttpBaseChannel, |
|
303
|
303
|
// Connections will only be established in this function.
|
|
304
|
304
|
// (including DNS prefetch and speculative connection.)
|
|
305
|
305
|
void MaybeResolveProxyAndBeginConnect();
|
|
306
|
|
- nsresult MaybeStartDNSPrefetch();
|
|
307
|
|
-
|
|
308
|
|
- // Tells the channel to resolve the origin of the end server we are connecting
|
|
309
|
|
- // to.
|
|
310
|
|
- static uint16_t const DNS_PREFETCH_ORIGIN = 1 << 0;
|
|
311
|
|
- // Tells the channel to resolve the host name of the proxy.
|
|
312
|
|
- static uint16_t const DNS_PREFETCH_PROXY = 1 << 1;
|
|
313
|
|
- // Will be set if the current channel uses an HTTP/HTTPS proxy.
|
|
314
|
|
- static uint16_t const DNS_PROXY_IS_HTTP = 1 << 2;
|
|
315
|
|
- // Tells the channel to wait for the result of the origin server resolution
|
|
316
|
|
- // before any connection attempts are made.
|
|
317
|
|
- static uint16_t const DNS_BLOCK_ON_ORIGIN_RESOLVE = 1 << 3;
|
|
|
306
|
+ void MaybeStartDNSPrefetch();
|
|
318
|
307
|
|
|
319
|
308
|
// Based on the proxy configuration determine the strategy for resolving the
|
|
320
|
309
|
// end server host name.
|
|
321
|
|
- // Returns a combination of the above flags.
|
|
322
|
|
- uint16_t GetProxyDNSStrategy();
|
|
|
310
|
+ ProxyDNSStrategy GetProxyDNSStrategy();
|
|
323
|
311
|
|
|
324
|
312
|
// We might synchronously or asynchronously call BeginConnect,
|
|
325
|
313
|
// which includes DNS prefetch and speculative connection, according to
|
netwerk/protocol/http/nsHttpConnectionInfo.h
| ... |
... |
@@ -127,6 +127,13 @@ class nsHttpConnectionInfo final : public ARefBase { |
|
127
|
127
|
const char* ProxyPassword() const {
|
|
128
|
128
|
return mProxyInfo ? mProxyInfo->Password().get() : nullptr;
|
|
129
|
129
|
}
|
|
|
130
|
+ uint32_t ProxyFlag() const {
|
|
|
131
|
+ uint32_t flags = 0;
|
|
|
132
|
+ if (mProxyInfo) {
|
|
|
133
|
+ mProxyInfo->GetFlags(&flags);
|
|
|
134
|
+ }
|
|
|
135
|
+ return flags;
|
|
|
136
|
+ }
|
|
130
|
137
|
|
|
131
|
138
|
const nsCString& ProxyAuthorizationHeader() const {
|
|
132
|
139
|
return mProxyInfo ? mProxyInfo->ProxyAuthorizationHeader() : EmptyCString();
|
netwerk/protocol/http/nsHttpConnectionMgr.cpp
| ... |
... |
@@ -3573,9 +3573,15 @@ void nsHttpConnectionMgr::DoSpeculativeConnectionInternal( |
|
3573
|
3573
|
return;
|
|
3574
|
3574
|
}
|
|
3575
|
3575
|
|
|
3576
|
|
- if (aFetchHTTPSRR && NS_SUCCEEDED(aTrans->FetchHTTPSRR())) {
|
|
3577
|
|
- // nsHttpConnectionMgr::DoSpeculativeConnection will be called again when
|
|
3578
|
|
- // HTTPS RR is available.
|
|
|
3576
|
+ ProxyDNSStrategy strategy = GetProxyDNSStrategyHelper(
|
|
|
3577
|
+ aEnt->mConnInfo->ProxyType(), aEnt->mConnInfo->ProxyFlag());
|
|
|
3578
|
+ // Speculative connections can be triggered by non-Necko consumers,
|
|
|
3579
|
+ // so add an extra check to ensure HTTPS RR isn't fetched when a proxy is
|
|
|
3580
|
+ // used.
|
|
|
3581
|
+ if (aFetchHTTPSRR && strategy == ProxyDNSStrategy::ORIGIN &&
|
|
|
3582
|
+ NS_SUCCEEDED(aTrans->FetchHTTPSRR())) {
|
|
|
3583
|
+ // nsHttpConnectionMgr::DoSpeculativeConnection will be called again
|
|
|
3584
|
+ // when HTTPS RR is available.
|
|
3579
|
3585
|
return;
|
|
3580
|
3586
|
}
|
|
3581
|
3587
|
|
netwerk/protocol/http/nsHttpHandler.cpp
| ... |
... |
@@ -2388,7 +2388,9 @@ nsresult nsHttpHandler::SpeculativeConnectInternal( |
|
2388
|
2388
|
}
|
|
2389
|
2389
|
}
|
|
2390
|
2390
|
|
|
2391
|
|
- return SpeculativeConnect(ci, aCallbacks);
|
|
|
2391
|
+ // When ech is enabled, always do speculative connect with HTTPS RR.
|
|
|
2392
|
+ return MaybeSpeculativeConnectWithHTTPSRR(ci, aCallbacks, 0,
|
|
|
2393
|
+ EchConfigEnabled());
|
|
2392
|
2394
|
}
|
|
2393
|
2395
|
|
|
2394
|
2396
|
NS_IMETHODIMP
|
netwerk/protocol/http/nsHttpHandler.h
| ... |
... |
@@ -296,14 +296,13 @@ class nsHttpHandler final : public nsIHttpProtocolHandler, |
|
296
|
296
|
return mConnMgr->GetSocketThreadTarget(target);
|
|
297
|
297
|
}
|
|
298
|
298
|
|
|
299
|
|
- [[nodiscard]] nsresult SpeculativeConnect(nsHttpConnectionInfo* ci,
|
|
300
|
|
- nsIInterfaceRequestor* callbacks,
|
|
301
|
|
- uint32_t caps = 0,
|
|
302
|
|
- bool aFetchHTTPSRR = false) {
|
|
|
299
|
+ [[nodiscard]] nsresult MaybeSpeculativeConnectWithHTTPSRR(
|
|
|
300
|
+ nsHttpConnectionInfo* ci, nsIInterfaceRequestor* callbacks, uint32_t caps,
|
|
|
301
|
+ bool aFetchHTTPSRR) {
|
|
303
|
302
|
TickleWifi(callbacks);
|
|
304
|
303
|
RefPtr<nsHttpConnectionInfo> clone = ci->Clone();
|
|
305
|
304
|
return mConnMgr->SpeculativeConnect(clone, callbacks, caps, nullptr,
|
|
306
|
|
- aFetchHTTPSRR | EchConfigEnabled());
|
|
|
305
|
+ aFetchHTTPSRR);
|
|
307
|
306
|
}
|
|
308
|
307
|
|
|
309
|
308
|
[[nodiscard]] nsresult SpeculativeConnect(nsHttpConnectionInfo* ci,
|
netwerk/test/unit/test_proxyDNS_leak.js
|
|
1
|
+/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
2
|
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
3
|
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
4
|
+
|
|
|
5
|
+// Test when socks proxy is registered, we don't try to resolve HTTPS record.
|
|
|
6
|
+// Steps:
|
|
|
7
|
+// 1. Use addHTTPSRecordOverride to add an override for service.com.
|
|
|
8
|
+// 2. Add a proxy filter to use socks proxy.
|
|
|
9
|
+// 3. Create a request to load service.com.
|
|
|
10
|
+// 4. See if the HTTPS record is in DNS cache entries.
|
|
|
11
|
+
|
|
|
12
|
+"use strict";
|
|
|
13
|
+
|
|
|
14
|
+const gDashboard = Cc["@mozilla.org/network/dashboard;1"].getService(
|
|
|
15
|
+ Ci.nsIDashboard
|
|
|
16
|
+);
|
|
|
17
|
+const pps = Cc["@mozilla.org/network/protocol-proxy-service;1"].getService();
|
|
|
18
|
+
|
|
|
19
|
+add_task(async function setup() {
|
|
|
20
|
+ Services.prefs.setBoolPref("network.dns.native_https_query", true);
|
|
|
21
|
+ Services.prefs.setBoolPref("network.dns.native_https_query_win10", true);
|
|
|
22
|
+ const override = Cc["@mozilla.org/network/native-dns-override;1"].getService(
|
|
|
23
|
+ Ci.nsINativeDNSResolverOverride
|
|
|
24
|
+ );
|
|
|
25
|
+
|
|
|
26
|
+ let rawBuffer = [
|
|
|
27
|
+ 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 0, 7, 115, 101, 114, 118, 105, 99, 101,
|
|
|
28
|
+ 3, 99, 111, 109, 0, 0, 65, 0, 1, 0, 0, 0, 55, 0, 13, 0, 1, 0, 0, 1, 0, 6, 2,
|
|
|
29
|
+ 104, 50, 2, 104, 51,
|
|
|
30
|
+ ];
|
|
|
31
|
+ override.addHTTPSRecordOverride("service.com", rawBuffer, rawBuffer.length);
|
|
|
32
|
+ override.addIPOverride("service.com", "127.0.0.1");
|
|
|
33
|
+ registerCleanupFunction(() => {
|
|
|
34
|
+ Services.prefs.clearUserPref("network.dns.native_https_query");
|
|
|
35
|
+ Services.prefs.clearUserPref("network.dns.native_https_query_win10");
|
|
|
36
|
+ Services.prefs.clearUserPref("network.dns.localDomains");
|
|
|
37
|
+ override.clearOverrides();
|
|
|
38
|
+ });
|
|
|
39
|
+});
|
|
|
40
|
+
|
|
|
41
|
+function makeChan(uri) {
|
|
|
42
|
+ let chan = NetUtil.newChannel({
|
|
|
43
|
+ uri,
|
|
|
44
|
+ loadUsingSystemPrincipal: true,
|
|
|
45
|
+ contentPolicyType: Ci.nsIContentPolicy.TYPE_DOCUMENT,
|
|
|
46
|
+ }).QueryInterface(Ci.nsIHttpChannel);
|
|
|
47
|
+ chan.loadFlags = Ci.nsIChannel.LOAD_INITIAL_DOCUMENT_URI;
|
|
|
48
|
+ return chan;
|
|
|
49
|
+}
|
|
|
50
|
+
|
|
|
51
|
+function channelOpenPromise(chan, flags) {
|
|
|
52
|
+ return new Promise(resolve => {
|
|
|
53
|
+ function finish(req, buffer) {
|
|
|
54
|
+ resolve([req, buffer]);
|
|
|
55
|
+ }
|
|
|
56
|
+ chan.asyncOpen(new ChannelListener(finish, null, flags));
|
|
|
57
|
+ });
|
|
|
58
|
+}
|
|
|
59
|
+
|
|
|
60
|
+async function isRecordFound(hostname) {
|
|
|
61
|
+ return new Promise(resolve => {
|
|
|
62
|
+ gDashboard.requestDNSInfo(function (data) {
|
|
|
63
|
+ let found = false;
|
|
|
64
|
+ for (let i = 0; i < data.entries.length; i++) {
|
|
|
65
|
+ if (
|
|
|
66
|
+ data.entries[i].hostname == hostname &&
|
|
|
67
|
+ data.entries[i].type == Ci.nsIDNSService.RESOLVE_TYPE_HTTPSSVC
|
|
|
68
|
+ ) {
|
|
|
69
|
+ found = true;
|
|
|
70
|
+ break;
|
|
|
71
|
+ }
|
|
|
72
|
+ }
|
|
|
73
|
+ resolve(found);
|
|
|
74
|
+ });
|
|
|
75
|
+ });
|
|
|
76
|
+}
|
|
|
77
|
+
|
|
|
78
|
+async function do_test_with_proxy_filter(filter) {
|
|
|
79
|
+ pps.registerFilter(filter, 10);
|
|
|
80
|
+
|
|
|
81
|
+ let chan = makeChan(`https://service.com/`);
|
|
|
82
|
+ await channelOpenPromise(chan, CL_EXPECT_LATE_FAILURE | CL_ALLOW_UNKNOWN_CL);
|
|
|
83
|
+
|
|
|
84
|
+ let found = await isRecordFound("service.com");
|
|
|
85
|
+ pps.unregisterFilter(filter);
|
|
|
86
|
+
|
|
|
87
|
+ return found;
|
|
|
88
|
+}
|
|
|
89
|
+
|
|
|
90
|
+add_task(async function test_proxyDNS_do_leak() {
|
|
|
91
|
+ let filter = new NodeProxyFilter("socks", "localhost", 443, 0);
|
|
|
92
|
+
|
|
|
93
|
+ let res = await do_test_with_proxy_filter(filter);
|
|
|
94
|
+
|
|
|
95
|
+ Assert.ok(res, "Should find a DNS entry");
|
|
|
96
|
+});
|
|
|
97
|
+
|
|
|
98
|
+add_task(async function test_proxyDNS_dont_leak() {
|
|
|
99
|
+ Services.dns.clearCache(false);
|
|
|
100
|
+
|
|
|
101
|
+ let filter = new NodeProxyFilter(
|
|
|
102
|
+ "socks",
|
|
|
103
|
+ "localhost",
|
|
|
104
|
+ 443,
|
|
|
105
|
+ Ci.nsIProxyInfo.TRANSPARENT_PROXY_RESOLVES_HOST
|
|
|
106
|
+ );
|
|
|
107
|
+
|
|
|
108
|
+ let res = await do_test_with_proxy_filter(filter);
|
|
|
109
|
+
|
|
|
110
|
+ Assert.ok(!res, "Should not find a DNS entry");
|
|
|
111
|
+}); |
netwerk/test/unit/xpcshell.toml
| ... |
... |
@@ -983,6 +983,12 @@ run-sequentially = "node server exceptions dont replay well" |
|
983
|
983
|
|
|
984
|
984
|
["test_proxy_pac.js"]
|
|
985
|
985
|
|
|
|
986
|
+["test_proxyDNS_leak.js"]
|
|
|
987
|
+skip-if = [
|
|
|
988
|
+ "os == 'android'",
|
|
|
989
|
+ "socketprocess_networking",
|
|
|
990
|
+]
|
|
|
991
|
+
|
|
986
|
992
|
["test_proxyconnect.js"]
|
|
987
|
993
|
skip-if = [
|
|
988
|
994
|
"tsan",
|
toolkit/content/aboutNetworking.js
| ... |
... |
@@ -116,6 +116,11 @@ function displayDns(data) { |
|
116
|
116
|
new_cont.setAttribute("id", "dns_content");
|
|
117
|
117
|
|
|
118
|
118
|
for (let i = 0; i < data.entries.length; i++) {
|
|
|
119
|
+ // TODO: Will be supported in bug 1889387.
|
|
|
120
|
+ if (data.entries[i].type != Ci.nsIDNSService.RESOLVE_TYPE_DEFAULT) {
|
|
|
121
|
+ continue;
|
|
|
122
|
+ }
|
|
|
123
|
+
|
|
119
|
124
|
let row = document.createElement("tr");
|
|
120
|
125
|
row.appendChild(col(data.entries[i].hostname));
|
|
121
|
126
|
row.appendChild(col(data.entries[i].family));
|
|