Bug 1356611 - per connection cache of JoinConnecton() r=nwgh

MozReview-Commit-ID: 6s0x9OWhhN1

--HG--
extra : rebase_source : 9edf046fbfb80ff3daed30c33c1679e190dfe660
This commit is contained in:
Patrick McManus 2017-04-14 17:24:53 -04:00
parent 671d7b719e
commit 748c661c7b
2 changed files with 56 additions and 45 deletions

View File

@ -89,6 +89,7 @@ Http2Session::Http2Session(nsISocketTransport *aSocketTransport, uint32_t versio
, mShouldGoAway(false)
, mClosed(false)
, mCleanShutdown(false)
, mReceivedSettings(false)
, mTLSProfileConfirmed(false)
, mGoAwayReason(NO_HTTP_ERROR)
, mClientGoAwayReason(UNASSIGNED)
@ -1504,6 +1505,8 @@ Http2Session::RecvSettings(Http2Session *self)
RETURN_SESSION_ERROR(self, PROTOCOL_ERROR);
}
self->mReceivedSettings = true;
uint32_t numEntries = self->mInputFrameDataSize / 6;
LOG3(("Http2Session::RecvSettings %p SETTINGS Control Frame "
"with %d entries ack=%X", self, numEntries,
@ -4153,49 +4156,20 @@ Http2Session::TestOriginFrame(const nsACString &hostname, int32_t port)
bool
Http2Session::TestJoinConnection(const nsACString &hostname, int32_t port)
{
if (!mConnection || mClosed || mShouldGoAway) {
return false;
}
if (mOriginFrameActivated) {
bool originFrameResult = TestOriginFrame(hostname, port);
if (!originFrameResult) {
return false;
}
} else {
LOG3(("TestJoinConnection %p no origin frame check used.\n", this));
}
nsresult rv;
bool isJoined = false;
nsCOMPtr<nsISupports> securityInfo;
nsCOMPtr<nsISSLSocketControl> sslSocketControl;
mConnection->GetSecurityInfo(getter_AddRefs(securityInfo));
sslSocketControl = do_QueryInterface(securityInfo, &rv);
if (NS_FAILED(rv) || !sslSocketControl) {
return false;
}
// try all the coalescable versions we support.
const SpdyInformation *info = gHttpHandler->SpdyInfo();
for (uint32_t index = SpdyInformation::kCount; index > 0; --index) {
if (info->ProtocolEnabled(index - 1)) {
rv = sslSocketControl->TestJoinConnection(info->VersionString[index - 1],
hostname, port, &isJoined);
if (NS_SUCCEEDED(rv) && isJoined) {
return true;
}
}
}
return false;
return RealJoinConnection(hostname, port, true);
}
bool
Http2Session::JoinConnection(const nsACString &hostname, int32_t port)
{
if (!mConnection || mClosed || mShouldGoAway) {
return RealJoinConnection(hostname, port, false);
}
bool
Http2Session::RealJoinConnection(const nsACString &hostname, int32_t port,
bool justKidding)
{
if (!mConnection || mClosed || mShouldGoAway || !mReceivedSettings) {
return false;
}
if (mOriginFrameActivated) {
@ -4207,6 +4181,18 @@ Http2Session::JoinConnection(const nsACString &hostname, int32_t port)
LOG3(("JoinConnection %p no origin frame check used.\n", this));
}
nsAutoCString key(hostname);
key.Append(':');
key.Append(justKidding ? 'k' : '.');
key.AppendInt(port);
bool cachedResult;
if (mJoinConnectionCache.Get(key, &cachedResult)) {
LOG(("joinconnection [%p %s] %s result=%d cache\n",
this, ConnectionInfo()->HashKey().get(), key.get(),
cachedResult));
return cachedResult;
}
nsresult rv;
bool isJoined = false;
@ -4221,16 +4207,35 @@ Http2Session::JoinConnection(const nsACString &hostname, int32_t port)
// try all the coalescable versions we support.
const SpdyInformation *info = gHttpHandler->SpdyInfo();
for (uint32_t index = SpdyInformation::kCount; index > 0; --index) {
if (info->ProtocolEnabled(index - 1)) {
rv = sslSocketControl->JoinConnection(info->VersionString[index - 1],
static_assert(SpdyInformation::kCount == 1, "assume 1 alpn version");
bool joinedReturn = false;
if (info->ProtocolEnabled(0)) {
if (justKidding) {
rv = sslSocketControl->TestJoinConnection(info->VersionString[0],
hostname, port, &isJoined);
} else {
rv = sslSocketControl->JoinConnection(info->VersionString[0],
hostname, port, &isJoined);
if (NS_SUCCEEDED(rv) && isJoined) {
return true;
}
}
if (NS_SUCCEEDED(rv) && isJoined) {
joinedReturn = true;
}
}
return false;
LOG(("joinconnection [%p %s] %s result=%d lookup\n",
this, ConnectionInfo()->HashKey().get(), key.get(), joinedReturn));
mJoinConnectionCache.Put(key, joinedReturn);
if (!justKidding) {
// cache a kidding entry too as this one is good for both
nsAutoCString key2(hostname);
key2.Append(':');
key2.Append('k');
key2.AppendInt(port);
if (!mJoinConnectionCache.Get(key2)) {
mJoinConnectionCache.Put(key2, joinedReturn);
}
}
return joinedReturn;
}
void

View File

@ -427,6 +427,9 @@ private:
// the session received a GoAway frame with a valid GoAwayID
bool mCleanShutdown;
// the session received the opening SETTINGS frame from the server
bool mReceivedSettings;
// The TLS comlpiance checks are not done in the ctor beacuse of bad
// exception handling - so we do them at IO time and cache the result
bool mTLSProfileConfirmed;
@ -518,10 +521,13 @@ private:
// The ID(s) of the stream(s) that we are getting 0RTT data from.
nsTArray<uint32_t> m0RTTStreams;
bool RealJoinConnection(const nsACString &hostname, int32_t port, bool jk);
bool TestOriginFrame(const nsACString &name, int32_t port);
bool mOriginFrameActivated;
nsDataHashtable<nsCStringHashKey, bool> mOriginFrame;
nsDataHashtable<nsCStringHashKey, bool> mJoinConnectionCache;
private:
/// connect tunnels
void DispatchOnTunnel(nsAHttpTransaction *, nsIInterfaceRequestor *);