From 34dc7af64a0b9b8be965259f6b607587087ce3ff Mon Sep 17 00:00:00 2001
From: Dragana Damjanovic
Date: Wed, 12 May 2021 12:59:58 +0000
Subject: [PATCH] Bug 1705065 - ConnectionEntry should hold reference to
DnsAndConnectSocket-s r=necko-reviewers,valentin
- Remove reference to ConnecionEntry from DnsAndConnectSocket. If ConnecionEntry is needed it is obtain from nsHttpConnectionMgr. It is only needed when a final connection is being set up.
- Put all functions that add and remove a DnsAndConnectSocket from the list in ConnecionEntry into one place (InsertIntoDnsAndConnectSockets, RemoveDnsAndConnectSocket, CloseAllDnsAndConnectSockets). Only these connection should remove/add DnsAndConnectSocket to ensure proper counting.
- Access DnsAndConnectSocket mostly from ConnecionEntry (e.g. refactor TryClaimingDnsAndConnectSocket).
- Remove some dead code (e.g. IsInDnsAndConnectSockets)
- Move some function into ConnecionEntry for a better code factoring (CreateDnsAndConnectSocket, MaybeProcessCoalescingKeys)
- Remove code that sets DNS flags in TransportSetup::SetupStreams because nsISocketTransport is not responsible for DNS lookups any more.
Differential Revision: https://phabricator.services.mozilla.com/D113119
---
netwerk/protocol/http/ConnectionEntry.cpp | 166 ++++++----
netwerk/protocol/http/ConnectionEntry.h | 11 +-
netwerk/protocol/http/DnsAndConnectSocket.cpp | 297 ++++++++----------
netwerk/protocol/http/DnsAndConnectSocket.h | 10 +-
.../protocol/http/PendingTransactionInfo.cpp | 20 +-
.../protocol/http/PendingTransactionInfo.h | 11 +-
netwerk/protocol/http/nsHttpConnectionMgr.cpp | 47 +--
netwerk/protocol/http/nsHttpConnectionMgr.h | 6 +-
8 files changed, 285 insertions(+), 283 deletions(-)
diff --git a/netwerk/protocol/http/ConnectionEntry.cpp b/netwerk/protocol/http/ConnectionEntry.cpp
index b9044b56916b..c5db65c61440 100644
--- a/netwerk/protocol/http/ConnectionEntry.cpp
+++ b/netwerk/protocol/http/ConnectionEntry.cpp
@@ -63,26 +63,18 @@ uint32_t ConnectionEntry::UnconnectedDnsAndConnectSockets() const {
return unconnectedDnsAndConnectSockets;
}
-bool ConnectionEntry::RemoveDnsAndConnectSocket(
- DnsAndConnectSocket* dnsAndSock) {
- bool isPrimary = false;
- // A failure to create the transport object at all
- // will result in it not being present in the DnsAndConnectSockets table.
- // That's expected.
+void ConnectionEntry::InsertIntoDnsAndConnectSockets(
+ DnsAndConnectSocket* sock) {
+ mDnsAndConnectSockets.AppendElement(sock);
+ gHttpHandler->ConnMgr()->IncreaseNumDnsAndConnectSockets();
+}
+
+void ConnectionEntry::RemoveDnsAndConnectSocket(DnsAndConnectSocket* dnsAndSock,
+ bool abandon) {
+ if (abandon) {
+ dnsAndSock->Abandon();
+ }
if (mDnsAndConnectSockets.RemoveElement(dnsAndSock)) {
- isPrimary = true;
- if (dnsAndSock->IsSpeculative()) {
- Telemetry::AutoCounter
- unusedSpeculativeConn;
- ++unusedSpeculativeConn;
-
- if (dnsAndSock->IsFromPredictor()) {
- Telemetry::AutoCounter
- totalPreconnectsUnused;
- ++totalPreconnectsUnused;
- }
- }
-
gHttpHandler->ConnMgr()->DecreaseNumDnsAndConnectSockets();
}
@@ -97,8 +89,20 @@ bool ConnectionEntry::RemoveDnsAndConnectSocket(
" failed to process pending queue\n"));
}
}
+}
- return isPrimary;
+void ConnectionEntry::CloseAllDnsAndConnectSockets() {
+ for (const auto& dnsAndSock : mDnsAndConnectSockets) {
+ dnsAndSock->Abandon();
+ gHttpHandler->ConnMgr()->DecreaseNumDnsAndConnectSockets();
+ }
+ mDnsAndConnectSockets.Clear();
+ nsresult rv = gHttpHandler->ConnMgr()->ProcessPendingQ(mConnInfo);
+ if (NS_FAILED(rv)) {
+ LOG(
+ ("ConnectionEntry::CloseAllDnsAndConnectSockets\n"
+ " failed to process pending queue\n"));
+ }
}
void ConnectionEntry::DisallowHttp2() {
@@ -519,25 +523,16 @@ void ConnectionEntry::MakeAllDontReuseExcept(HttpConnectionBase* conn) {
// Cancel any other pending connections - their associated transactions
// are in the pending queue and will be dispatched onto this new connection
- for (int32_t index = DnsAndConnectSocketsLength() - 1; index >= 0; --index) {
- RefPtr dnsAndSock = mDnsAndConnectSockets[index];
- LOG(
- ("ConnectionEntry::MakeAllDontReuseExcept forcing DnsAndConnectSocket "
- "abandon %p\n",
- dnsAndSock.get()));
- mDnsAndConnectSockets[index]->Abandon();
- }
+ CloseAllDnsAndConnectSockets();
}
bool ConnectionEntry::FindConnToClaim(
PendingTransactionInfo* pendingTransInfo) {
nsHttpTransaction* trans = pendingTransInfo->Transaction();
- uint32_t dnsAndSockLength = DnsAndConnectSocketsLength();
- for (uint32_t i = 0; i < dnsAndSockLength; i++) {
- auto* dnsAndSock = mDnsAndConnectSockets[i];
- if (dnsAndSock->AcceptsTransaction(trans) &&
- pendingTransInfo->TryClaimingDnsAndConnectSocket(dnsAndSock)) {
+ for (const auto& dnsAndSock : mDnsAndConnectSockets) {
+ if (dnsAndSock->AcceptsTransaction(trans) && dnsAndSock->Claim()) {
+ pendingTransInfo->RememberDnsAndConnectSocket(dnsAndSock);
// We've found a speculative connection or a connection that
// is free to be used in the DnsAndConnectSockets list.
// A free to be used connection is a connection that was
@@ -722,10 +717,7 @@ uint32_t ConnectionEntry::TimeoutTick() {
TimeStamp currentTime = TimeStamp::Now();
double maxConnectTime_ms = gHttpHandler->ConnectTimeout();
- for (uint32_t index = mDnsAndConnectSockets.Length(); index > 0;) {
- index--;
-
- DnsAndConnectSocket* dnsAndSock = mDnsAndConnectSockets[index];
+ for (const auto& dnsAndSock : Reversed(mDnsAndConnectSockets)) {
double delta = dnsAndSock->Duration(currentTime);
// If the socket has timed out, close it so the waiting
// transaction will get the proper signal.
@@ -740,7 +732,7 @@ uint32_t ConnectionEntry::TimeoutTick() {
if (delta > maxConnectTime_ms + 5000) {
LOG(("Abandon DnsAndConnectSocket to %s after %.2fms.\n",
mConnInfo->HashKey().get(), delta));
- dnsAndSock->Abandon();
+ RemoveDnsAndConnectSocket(dnsAndSock, true);
}
}
}
@@ -770,22 +762,6 @@ void ConnectionEntry::MoveConnection(HttpConnectionBase* proxyConn,
}
}
-void ConnectionEntry::InsertIntoDnsAndConnectSockets(
- DnsAndConnectSocket* sock) {
- mDnsAndConnectSockets.AppendElement(sock);
- gHttpHandler->ConnMgr()->IncreaseNumDnsAndConnectSockets();
-}
-
-void ConnectionEntry::CloseAllDnsAndConnectSockets() {
- for (int32_t i = int32_t(DnsAndConnectSocketsLength()) - 1; i >= 0; i--) {
- mDnsAndConnectSockets[i]->Abandon();
- }
-}
-
-bool ConnectionEntry::IsInDnsAndConnectSockets(DnsAndConnectSocket* sock) {
- return mDnsAndConnectSockets.Contains(sock);
-}
-
HttpRetParams ConnectionEntry::GetConnectionData() {
HttpRetParams data;
data.host = mConnInfo->Origin();
@@ -885,7 +861,11 @@ bool ConnectionEntry::RemoveTransFromPendingQ(nsHttpTransaction* aTrans) {
}
// Abandon all DnsAndConnectSockets belonging to the given transaction.
- pendingTransInfo->AbandonDnsAndConnectSocketAndForgetActiveConn();
+ nsWeakPtr tmp = pendingTransInfo->ForgetDnsAndConnectSocketAndActiveConn();
+ RefPtr dnsAndSock = do_QueryReferent(tmp);
+ if (dnsAndSock) {
+ RemoveDnsAndConnectSocket(dnsAndSock, true);
+ }
return true;
}
@@ -911,5 +891,81 @@ void ConnectionEntry::MaybeUpdateEchConfig(nsHttpConnectionInfo* aConnInfo) {
CloseIdleConnections();
}
+nsresult ConnectionEntry::CreateDnsAndConnectSocket(nsAHttpTransaction* trans, uint32_t caps,
+ bool speculative, bool isFromPredictor, bool urgentStart, bool allow1918,
+ PendingTransactionInfo* pendingTransInfo) {
+ MOZ_ASSERT(OnSocketThread(), "not on socket thread");
+ MOZ_ASSERT((speculative && !pendingTransInfo) ||
+ (!speculative && pendingTransInfo));
+
+ RefPtr sock = new DnsAndConnectSocket(
+ mConnInfo, trans, caps, speculative, isFromPredictor, urgentStart);
+
+ if (speculative) {
+ sock->SetAllow1918(allow1918);
+ }
+
+ nsresult rv = sock->Init(this);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ InsertIntoDnsAndConnectSockets(sock);
+
+ if (pendingTransInfo && sock->Claim()) {
+ pendingTransInfo->RememberDnsAndConnectSocket(sock);
+ }
+
+ return NS_OK;
+}
+
+bool ConnectionEntry::MaybeProcessCoalescingKeys(nsIDNSAddrRecord* dnsRecord) {
+ if (!mConnInfo || !AllowHttp2() || !mCoalescingKeys.IsEmpty() || !dnsRecord) {
+ return false;
+ }
+
+ nsTArray addressSet;
+ nsresult rv = dnsRecord->GetAddresses(addressSet);
+
+ if (NS_FAILED(rv) || addressSet.IsEmpty()) {
+ return false;
+ }
+
+ for (uint32_t i = 0; i < addressSet.Length(); ++i) {
+ if ((addressSet[i].raw.family == AF_INET &&
+ addressSet[i].inet.ip == 0) ||
+ (addressSet[i].raw.family == AF_INET6 &&
+ addressSet[i].inet6.ip.u64[0] == 0 &&
+ addressSet[i].inet6.ip.u64[1] == 0)) {
+ // Bug 1680249 - Don't create the coalescing key if the ip address is
+ // `0.0.0.0` or `::`.
+ LOG((
+ "ConnectionEntry::MaybeProcessCoalescingKeys skip creating "
+ "Coalescing Key for host [%s]",
+ mConnInfo->Origin()));
+ continue;
+ }
+ nsCString* newKey = mCoalescingKeys.AppendElement(nsCString());
+ newKey->SetLength(kIPv6CStrBufSize + 26);
+ addressSet[i].ToStringBuffer(newKey->BeginWriting(), kIPv6CStrBufSize);
+ newKey->SetLength(strlen(newKey->BeginReading()));
+ if (mConnInfo->GetAnonymous()) {
+ newKey->AppendLiteral("~A:");
+ } else {
+ newKey->AppendLiteral("~.:");
+ }
+ newKey->AppendInt(mConnInfo->OriginPort());
+ newKey->AppendLiteral("/[");
+ nsAutoCString suffix;
+ mConnInfo->GetOriginAttributes().CreateSuffix(suffix);
+ newKey->Append(suffix);
+ newKey->AppendLiteral("]viaDNS");
+ LOG((
+ "ConnectionEntry::MaybeProcessCoalescingKeys "
+ "Established New Coalescing Key # %d for host "
+ "%s [%s]",
+ i, mConnInfo->Origin(), newKey->get()));
+ }
+ return true;
+}
+
} // namespace net
} // namespace mozilla
diff --git a/netwerk/protocol/http/ConnectionEntry.h b/netwerk/protocol/http/ConnectionEntry.h
index 17ccb98d2cbc..62229817b6c6 100644
--- a/netwerk/protocol/http/ConnectionEntry.h
+++ b/netwerk/protocol/http/ConnectionEntry.h
@@ -84,8 +84,8 @@ class ConnectionEntry {
}
void InsertIntoDnsAndConnectSockets(DnsAndConnectSocket* sock);
+ void RemoveDnsAndConnectSocket(DnsAndConnectSocket* dnsAndSock, bool abandon);
void CloseAllDnsAndConnectSockets();
- bool IsInDnsAndConnectSockets(DnsAndConnectSocket* sock);
HttpRetParams GetConnectionData();
void LogConnections();
@@ -101,6 +101,13 @@ class ConnectionEntry {
// Remove a particular DnsAndConnectSocket from the mDnsAndConnectSocket array
bool RemoveDnsAndConnectSocket(DnsAndConnectSocket*);
+ nsresult CreateDnsAndConnectSocket(nsAHttpTransaction* trans, uint32_t caps,
+ bool speculative, bool isFromPredictor,
+ bool urgentStart, bool allow1918,
+ PendingTransactionInfo* pendingTransInfo);
+
+ bool MaybeProcessCoalescingKeys(nsIDNSAddrRecord* dnsRecord);
+
// Spdy sometimes resolves the address in the socket manager in order
// to re-coalesce sharded HTTP hosts. The dotted decimal address is
// combined with the Anonymous flag and OA from the connection information
@@ -190,7 +197,7 @@ class ConnectionEntry {
nsTArray> mIdleConns; // idle persistent connections
nsTArray> mActiveConns; // active connections
- nsTArray
+ nsTArray>
mDnsAndConnectSockets; // dns resolution and half open connections
PendingTransactionQueue mPendingQ;
diff --git a/netwerk/protocol/http/DnsAndConnectSocket.cpp b/netwerk/protocol/http/DnsAndConnectSocket.cpp
index 61668cc48c9c..768cb1573315 100644
--- a/netwerk/protocol/http/DnsAndConnectSocket.cpp
+++ b/netwerk/protocol/http/DnsAndConnectSocket.cpp
@@ -41,7 +41,7 @@ NS_INTERFACE_MAP_BEGIN(DnsAndConnectSocket)
NS_INTERFACE_MAP_ENTRY_CONCRETE(DnsAndConnectSocket)
NS_INTERFACE_MAP_END
-DnsAndConnectSocket::DnsAndConnectSocket(ConnectionEntry* ent,
+DnsAndConnectSocket::DnsAndConnectSocket(nsHttpConnectionInfo* ci,
nsAHttpTransaction* trans,
uint32_t caps, bool speculative,
bool isFromPredictor, bool urgentStart)
@@ -51,13 +51,13 @@ DnsAndConnectSocket::DnsAndConnectSocket(ConnectionEntry* ent,
mSpeculative(speculative),
mUrgentStart(urgentStart),
mIsFromPredictor(isFromPredictor),
- mEnt(ent),
+ mConnInfo(ci),
mBackupTransport(true) {
- MOZ_ASSERT(ent && trans, "constructor with null arguments");
+ MOZ_ASSERT(ci && trans, "constructor with null arguments");
LOG(("Creating DnsAndConnectSocket [this=%p trans=%p ent=%s key=%s]\n", this,
- trans, ent->mConnInfo->Origin(), ent->mConnInfo->HashKey().get()));
+ trans, mConnInfo->Origin(), mConnInfo->HashKey().get()));
- mIsHttp3 = mEnt->mConnInfo->IsHttp3();
+ mIsHttp3 = mConnInfo->IsHttp3();
if (speculative) {
Telemetry::AutoCounter
totalSpeculativeConn;
@@ -70,7 +70,7 @@ DnsAndConnectSocket::DnsAndConnectSocket(ConnectionEntry* ent,
}
}
- MOZ_ASSERT(mEnt);
+ MOZ_ASSERT(mConnInfo);
}
DnsAndConnectSocket::~DnsAndConnectSocket() {
@@ -81,45 +81,46 @@ DnsAndConnectSocket::~DnsAndConnectSocket() {
MOZ_ASSERT(!mPrimaryTransport.mWaitingForConnect);
MOZ_ASSERT(!mBackupTransport.mWaitingForConnect);
// Check in case something goes wrong that we decrease
- // the nsHttpConnectionMgr active connecttion number.
+ // the nsHttpConnectionMgr active connection number.
mPrimaryTransport.MaybeSetConnectingDone();
mBackupTransport.MaybeSetConnectingDone();
- if (mEnt) {
- bool inqueue = mEnt->RemoveDnsAndConnectSocket(this);
- LOG((
- "Destroying DnsAndConnectSocket was in the HalfOpenList=%d [this=%p]\n",
- inqueue, this));
+ if (mSpeculative) {
+ Telemetry::AutoCounter
+ unusedSpeculativeConn;
+ ++unusedSpeculativeConn;
+
+ if (mIsFromPredictor) {
+ Telemetry::AutoCounter
+ totalPreconnectsUnused;
+ ++totalPreconnectsUnused;
+ }
}
}
-nsresult DnsAndConnectSocket::Init() {
+nsresult DnsAndConnectSocket::Init(ConnectionEntry* ent) {
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
- MOZ_ASSERT(mEnt);
MOZ_ASSERT(mState == DnsAndSocketState::INIT);
- if (mEnt->mConnInfo->GetRoutedHost().IsEmpty()) {
- mPrimaryTransport.mHost = mEnt->mConnInfo->GetOrigin();
- mBackupTransport.mHost = mEnt->mConnInfo->GetOrigin();
+ if (mConnInfo->GetRoutedHost().IsEmpty()) {
+ mPrimaryTransport.mHost = mConnInfo->GetOrigin();
+ mBackupTransport.mHost = mConnInfo->GetOrigin();
} else {
- mPrimaryTransport.mHost = mEnt->mConnInfo->GetRoutedHost();
- mBackupTransport.mHost = mEnt->mConnInfo->GetRoutedHost();
+ mPrimaryTransport.mHost = mConnInfo->GetRoutedHost();
+ mBackupTransport.mHost = mConnInfo->GetRoutedHost();
}
CheckProxyConfig();
if (!mSkipDnsResolution) {
- nsresult rv = SetupDnsFlags();
+ nsresult rv = SetupDnsFlags(ent);
NS_ENSURE_SUCCESS(rv, rv);
}
return SetupEvent(SetupEvents::INIT_EVENT);
}
void DnsAndConnectSocket::CheckProxyConfig() {
- const nsHttpConnectionInfo* ci = mEnt->mConnInfo;
-
- if (ci->ProxyInfo()) {
- nsCOMPtr proxyInfo = ci->ProxyInfo();
+ if (nsCOMPtr proxyInfo = mConnInfo->ProxyInfo()) {
nsAutoCString proxyType(proxyInfo->Type());
bool proxyTransparent = false;
@@ -151,7 +152,7 @@ void DnsAndConnectSocket::CheckProxyConfig() {
}
}
-nsresult DnsAndConnectSocket::SetupDnsFlags() {
+nsresult DnsAndConnectSocket::SetupDnsFlags(ConnectionEntry* ent) {
LOG(("DnsAndConnectSocket::SetupDnsFlags [this=%p] ", this));
uint32_t dnsFlags = 0;
@@ -163,10 +164,10 @@ nsresult DnsAndConnectSocket::SetupDnsFlags() {
dnsFlags |= nsIDNSService::RESOLVE_DISABLE_IPV4;
} else if (mCaps & NS_HTTP_DISABLE_IPV6) {
dnsFlags |= nsIDNSService::RESOLVE_DISABLE_IPV6;
- } else if (mEnt->PreferenceKnown()) {
- if (mEnt->mPreferIPv6) {
+ } else if (ent->PreferenceKnown()) {
+ if (ent->mPreferIPv6) {
dnsFlags |= nsIDNSService::RESOLVE_DISABLE_IPV4;
- } else if (mEnt->mPreferIPv4) {
+ } else if (ent->mPreferIPv4) {
dnsFlags |= nsIDNSService::RESOLVE_DISABLE_IPV6;
}
mPrimaryTransport.mRetryWithDifferentIPFamily = true;
@@ -180,7 +181,7 @@ nsresult DnsAndConnectSocket::SetupDnsFlags() {
disableIpv6ForBackup = true;
}
- if (mEnt->mConnInfo->HasIPHintAddress()) {
+ if (ent->mConnInfo->HasIPHintAddress()) {
nsresult rv;
nsCOMPtr dns =
do_GetService("@mozilla.org/network/dns-service;1", &rv);
@@ -194,7 +195,7 @@ nsresult DnsAndConnectSocket::SetupDnsFlags() {
nsCOMPtr record;
rv = dns->ResolveNative(
mPrimaryTransport.mHost, nsIDNSService::RESOLVE_OFFLINE,
- mEnt->mConnInfo->GetOriginAttributes(), getter_AddRefs(record));
+ mConnInfo->GetOriginAttributes(), getter_AddRefs(record));
if (NS_FAILED(rv) || !record) {
LOG(("Setting Socket to use IP hint address"));
dnsFlags |= nsIDNSService::RESOLVE_IP_HINT;
@@ -230,27 +231,29 @@ nsresult DnsAndConnectSocket::SetupDnsFlags() {
nsresult DnsAndConnectSocket::SetupEvent(SetupEvents event) {
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
- LOG(("DnsAndConnectSocket::SetupEvent state=%d event=%d", mState, event));
+ LOG(("DnsAndConnectSocket::SetupEvent state=%d event=%d this=%p", mState,
+ event, this));
+ nsresult rv = NS_OK;
switch (event) {
- case SetupEvents::INIT_EVENT: {
+ case SetupEvents::INIT_EVENT:
MOZ_ASSERT(mState == DnsAndSocketState::INIT);
- nsresult rv = mPrimaryTransport.Init(this);
+ rv = mPrimaryTransport.Init(this);
if (NS_FAILED(rv)) {
mState = DnsAndSocketState::DONE;
- return rv;
- }
- if (mPrimaryTransport.FirstResolving()) {
+ } else if (mPrimaryTransport.FirstResolving()) {
mState = DnsAndSocketState::RESOLVING;
} else if (!mIsHttp3 && mPrimaryTransport.ConnectingOrRetry()) {
mState = DnsAndSocketState::CONNECTING;
SetupBackupTimer();
} else {
MOZ_ASSERT(false);
- return NS_ERROR_UNEXPECTED;
+ mState = DnsAndSocketState::DONE;
+ Abandon();
+ rv = NS_ERROR_UNEXPECTED;
}
- } break;
+ break;
case SetupEvents::RESOLVED_PRIMARY_EVENT:
- // This eventt may be posted multiple times if a DNS lookup is
+ // This event may be posted multiple times if a DNS lookup is
// retriggered, e.g with different parameter.
if (!mIsHttp3 && (mState == DnsAndSocketState::RESOLVING)) {
mState = DnsAndSocketState::CONNECTING;
@@ -284,11 +287,19 @@ nsresult DnsAndConnectSocket::SetupEvent(SetupEvents event) {
}
LOG(("DnsAndConnectSocket::SetupEvent state=%d", mState));
+ if (mState == DnsAndSocketState::DONE) {
+ RefPtr self(this);
+ RefPtr ent =
+ gHttpHandler->ConnMgr()->FindConnectionEntry(mConnInfo);
+ if (ent) {
+ ent->RemoveDnsAndConnectSocket(this, false);
+ }
+ return rv;
+ }
return NS_OK;
}
void DnsAndConnectSocket::SetupBackupTimer() {
- MOZ_ASSERT(mEnt);
uint16_t timeout = gHttpHandler->GetIdleSynTimeout();
MOZ_ASSERT(!mSynTimer, "timer already initd");
@@ -327,14 +338,12 @@ void DnsAndConnectSocket::CancelBackupTimer() {
void DnsAndConnectSocket::Abandon() {
LOG(("DnsAndConnectSocket::Abandon [this=%p ent=%s] %p %p %p %p", this,
- mEnt->mConnInfo->Origin(), mPrimaryTransport.mSocketTransport.get(),
+ mConnInfo->Origin(), mPrimaryTransport.mSocketTransport.get(),
mBackupTransport.mSocketTransport.get(),
mPrimaryTransport.mStreamOut.get(), mBackupTransport.mStreamOut.get()));
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
- RefPtr deleteProtector(this);
-
// Tell socket (and backup socket) to forget the half open socket.
mPrimaryTransport.Abandon();
mBackupTransport.Abandon();
@@ -343,13 +352,6 @@ void DnsAndConnectSocket::Abandon() {
CancelBackupTimer();
mState = DnsAndSocketState::DONE;
-
- // Remove the half open from the connection entry.
- if (mEnt) {
- mEnt->mDoNotDestroy = false;
- mEnt->RemoveDnsAndConnectSocket(this);
- }
- mEnt = nullptr;
}
double DnsAndConnectSocket::Duration(TimeStamp epoch) {
@@ -368,7 +370,6 @@ DnsAndConnectSocket::Notify(nsITimer* timer) {
MOZ_ASSERT(!mBackupTransport.mDNSRequest);
MOZ_ASSERT(!mBackupTransport.mSocketTransport);
MOZ_ASSERT(mSynTimer);
- MOZ_ASSERT(mEnt);
DebugOnly rv = SetupEvent(BACKUP_TIMER_FIRED_EVENT);
MOZ_ASSERT(NS_SUCCEEDED(rv));
@@ -414,7 +415,7 @@ DnsAndConnectSocket::OnLookupComplete(nsICancelable* request, nsIDNSRecord* rec,
// remember if it was primary because TransportSetups will delete the ref to
// the DNS request and check cannot be performed later.
bool isPrimary = IsPrimary(request);
- if (IsPrimary(request)) {
+ if (isPrimary) {
rv = mPrimaryTransport.OnLookupComplete(this, rec, status);
if ((!mIsHttp3 && mPrimaryTransport.ConnectingOrRetry()) ||
(mIsHttp3 && mPrimaryTransport.Resolved())) {
@@ -425,7 +426,21 @@ DnsAndConnectSocket::OnLookupComplete(nsICancelable* request, nsIDNSRecord* rec,
}
if (NS_FAILED(rv) || mIsHttp3) {
+ // Before calling SetupConn we need to hold reference to this, i.e. a
+ // delete protector, because the corresponding ConnectionEntry may be
+ // abandoned and that will abandon this DnsAndConnectSocket.
SetupConn(isPrimary, rv);
+ // During a connection dispatch that will happen in SetupConn,
+ // a ConnectionEntry may be abandon and that will abandon this
+ // DnsAndConnectSocket. In that case mState will already be
+ // DnsAndSocketState::DONE and we do not need to set it again.
+ if (mState != DnsAndSocketState::DONE) {
+ if (isPrimary) {
+ SetupEvent(SetupEvents::PRIMARY_DONE_EVENT);
+ } else {
+ SetupEvent(SetupEvents::BACKUP_DONE_EVENT);
+ }
+ }
}
return NS_OK;
}
@@ -437,12 +452,11 @@ DnsAndConnectSocket::OnOutputStreamReady(nsIAsyncOutputStream* out) {
MOZ_ASSERT(mPrimaryTransport.mSocketTransport ||
mBackupTransport.mSocketTransport);
MOZ_ASSERT(IsPrimary(out) || IsBackup(out), "stream mismatch");
- MOZ_ASSERT(mEnt);
RefPtr deleteProtector(this);
LOG(("DnsAndConnectSocket::OnOutputStreamReady [this=%p ent=%s %s]\n", this,
- mEnt->mConnInfo->Origin(), IsPrimary(out) ? "primary" : "backup"));
+ mConnInfo->Origin(), IsPrimary(out) ? "primary" : "backup"));
// Remember if it was primary or backup reuest.
bool isPrimary = IsPrimary(out);
@@ -478,27 +492,43 @@ DnsAndConnectSocket::OnOutputStreamReady(nsIAsyncOutputStream* out) {
return NS_ERROR_UNEXPECTED;
}
- mEnt->mDoNotDestroy = true;
-
+ // Before calling SetupConn we need to hold a reference to this, i.e. a
+ // delete protector, because the corresponding ConnectionEntry may be
+ // abandoned and that will abandon this DnsAndConnectSocket.
rv = SetupConn(isPrimary, rv);
- if (mEnt) {
- mEnt->mDoNotDestroy = false;
+ if (mState != DnsAndSocketState::DONE) {
+ // During a connection dispatch that will happen in SetupConn,
+ // a ConnectionEntry may be abandon and that will abandon this
+ // DnsAndConnectSocket. In that case mState will already be
+ // DnsAndSocketState::DONE and we do not need to set it again.
+ if (isPrimary) {
+ SetupEvent(SetupEvents::PRIMARY_DONE_EVENT);
+ } else {
+ SetupEvent(SetupEvents::BACKUP_DONE_EVENT);
+ }
}
return rv;
}
nsresult DnsAndConnectSocket::SetupConn(bool isPrimary, nsresult status) {
// assign the new socket to the http connection
+
+ RefPtr ent =
+ gHttpHandler->ConnMgr()->FindConnectionEntry(mConnInfo);
+ MOZ_DIAGNOSTIC_ASSERT(ent);
+ if (!ent) {
+ Abandon();
+ return NS_OK;
+ }
+
RefPtr conn;
nsresult rv = NS_OK;
if (isPrimary) {
- SetupEvent(SetupEvents::PRIMARY_DONE_EVENT);
- rv = mPrimaryTransport.SetupConn(mTransaction, mEnt, status, mCaps,
+ rv = mPrimaryTransport.SetupConn(mTransaction, ent, status, mCaps,
getter_AddRefs(conn));
} else {
- SetupEvent(SetupEvents::BACKUP_DONE_EVENT);
- rv = mBackupTransport.SetupConn(mTransaction, mEnt, status, mCaps,
+ rv = mBackupTransport.SetupConn(mTransaction, ent, status, mCaps,
getter_AddRefs(conn));
}
@@ -514,12 +544,12 @@ nsresult DnsAndConnectSocket::SetupConn(bool isPrimary, nsresult status) {
if (nsHttpTransaction* trans = mTransaction->QueryHttpTransaction()) {
if (mIsHttp3) {
trans->DisableHttp3();
- gHttpHandler->ExcludeHttp3(mEnt->mConnInfo);
+ gHttpHandler->ExcludeHttp3(mConnInfo);
}
// The transaction's connection info is changed after DisableHttp3(), so
// this is the only point we can remove this transaction from its conn
// entry.
- mEnt->RemoveTransFromPendingQ(trans);
+ ent->RemoveTransFromPendingQ(trans);
}
mTransaction->Close(rv);
@@ -532,11 +562,11 @@ nsresult DnsAndConnectSocket::SetupConn(bool isPrimary, nsresult status) {
// if this is still in the pending list, remove it and dispatch it
RefPtr pendingTransInfo =
- gHttpHandler->ConnMgr()->FindTransactionHelper(true, mEnt, mTransaction);
+ gHttpHandler->ConnMgr()->FindTransactionHelper(true, ent, mTransaction);
if (pendingTransInfo) {
MOZ_ASSERT(!mSpeculative, "Speculative Half Open found mTransaction");
- mEnt->InsertIntoActiveConns(conn);
+ ent->InsertIntoActiveConns(conn);
if (mIsHttp3) {
// Each connection must have a ConnectionHandle wrapper.
// In case of Http < 2 the a ConnectionHandle is created for each
@@ -555,7 +585,7 @@ nsresult DnsAndConnectSocket::SetupConn(bool isPrimary, nsresult status) {
pendingTransInfo->Transaction()->SetConnection(handle);
}
rv = gHttpHandler->ConnMgr()->DispatchTransaction(
- mEnt, pendingTransInfo->Transaction(), conn);
+ ent, pendingTransInfo->Transaction(), conn);
} else {
// this transaction was dispatched off the pending q before all the
// sockets established themselves.
@@ -576,8 +606,8 @@ nsresult DnsAndConnectSocket::SetupConn(bool isPrimary, nsresult status) {
// Http3 cannot be dispatched using OnMsgReclaimConnection (see below),
// therefore we need to use a Nulltransaction.
if (!connTCP ||
- (mEnt->mConnInfo->FirstHopSSL() && !mEnt->UrgentStartQueueLength() &&
- !mEnt->PendingQueueLength() && !mEnt->mConnInfo->UsingConnect())) {
+ (ent->mConnInfo->FirstHopSSL() && !ent->UrgentStartQueueLength() &&
+ !ent->PendingQueueLength() && !ent->mConnInfo->UsingConnect())) {
LOG(
("DnsAndConnectSocket::SetupConn null transaction will "
"be used to finish SSL handshake on conn %p\n",
@@ -589,11 +619,11 @@ nsresult DnsAndConnectSocket::SetupConn(bool isPrimary, nsresult status) {
mDispatchedMTransaction = true;
trans = mTransaction;
} else {
- trans = new NullHttpTransaction(mEnt->mConnInfo, callbacks, mCaps);
+ trans = new NullHttpTransaction(mConnInfo, callbacks, mCaps);
}
- mEnt->InsertIntoActiveConns(conn);
- rv = gHttpHandler->ConnMgr()->DispatchAbstractTransaction(mEnt, trans,
+ ent->InsertIntoActiveConns(conn);
+ rv = gHttpHandler->ConnMgr()->DispatchAbstractTransaction(ent, trans,
mCaps, conn, 0);
} else {
// otherwise just put this in the persistent connection pool
@@ -610,24 +640,22 @@ nsresult DnsAndConnectSocket::SetupConn(bool isPrimary, nsresult status) {
// idle queue.
// If the connection is in the idle queue but it is using ssl, make
// a nulltransaction for it to finish ssl handshake!
-
- // !!! It can be that mEnt is null after OnMsgReclaimConnection.!!!
- if (mEnt && mEnt->mConnInfo->FirstHopSSL() &&
- !mEnt->mConnInfo->UsingConnect()) {
+ if (ent->mConnInfo->FirstHopSSL() &&
+ !ent->mConnInfo->UsingConnect()) {
RefPtr connTCP = do_QueryObject(conn);
// If RemoveIdleConnection succeeds that means that conn is in the
// idle queue.
- if (connTCP && NS_SUCCEEDED(mEnt->RemoveIdleConnection(connTCP))) {
+ if (connTCP && NS_SUCCEEDED(ent->RemoveIdleConnection(connTCP))) {
RefPtr trans;
if (mTransaction->IsNullTransaction() && !mDispatchedMTransaction) {
mDispatchedMTransaction = true;
trans = mTransaction;
} else {
- trans = new NullHttpTransaction(mEnt->mConnInfo, callbacks, mCaps);
+ trans = new NullHttpTransaction(ent->mConnInfo, callbacks, mCaps);
}
- mEnt->InsertIntoActiveConns(conn);
+ ent->InsertIntoActiveConns(conn);
rv = gHttpHandler->ConnMgr()->DispatchAbstractTransaction(
- mEnt, trans, mCaps, conn, 0);
+ ent, trans, mCaps, conn, 0);
}
}
}
@@ -649,7 +677,6 @@ DnsAndConnectSocket::OnTransportStatus(nsITransport* trans, nsresult status,
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
MOZ_ASSERT(IsPrimary(trans) || IsBackup(trans));
- MOZ_ASSERT(mEnt);
if (mTransaction) {
if (IsPrimary(trans) ||
(IsBackup(trans) && (status == NS_NET_STATUS_CONNECTED_TO) &&
@@ -685,55 +712,18 @@ DnsAndConnectSocket::OnTransportStatus(nsITransport* trans, nsresult status,
// for this entry before then make the hash key if our dns lookup
// just completed. We can't do coalescing if using a proxy because the
// ip addresses are not available to the client.
-
- if (status == NS_NET_STATUS_CONNECTING_TO && gHttpHandler->IsSpdyEnabled() &&
- gHttpHandler->CoalesceSpdy() && mEnt && mEnt->mConnInfo &&
- mEnt->mConnInfo->EndToEndSSL() && mEnt->AllowHttp2() &&
- !mEnt->mConnInfo->UsingProxy() && mEnt->mCoalescingKeys.IsEmpty()) {
- nsCOMPtr dnsRecord(
+ nsCOMPtr dnsRecord(
do_GetInterface(mPrimaryTransport.mSocketTransport));
- nsTArray addressSet;
- nsresult rv = NS_ERROR_NOT_AVAILABLE;
- if (dnsRecord) {
- rv = dnsRecord->GetAddresses(addressSet);
- }
+ if (status == NS_NET_STATUS_CONNECTING_TO && gHttpHandler->IsSpdyEnabled() &&
+ gHttpHandler->CoalesceSpdy() && mConnInfo && mConnInfo->EndToEndSSL() &&
+ !mConnInfo->UsingProxy() && dnsRecord) {
- if (NS_SUCCEEDED(rv) && !addressSet.IsEmpty()) {
- for (uint32_t i = 0; i < addressSet.Length(); ++i) {
- if ((addressSet[i].raw.family == AF_INET &&
- addressSet[i].inet.ip == 0) ||
- (addressSet[i].raw.family == AF_INET6 &&
- addressSet[i].inet6.ip.u64[0] == 0 &&
- addressSet[i].inet6.ip.u64[1] == 0)) {
- // Bug 1680249 - Don't create the coalescing key if the ip address is
- // `0.0.0.0` or `::`.
- LOG((
- "DnsAndConnectSocket: skip creating Coalescing Key for host [%s]",
- mEnt->mConnInfo->Origin()));
- continue;
- }
- nsCString* newKey = mEnt->mCoalescingKeys.AppendElement(nsCString());
- newKey->SetLength(kIPv6CStrBufSize + 26);
- addressSet[i].ToStringBuffer(newKey->BeginWriting(), kIPv6CStrBufSize);
- newKey->SetLength(strlen(newKey->BeginReading()));
- if (mEnt->mConnInfo->GetAnonymous()) {
- newKey->AppendLiteral("~A:");
- } else {
- newKey->AppendLiteral("~.:");
- }
- newKey->AppendInt(mEnt->mConnInfo->OriginPort());
- newKey->AppendLiteral("/[");
- nsAutoCString suffix;
- mEnt->mConnInfo->GetOriginAttributes().CreateSuffix(suffix);
- newKey->Append(suffix);
- newKey->AppendLiteral("]viaDNS");
- LOG((
- "DnsAndConnectSocket::OnTransportStatus "
- "STATUS_CONNECTING_TO Established New Coalescing Key # %d for host "
- "%s [%s]",
- i, mEnt->mConnInfo->Origin(), newKey->get()));
+ RefPtr ent = gHttpHandler->ConnMgr()->FindConnectionEntry(mConnInfo);
+ MOZ_DIAGNOSTIC_ASSERT(ent);
+ if (ent) {
+ if (ent->MaybeProcessCoalescingKeys(dnsRecord)) {
+ gHttpHandler->ConnMgr()->ProcessSpdyPendingQ(ent);
}
- gHttpHandler->ConnMgr()->ProcessSpdyPendingQ(mEnt);
}
}
@@ -807,7 +797,7 @@ bool DnsAndConnectSocket::Claim() {
// Http3 has its own syn-retransmission, therefore it does not need a
// backup connection.
- if (mPrimaryTransport.ConnectingOrRetry() && mEnt &&
+ if (mPrimaryTransport.ConnectingOrRetry() &&
!mBackupTransport.mSocketTransport && !mSynTimer && !mIsHttp3) {
SetupBackupTimer();
}
@@ -1025,6 +1015,7 @@ nsresult DnsAndConnectSocket::TransportSetup::SetupConn(
NS_SUCCEEDED(mSocketTransport->GetPeerAddr(&peeraddr))) {
ent->RecordIPFamilyPreference(peeraddr.raw.family);
}
+
conn.forget(connection);
mSocketTransport = nullptr;
mStreamOut = nullptr;
@@ -1037,10 +1028,9 @@ nsresult DnsAndConnectSocket::TransportSetup::SetupStreams(
DnsAndConnectSocket* dnsAndSock) {
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
- MOZ_ASSERT(dnsAndSock->mEnt);
nsresult rv;
nsTArray socketTypes;
- const nsHttpConnectionInfo* ci = dnsAndSock->mEnt->mConnInfo;
+ const nsHttpConnectionInfo* ci = dnsAndSock->mConnInfo;
if (dnsAndSock->mIsHttp3) {
socketTypes.AppendElement("quic"_ns);
} else {
@@ -1138,7 +1128,7 @@ nsresult DnsAndConnectSocket::TransportSetup::SetupStreams(
// record is in cache before setting USE_IP_HINT_ADDRESS.
nsCOMPtr record;
rv = dns->ResolveNative(mHost, nsIDNSService::RESOLVE_OFFLINE,
- dnsAndSock->mEnt->mConnInfo->GetOriginAttributes(),
+ dnsAndSock->mConnInfo->GetOriginAttributes(),
getter_AddRefs(record));
if (NS_FAILED(rv) || !record) {
LOG(("Setting Socket to use IP hint address"));
@@ -1146,21 +1136,7 @@ nsresult DnsAndConnectSocket::TransportSetup::SetupStreams(
}
}
- if (dnsAndSock->mCaps & NS_HTTP_DISABLE_IPV4) {
- tmpFlags |= nsISocketTransport::DISABLE_IPV4;
- } else if (dnsAndSock->mCaps & NS_HTTP_DISABLE_IPV6) {
- tmpFlags |= nsISocketTransport::DISABLE_IPV6;
- } else if (dnsAndSock->mEnt->PreferenceKnown()) {
- if (dnsAndSock->mEnt->mPreferIPv6) {
- tmpFlags |= nsISocketTransport::DISABLE_IPV4;
- } else if (dnsAndSock->mEnt->mPreferIPv4) {
- tmpFlags |= nsISocketTransport::DISABLE_IPV6;
- }
-
- // In case the host is no longer accessible via the preferred IP family,
- // try the opposite one and potentially restate the preference.
- tmpFlags |= nsISocketTransport::RETRY_WITH_DIFFERENT_IP_FAMILY;
-
+ if (mRetryWithDifferentIPFamily) {
// From the same reason, let the backup socket fail faster to try the other
// family.
uint16_t fallbackTimeout =
@@ -1169,27 +1145,16 @@ nsresult DnsAndConnectSocket::TransportSetup::SetupStreams(
socketTransport->SetTimeout(nsISocketTransport::TIMEOUT_CONNECT,
fallbackTimeout);
}
- } else if (mIsBackup && gHttpHandler->FastFallbackToIPv4()) {
- // For backup connections, we disable IPv6. That's because some users have
- // broken IPv6 connectivity (leading to very long timeouts), and disabling
- // IPv6 on the backup connection gives them a much better user experience
- // with dual-stack hosts, though they still pay the 250ms delay for each new
- // connection. This strategy is also known as "happy eyeballs".
- tmpFlags |= nsISocketTransport::DISABLE_IPV6;
}
if (!dnsAndSock->Allow1918()) {
tmpFlags |= nsISocketTransport::DISABLE_RFC1918;
}
- MOZ_ASSERT(!(tmpFlags & nsISocketTransport::DISABLE_IPV4) ||
- !(tmpFlags & nsISocketTransport::DISABLE_IPV6),
- "Both types should not be disabled at the same time.");
socketTransport->SetConnectionFlags(tmpFlags);
socketTransport->SetTlsFlags(ci->GetTlsFlags());
- const OriginAttributes& originAttributes =
- dnsAndSock->mEnt->mConnInfo->GetOriginAttributes();
+ const OriginAttributes& originAttributes = dnsAndSock->mConnInfo->GetOriginAttributes();
if (originAttributes != OriginAttributes()) {
socketTransport->SetOriginAttributes(originAttributes);
}
@@ -1207,9 +1172,13 @@ nsresult DnsAndConnectSocket::TransportSetup::SetupStreams(
NS_ENSURE_SUCCESS(rv, rv);
}
- Telemetry::Accumulate(Telemetry::HTTP_CONNECTION_ENTRY_CACHE_HIT_1,
- dnsAndSock->mEnt->mUsedForConnection);
- dnsAndSock->mEnt->mUsedForConnection = true;
+ RefPtr ent = gHttpHandler->ConnMgr()->FindConnectionEntry(ci);
+ MOZ_DIAGNOSTIC_ASSERT(ent);
+ if (ent) {
+ Telemetry::Accumulate(Telemetry::HTTP_CONNECTION_ENTRY_CACHE_HIT_1,
+ ent->mUsedForConnection);
+ ent->mUsedForConnection = true;
+ }
nsCOMPtr sout;
rv = socketTransport->OpenOutputStream(nsITransport::OPEN_UNBUFFERED, 0, 0,
@@ -1252,14 +1221,14 @@ nsresult DnsAndConnectSocket::TransportSetup::ResolveHost(
nsresult rv = dns->AsyncResolveNative(
mHost, nsIDNSService::RESOLVE_TYPE_DEFAULT, mDnsFlags, nullptr,
dnsAndSock, gSocketTransportService,
- dnsAndSock->mEnt->mConnInfo->GetOriginAttributes(),
+ dnsAndSock->mConnInfo->GetOriginAttributes(),
getter_AddRefs(mDNSRequest));
if (NS_FAILED(rv) && (mDnsFlags & nsIDNSService::RESOLVE_IP_HINT)) {
mDnsFlags &= ~nsIDNSService::RESOLVE_IP_HINT;
return dns->AsyncResolveNative(
mHost, nsIDNSService::RESOLVE_TYPE_DEFAULT, mDnsFlags, nullptr,
dnsAndSock, gSocketTransportService,
- dnsAndSock->mEnt->mConnInfo->GetOriginAttributes(),
+ dnsAndSock->mConnInfo->GetOriginAttributes(),
getter_AddRefs(mDNSRequest));
}
@@ -1273,7 +1242,7 @@ nsresult DnsAndConnectSocket::TransportSetup::OnLookupComplete(
mDNSRecord = do_QueryInterface(rec);
MOZ_ASSERT(mDNSRecord);
- if (dnsAndSock->mEnt->mConnInfo->IsHttp3()) {
+ if (dnsAndSock->mConnInfo->IsHttp3()) {
mState = TransportSetup::TransportSetupState::RESOLVED;
return status;
} else {
diff --git a/netwerk/protocol/http/DnsAndConnectSocket.h b/netwerk/protocol/http/DnsAndConnectSocket.h
index d94f32310ed1..2adec097b519 100644
--- a/netwerk/protocol/http/DnsAndConnectSocket.h
+++ b/netwerk/protocol/http/DnsAndConnectSocket.h
@@ -52,19 +52,17 @@ class DnsAndConnectSocket final : public nsIOutputStreamCallback,
NS_DECL_NSINAMED
NS_DECL_NSIDNSLISTENER
- DnsAndConnectSocket(ConnectionEntry* ent, nsAHttpTransaction* trans,
+ DnsAndConnectSocket(nsHttpConnectionInfo* ci, nsAHttpTransaction* trans,
uint32_t caps, bool speculative, bool isFromPredictor,
bool urgentStart);
- [[nodiscard]] nsresult Init();
+ [[nodiscard]] nsresult Init(ConnectionEntry* ent);
void Abandon();
double Duration(TimeStamp epoch);
void CloseTransports(nsresult error);
bool IsSpeculative() { return mSpeculative; }
- bool IsFromPredictor() { return mIsFromPredictor; }
-
bool Allow1918() { return mAllow1918; }
void SetAllow1918(bool val) { mAllow1918 = val; }
@@ -201,7 +199,7 @@ class DnsAndConnectSocket final : public nsIOutputStreamCallback,
bool removeWhenFound);
void CheckProxyConfig();
- nsresult SetupDnsFlags();
+ nsresult SetupDnsFlags(ConnectionEntry* ent);
nsresult SetupEvent(SetupEvents event);
RefPtr mTransaction;
@@ -242,7 +240,7 @@ class DnsAndConnectSocket final : public nsIOutputStreamCallback,
// transactions.
bool mFreeToUse = true;
- RefPtr mEnt;
+ RefPtr mConnInfo;
nsCOMPtr mSynTimer;
TransportSetup mBackupTransport;
diff --git a/netwerk/protocol/http/PendingTransactionInfo.cpp b/netwerk/protocol/http/PendingTransactionInfo.cpp
index 9de3fc8adb00..8c0f2561c91a 100644
--- a/netwerk/protocol/http/PendingTransactionInfo.cpp
+++ b/netwerk/protocol/http/PendingTransactionInfo.cpp
@@ -95,24 +95,18 @@ bool PendingTransactionInfo::IsAlreadyClaimedInitializingConn() {
return alreadyDnsAndSockOrWaitingForTLS;
}
-void PendingTransactionInfo::AbandonDnsAndConnectSocketAndForgetActiveConn() {
- // Abandon all DnsAndConnectSockets belonging to the given transaction.
- RefPtr dnsAndSock = do_QueryReferent(mDnsAndSock);
- if (dnsAndSock) {
- dnsAndSock->Abandon();
- }
+nsWeakPtr PendingTransactionInfo::ForgetDnsAndConnectSocketAndActiveConn() {
+ nsWeakPtr dnsAndSock = mDnsAndSock;
+
mDnsAndSock = nullptr;
mActiveConn = nullptr;
+ return dnsAndSock;
}
-bool PendingTransactionInfo::TryClaimingDnsAndConnectSocket(
+void PendingTransactionInfo::RememberDnsAndConnectSocket(
DnsAndConnectSocket* sock) {
- if (sock->Claim()) {
- mDnsAndSock =
- do_GetWeakReference(static_cast(sock));
- return true;
- }
- return false;
+ mDnsAndSock =
+ do_GetWeakReference(static_cast(sock));
}
bool PendingTransactionInfo::TryClaimingActiveConn(HttpConnectionBase* conn) {
diff --git a/netwerk/protocol/http/PendingTransactionInfo.h b/netwerk/protocol/http/PendingTransactionInfo.h
index 70d14d8af59f..863b43ae0350 100644
--- a/netwerk/protocol/http/PendingTransactionInfo.h
+++ b/netwerk/protocol/http/PendingTransactionInfo.h
@@ -24,11 +24,14 @@ class PendingTransactionInfo final : public ARefBase {
// a connection in TLS handshake phase.
bool IsAlreadyClaimedInitializingConn();
- void AbandonDnsAndConnectSocketAndForgetActiveConn();
+ // This function return a weak poointer to DnsAndConnectSocket.
+ // The pointer is used by the caller(ConnectionEntry) to remove the
+ // DnsAndConnectSocket from the internal list. PendingTransactionInfo
+ // cannot perform this opereation.
+ [[nodiscard]] nsWeakPtr ForgetDnsAndConnectSocketAndActiveConn();
- // Try to claim a halfOpen socket. We can only claim it if it is not
- // claimed yet.
- bool TryClaimingDnsAndConnectSocket(DnsAndConnectSocket* sock);
+ // Remember associated DnsAndConnectSocket.
+ void RememberDnsAndConnectSocket(DnsAndConnectSocket* sock);
// Similar as above, but for a ActiveConn that is performing a TLS handshake
// and has only a NullTransaction associated.
bool TryClaimingActiveConn(HttpConnectionBase* conn);
diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.cpp b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
index 416bd9228d3e..4bbcb3f10ed6 100644
--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
@@ -1232,15 +1232,15 @@ nsresult nsHttpConnectionMgr::MakeNewConnection(
if (AtActiveConnectionLimit(ent, trans->Caps()))
return NS_ERROR_NOT_AVAILABLE;
- nsresult rv =
- CreateTransport(ent, trans, trans->Caps(), false, false,
- trans->ClassOfService() & nsIClassOfService::UrgentStart,
- true, pendingTransInfo);
+ nsresult rv = ent->CreateDnsAndConnectSocket(
+ trans, trans->Caps(), false, false,
+ trans->ClassOfService() & nsIClassOfService::UrgentStart, true,
+ pendingTransInfo);
if (NS_FAILED(rv)) {
/* hard failure */
LOG(
("nsHttpConnectionMgr::MakeNewConnection [ci = %s trans = %p] "
- "CreateTransport() hard failure.\n",
+ "CreateDnsAndConnectSocket() hard failure.\n",
ent->mConnInfo->HashKey().get(), trans));
trans->Close(rv);
if (rv == NS_ERROR_NOT_AVAILABLE) rv = NS_ERROR_FAILURE;
@@ -1738,36 +1738,6 @@ void nsHttpConnectionMgr::RecvdConnect() {
ConditionallyStopTimeoutTick();
}
-nsresult nsHttpConnectionMgr::CreateTransport(
- ConnectionEntry* ent, nsAHttpTransaction* trans, uint32_t caps,
- bool speculative, bool isFromPredictor, bool urgentStart, bool allow1918,
- PendingTransactionInfo* pendingTransInfo) {
- MOZ_ASSERT(OnSocketThread(), "not on socket thread");
- MOZ_ASSERT((speculative && !pendingTransInfo) ||
- (!speculative && pendingTransInfo));
-
- RefPtr sock = new DnsAndConnectSocket(
- ent, trans, caps, speculative, isFromPredictor, urgentStart);
-
- if (speculative) {
- sock->SetAllow1918(allow1918);
- }
- // The socket stream holds the reference to the half open
- // socket - so if the stream fails to init the half open
- // will go away.
- nsresult rv = sock->Init();
- NS_ENSURE_SUCCESS(rv, rv);
-
- if (pendingTransInfo) {
- DebugOnly claimed =
- pendingTransInfo->TryClaimingDnsAndConnectSocket(sock);
- MOZ_ASSERT(claimed);
- }
-
- ent->InsertIntoDnsAndConnectSockets(sock);
- return NS_OK;
-}
-
void nsHttpConnectionMgr::DispatchSpdyPendingQ(
nsTArray>& pendingQ, ConnectionEntry* ent,
HttpConnectionBase* connH2, HttpConnectionBase* connH3) {
@@ -3298,7 +3268,7 @@ void nsHttpConnectionMgr::DoSpeculativeConnection(
Unused << aTrans->FetchHTTPSRR();
}
DebugOnly rv =
- CreateTransport(ent, aTrans, aTrans->Caps(), true, isFromPredictor,
+ ent->CreateDnsAndConnectSocket(aTrans, aTrans->Caps(), true, isFromPredictor,
false, allow1918, nullptr);
MOZ_ASSERT(NS_SUCCEEDED(rv));
} else {
@@ -3506,6 +3476,11 @@ nsHttpConnectionMgr::FindTransactionHelper(bool removeWhenFound,
return info.forget();
}
+already_AddRefed
+nsHttpConnectionMgr::FindConnectionEntry(const nsHttpConnectionInfo* ci) {
+ return mCT.Get(ci->HashKey());
+}
+
nsHttpConnectionMgr* nsHttpConnectionMgr::AsHttpConnectionMgr() { return this; }
HttpConnectionMgrParent* nsHttpConnectionMgr::AsHttpConnectionMgrParent() {
diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.h b/netwerk/protocol/http/nsHttpConnectionMgr.h
index 7f06bcb6ea7d..b567a5aacfb3 100644
--- a/netwerk/protocol/http/nsHttpConnectionMgr.h
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.h
@@ -171,6 +171,9 @@ class nsHttpConnectionMgr final : public HttpConnectionMgrShell,
already_AddRefed FindTransactionHelper(
bool removeWhenFound, ConnectionEntry* aEnt, nsAHttpTransaction* aTrans);
+ already_AddRefed FindConnectionEntry(
+ const nsHttpConnectionInfo* ci);
+
public:
static nsAHttpConnection* MakeConnectionHandle(HttpConnectionBase* aWrapped);
void RegisterOriginCoalescingKey(HttpConnectionBase*, const nsACString& host,
@@ -255,9 +258,6 @@ class nsHttpConnectionMgr final : public HttpConnectionMgrShell,
[[nodiscard]] nsresult ProcessNewTransaction(nsHttpTransaction*);
[[nodiscard]] nsresult EnsureSocketThreadTarget();
void ReportProxyTelemetry(ConnectionEntry* ent);
- [[nodiscard]] nsresult CreateTransport(
- ConnectionEntry*, nsAHttpTransaction*, uint32_t, bool, bool, bool, bool,
- PendingTransactionInfo* pendingTransInfo);
void StartedConnect();
void RecvdConnect();