Backed out changeset 3c71363497a8 (bug 1188435)

This commit is contained in:
Carsten "Tomcat" Book 2017-04-25 16:32:01 +02:00
Родитель deb3127d30
Коммит 67baf53f29
8 изменённых файлов: 90 добавлений и 261 удалений

Просмотреть файл

@ -32,7 +32,7 @@ public:
// To use TFO we need to have a transaction prepared, e.g. also have
// nsHttpConnection ready. This functions is call by nsSocketTransport to
// setup a connection.
virtual nsresult StartFastOpen(PRFileDesc *fd) = 0;
virtual nsresult StartFastOpen() = 0;
// Inform nsHalfopenSocket whether a connection using TFO succeeded or not.
// This will cancel the backup connection and in case of a failure rewind
// the transaction.

Просмотреть файл

@ -16,58 +16,24 @@ static PRDescIdentity sTCPFastOpenLayerIdentity;
static PRIOMethods sTCPFastOpenLayerMethods;
static PRIOMethods *sTCPFastOpenLayerMethodsPtr = nullptr;
#define TFO_MAX_PACKET_SIZE_IPV4 1460
#define TFO_MAX_PACKET_SIZE_IPV6 1440
#define TFO_TLS_RECORD_HEADER_SIZE 22
/**
* For the TCP Fast Open it is necessary to send all data that can fit into the
* first packet on a single sendto function call. Consecutive calls will not
* have an effect. Therefore TCPFastOpenLayer will collect some data before
* calling sendto. Necko and nss will call PR_Write multiple times with small
* amount of data.
* TCPFastOpenLayer has 4 states:
* WAITING_FOR_CONNECT:
* This is before connect is call. A call of recv, send or getpeername will
* return PR_NOT_CONNECTED_ERROR. After connect is call the state transfers
* into COLLECT_DATA_FOR_FIRST_PACKET.
*
* COLLECT_DATA_FOR_FIRST_PACKET:
* In this state all data received by send function calls will be stored in
* a buffer. If transaction do not have any more data ready to be sent or
* the buffer is full, TCPFastOpenFinish is call. TCPFastOpenFinish sends
* the collected data using sendto function and the state transfers to
* WAITING_FOR_CONNECTCONTINUE. If an error occurs during sendto, the error
* is reported by the TCPFastOpenFinish return values. nsSocketTransfer is
* the only caller of TCPFastOpenFinish; it knows how to interpreter these
* errors.
* WAITING_FOR_CONNECTCONTINUE:
* connectcontinue transfers from this state to CONNECTED. Any other
* function (e.g. send, recv) returns PR_WOULD_BLOCK_ERROR.
* CONNECTED:
* The size of mFirstPacketBuf is 1440/1460 (RFC7413 recomends that packet
* does exceeds these sizes). SendTo does not have to consume all buffered
* data and some data can be still in mFirstPacketBuf. Before sending any
* new data we need to send the remaining buffered data.
**/
class TCPFastOpenSecret
{
public:
TCPFastOpenSecret()
: mState(WAITING_FOR_CONNECT)
, mFirstPacketBufLen(0)
, mConnectResult(0)
, mFastOpenNotSupported(false)
{}
enum {
CONNECTED,
WAITING_FOR_CONNECTCONTINUE,
COLLECT_DATA_FOR_FIRST_PACKET,
WAITING_FOR_FIRST_SEND,
WAITING_FOR_CONNECT
} mState;
PRNetAddr mAddr;
char mFirstPacketBuf[1460];
uint16_t mFirstPacketBufLen;
PRErrorCode mConnectResult;
bool mFastOpenNotSupported;
};
static PRStatus
@ -86,9 +52,10 @@ TCPFastOpenConnect(PRFileDesc *fd, const PRNetAddr *addr,
return PR_FAILURE;
}
// Remember the address. It will be used for sendto or connect later.
// Remember the address we will call PR_Sendto and for that we need
// the address.
memcpy(&secret->mAddr, addr, sizeof(secret->mAddr));
secret->mState = TCPFastOpenSecret::COLLECT_DATA_FOR_FIRST_PACKET;
secret->mState = TCPFastOpenSecret::WAITING_FOR_FIRST_SEND;
return PR_SUCCESS;
}
@ -106,57 +73,52 @@ TCPFastOpenSend(PRFileDesc *fd, const void *buf, PRInt32 amount,
switch(secret->mState) {
case TCPFastOpenSecret::CONNECTED:
// Before sending new data we need to drain the data collected during tfo.
if (secret->mFirstPacketBufLen) {
SOCKET_LOG(("TCPFastOpenSend - %d bytes to drain from "
"mFirstPacketBufLen.\n",
secret->mFirstPacketBufLen ));
PRInt32 rv = (fd->lower->methods->send)(fd->lower,
secret->mFirstPacketBuf,
secret->mFirstPacketBufLen,
0, // flags
PR_INTERVAL_NO_WAIT);
if (rv <= 0) {
return rv;
} else {
secret->mFirstPacketBufLen -= rv;
if (secret->mFirstPacketBufLen) {
memmove(secret->mFirstPacketBuf,
secret->mFirstPacketBuf + rv,
secret->mFirstPacketBufLen);
PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
return PR_FAILURE;
} // if we drained the buffer we can fall through this checks and call
// send for the new data
}
}
SOCKET_LOG(("TCPFastOpenSend sending new data.\n"));
return (fd->lower->methods->send)(fd->lower, buf, amount, flags, timeout);
case TCPFastOpenSecret::WAITING_FOR_CONNECTCONTINUE:
PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
return -1;
case TCPFastOpenSecret::COLLECT_DATA_FOR_FIRST_PACKET:
case TCPFastOpenSecret::WAITING_FOR_FIRST_SEND:
{
int32_t toSend =
(secret->mAddr.raw.family == PR_AF_INET) ? TFO_MAX_PACKET_SIZE_IPV4
: TFO_MAX_PACKET_SIZE_IPV6;
MOZ_ASSERT(secret->mFirstPacketBufLen <= toSend);
toSend -= secret->mFirstPacketBufLen;
PRInt32 rv = (fd->lower->methods->sendto)(fd->lower, buf, amount, flags,
&secret->mAddr, timeout);
SOCKET_LOG(("TCPFastOpenSend: amount of data in the buffer=%d; the amount"
" of additional data that can be stored=%d.\n",
secret->mFirstPacketBufLen, toSend));
if (!toSend) {
PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
return -1;
SOCKET_LOG(("TCPFastOpenSend - sendto result=%d.\n", rv));
if (rv > -1) {
secret->mState = TCPFastOpenSecret::WAITING_FOR_CONNECTCONTINUE;
secret->mConnectResult = PR_IN_PROGRESS_ERROR;
return rv;
}
toSend = (toSend > amount) ? amount : toSend;
memcpy(secret->mFirstPacketBuf + secret->mFirstPacketBufLen, buf, toSend);
secret->mFirstPacketBufLen += toSend;
return toSend;
secret->mConnectResult = PR_GetError();
SOCKET_LOG(("TCPFastOpenSend - sendto error=%d.\n",
secret->mConnectResult));
if (secret->mConnectResult == PR_IS_CONNECTED_ERROR) {
secret->mState = TCPFastOpenSecret::CONNECTED;
} else if (secret->mConnectResult == PR_IN_PROGRESS_ERROR) {
secret->mState = TCPFastOpenSecret::WAITING_FOR_CONNECTCONTINUE;
} else if (secret->mConnectResult == PR_NOT_IMPLEMENTED_ERROR || // When a windows version does not support Fast Open it will return this error.
secret->mConnectResult == PR_NOT_TCP_SOCKET_ERROR) { // SendTo will return PR_NOT_TCP_SOCKET_ERROR if TCP Fast Open is turned off on Linux.
// We can call connect again.
secret->mFastOpenNotSupported = true;
rv = (fd->lower->methods->connect)(fd->lower, &secret->mAddr, timeout);
if (rv == PR_SUCCESS) {
secret->mConnectResult = PR_IS_CONNECTED_ERROR;
secret->mState = TCPFastOpenSecret::CONNECTED;
} else {
secret->mConnectResult = PR_GetError();
secret->mState = TCPFastOpenSecret::WAITING_FOR_CONNECTCONTINUE;
}
}
// Error will be picked up by TCPFastOpenConnectResult.
PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
return -1;
}
case TCPFastOpenSecret::WAITING_FOR_CONNECT:
PR_SetError(PR_NOT_CONNECTED_ERROR, 0);
@ -183,34 +145,10 @@ TCPFastOpenRecv(PRFileDesc *fd, void *buf, PRInt32 amount,
PRInt32 rv = -1;
switch(secret->mState) {
case TCPFastOpenSecret::CONNECTED:
if (secret->mFirstPacketBufLen) {
// TLS will not call write before receiving data from a server, therefore
// we need to force sending buffered data even during recv call. Otherwise
// It can come to a deadlock (clients waits for response, but the request
// is sitting in mFirstPacketBufLen).
SOCKET_LOG(("TCPFastOpenRevc - %d bytes to drain from mFirstPacketBuf.\n",
secret->mFirstPacketBufLen ));
PRInt32 rv = (fd->lower->methods->send)(fd->lower,
secret->mFirstPacketBuf,
secret->mFirstPacketBufLen,
0, // flags
PR_INTERVAL_NO_WAIT);
if (rv <= 0) {
return rv;
} else {
secret->mFirstPacketBufLen -= rv;
if (secret->mFirstPacketBufLen) {
memmove(secret->mFirstPacketBuf,
secret->mFirstPacketBuf + rv,
secret->mFirstPacketBufLen);
}
}
}
rv = (fd->lower->methods->recv)(fd->lower, buf, amount, flags, timeout);
break;
case TCPFastOpenSecret::WAITING_FOR_CONNECTCONTINUE:
case TCPFastOpenSecret::COLLECT_DATA_FOR_FIRST_PACKET:
case TCPFastOpenSecret::WAITING_FOR_FIRST_SEND:
PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
break;
case TCPFastOpenSecret::WAITING_FOR_CONNECT:
@ -238,7 +176,7 @@ TCPFastOpenConnectContinue(PRFileDesc *fd, PRInt16 out_flags)
rv = PR_SUCCESS;
break;
case TCPFastOpenSecret::WAITING_FOR_CONNECT:
case TCPFastOpenSecret::COLLECT_DATA_FOR_FIRST_PACKET:
case TCPFastOpenSecret::WAITING_FOR_FIRST_SEND:
PR_SetError(PR_NOT_CONNECTED_ERROR, 0);
rv = PR_FAILURE;
break;
@ -246,7 +184,9 @@ TCPFastOpenConnectContinue(PRFileDesc *fd, PRInt16 out_flags)
rv = (fd->lower->methods->connectcontinue)(fd->lower, out_flags);
SOCKET_LOG(("TCPFastOpenConnectContinue result=%d.\n", rv));
secret->mState = TCPFastOpenSecret::CONNECTED;
if (rv == PR_SUCCESS) {
secret->mState = TCPFastOpenSecret::CONNECTED;
}
}
return rv;
}
@ -289,20 +229,6 @@ TCPFastOpenGetpeername (PRFileDesc *fd, PRNetAddr *addr)
return PR_SUCCESS;
}
static PRInt16
TCPFastOpenPoll(PRFileDesc *fd, PRInt16 how_flags, PRInt16 *p_out_flags)
{
MOZ_RELEASE_ASSERT(fd);
MOZ_RELEASE_ASSERT(fd->identity == sTCPFastOpenLayerIdentity);
TCPFastOpenSecret *secret = reinterpret_cast<TCPFastOpenSecret *>(fd->secret);
if (secret->mFirstPacketBufLen) {
how_flags |= PR_POLL_WRITE;
}
return fd->lower->methods->poll(fd->lower, how_flags, p_out_flags);
}
nsresult
AttachTCPFastOpenIOLayer(PRFileDesc *fd)
{
@ -319,7 +245,6 @@ AttachTCPFastOpenIOLayer(PRFileDesc *fd)
sTCPFastOpenLayerMethods.connectcontinue = TCPFastOpenConnectContinue;
sTCPFastOpenLayerMethods.close = TCPFastOpenClose;
sTCPFastOpenLayerMethods.getpeername = TCPFastOpenGetpeername;
sTCPFastOpenLayerMethods.poll = TCPFastOpenPoll;
sTCPFastOpenLayerMethodsPtr = &sTCPFastOpenLayerMethods;
}
@ -345,8 +270,8 @@ AttachTCPFastOpenIOLayer(PRFileDesc *fd)
}
void
TCPFastOpenFinish(PRFileDesc * fd, PRErrorCode *err,
bool *fastOpenNotSupported)
TCPFastOpenConnectResult(PRFileDesc * fd, PRErrorCode *err,
bool *fastOpenNotSupported)
{
PRFileDesc *tfoFd = PR_GetIdentitiesLayer(fd, sTCPFastOpenLayerIdentity);
MOZ_RELEASE_ASSERT(tfoFd);
@ -354,104 +279,24 @@ TCPFastOpenFinish(PRFileDesc * fd, PRErrorCode *err,
TCPFastOpenSecret *secret = reinterpret_cast<TCPFastOpenSecret *>(tfoFd->secret);
MOZ_ASSERT(secret->mState == TCPFastOpenSecret::COLLECT_DATA_FOR_FIRST_PACKET);
MOZ_ASSERT(secret->mState != TCPFastOpenSecret::WAITING_FOR_CONNECT);
*fastOpenNotSupported = false;
PRErrorCode result = 0;
*fastOpenNotSupported = secret->mFastOpenNotSupported;
if (!secret->mFirstPacketBufLen) {
// Because of the way our nsHttpTransaction dispatch work, it can happened
// that data has not been written into the socket.
// In this case we can just call connect.
if (secret->mState == TCPFastOpenSecret::WAITING_FOR_FIRST_SEND) {
// Because of the way our HttpTransaction dispatch work, it can happened
// that connect is not called.
PRInt32 rv = (tfoFd->lower->methods->connect)(tfoFd->lower, &secret->mAddr,
PR_INTERVAL_NO_WAIT);
PR_INTERVAL_NO_WAIT);
if (rv == PR_SUCCESS) {
result = PR_IS_CONNECTED_ERROR;
secret->mConnectResult = PR_IS_CONNECTED_ERROR;
secret->mState = TCPFastOpenSecret::CONNECTED;
} else {
result = PR_GetError();
}
} else {
// We have some data ready in the buffer we will send it with the syn
// packet.
PRInt32 rv = (tfoFd->lower->methods->sendto)(tfoFd->lower,
secret->mFirstPacketBuf,
secret->mFirstPacketBufLen,
0, //flags
&secret->mAddr,
PR_INTERVAL_NO_WAIT);
SOCKET_LOG(("TCPFastOpenFinish - sendto result=%d.\n", rv));
if (rv > 0) {
result = PR_IN_PROGRESS_ERROR;
secret->mFirstPacketBufLen -= rv;
if (secret->mFirstPacketBufLen) {
memmove(secret->mFirstPacketBuf,
secret->mFirstPacketBuf + rv,
secret->mFirstPacketBufLen);
}
} else {
result = PR_GetError();
SOCKET_LOG(("TCPFastOpenFinish - sendto error=%d.\n", result));
if (result == PR_NOT_IMPLEMENTED_ERROR || // When a windows version does not support Fast Open it will return this error.
result == PR_NOT_TCP_SOCKET_ERROR) { // SendTo will return PR_NOT_TCP_SOCKET_ERROR if TCP Fast Open is turned off on Linux.
// We can call connect again.
*fastOpenNotSupported = true;
rv = (fd->lower->methods->connect)(fd->lower, &secret->mAddr, PR_INTERVAL_NO_WAIT);
if (rv == PR_SUCCESS) {
result = PR_IS_CONNECTED_ERROR;
} else {
result = PR_GetError();
}
}
secret->mConnectResult = PR_GetError();
secret->mState = TCPFastOpenSecret::WAITING_FOR_CONNECTCONTINUE;
}
}
if (result == PR_IN_PROGRESS_ERROR) {
secret->mState = TCPFastOpenSecret::WAITING_FOR_CONNECTCONTINUE;
} else {
// If the error is not PR_IN_PROGRESS_ERROR, change the state to CONNECT so
// that recv/send can perform recv/send on the next lower layer and pick up
// the real error. This is really important!
// The result can also be PR_IS_CONNECTED_ERROR, that should change the
// state to CONNECT anyway.
secret->mState = TCPFastOpenSecret::CONNECTED;
}
*err = result;
}
/* This function returns the size of the remaining free space in the
* first_packet_buffer. This will be used by transactions with a tls layer. For
* other transactions it is not necessary. The tls transactions make a tls
* record before writing to this layer and if the record is too big the part
* that does not have place in the mFirstPacketBuf will be saved on the tls
* layer. During TFO we cannot send more than TFO_MAX_PACKET_SIZE_IPV4/6 bytes,
* so if we have a big tls record, this record is encrypted with 0RTT key,
* tls-early-data can be rejected and than we still need to send the rest of the
* record.
*/
int32_t
TCPFastOpenGetBufferSizeLeft(PRFileDesc *fd)
{
PRFileDesc *tfoFd = PR_GetIdentitiesLayer(fd, sTCPFastOpenLayerIdentity);
MOZ_RELEASE_ASSERT(tfoFd);
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
TCPFastOpenSecret *secret = reinterpret_cast<TCPFastOpenSecret *>(tfoFd->secret);
MOZ_ASSERT(secret->mState == TCPFastOpenSecret::COLLECT_DATA_FOR_FIRST_PACKET);
int32_t sizeLeft =
(secret->mAddr.raw.family == PR_AF_INET) ? TFO_MAX_PACKET_SIZE_IPV4
: TFO_MAX_PACKET_SIZE_IPV6;
MOZ_ASSERT(secret->mFirstPacketBufLen <= sizeLeft);
sizeLeft -= secret->mFirstPacketBufLen;
SOCKET_LOG(("TCPFastOpenGetBufferSizeLeft=%d.\n", sizeLeft));
return (sizeLeft > TFO_TLS_RECORD_HEADER_SIZE) ?
sizeLeft - TFO_TLS_RECORD_HEADER_SIZE : 0;
*err = secret->mConnectResult;
}
}

Просмотреть файл

@ -12,19 +12,12 @@
namespace mozilla {
namespace net {
/**
* This layer must be placed just above PR-tcp socket, i.e. it must be under
* nss layer.
* At the beginning of TCPFastOpenLayer.cpp there is explanation what this
* layer do.
**/
nsresult AttachTCPFastOpenIOLayer(PRFileDesc *fd);
// Get the result of TCP Fast Open.
void TCPFastOpenFinish(PRFileDesc *fd, PRErrorCode *err,
bool *fastOpenNotSupported);
void TCPFastOpenConnectResult(PRFileDesc *fd, PRErrorCode *err,
bool *fastOpenNotSupported);
int32_t TCPFastOpenGetBufferSizeLeft(PRFileDesc *fd);
}
}

Просмотреть файл

@ -1518,12 +1518,12 @@ nsSocketTransport::InitiateSocket()
mFDFastOpenInProgress = true;
}
SOCKET_LOG(("Using TCP Fast Open."));
rv = mFastOpenCallback->StartFastOpen(fd);
rv = mFastOpenCallback->StartFastOpen();
status = PR_FAILURE;
connectCalled = false;
bool fastOpenNotSupported = false;
TCPFastOpenFinish(fd, &code, &fastOpenNotSupported);
TCPFastOpenConnectResult(fd, &code, &fastOpenNotSupported);
SOCKET_LOG(("called StartFastOpen - code=%d; fastOpen is %s "
"supported.\n", code,
fastOpenNotSupported ? "not" : ""));

