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

send d6d probe packets via writeD6DProbingDataToSocket

Summary:
This is the transport function that sends d6d probe to socket. It
- checks if there's the pending event `sendD6DProbePacket`, which will be set by upon d6d's probe timer expiration.
- uses the current probeSize to instantiate a D6DProbeScheduler, which will be changed by a small d6d state machine.

Reviewed By: yangchi

Differential Revision: D23193967

fbshipit-source-id: dfe6ce831cfd6ff0470e801644b95d4e8da34e87
This commit is contained in:
Xiaoting Tang
2020-09-14 22:27:53 -07:00
committed by Facebook GitHub Bot
parent 23f817100a
commit 1aec6b57f0
5 changed files with 96 additions and 0 deletions

View File

@@ -22,6 +22,7 @@ using DurationRep = std::chrono::microseconds::rep;
using namespace std::chrono_literals;
// Default QUIC packet size for both read and write.
// TODO(xtt): make them configurable
constexpr uint64_t kDefaultV4UDPSendPacketLen = 1252;
constexpr uint64_t kDefaultV6UDPSendPacketLen = 1232;
// With Android NDK r15c for some apps we use gnu-libstdc++ instead of

View File

@@ -1341,6 +1341,49 @@ uint64_t writeProbingDataToSocket(
return written;
}
uint64_t writeD6DProbeToSocket(
folly::AsyncUDPSocket& sock,
QuicConnectionStateBase& connection,
const ConnectionId& srcConnId,
const ConnectionId& dstConnId,
const Aead& aead,
const PacketNumberCipher& headerCipher,
QuicVersion version) {
if (!connection.pendingEvents.sendD6DProbePacket) {
return 0;
}
auto builder = ShortHeaderBuilder();
// D6D probe is always in AppData pnSpace
auto pnSpace = PacketNumberSpace::AppData;
// Skip a packet number for probing packets to elicit acks
increaseNextPacketNum(connection, pnSpace);
D6DProbeScheduler d6dProbeScheduler(
connection,
"D6DProbeScheduler",
aead.getCipherOverhead(),
connection.d6d.currentProbeSize);
auto written = writeConnectionDataToSocket(
sock,
connection,
srcConnId,
dstConnId,
builder,
pnSpace,
d6dProbeScheduler,
unlimitedWritableBytes,
1,
aead,
headerCipher,
version);
VLOG_IF(10, written > 0) << nodeToString(connection.nodeType)
<< " writing d6d probes using scheduler=D6DScheduler"
<< connection;
if (written > 0) {
connection.pendingEvents.sendD6DProbePacket = false;
}
return written;
}
WriteDataReason shouldWriteData(const QuicConnectionStateBase& conn) {
if (conn.pendingEvents.numProbePackets) {
VLOG(10) << nodeToString(conn.nodeType) << " needs write because of PTO"

View File

@@ -282,6 +282,15 @@ uint64_t writeProbingDataToSocket(
QuicVersion version,
const std::string& token = std::string());
uint64_t writeD6DProbeToSocket(
folly::AsyncUDPSocket& sock,
QuicConnectionStateBase& connection,
const ConnectionId& srcConnId,
const ConnectionId& dstConnId,
const Aead& aead,
const PacketNumberCipher& headerCipher,
QuicVersion version);
HeaderBuilder LongHeaderBuilder(LongHeader::Types packetType);
HeaderBuilder ShortHeaderBuilder();

View File

@@ -2519,5 +2519,42 @@ TEST_F(QuicTransportFunctionsTest, WriteProbingWithInplaceBuilder) {
EXPECT_EQ(conn->outstandings.packets.size(), outstandingPacketsCount + 3);
}
TEST_F(QuicTransportFunctionsTest, WriteD6DProbesWithInplaceBuilder) {
auto conn = createConn();
conn->transportSettings.dataPathType = DataPathType::ContinuousMemory;
conn->d6d.currentProbeSize = 1450;
conn->pendingEvents.sendD6DProbePacket = true;
auto simpleBufAccessor =
std::make_unique<SimpleBufAccessor>(kDefaultMaxUDPPayload * 16);
auto outputBuf = simpleBufAccessor->obtain();
auto bufPtr = outputBuf.get();
simpleBufAccessor->release(std::move(outputBuf));
conn->bufAccessor = simpleBufAccessor.get();
conn->transportSettings.batchingMode = QuicBatchingMode::BATCHING_MODE_GSO;
EventBase evb;
folly::test::MockAsyncUDPSocket mockSock(&evb);
EXPECT_CALL(mockSock, getGSO()).WillRepeatedly(Return(true));
EXPECT_CALL(mockSock, write(_, _))
.Times(1)
.WillOnce(Invoke([&](const SocketAddress&,
const std::unique_ptr<folly::IOBuf>& sockBuf) {
EXPECT_EQ(sockBuf->length(), conn->d6d.currentProbeSize);
EXPECT_EQ(sockBuf.get(), bufPtr);
EXPECT_TRUE(folly::IOBufEqualTo()(*sockBuf, *bufPtr));
EXPECT_FALSE(sockBuf->isChained());
return sockBuf->computeChainDataLength();
}));
writeD6DProbeToSocket(
mockSock,
*conn,
*conn->clientConnectionId,
*conn->serverConnectionId,
*aead,
*headerCipher,
getVersion(*conn));
EXPECT_EQ(0, bufPtr->length());
EXPECT_EQ(0, bufPtr->headroom());
}
} // namespace test
} // namespace quic

View File

@@ -626,6 +626,9 @@ struct QuicConnectionStateBase : public folly::DelayedDestruction {
// To send a ping frame
bool sendPing{false};
// To send a d6d probe packet
bool sendD6DProbePacket{false};
// Do we need to send data blocked frame when connection is blocked.
bool sendDataBlocked{false};
@@ -765,6 +768,9 @@ struct QuicConnectionStateBase : public folly::DelayedDestruction {
// The base PMTU to start probing with
uint16_t basePMTU{kDefaultD6DBasePMTU};
// Current probe size
uint32_t currentProbeSize{kDefaultD6DBasePMTU};
// The raise timeout
std::chrono::seconds raiseTimeout{kDefaultD6DRaiseTimeout};
};