2018-05-29 15:24:12 +08:00
parent 71768ddd07
commit d115a1d7ad
13 changed files with 351 additions and 30 deletions
+9 -7
View File
@@ -893,13 +893,15 @@ typedef struct
#define ERROR(key, val) {key, #key}
ErrorEntry socketTransportStatuses[] = {
ERROR(NS_NET_STATUS_RESOLVING_HOST, FAILURE(3)),
ERROR(NS_NET_STATUS_RESOLVED_HOST, FAILURE(11)),
ERROR(NS_NET_STATUS_CONNECTING_TO, FAILURE(7)),
ERROR(NS_NET_STATUS_CONNECTED_TO, FAILURE(4)),
ERROR(NS_NET_STATUS_SENDING_TO, FAILURE(5)),
ERROR(NS_NET_STATUS_WAITING_FOR, FAILURE(10)),
ERROR(NS_NET_STATUS_RECEIVING_FROM, FAILURE(6)),
ERROR(NS_NET_STATUS_RESOLVING_HOST, FAILURE(3)),
ERROR(NS_NET_STATUS_RESOLVED_HOST, FAILURE(11)),
ERROR(NS_NET_STATUS_CONNECTING_TO, FAILURE(7)),
ERROR(NS_NET_STATUS_CONNECTED_TO, FAILURE(4)),
ERROR(NS_NET_STATUS_TLS_HANDSHAKE_STARTING, FAILURE(12)),
ERROR(NS_NET_STATUS_TLS_HANDSHAKE_ENDED, FAILURE(13)),
ERROR(NS_NET_STATUS_SENDING_TO, FAILURE(5)),
ERROR(NS_NET_STATUS_WAITING_FOR, FAILURE(10)),
ERROR(NS_NET_STATUS_RECEIVING_FROM, FAILURE(6)),
};
#undef ERROR
+1
View File
@@ -7,6 +7,7 @@ pref("security.tls.version.max", 3);
pref("security.tls.version.fallback-limit", 3);
pref("security.tls.insecure_fallback_hosts", "");
pref("security.tls.unrestricted_rc4_fallback", false);
pref("security.tls.enable_0rtt_data", false);
pref("security.ssl.treat_unsafe_negotiation_as_broken", false);
pref("security.ssl.require_safe_negotiation", false);
@@ -204,6 +204,22 @@ public:
virtual void DisableSpdy() { }
virtual void ReuseConnectionOnRestartOK(bool) { }
// Returns true if early-data is possible.
virtual bool Do0RTT() {
return false;
}
// This function will be called when a tls handshake has been finished and
// we know whether early-data that was sent has been accepted or not, e.g.
// do we need to restart a transaction. This will be called only if Do0RTT
// returns true.
// If aRestart parameter is true we need to restart the transaction,
// otherwise the erly-data has been accepted and we can continue the
// transaction.
// The function will return success or failure of the transaction restart.
virtual nsresult Finish0RTT(bool aRestart) {
return NS_ERROR_NOT_IMPLEMENTED;
}
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsAHttpTransaction, NS_AHTTPTRANSACTION_IID)
+121 -13
View File
@@ -79,6 +79,9 @@ nsHttpConnection::nsHttpConnection()
, mResponseTimeoutEnabled(false)
, mTCPKeepaliveConfig(kTCPKeepaliveDisabled)
, mForceSendPending(false)
, m0RTTChecked(false)
, mWaitingFor0RTTResponse(false)
, mContentBytesWritten0RTT(0)
{
LOG(("Creating nsHttpConnection @%p\n", this));
@@ -268,8 +271,12 @@ nsHttpConnection::StartSpdy(uint8_t spdyVersion)
}
bool
nsHttpConnection::EnsureNPNComplete()
nsHttpConnection::EnsureNPNComplete(nsresult &aOut0RTTWriteHandshakeValue,
uint32_t &aOut0RTTBytesWritten)
{
aOut0RTTWriteHandshakeValue = NS_OK;
aOut0RTTBytesWritten = 0;
// If for some reason the components to check on NPN aren't available,
// this function will just return true to continue on and disable SPDY
@@ -294,16 +301,81 @@ nsHttpConnection::EnsureNPNComplete()
goto npnComplete;
}
if (!m0RTTChecked) {
// We reuse m0RTTChecked. We want to send this status only once.
mTransaction->OnTransportStatus(mSocketTransport,
NS_NET_STATUS_TLS_HANDSHAKE_STARTING,
0);
}
ssl = do_QueryInterface(securityInfo, &rv);
if (NS_FAILED(rv))
goto npnComplete;
rv = ssl->GetNegotiatedNPN(negotiatedNPN);
if (!m0RTTChecked && (rv == NS_ERROR_NOT_CONNECTED) &&
!mConnInfo->UsingProxy()) {
// There is no ALPN info (yet!). We need to consider doing 0RTT. We
// will do so if there is ALPN information from a previous session
// (AlpnEarlySelection), we are using HTTP/1, and the request data can
// be safely retried.
m0RTTChecked = true;
nsAutoCString earlyNegotiatedNPN;
nsresult rvEarlyAlpn = ssl->GetAlpnEarlySelection(earlyNegotiatedNPN);
if (NS_FAILED(rvEarlyAlpn)) {
// if ssl->DriveHandshake() has never been called the value
// for AlpnEarlySelection is still not set. So call it here and
// check again.
LOG(("nsHttpConnection::EnsureNPNComplete %p - "
"early selected alpn not available, we will try one more time.",
this));
// Let's do DriveHandshake again.
rv = ssl->DriveHandshake();
if (NS_FAILED(rv) && rv != NS_BASE_STREAM_WOULD_BLOCK) {
goto npnComplete;
}
// Check NegotiatedNPN first.
rv = ssl->GetNegotiatedNPN(negotiatedNPN);
if (rv == NS_ERROR_NOT_CONNECTED) {
rvEarlyAlpn = ssl->GetAlpnEarlySelection(earlyNegotiatedNPN);
}
}
if (NS_FAILED(rvEarlyAlpn)) {
LOG(("nsHttpConnection::EnsureNPNComplete %p - "
"early selected alpn not available", this));
} else {
LOG(("nsHttpConnection::EnsureNPNComplete %p -"
"early selected alpn: %s", this, earlyNegotiatedNPN.get()));
uint32_t infoIndex;
const SpdyInformation *info = gHttpHandler->SpdyInfo();
// We are doing 0RTT only with Http/1 right now!
if (NS_FAILED(info->GetNPNIndex(earlyNegotiatedNPN, &infoIndex))) {
// Check if early-data is allowed for this transaction.
if (mTransaction->Do0RTT()) {
LOG(("nsHttpConnection::EnsureNPNComplete [this=%p] - We "
"can do 0RTT!", this));
mWaitingFor0RTTResponse = true;
}
}
}
}
if (rv == NS_ERROR_NOT_CONNECTED) {
// By writing 0 bytes to the socket the SSL handshake machine is
// pushed forward.
uint32_t count = 0;
rv = mSocketOut->Write("", 0, &count);
if (mWaitingFor0RTTResponse) {
aOut0RTTWriteHandshakeValue = mTransaction->ReadSegments(this,
nsIOService::gDefaultSegmentSize, &aOut0RTTBytesWritten);
if (NS_FAILED(aOut0RTTWriteHandshakeValue) &&
aOut0RTTWriteHandshakeValue != NS_BASE_STREAM_WOULD_BLOCK) {
goto npnComplete;
}
LOG(("nsHttpConnection::EnsureNPNComplete [this=%p] - written %d "
"bytes during 0RTT", this, aOut0RTTBytesWritten));
mContentBytesWritten0RTT += aOut0RTTBytesWritten;
}
rv = ssl->DriveHandshake();
if (NS_FAILED(rv) && rv != NS_BASE_STREAM_WOULD_BLOCK) {
goto npnComplete;
}
@@ -316,10 +388,30 @@ nsHttpConnection::EnsureNPNComplete()
this, mConnInfo->HashKey().get(), negotiatedNPN.get(),
mTLSFilter ? " [Double Tunnel]" : ""));
uint32_t infoIndex;
const SpdyInformation *info = gHttpHandler->SpdyInfo();
if (NS_SUCCEEDED(info->GetNPNIndex(negotiatedNPN, &infoIndex))) {
StartSpdy(info->Version[infoIndex]);
bool ealyDataAccepted = false;
if (mWaitingFor0RTTResponse) {
mWaitingFor0RTTResponse = false;
// Check if early data has been accepted.
rv = ssl->GetEarlyDataAccepted(&ealyDataAccepted);
LOG(("nsHttpConnection::EnsureNPNComplete [this=%p] - early data "
"that was sent during 0RTT %s been accepted.",
this, ealyDataAccepted ? "has" : "has not"));
if (NS_FAILED(rv) ||
NS_FAILED(mTransaction->Finish0RTT(!ealyDataAccepted))) {
mTransaction->Close(NS_ERROR_NET_RESET);
goto npnComplete;
}
}
if (!ealyDataAccepted) {
uint32_t infoIndex;
const SpdyInformation *info = gHttpHandler->SpdyInfo();
if (NS_SUCCEEDED(info->GetNPNIndex(negotiatedNPN, &infoIndex))) {
StartSpdy(info->Version[infoIndex]);
}
} else {
LOG(("nsHttpConnection::EnsureNPNComplete [this=%p] - %d bytes "
"has been sent during 0RTT.", this, mContentBytesWritten0RTT));
mContentBytesWritten = mContentBytesWritten0RTT;
}
Telemetry::Accumulate(Telemetry::SPDY_NPN_CONNECT, UsingSpdy());
@@ -328,6 +420,17 @@ nsHttpConnection::EnsureNPNComplete()
npnComplete:
LOG(("nsHttpConnection::EnsureNPNComplete setting complete to true"));
mNPNComplete = true;
mTransaction->OnTransportStatus(mSocketTransport,
NS_NET_STATUS_TLS_HANDSHAKE_ENDED,
0);
if (mWaitingFor0RTTResponse) {
mWaitingFor0RTTResponse = false;
if (NS_FAILED(mTransaction->Finish0RTT(true))) {
mTransaction->Close(NS_ERROR_NET_RESET);
}
mContentBytesWritten0RTT = 0;
}
return true;
}
@@ -1572,7 +1675,9 @@ nsHttpConnection::OnSocketWritable()
// request differently for http/1, http/2, spdy, etc.. and that is
// negotiated with NPN/ALPN in the SSL handshake.
if (mConnInfo->UsingHttpsProxy() && !EnsureNPNComplete()) {
if (mConnInfo->UsingHttpsProxy() &&
!EnsureNPNComplete(rv, transactionBytes)) {
MOZ_ASSERT(!transactionBytes);
mSocketOutCondition = NS_BASE_STREAM_WOULD_BLOCK;
} else if (mProxyConnectStream) {
// If we're need an HTTP/1 CONNECT tunnel through a proxy
@@ -1581,8 +1686,11 @@ nsHttpConnection::OnSocketWritable()
rv = mProxyConnectStream->ReadSegments(ReadFromStream, this,
nsIOService::gDefaultSegmentSize,
&transactionBytes);
} else if (!EnsureNPNComplete()) {
mSocketOutCondition = NS_BASE_STREAM_WOULD_BLOCK;
} else if (!EnsureNPNComplete(rv, transactionBytes)) {
if (NS_SUCCEEDED(rv) && !transactionBytes &&
NS_SUCCEEDED(mSocketOutCondition)) {
mSocketOutCondition = NS_BASE_STREAM_WOULD_BLOCK;
}
} else {
// for non spdy sessions let the connection manager know
@@ -1630,7 +1738,7 @@ nsHttpConnection::OnSocketWritable()
} else if (!transactionBytes) {
rv = NS_OK;
if (mTransaction) { // in case the ReadSegments stack called CloseTransaction()
if (mTransaction && !mWaitingFor0RTTResponse) { // in case the ReadSegments stack called CloseTransaction()
//
// at this point we've written out the entire transaction, and now we
// must wait for the server's response. we manufacture a status message
+13 -1
View File
@@ -241,7 +241,8 @@ private:
// Makes certain the SSL handshake is complete and NPN negotiation
// has had a chance to happen
bool EnsureNPNComplete();
bool EnsureNPNComplete(nsresult &aOut0RTTWriteHandshakeValue,
uint32_t &aOut0RTTBytesWritten);
void SetupSSL();
// Start the Spdy transaction handler when NPN indicates spdy/*
@@ -350,6 +351,17 @@ private:
uint32_t mTCPKeepaliveConfig;
nsCOMPtr<nsITimer> mTCPKeepaliveTransitionTimer;
// Helper variable for 0RTT handshake;
bool m0RTTChecked; // Possible 0RTT has been
// checked.
bool mWaitingFor0RTTResponse; // We have are
// sending 0RTT
// data and we
// are waiting
// for the end of
// the handsake.
int64_t mContentBytesWritten0RTT;
private:
// For ForceSend()
static void ForceSendIO(nsITimer *aTimer, void *aClosure);
+80 -2
View File
@@ -139,6 +139,8 @@ nsHttpTransaction::nsHttpTransaction()
, mAppId(NECKO_NO_APP_ID)
, mIsInBrowser(false)
, mClassOfService(0)
, m0RTTInProgress(false)
, mTransportStatus(NS_OK)
{
LOG(("Creating nsHttpTransaction @%p\n", this));
gHttpHandler->GetMaxPipelineObjectSize(&mMaxPipelineObjectSize);
@@ -529,6 +531,50 @@ nsHttpTransaction::OnTransportStatus(nsITransport* transport,
}
}
// A transaction can given to multiple HalfOpen sockets (this is a bug in
// nsHttpConnectionMgr). We are going to fix it here as a work around to be
// able to uplift it.
switch(status) {
case NS_NET_STATUS_RESOLVING_HOST:
if (mTransportStatus != NS_OK) {
LOG(("nsHttpTransaction::OnSocketStatus - ignore socket events "
"from backup transport"));
return;
}
break;
case NS_NET_STATUS_RESOLVED_HOST:
if (mTransportStatus != NS_NET_STATUS_RESOLVING_HOST &&
mTransportStatus != NS_OK) {
LOG(("nsHttpTransaction::OnSocketStatus - ignore socket events "
"from backup transport"));
return;
}
break;
case NS_NET_STATUS_CONNECTING_TO:
if (mTransportStatus != NS_NET_STATUS_RESOLVING_HOST &&
mTransportStatus != NS_NET_STATUS_RESOLVED_HOST &&
mTransportStatus != NS_OK) {
LOG(("nsHttpTransaction::OnSocketStatus - ignore socket events "
"from backup transport"));
return;
}
break;
case NS_NET_STATUS_CONNECTED_TO:
if (mTransportStatus != NS_NET_STATUS_RESOLVING_HOST &&
mTransportStatus != NS_NET_STATUS_RESOLVED_HOST &&
mTransportStatus != NS_NET_STATUS_CONNECTING_TO &&
mTransportStatus != NS_OK) {
LOG(("nsHttpTransaction::OnSocketStatus - ignore socket events "
"from backup transport"));
return;
}
break;
default:
LOG(("nsHttpTransaction::OnSocketStatus - a new event"));
}
mTransportStatus = status;
// If the timing is enabled, and we are not using a persistent connection
// then the requestStart timestamp will be null, so we mark the timestamps
// for domainLookupStart/End and connectStart/End
@@ -542,7 +588,9 @@ nsHttpTransaction::OnTransportStatus(nsITransport* transport,
} else if (status == NS_NET_STATUS_CONNECTING_TO) {
SetConnectStart(TimeStamp::Now());
} else if (status == NS_NET_STATUS_CONNECTED_TO) {
SetConnectEnd(TimeStamp::Now());
SetConnectEnd(TimeStamp::Now(), true);
} else if (status == NS_NET_STATUS_TLS_HANDSHAKE_ENDED) {
SetConnectEnd(TimeStamp::Now(), false);
}
}
@@ -687,7 +735,7 @@ nsHttpTransaction::ReadSegments(nsAHttpSegmentReader *reader,
return mStatus;
}
if (!mConnected) {
if (!mConnected && !m0RTTInProgress) {
mConnected = true;
mConnection->GetSecurityInfo(getter_AddRefs(mSecurityInfo));
}
@@ -1271,6 +1319,8 @@ nsHttpTransaction::Restart()
}
}
mTransportStatus = NS_OK;
return gHttpHandler->InitiateTransaction(this, mPriority);
}
@@ -2304,5 +2354,33 @@ nsHttpTransaction::GetNetworkAddresses(NetAddr &self, NetAddr &peer)
peer = mPeerAddr;
}
bool
nsHttpTransaction::Do0RTT()
{
if (mRequestHead->IsSafeMethod() &&
!mConnection->IsProxyConnectInProgress()) {
m0RTTInProgress = true;
}
return m0RTTInProgress;
}
nsresult
nsHttpTransaction::Finish0RTT(bool aRestart)
{
MOZ_ASSERT(m0RTTInProgress);
m0RTTInProgress = false;
if (aRestart) {
// Reset request headers to be sent again.
nsCOMPtr<nsISeekableStream> seekable =
do_QueryInterface(mRequestStream);
if (seekable) {
seekable->Seek(nsISeekableStream::NS_SEEK_SET, 0);
} else {
return NS_ERROR_FAILURE;
}
}
return NS_OK;
}
} // namespace net
} // namespace mozilla
@@ -164,6 +164,8 @@ public:
int64_t GetTransferSize() { return mTransferSize; }
bool Do0RTT() override;
nsresult Finish0RTT(bool aRestart) override;
private:
friend class DeleteHttpTransaction;
virtual ~nsHttpTransaction();
@@ -451,6 +453,10 @@ public:
private:
RefPtr<ASpdySession> mTunnelProvider;
bool m0RTTInProgress;
nsresult mTransportStatus;
public:
void GetNetworkAddresses(NetAddr &self, NetAddr &peer);
+16
View File
@@ -44,6 +44,22 @@ interface nsISSLSocketControl : nsISupports {
*/
readonly attribute ACString negotiatedNPN;
/* For 0RTT we need to know the alpn protocol selected for the last tls
* session. This function will return a value if applicable or an error
* NS_ERROR_NOT_AVAILABLE.
*/
ACString getAlpnEarlySelection();
/* If 0RTT handshake was applied and some data has been sent, as soon as
* the handshake finishes this attribute will be set to appropriate value.
*/
readonly attribute bool earlyDataAccepted;
/* When 0RTT is performed, PR_Write will not drive the handshake forward.
* It must be forced by calling this function.
*/
void driveHandshake();
/* Determine if a potential SSL connection to hostname:port with
* a desired NPN negotiated protocol of npnProtocol can use the socket
* associated with this object instead of making a new one.
+1
View File
@@ -887,6 +887,7 @@ PreliminaryHandshakeDone(PRFileDesc* fd)
SSLChannelInfo channelInfo;
if (SSL_GetChannelInfo(fd, &channelInfo, sizeof(channelInfo)) == SECSuccess) {
infoObject->SetSSLVersionUsed(channelInfo.protocolVersion);
infoObject->SetEarlyDataAccepted(channelInfo.earlyDataAccepted);
SSLCipherSuiteInfo cipherInfo;
if (SSL_GetCipherSuiteInfo(channelInfo.cipherSuite, &cipherInfo,
+9
View File
@@ -726,6 +726,7 @@ static const bool REQUIRE_SAFE_NEGOTIATION_DEFAULT = false;
static const bool FALSE_START_ENABLED_DEFAULT = true;
static const bool NPN_ENABLED_DEFAULT = true;
static const bool ALPN_ENABLED_DEFAULT = false;
static const bool ENABLED_0RTT_DATA_DEFAULT = false;
static void
ConfigureTLSSessionIdentifiers()
@@ -1086,6 +1087,10 @@ nsNSSComponent::InitializeNSS()
Preferences::GetBool("security.ssl.enable_alpn",
ALPN_ENABLED_DEFAULT));
SSL_OptionSetDefault(SSL_ENABLE_0RTT_DATA,
Preferences::GetBool("security.tls.enable_0rtt_data",
ENABLED_0RTT_DATA_DEFAULT));
if (NS_FAILED(InitializeCipherSuite())) {
MOZ_LOG(gPIPNSSLog, LogLevel::Error, ("Unable to initialize cipher suite settings\n"));
return NS_ERROR_FAILURE;
@@ -1300,6 +1305,10 @@ nsNSSComponent::Observe(nsISupports* aSubject, const char* aTopic,
SSL_OptionSetDefault(SSL_ENABLE_ALPN,
Preferences::GetBool("security.ssl.enable_alpn",
ALPN_ENABLED_DEFAULT));
} else if (prefName.EqualsLiteral("security.tls.enable_0rtt_data")) {
SSL_OptionSetDefault(SSL_ENABLE_0RTT_DATA,
Preferences::GetBool("security.tls.enable_0rtt_data",
ENABLED_0RTT_DATA_DEFAULT));
} else if (prefName.Equals("security.ssl.disable_session_identifiers")) {
ConfigureTLSSessionIdentifiers();
} else if (prefName.EqualsLiteral("security.OCSP.enabled") ||
+68
View File
@@ -61,6 +61,8 @@ using namespace mozilla::psm;
namespace {
#define MAX_ALPN_LENGTH 255
void
getSiteKey(const nsACString& hostName, uint16_t port,
/*out*/ nsCSubstring& key)
@@ -93,6 +95,7 @@ nsNSSSocketInfo::nsNSSSocketInfo(SharedSSLState& aState, uint32_t providerFlags)
mRememberClientAuthCertificate(false),
mPreliminaryHandshakeDone(false),
mNPNCompleted(false),
mEarlyDataAccepted(false),
mFalseStartCallbackCalled(false),
mFalseStarted(false),
mIsFullHandshake(false),
@@ -313,6 +316,71 @@ nsNSSSocketInfo::GetNegotiatedNPN(nsACString& aNegotiatedNPN)
return NS_OK;
}
NS_IMETHODIMP
nsNSSSocketInfo::GetAlpnEarlySelection(nsACString& aAlpnSelected)
{
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown() || isPK11LoggedOut()) {
return NS_ERROR_NOT_AVAILABLE;
}
SSLNextProtoState alpnState;
unsigned char chosenAlpn[MAX_ALPN_LENGTH];
unsigned int chosenAlpnLen;
SECStatus rv = SSL_GetNextProto(mFd, &alpnState, chosenAlpn, &chosenAlpnLen,
AssertedCast<unsigned int>(ArrayLength(chosenAlpn)));
if (rv != SECSuccess || alpnState != SSL_NEXT_PROTO_EARLY_VALUE ||
chosenAlpnLen == 0) {
return NS_ERROR_NOT_AVAILABLE;
}
aAlpnSelected.Assign(BitwiseCast<char*, unsigned char*>(chosenAlpn),
chosenAlpnLen);
return NS_OK;
}
NS_IMETHODIMP
nsNSSSocketInfo::GetEarlyDataAccepted(bool* aAccepted)
{
*aAccepted = mEarlyDataAccepted;
return NS_OK;
}
void
nsNSSSocketInfo::SetEarlyDataAccepted(bool aAccepted)
{
mEarlyDataAccepted = aAccepted;
}
NS_IMETHODIMP
nsNSSSocketInfo::DriveHandshake()
{
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown() || isPK11LoggedOut()) {
return NS_ERROR_NOT_AVAILABLE;
}
if (!mFd) {
return NS_ERROR_FAILURE;
}
PRErrorCode errorCode = GetErrorCode();
if (errorCode) {
return GetXPCOMFromNSSError(errorCode);
}
SECStatus rv = SSL_ForceHandshake(mFd);
if (rv != SECSuccess) {
errorCode = PR_GetError();
if (errorCode == PR_WOULD_BLOCK_ERROR) {
return NS_BASE_STREAM_WOULD_BLOCK;
}
SetCanceled(errorCode, PlainErrorMessage);
return GetXPCOMFromNSSError(errorCode);
}
return NS_OK;
}
NS_IMETHODIMP
nsNSSSocketInfo::IsAcceptableForHost(const nsACString& hostname, bool* _retval)
{
+2
View File
@@ -52,6 +52,7 @@ public:
const nsNSSShutDownPreventionLock& proofOfLock);
void SetNegotiatedNPN(const char* value, uint32_t length);
void SetEarlyDataAccepted(bool aAccepted);
void SetHandshakeCompleted();
void NoteTimeUntilReady();
@@ -139,6 +140,7 @@ private:
nsCString mNegotiatedNPN;
bool mNPNCompleted;
bool mEarlyDataAccepted;
bool mFalseStartCallbackCalled;
bool mFalseStarted;
bool mIsFullHandshake;
+9 -7
View File
@@ -313,13 +313,15 @@
ERROR(NS_NET_STATUS_WRITING, FAILURE(9)),
/* nsISocketTransport */
ERROR(NS_NET_STATUS_RESOLVING_HOST, FAILURE(3)),
ERROR(NS_NET_STATUS_RESOLVED_HOST, FAILURE(11)),
ERROR(NS_NET_STATUS_CONNECTING_TO, FAILURE(7)),
ERROR(NS_NET_STATUS_CONNECTED_TO, FAILURE(4)),
ERROR(NS_NET_STATUS_SENDING_TO, FAILURE(5)),
ERROR(NS_NET_STATUS_WAITING_FOR, FAILURE(10)),
ERROR(NS_NET_STATUS_RECEIVING_FROM, FAILURE(6)),
ERROR(NS_NET_STATUS_RESOLVING_HOST, FAILURE(3)),
ERROR(NS_NET_STATUS_RESOLVED_HOST, FAILURE(11)),
ERROR(NS_NET_STATUS_CONNECTING_TO, FAILURE(7)),
ERROR(NS_NET_STATUS_CONNECTED_TO, FAILURE(4)),
ERROR(NS_NET_STATUS_TLS_HANDSHAKE_STARTING, FAILURE(12)),
ERROR(NS_NET_STATUS_TLS_HANDSHAKE_ENDED, FAILURE(13)),
ERROR(NS_NET_STATUS_SENDING_TO, FAILURE(5)),
ERROR(NS_NET_STATUS_WAITING_FOR, FAILURE(10)),
ERROR(NS_NET_STATUS_RECEIVING_FROM, FAILURE(6)),
/* nsIInterceptedChannel */
/* Generic error for non-specific failures during service worker interception */