Bug 1739001 - Pre-fetch connection info for TRRServiceChannel, r=necko-reviewers,valentin,nhnt11

Differential Revision: https://phabricator.services.mozilla.com/D130814
This commit is contained in:
Kershaw Chang 2021-11-29 15:19:15 +00:00
Родитель 323ecd6f31
Коммит 478d192351
24 изменённых файлов: 497 добавлений и 33 удалений

Просмотреть файл

@ -10029,6 +10029,12 @@
value: false
mirror: always
# Whether to use the connection info that is generated asynchronously.
- name: network.trr.async_connInfo
type: RelaxedAtomicBool
value: false
mirror: always
# Allow the network changed event to get sent when a network topology or setup
# change is noticed while running.
- name: network.notify.changed

Просмотреть файл

@ -15,6 +15,18 @@ interface nsIChannel;
interface nsIURI;
interface nsISerialEventTarget;
[scriptable, uuid(77984234-aad5-47fc-a412-03398c2134a5)]
interface nsIProxyConfigChangedCallback : nsISupports
{
/**
* Called when one of the following conditions are changed.
* 1. System proxy settings changed.
* 2. A proxy filter is registered or unregistered.
* 3. Proxy related prefs changed.
*/
void onProxyConfigChanged();
};
/**
* nsIProtocolProxyService provides methods to access information about
* various network proxies.
@ -274,6 +286,28 @@ interface nsIProtocolProxyService : nsISupports
*/
void unregisterChannelFilter(in nsIProtocolProxyChannelFilter aFilter);
/**
* This method is used to register a nsIProxyConfigChangedCallback.
*
* @param aCallback
* The aCallback instance to be registered.
*/
void addProxyConfigCallback(in nsIProxyConfigChangedCallback aCallback);
/**
* This method is used to unregister a nsIProxyConfigChangedCallback.
*
* @param aCallback
* The aCallback instance to be unregistered.
*/
void removeProxyConfigCallback(in nsIProxyConfigChangedCallback aCallback);
/**
* This method is used internal only. Called when proxy config is changed.
*/
void notifyProxyConfigChangedInternal();
/**
* These values correspond to the possible integer values for the
* network.proxy.type preference.

Просмотреть файл

@ -896,6 +896,13 @@ nsPACMan::OnStreamComplete(nsIStreamLoader* loader, nsISupports* context,
}
}
nsCOMPtr<nsIProtocolProxyService> pps =
do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID);
MOZ_ASSERT(pps);
if (pps) {
pps->NotifyProxyConfigChangedInternal();
}
// We succeeded in loading the pac file using a bunch of interfaces that are
// main thread only. Unfortunately, we have to initialize the instance of
// the PAC evaluator (NS_PROXYAUTOCONFIG_CONTRACTID) on the PAC thread,

Просмотреть файл

@ -17,7 +17,7 @@
#include "nsIProtocolProxyCallback.h"
#include "nsIChannel.h"
#include "nsICancelable.h"
#include "nsIDNSService.h"
#include "nsDNSService2.h"
#include "nsPIDNSService.h"
#include "nsIPrefBranch.h"
#include "nsIPrefService.h"
@ -40,10 +40,10 @@
#include "nsIHttpChannelInternal.h"
#include "mozilla/dom/nsMixedContentBlocker.h"
#include "mozilla/Logging.h"
#include "mozilla/ScopeExit.h"
#include "mozilla/StaticPrefs_network.h"
#include "mozilla/Tokenizer.h"
#include "mozilla/Unused.h"
#include "mozilla/StaticPrefs_network.h"
//----------------------------------------------------------------------------
@ -957,6 +957,8 @@ void nsProtocolProxyService::PrefsChanged(nsIPrefBranch* prefBranch,
nsresult rv = NS_OK;
bool reloadPAC = false;
nsAutoCString tempString;
auto invokeCallback =
MakeScopeExit([&] { NotifyProxyConfigChangedInternal(); });
if (!pref || !strcmp(pref, PROXY_PREF("type"))) {
int32_t type = -1;
@ -1749,6 +1751,9 @@ nsresult nsProtocolProxyService::InsertFilterLink(RefPtr<FilterLink>&& link) {
mFilters.AppendElement(link);
mFilters.Sort(ProxyFilterPositionComparator());
NotifyProxyConfigChangedInternal();
return NS_OK;
}
@ -1774,9 +1779,15 @@ nsProtocolProxyService::RegisterChannelFilter(
nsresult nsProtocolProxyService::RemoveFilterLink(nsISupports* givenObject) {
LOG(("nsProtocolProxyService::RemoveFilterLink target=%p", givenObject));
return mFilters.RemoveElement(givenObject, ProxyFilterObjectComparator())
? NS_OK
: NS_ERROR_UNEXPECTED;
nsresult rv =
mFilters.RemoveElement(givenObject, ProxyFilterObjectComparator())
? NS_OK
: NS_ERROR_UNEXPECTED;
if (NS_SUCCEEDED(rv)) {
NotifyProxyConfigChangedInternal();
}
return rv;
}
NS_IMETHODIMP
@ -2257,7 +2268,9 @@ void nsProtocolProxyService::MaybeDisableDNSPrefetch(nsIProxyInfo* aProxy) {
nsCOMPtr<nsProxyInfo> pi = do_QueryInterface(aProxy);
if (!pi || !pi->mType || pi->mType == kProxyType_DIRECT) return;
nsCOMPtr<nsIDNSService> dns = do_GetService(NS_DNSSERVICE_CONTRACTID);
// To avoid getting DNS service recursively, we directly use
// GetXPCOMSingleton().
nsCOMPtr<nsIDNSService> dns = nsDNSService::GetXPCOMSingleton();
if (!dns) return;
nsCOMPtr<nsPIDNSService> pdns = do_QueryInterface(dns);
if (!pdns) return;
@ -2411,5 +2424,37 @@ bool nsProtocolProxyService::GetIsPACLoading() {
return mPACMan && mPACMan->IsLoading();
}
NS_IMETHODIMP
nsProtocolProxyService::AddProxyConfigCallback(
nsIProxyConfigChangedCallback* aCallback) {
MOZ_ASSERT(NS_IsMainThread());
if (!aCallback) {
return NS_ERROR_INVALID_ARG;
}
mProxyConfigChangedCallbacks.AppendElement(aCallback);
return NS_OK;
}
NS_IMETHODIMP
nsProtocolProxyService::RemoveProxyConfigCallback(
nsIProxyConfigChangedCallback* aCallback) {
MOZ_ASSERT(NS_IsMainThread());
mProxyConfigChangedCallbacks.RemoveElement(aCallback);
return NS_OK;
}
NS_IMETHODIMP
nsProtocolProxyService::NotifyProxyConfigChangedInternal() {
LOG(("nsProtocolProxyService::NotifyProxyConfigChangedInternal"));
MOZ_ASSERT(NS_IsMainThread());
for (const auto& callback : mProxyConfigChangedCallbacks) {
callback->OnProxyConfigChanged();
}
return NS_OK;
}
} // namespace net
} // namespace mozilla

Просмотреть файл

@ -374,6 +374,9 @@ class nsProtocolProxyService final : public nsIProtocolProxyService2,
// Filters, always sorted by the position.
nsTArray<RefPtr<FilterLink>> mFilters;
nsTArray<nsCOMPtr<nsIProxyConfigChangedCallback>>
mProxyConfigChangedCallbacks;
uint32_t mProxyConfig{PROXYCONFIG_DIRECT};
nsCString mHTTPProxyHost;

Просмотреть файл

@ -132,6 +132,9 @@ nsresult ChildDNSService::AsyncResolveInternal(
RefPtr<DNSRequestActor> dnsReq;
if (resolveDNSInSocketProcess) {
dnsReq = new DNSRequestParent(sender);
if (!mTRRServiceParent->TRRConnectionInfoInited()) {
mTRRServiceParent->InitTRRConnectionInfo();
}
} else {
dnsReq = new DNSRequestChild(sender);
}
@ -303,7 +306,7 @@ ChildDNSService::GetCurrentTrrURI(nsACString& aURI) {
return NS_ERROR_NOT_AVAILABLE;
}
mTRRServiceParent->GetTrrURI(aURI);
mTRRServiceParent->GetURI(aURI);
return NS_OK;
}

Просмотреть файл

@ -6,6 +6,7 @@
include protocol PSocketProcess;
include NeckoChannelParams;
include PSMIPCTypes;
namespace mozilla {
@ -17,6 +18,7 @@ namespace net {
parent:
async NotifyNetworkConnectivityServiceObservers(nsCString aTopic);
async InitTRRConnectionInfo();
child:
async __delete__();
@ -24,6 +26,7 @@ child:
async UpdateParentalControlEnabled(bool aEnabled);
async ClearDNSCache(bool aTrrToo);
async SetDetectedTrrURI(nsCString aURI);
async SetDefaultTRRConnectionInfo(HttpConnectionInfoCloneArgs? aConnInfoArgs);
};
} //namespace net

Просмотреть файл

@ -306,6 +306,24 @@ nsresult TRR::SendHTTPRequest() {
rv = internalChannel->SetIsTRRServiceChannel(true);
NS_ENSURE_SUCCESS(rv, rv);
if (UseDefaultServer() && StaticPrefs::network_trr_async_connInfo()) {
RefPtr<nsHttpConnectionInfo> trrConnInfo =
TRRService::Get()->TRRConnectionInfo();
if (trrConnInfo) {
nsAutoCString host;
dnsURI->GetHost(host);
if (host.Equals(trrConnInfo->GetOrigin())) {
internalChannel->SetConnectionInfo(trrConnInfo);
LOG(("TRR::SendHTTPRequest use conn info:%s\n",
trrConnInfo->HashKey().get()));
} else {
MOZ_DIAGNOSTIC_ASSERT(false);
}
} else {
TRRService::Get()->InitTRRConnectionInfo();
}
}
if (useGet) {
rv = httpChannel->SetRequestMethod("GET"_ns);
NS_ENSURE_SUCCESS(rv, rv);

Просмотреть файл

@ -7,6 +7,7 @@
#include "nsCharSeparatedTokenizer.h"
#include "nsComponentManagerUtils.h"
#include "nsDirectoryServiceUtils.h"
#include "nsHttpConnectionInfo.h"
#include "nsICaptivePortalService.h"
#include "nsIFile.h"
#include "nsIParentalControlsService.h"
@ -24,6 +25,7 @@
#include "mozilla/TelemetryComms.h"
#include "mozilla/Tokenizer.h"
#include "mozilla/net/rust_helper.h"
#include "mozilla/net/TRRServiceChild.h"
// Put DNSLogging.h at the end to avoid LOG being overwritten by other headers.
#include "DNSLogging.h"
@ -60,7 +62,8 @@ constexpr nsLiteralCString kTRRDomains[] = {
// static
const nsCString& TRRService::ProviderKey() { return kTRRDomains[sDomainIndex]; }
NS_IMPL_ISUPPORTS(TRRService, nsIObserver, nsISupportsWeakReference)
NS_IMPL_ISUPPORTS_INHERITED(TRRService, TRRServiceBase, nsIObserver,
nsISupportsWeakReference)
NS_IMPL_ADDREF_USING_AGGREGATOR(TRRService::ConfirmationContext, OwningObject())
NS_IMPL_RELEASE_USING_AGGREGATOR(TRRService::ConfirmationContext,
@ -336,6 +339,8 @@ bool TRRService::MaybeSetPrivateURI(const nsACString& aURI) {
mPrivateURI = newURI;
AsyncCreateTRRConnectionInfo(mPrivateURI);
// The URI has changed. We should trigger a new confirmation immediately.
// We must do this here because the URI could also change because of
// steering.
@ -507,10 +512,9 @@ void TRRService::ReadEtcHostsFile() {
NS_DISPATCH_EVENT_MAY_BLOCK);
}
nsresult TRRService::GetURI(nsACString& result) {
void TRRService::GetURI(nsACString& result) {
MutexAutoLock lock(mLock);
result = mPrivateURI;
return NS_OK;
}
nsresult TRRService::GetCredentials(nsCString& result) {
@ -1307,5 +1311,31 @@ AHostResolver::LookupStatus TRRService::CompleteLookupByType(
return LOOKUP_OK;
}
NS_IMETHODIMP TRRService::OnProxyConfigChanged() {
LOG(("TRRService::OnProxyConfigChanged"));
nsAutoCString uri;
GetURI(uri);
AsyncCreateTRRConnectionInfo(uri);
return NS_OK;
}
void TRRService::InitTRRConnectionInfo() {
if (XRE_IsParentProcess()) {
TRRServiceBase::InitTRRConnectionInfo();
return;
}
MOZ_ASSERT(XRE_IsSocketProcess());
MOZ_ASSERT(NS_IsMainThread());
TRRServiceChild* child = TRRServiceChild::GetSingleton();
if (child && child->CanSend()) {
LOG(("TRRService::SendInitTRRConnectionInfo"));
Unused << child->SendInitTRRConnectionInfo();
}
}
} // namespace net
} // namespace mozilla

Просмотреть файл

@ -33,8 +33,9 @@ class TRRService : public TRRServiceBase,
public nsSupportsWeakReference,
public AHostResolver {
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIOBSERVER
NS_DECL_NSIPROXYCONFIGCHANGEDCALLBACK
TRRService();
static TRRService* Get();
@ -46,7 +47,7 @@ class TRRService : public TRRServiceBase,
uint32_t ConfirmationState() { return mConfirmation.State(); }
bool DisableIPv6() { return mDisableIPv6; }
nsresult GetURI(nsACString& result);
void GetURI(nsACString& result) override;
nsresult GetCredentials(nsCString& result);
uint32_t GetRequestTimeout();
@ -78,6 +79,8 @@ class TRRService : public TRRServiceBase,
// If the DoH server is not one of the built-in ones it will return "(other)"
static const nsCString& ProviderKey();
void InitTRRConnectionInfo() override;
private:
virtual ~TRRService();

Просмотреть файл

@ -7,19 +7,33 @@
#include "TRRServiceBase.h"
#include "mozilla/Preferences.h"
#include "mozilla/ScopeExit.h"
#include "nsHostResolver.h"
#include "nsNetUtil.h"
#include "nsIOService.h"
#include "nsIDNSService.h"
#include "nsIProxyInfo.h"
#include "nsHttpConnectionInfo.h"
#include "nsHttpHandler.h"
#include "mozilla/StaticPrefs_network.h"
#include "AlternateServices.h"
#include "ProxyConfigLookup.h"
// Put DNSLogging.h at the end to avoid LOG being overwritten by other headers.
#include "DNSLogging.h"
#include "mozilla/StaticPrefs_network.h"
namespace mozilla {
namespace net {
NS_IMPL_ISUPPORTS(TRRServiceBase, nsIProxyConfigChangedCallback)
TRRServiceBase::TRRServiceBase()
: mMode(nsIDNSService::MODE_NATIVEONLY), mURISetByDetection(false) {}
: mDefaultTRRConnectionInfo("DataMutex::mDefaultTRRConnectionInfo") {}
TRRServiceBase::~TRRServiceBase() {
if (mTRRConnectionInfoInited) {
UnregisterProxyChangeListener();
}
}
void TRRServiceBase::ProcessURITemplate(nsACString& aURI) {
// URI Template, RFC 6570.
@ -149,5 +163,181 @@ void TRRServiceBase::OnTRRURIChange() {
CheckURIPrefs();
}
static already_AddRefed<nsHttpConnectionInfo> CreateConnInfoHelper(
nsIURI* aURI, nsIProxyInfo* aProxyInfo) {
MOZ_ASSERT(NS_IsMainThread());
nsAutoCString host;
nsAutoCString scheme;
nsAutoCString username;
int32_t port = -1;
bool isHttps = aURI->SchemeIs("https");
nsresult rv = aURI->GetScheme(scheme);
if (NS_FAILED(rv)) {
return nullptr;
}
rv = aURI->GetAsciiHost(host);
if (NS_FAILED(rv)) {
return nullptr;
}
rv = aURI->GetPort(&port);
if (NS_FAILED(rv)) {
return nullptr;
}
// Just a warning here because some nsIURIs do not implement this method.
if (NS_WARN_IF(NS_FAILED(aURI->GetUsername(username)))) {
LOG(("Failed to get username for aURI(%s)",
aURI->GetSpecOrDefault().get()));
}
gHttpHandler->MaybeAddAltSvcForTesting(aURI, username, false, nullptr,
OriginAttributes());
nsCOMPtr<nsProxyInfo> proxyInfo = do_QueryInterface(aProxyInfo);
RefPtr<nsHttpConnectionInfo> connInfo = new nsHttpConnectionInfo(
host, port, ""_ns, username, proxyInfo, OriginAttributes(), isHttps);
bool http2Allowed = !gHttpHandler->IsHttp2Excluded(connInfo);
bool http3Allowed = proxyInfo ? proxyInfo->IsDirect() : true;
RefPtr<AltSvcMapping> mapping;
if ((http2Allowed || http3Allowed) &&
AltSvcMapping::AcceptableProxy(proxyInfo) &&
(scheme.EqualsLiteral("http") || scheme.EqualsLiteral("https")) &&
(mapping = gHttpHandler->GetAltServiceMapping(
scheme, host, port, false, OriginAttributes(), http2Allowed,
http3Allowed))) {
mapping->GetConnectionInfo(getter_AddRefs(connInfo), proxyInfo,
OriginAttributes());
}
return connInfo.forget();
}
void TRRServiceBase::InitTRRConnectionInfo() {
if (!XRE_IsParentProcess()) {
return;
}
if (mTRRConnectionInfoInited) {
return;
}
if (!NS_IsMainThread()) {
NS_DispatchToMainThread(NS_NewRunnableFunction(
"TRRServiceBase::InitTRRConnectionInfo",
[self = RefPtr{this}]() { self->InitTRRConnectionInfo(); }));
return;
}
LOG(("TRRServiceBase::InitTRRConnectionInfo"));
nsAutoCString uri;
GetURI(uri);
AsyncCreateTRRConnectionInfoInternal(uri);
}
void TRRServiceBase::AsyncCreateTRRConnectionInfo(const nsACString& aURI) {
LOG(
("TRRServiceBase::AsyncCreateTRRConnectionInfo "
"mTRRConnectionInfoInited=%d",
bool(mTRRConnectionInfoInited)));
if (!mTRRConnectionInfoInited) {
return;
}
AsyncCreateTRRConnectionInfoInternal(aURI);
}
void TRRServiceBase::AsyncCreateTRRConnectionInfoInternal(
const nsACString& aURI) {
if (!XRE_IsParentProcess()) {
return;
}
SetDefaultTRRConnectionInfo(nullptr);
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIURI> dnsURI;
nsresult rv = NS_NewURI(getter_AddRefs(dnsURI), aURI);
if (NS_FAILED(rv)) {
return;
}
rv = ProxyConfigLookup::Create(
[self = RefPtr{this}, uri(dnsURI)](nsIProxyInfo* aProxyInfo,
nsresult aStatus) mutable {
if (NS_FAILED(aStatus)) {
self->SetDefaultTRRConnectionInfo(nullptr);
return;
}
RefPtr<nsHttpConnectionInfo> connInfo =
CreateConnInfoHelper(uri, aProxyInfo);
self->SetDefaultTRRConnectionInfo(connInfo);
if (!self->mTRRConnectionInfoInited) {
self->mTRRConnectionInfoInited = true;
self->RegisterProxyChangeListener();
}
},
dnsURI, 0, nullptr);
// mDefaultTRRConnectionInfo is set to nullptr at the beginning of this
// method, so we don't really care aobut the |rv| here. If it's failed,
// mDefaultTRRConnectionInfo stays as nullptr and we'll create a new
// connection info in TRRServiceChannel again.
Unused << NS_WARN_IF(NS_FAILED(rv));
}
already_AddRefed<nsHttpConnectionInfo> TRRServiceBase::TRRConnectionInfo() {
RefPtr<nsHttpConnectionInfo> connInfo;
{
auto lock = mDefaultTRRConnectionInfo.Lock();
connInfo = *lock;
}
return connInfo.forget();
}
void TRRServiceBase::SetDefaultTRRConnectionInfo(
nsHttpConnectionInfo* aConnInfo) {
LOG(("TRRService::SetDefaultTRRConnectionInfo aConnInfo=%s",
aConnInfo ? aConnInfo->HashKey().get() : "none"));
{
auto lock = mDefaultTRRConnectionInfo.Lock();
lock.ref() = aConnInfo;
}
}
void TRRServiceBase::RegisterProxyChangeListener() {
if (!XRE_IsParentProcess()) {
return;
}
nsCOMPtr<nsIProtocolProxyService> pps =
do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID);
if (!pps) {
return;
}
pps->AddProxyConfigCallback(this);
}
void TRRServiceBase::UnregisterProxyChangeListener() {
if (!XRE_IsParentProcess()) {
return;
}
nsCOMPtr<nsIProtocolProxyService> pps =
do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID);
if (!pps) {
return;
}
pps->RemoveProxyConfigCallback(this);
}
} // namespace net
} // namespace mozilla

Просмотреть файл

@ -7,22 +7,38 @@
#define TRRServiceBase_h_
#include "mozilla/Atomics.h"
#include "mozilla/DataMutex.h"
#include "nsString.h"
#include "nsIDNSService.h"
#include "nsIProtocolProxyService2.h"
class nsICancelable;
class nsIProxyInfo;
namespace mozilla {
namespace net {
class nsHttpConnectionInfo;
static const char kRolloutURIPref[] = "doh-rollout.uri";
static const char kRolloutModePref[] = "doh-rollout.mode";
class TRRServiceBase {
class TRRServiceBase : public nsIProxyConfigChangedCallback {
public:
NS_DECL_THREADSAFE_ISUPPORTS
TRRServiceBase();
nsIDNSService::ResolverMode Mode() { return mMode; }
virtual void GetURI(nsACString& result) = 0;
already_AddRefed<nsHttpConnectionInfo> TRRConnectionInfo();
// Called to initialize the connection info. Once the connection info is
// created first time, mTRRConnectionInfoInited will be set to true.
virtual void InitTRRConnectionInfo();
bool TRRConnectionInfoInited() const { return mTRRConnectionInfoInited; }
protected:
~TRRServiceBase() = default;
virtual ~TRRServiceBase();
virtual bool MaybeSetPrivateURI(const nsACString& aURI) = 0;
void ProcessURITemplate(nsACString& aURI);
// Checks the network.trr.uri or the doh-rollout.uri prefs and sets the URI
@ -38,6 +54,19 @@ class TRRServiceBase {
void OnTRRURIChange();
virtual void ReadEtcHostsFile() {}
// Called to create a connection info that will be used by TRRServiceChannel.
// Note that when this function is called, mDefaultTRRConnectionInfo will be
// set to null to invalidate the connection info.
// When the connection info is created, SetDefaultTRRConnectionInfo() is
// called to set the result to mDefaultTRRConnectionInfo.
// Note that this method does nothing when mTRRConnectionInfoInited is false.
// We want to starting updating the connection info after it's create first
// time.
void AsyncCreateTRRConnectionInfo(const nsACString& aURI);
void AsyncCreateTRRConnectionInfoInternal(const nsACString& aURI);
virtual void SetDefaultTRRConnectionInfo(nsHttpConnectionInfo* aConnInfo);
void RegisterProxyChangeListener();
void UnregisterProxyChangeListener();
nsCString mPrivateURI;
// Pref caches should only be used on the main thread.
@ -45,8 +74,11 @@ class TRRServiceBase {
nsCString mRolloutURIPref;
nsCString mDefaultURIPref;
Atomic<nsIDNSService::ResolverMode, Relaxed> mMode;
Atomic<bool, Relaxed> mURISetByDetection;
Atomic<nsIDNSService::ResolverMode, Relaxed> mMode{
nsIDNSService::MODE_NATIVEONLY};
Atomic<bool, Relaxed> mURISetByDetection{false};
Atomic<bool, Relaxed> mTRRConnectionInfoInited{false};
DataMutex<RefPtr<nsHttpConnectionInfo>> mDefaultTRRConnectionInfo;
};
} // namespace net

Просмотреть файл

@ -5,9 +5,11 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/net/TRRServiceChild.h"
#include "mozilla/Atomics.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/Services.h"
#include "mozilla/StaticPtr.h"
#include "nsHttpConnectionInfo.h"
#include "nsIDNService.h"
#include "nsIObserverService.h"
#include "nsServiceManagerUtils.h"
@ -17,9 +19,26 @@ namespace mozilla {
namespace net {
static StaticRefPtr<nsIDNSService> sDNSService;
static Atomic<TRRServiceChild*> sTRRServiceChild;
NS_IMPL_ISUPPORTS(TRRServiceChild, nsIObserver, nsISupportsWeakReference)
TRRServiceChild::TRRServiceChild() {
MOZ_ASSERT(NS_IsMainThread());
sTRRServiceChild = this;
}
TRRServiceChild::~TRRServiceChild() {
MOZ_ASSERT(NS_IsMainThread());
sTRRServiceChild = nullptr;
}
/* static */
TRRServiceChild* TRRServiceChild::GetSingleton() {
MOZ_ASSERT(NS_IsMainThread());
return sTRRServiceChild;
}
void TRRServiceChild::Init(const bool& aCaptiveIsPassed,
const bool& aParentalControlEnabled,
nsTArray<nsCString>&& aDNSSuffixList) {
@ -79,5 +98,18 @@ mozilla::ipc::IPCResult TRRServiceChild::RecvSetDetectedTrrURI(
return IPC_OK();
}
mozilla::ipc::IPCResult TRRServiceChild::RecvSetDefaultTRRConnectionInfo(
Maybe<HttpConnectionInfoCloneArgs>&& aArgs) {
if (!aArgs) {
TRRService::Get()->SetDefaultTRRConnectionInfo(nullptr);
return IPC_OK();
}
RefPtr<nsHttpConnectionInfo> cinfo =
nsHttpConnectionInfo::DeserializeHttpConnectionInfoCloneArgs(aArgs.ref());
TRRService::Get()->SetDefaultTRRConnectionInfo(cinfo);
return IPC_OK();
}
} // namespace net
} // namespace mozilla

