bug 1153212 - Alt-Svc Fixes r=dkeeler r=hurley

This commit is contained in:
Patrick McManus 2015-04-13 17:11:59 -04:00
parent 0fa4117285
commit d428323d51
4 changed files with 117 additions and 23 deletions

View File

@ -63,6 +63,9 @@ public:
const nsCString &GetAuthenticationHost() const { return mAuthenticationHost; }
int32_t GetAuthenticationPort() const { return mAuthenticationPort; }
const nsCString &GetOrigin() const { return mAuthenticationHost.IsEmpty() ? mHost : mAuthenticationHost; }
int32_t OriginPort() const { return mAuthenticationHost.IsEmpty() ? mPort : mAuthenticationPort; }
// With overhead rebuilding the hash key. The initial
// network interface is empty. So you can reduce one call
// if there's no explicit route after ctor.

View File

@ -880,8 +880,8 @@ nsHttpConnectionMgr::GetSpdyPreferredEnt(nsConnectionEntry *aOriginalEntry)
NS_SUCCEEDED(rv) && index > 0; --index) {
if (info->ProtocolEnabled(index - 1)) {
rv = sslSocketControl->JoinConnection(info->VersionString[index - 1],
aOriginalEntry->mConnInfo->GetHost(),
aOriginalEntry->mConnInfo->Port(),
aOriginalEntry->mConnInfo->GetOrigin(),
aOriginalEntry->mConnInfo->OriginPort(),
&isJoined);
if (NS_SUCCEEDED(rv) && isJoined) {
break;

View File

@ -194,8 +194,16 @@ nsNSSSocketInfo::GetBypassAuthentication(bool* arg)
NS_IMETHODIMP
nsNSSSocketInfo::SetBypassAuthentication(bool arg)
{
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown()) {
return NS_ERROR_NOT_AVAILABLE;
}
if (!mFd) {
return NS_ERROR_FAILURE;
}
mBypassAuthentication = arg;
return NS_OK;
return SyncNSSNames(locker);
}
NS_IMETHODIMP
@ -215,7 +223,25 @@ nsNSSSocketInfo::GetAuthenticationName(nsACString& aAuthenticationName)
NS_IMETHODIMP
nsNSSSocketInfo::SetAuthenticationName(const nsACString& aAuthenticationName)
{
return SetHostName(PromiseFlatCString(aAuthenticationName).get());
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown()) {
return NS_ERROR_NOT_AVAILABLE;
}
if (!mFd) {
return NS_ERROR_FAILURE;
}
nsCString authenticationName(aAuthenticationName);
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
("[%p] nsNSSSocketInfo::SetAuthenticationName change from %s to %s\n",
mFd, PromiseFlatCString(GetHostName()).get(),
authenticationName.get()));
nsresult rv = SetHostName(authenticationName.get());
if (NS_FAILED(rv)) {
return rv;
}
return SyncNSSNames(locker);
}
NS_IMETHODIMP
@ -227,7 +253,19 @@ nsNSSSocketInfo::GetAuthenticationPort(int32_t* aAuthenticationPort)
NS_IMETHODIMP
nsNSSSocketInfo::SetAuthenticationPort(int32_t aAuthenticationPort)
{
return SetPort(aAuthenticationPort);
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown()) {
return NS_ERROR_NOT_AVAILABLE;
}
if (!mFd) {
return NS_ERROR_FAILURE;
}
nsresult rv = SetPort(aAuthenticationPort);
if (NS_FAILED(rv)) {
return rv;
}
return SyncNSSNames(locker);
}
NS_IMETHODIMP
@ -266,6 +304,36 @@ nsNSSSocketInfo::SetNotificationCallbacks(nsIInterfaceRequestor* aCallbacks)
return NS_OK;
}
// forward declare this for SyncNSSNames()
static nsresult
nsSSLIOLayerSetPeerName(PRFileDesc* fd, nsNSSSocketInfo* infoObject,
const char* host, int32_t port,
const nsNSSShutDownPreventionLock& /* proofOfLock */);
nsresult
nsNSSSocketInfo::SyncNSSNames(const nsNSSShutDownPreventionLock& proofOfLock)
{
// I don't know why any of these calls would fail, but if they do
// we need to call SetCanceled to avoid non-determinstic results
const char* hostName = GetHostNameRaw();
if (SECSuccess != SSL_SetURL(mFd, hostName)) {
PR_LOG(gPIPNSSLog, PR_LOG_ERROR, ("[%p] SyncNSSNames SSL_SetURL error: %d\n",
(void*) mFd, PR_GetError()));
SetCanceled(PR_INVALID_STATE_ERROR, PlainErrorMessage);
return NS_ERROR_FAILURE;
}
int32_t port = GetPort();
if (NS_FAILED(nsSSLIOLayerSetPeerName(mFd, this, hostName, port, proofOfLock))) {
PR_LOG(gPIPNSSLog, PR_LOG_ERROR, ("[%p] SyncNSSNames SetPeerName error: %d\n",
(void*) mFd, PR_GetError()));
SetCanceled(PR_INVALID_STATE_ERROR, PlainErrorMessage);
return NS_ERROR_FAILURE;
}
return NS_OK;
}
void
nsNSSSocketInfo::NoteTimeUntilReady()
{
@ -445,6 +513,12 @@ nsNSSSocketInfo::JoinConnection(const nsACString& npnProtocol,
if (!mNPNCompleted || !mNegotiatedNPN.Equals(npnProtocol))
return NS_OK;
if (mBypassAuthentication) {
// An unauthenticated connection does not know whether or not it
// is acceptable for a particular hostname
return NS_OK;
}
IsAcceptableForHost(hostname, _retval);
if (*_retval) {
@ -2520,12 +2594,45 @@ loser:
return nullptr;
}
static nsresult
nsSSLIOLayerSetPeerName(PRFileDesc* fd, nsNSSSocketInfo* infoObject,
const char* host, int32_t port,
const nsNSSShutDownPreventionLock& /*proofOfLock*/)
{
// Set the Peer ID so that SSL proxy connections work properly and to
// separate anonymous and/or private browsing connections.
uint32_t flags = infoObject->GetProviderFlags();
nsAutoCString peerId;
if (flags & nsISocketProvider::ANONYMOUS_CONNECT) { // See bug 466080
peerId.AppendLiteral("anon:");
}
if (flags & nsISocketProvider::NO_PERMANENT_STORAGE) {
peerId.AppendLiteral("private:");
}
if (infoObject->GetBypassAuthentication()) {
peerId.AppendLiteral("bypassAuth:");
}
peerId.Append(host);
peerId.Append(':');
peerId.AppendInt(port);
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
("[%p] nsSSLIOLayerSetPeerName to %s\n", fd, peerId.get()));
if (SECSuccess != SSL_SetSockPeerID(fd, peerId.get())) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
static nsresult
nsSSLIOLayerSetOptions(PRFileDesc* fd, bool forSTARTTLS,
const char* proxyHost, const char* host, int32_t port,
nsNSSSocketInfo* infoObject)
{
nsNSSShutDownPreventionLock locker;
if (infoObject->isAlreadyShutDown()) {
return NS_ERROR_NOT_AVAILABLE;
}
if (forSTARTTLS || proxyHost) {
if (SECSuccess != SSL_OptionSet(fd, SSL_SECURITY, false)) {
return NS_ERROR_FAILURE;
@ -2576,24 +2683,7 @@ nsSSLIOLayerSetOptions(PRFileDesc* fd, bool forSTARTTLS,
return NS_ERROR_FAILURE;
}
// Set the Peer ID so that SSL proxy connections work properly and to
// separate anonymous and/or private browsing connections.
uint32_t flags = infoObject->GetProviderFlags();
nsAutoCString peerId;
if (flags & nsISocketProvider::ANONYMOUS_CONNECT) { // See bug 466080
peerId.AppendLiteral("anon:");
}
if (flags & nsISocketProvider::NO_PERMANENT_STORAGE) {
peerId.AppendLiteral("private:");
}
peerId.Append(host);
peerId.Append(':');
peerId.AppendInt(port);
if (SECSuccess != SSL_SetSockPeerID(fd, peerId.get())) {
return NS_ERROR_FAILURE;
}
return NS_OK;
return nsSSLIOLayerSetPeerName(fd, infoObject, host, port, locker);
}
nsresult

View File

@ -136,6 +136,7 @@ private:
bool mPreliminaryHandshakeDone; // after false start items are complete
nsresult ActivateSSL();
nsresult SyncNSSNames(const nsNSSShutDownPreventionLock& proofOfLock);
nsCString mNegotiatedNPN;
bool mNPNCompleted;