1
0
mirror of https://github.com/facebookincubator/mvfst.git synced 2025-08-08 09:42:06 +03:00

Log Server Handshake Size

Summary: - logging number of bytes the server sent during the handshake for insight.

Reviewed By: mjoras

Differential Revision: D33069800

fbshipit-source-id: e7e8f25183ee30de99e2971bae3c6b93882f6e63
This commit is contained in:
Hani Damlaj
2022-01-06 10:32:50 -08:00
committed by Facebook GitHub Bot
parent 0a4790b993
commit f60c254c49
5 changed files with 125 additions and 97 deletions

View File

@@ -176,7 +176,8 @@ WriteQuicDataResult writeQuicDataToSocketImpl(
aead, aead,
headerCipher, headerCipher,
version, version,
writeLoopBeginTime); writeLoopBeginTime)
.packetsWritten;
VLOG_IF(10, packetsWritten || probesWritten) VLOG_IF(10, packetsWritten || probesWritten)
<< nodeToString(connection.nodeType) << " written data " << nodeToString(connection.nodeType) << " written data "
<< (exceptCryptoStream ? "without crypto data " : "") << (exceptCryptoStream ? "without crypto data " : "")
@@ -984,6 +985,7 @@ WriteQuicDataResult writeCryptoAndAckDataToSocket(
auto builder = LongHeaderBuilder(packetType); auto builder = LongHeaderBuilder(packetType);
WriteQuicDataResult result; WriteQuicDataResult result;
auto& packetsWritten = result.packetsWritten; auto& packetsWritten = result.packetsWritten;
auto& bytesWritten = result.bytesWritten;
auto& probesWritten = result.probesWritten; auto& probesWritten = result.probesWritten;
auto& cryptoStream = auto& cryptoStream =
*getCryptoStream(*connection.cryptoState, encryptionLevel); *getCryptoStream(*connection.cryptoState, encryptionLevel);
@@ -1011,7 +1013,7 @@ WriteQuicDataResult writeCryptoAndAckDataToSocket(
// Only get one chance to write probes. // Only get one chance to write probes.
numProbePackets = 0; numProbePackets = 0;
// Crypto data is written without aead protection. // Crypto data is written without aead protection.
packetsWritten += writeConnectionDataToSocket( auto writeResult = writeConnectionDataToSocket(
sock, sock,
connection, connection,
srcConnId, srcConnId,
@@ -1026,6 +1028,10 @@ WriteQuicDataResult writeCryptoAndAckDataToSocket(
version, version,
Clock::now(), Clock::now(),
token); token);
packetsWritten += writeResult.packetsWritten;
bytesWritten += writeResult.bytesWritten;
VLOG_IF(10, packetsWritten || probesWritten) VLOG_IF(10, packetsWritten || probesWritten)
<< nodeToString(connection.nodeType) << nodeToString(connection.nodeType)
<< " written crypto and acks data type=" << packetType << " written crypto and acks data type=" << packetType
@@ -1120,7 +1126,8 @@ uint64_t writeZeroRttDataToSocket(
aead, aead,
headerCipher, headerCipher,
version, version,
Clock::now()); Clock::now())
.packetsWritten;
VLOG_IF(10, written > 0) << nodeToString(connection.nodeType) VLOG_IF(10, written > 0) << nodeToString(connection.nodeType)
<< " written zero rtt data, packets=" << written << " written zero rtt data, packets=" << written
<< " " << connection; << " " << connection;
@@ -1308,7 +1315,7 @@ void encryptPacketHeader(
} }
} }
uint64_t writeConnectionDataToSocket( WriteQuicDataResult writeConnectionDataToSocket(
folly::AsyncUDPSocket& sock, folly::AsyncUDPSocket& sock,
QuicConnectionStateBase& connection, QuicConnectionStateBase& connection,
const ConnectionId& srcConnId, const ConnectionId& srcConnId,
@@ -1358,6 +1365,9 @@ uint64_t writeConnectionDataToSocket(
QuicBatchingMode::BATCHING_MODE_NONE QuicBatchingMode::BATCHING_MODE_NONE
? connection.transportSettings.writeConnectionDataPacketsLimit ? connection.transportSettings.writeConnectionDataPacketsLimit
: connection.transportSettings.maxBatchSize; : connection.transportSettings.maxBatchSize;
uint64_t bytesWritten = 0;
while (scheduler.hasData() && ioBufBatch.getPktSent() < packetLimit && while (scheduler.hasData() && ioBufBatch.getPktSent() < packetLimit &&
((ioBufBatch.getPktSent() < batchSize) || ((ioBufBatch.getPktSent() < batchSize) ||
writeLoopTimeLimit(writeLoopBeginTime, connection))) { writeLoopTimeLimit(writeLoopBeginTime, connection))) {
@@ -1389,13 +1399,15 @@ uint64_t writeConnectionDataToSocket(
headerCipher); headerCipher);
if (!ret.buildSuccess) { if (!ret.buildSuccess) {
return ioBufBatch.getPktSent(); return {ioBufBatch.getPktSent(), 0, bytesWritten};
} }
// If we build a packet, we updateConnection(), even if write might have // If we build a packet, we updateConnection(), even if write might have
// been failed. Because if it builds, a lot of states need to be updated no // been failed. Because if it builds, a lot of states need to be updated no
// matter the write result. We are basically treating this case as if we // matter the write result. We are basically treating this case as if we
// pretend write was also successful but packet is lost somewhere in the // pretend write was also successful but packet is lost somewhere in the
// network. // network.
bytesWritten += ret.encodedSize;
auto& result = ret.result; auto& result = ret.result;
updateConnection( updateConnection(
connection, connection,
@@ -1413,7 +1425,7 @@ uint64_t writeConnectionDataToSocket(
connection.writeDebugState.noWriteReason = connection.writeDebugState.noWriteReason =
NoWriteReason::SOCKET_FAILURE; NoWriteReason::SOCKET_FAILURE;
} }
return ioBufBatch.getPktSent(); return {ioBufBatch.getPktSent(), 0, bytesWritten};
} }
} }
@@ -1425,7 +1437,7 @@ uint64_t writeConnectionDataToSocket(
CHECK(buf->length() == 0 && buf->headroom() == 0); CHECK(buf->length() == 0 && buf->headroom() == 0);
connection.bufAccessor->release(std::move(buf)); connection.bufAccessor->release(std::move(buf));
} }
return ioBufBatch.getPktSent(); return {ioBufBatch.getPktSent(), 0, bytesWritten};
} }
uint64_t writeProbingDataToSocket( uint64_t writeProbingDataToSocket(
@@ -1461,7 +1473,8 @@ uint64_t writeProbingDataToSocket(
headerCipher, headerCipher,
version, version,
writeLoopBeginTime, writeLoopBeginTime,
token); token)
.packetsWritten;
if (probesToSend && !written) { if (probesToSend && !written) {
// Fall back to send a ping: // Fall back to send a ping:
connection.pendingEvents.sendPing = true; connection.pendingEvents.sendPing = true;
@@ -1483,7 +1496,8 @@ uint64_t writeProbingDataToSocket(
aead, aead,
headerCipher, headerCipher,
version, version,
writeLoopBeginTime); writeLoopBeginTime)
.packetsWritten;
} }
VLOG_IF(10, written > 0) VLOG_IF(10, written > 0)
<< nodeToString(connection.nodeType) << nodeToString(connection.nodeType)
@@ -1525,7 +1539,8 @@ uint64_t writeD6DProbeToSocket(
aead, aead,
headerCipher, headerCipher,
version, version,
Clock::now()); Clock::now())
.packetsWritten;
VLOG_IF(10, written > 0) << nodeToString(connection.nodeType) VLOG_IF(10, written > 0) << nodeToString(connection.nodeType)
<< " writing d6d probes using scheduler=D6DScheduler" << " writing d6d probes using scheduler=D6DScheduler"
<< connection; << connection;