Просмотреть файл

@ -26,7 +26,8 @@ class TRRServiceChild : public PTRRServiceChild,
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
explicit TRRServiceChild() = default;
TRRServiceChild();
static TRRServiceChild* GetSingleton();
void Init(const bool& aCaptiveIsPassed, const bool& aParentalControlEnabled,
nsTArray<nsCString>&& aDNSSuffixList);
@ -38,9 +39,11 @@ class TRRServiceChild : public PTRRServiceChild,
const bool& aEnabled);
mozilla::ipc::IPCResult RecvClearDNSCache(const bool& aTrrToo);
mozilla::ipc::IPCResult RecvSetDetectedTrrURI(const nsCString& aURI);
mozilla::ipc::IPCResult RecvSetDefaultTRRConnectionInfo(
Maybe<HttpConnectionInfoCloneArgs>&& aArgs);
private:
virtual ~TRRServiceChild() = default;
virtual ~TRRServiceChild();
};
} // namespace net

Просмотреть файл

@ -11,6 +11,7 @@
#include "mozilla/psm/PSMIPCTypes.h"
#include "mozilla/Preferences.h"
#include "mozilla/Unused.h"
#include "nsHttpConnectionInfo.h"
#include "nsICaptivePortalService.h"
#include "nsIParentalControlsService.h"
#include "nsINetworkLinkService.h"
@ -19,6 +20,8 @@
#include "nsNetCID.h"
#include "TRRService.h"
#include "DNSLogging.h"
namespace mozilla {
namespace net {
@ -28,7 +31,10 @@ static const char* gTRRUriCallbackPrefs[] = {
kRolloutModePref, nullptr,
};
NS_IMPL_ISUPPORTS(TRRServiceParent, nsIObserver, nsISupportsWeakReference)
NS_IMPL_ISUPPORTS_INHERITED(TRRServiceParent, TRRServiceBase, nsIObserver,
nsISupportsWeakReference)
TRRServiceParent::~TRRServiceParent() = default;
void TRRServiceParent::Init() {
MOZ_ASSERT(gIOService);
@ -107,6 +113,7 @@ bool TRRServiceParent::MaybeSetPrivateURI(const nsACString& aURI) {
}
mPrivateURI = newURI;
AsyncCreateTRRConnectionInfo(mPrivateURI);
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (obs) {
@ -127,7 +134,12 @@ void TRRServiceParent::SetDetectedTrrURI(const nsACString& aURI) {
});
}
void TRRServiceParent::GetTrrURI(nsACString& aURI) { aURI = mPrivateURI; }
void TRRServiceParent::GetURI(nsACString& aURI) {
// We don't need a lock here, since mPrivateURI is only touched on main
// thread.
MOZ_ASSERT(NS_IsMainThread());
aURI = mPrivateURI;
}
void TRRServiceParent::UpdateParentalControlEnabled() {
bool enabled = TRRService::GetParentalControlEnabledInternal();
@ -160,5 +172,35 @@ void TRRServiceParent::ActorDestroy(ActorDestroyReason why) {
gTRRUriCallbackPrefs, this);
}
NS_IMETHODIMP TRRServiceParent::OnProxyConfigChanged() {
LOG(("TRRServiceParent::OnProxyConfigChanged"));
AsyncCreateTRRConnectionInfo(mPrivateURI);
return NS_OK;
}
void TRRServiceParent::SetDefaultTRRConnectionInfo(
nsHttpConnectionInfo* aConnInfo) {
TRRServiceBase::SetDefaultTRRConnectionInfo(aConnInfo);
if (!CanSend()) {
return;
}
if (!aConnInfo) {
Unused << SendSetDefaultTRRConnectionInfo(Nothing());
return;
}
HttpConnectionInfoCloneArgs infoArgs;
nsHttpConnectionInfo::SerializeHttpConnectionInfo(aConnInfo, infoArgs);
Unused << SendSetDefaultTRRConnectionInfo(Some(infoArgs));
}
mozilla::ipc::IPCResult TRRServiceParent::RecvInitTRRConnectionInfo() {
InitTRRConnectionInfo();
return IPC_OK();
}
} // namespace net
} // namespace mozilla