Просмотреть файл

@ -35,7 +35,6 @@
#include "nsStringStream.h"
#include "sslt.h"
#include "TunnelUtils.h"
#include "TCPFastOpenLayer.h"
namespace mozilla {
namespace net {
@ -88,7 +87,7 @@ nsHttpConnection::nsHttpConnection()
, mDid0RTTSpdy(false)
, mResponseThrottled(false)
, mResumeRecvOnUnthrottle(false)
, mFastOpen(nullptr)
, mFastOpen(false)
{
LOG(("Creating nsHttpConnection @%p\n", this));
@ -384,7 +383,9 @@ nsHttpConnection::EnsureNPNComplete(nsresult &aOut0RTTWriteHandshakeValue,
}
rv = ssl->GetNegotiatedNPN(negotiatedNPN);
if (!m0RTTChecked && (rv == NS_ERROR_NOT_CONNECTED) &&
// Fast Open does not work well with TLS Early Data. TODO: dragana
// fix this.
if (!mFastOpen && !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
@ -443,24 +444,15 @@ nsHttpConnection::EnsureNPNComplete(nsresult &aOut0RTTWriteHandshakeValue,
if (rv == NS_ERROR_NOT_CONNECTED) {
if (mWaitingFor0RTTResponse) {
int32_t segmentSize = nsIOService::gDefaultSegmentSize;
if (mFastOpen) {
segmentSize = TCPFastOpenGetBufferSizeLeft(mFastOpen);
LOG(("nsHttpConnection::EnsureNPNComplete [this=%p] - It is "
"fast open and the first packet has %d byte to fill.",
this, segmentSize));
}
if (segmentSize) {
aOut0RTTWriteHandshakeValue = mTransaction->ReadSegments(this,
segmentSize, &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;
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();

Просмотреть файл

@ -83,7 +83,7 @@ public:
MOZ_MUST_USE nsresult Activate(nsAHttpTransaction *, uint32_t caps,
int32_t pri);
void SetFastOpen(PRFileDesc *aFastOpen) { mFastOpen = aFastOpen; }
void SetFastOpen(bool aFastOpen) { mFastOpen = aFastOpen; }
// Close this connection and return the transaction. The transaction is
// restarted as well. This will only happened before connection is
// connected.
@ -399,7 +399,7 @@ private:
// to ResumeRecv() when untrottled again. Only accessed on the socket thread.
bool mResumeRecvOnUnthrottle;
PRFileDesc *mFastOpen;
bool mFastOpen;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsHttpConnection, NS_HTTPCONNECTION_IID)

Просмотреть файл

@ -3425,7 +3425,7 @@ nsHalfOpenSocket::OnOutputStreamReady(nsIAsyncOutputStream *out)
}
}
return SetupConn(out, nullptr);
return SetupConn(out, false);
}
bool
@ -3474,9 +3474,8 @@ nsHalfOpenSocket::FastOpenEnabled()
nsresult
nsHttpConnectionMgr::
nsHalfOpenSocket::StartFastOpen(PRFileDesc *fd)
nsHalfOpenSocket::StartFastOpen()
{
MOZ_ASSERT(fd);
MOZ_ASSERT(mStreamOut);
MOZ_ASSERT(mEnt && !mBackupTransport);
mUsingFastOpen = true;
@ -3488,7 +3487,7 @@ nsHalfOpenSocket::StartFastOpen(PRFileDesc *fd)
mStreamOut->AsyncWait(nullptr, 0, 0, nullptr);
mSocketTransport->SetEventSink(nullptr, nullptr);
gHttpHandler->ConnMgr()->RecvdConnect();
return SetupConn(mStreamOut, fd);
return SetupConn(mStreamOut, true);
}
void
@ -3538,7 +3537,7 @@ nsHalfOpenSocket::FastOpenNotSupported()
nsresult
nsHttpConnectionMgr::
nsHalfOpenSocket::SetupConn(nsIAsyncOutputStream *out,
PRFileDesc *aFastOpen)
bool aFastOpen)
{
MOZ_ASSERT(!aFastOpen || (out == mStreamOut));
// assign the new socket to the http connection
@ -3697,7 +3696,7 @@ nsHalfOpenSocket::SetupConn(nsIAsyncOutputStream *out,
mTransaction = new NullHttpTransaction(mEnt->mConnInfo,
callbacks, mCaps);
conn->SetFastOpen(nullptr);
conn->SetFastOpen(false);
mConnectionNegotiatingFastOpen = conn;
}

Просмотреть файл

@ -373,12 +373,12 @@ private:
void Unclaim();
bool FastOpenEnabled() override;
nsresult StartFastOpen(PRFileDesc *) override;
nsresult StartFastOpen() override;
void FastOpenConnected(nsresult) override;
void FastOpenNotSupported() override;
private:
nsresult SetupConn(nsIAsyncOutputStream *out,
PRFileDesc *aFastOpen);
bool aFastOpen);
// To find out whether |mTransaction| is still in the connection entry's
// pending queue. If the transaction is found and |removeWhenFound| is