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

Limit Quic PacketNumber to 2^62 -1

Summary: inspect PN, and when it reaches 2^62 -2 trigger a transport close through a pending event.

Reviewed By: yangchi

Differential Revision: D18239661

fbshipit-source-id: 1a218678099016693149e12ff121e2a39b95aecc
This commit is contained in:
Huzefa Zakir
2019-11-06 19:34:10 -08:00
committed by Facebook Github Bot
parent ed7646cad2
commit 42bfa9dc4a
6 changed files with 32 additions and 0 deletions

View File

@@ -378,6 +378,8 @@ constexpr uint64_t kMinNumAvailableConnIds = 8;
// default capability of QUIC partial reliability // default capability of QUIC partial reliability
constexpr TransportPartialReliabilitySetting kDefaultPartialReliability = false; constexpr TransportPartialReliabilitySetting kDefaultPartialReliability = false;
constexpr uint64_t kMaxPacketNumber = (1ull << 62) - 1;
enum class ZeroRttSourceTokenMatchingPolicy : uint8_t { enum class ZeroRttSourceTokenMatchingPolicy : uint8_t {
REJECT_IF_NO_EXACT_MATCH, REJECT_IF_NO_EXACT_MATCH,
LIMIT_IF_NO_EXACT_MATCH, LIMIT_IF_NO_EXACT_MATCH,

View File

@@ -2277,6 +2277,11 @@ void QuicTransportBase::writeSocketData() {
auto packetsBefore = conn_->outstandingPackets.size(); auto packetsBefore = conn_->outstandingPackets.size();
writeData(); writeData();
if (closeState_ != CloseState::CLOSED) { if (closeState_ != CloseState::CLOSED) {
if (conn_->pendingEvents.closeTransport == true) {
throw QuicTransportException(
"Max packet number reached",
TransportErrorCode::PROTOCOL_VIOLATION);
}
setLossDetectionAlarm(*conn_, *this); setLossDetectionAlarm(*conn_, *this);
auto packetsAfter = conn_->outstandingPackets.size(); auto packetsAfter = conn_->outstandingPackets.size();
bool packetWritten = (packetsAfter > packetsBefore); bool packetWritten = (packetsAfter > packetsBefore);

View File

@@ -356,6 +356,10 @@ class TestQuicTransport
closeImpl(folly::none, false, false); closeImpl(folly::none, false, false);
} }
void invokeWriteSocketData() {
writeSocketData();
}
QuicServerConnectionState* transportConn; QuicServerConnectionState* transportConn;
std::unique_ptr<Aead> aead; std::unique_ptr<Aead> aead;
std::unique_ptr<PacketNumberCipher> headerCipher; std::unique_ptr<PacketNumberCipher> headerCipher;
@@ -1285,7 +1289,14 @@ TEST_P(QuicTransportImplTestClose, TestNotifyPendingWriteOnCloseWithError) {
} }
evb->loopOnce(); evb->loopOnce();
} }
TEST_F(QuicTransportImplTest, TestTransportCloseWithMaxPacketNumber) {
transport->setServerConnectionId();
transport->transportConn->pendingEvents.closeTransport = false;
EXPECT_NO_THROW(transport->invokeWriteSocketData());
transport->transportConn->pendingEvents.closeTransport = true;
EXPECT_THROW(transport->invokeWriteSocketData(), QuicTransportException);
}
TEST_F(QuicTransportImplTest, TestGracefulCloseWithActiveStream) { TEST_F(QuicTransportImplTest, TestGracefulCloseWithActiveStream) {
EXPECT_CALL(connCallback, onConnectionEnd()).Times(0); EXPECT_CALL(connCallback, onConnectionEnd()).Times(0);
EXPECT_CALL(connCallback, onConnectionError(_)).Times(0); EXPECT_CALL(connCallback, onConnectionError(_)).Times(0);

View File

@@ -213,6 +213,9 @@ void increaseNextPacketNum(
QuicConnectionStateBase& conn, QuicConnectionStateBase& conn,
PacketNumberSpace pnSpace) noexcept { PacketNumberSpace pnSpace) noexcept {
getAckState(conn, pnSpace).nextPacketNum++; getAckState(conn, pnSpace).nextPacketNum++;
if (getAckState(conn, pnSpace).nextPacketNum == kMaxPacketNumber - 1) {
conn.pendingEvents.closeTransport = true;
}
} }
std::deque<OutstandingPacket>::iterator getFirstOutstandingPacket( std::deque<OutstandingPacket>::iterator getFirstOutstandingPacket(

View File

@@ -609,6 +609,9 @@ struct QuicConnectionStateBase {
uint8_t numProbePackets{0}; uint8_t numProbePackets{0};
bool cancelPingTimeout{false}; bool cancelPingTimeout{false};
// close transport when the next packet number reaches kMaxPacketNum
bool closeTransport{false};
}; };
PendingEvents pendingEvents; PendingEvents pendingEvents;

View File

@@ -584,6 +584,14 @@ TEST_F(QuicStateFunctionsTest, EarliestLossTimer) {
EXPECT_EQ(currentTime, earliestLossTimer(conn).first.value()); EXPECT_EQ(currentTime, earliestLossTimer(conn).first.value());
} }
TEST_P(QuicStateFunctionsTest, CloseTranportStateChange) {
QuicConnectionStateBase conn(QuicNodeType::Server);
getAckState(conn, GetParam()).nextPacketNum = kMaxPacketNumber - 2;
EXPECT_FALSE(conn.pendingEvents.closeTransport);
increaseNextPacketNum(conn, GetParam());
EXPECT_TRUE(conn.pendingEvents.closeTransport);
}
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
QuicStateFunctionsTests, QuicStateFunctionsTests,
QuicStateFunctionsTest, QuicStateFunctionsTest,