Просмотреть файл

@ -20,8 +20,9 @@ class TRRServiceParent : public TRRServiceBase,
public nsSupportsWeakReference,
public PTRRServiceParent {
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIOBSERVER
NS_DECL_NSIPROXYCONFIGCHANGEDCALLBACK
TRRServiceParent() = default;
void Init();
@ -29,14 +30,16 @@ class TRRServiceParent : public TRRServiceBase,
static void PrefsChanged(const char* aName, void* aSelf);
void SetDetectedTrrURI(const nsACString& aURI);
bool MaybeSetPrivateURI(const nsACString& aURI) override;
void GetTrrURI(nsACString& aURI);
void GetURI(nsACString& result) override;
mozilla::ipc::IPCResult RecvNotifyNetworkConnectivityServiceObservers(
const nsCString& aTopic);
mozilla::ipc::IPCResult RecvInitTRRConnectionInfo();
private:
virtual ~TRRServiceParent() = default;
virtual ~TRRServiceParent();
virtual void ActorDestroy(ActorDestroyReason why) override;
void prefsChanged(const char* aName);
void SetDefaultTRRConnectionInfo(nsHttpConnectionInfo* aConnInfo) override;
};
} // namespace net

Просмотреть файл

@ -105,6 +105,7 @@ GeneratedFile(
# need to include etld_data.inc
LOCAL_INCLUDES += [
"/netwerk/base",
"/netwerk/ipc",
"/netwerk/protocol/http",
]

Просмотреть файл

@ -1368,7 +1368,7 @@ nsDNSService::SetDetectedTrrURI(const nsACString& aURI) {
NS_IMETHODIMP
nsDNSService::GetCurrentTrrURI(nsACString& aURI) {
if (mTrrService) {
return mTrrService->GetURI(aURI);
mTrrService->GetURI(aURI);
}
return NS_OK;
}

Просмотреть файл

@ -5621,5 +5621,9 @@ void HttpBaseChannel::SetDummyChannelForImageCache() {
mResponseHead = MakeUnique<nsHttpResponseHead>();
}
void HttpBaseChannel::SetConnectionInfo(nsHttpConnectionInfo* aCI) {
mConnectionInfo = aCI ? aCI->Clone() : nullptr;
}
} // namespace net
} // namespace mozilla

