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

Make the AckState for Initial/Handshake a unique_ptr

Summary:
We don't need to carry these states after the handshake is confirmed, so make them pointers instead. This will facilitate adding a structure to the AckState for tracking duplicate packets.

(Note: this ignores all push blocking failures!)

Reviewed By: hanidamlaj

Differential Revision: D41626895

fbshipit-source-id: d8ac960b3672b9bb9adaaececa53a1203ec801e0
This commit is contained in:
Matt Joras
2022-12-20 11:08:43 -08:00
committed by Facebook GitHub Bot
parent 1a41bc78cf
commit 1275798146
20 changed files with 281 additions and 217 deletions

View File

@@ -385,8 +385,12 @@ void QuicTransportBase::closeImpl(
conn_->pendingEvents = QuicConnectionStateBase::PendingEvents(); conn_->pendingEvents = QuicConnectionStateBase::PendingEvents();
conn_->streamManager->clearActionable(); conn_->streamManager->clearActionable();
conn_->streamManager->clearWritable(); conn_->streamManager->clearWritable();
conn_->ackStates.initialAckState.acks.clear(); if (conn_->ackStates.initialAckState) {
conn_->ackStates.handshakeAckState.acks.clear(); conn_->ackStates.initialAckState->acks.clear();
}
if (conn_->ackStates.handshakeAckState) {
conn_->ackStates.handshakeAckState->acks.clear();
}
conn_->ackStates.appDataAckState.acks.clear(); conn_->ackStates.appDataAckState.acks.clear();
if (transportReadyNotified_) { if (transportReadyNotified_) {

View File

@@ -49,9 +49,15 @@ std::string largestAckScheduledToString(
const quic::QuicConnectionStateBase& conn) noexcept { const quic::QuicConnectionStateBase& conn) noexcept {
return folly::to<std::string>( return folly::to<std::string>(
"[", "[",
optionalToString(conn.ackStates.initialAckState.largestAckScheduled), optionalToString(
conn.ackStates.initialAckState
? conn.ackStates.initialAckState->largestAckScheduled
: folly::none),
",", ",",
optionalToString(conn.ackStates.handshakeAckState.largestAckScheduled), optionalToString(
conn.ackStates.handshakeAckState
? conn.ackStates.handshakeAckState->largestAckScheduled
: folly::none),
",", ",",
optionalToString(conn.ackStates.appDataAckState.largestAckScheduled), optionalToString(conn.ackStates.appDataAckState.largestAckScheduled),
"]"); "]");
@@ -61,35 +67,20 @@ std::string largestAckToSendToString(
const quic::QuicConnectionStateBase& conn) noexcept { const quic::QuicConnectionStateBase& conn) noexcept {
return folly::to<std::string>( return folly::to<std::string>(
"[", "[",
optionalToString(largestAckToSend(conn.ackStates.initialAckState)), optionalToString(
conn.ackStates.initialAckState
? largestAckToSend(*conn.ackStates.initialAckState)
: folly::none),
",", ",",
optionalToString(largestAckToSend(conn.ackStates.handshakeAckState)), optionalToString(
conn.ackStates.handshakeAckState
? largestAckToSend(*conn.ackStates.handshakeAckState)
: folly::none),
",", ",",
optionalToString(largestAckToSend(conn.ackStates.appDataAckState)), optionalToString(largestAckToSend(conn.ackStates.appDataAckState)),
"]"); "]");
} }
bool toWriteInitialAcks(const quic::QuicConnectionStateBase& conn) {
return (
conn.initialWriteCipher &&
hasAcksToSchedule(conn.ackStates.initialAckState) &&
conn.ackStates.initialAckState.needsToSendAckImmediately);
}
bool toWriteHandshakeAcks(const quic::QuicConnectionStateBase& conn) {
return (
conn.handshakeWriteCipher &&
hasAcksToSchedule(conn.ackStates.handshakeAckState) &&
conn.ackStates.handshakeAckState.needsToSendAckImmediately);
}
bool toWriteAppDataAcks(const quic::QuicConnectionStateBase& conn) {
return (
conn.oneRttWriteCipher &&
hasAcksToSchedule(conn.ackStates.appDataAckState) &&
conn.ackStates.appDataAckState.needsToSendAckImmediately);
}
using namespace quic; using namespace quic;
/** /**
@@ -1796,11 +1787,13 @@ void handshakeConfirmed(QuicConnectionStateBase& conn) {
conn.readCodec->setInitialReadCipher(nullptr); conn.readCodec->setInitialReadCipher(nullptr);
conn.readCodec->setInitialHeaderCipher(nullptr); conn.readCodec->setInitialHeaderCipher(nullptr);
implicitAckCryptoStream(conn, EncryptionLevel::Initial); implicitAckCryptoStream(conn, EncryptionLevel::Initial);
conn.ackStates.initialAckState.reset();
conn.handshakeWriteCipher.reset(); conn.handshakeWriteCipher.reset();
conn.handshakeWriteHeaderCipher.reset(); conn.handshakeWriteHeaderCipher.reset();
conn.readCodec->setHandshakeReadCipher(nullptr); conn.readCodec->setHandshakeReadCipher(nullptr);
conn.readCodec->setHandshakeHeaderCipher(nullptr); conn.readCodec->setHandshakeHeaderCipher(nullptr);
implicitAckCryptoStream(conn, EncryptionLevel::Handshake); implicitAckCryptoStream(conn, EncryptionLevel::Handshake);
conn.ackStates.handshakeAckState.reset();
} }
bool hasInitialOrHandshakeCiphers(QuicConnectionStateBase& conn) { bool hasInitialOrHandshakeCiphers(QuicConnectionStateBase& conn) {
@@ -1839,4 +1832,25 @@ bool setCustomTransportParameter(
return true; return true;
} }
bool toWriteInitialAcks(const quic::QuicConnectionStateBase& conn) {
return (
conn.initialWriteCipher && conn.ackStates.initialAckState &&
hasAcksToSchedule(*conn.ackStates.initialAckState) &&
conn.ackStates.initialAckState->needsToSendAckImmediately);
}
bool toWriteHandshakeAcks(const quic::QuicConnectionStateBase& conn) {
return (
conn.handshakeWriteCipher && conn.ackStates.handshakeAckState &&
hasAcksToSchedule(*conn.ackStates.handshakeAckState) &&
conn.ackStates.handshakeAckState->needsToSendAckImmediately);
}
bool toWriteAppDataAcks(const quic::QuicConnectionStateBase& conn) {
return (
conn.oneRttWriteCipher &&
hasAcksToSchedule(conn.ackStates.appDataAckState) &&
conn.ackStates.appDataAckState.needsToSendAckImmediately);
}
} // namespace quic } // namespace quic

View File

@@ -344,4 +344,8 @@ bool setCustomTransportParameter(
std::unique_ptr<CustomTransportParameter> customParam, std::unique_ptr<CustomTransportParameter> customParam,
std::vector<TransportParameter>& customTransportParameters); std::vector<TransportParameter>& customTransportParameters);
bool toWriteInitialAcks(const quic::QuicConnectionStateBase& conn);
bool toWriteHandshakeAcks(const quic::QuicConnectionStateBase& conn);
bool toWriteAppDataAcks(const quic::QuicConnectionStateBase& conn);
} // namespace quic } // namespace quic

View File

@@ -175,7 +175,7 @@ TEST_F(QuicPacketSchedulerTest, CryptoPaddingInitialPacket) {
RegularQuicPacketBuilder builder( RegularQuicPacketBuilder builder(
conn.udpSendPacketLen, conn.udpSendPacketLen,
std::move(longHeader), std::move(longHeader),
conn.ackStates.initialAckState.largestAckedByPeer.value_or(0)); conn.ackStates.initialAckState->largestAckedByPeer.value_or(0));
FrameScheduler cryptoOnlyScheduler = FrameScheduler cryptoOnlyScheduler =
std::move( std::move(
FrameScheduler::Builder( FrameScheduler::Builder(
@@ -207,10 +207,10 @@ TEST_F(QuicPacketSchedulerTest, PaddingInitialPureAcks) {
RegularQuicPacketBuilder builder( RegularQuicPacketBuilder builder(
conn.udpSendPacketLen, conn.udpSendPacketLen,
std::move(longHeader), std::move(longHeader),
conn.ackStates.handshakeAckState.largestAckedByPeer.value_or(0)); conn.ackStates.handshakeAckState->largestAckedByPeer.value_or(0));
conn.ackStates.initialAckState.largestRecvdPacketTime = Clock::now(); conn.ackStates.initialAckState->largestRecvdPacketTime = Clock::now();
conn.ackStates.initialAckState.needsToSendAckImmediately = true; conn.ackStates.initialAckState->needsToSendAckImmediately = true;
conn.ackStates.initialAckState.acks.insert(10); conn.ackStates.initialAckState->acks.insert(10);
FrameScheduler acksOnlyScheduler = FrameScheduler acksOnlyScheduler =
std::move( std::move(
FrameScheduler::Builder( FrameScheduler::Builder(
@@ -241,10 +241,10 @@ TEST_F(QuicPacketSchedulerTest, InitialPaddingDoesNotUseWrapper) {
RegularQuicPacketBuilder builder( RegularQuicPacketBuilder builder(
conn.udpSendPacketLen, conn.udpSendPacketLen,
std::move(longHeader), std::move(longHeader),
conn.ackStates.handshakeAckState.largestAckedByPeer.value_or(0)); conn.ackStates.handshakeAckState->largestAckedByPeer.value_or(0));
conn.ackStates.initialAckState.largestRecvdPacketTime = Clock::now(); conn.ackStates.initialAckState->largestRecvdPacketTime = Clock::now();
conn.ackStates.initialAckState.needsToSendAckImmediately = true; conn.ackStates.initialAckState->needsToSendAckImmediately = true;
conn.ackStates.initialAckState.acks.insert(10); conn.ackStates.initialAckState->acks.insert(10);
FrameScheduler acksOnlyScheduler = FrameScheduler acksOnlyScheduler =
std::move( std::move(
FrameScheduler::Builder( FrameScheduler::Builder(
@@ -275,7 +275,7 @@ TEST_F(QuicPacketSchedulerTest, CryptoServerInitialPadded) {
RegularQuicPacketBuilder builder1( RegularQuicPacketBuilder builder1(
conn.udpSendPacketLen, conn.udpSendPacketLen,
std::move(longHeader1), std::move(longHeader1),
conn.ackStates.initialAckState.largestAckedByPeer.value_or(0)); conn.ackStates.initialAckState->largestAckedByPeer.value_or(0));
FrameScheduler scheduler = FrameScheduler scheduler =
std::move( std::move(
FrameScheduler::Builder( FrameScheduler::Builder(
@@ -308,7 +308,7 @@ TEST_F(QuicPacketSchedulerTest, PadTwoInitialPackets) {
RegularQuicPacketBuilder builder1( RegularQuicPacketBuilder builder1(
conn.udpSendPacketLen, conn.udpSendPacketLen,
std::move(longHeader1), std::move(longHeader1),
conn.ackStates.initialAckState.largestAckedByPeer.value_or(0)); conn.ackStates.initialAckState->largestAckedByPeer.value_or(0));
FrameScheduler scheduler = FrameScheduler scheduler =
std::move( std::move(
FrameScheduler::Builder( FrameScheduler::Builder(
@@ -336,7 +336,7 @@ TEST_F(QuicPacketSchedulerTest, PadTwoInitialPackets) {
RegularQuicPacketBuilder builder2( RegularQuicPacketBuilder builder2(
conn.udpSendPacketLen, conn.udpSendPacketLen,
std::move(longHeader2), std::move(longHeader2),
conn.ackStates.initialAckState.largestAckedByPeer.value_or(0)); conn.ackStates.initialAckState->largestAckedByPeer.value_or(0));
writeDataToQuicStream( writeDataToQuicStream(
conn.cryptoState->initialStream, folly::IOBuf::copyBuffer("shlo again")); conn.cryptoState->initialStream, folly::IOBuf::copyBuffer("shlo again"));
auto result2 = scheduler.scheduleFramesForPacket( auto result2 = scheduler.scheduleFramesForPacket(
@@ -359,7 +359,7 @@ TEST_F(QuicPacketSchedulerTest, CryptoPaddingRetransmissionClientInitial) {
RegularQuicPacketBuilder builder( RegularQuicPacketBuilder builder(
conn.udpSendPacketLen, conn.udpSendPacketLen,
std::move(longHeader), std::move(longHeader),
conn.ackStates.initialAckState.largestAckedByPeer.value_or(0)); conn.ackStates.initialAckState->largestAckedByPeer.value_or(0));
FrameScheduler scheduler = FrameScheduler scheduler =
std::move( std::move(
FrameScheduler::Builder( FrameScheduler::Builder(
@@ -391,7 +391,7 @@ TEST_F(QuicPacketSchedulerTest, CryptoSchedulerOnlySingleLossFits) {
RegularQuicPacketBuilder builder( RegularQuicPacketBuilder builder(
conn.udpSendPacketLen, conn.udpSendPacketLen,
std::move(longHeader), std::move(longHeader),
conn.ackStates.handshakeAckState.largestAckedByPeer.value_or(0)); conn.ackStates.handshakeAckState->largestAckedByPeer.value_or(0));
builder.encodePacketHeader(); builder.encodePacketHeader();
PacketBuilderWrapper builderWrapper(builder, 13); PacketBuilderWrapper builderWrapper(builder, 13);
CryptoStreamScheduler scheduler( CryptoStreamScheduler scheduler(
@@ -419,8 +419,8 @@ TEST_F(QuicPacketSchedulerTest, CryptoWritePartialLossBuffer) {
RegularQuicPacketBuilder builder( RegularQuicPacketBuilder builder(
25, 25,
std::move(longHeader), std::move(longHeader),
conn.ackStates.initialAckState.largestAckedByPeer.value_or( conn.ackStates.initialAckState->largestAckedByPeer.value_or(
conn.ackStates.initialAckState.nextPacketNum)); conn.ackStates.initialAckState->nextPacketNum));
FrameScheduler cryptoOnlyScheduler = FrameScheduler cryptoOnlyScheduler =
std::move( std::move(
FrameScheduler::Builder( FrameScheduler::Builder(
@@ -712,7 +712,7 @@ TEST_F(QuicPacketSchedulerTest, DoNotCloneProcessedClonedPacket) {
RegularQuicPacketBuilder builder( RegularQuicPacketBuilder builder(
conn.udpSendPacketLen, conn.udpSendPacketLen,
std::move(header), std::move(header),
conn.ackStates.initialAckState.largestAckedByPeer.value_or(0)); conn.ackStates.initialAckState->largestAckedByPeer.value_or(0));
auto result = cloningScheduler.scheduleFramesForPacket( auto result = cloningScheduler.scheduleFramesForPacket(
std::move(builder), kDefaultUDPSendPacketLen); std::move(builder), kDefaultUDPSendPacketLen);
EXPECT_TRUE(result.packetEvent.has_value() && result.packet.has_value()); EXPECT_TRUE(result.packetEvent.has_value() && result.packet.has_value());
@@ -767,8 +767,8 @@ TEST_F(QuicPacketSchedulerTest, CloneSchedulerHasHandshakeDataAndAcks) {
WriteCryptoFrame(0, 4)); WriteCryptoFrame(0, 4));
// Make it look like we received some acks from the peer. // Make it look like we received some acks from the peer.
conn.ackStates.handshakeAckState.acks.insert(10); conn.ackStates.handshakeAckState->acks.insert(10);
conn.ackStates.handshakeAckState.largestRecvdPacketTime = Clock::now(); conn.ackStates.handshakeAckState->largestRecvdPacketTime = Clock::now();
// Create cloning scheduler. // Create cloning scheduler.
CloningScheduler cloningScheduler(noopScheduler, conn, "CopyCat", 0); CloningScheduler cloningScheduler(noopScheduler, conn, "CopyCat", 0);
@@ -1184,19 +1184,19 @@ class AckSchedulingTest : public TestWithParam<PacketNumberSpace> {};
TEST_F(QuicPacketSchedulerTest, AckStateHasAcksToSchedule) { TEST_F(QuicPacketSchedulerTest, AckStateHasAcksToSchedule) {
QuicClientConnectionState conn( QuicClientConnectionState conn(
FizzClientQuicHandshakeContext::Builder().build()); FizzClientQuicHandshakeContext::Builder().build());
EXPECT_FALSE(hasAcksToSchedule(conn.ackStates.initialAckState)); EXPECT_FALSE(hasAcksToSchedule(*conn.ackStates.initialAckState));
EXPECT_FALSE(hasAcksToSchedule(conn.ackStates.handshakeAckState)); EXPECT_FALSE(hasAcksToSchedule(*conn.ackStates.handshakeAckState));
EXPECT_FALSE(hasAcksToSchedule(conn.ackStates.appDataAckState)); EXPECT_FALSE(hasAcksToSchedule(conn.ackStates.appDataAckState));
conn.ackStates.initialAckState.acks.insert(0, 100); conn.ackStates.initialAckState->acks.insert(0, 100);
EXPECT_TRUE(hasAcksToSchedule(conn.ackStates.initialAckState)); EXPECT_TRUE(hasAcksToSchedule(*conn.ackStates.initialAckState));
conn.ackStates.handshakeAckState.acks.insert(0, 100); conn.ackStates.handshakeAckState->acks.insert(0, 100);
conn.ackStates.handshakeAckState.largestAckScheduled = 200; conn.ackStates.handshakeAckState->largestAckScheduled = 200;
EXPECT_FALSE(hasAcksToSchedule(conn.ackStates.handshakeAckState)); EXPECT_FALSE(hasAcksToSchedule(*conn.ackStates.handshakeAckState));
conn.ackStates.handshakeAckState.largestAckScheduled = folly::none; conn.ackStates.handshakeAckState->largestAckScheduled = folly::none;
EXPECT_TRUE(hasAcksToSchedule(conn.ackStates.handshakeAckState)); EXPECT_TRUE(hasAcksToSchedule(*conn.ackStates.handshakeAckState));
} }
TEST_F(QuicPacketSchedulerTest, AckSchedulerHasAcksToSchedule) { TEST_F(QuicPacketSchedulerTest, AckSchedulerHasAcksToSchedule) {
@@ -1212,30 +1212,30 @@ TEST_F(QuicPacketSchedulerTest, AckSchedulerHasAcksToSchedule) {
EXPECT_FALSE(handshakeAckScheduler.hasPendingAcks()); EXPECT_FALSE(handshakeAckScheduler.hasPendingAcks());
EXPECT_FALSE(appDataAckScheduler.hasPendingAcks()); EXPECT_FALSE(appDataAckScheduler.hasPendingAcks());
conn.ackStates.initialAckState.acks.insert(0, 100); conn.ackStates.initialAckState->acks.insert(0, 100);
EXPECT_TRUE(initialAckScheduler.hasPendingAcks()); EXPECT_TRUE(initialAckScheduler.hasPendingAcks());
conn.ackStates.handshakeAckState.acks.insert(0, 100); conn.ackStates.handshakeAckState->acks.insert(0, 100);
conn.ackStates.handshakeAckState.largestAckScheduled = 200; conn.ackStates.handshakeAckState->largestAckScheduled = 200;
EXPECT_FALSE(handshakeAckScheduler.hasPendingAcks()); EXPECT_FALSE(handshakeAckScheduler.hasPendingAcks());
conn.ackStates.handshakeAckState.largestAckScheduled = folly::none; conn.ackStates.handshakeAckState->largestAckScheduled = folly::none;
EXPECT_TRUE(handshakeAckScheduler.hasPendingAcks()); EXPECT_TRUE(handshakeAckScheduler.hasPendingAcks());
} }
TEST_F(QuicPacketSchedulerTest, LargestAckToSend) { TEST_F(QuicPacketSchedulerTest, LargestAckToSend) {
QuicClientConnectionState conn( QuicClientConnectionState conn(
FizzClientQuicHandshakeContext::Builder().build()); FizzClientQuicHandshakeContext::Builder().build());
EXPECT_EQ(folly::none, largestAckToSend(conn.ackStates.initialAckState)); EXPECT_EQ(folly::none, largestAckToSend(*conn.ackStates.initialAckState));
EXPECT_EQ(folly::none, largestAckToSend(conn.ackStates.handshakeAckState)); EXPECT_EQ(folly::none, largestAckToSend(*conn.ackStates.handshakeAckState));
EXPECT_EQ(folly::none, largestAckToSend(conn.ackStates.appDataAckState)); EXPECT_EQ(folly::none, largestAckToSend(conn.ackStates.appDataAckState));
conn.ackStates.initialAckState.acks.insert(0, 50); conn.ackStates.initialAckState->acks.insert(0, 50);
conn.ackStates.handshakeAckState.acks.insert(0, 50); conn.ackStates.handshakeAckState->acks.insert(0, 50);
conn.ackStates.handshakeAckState.acks.insert(75, 150); conn.ackStates.handshakeAckState->acks.insert(75, 150);
EXPECT_EQ(50, *largestAckToSend(conn.ackStates.initialAckState)); EXPECT_EQ(50, *largestAckToSend(*conn.ackStates.initialAckState));
EXPECT_EQ(150, *largestAckToSend(conn.ackStates.handshakeAckState)); EXPECT_EQ(150, *largestAckToSend(*conn.ackStates.handshakeAckState));
EXPECT_EQ(folly::none, largestAckToSend(conn.ackStates.appDataAckState)); EXPECT_EQ(folly::none, largestAckToSend(conn.ackStates.appDataAckState));
} }
@@ -1253,18 +1253,18 @@ TEST_F(QuicPacketSchedulerTest, NeedsToSendAckWithoutAcksAvailable) {
EXPECT_FALSE(handshakeAckScheduler.hasPendingAcks()); EXPECT_FALSE(handshakeAckScheduler.hasPendingAcks());
EXPECT_FALSE(appDataAckScheduler.hasPendingAcks()); EXPECT_FALSE(appDataAckScheduler.hasPendingAcks());
conn.ackStates.initialAckState.needsToSendAckImmediately = true; conn.ackStates.initialAckState->needsToSendAckImmediately = true;
conn.ackStates.handshakeAckState.needsToSendAckImmediately = true; conn.ackStates.handshakeAckState->needsToSendAckImmediately = true;
conn.ackStates.appDataAckState.needsToSendAckImmediately = true; conn.ackStates.appDataAckState.needsToSendAckImmediately = true;
conn.ackStates.initialAckState.acks.insert(0, 100); conn.ackStates.initialAckState->acks.insert(0, 100);
EXPECT_TRUE(initialAckScheduler.hasPendingAcks()); EXPECT_TRUE(initialAckScheduler.hasPendingAcks());
conn.ackStates.handshakeAckState.acks.insert(0, 100); conn.ackStates.handshakeAckState->acks.insert(0, 100);
conn.ackStates.handshakeAckState.largestAckScheduled = 200; conn.ackStates.handshakeAckState->largestAckScheduled = 200;
EXPECT_FALSE(handshakeAckScheduler.hasPendingAcks()); EXPECT_FALSE(handshakeAckScheduler.hasPendingAcks());
conn.ackStates.handshakeAckState.largestAckScheduled = folly::none; conn.ackStates.handshakeAckState->largestAckScheduled = folly::none;
EXPECT_TRUE(handshakeAckScheduler.hasPendingAcks()); EXPECT_TRUE(handshakeAckScheduler.hasPendingAcks());
} }
@@ -2380,7 +2380,7 @@ TEST_F(QuicPacketSchedulerTest, ImmediateAckFrameSchedulerOnRequest) {
RegularQuicPacketBuilder builder( RegularQuicPacketBuilder builder(
conn.udpSendPacketLen, conn.udpSendPacketLen,
std::move(longHeader), std::move(longHeader),
conn.ackStates.initialAckState.largestAckedByPeer.value_or(0)); conn.ackStates.initialAckState->largestAckedByPeer.value_or(0));
FrameScheduler immediateAckOnlyScheduler = FrameScheduler immediateAckOnlyScheduler =
std::move( std::move(
@@ -2416,7 +2416,7 @@ TEST_F(QuicPacketSchedulerTest, ImmediateAckFrameSchedulerNotRequested) {
RegularQuicPacketBuilder builder( RegularQuicPacketBuilder builder(
conn.udpSendPacketLen, conn.udpSendPacketLen,
std::move(longHeader), std::move(longHeader),
conn.ackStates.initialAckState.largestAckedByPeer.value_or(0)); conn.ackStates.initialAckState->largestAckedByPeer.value_or(0));
FrameScheduler immediateAckOnlyScheduler = FrameScheduler immediateAckOnlyScheduler =
std::move( std::move(

View File

@@ -841,7 +841,7 @@ TEST_P(QuicTransportImplTestBase, WriteAckPacketUnsetsLooper) {
pktHasCryptoData, pktHasCryptoData,
Clock::now()); Clock::now());
ASSERT_TRUE(transport->transportConn->ackStates.initialAckState ASSERT_TRUE(transport->transportConn->ackStates.initialAckState
.needsToSendAckImmediately); ->needsToSendAckImmediately);
// Trigger the loop callback. This will trigger writes and we assume this will // Trigger the loop callback. This will trigger writes and we assume this will
// write the acks since we have nothing else to write. // write the acks since we have nothing else to write.
transport->writeLooper()->runLoopCallback(); transport->writeLooper()->runLoopCallback();

View File

@@ -114,14 +114,14 @@ auto buildEmptyPacket(
LongHeader::Types::Initial, LongHeader::Types::Initial,
*conn.clientConnectionId, *conn.clientConnectionId,
*conn.serverConnectionId, *conn.serverConnectionId,
conn.ackStates.initialAckState.nextPacketNum, conn.ackStates.initialAckState->nextPacketNum,
*conn.version); *conn.version);
} else if (pnSpace == PacketNumberSpace::Handshake) { } else if (pnSpace == PacketNumberSpace::Handshake) {
header = LongHeader( header = LongHeader(
LongHeader::Types::Handshake, LongHeader::Types::Handshake,
*conn.clientConnectionId, *conn.clientConnectionId,
*conn.serverConnectionId, *conn.serverConnectionId,
conn.ackStates.handshakeAckState.nextPacketNum, conn.ackStates.handshakeAckState->nextPacketNum,
*conn.version); *conn.version);
} else if (pnSpace == PacketNumberSpace::AppData) { } else if (pnSpace == PacketNumberSpace::AppData) {
header = LongHeader( header = LongHeader(
@@ -249,9 +249,9 @@ TEST_F(QuicTransportFunctionsTest, TestUpdateConnection) {
packet.packet.frames.push_back(std::move(writeStreamFrame2)); packet.packet.frames.push_back(std::move(writeStreamFrame2));
auto currentNextInitialPacketNum = auto currentNextInitialPacketNum =
conn->ackStates.initialAckState.nextPacketNum; conn->ackStates.initialAckState->nextPacketNum;
auto currentNextHandshakePacketNum = auto currentNextHandshakePacketNum =
conn->ackStates.handshakeAckState.nextPacketNum; conn->ackStates.handshakeAckState->nextPacketNum;
auto currentNextAppDataPacketNum = auto currentNextAppDataPacketNum =
conn->ackStates.appDataAckState.nextPacketNum; conn->ackStates.appDataAckState.nextPacketNum;
EXPECT_CALL(*rawCongestionController, onPacketSent(_)).Times(1); EXPECT_CALL(*rawCongestionController, onPacketSent(_)).Times(1);
@@ -268,10 +268,10 @@ TEST_F(QuicTransportFunctionsTest, TestUpdateConnection) {
false /* isDSRPacket */); false /* isDSRPacket */);
EXPECT_EQ( EXPECT_EQ(
conn->ackStates.initialAckState.nextPacketNum, conn->ackStates.initialAckState->nextPacketNum,
currentNextInitialPacketNum); currentNextInitialPacketNum);
EXPECT_GT( EXPECT_GT(
conn->ackStates.handshakeAckState.nextPacketNum, conn->ackStates.handshakeAckState->nextPacketNum,
currentNextHandshakePacketNum); currentNextHandshakePacketNum);
EXPECT_EQ( EXPECT_EQ(
conn->ackStates.appDataAckState.nextPacketNum, conn->ackStates.appDataAckState.nextPacketNum,
@@ -313,9 +313,9 @@ TEST_F(QuicTransportFunctionsTest, TestUpdateConnection) {
packet2.packet.frames.push_back(std::move(writeStreamFrame5)); packet2.packet.frames.push_back(std::move(writeStreamFrame5));
EXPECT_CALL(*rawCongestionController, onPacketSent(_)).Times(1); EXPECT_CALL(*rawCongestionController, onPacketSent(_)).Times(1);
currentNextInitialPacketNum = conn->ackStates.initialAckState.nextPacketNum; currentNextInitialPacketNum = conn->ackStates.initialAckState->nextPacketNum;
currentNextHandshakePacketNum = currentNextHandshakePacketNum =
conn->ackStates.handshakeAckState.nextPacketNum; conn->ackStates.handshakeAckState->nextPacketNum;
currentNextAppDataPacketNum = conn->ackStates.appDataAckState.nextPacketNum; currentNextAppDataPacketNum = conn->ackStates.appDataAckState.nextPacketNum;
EXPECT_CALL(*rawCongestionController, isAppLimited()) EXPECT_CALL(*rawCongestionController, isAppLimited())
.Times(1) .Times(1)
@@ -329,10 +329,10 @@ TEST_F(QuicTransportFunctionsTest, TestUpdateConnection) {
getEncodedBodySize(packet2), getEncodedBodySize(packet2),
false /* isDSRPacket */); false /* isDSRPacket */);
EXPECT_EQ( EXPECT_EQ(
conn->ackStates.initialAckState.nextPacketNum, conn->ackStates.initialAckState->nextPacketNum,
currentNextInitialPacketNum); currentNextInitialPacketNum);
EXPECT_GT( EXPECT_GT(
conn->ackStates.handshakeAckState.nextPacketNum, conn->ackStates.handshakeAckState->nextPacketNum,
currentNextHandshakePacketNum); currentNextHandshakePacketNum);
EXPECT_EQ( EXPECT_EQ(
conn->ackStates.appDataAckState.nextPacketNum, conn->ackStates.appDataAckState.nextPacketNum,
@@ -430,9 +430,9 @@ TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionPacketRetrans) {
// mimic send, call updateConnection // mimic send, call updateConnection
auto currentNextInitialPacketNum = auto currentNextInitialPacketNum =
conn->ackStates.initialAckState.nextPacketNum; conn->ackStates.initialAckState->nextPacketNum;
auto currentNextHandshakePacketNum = auto currentNextHandshakePacketNum =
conn->ackStates.handshakeAckState.nextPacketNum; conn->ackStates.handshakeAckState->nextPacketNum;
auto currentNextAppDataPacketNum = auto currentNextAppDataPacketNum =
conn->ackStates.appDataAckState.nextPacketNum; conn->ackStates.appDataAckState.nextPacketNum;
EXPECT_CALL(*rawCongestionController, onPacketSent(_)).Times(1); EXPECT_CALL(*rawCongestionController, onPacketSent(_)).Times(1);
@@ -450,10 +450,10 @@ TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionPacketRetrans) {
// appData packet number should increase // appData packet number should increase
EXPECT_EQ( EXPECT_EQ(
conn->ackStates.initialAckState.nextPacketNum, conn->ackStates.initialAckState->nextPacketNum,
currentNextInitialPacketNum); // no change currentNextInitialPacketNum); // no change
EXPECT_EQ( EXPECT_EQ(
conn->ackStates.handshakeAckState.nextPacketNum, conn->ackStates.handshakeAckState->nextPacketNum,
currentNextHandshakePacketNum); // no change currentNextHandshakePacketNum); // no change
EXPECT_GT( EXPECT_GT(
conn->ackStates.appDataAckState.nextPacketNum, conn->ackStates.appDataAckState.nextPacketNum,
@@ -494,9 +494,9 @@ TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionPacketRetrans) {
// mimic send, call updateConnection // mimic send, call updateConnection
EXPECT_CALL(*rawCongestionController, onPacketSent(_)).Times(1); EXPECT_CALL(*rawCongestionController, onPacketSent(_)).Times(1);
currentNextInitialPacketNum = conn->ackStates.initialAckState.nextPacketNum; currentNextInitialPacketNum = conn->ackStates.initialAckState->nextPacketNum;
currentNextHandshakePacketNum = currentNextHandshakePacketNum =
conn->ackStates.handshakeAckState.nextPacketNum; conn->ackStates.handshakeAckState->nextPacketNum;
currentNextAppDataPacketNum = conn->ackStates.appDataAckState.nextPacketNum; currentNextAppDataPacketNum = conn->ackStates.appDataAckState.nextPacketNum;
EXPECT_CALL(*rawCongestionController, isAppLimited()) EXPECT_CALL(*rawCongestionController, isAppLimited())
.Times(1) .Times(1)
@@ -510,10 +510,10 @@ TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionPacketRetrans) {
getEncodedBodySize(packet2), getEncodedBodySize(packet2),
false /* isDSRPacket */); false /* isDSRPacket */);
EXPECT_EQ( EXPECT_EQ(
conn->ackStates.initialAckState.nextPacketNum, conn->ackStates.initialAckState->nextPacketNum,
currentNextInitialPacketNum); // no change currentNextInitialPacketNum); // no change
EXPECT_EQ( EXPECT_EQ(
conn->ackStates.handshakeAckState.nextPacketNum, conn->ackStates.handshakeAckState->nextPacketNum,
currentNextHandshakePacketNum); // no change currentNextHandshakePacketNum); // no change
EXPECT_GT( EXPECT_GT(
conn->ackStates.appDataAckState.nextPacketNum, conn->ackStates.appDataAckState.nextPacketNum,
@@ -598,9 +598,9 @@ TEST_F(
// mimic send, call updateConnection // mimic send, call updateConnection
auto currentNextInitialPacketNum = auto currentNextInitialPacketNum =
conn->ackStates.initialAckState.nextPacketNum; conn->ackStates.initialAckState->nextPacketNum;
auto currentNextHandshakePacketNum = auto currentNextHandshakePacketNum =
conn->ackStates.handshakeAckState.nextPacketNum; conn->ackStates.handshakeAckState->nextPacketNum;
auto currentNextAppDataPacketNum = auto currentNextAppDataPacketNum =
conn->ackStates.appDataAckState.nextPacketNum; conn->ackStates.appDataAckState.nextPacketNum;
EXPECT_CALL(*rawCongestionController, onPacketSent(_)).Times(1); EXPECT_CALL(*rawCongestionController, onPacketSent(_)).Times(1);
@@ -618,10 +618,10 @@ TEST_F(
// appData packet number should increase // appData packet number should increase
EXPECT_EQ( EXPECT_EQ(
conn->ackStates.initialAckState.nextPacketNum, conn->ackStates.initialAckState->nextPacketNum,
currentNextInitialPacketNum); // no change currentNextInitialPacketNum); // no change
EXPECT_EQ( EXPECT_EQ(
conn->ackStates.handshakeAckState.nextPacketNum, conn->ackStates.handshakeAckState->nextPacketNum,
currentNextHandshakePacketNum); // no change currentNextHandshakePacketNum); // no change
EXPECT_GT( EXPECT_GT(
conn->ackStates.appDataAckState.nextPacketNum, conn->ackStates.appDataAckState.nextPacketNum,
@@ -683,9 +683,9 @@ TEST_F(
// mimic send, call updateConnection // mimic send, call updateConnection
EXPECT_CALL(*rawCongestionController, onPacketSent(_)).Times(1); EXPECT_CALL(*rawCongestionController, onPacketSent(_)).Times(1);
currentNextInitialPacketNum = conn->ackStates.initialAckState.nextPacketNum; currentNextInitialPacketNum = conn->ackStates.initialAckState->nextPacketNum;
currentNextHandshakePacketNum = currentNextHandshakePacketNum =
conn->ackStates.handshakeAckState.nextPacketNum; conn->ackStates.handshakeAckState->nextPacketNum;
currentNextAppDataPacketNum = conn->ackStates.appDataAckState.nextPacketNum; currentNextAppDataPacketNum = conn->ackStates.appDataAckState.nextPacketNum;
EXPECT_CALL(*rawCongestionController, isAppLimited()) EXPECT_CALL(*rawCongestionController, isAppLimited())
.Times(1) .Times(1)
@@ -699,10 +699,10 @@ TEST_F(
getEncodedBodySize(packet2), getEncodedBodySize(packet2),
false /* isDSRPacket */); false /* isDSRPacket */);
EXPECT_EQ( EXPECT_EQ(
conn->ackStates.initialAckState.nextPacketNum, conn->ackStates.initialAckState->nextPacketNum,
currentNextInitialPacketNum); // no change currentNextInitialPacketNum); // no change
EXPECT_EQ( EXPECT_EQ(
conn->ackStates.handshakeAckState.nextPacketNum, conn->ackStates.handshakeAckState->nextPacketNum,
currentNextHandshakePacketNum); // no change currentNextHandshakePacketNum); // no change
EXPECT_GT( EXPECT_GT(
conn->ackStates.appDataAckState.nextPacketNum, conn->ackStates.appDataAckState.nextPacketNum,
@@ -782,8 +782,8 @@ TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionD6DNeedsAppDataPNSpace) {
TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionPacketSorting) { TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionPacketSorting) {
auto conn = createConn(); auto conn = createConn();
conn->qLogger = std::make_shared<quic::FileQLogger>(VantagePoint::Client); conn->qLogger = std::make_shared<quic::FileQLogger>(VantagePoint::Client);
conn->ackStates.initialAckState.nextPacketNum = 0; conn->ackStates.initialAckState->nextPacketNum = 0;
conn->ackStates.handshakeAckState.nextPacketNum = 1; conn->ackStates.handshakeAckState->nextPacketNum = 1;
conn->ackStates.appDataAckState.nextPacketNum = 2; conn->ackStates.appDataAckState.nextPacketNum = 2;
auto initialPacket = buildEmptyPacket(*conn, PacketNumberSpace::Initial); auto initialPacket = buildEmptyPacket(*conn, PacketNumberSpace::Initial);
auto handshakePacket = buildEmptyPacket(*conn, PacketNumberSpace::Handshake); auto handshakePacket = buildEmptyPacket(*conn, PacketNumberSpace::Handshake);
@@ -967,7 +967,7 @@ TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionEmptyAckWriteResult) {
// buildEmptyPacket() builds a Handshake packet, we use handshakeAckState to // buildEmptyPacket() builds a Handshake packet, we use handshakeAckState to
// verify. // verify.
auto currentPendingLargestAckScheduled = auto currentPendingLargestAckScheduled =
conn->ackStates.handshakeAckState.largestAckScheduled; conn->ackStates.handshakeAckState->largestAckScheduled;
updateConnection( updateConnection(
*conn, *conn,
folly::none, folly::none,
@@ -991,7 +991,7 @@ TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionEmptyAckWriteResult) {
EXPECT_EQ( EXPECT_EQ(
currentPendingLargestAckScheduled, currentPendingLargestAckScheduled,
conn->ackStates.handshakeAckState.largestAckScheduled); conn->ackStates.handshakeAckState->largestAckScheduled);
} }
TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionPureAckCounter) { TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionPureAckCounter) {
@@ -2970,11 +2970,11 @@ TEST_F(QuicTransportFunctionsTest, NothingWritten) {
EXPECT_CALL(*rawCongestionController, getWritableBytes()) EXPECT_CALL(*rawCongestionController, getWritableBytes())
.WillRepeatedly(Return(18)); .WillRepeatedly(Return(18));
addAckStatesWithCurrentTimestamps(conn->ackStates.initialAckState, 0, 1000); addAckStatesWithCurrentTimestamps(*conn->ackStates.initialAckState, 0, 1000);
addAckStatesWithCurrentTimestamps( addAckStatesWithCurrentTimestamps(
conn->ackStates.initialAckState, 1500, 2000); *conn->ackStates.initialAckState, 1500, 2000);
addAckStatesWithCurrentTimestamps( addAckStatesWithCurrentTimestamps(
conn->ackStates.initialAckState, 2500, 3000); *conn->ackStates.initialAckState, 2500, 3000);
auto res = writeQuicDataToSocket( auto res = writeQuicDataToSocket(
*rawSocket, *rawSocket,
*conn, *conn,
@@ -3155,7 +3155,7 @@ TEST_F(QuicTransportFunctionsTest, WriteProbingCryptoData) {
conn.clientConnectionId = getTestConnectionId(); conn.clientConnectionId = getTestConnectionId();
// writeCryptoDataProbesToSocketForTest writes Initial LongHeader, thus it // writeCryptoDataProbesToSocketForTest writes Initial LongHeader, thus it
// writes at Initial level. // writes at Initial level.
auto currentPacketSeqNum = conn.ackStates.initialAckState.nextPacketNum; auto currentPacketSeqNum = conn.ackStates.initialAckState->nextPacketNum;
// Replace real congestionController with MockCongestionController: // Replace real congestionController with MockCongestionController:
auto mockCongestionController = auto mockCongestionController =
std::make_unique<NiceMock<MockCongestionController>>(); std::make_unique<NiceMock<MockCongestionController>>();
@@ -3184,7 +3184,7 @@ TEST_F(QuicTransportFunctionsTest, WriteProbingCryptoData) {
})); }));
writeCryptoDataProbesToSocketForTest( writeCryptoDataProbesToSocketForTest(
*rawSocket, conn, 1, *aead, *headerCipher, getVersion(conn)); *rawSocket, conn, 1, *aead, *headerCipher, getVersion(conn));
EXPECT_LT(currentPacketSeqNum, conn.ackStates.initialAckState.nextPacketNum); EXPECT_LT(currentPacketSeqNum, conn.ackStates.initialAckState->nextPacketNum);
EXPECT_FALSE(conn.outstandings.packets.empty()); EXPECT_FALSE(conn.outstandings.packets.empty());
EXPECT_TRUE(conn.pendingEvents.setLossDetectionAlarm); EXPECT_TRUE(conn.pendingEvents.setLossDetectionAlarm);
EXPECT_GT(cryptoStream->currentWriteOffset, currentStreamWriteOffset); EXPECT_GT(cryptoStream->currentWriteOffset, currentStreamWriteOffset);
@@ -3202,7 +3202,7 @@ TEST_F(QuicTransportFunctionsTest, WriteableBytesLimitedProbingCryptoData) {
conn.clientConnectionId = getTestConnectionId(); conn.clientConnectionId = getTestConnectionId();
// writeCryptoDataProbesToSocketForTest writes Initial LongHeader, thus it // writeCryptoDataProbesToSocketForTest writes Initial LongHeader, thus it
// writes at Initial level. // writes at Initial level.
auto currentPacketSeqNum = conn.ackStates.initialAckState.nextPacketNum; auto currentPacketSeqNum = conn.ackStates.initialAckState->nextPacketNum;
// Replace real congestionController with MockCongestionController: // Replace real congestionController with MockCongestionController:
auto mockCongestionController = auto mockCongestionController =
std::make_unique<NiceMock<MockCongestionController>>(); std::make_unique<NiceMock<MockCongestionController>>();
@@ -3232,7 +3232,7 @@ TEST_F(QuicTransportFunctionsTest, WriteableBytesLimitedProbingCryptoData) {
*rawSocket, conn, probesToSend, *aead, *headerCipher, getVersion(conn)); *rawSocket, conn, probesToSend, *aead, *headerCipher, getVersion(conn));
EXPECT_EQ(conn.numProbesWritableBytesLimited, 1); EXPECT_EQ(conn.numProbesWritableBytesLimited, 1);
EXPECT_LT(currentPacketSeqNum, conn.ackStates.initialAckState.nextPacketNum); EXPECT_LT(currentPacketSeqNum, conn.ackStates.initialAckState->nextPacketNum);
EXPECT_FALSE(conn.outstandings.packets.empty()); EXPECT_FALSE(conn.outstandings.packets.empty());
EXPECT_TRUE(conn.pendingEvents.setLossDetectionAlarm); EXPECT_TRUE(conn.pendingEvents.setLossDetectionAlarm);
EXPECT_GT(cryptoStream->currentWriteOffset, currentStreamWriteOffset); EXPECT_GT(cryptoStream->currentWriteOffset, currentStreamWriteOffset);
@@ -3643,8 +3643,8 @@ TEST_F(QuicTransportFunctionsTest, HasAckDataToWriteCipherAndAckStateMatch) {
conn->ackStates.appDataAckState.needsToSendAckImmediately = true; conn->ackStates.appDataAckState.needsToSendAckImmediately = true;
conn->ackStates.appDataAckState.acks.insert(0, 100); conn->ackStates.appDataAckState.acks.insert(0, 100);
EXPECT_FALSE(hasAckDataToWrite(*conn)); EXPECT_FALSE(hasAckDataToWrite(*conn));
conn->ackStates.initialAckState.needsToSendAckImmediately = true; conn->ackStates.initialAckState->needsToSendAckImmediately = true;
conn->ackStates.initialAckState.acks.insert(0, 100); conn->ackStates.initialAckState->acks.insert(0, 100);
EXPECT_TRUE(hasAckDataToWrite(*conn)); EXPECT_TRUE(hasAckDataToWrite(*conn));
} }
@@ -3661,15 +3661,15 @@ TEST_F(QuicTransportFunctionsTest, HasAckDataToWriteNoImmediateAcks) {
TEST_F(QuicTransportFunctionsTest, HasAckDataToWriteNoAcksScheduled) { TEST_F(QuicTransportFunctionsTest, HasAckDataToWriteNoAcksScheduled) {
auto conn = createConn(); auto conn = createConn();
conn->oneRttWriteCipher = test::createNoOpAead(); conn->oneRttWriteCipher = test::createNoOpAead();
conn->ackStates.initialAckState.needsToSendAckImmediately = true; conn->ackStates.initialAckState->needsToSendAckImmediately = true;
EXPECT_FALSE(hasAckDataToWrite(*conn)); EXPECT_FALSE(hasAckDataToWrite(*conn));
} }
TEST_F(QuicTransportFunctionsTest, HasAckDataToWrite) { TEST_F(QuicTransportFunctionsTest, HasAckDataToWrite) {
auto conn = createConn(); auto conn = createConn();
conn->oneRttWriteCipher = test::createNoOpAead(); conn->oneRttWriteCipher = test::createNoOpAead();
conn->ackStates.initialAckState.needsToSendAckImmediately = true; conn->ackStates.initialAckState->needsToSendAckImmediately = true;
conn->ackStates.initialAckState.acks.insert(0); conn->ackStates.initialAckState->acks.insert(0);
EXPECT_TRUE(hasAckDataToWrite(*conn)); EXPECT_TRUE(hasAckDataToWrite(*conn));
} }
@@ -3679,9 +3679,9 @@ TEST_F(QuicTransportFunctionsTest, HasAckDataToWriteMismatch) {
// should not send. // should not send.
auto conn = createConn(); auto conn = createConn();
EXPECT_FALSE(hasAckDataToWrite(*conn)); EXPECT_FALSE(hasAckDataToWrite(*conn));
conn->ackStates.initialAckState.needsToSendAckImmediately = true; conn->ackStates.initialAckState->needsToSendAckImmediately = true;
EXPECT_FALSE(hasAckDataToWrite(*conn)); EXPECT_FALSE(hasAckDataToWrite(*conn));
conn->ackStates.handshakeAckState.acks.insert(0, 10); conn->ackStates.handshakeAckState->acks.insert(0, 10);
conn->handshakeWriteCipher = test::createNoOpAead(); conn->handshakeWriteCipher = test::createNoOpAead();
EXPECT_FALSE(hasAckDataToWrite(*conn)); EXPECT_FALSE(hasAckDataToWrite(*conn));
} }

View File

@@ -634,8 +634,12 @@ void QuicClientTransport::processPacketData(
FrameType::IMMEDIATE_ACK); FrameType::IMMEDIATE_ACK);
} }
// Send an ACK from any packet number space. // Send an ACK from any packet number space.
conn_->ackStates.initialAckState.needsToSendAckImmediately = true; if (conn_->ackStates.initialAckState) {
conn_->ackStates.handshakeAckState.needsToSendAckImmediately = true; conn_->ackStates.initialAckState->needsToSendAckImmediately = true;
}
if (conn_->ackStates.handshakeAckState) {
conn_->ackStates.handshakeAckState->needsToSendAckImmediately = true;
}
conn_->ackStates.appDataAckState.needsToSendAckImmediately = true; conn_->ackStates.appDataAckState.needsToSendAckImmediately = true;
break; break;
} }
@@ -908,9 +912,7 @@ void QuicClientTransport::writeData() {
if ((initialCryptoStream.retransmissionBuffer.size() && if ((initialCryptoStream.retransmissionBuffer.size() &&
conn_->outstandings.packetCount[PacketNumberSpace::Initial] && conn_->outstandings.packetCount[PacketNumberSpace::Initial] &&
numProbePackets) || numProbePackets) ||
initialScheduler.hasData() || initialScheduler.hasData() || toWriteInitialAcks(*conn_)) {
(conn_->ackStates.initialAckState.needsToSendAckImmediately &&
hasAcksToSchedule(conn_->ackStates.initialAckState))) {
CHECK(conn_->initialHeaderCipher); CHECK(conn_->initialHeaderCipher);
std::string& token = clientConn_->retryToken.empty() std::string& token = clientConn_->retryToken.empty()
? clientConn_->newToken ? clientConn_->newToken
@@ -941,9 +943,7 @@ void QuicClientTransport::writeData() {
if ((conn_->outstandings.packetCount[PacketNumberSpace::Handshake] && if ((conn_->outstandings.packetCount[PacketNumberSpace::Handshake] &&
handshakeCryptoStream.retransmissionBuffer.size() && handshakeCryptoStream.retransmissionBuffer.size() &&
numProbePackets) || numProbePackets) ||
handshakeScheduler.hasData() || handshakeScheduler.hasData() || toWriteHandshakeAcks(*conn_)) {
(conn_->ackStates.handshakeAckState.needsToSendAckImmediately &&
hasAcksToSchedule(conn_->ackStates.handshakeAckState))) {
CHECK(conn_->handshakeWriteHeaderCipher); CHECK(conn_->handshakeWriteHeaderCipher);
packetLimit -= writeCryptoAndAckDataToSocket( packetLimit -= writeCryptoAndAckDataToSocket(
*socket_, *socket_,

View File

@@ -39,10 +39,10 @@ std::unique_ptr<QuicClientConnectionState> undoAllClientStateForRetry(
conn->originalDestinationConnectionId; conn->originalDestinationConnectionId;
// TODO: don't carry server connection id over to the new connection. // TODO: don't carry server connection id over to the new connection.
newConn->serverConnectionId = conn->serverConnectionId; newConn->serverConnectionId = conn->serverConnectionId;
newConn->ackStates.initialAckState.nextPacketNum = newConn->ackStates.initialAckState->nextPacketNum =
conn->ackStates.initialAckState.nextPacketNum; conn->ackStates.initialAckState->nextPacketNum;
newConn->ackStates.handshakeAckState.nextPacketNum = newConn->ackStates.handshakeAckState->nextPacketNum =
conn->ackStates.handshakeAckState.nextPacketNum; conn->ackStates.handshakeAckState->nextPacketNum;
newConn->ackStates.appDataAckState.nextPacketNum = newConn->ackStates.appDataAckState.nextPacketNum =
conn->ackStates.appDataAckState.nextPacketNum; conn->ackStates.appDataAckState.nextPacketNum;
newConn->version = conn->version; newConn->version = conn->version;

View File

@@ -188,11 +188,12 @@ CodecResult QuicReadCodec::parseLongHeaderPacket(
folly::Optional<PacketNum> largestRecvdPacketNum; folly::Optional<PacketNum> largestRecvdPacketNum;
switch (longHeaderTypeToProtectionType(type)) { switch (longHeaderTypeToProtectionType(type)) {
case ProtectionType::Initial: case ProtectionType::Initial:
largestRecvdPacketNum = ackStates.initialAckState.largestRecvdPacketNum; largestRecvdPacketNum = ackStates.initialAckState->largestRecvdPacketNum;
break; break;
case ProtectionType::Handshake: case ProtectionType::Handshake:
largestRecvdPacketNum = ackStates.handshakeAckState.largestRecvdPacketNum; largestRecvdPacketNum =
ackStates.handshakeAckState->largestRecvdPacketNum;
break; break;
case ProtectionType::ZeroRtt: case ProtectionType::ZeroRtt:

View File

@@ -101,8 +101,8 @@ class QuicLossFunctionsTest : public TestWithParam<PacketNumberSpace> {
FizzServerQuicHandshakeContext::Builder().build()); FizzServerQuicHandshakeContext::Builder().build());
conn->clientConnectionId = getTestConnectionId(); conn->clientConnectionId = getTestConnectionId();
conn->version = QuicVersion::MVFST; conn->version = QuicVersion::MVFST;
conn->ackStates.initialAckState.nextPacketNum = 1; conn->ackStates.initialAckState->nextPacketNum = 1;
conn->ackStates.handshakeAckState.nextPacketNum = 1; conn->ackStates.handshakeAckState->nextPacketNum = 1;
conn->ackStates.appDataAckState.nextPacketNum = 1; conn->ackStates.appDataAckState.nextPacketNum = 1;
conn->flowControlState.peerAdvertisedInitialMaxStreamOffsetBidiLocal = conn->flowControlState.peerAdvertisedInitialMaxStreamOffsetBidiLocal =
kDefaultStreamWindowSize; kDefaultStreamWindowSize;
@@ -134,8 +134,8 @@ class QuicLossFunctionsTest : public TestWithParam<PacketNumberSpace> {
FizzClientQuicHandshakeContext::Builder().build()); FizzClientQuicHandshakeContext::Builder().build());
conn->clientConnectionId = getTestConnectionId(); conn->clientConnectionId = getTestConnectionId();
conn->version = QuicVersion::MVFST; conn->version = QuicVersion::MVFST;
conn->ackStates.initialAckState.nextPacketNum = 1; conn->ackStates.initialAckState->nextPacketNum = 1;
conn->ackStates.handshakeAckState.nextPacketNum = 1; conn->ackStates.handshakeAckState->nextPacketNum = 1;
conn->ackStates.appDataAckState.nextPacketNum = 1; conn->ackStates.appDataAckState.nextPacketNum = 1;
conn->flowControlState.peerAdvertisedInitialMaxStreamOffsetBidiLocal = conn->flowControlState.peerAdvertisedInitialMaxStreamOffsetBidiLocal =
kDefaultStreamWindowSize; kDefaultStreamWindowSize;
@@ -198,7 +198,7 @@ PacketNum QuicLossFunctionsTest::sendPacket(
LongHeader::Types::Initial, LongHeader::Types::Initial,
*conn.clientConnectionId, *conn.clientConnectionId,
*conn.serverConnectionId, *conn.serverConnectionId,
conn.ackStates.initialAckState.nextPacketNum, conn.ackStates.initialAckState->nextPacketNum,
*conn.version); *conn.version);
isHandshake = true; isHandshake = true;
break; break;
@@ -207,7 +207,7 @@ PacketNum QuicLossFunctionsTest::sendPacket(
LongHeader::Types::Handshake, LongHeader::Types::Handshake,
*conn.clientConnectionId, *conn.clientConnectionId,
*conn.serverConnectionId, *conn.serverConnectionId,
conn.ackStates.handshakeAckState.nextPacketNum, conn.ackStates.handshakeAckState->nextPacketNum,
*conn.version); *conn.version);
isHandshake = true; isHandshake = true;
break; break;
@@ -736,7 +736,7 @@ TEST_F(QuicLossFunctionsTest, TestMarkPacketLoss) {
writeDataToQuicStream(*stream1, buf->clone(), true); writeDataToQuicStream(*stream1, buf->clone(), true);
writeDataToQuicStream(*stream2, buf->clone(), true); writeDataToQuicStream(*stream2, buf->clone(), true);
auto packetSeqNum = conn->ackStates.handshakeAckState.nextPacketNum; auto packetSeqNum = conn->ackStates.handshakeAckState->nextPacketNum;
LongHeader header( LongHeader header(
LongHeader::Types::Handshake, LongHeader::Types::Handshake,
*conn->clientConnectionId, *conn->clientConnectionId,
@@ -1026,7 +1026,7 @@ TEST_F(QuicLossFunctionsTest, TestHandleAckForLoss) {
LongHeader::Types::Handshake, LongHeader::Types::Handshake,
*conn->clientConnectionId, *conn->clientConnectionId,
*conn->serverConnectionId, *conn->serverConnectionId,
conn->ackStates.handshakeAckState.nextPacketNum++, conn->ackStates.handshakeAckState->nextPacketNum++,
conn->version.value()); conn->version.value());
RegularQuicWritePacket outstandingRegularPacket(std::move(longHeader)); RegularQuicWritePacket outstandingRegularPacket(std::move(longHeader));
auto now = Clock::now(); auto now = Clock::now();

View File

@@ -273,9 +273,7 @@ void QuicServerTransport::writeData() {
conn_->pendingEvents.numProbePackets[PacketNumberSpace::Initial]; conn_->pendingEvents.numProbePackets[PacketNumberSpace::Initial];
if ((numProbePackets && initialCryptoStream.retransmissionBuffer.size() && if ((numProbePackets && initialCryptoStream.retransmissionBuffer.size() &&
conn_->outstandings.packetCount[PacketNumberSpace::Initial]) || conn_->outstandings.packetCount[PacketNumberSpace::Initial]) ||
initialScheduler.hasData() || initialScheduler.hasData() || toWriteInitialAcks(*conn_)) {
(conn_->ackStates.initialAckState.needsToSendAckImmediately &&
hasAcksToSchedule(conn_->ackStates.initialAckState))) {
CHECK(conn_->initialWriteCipher); CHECK(conn_->initialWriteCipher);
CHECK(conn_->initialHeaderCipher); CHECK(conn_->initialHeaderCipher);
@@ -306,9 +304,7 @@ void QuicServerTransport::writeData() {
if ((conn_->outstandings.packetCount[PacketNumberSpace::Handshake] && if ((conn_->outstandings.packetCount[PacketNumberSpace::Handshake] &&
handshakeCryptoStream.retransmissionBuffer.size() && handshakeCryptoStream.retransmissionBuffer.size() &&
numProbePackets) || numProbePackets) ||
handshakeScheduler.hasData() || handshakeScheduler.hasData() || toWriteHandshakeAcks(*conn_)) {
(conn_->ackStates.handshakeAckState.needsToSendAckImmediately &&
hasAcksToSchedule(conn_->ackStates.handshakeAckState))) {
CHECK(conn_->handshakeWriteCipher); CHECK(conn_->handshakeWriteCipher);
CHECK(conn_->handshakeWriteHeaderCipher); CHECK(conn_->handshakeWriteHeaderCipher);
auto res = writeCryptoAndAckDataToSocket( auto res = writeCryptoAndAckDataToSocket(

View File

@@ -1320,8 +1320,12 @@ void onServerReadDataFromOpen(
FrameType::IMMEDIATE_ACK); FrameType::IMMEDIATE_ACK);
} }
// Send an ACK from any packet number space. // Send an ACK from any packet number space.
conn.ackStates.initialAckState.needsToSendAckImmediately = true; if (conn.ackStates.initialAckState) {
conn.ackStates.handshakeAckState.needsToSendAckImmediately = true; conn.ackStates.initialAckState->needsToSendAckImmediately = true;
}
if (conn.ackStates.handshakeAckState) {
conn.ackStates.handshakeAckState->needsToSendAckImmediately = true;
}
conn.ackStates.appDataAckState.needsToSendAckImmediately = true; conn.ackStates.appDataAckState.needsToSendAckImmediately = true;
break; break;
} }

View File

@@ -112,12 +112,12 @@ TEST_F(QuicServerTransportTest, TestReadMultipleStreams) {
auto packet = std::move(builder).buildPacket(); auto packet = std::move(builder).buildPacket();
// Clear out the existing acks to make sure that we are the cause of the acks. // Clear out the existing acks to make sure that we are the cause of the acks.
server->getNonConstConn().ackStates.initialAckState.acks.clear(); server->getNonConstConn().ackStates.initialAckState->acks.clear();
server->getNonConstConn().ackStates.initialAckState.largestRecvdPacketTime = server->getNonConstConn().ackStates.initialAckState->largestRecvdPacketTime =
folly::none;
server->getNonConstConn().ackStates.handshakeAckState.acks.clear();
server->getNonConstConn().ackStates.handshakeAckState.largestRecvdPacketTime =
folly::none; folly::none;
server->getNonConstConn().ackStates.handshakeAckState->acks.clear();
server->getNonConstConn()
.ackStates.handshakeAckState->largestRecvdPacketTime = folly::none;
server->getNonConstConn().ackStates.appDataAckState.acks.clear(); server->getNonConstConn().ackStates.appDataAckState.acks.clear();
server->getNonConstConn().ackStates.appDataAckState.largestRecvdPacketTime = server->getNonConstConn().ackStates.appDataAckState.largestRecvdPacketTime =
folly::none; folly::none;
@@ -3056,9 +3056,9 @@ TEST_F(QuicServerTransportTest, ImmediateAckProtocolViolation) {
ASSERT_THROW(deliverData(packetToBuf(packet)), std::runtime_error); ASSERT_THROW(deliverData(packetToBuf(packet)), std::runtime_error);
// Verify that none of the ack states have changed // Verify that none of the ack states have changed
EXPECT_FALSE( EXPECT_FALSE(
server->getConn().ackStates.initialAckState.needsToSendAckImmediately); server->getConn().ackStates.initialAckState->needsToSendAckImmediately);
EXPECT_FALSE( EXPECT_FALSE(
server->getConn().ackStates.handshakeAckState.needsToSendAckImmediately); server->getConn().ackStates.handshakeAckState->needsToSendAckImmediately);
EXPECT_FALSE( EXPECT_FALSE(
server->getConn().ackStates.appDataAckState.needsToSendAckImmediately); server->getConn().ackStates.appDataAckState.needsToSendAckImmediately);
} }

View File

@@ -51,17 +51,19 @@ struct AckState : WriteAckState {
struct AckStates { struct AckStates {
explicit AckStates(PacketNum startingNum) { explicit AckStates(PacketNum startingNum) {
initialAckState.nextPacketNum = startingNum; initialAckState = std::make_unique<AckState>();
handshakeAckState.nextPacketNum = startingNum; handshakeAckState = std::make_unique<AckState>();
initialAckState->nextPacketNum = startingNum;
handshakeAckState->nextPacketNum = startingNum;
appDataAckState.nextPacketNum = startingNum; appDataAckState.nextPacketNum = startingNum;
} }
AckStates() : AckStates(folly::Random::secureRand32(kMaxInitialPacketNum)) {} AckStates() : AckStates(folly::Random::secureRand32(kMaxInitialPacketNum)) {}
// AckState for acks to peer packets in Initial packet number space. // AckState for acks to peer packets in Initial packet number space.
AckState initialAckState; std::unique_ptr<AckState> initialAckState{};
// AckState for acks to peer packets in Handshake packet number space. // AckState for acks to peer packets in Handshake packet number space.
AckState handshakeAckState; std::unique_ptr<AckState> handshakeAckState{};
// AckState for acks to peer packets in AppData packet number space. // AckState for acks to peer packets in AppData packet number space.
AckState appDataAckState; AckState appDataAckState;
std::chrono::microseconds maxAckDelay{kMaxAckTimeout}; std::chrono::microseconds maxAckDelay{kMaxAckTimeout};

View File

@@ -199,9 +199,9 @@ AckState& getAckState(
PacketNumberSpace pnSpace) noexcept { PacketNumberSpace pnSpace) noexcept {
switch (pnSpace) { switch (pnSpace) {
case PacketNumberSpace::Initial: case PacketNumberSpace::Initial:
return conn.ackStates.initialAckState; return *CHECK_NOTNULL(conn.ackStates.initialAckState.get());
case PacketNumberSpace::Handshake: case PacketNumberSpace::Handshake:
return conn.ackStates.handshakeAckState; return *CHECK_NOTNULL(conn.ackStates.handshakeAckState.get());
case PacketNumberSpace::AppData: case PacketNumberSpace::AppData:
return conn.ackStates.appDataAckState; return conn.ackStates.appDataAckState;
} }
@@ -213,21 +213,43 @@ const AckState& getAckState(
PacketNumberSpace pnSpace) noexcept { PacketNumberSpace pnSpace) noexcept {
switch (pnSpace) { switch (pnSpace) {
case PacketNumberSpace::Initial: case PacketNumberSpace::Initial:
return conn.ackStates.initialAckState; return *CHECK_NOTNULL(conn.ackStates.initialAckState.get());
case PacketNumberSpace::Handshake: case PacketNumberSpace::Handshake:
return conn.ackStates.handshakeAckState; return *CHECK_NOTNULL(conn.ackStates.handshakeAckState.get());
case PacketNumberSpace::AppData: case PacketNumberSpace::AppData:
return conn.ackStates.appDataAckState; return conn.ackStates.appDataAckState;
} }
folly::assume_unreachable(); folly::assume_unreachable();
} }
const AckState* getAckStatePtr(
const QuicConnectionStateBase& conn,
PacketNumberSpace pnSpace) noexcept {
switch (pnSpace) {
case PacketNumberSpace::Initial:
return conn.ackStates.initialAckState.get();
case PacketNumberSpace::Handshake:
return conn.ackStates.handshakeAckState.get();
case PacketNumberSpace::AppData:
return &conn.ackStates.appDataAckState;
}
folly::assume_unreachable();
}
AckStateVersion currentAckStateVersion( AckStateVersion currentAckStateVersion(
const QuicConnectionStateBase& conn) noexcept { const QuicConnectionStateBase& conn) noexcept {
return AckStateVersion( AckStateVersion ret;
conn.ackStates.initialAckState.acks.insertVersion(), if (conn.ackStates.initialAckState) {
conn.ackStates.handshakeAckState.acks.insertVersion(), ret.initialAckStateVersion =
conn.ackStates.appDataAckState.acks.insertVersion()); conn.ackStates.initialAckState->acks.insertVersion();
}
if (conn.ackStates.handshakeAckState) {
ret.handshakeAckStateVersion =
conn.ackStates.handshakeAckState->acks.insertVersion();
}
ret.appDataAckStateVersion =
conn.ackStates.appDataAckState.acks.insertVersion();
return ret;
} }
PacketNum getNextPacketNum( PacketNum getNextPacketNum(
@@ -280,47 +302,57 @@ std::deque<OutstandingPacket>::iterator getNextOutstandingPacket(
bool hasReceivedPacketsAtLastCloseSent( bool hasReceivedPacketsAtLastCloseSent(
const QuicConnectionStateBase& conn) noexcept { const QuicConnectionStateBase& conn) noexcept {
return conn.ackStates.initialAckState.largestReceivedAtLastCloseSent || const auto* initialAckState = conn.ackStates.initialAckState.get();
conn.ackStates.handshakeAckState.largestReceivedAtLastCloseSent || const auto* handshakeAckState = conn.ackStates.handshakeAckState.get();
conn.ackStates.appDataAckState.largestReceivedAtLastCloseSent; const auto& appDataAckState = conn.ackStates.appDataAckState;
return (initialAckState && initialAckState->largestReceivedAtLastCloseSent) ||
(handshakeAckState &&
handshakeAckState->largestReceivedAtLastCloseSent) ||
appDataAckState.largestReceivedAtLastCloseSent;
} }
bool hasNotReceivedNewPacketsSinceLastCloseSent( bool hasNotReceivedNewPacketsSinceLastCloseSent(
const QuicConnectionStateBase& conn) noexcept { const QuicConnectionStateBase& conn) noexcept {
DCHECK( const auto* initialAckState = conn.ackStates.initialAckState.get();
!conn.ackStates.initialAckState.largestReceivedAtLastCloseSent || const auto* handshakeAckState = conn.ackStates.handshakeAckState.get();
*conn.ackStates.initialAckState.largestReceivedAtLastCloseSent <= const auto& appDataAckState = conn.ackStates.appDataAckState;
*conn.ackStates.initialAckState.largestRecvdPacketNum);
DCHECK( return (initialAckState ? initialAckState->largestReceivedAtLastCloseSent ==
!conn.ackStates.handshakeAckState.largestReceivedAtLastCloseSent || initialAckState->largestRecvdPacketNum
*conn.ackStates.handshakeAckState.largestReceivedAtLastCloseSent <= : true) &&
*conn.ackStates.handshakeAckState.largestRecvdPacketNum); (handshakeAckState ? handshakeAckState->largestReceivedAtLastCloseSent ==
DCHECK( handshakeAckState->largestRecvdPacketNum
!conn.ackStates.appDataAckState.largestReceivedAtLastCloseSent || : true) &&
*conn.ackStates.appDataAckState.largestReceivedAtLastCloseSent <= appDataAckState.largestReceivedAtLastCloseSent ==
*conn.ackStates.appDataAckState.largestRecvdPacketNum); appDataAckState.largestRecvdPacketNum;
return conn.ackStates.initialAckState.largestReceivedAtLastCloseSent ==
conn.ackStates.initialAckState.largestRecvdPacketNum &&
conn.ackStates.handshakeAckState.largestReceivedAtLastCloseSent ==
conn.ackStates.handshakeAckState.largestRecvdPacketNum &&
conn.ackStates.appDataAckState.largestReceivedAtLastCloseSent ==
conn.ackStates.appDataAckState.largestRecvdPacketNum;
} }
void updateLargestReceivedPacketsAtLastCloseSent( void updateLargestReceivedPacketsAtLastCloseSent(
QuicConnectionStateBase& conn) noexcept { QuicConnectionStateBase& conn) noexcept {
conn.ackStates.initialAckState.largestReceivedAtLastCloseSent = auto* initialAckState = conn.ackStates.initialAckState.get();
conn.ackStates.initialAckState.largestRecvdPacketNum; auto* handshakeAckState = conn.ackStates.handshakeAckState.get();
conn.ackStates.handshakeAckState.largestReceivedAtLastCloseSent = auto& appDataAckState = conn.ackStates.appDataAckState;
conn.ackStates.handshakeAckState.largestRecvdPacketNum;
conn.ackStates.appDataAckState.largestReceivedAtLastCloseSent = if (initialAckState) {
initialAckState->largestReceivedAtLastCloseSent =
conn.ackStates.initialAckState->largestRecvdPacketNum;
}
if (handshakeAckState) {
handshakeAckState->largestReceivedAtLastCloseSent =
handshakeAckState->largestRecvdPacketNum;
}
appDataAckState.largestReceivedAtLastCloseSent =
conn.ackStates.appDataAckState.largestRecvdPacketNum; conn.ackStates.appDataAckState.largestRecvdPacketNum;
} }
bool hasReceivedPackets(const QuicConnectionStateBase& conn) noexcept { bool hasReceivedPackets(const QuicConnectionStateBase& conn) noexcept {
return conn.ackStates.initialAckState.largestRecvdPacketNum || const auto* initialAckState = conn.ackStates.initialAckState.get();
conn.ackStates.handshakeAckState.largestRecvdPacketNum || const auto* handshakeAckState = conn.ackStates.handshakeAckState.get();
conn.ackStates.appDataAckState.largestRecvdPacketNum; const auto& appDataAckState = conn.ackStates.appDataAckState;
return (initialAckState ? initialAckState->largestRecvdPacketNum : true) ||
(handshakeAckState ? handshakeAckState->largestRecvdPacketNum : true) ||
appDataAckState.largestRecvdPacketNum;
} }
folly::Optional<TimePoint>& getLossTime( folly::Optional<TimePoint>& getLossTime(

View File

@@ -44,6 +44,10 @@ const AckState& getAckState(
const QuicConnectionStateBase& conn, const QuicConnectionStateBase& conn,
PacketNumberSpace pnSpace) noexcept; PacketNumberSpace pnSpace) noexcept;
const AckState* getAckStatePtr(
const QuicConnectionStateBase& conn,
PacketNumberSpace pnSpace) noexcept;
AckStateVersion currentAckStateVersion( AckStateVersion currentAckStateVersion(
const QuicConnectionStateBase& conn) noexcept; const QuicConnectionStateBase& conn) noexcept;

View File

@@ -808,6 +808,8 @@ struct AckStateVersion {
uint64_t handshakeVersion, uint64_t handshakeVersion,
uint64_t appDataVersion); uint64_t appDataVersion);
AckStateVersion() = default;
bool operator==(const AckStateVersion& other) const; bool operator==(const AckStateVersion& other) const;
bool operator!=(const AckStateVersion& other) const; bool operator!=(const AckStateVersion& other) const;
}; };

View File

@@ -35,8 +35,8 @@ std::unique_ptr<QuicServerConnectionState> createConn() {
FizzServerQuicHandshakeContext::Builder().build()); FizzServerQuicHandshakeContext::Builder().build());
conn->clientConnectionId = getTestConnectionId(); conn->clientConnectionId = getTestConnectionId();
conn->version = QuicVersion::MVFST; conn->version = QuicVersion::MVFST;
conn->ackStates.initialAckState.nextPacketNum = 1; conn->ackStates.initialAckState->nextPacketNum = 1;
conn->ackStates.handshakeAckState.nextPacketNum = 1; conn->ackStates.handshakeAckState->nextPacketNum = 1;
conn->ackStates.appDataAckState.nextPacketNum = 1; conn->ackStates.appDataAckState.nextPacketNum = 1;
conn->flowControlState.peerAdvertisedInitialMaxStreamOffsetBidiLocal = conn->flowControlState.peerAdvertisedInitialMaxStreamOffsetBidiLocal =
kDefaultStreamWindowSize; kDefaultStreamWindowSize;

View File

@@ -1164,17 +1164,17 @@ TEST_P(AckHandlersTest, PurgeAcks) {
WriteAckFrame ackFrame; WriteAckFrame ackFrame;
ackFrame.ackBlocks.emplace_back(900, 1000); ackFrame.ackBlocks.emplace_back(900, 1000);
ackFrame.ackBlocks.emplace_back(500, 700); ackFrame.ackBlocks.emplace_back(500, 700);
conn.ackStates.initialAckState.acks.insert(900, 1200); conn.ackStates.initialAckState->acks.insert(900, 1200);
conn.ackStates.initialAckState.acks.insert(500, 800); conn.ackStates.initialAckState->acks.insert(500, 800);
auto expectedTime = Clock::now(); auto expectedTime = Clock::now();
conn.ackStates.initialAckState.largestRecvdPacketTime = expectedTime; conn.ackStates.initialAckState->largestRecvdPacketTime = expectedTime;
commonAckVisitorForAckFrame(conn.ackStates.initialAckState, ackFrame); commonAckVisitorForAckFrame(*conn.ackStates.initialAckState, ackFrame);
// We should have purged old packets in ack state // We should have purged old packets in ack state
EXPECT_EQ(conn.ackStates.initialAckState.acks.size(), 1); EXPECT_EQ(conn.ackStates.initialAckState->acks.size(), 1);
EXPECT_EQ(conn.ackStates.initialAckState.acks.front().start, 1001); EXPECT_EQ(conn.ackStates.initialAckState->acks.front().start, 1001);
EXPECT_EQ(conn.ackStates.initialAckState.acks.front().end, 1200); EXPECT_EQ(conn.ackStates.initialAckState->acks.front().end, 1200);
EXPECT_EQ( EXPECT_EQ(
expectedTime, *conn.ackStates.initialAckState.largestRecvdPacketTime); expectedTime, *conn.ackStates.initialAckState->largestRecvdPacketTime);
} }
TEST_P(AckHandlersTest, NoSkipAckVisitor) { TEST_P(AckHandlersTest, NoSkipAckVisitor) {
@@ -1590,9 +1590,9 @@ TEST_P(AckHandlersTest, AckNotOutstandingButLoss) {
conn.lossState.lrtt = 150ms; conn.lossState.lrtt = 150ms;
// Packet 2 has been sent and acked: // Packet 2 has been sent and acked:
if (GetParam() == PacketNumberSpace::Initial) { if (GetParam() == PacketNumberSpace::Initial) {
conn.ackStates.initialAckState.largestAckedByPeer = 2; conn.ackStates.initialAckState->largestAckedByPeer = 2;
} else if (GetParam() == PacketNumberSpace::Handshake) { } else if (GetParam() == PacketNumberSpace::Handshake) {
conn.ackStates.handshakeAckState.largestAckedByPeer = 2; conn.ackStates.handshakeAckState->largestAckedByPeer = 2;
} else { } else {
conn.ackStates.appDataAckState.largestAckedByPeer = 2; conn.ackStates.appDataAckState.largestAckedByPeer = 2;
} }
@@ -3171,14 +3171,14 @@ class AckEventForAppDataTest : public Test {
LongHeader::Types::Initial, LongHeader::Types::Initial,
*conn_->clientConnectionId, *conn_->clientConnectionId,
*conn_->serverConnectionId, *conn_->serverConnectionId,
conn_->ackStates.initialAckState.nextPacketNum, conn_->ackStates.initialAckState->nextPacketNum,
*conn_->version); *conn_->version);
} else if (pnSpace == PacketNumberSpace::Handshake) { } else if (pnSpace == PacketNumberSpace::Handshake) {
header = LongHeader( header = LongHeader(
LongHeader::Types::Handshake, LongHeader::Types::Handshake,
*conn_->clientConnectionId, *conn_->clientConnectionId,
*conn_->serverConnectionId, *conn_->serverConnectionId,
conn_->ackStates.handshakeAckState.nextPacketNum, conn_->ackStates.handshakeAckState->nextPacketNum,
*conn_->version); *conn_->version);
} else if (pnSpace == PacketNumberSpace::AppData) { } else if (pnSpace == PacketNumberSpace::AppData) {
header = LongHeader( header = LongHeader(

View File

@@ -1161,17 +1161,18 @@ TEST_F(QuicStateFunctionsTest, GetOutstandingPackets) {
TEST_F(QuicStateFunctionsTest, UpdateLargestReceivePacketsAtLatCloseSent) { TEST_F(QuicStateFunctionsTest, UpdateLargestReceivePacketsAtLatCloseSent) {
QuicConnectionStateBase conn(QuicNodeType::Client); QuicConnectionStateBase conn(QuicNodeType::Client);
EXPECT_FALSE(conn.ackStates.initialAckState.largestReceivedAtLastCloseSent); EXPECT_FALSE(conn.ackStates.initialAckState->largestReceivedAtLastCloseSent);
EXPECT_FALSE(conn.ackStates.handshakeAckState.largestReceivedAtLastCloseSent); EXPECT_FALSE(
conn.ackStates.handshakeAckState->largestReceivedAtLastCloseSent);
EXPECT_FALSE(conn.ackStates.appDataAckState.largestReceivedAtLastCloseSent); EXPECT_FALSE(conn.ackStates.appDataAckState.largestReceivedAtLastCloseSent);
conn.ackStates.initialAckState.largestRecvdPacketNum = 123; conn.ackStates.initialAckState->largestRecvdPacketNum = 123;
conn.ackStates.handshakeAckState.largestRecvdPacketNum = 654; conn.ackStates.handshakeAckState->largestRecvdPacketNum = 654;
conn.ackStates.appDataAckState.largestRecvdPacketNum = 789; conn.ackStates.appDataAckState.largestRecvdPacketNum = 789;
updateLargestReceivedPacketsAtLastCloseSent(conn); updateLargestReceivedPacketsAtLastCloseSent(conn);
EXPECT_EQ( EXPECT_EQ(
123, *conn.ackStates.initialAckState.largestReceivedAtLastCloseSent); 123, *conn.ackStates.initialAckState->largestReceivedAtLastCloseSent);
EXPECT_EQ( EXPECT_EQ(
654, *conn.ackStates.handshakeAckState.largestReceivedAtLastCloseSent); 654, *conn.ackStates.handshakeAckState->largestReceivedAtLastCloseSent);
EXPECT_EQ( EXPECT_EQ(
789, *conn.ackStates.appDataAckState.largestReceivedAtLastCloseSent); 789, *conn.ackStates.appDataAckState.largestReceivedAtLastCloseSent);
} }