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:
committed by
Facebook GitHub Bot
parent
23f817100a
commit
1aec6b57f0
@@ -22,6 +22,7 @@ using DurationRep = std::chrono::microseconds::rep;
|
|||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
// Default QUIC packet size for both read and write.
|
// Default QUIC packet size for both read and write.
|
||||||
|
// TODO(xtt): make them configurable
|
||||||
constexpr uint64_t kDefaultV4UDPSendPacketLen = 1252;
|
constexpr uint64_t kDefaultV4UDPSendPacketLen = 1252;
|
||||||
constexpr uint64_t kDefaultV6UDPSendPacketLen = 1232;
|
constexpr uint64_t kDefaultV6UDPSendPacketLen = 1232;
|
||||||
// With Android NDK r15c for some apps we use gnu-libstdc++ instead of
|
// With Android NDK r15c for some apps we use gnu-libstdc++ instead of
|
||||||
|
@@ -1341,6 +1341,49 @@ uint64_t writeProbingDataToSocket(
|
|||||||
return written;
|
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) {
|
WriteDataReason shouldWriteData(const QuicConnectionStateBase& conn) {
|
||||||
if (conn.pendingEvents.numProbePackets) {
|
if (conn.pendingEvents.numProbePackets) {
|
||||||
VLOG(10) << nodeToString(conn.nodeType) << " needs write because of PTO"
|
VLOG(10) << nodeToString(conn.nodeType) << " needs write because of PTO"
|
||||||
|
@@ -282,6 +282,15 @@ uint64_t writeProbingDataToSocket(
|
|||||||
QuicVersion version,
|
QuicVersion version,
|
||||||
const std::string& token = std::string());
|
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 LongHeaderBuilder(LongHeader::Types packetType);
|
||||||
HeaderBuilder ShortHeaderBuilder();
|
HeaderBuilder ShortHeaderBuilder();
|
||||||
|
|
||||||
|
@@ -2519,5 +2519,42 @@ TEST_F(QuicTransportFunctionsTest, WriteProbingWithInplaceBuilder) {
|
|||||||
EXPECT_EQ(conn->outstandings.packets.size(), outstandingPacketsCount + 3);
|
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 test
|
||||||
} // namespace quic
|
} // namespace quic
|
||||||
|
@@ -626,6 +626,9 @@ struct QuicConnectionStateBase : public folly::DelayedDestruction {
|
|||||||
// To send a ping frame
|
// To send a ping frame
|
||||||
bool sendPing{false};
|
bool sendPing{false};
|
||||||
|
|
||||||
|
// To send a d6d probe packet
|
||||||
|
bool sendD6DProbePacket{false};
|
||||||
|
|
||||||
// Do we need to send data blocked frame when connection is blocked.
|
// Do we need to send data blocked frame when connection is blocked.
|
||||||
bool sendDataBlocked{false};
|
bool sendDataBlocked{false};
|
||||||
|
|
||||||
@@ -765,6 +768,9 @@ struct QuicConnectionStateBase : public folly::DelayedDestruction {
|
|||||||
// The base PMTU to start probing with
|
// The base PMTU to start probing with
|
||||||
uint16_t basePMTU{kDefaultD6DBasePMTU};
|
uint16_t basePMTU{kDefaultD6DBasePMTU};
|
||||||
|
|
||||||
|
// Current probe size
|
||||||
|
uint32_t currentProbeSize{kDefaultD6DBasePMTU};
|
||||||
|
|
||||||
// The raise timeout
|
// The raise timeout
|
||||||
std::chrono::seconds raiseTimeout{kDefaultD6DRaiseTimeout};
|
std::chrono::seconds raiseTimeout{kDefaultD6DRaiseTimeout};
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user