Просмотреть файл

@ -340,6 +340,9 @@ class HttpBaseChannel : public nsHashPropertyBag,
NS_IMETHOD SetWaitForHTTPSSVCRecord() override;
virtual void SetConnectionInfo(
mozilla::net::nsHttpConnectionInfo* aCI) override;
// nsISupportsPriority
NS_IMETHOD GetPriority(int32_t* value) override;
NS_IMETHOD AdjustPriority(int32_t delta) override;

Просмотреть файл

@ -220,7 +220,9 @@ nsresult TRRServiceChannel::MaybeResolveProxyAndBeginConnect() {
// at this point. The only time we know mProxyInfo already is if we're
// proxying a non-http protocol like ftp. We don't need to discover proxy
// settings if we are never going to make a network connection.
if (!mProxyInfo &&
// If mConnectionInfo is already supplied, we don't need to do proxy
// resolution again.
if (!mProxyInfo && !mConnectionInfo &&
!(mLoadFlags & (nsICachingChannel::LOAD_ONLY_FROM_CACHE |
nsICachingChannel::LOAD_NO_NETWORK_IO)) &&
NS_SUCCEEDED(ResolveProxy())) {
@ -409,7 +411,6 @@ nsresult TRRServiceChannel::BeginConnect() {
Telemetry::Accumulate(Telemetry::HTTP_TRANSACTION_USE_ALTSVC_OE, !isHttps);
} else if (mConnectionInfo) {
LOG(("TRRServiceChannel %p Using channel supplied connection info", this));
Telemetry::Accumulate(Telemetry::HTTP_TRANSACTION_USE_ALTSVC, false);
} else {
LOG(("TRRServiceChannel %p Using default connection info", this));

Просмотреть файл

@ -8650,10 +8650,6 @@ void nsHttpChannel::SetCouldBeSynthesized() {
StoreResponseCouldBeSynthesized(true);
}
void nsHttpChannel::SetConnectionInfo(nsHttpConnectionInfo* aCI) {
mConnectionInfo = aCI ? aCI->Clone() : nullptr;
}
NS_IMETHODIMP
nsHttpChannel::OnPreflightSucceeded() {
MOZ_ASSERT(LoadRequireCORSPreflight(), "Why did a preflight happen?");

Просмотреть файл

@ -259,7 +259,6 @@ class nsHttpChannel final : public HttpBaseChannel,
RefPtr<TransactionObserver> mTransactionObserver;
public:
void SetConnectionInfo(nsHttpConnectionInfo*); // clones the argument
void SetTransactionObserver(TransactionObserver* arg) {
mTransactionObserver = arg;
}

Просмотреть файл

@ -13,6 +13,7 @@ template<class T> class nsCOMArray;
namespace mozilla {
class TimeStamp;
namespace net {
class nsHttpConnectionInfo;
class WebSocketConnectionBase;
}
}
@ -461,4 +462,9 @@ interface nsIHttpChannelInternal : nsISupports
* Set Early Hint Observer.
*/
[must_use] void setEarlyHintObserver(in nsIEarlyHintObserver aObserver);
%{ C++
virtual void SetConnectionInfo(mozilla::net::nsHttpConnectionInfo* aInfo) {}
%}
};