mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-28 21:28:55 +00:00
bug 528288 spdy - only coalesce (i.e. ip pool) hostnames with compatible ssl certs sr=biesi r=honzab r=bsmith
patch 9
This commit is contained in:
parent
d7a9653123
commit
7b7e03e318
@ -51,6 +51,9 @@
|
||||
#include "nsIDNSService.h"
|
||||
#include "nsICancelable.h"
|
||||
|
||||
#include "nsISSLStatusProvider.h"
|
||||
#include "nsISSLStatus.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
// defined by the socket transport service while active
|
||||
@ -447,15 +450,22 @@ nsHttpConnectionMgr::ReportSpdyConnection(nsHttpConnection *conn,
|
||||
PRUint64 timeOfExpire = NowInSeconds() + ttl;
|
||||
if (!mTimer || timeOfExpire < mTimeOfNextWakeUp)
|
||||
PruneDeadConnectionsAfter(ttl);
|
||||
|
||||
nsConnectionEntry *preferred = GetSpdyPreferred(ent->mDottedDecimalAddress);
|
||||
|
||||
// Lookup preferred directly from the hash instead of using
|
||||
// GetSpdyPreferred() because we want to avoid the cert compatibility
|
||||
// check at this point because the cert is never part of the hash
|
||||
// lookup. Filtering on that has to be done at the time of use
|
||||
// rather than the time of registration (i.e. now).
|
||||
nsConnectionEntry *preferred =
|
||||
mSpdyPreferredHash.Get(ent->mDottedDecimalAddress);
|
||||
|
||||
LOG(("ReportSpdyConnection %s %s ent=%p ispreferred=%d\n",
|
||||
ent->mConnInfo->Host(), ent->mDottedDecimalAddress.get(),
|
||||
ent, preferred));
|
||||
|
||||
if (!preferred) {
|
||||
ent->mSpdyPreferred = true;
|
||||
SetSpdyPreferred(ent->mDottedDecimalAddress, ent);
|
||||
SetSpdyPreferred(ent);
|
||||
ent->mSpdyRedir = false;
|
||||
}
|
||||
else if (preferred != ent) {
|
||||
@ -464,6 +474,36 @@ nsHttpConnectionMgr::ReportSpdyConnection(nsHttpConnection *conn,
|
||||
ent->mSpdyRedir = true;
|
||||
conn->DontReuse();
|
||||
}
|
||||
|
||||
// If this is a preferred host for coalescing (aka ip pooling) then
|
||||
// keep a reference to the server SSL cert. This will be used as an
|
||||
// extra level of verification when deciding that
|
||||
// connections from other hostnames are redirected to the preferred host.
|
||||
//
|
||||
|
||||
// Even if mCert is already set update the reference in case the
|
||||
// reference is changing.
|
||||
ent->mCert = nsnull;
|
||||
|
||||
nsCOMPtr<nsISupports> securityInfo;
|
||||
nsCOMPtr<nsISSLStatusProvider> sslStatusProvider;
|
||||
nsCOMPtr<nsISSLStatus> sslStatus;
|
||||
nsCOMPtr<nsIX509Cert> cert;
|
||||
|
||||
conn->GetSecurityInfo(getter_AddRefs(securityInfo));
|
||||
if (securityInfo)
|
||||
sslStatusProvider = do_QueryInterface(securityInfo);
|
||||
|
||||
if (sslStatusProvider)
|
||||
sslStatusProvider->
|
||||
GetSSLStatus(getter_AddRefs(sslStatus));
|
||||
|
||||
if (sslStatus)
|
||||
sslStatus->GetServerCert(getter_AddRefs(cert));
|
||||
|
||||
if (cert)
|
||||
ent->mCert = do_QueryInterface(cert);
|
||||
|
||||
ProcessSpdyPendingQ();
|
||||
}
|
||||
|
||||
@ -534,27 +574,52 @@ nsHttpConnectionMgr::TrimAlternateProtocolHash(PLDHashTable *table,
|
||||
}
|
||||
|
||||
nsHttpConnectionMgr::nsConnectionEntry *
|
||||
nsHttpConnectionMgr::GetSpdyPreferred(nsACString &aDottedDecimal)
|
||||
nsHttpConnectionMgr::GetSpdyPreferred(nsConnectionEntry *aOriginalEntry)
|
||||
{
|
||||
if (!gHttpHandler->IsSpdyEnabled() ||
|
||||
!gHttpHandler->CoalesceSpdy() ||
|
||||
aDottedDecimal.IsEmpty())
|
||||
aOriginalEntry->mDottedDecimalAddress.IsEmpty())
|
||||
return nsnull;
|
||||
|
||||
return mSpdyPreferredHash.Get(aDottedDecimal);
|
||||
nsConnectionEntry *preferred =
|
||||
mSpdyPreferredHash.Get(aOriginalEntry->mDottedDecimalAddress);
|
||||
|
||||
if (preferred == aOriginalEntry)
|
||||
return aOriginalEntry; /* no redirection so no cert check required */
|
||||
|
||||
if (!preferred || !preferred->mCert)
|
||||
return nsnull; /* no ip pooling */
|
||||
|
||||
nsresult rv;
|
||||
bool validCert = false;
|
||||
|
||||
rv = preferred->mCert->IsValidForHostname(
|
||||
aOriginalEntry->mConnInfo->GetHost(), &validCert);
|
||||
|
||||
if (NS_FAILED(rv) || !validCert) {
|
||||
LOG(("nsHttpConnectionMgr::GetSpdyPreferredConnection "
|
||||
"Host %s has cert which cannot be confirmed to use "
|
||||
"with %s connections",
|
||||
preferred->mConnInfo->Host(), aOriginalEntry->mConnInfo->Host()));
|
||||
return nsnull; /* no ip pooling */
|
||||
}
|
||||
|
||||
LOG(("nsHttpConnectionMgr::GetSpdyPreferredConnection "
|
||||
"Host %s has cert valid for %s connections",
|
||||
preferred->mConnInfo->Host(), aOriginalEntry->mConnInfo->Host()));
|
||||
return preferred;
|
||||
}
|
||||
|
||||
void
|
||||
nsHttpConnectionMgr::SetSpdyPreferred(nsACString &aDottedDecimal,
|
||||
nsConnectionEntry *ent)
|
||||
nsHttpConnectionMgr::SetSpdyPreferred(nsConnectionEntry *ent)
|
||||
{
|
||||
if (!gHttpHandler->CoalesceSpdy())
|
||||
return;
|
||||
|
||||
if (aDottedDecimal.IsEmpty())
|
||||
if (ent->mDottedDecimalAddress.IsEmpty())
|
||||
return;
|
||||
|
||||
mSpdyPreferredHash.Put(aDottedDecimal, ent);
|
||||
mSpdyPreferredHash.Put(ent->mDottedDecimalAddress, ent);
|
||||
}
|
||||
|
||||
void
|
||||
@ -982,8 +1047,7 @@ nsHttpConnectionMgr::GetConnection(nsConnectionEntry *ent,
|
||||
ent->mConnInfo->UsingSSL() &&
|
||||
!ent->mConnInfo->UsingHttpProxy())
|
||||
{
|
||||
nsConnectionEntry *preferred =
|
||||
GetSpdyPreferred(ent->mDottedDecimalAddress);
|
||||
nsConnectionEntry *preferred = GetSpdyPreferred(ent);
|
||||
if (preferred)
|
||||
ent = preferred;
|
||||
|
||||
@ -1200,8 +1264,7 @@ nsHttpConnectionMgr::ProcessNewTransaction(nsHttpTransaction *trans)
|
||||
|
||||
// SPDY coalescing of hostnames means we might redirect from this
|
||||
// connection entry onto the preferred one.
|
||||
nsConnectionEntry *preferredEntry =
|
||||
GetSpdyPreferred(ent->mDottedDecimalAddress);
|
||||
nsConnectionEntry *preferredEntry = GetSpdyPreferred(ent);
|
||||
if (preferredEntry) {
|
||||
LOG(("nsHttpConnectionMgr::ProcessNewTransaction trans=%p "
|
||||
"redirected via coalescing from %s to %s\n", trans,
|
||||
@ -1294,7 +1357,7 @@ nsHttpConnectionMgr::GetSpdyPreferredConn(nsConnectionEntry *ent)
|
||||
NS_ABORT_IF_FALSE(PR_GetCurrentThread() == gSocketThread, "wrong thread");
|
||||
NS_ABORT_IF_FALSE(ent, "no connection entry");
|
||||
|
||||
nsConnectionEntry *preferred = GetSpdyPreferred(ent->mDottedDecimalAddress);
|
||||
nsConnectionEntry *preferred = GetSpdyPreferred(ent);
|
||||
|
||||
// this entry is spdy-enabled if it is a redirect to another spdy host
|
||||
if (preferred && preferred != ent) {
|
||||
|
@ -54,6 +54,7 @@
|
||||
|
||||
#include "nsIObserver.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsIX509Cert3.h"
|
||||
|
||||
class nsHttpPipeline;
|
||||
|
||||
@ -205,6 +206,7 @@ private:
|
||||
bool mSpdyRedir;
|
||||
bool mDidDNS;
|
||||
bool mSpdyPreferred;
|
||||
nsCOMPtr<nsIX509Cert3> mCert;
|
||||
};
|
||||
|
||||
// nsConnectionHandle
|
||||
@ -321,9 +323,8 @@ private:
|
||||
void RecvdConnect();
|
||||
|
||||
// Manage the preferred spdy connection entry for this address
|
||||
nsConnectionEntry *GetSpdyPreferred(nsACString &aDottedDecimal);
|
||||
void SetSpdyPreferred(nsACString &aDottedDecimal,
|
||||
nsConnectionEntry *ent);
|
||||
nsConnectionEntry *GetSpdyPreferred(nsConnectionEntry *aOriginalEntry);
|
||||
void SetSpdyPreferred(nsConnectionEntry *ent);
|
||||
void RemoveSpdyPreferred(nsACString &aDottedDecimal);
|
||||
nsHttpConnection *GetSpdyPreferredConn(nsConnectionEntry *ent);
|
||||
nsDataHashtable<nsCStringHashKey, nsConnectionEntry *> mSpdyPreferredHash;
|
||||
|
@ -43,7 +43,7 @@ interface nsICertVerificationListener;
|
||||
/**
|
||||
* Extending nsIX509Cert
|
||||
*/
|
||||
[scriptable, uuid(399004d8-b8c7-4eb9-8362-d99f4c0161fd)]
|
||||
[scriptable, uuid(09143cd9-dee3-4870-8450-8440c87e40e2)]
|
||||
interface nsIX509Cert3 : nsIX509Cert2 {
|
||||
|
||||
/**
|
||||
@ -88,6 +88,15 @@ interface nsIX509Cert3 : nsIX509Cert2 {
|
||||
void getAllTokenNames(out unsigned long length,
|
||||
[retval, array, size_is(length)] out wstring
|
||||
tokenNames);
|
||||
|
||||
/**
|
||||
* Determine if the certificate can be verified for specific host name
|
||||
*
|
||||
* @param aHostName the hostname to be verified
|
||||
* @return a boolean successful verification
|
||||
*/
|
||||
bool isValidForHostname(in AUTF8String aHostName);
|
||||
|
||||
};
|
||||
|
||||
[scriptable, uuid(2fd0a785-9f2d-4327-8871-8c3e0783891d)]
|
||||
|
@ -938,6 +938,26 @@ nsNSSCertificate::GetAllTokenNames(PRUint32 *aLength, PRUnichar*** aTokenNames)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSSCertificate::IsValidForHostname(const nsACString & aHostName,
|
||||
bool *retval)
|
||||
{
|
||||
*retval = false;
|
||||
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
if (isAlreadyShutDown())
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
if (!mCert)
|
||||
return NS_OK;
|
||||
|
||||
if (CERT_VerifyCertName(mCert,
|
||||
PromiseFlatCString(aHostName).get()) == SECSuccess)
|
||||
*retval = true;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSSCertificate::GetSubjectName(nsAString &_subjectName)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user