author | Kershaw Chang <kershaw@mozilla.com> |
Wed, 21 Oct 2020 00:52:46 +0000 (2020-10-21) | |
changeset 553801 | c0e399e7d49594e1e245e4eaa21a3bb3f6148d7b |
parent 553800 | 7abfe9ea6def28b5140620ca38a84664195935d5 |
child 553802 | 9a84d54b203f249e80bf0f13bb6645f912e28140 |
push id | 129058 |
push user | kjang@mozilla.com |
push date | Wed, 21 Oct 2020 07:46:54 +0000 (2020-10-21) |
treeherder | autoland@c0e399e7d495 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | necko-reviewers, fluent-reviewers, flod, dragana, webidl, asuth |
bugs | 1667356 |
milestone | 84.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/webidl/NetDashboard.webidl +++ b/dom/webidl/NetDashboard.webidl @@ -76,16 +76,61 @@ dictionary DNSCacheDict { [GenerateConversionToJS] dictionary DNSLookupDict { sequence<DOMString> address; DOMString error = ""; boolean answer = false; }; +dictionary SVCParam { + unsigned short type = 0; +}; + +dictionary SVCParamAlpn : SVCParam { + DOMString alpn = ""; +}; + +dictionary SVCParamNoDefaultAlpn : SVCParam { +}; + +dictionary SVCParamPort : SVCParam { + unsigned short port = 0; +}; + +dictionary SVCParamIPv4Hint : SVCParam { + sequence<DOMString> address; +}; + +dictionary SVCParamIPv6Hint : SVCParam { + sequence<DOMString> address; +}; + +dictionary SVCParamEchConfig : SVCParam { + DOMString echConfig = ""; +}; + +dictionary HTTPSRecord { + unsigned short priority = 0; + DOMString targetName = ""; + SVCParamAlpn alpn; + SVCParamNoDefaultAlpn noDefaultAlpn; + SVCParamPort port; + SVCParamIPv4Hint ipv4Hint; + SVCParamIPv6Hint ipv6Hint; + SVCParamEchConfig echConfig; +}; + +[GenerateConversionToJS] +dictionary HTTPSRRLookupDict { + DOMString error = ""; + boolean answer = false; + sequence<HTTPSRecord> records; +}; + [GenerateConversionToJS] dictionary ConnStatusDict { DOMString status = ""; }; dictionary RcwnPerfStats { unsigned long avgShort = 0; unsigned long avgLong = 0;
--- a/netwerk/base/Dashboard.cpp +++ b/netwerk/base/Dashboard.cpp @@ -2,24 +2,27 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http:mozilla.org/MPL/2.0/. */ #include "mozilla/dom/NetDashboardBinding.h" #include "mozilla/dom/ToJSValue.h" #include "mozilla/ErrorNames.h" #include "mozilla/net/Dashboard.h" #include "mozilla/net/HttpInfo.h" +#include "mozilla/net/HTTPSSVC.h" #include "mozilla/net/SocketProcessParent.h" #include "nsHttp.h" #include "nsICancelable.h" #include "nsIDNSListener.h" #include "nsIDNSService.h" #include "nsIDNSRecord.h" +#include "nsIDNSByTypeRecord.h" #include "nsIInputStream.h" #include "nsINamed.h" +#include "nsINetAddr.h" #include "nsISocketTransport.h" #include "nsProxyRelease.h" #include "nsSocketTransportService2.h" #include "nsThreadUtils.h" #include "nsURLHelper.h" #include "mozilla/Logging.h" #include "nsIOService.h" #include "../cache2/CacheFileUtils.h" @@ -238,16 +241,17 @@ class LookupHelper final : public nsIDNS public: NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSIDNSLISTENER LookupHelper() : mEventTarget{nullptr}, mStatus{NS_ERROR_NOT_INITIALIZED} {} nsresult ConstructAnswer(LookupArgument* aArgument); + nsresult ConstructHTTPSRRAnswer(LookupArgument* aArgument); public: nsCOMPtr<nsICancelable> mCancel; nsMainThreadPtrHandle<nsINetDashboardCallback> mCallback; nsIEventTarget* mEventTarget; nsresult mStatus; }; @@ -255,16 +259,27 @@ NS_IMPL_ISUPPORTS(LookupHelper, nsIDNSLi NS_IMETHODIMP LookupHelper::OnLookupComplete(nsICancelable* aRequest, nsIDNSRecord* aRecord, nsresult aStatus) { MOZ_ASSERT(aRequest == mCancel); mCancel = nullptr; mStatus = aStatus; + nsCOMPtr<nsIDNSHTTPSSVCRecord> httpsRecord = do_QueryInterface(aRecord); + if (httpsRecord) { + RefPtr<LookupArgument> arg = new LookupArgument(aRecord, this); + mEventTarget->Dispatch( + NewRunnableMethod<RefPtr<LookupArgument>>( + "net::LookupHelper::ConstructHTTPSRRAnswer", this, + &LookupHelper::ConstructHTTPSRRAnswer, arg), + NS_DISPATCH_NORMAL); + return NS_OK; + } + RefPtr<LookupArgument> arg = new LookupArgument(aRecord, this); mEventTarget->Dispatch(NewRunnableMethod<RefPtr<LookupArgument>>( "net::LookupHelper::ConstructAnswer", this, &LookupHelper::ConstructAnswer, arg), NS_DISPATCH_NORMAL); return NS_OK; } @@ -303,16 +318,150 @@ nsresult LookupHelper::ConstructAnswer(L return NS_ERROR_FAILURE; } this->mCallback->OnDashboardDataAvailable(val); return NS_OK; } +nsresult LookupHelper::ConstructHTTPSRRAnswer(LookupArgument* aArgument) { + nsCOMPtr<nsIDNSHTTPSSVCRecord> httpsRecord = + do_QueryInterface(aArgument->mRecord); + + AutoSafeJSContext cx; + + mozilla::dom::HTTPSRRLookupDict dict; + dict.mRecords.Construct(); + + Sequence<dom::HTTPSRecord>& records = dict.mRecords.Value(); + if (NS_SUCCEEDED(mStatus) && httpsRecord) { + dict.mAnswer = true; + nsTArray<RefPtr<nsISVCBRecord>> svcbRecords; + httpsRecord->GetRecords(svcbRecords); + + for (const auto& record : svcbRecords) { + dom::HTTPSRecord* nextRecord = records.AppendElement(fallible); + if (!nextRecord) { + return NS_ERROR_OUT_OF_MEMORY; + } + + Unused << record->GetPriority(&nextRecord->mPriority); + nsCString name; + Unused << record->GetName(name); + CopyASCIItoUTF16(name, nextRecord->mTargetName); + + nsTArray<RefPtr<nsISVCParam>> values; + Unused << record->GetValues(values); + if (values.IsEmpty()) { + continue; + } + + for (const auto& value : values) { + uint16_t type; + Unused << value->GetType(&type); + switch (type) { + case SvcParamKeyAlpn: { + nextRecord->mAlpn.Construct(); + nextRecord->mAlpn.Value().mType = type; + nsCOMPtr<nsISVCParamAlpn> alpnParam = do_QueryInterface(value); + nsCString alpnStr; + Unused << alpnParam->GetAlpn(alpnStr); + CopyASCIItoUTF16(alpnStr, nextRecord->mAlpn.Value().mAlpn); + break; + } + case SvcParamKeyNoDefaultAlpn: { + nextRecord->mNoDefaultAlpn.Construct(); + nextRecord->mNoDefaultAlpn.Value().mType = type; + break; + } + case SvcParamKeyPort: { + nextRecord->mPort.Construct(); + nextRecord->mPort.Value().mType = type; + nsCOMPtr<nsISVCParamPort> portParam = do_QueryInterface(value); + Unused << portParam->GetPort(&nextRecord->mPort.Value().mPort); + break; + } + case SvcParamKeyIpv4Hint: { + nextRecord->mIpv4Hint.Construct(); + nextRecord->mIpv4Hint.Value().mType = type; + nsCOMPtr<nsISVCParamIPv4Hint> ipv4Param = do_QueryInterface(value); + nsTArray<RefPtr<nsINetAddr>> ipv4Hint; + Unused << ipv4Param->GetIpv4Hint(ipv4Hint); + if (!ipv4Hint.IsEmpty()) { + nextRecord->mIpv4Hint.Value().mAddress.Construct(); + for (const auto& address : ipv4Hint) { + nsString* nextAddress = nextRecord->mIpv4Hint.Value() + .mAddress.Value() + .AppendElement(fallible); + if (!nextAddress) { + return NS_ERROR_OUT_OF_MEMORY; + } + + nsCString addressASCII; + Unused << address->GetAddress(addressASCII); + CopyASCIItoUTF16(addressASCII, *nextAddress); + } + } + break; + } + case SvcParamKeyIpv6Hint: { + nextRecord->mIpv6Hint.Construct(); + nextRecord->mIpv6Hint.Value().mType = type; + nsCOMPtr<nsISVCParamIPv6Hint> ipv6Param = do_QueryInterface(value); + nsTArray<RefPtr<nsINetAddr>> ipv6Hint; + Unused << ipv6Param->GetIpv6Hint(ipv6Hint); + if (!ipv6Hint.IsEmpty()) { + nextRecord->mIpv6Hint.Value().mAddress.Construct(); + for (const auto& address : ipv6Hint) { + nsString* nextAddress = nextRecord->mIpv6Hint.Value() + .mAddress.Value() + .AppendElement(fallible); + if (!nextAddress) { + return NS_ERROR_OUT_OF_MEMORY; + } + + nsCString addressASCII; + Unused << address->GetAddress(addressASCII); + CopyASCIItoUTF16(addressASCII, *nextAddress); + } + } + break; + } + case SvcParamKeyEchConfig: { + nextRecord->mEchConfig.Construct(); + nextRecord->mEchConfig.Value().mType = type; + nsCOMPtr<nsISVCParamEchConfig> echConfigParam = + do_QueryInterface(value); + nsCString echConfigStr; + Unused << echConfigParam->GetEchconfig(echConfigStr); + CopyASCIItoUTF16(echConfigStr, + nextRecord->mEchConfig.Value().mEchConfig); + break; + } + default: + break; + } + } + } + } else { + dict.mAnswer = false; + GetErrorString(mStatus, dict.mError); + } + + JS::RootedValue val(cx); + if (!ToJSValue(cx, dict, &val)) { + return NS_ERROR_FAILURE; + } + + this->mCallback->OnDashboardDataAvailable(val); + + return NS_OK; +} + NS_IMPL_ISUPPORTS(Dashboard, nsIDashboard, nsIDashboardEventNotifier) Dashboard::Dashboard() { mEnableLogging = false; } NS_IMETHODIMP Dashboard::RequestSockets(nsINetDashboardCallback* aCallback) { RefPtr<SocketData> socketData = new SocketData(); socketData->mCallback = new nsMainThreadPtrHolder<nsINetDashboardCallback>( @@ -771,16 +920,39 @@ Dashboard::RequestDNSLookup(const nsACSt OriginAttributes attrs; rv = mDnsService->AsyncResolveNative( aHost, nsIDNSService::RESOLVE_TYPE_DEFAULT, 0, nullptr, helper.get(), NS_GetCurrentThread(), attrs, getter_AddRefs(helper->mCancel)); return rv; } NS_IMETHODIMP +Dashboard::RequestDNSHTTPSRRLookup(const nsACString& aHost, + nsINetDashboardCallback* aCallback) { + nsresult rv; + + if (!mDnsService) { + mDnsService = do_GetService("@mozilla.org/network/dns-service;1", &rv); + if (NS_FAILED(rv)) { + return rv; + } + } + + RefPtr<LookupHelper> helper = new LookupHelper(); + helper->mCallback = new nsMainThreadPtrHolder<nsINetDashboardCallback>( + "nsINetDashboardCallback", aCallback, true); + helper->mEventTarget = GetCurrentEventTarget(); + OriginAttributes attrs; + rv = mDnsService->AsyncResolveNative( + aHost, nsIDNSService::RESOLVE_TYPE_HTTPSSVC, 0, nullptr, helper.get(), + NS_GetCurrentThread(), attrs, getter_AddRefs(helper->mCancel)); + return rv; +} + +NS_IMETHODIMP Dashboard::RequestRcwnStats(nsINetDashboardCallback* aCallback) { RefPtr<RcwnData> rcwnData = new RcwnData(); rcwnData->mEventTarget = GetCurrentEventTarget(); rcwnData->mCallback = new nsMainThreadPtrHolder<nsINetDashboardCallback>( "nsINetDashboardCallback", aCallback, true); return rcwnData->mEventTarget->Dispatch( NewRunnableMethod<RefPtr<RcwnData>>("net::Dashboard::GetRcwnData", this,
--- a/netwerk/base/nsIDashboard.idl +++ b/netwerk/base/nsIDashboard.idl @@ -45,15 +45,20 @@ interface nsIDashboard : nsISupports /* When true, the service will log websocket events */ attribute boolean enableLogging; /* DNS resolver for host name * aHost: host name */ void requestDNSLookup(in ACString aHost, in nsINetDashboardCallback cb); + /* Resolve HTTPS RRs for host name + * aHost: host name */ + void requestDNSHTTPSRRLookup(in ACString aHost, + in nsINetDashboardCallback cb); + /** * Asyncly returns stats regarding the "Race Cache With Network" feature. */ void requestRcwnStats(in nsINetDashboardCallback cb); AUTF8String getLogPath(); };
--- a/toolkit/content/aboutNetworking.html +++ b/toolkit/content/aboutNetworking.html @@ -143,16 +143,25 @@ <table> <thead> <tr> <th data-l10n-id="about-networking-dns-lookup-table-column"/> </tr> </thead> <tbody id="dnslookuptool_content" /> </table> + <hr/> + <table> + <thead> + <tr> + <th data-l10n-id="about-networking-dns-https-rr-lookup-table-column"/> + </tr> + </thead> + <tbody id="https_rr_content" /> + </table> </div> <div id="rcwn" class="tab" hidden="true"> <table> <thead> <tr> <th data-l10n-id="about-networking-rcwn-status"/> <th data-l10n-id="about-networking-total-network-requests"/>
--- a/toolkit/content/aboutNetworking.js +++ b/toolkit/content/aboutNetworking.js @@ -506,17 +506,22 @@ function setAutoRefreshInterval(checkBox // Mostly the issue is with the autorefresh checkbox. window.addEventListener("pageshow", function() { init(); }); function doLookup() { let host = document.getElementById("host").value; if (host) { - gDashboard.requestDNSLookup(host, displayDNSLookup); + try { + gDashboard.requestDNSLookup(host, displayDNSLookup); + } catch (e) {} + try { + gDashboard.requestDNSHTTPSRRLookup(host, displayHTTPSRRLookup); + } catch (e) {} } } function displayDNSLookup(data) { let cont = document.getElementById("dnslookuptool_content"); let parent = cont.parentNode; let new_cont = document.createElement("tbody"); new_cont.setAttribute("id", "dnslookuptool_content"); @@ -528,8 +533,57 @@ function displayDNSLookup(data) { new_cont.appendChild(row); } } else { new_cont.appendChild(col(data.error)); } parent.replaceChild(new_cont, cont); } + +function displayHTTPSRRLookup(data) { + let cont = document.getElementById("https_rr_content"); + let parent = cont.parentNode; + let new_cont = document.createElement("tbody"); + new_cont.setAttribute("id", "https_rr_content"); + + if (data.answer) { + for (let record of data.records) { + let row = document.createElement("tr"); + let alpn = record.alpn ? `alpn="${record.alpn.alpn}" ` : ""; + let noDefaultAlpn = record.noDefaultAlpn ? "noDefaultAlpn " : ""; + let port = record.port ? `port="${record.port.port}" ` : ""; + let echconfig = record.echconfig + ? `echconfig="${record.echconfig.echconfig}" ` + : ""; + let ipv4hint = ""; + let ipv6hint = ""; + if (record.ipv4Hint) { + let ipv4Str = ""; + for (let addr of record.ipv4Hint.address) { + ipv4Str += `${addr}, `; + } + // Remove ", " at the end. + ipv4Str = ipv4Str.slice(0, -2); + ipv4hint = `ipv4hint="${ipv4Str}" `; + } + if (record.ipv6Hint) { + let ipv6Str = ""; + for (let addr of record.ipv6Hint.address) { + ipv6Str += `${addr}, `; + } + // Remove ", " at the end. + ipv6Str = ipv6Str.slice(0, -2); + ipv6hint = `ipv6hint="${ipv6Str}" `; + } + + let str = `${record.priority} ${record.name} `; + str += `(${alpn}${noDefaultAlpn}${port}`; + str += `${ipv4hint}${echconfig}${ipv6hint})`; + row.appendChild(col(str)); + new_cont.appendChild(row); + } + } else { + new_cont.appendChild(col(data.error)); + } + + parent.replaceChild(new_cont, cont); +}
--- a/toolkit/locales/en-US/toolkit/about/aboutNetworking.ftl +++ b/toolkit/locales/en-US/toolkit/about/aboutNetworking.ftl @@ -40,16 +40,17 @@ about-networking-current-log-modules = C about-networking-set-log-file = Set Log File about-networking-set-log-modules = Set Log Modules about-networking-start-logging = Start Logging about-networking-stop-logging = Stop Logging about-networking-dns-lookup = DNS Lookup about-networking-dns-lookup-button = Resolve about-networking-dns-domain = Domain: about-networking-dns-lookup-table-column = IPs +about-networking-dns-https-rr-lookup-table-column = HTTP RRs about-networking-rcwn = RCWN Stats about-networking-rcwn-status = RCWN Status about-networking-rcwn-cache-won-count = Cache won count about-networking-rcwn-net-won-count = Net won count about-networking-total-network-requests = Total network request count about-networking-rcwn-operation = Cache Operation about-networking-rcwn-perf-open = Open about-networking-rcwn-perf-read = Read