Skip to content

Commit

Permalink
Immediately retransmit initial packets in writeCryptoAndAckDataToSocket
Browse files Browse the repository at this point in the history
Summary: In `writeCryptoAndAckDataToSocket`, add an additional `writeProbingDataToSocket` call at the end that is limited to the number of CRYPTO frame-containing packets just written, gated by the new `TransportSetttings` field `immediatelyRetransmitInitialPackets`.

Reviewed By: mjoras

Differential Revision: D64485616

fbshipit-source-id: f0927a3796767700fd46673195e1cd4e1bbbcbeb
  • Loading branch information
Jolene Tan authored and facebook-github-bot committed Oct 24, 2024
1 parent cc14fe8 commit 1dad954
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 1 deletion.
23 changes: 22 additions & 1 deletion quic/api/QuicTransportFunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1107,7 +1107,7 @@ WriteQuicDataResult writeCryptoAndAckDataToSocket(
connection,
srcConnId,
dstConnId,
std::move(builder),
builder,
LongHeader::typeToPacketNumberSpace(packetType),
scheduler,
congestionControlWritableBytes,
Expand All @@ -1121,6 +1121,27 @@ WriteQuicDataResult writeCryptoAndAckDataToSocket(
packetsWritten += writeResult.packetsWritten;
bytesWritten += writeResult.bytesWritten;

if (connection.transportSettings.immediatelyRetransmitInitialPackets &&
packetsWritten > 0 && packetsWritten < packetLimit) {
auto remainingLimit = packetLimit - packetsWritten;
auto cloneResult = writeProbingDataToSocket(
sock,
connection,
srcConnId,
dstConnId,
builder,
encryptionLevel,
LongHeader::typeToPacketNumberSpace(packetType),
scheduler,
packetsWritten < remainingLimit ? packetsWritten : remainingLimit,
cleartextCipher,
headerCipher,
version,
token);
probesWritten += cloneResult.probesWritten;
bytesWritten += cloneResult.bytesWritten;
}

VLOG_IF(10, packetsWritten || probesWritten)
<< nodeToString(connection.nodeType)
<< " written crypto and acks data type=" << packetType
Expand Down
32 changes: 32 additions & 0 deletions quic/api/test/QuicTransportFunctionsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3372,6 +3372,38 @@ TEST_F(QuicTransportFunctionsTest, NoCryptoProbeWriteIfNoProbeCredit) {
EXPECT_EQ(0, res.probesWritten);
}

TEST_F(QuicTransportFunctionsTest, ImmediatelyRetransmitInitialPackets) {
auto conn = createConn();
conn->transportSettings.immediatelyRetransmitInitialPackets = true;
auto cryptoStream = &conn->cryptoState->initialStream;
auto buf = buildRandomInputData(1600);
writeDataToQuicStream(*cryptoStream, buf->clone());
EventBase evb;
std::shared_ptr<FollyQuicEventBase> qEvb =
std::make_shared<FollyQuicEventBase>(&evb);
auto socket =
std::make_unique<NiceMock<quic::test::MockAsyncUDPSocket>>(qEvb);
auto rawSocket = socket.get();
auto res = writeCryptoAndAckDataToSocket(
*rawSocket,
*conn,
*conn->clientConnectionId,
*conn->serverConnectionId,
LongHeader::Types::Initial,
*conn->initialWriteCipher,
*conn->initialHeaderCipher,
getVersion(*conn),
conn->transportSettings.writeConnectionDataPacketsLimit);
EXPECT_GE(res.bytesWritten, buf->computeChainDataLength());

EXPECT_EQ(2, res.packetsWritten);
EXPECT_EQ(2, res.probesWritten);
EXPECT_EQ(conn->udpSendPacketLen * 4, res.bytesWritten);
ASSERT_EQ(4, conn->outstandings.packets.size());
ASSERT_EQ(2, cryptoStream->retransmissionBuffer.size());
ASSERT_TRUE(cryptoStream->pendingWrites.empty());
}

TEST_F(QuicTransportFunctionsTest, ResetNumProbePackets) {
auto conn = createConn();
EventBase evb;
Expand Down
1 change: 1 addition & 0 deletions quic/state/TransportSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,7 @@ struct TransportSettings {
// Raise read callbacks for all unidirectional streams first on data
// reception.
bool unidirectionalStreamsReadCallbacksFirst{false};
bool immediatelyRetransmitInitialPackets{false};
};

} // namespace quic

0 comments on commit 1dad954

Please sign in to comment.