View File

@@ -83,6 +83,7 @@ using WritableBytesFunc =
struct WriteQuicDataResult { struct WriteQuicDataResult {
uint64_t packetsWritten{}; uint64_t packetsWritten{};
uint64_t probesWritten{}; uint64_t probesWritten{};
uint64_t bytesWritten{};
}; };
/** /**
@@ -270,7 +271,7 @@ void encryptPacketHeader(
* data allowed by the writableBytesFunc and will only write a maximum * data allowed by the writableBytesFunc and will only write a maximum
* number of packetLimit packets at each invocation. * number of packetLimit packets at each invocation.
*/ */
uint64_t writeConnectionDataToSocket( WriteQuicDataResult writeConnectionDataToSocket(
folly::AsyncUDPSocket& sock, folly::AsyncUDPSocket& sock,
QuicConnectionStateBase& connection, QuicConnectionStateBase& connection,
const ConnectionId& srcConnId, const ConnectionId& srcConnId,

View File

@@ -3149,6 +3149,7 @@ TEST_F(QuicTransportFunctionsTest, TestCryptoWritingIsHandshakeInOutstanding) {
EXPECT_EQ(1, res.packetsWritten); EXPECT_EQ(1, res.packetsWritten);
EXPECT_EQ(0, res.probesWritten); EXPECT_EQ(0, res.probesWritten);
EXPECT_GE(res.bytesWritten, buf->computeChainDataLength());
ASSERT_EQ(1, conn->outstandings.packets.size()); ASSERT_EQ(1, conn->outstandings.packets.size());
EXPECT_TRUE(getFirstOutstandingPacket(*conn, PacketNumberSpace::Initial) EXPECT_TRUE(getFirstOutstandingPacket(*conn, PacketNumberSpace::Initial)
->metadata.isHandshake); ->metadata.isHandshake);
@@ -3173,6 +3174,7 @@ TEST_F(QuicTransportFunctionsTest, NoCryptoProbeWriteIfNoProbeCredit) {
*conn->initialHeaderCipher, *conn->initialHeaderCipher,
getVersion(*conn), getVersion(*conn),
conn->transportSettings.writeConnectionDataPacketsLimit); conn->transportSettings.writeConnectionDataPacketsLimit);
EXPECT_GE(res.bytesWritten, buf->computeChainDataLength());
EXPECT_EQ(1, res.packetsWritten); EXPECT_EQ(1, res.packetsWritten);
EXPECT_EQ(0, res.probesWritten); EXPECT_EQ(0, res.probesWritten);
@@ -3195,7 +3197,7 @@ TEST_F(QuicTransportFunctionsTest, NoCryptoProbeWriteIfNoProbeCredit) {
*conn->initialHeaderCipher, *conn->initialHeaderCipher,
getVersion(*conn), getVersion(*conn),
conn->transportSettings.writeConnectionDataPacketsLimit); conn->transportSettings.writeConnectionDataPacketsLimit);
EXPECT_EQ(0, res.bytesWritten);
EXPECT_EQ(0, res.packetsWritten); EXPECT_EQ(0, res.packetsWritten);
EXPECT_EQ(0, res.probesWritten); EXPECT_EQ(0, res.probesWritten);
} }
@@ -3208,7 +3210,7 @@ TEST_F(QuicTransportFunctionsTest, ResetNumProbePackets) {
auto rawSocket = socket.get(); auto rawSocket = socket.get();
conn->pendingEvents.numProbePackets[PacketNumberSpace::Initial] = 2; conn->pendingEvents.numProbePackets[PacketNumberSpace::Initial] = 2;
writeCryptoAndAckDataToSocket( auto writeRes1 = writeCryptoAndAckDataToSocket(
*rawSocket, *rawSocket,
*conn, *conn,
*conn->clientConnectionId, *conn->clientConnectionId,
@@ -3219,11 +3221,12 @@ TEST_F(QuicTransportFunctionsTest, ResetNumProbePackets) {
getVersion(*conn), getVersion(*conn),
conn->transportSettings.writeConnectionDataPacketsLimit); conn->transportSettings.writeConnectionDataPacketsLimit);
EXPECT_FALSE(conn->pendingEvents.anyProbePackets()); EXPECT_FALSE(conn->pendingEvents.anyProbePackets());
EXPECT_EQ(0, writeRes1.bytesWritten);
conn->handshakeWriteCipher = createNoOpAead(); conn->handshakeWriteCipher = createNoOpAead();
conn->handshakeWriteHeaderCipher = createNoOpHeaderCipher(); conn->handshakeWriteHeaderCipher = createNoOpHeaderCipher();
conn->pendingEvents.numProbePackets[PacketNumberSpace::Handshake] = 2; conn->pendingEvents.numProbePackets[PacketNumberSpace::Handshake] = 2;
writeCryptoAndAckDataToSocket( auto writeRes2 = writeCryptoAndAckDataToSocket(
*rawSocket, *rawSocket,
*conn, *conn,
*conn->clientConnectionId, *conn->clientConnectionId,
@@ -3234,6 +3237,7 @@ TEST_F(QuicTransportFunctionsTest, ResetNumProbePackets) {
getVersion(*conn), getVersion(*conn),
conn->transportSettings.writeConnectionDataPacketsLimit); conn->transportSettings.writeConnectionDataPacketsLimit);
EXPECT_FALSE(conn->pendingEvents.anyProbePackets()); EXPECT_FALSE(conn->pendingEvents.anyProbePackets());
EXPECT_EQ(0, writeRes2.bytesWritten);
conn->oneRttWriteCipher = createNoOpAead(); conn->oneRttWriteCipher = createNoOpAead();
conn->oneRttWriteHeaderCipher = createNoOpHeaderCipher(); conn->oneRttWriteHeaderCipher = createNoOpHeaderCipher();

View File

@@ -286,7 +286,8 @@ void QuicServerTransport::writeData() {
hasAcksToSchedule(conn_->ackStates.initialAckState))) { hasAcksToSchedule(conn_->ackStates.initialAckState))) {
CHECK(conn_->initialWriteCipher); CHECK(conn_->initialWriteCipher);
CHECK(conn_->initialHeaderCipher); CHECK(conn_->initialHeaderCipher);
packetLimit -= writeCryptoAndAckDataToSocket(
auto res = writeCryptoAndAckDataToSocket(
*socket_, *socket_,
*conn_, *conn_,
srcConnId /* src */, srcConnId /* src */,
@@ -295,8 +296,10 @@ void QuicServerTransport::writeData() {
*conn_->initialWriteCipher, *conn_->initialWriteCipher,
*conn_->initialHeaderCipher, *conn_->initialHeaderCipher,
version, version,
packetLimit) packetLimit);
.packetsWritten;
packetLimit -= res.packetsWritten;
serverConn_->numHandshakeBytesSent += res.bytesWritten;
} }
if (!packetLimit && !conn_->pendingEvents.anyProbePackets()) { if (!packetLimit && !conn_->pendingEvents.anyProbePackets()) {
return; return;
@@ -316,7 +319,7 @@ void QuicServerTransport::writeData() {
hasAcksToSchedule(conn_->ackStates.handshakeAckState))) { hasAcksToSchedule(conn_->ackStates.handshakeAckState))) {
CHECK(conn_->handshakeWriteCipher); CHECK(conn_->handshakeWriteCipher);
CHECK(conn_->handshakeWriteHeaderCipher); CHECK(conn_->handshakeWriteHeaderCipher);
packetLimit -= writeCryptoAndAckDataToSocket( auto res = writeCryptoAndAckDataToSocket(
*socket_, *socket_,
*conn_, *conn_,
srcConnId /* src */, srcConnId /* src */,
@@ -325,8 +328,10 @@ void QuicServerTransport::writeData() {
*conn_->handshakeWriteCipher, *conn_->handshakeWriteCipher,
*conn_->handshakeWriteHeaderCipher, *conn_->handshakeWriteHeaderCipher,
version, version,
packetLimit) packetLimit);
.packetsWritten;
packetLimit -= res.packetsWritten;
serverConn_->numHandshakeBytesSent += res.bytesWritten;
} }
if (!packetLimit && !conn_->pendingEvents.anyProbePackets()) { if (!packetLimit && !conn_->pendingEvents.anyProbePackets()) {
return; return;

View File

@@ -132,6 +132,9 @@ struct QuicServerConnectionState : public QuicConnectionStateBase {
// Whether we've sent the new_token frame yet. // Whether we've sent the new_token frame yet.
bool sentNewTokenFrame{false}; bool sentNewTokenFrame{false};
// Number of bytes the server has written during the handshake.
uint64_t numHandshakeBytesSent{0};
#ifdef CCP_ENABLED #ifdef CCP_ENABLED
// Pointer to struct that maintains state needed for interacting with libccp. // Pointer to struct that maintains state needed for interacting with libccp.
// Once instance of this struct is created for each instance of // Once instance of this struct is created for each instance of