mirror of
https://github.com/facebookincubator/mvfst.git
synced 2025-04-18 17:24:03 +03:00
Remove exception throwing from QuicInteger
Summary: Continuing the theme, removing it from QuicInteger which ends up being in a lot of the write paths. Reviewed By: kvtsoy Differential Revision: D72757026 fbshipit-source-id: 99a6ab2caea8fb495b1cb466172611002968e527
This commit is contained in:
parent
7dbd219831
commit
b81c086d09
@ -33,7 +33,7 @@ AckScheduler::AckScheduler(
|
||||
const AckState& ackState)
|
||||
: conn_(conn), ackState_(ackState) {}
|
||||
|
||||
Optional<PacketNum> AckScheduler::writeNextAcks(
|
||||
folly::Expected<Optional<PacketNum>, QuicError> AckScheduler::writeNextAcks(
|
||||
PacketBuilderInterface& builder) {
|
||||
// Use default ack delay for long headers. Usually long headers are sent
|
||||
// before crypto negotiation, so the peer might not know about the ack delay
|
||||
@ -61,49 +61,56 @@ Optional<PacketNum> AckScheduler::writeNextAcks(
|
||||
conn_.connectionTime, /* connect timestamp */
|
||||
};
|
||||
|
||||
Optional<WriteAckFrameResult> ackWriteResult;
|
||||
auto ackWriteResult =
|
||||
[&]() -> folly::Expected<Optional<WriteAckFrameResult>, QuicError> {
|
||||
uint64_t peerRequestedTimestampsCount =
|
||||
conn_.maybePeerAckReceiveTimestampsConfig.has_value()
|
||||
? conn_.maybePeerAckReceiveTimestampsConfig.value()
|
||||
.maxReceiveTimestampsPerAck
|
||||
: 0;
|
||||
|
||||
uint64_t peerRequestedTimestampsCount =
|
||||
conn_.maybePeerAckReceiveTimestampsConfig.has_value()
|
||||
? conn_.maybePeerAckReceiveTimestampsConfig.value()
|
||||
.maxReceiveTimestampsPerAck
|
||||
: 0;
|
||||
if (conn_.negotiatedExtendedAckFeatures > 0) {
|
||||
// The peer supports extended ACKs and we have them enabled.
|
||||
return writeAckFrame(
|
||||
meta,
|
||||
builder,
|
||||
FrameType::ACK_EXTENDED,
|
||||
conn_.transportSettings.maybeAckReceiveTimestampsConfigSentToPeer
|
||||
.value_or(AckReceiveTimestampsConfig()),
|
||||
peerRequestedTimestampsCount,
|
||||
conn_.negotiatedExtendedAckFeatures);
|
||||
} else if (
|
||||
conn_.transportSettings.readEcnOnIngress &&
|
||||
(meta.ackState.ecnECT0CountReceived ||
|
||||
meta.ackState.ecnECT1CountReceived ||
|
||||
meta.ackState.ecnCECountReceived)) {
|
||||
// We have to report ECN counts, but we can't use the extended ACK
|
||||
// frame. In this case, we give ACK_ECN precedence over
|
||||
// ACK_RECEIVE_TIMESTAMPS.
|
||||
return writeAckFrame(meta, builder, FrameType::ACK_ECN);
|
||||
} else if (conn_.negotiatedAckReceiveTimestampSupport) {
|
||||
// Use ACK_RECEIVE_TIMESTAMPS if its enabled on both endpoints AND the
|
||||
// peer requests at least 1 timestamp
|
||||
return writeAckFrame(
|
||||
meta,
|
||||
builder,
|
||||
FrameType::ACK_RECEIVE_TIMESTAMPS,
|
||||
conn_.transportSettings.maybeAckReceiveTimestampsConfigSentToPeer
|
||||
.value(),
|
||||
peerRequestedTimestampsCount);
|
||||
} else {
|
||||
return writeAckFrame(meta, builder, FrameType::ACK);
|
||||
}
|
||||
}();
|
||||
|
||||
if (conn_.negotiatedExtendedAckFeatures > 0) {
|
||||
// The peer supports extended ACKs and we have them enabled.
|
||||
ackWriteResult = writeAckFrame(
|
||||
meta,
|
||||
builder,
|
||||
FrameType::ACK_EXTENDED,
|
||||
conn_.transportSettings.maybeAckReceiveTimestampsConfigSentToPeer
|
||||
.value_or(AckReceiveTimestampsConfig()),
|
||||
peerRequestedTimestampsCount,
|
||||
conn_.negotiatedExtendedAckFeatures);
|
||||
} else if (
|
||||
conn_.transportSettings.readEcnOnIngress &&
|
||||
(meta.ackState.ecnECT0CountReceived ||
|
||||
meta.ackState.ecnECT1CountReceived ||
|
||||
meta.ackState.ecnCECountReceived)) {
|
||||
// We have to report ECN counts, but we can't use the extended ACK
|
||||
// frame. In this case, we give ACK_ECN precedence over
|
||||
// ACK_RECEIVE_TIMESTAMPS.
|
||||
ackWriteResult = writeAckFrame(meta, builder, FrameType::ACK_ECN);
|
||||
} else if (conn_.negotiatedAckReceiveTimestampSupport) {
|
||||
// Use ACK_RECEIVE_TIMESTAMPS if its enabled on both endpoints AND the
|
||||
// peer requests at least 1 timestamp
|
||||
ackWriteResult = writeAckFrame(
|
||||
meta,
|
||||
builder,
|
||||
FrameType::ACK_RECEIVE_TIMESTAMPS,
|
||||
conn_.transportSettings.maybeAckReceiveTimestampsConfigSentToPeer
|
||||
.value(),
|
||||
peerRequestedTimestampsCount);
|
||||
} else {
|
||||
ackWriteResult = writeAckFrame(meta, builder, FrameType::ACK);
|
||||
if (ackWriteResult.hasError()) {
|
||||
return folly::makeUnexpected(ackWriteResult.error());
|
||||
}
|
||||
if (!ackWriteResult) {
|
||||
|
||||
if (!ackWriteResult.value()) {
|
||||
return none;
|
||||
}
|
||||
|
||||
return largestAckedPacketNum;
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,8 @@ class AckScheduler {
|
||||
public:
|
||||
AckScheduler(const QuicConnectionStateBase& conn, const AckState& ackState);
|
||||
|
||||
Optional<PacketNum> writeNextAcks(PacketBuilderInterface& builder);
|
||||
[[nodiscard]] folly::Expected<Optional<PacketNum>, QuicError> writeNextAcks(
|
||||
PacketBuilderInterface& builder);
|
||||
|
||||
[[nodiscard]] bool hasPendingAcks() const;
|
||||
|
||||
|
@ -227,12 +227,18 @@ FrameScheduler::scheduleFramesForPacket(
|
||||
const LongHeader* longHeader = builder.getPacketHeader().asLong();
|
||||
bool initialPacket =
|
||||
longHeader && longHeader->getHeaderType() == LongHeader::Types::Initial;
|
||||
builder.encodePacketHeader();
|
||||
auto encodeRes = builder.encodePacketHeader();
|
||||
if (encodeRes.hasError()) {
|
||||
return folly::makeUnexpected(encodeRes.error());
|
||||
}
|
||||
// Add fixed padding at start of short header packets if configured
|
||||
if (shortHeader && conn_.transportSettings.fixedShortHeaderPadding > 0) {
|
||||
for (size_t i = 0; i < conn_.transportSettings.fixedShortHeaderPadding;
|
||||
i++) {
|
||||
writeFrame(PaddingFrame(), builder);
|
||||
auto writeRes = writeFrame(PaddingFrame(), builder);
|
||||
if (writeRes.hasError()) {
|
||||
return folly::makeUnexpected(writeRes.error());
|
||||
}
|
||||
}
|
||||
shortHeaderPadding = conn_.transportSettings.fixedShortHeaderPadding;
|
||||
}
|
||||
@ -246,7 +252,11 @@ FrameScheduler::scheduleFramesForPacket(
|
||||
bool cryptoDataWritten = false;
|
||||
bool rstWritten = false;
|
||||
if (cryptoStreamScheduler_ && cryptoStreamScheduler_->hasData()) {
|
||||
cryptoDataWritten = cryptoStreamScheduler_->writeCryptoData(wrapper);
|
||||
auto cryptoDataRes = cryptoStreamScheduler_->writeCryptoData(wrapper);
|
||||
if (cryptoDataRes.hasError()) {
|
||||
return folly::makeUnexpected(cryptoDataRes.error());
|
||||
}
|
||||
cryptoDataWritten = cryptoDataRes.value();
|
||||
}
|
||||
if (rstScheduler_ && rstScheduler_->hasPendingRsts()) {
|
||||
rstWritten = rstScheduler_->writeRsts(wrapper);
|
||||
@ -256,14 +266,20 @@ FrameScheduler::scheduleFramesForPacket(
|
||||
if (cryptoDataWritten || rstWritten) {
|
||||
// If packet has non ack data, it is subject to congestion control. We
|
||||
// need to use the wrapper/
|
||||
ackScheduler_->writeNextAcks(wrapper);
|
||||
auto writeAcksRes = ackScheduler_->writeNextAcks(wrapper);
|
||||
if (writeAcksRes.hasError()) {
|
||||
return folly::makeUnexpected(writeAcksRes.error());
|
||||
}
|
||||
} else {
|
||||
// If we start with writing acks, we will let the ack scheduler write
|
||||
// up to the full packet space. If the ack bytes exceeds the writable
|
||||
// bytes, this will be a pure ack packet and it will skip congestion
|
||||
// controller. Otherwise, we will give other schedulers an opportunity to
|
||||
// write up to writable bytes.
|
||||
ackScheduler_->writeNextAcks(builder);
|
||||
auto writeAcksRes = ackScheduler_->writeNextAcks(builder);
|
||||
if (writeAcksRes.hasError()) {
|
||||
return folly::makeUnexpected(writeAcksRes.error());
|
||||
}
|
||||
}
|
||||
}
|
||||
// Immediate ACK frames are subject to congestion control but should be sent
|
||||
@ -297,14 +313,20 @@ FrameScheduler::scheduleFramesForPacket(
|
||||
}
|
||||
if (datagramFrameScheduler_ &&
|
||||
datagramFrameScheduler_->hasPendingDatagramFrames()) {
|
||||
datagramFrameScheduler_->writeDatagramFrames(wrapper);
|
||||
auto datagramRes = datagramFrameScheduler_->writeDatagramFrames(wrapper);
|
||||
if (datagramRes.hasError()) {
|
||||
return folly::makeUnexpected(datagramRes.error());
|
||||
}
|
||||
}
|
||||
|
||||
if (builder.hasFramesPending()) {
|
||||
if (initialPacket) {
|
||||
// This is the initial packet, we need to fill er up.
|
||||
while (builder.remainingSpaceInPkt() > 0) {
|
||||
writeFrame(PaddingFrame(), builder);
|
||||
auto writeRes = writeFrame(PaddingFrame(), builder);
|
||||
if (writeRes.hasError()) {
|
||||
return folly::makeUnexpected(writeRes.error());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (shortHeader) {
|
||||
@ -312,7 +334,10 @@ FrameScheduler::scheduleFramesForPacket(
|
||||
if (paddingModulo > 0) {
|
||||
size_t paddingIncrement = wrapper.remainingSpaceInPkt() % paddingModulo;
|
||||
for (size_t i = 0; i < paddingIncrement; i++) {
|
||||
writeFrame(PaddingFrame(), builder);
|
||||
auto writeRes = writeFrame(PaddingFrame(), builder);
|
||||
if (writeRes.hasError()) {
|
||||
return folly::makeUnexpected(writeRes.error());
|
||||
}
|
||||
}
|
||||
shortHeaderPadding += paddingIncrement;
|
||||
}
|
||||
@ -627,7 +652,10 @@ bool PingFrameScheduler::hasPingFrame() const {
|
||||
}
|
||||
|
||||
bool PingFrameScheduler::writePing(PacketBuilderInterface& builder) {
|
||||
return 0 != writeFrame(PingFrame(), builder);
|
||||
auto writeFrameResult = writeFrame(PingFrame(), builder);
|
||||
// We shouldn't ever error on a PING.
|
||||
CHECK(!writeFrameResult.hasError());
|
||||
return writeFrameResult.value() != 0;
|
||||
}
|
||||
|
||||
DatagramFrameScheduler::DatagramFrameScheduler(QuicConnectionStateBase& conn)
|
||||
@ -637,7 +665,7 @@ bool DatagramFrameScheduler::hasPendingDatagramFrames() const {
|
||||
return !conn_.datagramState.writeBuffer.empty();
|
||||
}
|
||||
|
||||
bool DatagramFrameScheduler::writeDatagramFrames(
|
||||
folly::Expected<bool, QuicError> DatagramFrameScheduler::writeDatagramFrames(
|
||||
PacketBuilderInterface& builder) {
|
||||
bool sent = false;
|
||||
for (size_t i = 0; i <= conn_.datagramState.writeBuffer.size(); ++i) {
|
||||
@ -645,15 +673,26 @@ bool DatagramFrameScheduler::writeDatagramFrames(
|
||||
auto len = payload.chainLength();
|
||||
uint64_t spaceLeft = builder.remainingSpaceInPkt();
|
||||
QuicInteger frameTypeQuicInt(static_cast<uint8_t>(FrameType::DATAGRAM_LEN));
|
||||
auto frameTypeSize = frameTypeQuicInt.getSize();
|
||||
if (frameTypeSize.hasError()) {
|
||||
return folly::makeUnexpected(frameTypeSize.error());
|
||||
}
|
||||
QuicInteger datagramLenInt(len);
|
||||
auto datagramLenSize = datagramLenInt.getSize();
|
||||
if (datagramLenSize.hasError()) {
|
||||
return folly::makeUnexpected(datagramLenSize.error());
|
||||
}
|
||||
auto datagramFrameLength =
|
||||
frameTypeQuicInt.getSize() + len + datagramLenInt.getSize();
|
||||
frameTypeSize.value() + len + datagramLenSize.value();
|
||||
if (folly::to<uint64_t>(datagramFrameLength) <= spaceLeft) {
|
||||
auto datagramFrame = DatagramFrame(len, payload.move());
|
||||
auto res = writeFrame(datagramFrame, builder);
|
||||
if (res.hasError()) {
|
||||
return folly::makeUnexpected(res.error());
|
||||
}
|
||||
// Must always succeed since we have already checked that there is enough
|
||||
// space to write the frame
|
||||
CHECK_GT(res, 0);
|
||||
CHECK_GT(res.value(), 0);
|
||||
QUIC_STATS(conn_.statsCallback, onDatagramWrite, len);
|
||||
conn_.datagramState.writeBuffer.pop_front();
|
||||
sent = true;
|
||||
@ -734,7 +773,8 @@ CryptoStreamScheduler::CryptoStreamScheduler(
|
||||
const QuicCryptoStream& cryptoStream)
|
||||
: conn_(conn), cryptoStream_(cryptoStream) {}
|
||||
|
||||
bool CryptoStreamScheduler::writeCryptoData(PacketBuilderInterface& builder) {
|
||||
folly::Expected<bool, QuicError> CryptoStreamScheduler::writeCryptoData(
|
||||
PacketBuilderInterface& builder) {
|
||||
bool cryptoDataWritten = false;
|
||||
uint64_t writableData =
|
||||
folly::to<uint64_t>(cryptoStream_.pendingWrites.chainLength());
|
||||
@ -743,21 +783,27 @@ bool CryptoStreamScheduler::writeCryptoData(PacketBuilderInterface& builder) {
|
||||
// will always take precedence over the crypto data.
|
||||
for (const auto& buffer : cryptoStream_.lossBuffer) {
|
||||
auto res = writeCryptoFrame(buffer.offset, buffer.data, builder);
|
||||
if (!res) {
|
||||
if (res.hasError()) {
|
||||
return folly::makeUnexpected(res.error());
|
||||
}
|
||||
if (!res.value()) {
|
||||
return cryptoDataWritten;
|
||||
}
|
||||
VLOG(4) << "Wrote retransmitted crypto" << " offset=" << buffer.offset
|
||||
<< " bytes=" << res->len << " " << conn_;
|
||||
<< " bytes=" << res.value()->len << " " << conn_;
|
||||
cryptoDataWritten = true;
|
||||
}
|
||||
|
||||
if (writableData != 0) {
|
||||
auto res = writeCryptoFrame(
|
||||
cryptoStream_.currentWriteOffset, cryptoStream_.pendingWrites, builder);
|
||||
if (res) {
|
||||
if (res.hasError()) {
|
||||
return folly::makeUnexpected(res.error());
|
||||
}
|
||||
if (res.value()) {
|
||||
VLOG(4) << "Wrote crypto frame"
|
||||
<< " offset=" << cryptoStream_.currentWriteOffset
|
||||
<< " bytesWritten=" << res->len << " " << conn_;
|
||||
<< " bytesWritten=" << res.value()->len << " " << conn_;
|
||||
cryptoDataWritten = true;
|
||||
}
|
||||
}
|
||||
@ -779,7 +825,10 @@ bool ImmediateAckFrameScheduler::hasPendingImmediateAckFrame() const {
|
||||
|
||||
bool ImmediateAckFrameScheduler::writeImmediateAckFrame(
|
||||
PacketBuilderInterface& builder) {
|
||||
return 0 != writeFrame(ImmediateAckFrame(), builder);
|
||||
auto result = writeFrame(ImmediateAckFrame(), builder);
|
||||
// We shouldn't ever error on an IMMEDIATE_ACK.
|
||||
CHECK(!result.hasError());
|
||||
return result.value() != 0;
|
||||
}
|
||||
|
||||
CloningScheduler::CloningScheduler(
|
||||
@ -891,7 +940,10 @@ CloningScheduler::scheduleFramesForPacket(
|
||||
}
|
||||
|
||||
internalBuilder->accountForCipherOverhead(cipherOverhead_);
|
||||
internalBuilder->encodePacketHeader();
|
||||
auto encodeRes = internalBuilder->encodePacketHeader();
|
||||
if (encodeRes.hasError()) {
|
||||
return folly::makeUnexpected(encodeRes.error());
|
||||
}
|
||||
PacketRebuilder rebuilder(*internalBuilder, conn_);
|
||||
|
||||
// TODO: It's possible we write out a packet that's larger than the
|
||||
|
@ -174,7 +174,8 @@ class DatagramFrameScheduler {
|
||||
|
||||
[[nodiscard]] bool hasPendingDatagramFrames() const;
|
||||
|
||||
bool writeDatagramFrames(PacketBuilderInterface& builder);
|
||||
[[nodiscard]] folly::Expected<bool, QuicError> writeDatagramFrames(
|
||||
PacketBuilderInterface& builder);
|
||||
|
||||
private:
|
||||
QuicConnectionStateBase& conn_;
|
||||
@ -213,7 +214,8 @@ class CryptoStreamScheduler {
|
||||
/**
|
||||
* Returns whether or we could write data to the stream.
|
||||
*/
|
||||
bool writeCryptoData(PacketBuilderInterface& builder);
|
||||
[[nodiscard]] folly::Expected<bool, QuicError> writeCryptoData(
|
||||
PacketBuilderInterface& builder);
|
||||
|
||||
bool hasData() const;
|
||||
|
||||
|
@ -1313,47 +1313,80 @@ void writeCloseCommon(
|
||||
connection.udpSendPacketLen,
|
||||
header,
|
||||
getAckState(connection, pnSpace).largestAckedByPeer.value_or(0));
|
||||
packetBuilder.encodePacketHeader();
|
||||
auto encodeResult = packetBuilder.encodePacketHeader();
|
||||
if (encodeResult.hasError()) {
|
||||
LOG(ERROR) << "Error encoding packet header: "
|
||||
<< encodeResult.error().message;
|
||||
return;
|
||||
}
|
||||
packetBuilder.accountForCipherOverhead(aead.getCipherOverhead());
|
||||
size_t written = 0;
|
||||
if (!closeDetails) {
|
||||
written = writeFrame(
|
||||
auto writeResult = writeFrame(
|
||||
ConnectionCloseFrame(
|
||||
QuicErrorCode(TransportErrorCode::NO_ERROR),
|
||||
std::string("No error")),
|
||||
packetBuilder);
|
||||
if (writeResult.hasError()) {
|
||||
LOG(ERROR) << "Error writing frame: " << writeResult.error().message;
|
||||
return;
|
||||
}
|
||||
written = *writeResult;
|
||||
} else {
|
||||
switch (closeDetails->code.type()) {
|
||||
case QuicErrorCode::Type::ApplicationErrorCode:
|
||||
written = writeFrame(
|
||||
case QuicErrorCode::Type::ApplicationErrorCode: {
|
||||
auto writeResult = writeFrame(
|
||||
ConnectionCloseFrame(
|
||||
QuicErrorCode(*closeDetails->code.asApplicationErrorCode()),
|
||||
closeDetails->message,
|
||||
quic::FrameType::CONNECTION_CLOSE_APP_ERR),
|
||||
packetBuilder);
|
||||
if (writeResult.hasError()) {
|
||||
LOG(ERROR) << "Error writing frame: " << writeResult.error().message;
|
||||
return;
|
||||
}
|
||||
written = *writeResult;
|
||||
break;
|
||||
case QuicErrorCode::Type::TransportErrorCode:
|
||||
written = writeFrame(
|
||||
}
|
||||
case QuicErrorCode::Type::TransportErrorCode: {
|
||||
auto writeResult = writeFrame(
|
||||
ConnectionCloseFrame(
|
||||
QuicErrorCode(*closeDetails->code.asTransportErrorCode()),
|
||||
closeDetails->message,
|
||||
quic::FrameType::CONNECTION_CLOSE),
|
||||
packetBuilder);
|
||||
if (writeResult.hasError()) {
|
||||
LOG(ERROR) << "Error writing frame: " << writeResult.error().message;
|
||||
return;
|
||||
}
|
||||
written = *writeResult;
|
||||
break;
|
||||
case QuicErrorCode::Type::LocalErrorCode:
|
||||
written = writeFrame(
|
||||
}
|
||||
case QuicErrorCode::Type::LocalErrorCode: {
|
||||
auto writeResult = writeFrame(
|
||||
ConnectionCloseFrame(
|
||||
QuicErrorCode(TransportErrorCode::INTERNAL_ERROR),
|
||||
std::string("Internal error"),
|
||||
quic::FrameType::CONNECTION_CLOSE),
|
||||
packetBuilder);
|
||||
if (writeResult.hasError()) {
|
||||
LOG(ERROR) << "Error writing frame: " << writeResult.error().message;
|
||||
return;
|
||||
}
|
||||
written = *writeResult;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pnSpace == PacketNumberSpace::Initial &&
|
||||
connection.nodeType == QuicNodeType::Client) {
|
||||
while (packetBuilder.remainingSpaceInPkt() > 0) {
|
||||
writeFrame(PaddingFrame(), packetBuilder);
|
||||
auto paddingResult = writeFrame(PaddingFrame(), packetBuilder);
|
||||
if (paddingResult.hasError()) {
|
||||
LOG(ERROR) << "Error writing padding frame: "
|
||||
<< paddingResult.error().message;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (written == 0) {
|
||||
|
@ -139,7 +139,7 @@ RegularQuicPacketBuilder createPacketBuilder(QuicClientConnectionState& conn) {
|
||||
conn.udpSendPacketLen,
|
||||
std::move(shortHeader),
|
||||
conn.ackStates.appDataAckState.largestAckedByPeer.value_or(0));
|
||||
builder.encodePacketHeader();
|
||||
CHECK(!builder.encodePacketHeader().hasError());
|
||||
return builder;
|
||||
}
|
||||
|
||||
@ -486,7 +486,7 @@ TEST_F(QuicPacketSchedulerTest, CryptoSchedulerOnlySingleLossFits) {
|
||||
conn.udpSendPacketLen,
|
||||
std::move(longHeader),
|
||||
conn.ackStates.handshakeAckState->largestAckedByPeer.value_or(0));
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
PacketBuilderWrapper builderWrapper(builder, 13);
|
||||
CryptoStreamScheduler scheduler(
|
||||
conn, *getCryptoStream(*conn.cryptoState, EncryptionLevel::Handshake));
|
||||
@ -557,7 +557,7 @@ TEST_F(QuicPacketSchedulerTest, StreamFrameSchedulerExists) {
|
||||
conn.udpSendPacketLen,
|
||||
std::move(shortHeader),
|
||||
conn.ackStates.appDataAckState.largestAckedByPeer.value_or(0));
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
auto originalSpace = builder.remainingSpaceInPkt();
|
||||
conn.streamManager->queueWindowUpdate(stream->id);
|
||||
scheduler.writeWindowUpdates(builder);
|
||||
@ -581,7 +581,7 @@ TEST_F(QuicPacketSchedulerTest, StreamFrameNoSpace) {
|
||||
conn.udpSendPacketLen,
|
||||
std::move(shortHeader),
|
||||
conn.ackStates.appDataAckState.largestAckedByPeer.value_or(0));
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
PacketBuilderWrapper builderWrapper(builder, 2);
|
||||
auto originalSpace = builder.remainingSpaceInPkt();
|
||||
conn.streamManager->queueWindowUpdate(stream->id);
|
||||
@ -604,7 +604,7 @@ TEST_F(QuicPacketSchedulerTest, StreamFrameSchedulerStreamNotExists) {
|
||||
conn.udpSendPacketLen,
|
||||
std::move(shortHeader),
|
||||
conn.ackStates.appDataAckState.largestAckedByPeer.value_or(0));
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
auto originalSpace = builder.remainingSpaceInPkt();
|
||||
conn.streamManager->queueWindowUpdate(nonExistentStream);
|
||||
scheduler.writeWindowUpdates(builder);
|
||||
@ -707,10 +707,11 @@ TEST_F(QuicPacketSchedulerTest, WriteOnlyOutstandingPacketsTest) {
|
||||
.ackDelayExponent = static_cast<uint8_t>(kDefaultAckDelayExponent)};
|
||||
|
||||
// Write those framses with a regular builder
|
||||
writeFrame(connCloseFrame, regularBuilder);
|
||||
writeFrame(QuicSimpleFrame(maxStreamFrame), regularBuilder);
|
||||
writeFrame(pingFrame, regularBuilder);
|
||||
writeAckFrame(ackMeta, regularBuilder);
|
||||
ASSERT_FALSE(writeFrame(connCloseFrame, regularBuilder).hasError());
|
||||
ASSERT_FALSE(
|
||||
writeFrame(QuicSimpleFrame(maxStreamFrame), regularBuilder).hasError());
|
||||
ASSERT_FALSE(writeFrame(pingFrame, regularBuilder).hasError());
|
||||
ASSERT_FALSE(writeAckFrame(ackMeta, regularBuilder).hasError());
|
||||
|
||||
auto result = cloningScheduler.scheduleFramesForPacket(
|
||||
std::move(regularBuilder), kDefaultUDPSendPacketLen);
|
||||
@ -1919,7 +1920,7 @@ TEST_F(QuicPacketSchedulerTest, WriteLossWithoutFlowControl) {
|
||||
conn.udpSendPacketLen,
|
||||
std::move(shortHeader1),
|
||||
conn.ackStates.appDataAckState.largestAckedByPeer.value_or(0));
|
||||
builder1.encodePacketHeader();
|
||||
ASSERT_FALSE(builder1.encodePacketHeader().hasError());
|
||||
scheduler.writeStreams(builder1);
|
||||
auto packet1 = std::move(builder1).buildPacket().packet;
|
||||
ASSERT_FALSE(
|
||||
@ -1949,7 +1950,7 @@ TEST_F(QuicPacketSchedulerTest, WriteLossWithoutFlowControl) {
|
||||
conn.udpSendPacketLen,
|
||||
std::move(shortHeader2),
|
||||
conn.ackStates.appDataAckState.largestAckedByPeer.value_or(0));
|
||||
builder2.encodePacketHeader();
|
||||
ASSERT_FALSE(builder2.encodePacketHeader().hasError());
|
||||
scheduler.writeStreams(builder2);
|
||||
auto packet2 = std::move(builder2).buildPacket().packet;
|
||||
ASSERT_FALSE(
|
||||
@ -1997,7 +1998,7 @@ TEST_F(QuicPacketSchedulerTest, WriteLossWithoutFlowControlIgnoreDSR) {
|
||||
conn.udpSendPacketLen,
|
||||
std::move(shortHeader1),
|
||||
conn.ackStates.appDataAckState.largestAckedByPeer.value_or(0));
|
||||
builder1.encodePacketHeader();
|
||||
ASSERT_FALSE(builder1.encodePacketHeader().hasError());
|
||||
scheduler.writeStreams(builder1);
|
||||
auto packet1 = std::move(builder1).buildPacket().packet;
|
||||
ASSERT_FALSE(
|
||||
@ -2042,7 +2043,7 @@ TEST_F(QuicPacketSchedulerTest, WriteLossWithoutFlowControlSequential) {
|
||||
conn.udpSendPacketLen,
|
||||
std::move(shortHeader1),
|
||||
conn.ackStates.appDataAckState.largestAckedByPeer.value_or(0));
|
||||
builder1.encodePacketHeader();
|
||||
ASSERT_FALSE(builder1.encodePacketHeader().hasError());
|
||||
scheduler.writeStreams(builder1);
|
||||
auto packet1 = std::move(builder1).buildPacket().packet;
|
||||
ASSERT_FALSE(
|
||||
@ -2072,7 +2073,7 @@ TEST_F(QuicPacketSchedulerTest, WriteLossWithoutFlowControlSequential) {
|
||||
conn.udpSendPacketLen,
|
||||
std::move(shortHeader2),
|
||||
conn.ackStates.appDataAckState.largestAckedByPeer.value_or(0));
|
||||
builder2.encodePacketHeader();
|
||||
ASSERT_FALSE(builder2.encodePacketHeader().hasError());
|
||||
scheduler.writeStreams(builder2);
|
||||
auto packet2 = std::move(builder2).buildPacket().packet;
|
||||
ASSERT_FALSE(
|
||||
@ -2121,7 +2122,7 @@ TEST_F(QuicPacketSchedulerTest, RunOutFlowControlDuringStreamWrite) {
|
||||
conn.udpSendPacketLen,
|
||||
std::move(shortHeader1),
|
||||
conn.ackStates.appDataAckState.largestAckedByPeer.value_or(0));
|
||||
builder1.encodePacketHeader();
|
||||
ASSERT_FALSE(builder1.encodePacketHeader().hasError());
|
||||
scheduler.writeStreams(builder1);
|
||||
auto packet1 = std::move(builder1).buildPacket().packet;
|
||||
ASSERT_FALSE(
|
||||
@ -2175,7 +2176,7 @@ TEST_F(QuicPacketSchedulerTest, WritingFINFromBufWithBufMetaFirst) {
|
||||
conn.udpSendPacketLen,
|
||||
std::move(header),
|
||||
conn.ackStates.appDataAckState.largestAckedByPeer.value_or(0));
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
StreamFrameScheduler scheduler(conn);
|
||||
scheduler.writeStreams(builder);
|
||||
auto packet = std::move(builder).buildPacket().packet;
|
||||
@ -2213,7 +2214,7 @@ TEST_F(QuicPacketSchedulerTest, NoFINWriteWhenBufMetaWrittenFIN) {
|
||||
conn.udpSendPacketLen,
|
||||
std::move(header),
|
||||
conn.ackStates.appDataAckState.largestAckedByPeer.value_or(0));
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
StreamFrameScheduler scheduler(conn);
|
||||
scheduler.writeStreams(builder);
|
||||
auto packet = std::move(builder).buildPacket().packet;
|
||||
@ -2258,7 +2259,7 @@ TEST_F(QuicPacketSchedulerTest, DatagramFrameSchedulerMultipleFramesPerPacket) {
|
||||
.WillRepeatedly(Invoke([](uint64_t bytes) { EXPECT_GT(bytes, 0); }));
|
||||
// Call scheduler
|
||||
auto& frames = builder.frames_;
|
||||
scheduler.writeDatagramFrames(builder);
|
||||
ASSERT_FALSE(scheduler.writeDatagramFrames(builder).hasError());
|
||||
ASSERT_EQ(frames.size(), 2);
|
||||
}
|
||||
|
||||
@ -2286,12 +2287,12 @@ TEST_F(QuicPacketSchedulerTest, DatagramFrameSchedulerOneFramePerPacket) {
|
||||
EXPECT_CALL(quicStats, onDatagramWrite(_))
|
||||
.Times(1)
|
||||
.WillRepeatedly(Invoke([](uint64_t bytes) { EXPECT_GT(bytes, 0); }));
|
||||
scheduler.writeDatagramFrames(builder);
|
||||
ASSERT_FALSE(scheduler.writeDatagramFrames(builder).hasError());
|
||||
ASSERT_EQ(frames.size(), 1);
|
||||
EXPECT_CALL(quicStats, onDatagramWrite(_))
|
||||
.Times(1)
|
||||
.WillRepeatedly(Invoke([](uint64_t bytes) { EXPECT_GT(bytes, 0); }));
|
||||
scheduler.writeDatagramFrames(builder);
|
||||
ASSERT_FALSE(scheduler.writeDatagramFrames(builder).hasError());
|
||||
ASSERT_EQ(frames.size(), 2);
|
||||
}
|
||||
|
||||
@ -2315,14 +2316,14 @@ TEST_F(QuicPacketSchedulerTest, DatagramFrameWriteWhenRoomAvailable) {
|
||||
conn.statsCallback = &quicStats;
|
||||
// Call scheduler
|
||||
auto& frames = builder.frames_;
|
||||
scheduler.writeDatagramFrames(builder);
|
||||
ASSERT_FALSE(scheduler.writeDatagramFrames(builder).hasError());
|
||||
ASSERT_EQ(frames.size(), 0);
|
||||
EXPECT_CALL(builder, remainingSpaceInPkt())
|
||||
.WillRepeatedly(Return(conn.udpSendPacketLen / 2));
|
||||
EXPECT_CALL(quicStats, onDatagramWrite(_))
|
||||
.Times(1)
|
||||
.WillRepeatedly(Invoke([](uint64_t bytes) { EXPECT_GT(bytes, 0); }));
|
||||
scheduler.writeDatagramFrames(builder);
|
||||
ASSERT_FALSE(scheduler.writeDatagramFrames(builder).hasError());
|
||||
ASSERT_EQ(frames.size(), 1);
|
||||
}
|
||||
|
||||
@ -2365,8 +2366,8 @@ TEST_F(QuicPacketSchedulerTest, ShortHeaderPaddingWithSpaceForPadding) {
|
||||
|
||||
DatagramFrame frame1(inputDataLength1, std::move(inputData1));
|
||||
DatagramFrame frame2(inputDataLength2, std::move(inputData2));
|
||||
writeFrame(frame1, builder1);
|
||||
writeFrame(frame2, builder2);
|
||||
ASSERT_FALSE(writeFrame(frame1, builder1).hasError());
|
||||
ASSERT_FALSE(writeFrame(frame2, builder2).hasError());
|
||||
|
||||
NiceMock<MockQuicStats> quicStats;
|
||||
conn.statsCallback = &quicStats;
|
||||
@ -2479,7 +2480,7 @@ TEST_F(QuicPacketSchedulerTest, ShortHeaderPaddingNearMaxPacketLength) {
|
||||
conn.ackStates.appDataAckState.largestAckedByPeer.value_or(0));
|
||||
|
||||
DatagramFrame frame(inputDataLength, std::move(inputData));
|
||||
writeFrame(frame, builder);
|
||||
ASSERT_FALSE(writeFrame(frame, builder).hasError());
|
||||
|
||||
NiceMock<MockQuicStats> quicStats;
|
||||
conn.statsCallback = &quicStats;
|
||||
@ -2534,7 +2535,7 @@ TEST_F(QuicPacketSchedulerTest, ShortHeaderPaddingMaxPacketLength) {
|
||||
// create enough input data to fully fill packet
|
||||
while (builder.remainingSpaceInPkt() >
|
||||
connectionIdSize + packetNumberEncoding.length + 1) {
|
||||
writeFrame(PaddingFrame(), builder);
|
||||
ASSERT_FALSE(writeFrame(PaddingFrame(), builder).hasError());
|
||||
}
|
||||
|
||||
NiceMock<MockQuicStats> quicStats;
|
||||
@ -2872,7 +2873,9 @@ TEST_F(QuicAckSchedulerTest, DefaultAckFrame) {
|
||||
AckScheduler ackScheduler(*conn_, ackState_);
|
||||
ASSERT_TRUE(ackScheduler.hasPendingAcks());
|
||||
|
||||
ASSERT_TRUE(ackScheduler.writeNextAcks(*builder_) != none);
|
||||
auto writeResult = ackScheduler.writeNextAcks(*builder_);
|
||||
ASSERT_FALSE(writeResult.hasError());
|
||||
ASSERT_TRUE(writeResult.value() != none);
|
||||
ASSERT_EQ(builder_->frames_.size(), 1);
|
||||
|
||||
auto ackFrame = builder_->frames_[0].asWriteAckFrame();
|
||||
@ -2897,7 +2900,9 @@ TEST_F(QuicAckSchedulerTest, WriteAckEcnWhenReadingEcnOnEgress) {
|
||||
AckScheduler ackScheduler(*conn_, ackState_);
|
||||
ASSERT_TRUE(ackScheduler.hasPendingAcks());
|
||||
|
||||
ASSERT_TRUE(ackScheduler.writeNextAcks(*builder_) != none);
|
||||
auto writeResult = ackScheduler.writeNextAcks(*builder_);
|
||||
ASSERT_FALSE(writeResult.hasError());
|
||||
ASSERT_TRUE(writeResult.value() != none);
|
||||
ASSERT_EQ(builder_->frames_.size(), 1);
|
||||
|
||||
auto ackFrame = builder_->frames_[0].asWriteAckFrame();
|
||||
@ -2927,7 +2932,9 @@ TEST_F(QuicAckSchedulerTest, WriteAckReceiveTimestampsWhenEnabled) {
|
||||
AckScheduler ackScheduler(*conn_, ackState_);
|
||||
ASSERT_TRUE(ackScheduler.hasPendingAcks());
|
||||
|
||||
ASSERT_TRUE(ackScheduler.writeNextAcks(*builder_) != none);
|
||||
auto writeResult = ackScheduler.writeNextAcks(*builder_);
|
||||
ASSERT_FALSE(writeResult.hasError());
|
||||
ASSERT_TRUE(writeResult.value() != none);
|
||||
ASSERT_EQ(builder_->frames_.size(), 1);
|
||||
|
||||
auto ackFrame = builder_->frames_[0].asWriteAckFrame();
|
||||
@ -2957,7 +2964,9 @@ TEST_F(QuicAckSchedulerTest, AckEcnTakesPrecedenceOverReceiveTimestamps) {
|
||||
AckScheduler ackScheduler(*conn_, ackState_);
|
||||
ASSERT_TRUE(ackScheduler.hasPendingAcks());
|
||||
|
||||
ASSERT_TRUE(ackScheduler.writeNextAcks(*builder_) != none);
|
||||
auto writeResult = ackScheduler.writeNextAcks(*builder_);
|
||||
ASSERT_FALSE(writeResult.hasError());
|
||||
ASSERT_TRUE(writeResult.value() != none);
|
||||
ASSERT_EQ(builder_->frames_.size(), 1);
|
||||
|
||||
auto ackFrame = builder_->frames_[0].asWriteAckFrame();
|
||||
@ -2987,7 +2996,9 @@ TEST_F(QuicAckSchedulerTest, AckExtendedNotSentIfNotSupported) {
|
||||
AckScheduler ackScheduler(*conn_, ackState_);
|
||||
ASSERT_TRUE(ackScheduler.hasPendingAcks());
|
||||
|
||||
ASSERT_TRUE(ackScheduler.writeNextAcks(*builder_) != none);
|
||||
auto writeResult = ackScheduler.writeNextAcks(*builder_);
|
||||
ASSERT_FALSE(writeResult.hasError());
|
||||
ASSERT_TRUE(writeResult.value() != none);
|
||||
ASSERT_EQ(builder_->frames_.size(), 1);
|
||||
|
||||
auto ackFrame = builder_->frames_[0].asWriteAckFrame();
|
||||
@ -3016,7 +3027,9 @@ TEST_F(QuicAckSchedulerTest, AckExtendedNotSentIfNotEnabled) {
|
||||
AckScheduler ackScheduler(*conn_, ackState_);
|
||||
ASSERT_TRUE(ackScheduler.hasPendingAcks());
|
||||
|
||||
ASSERT_TRUE(ackScheduler.writeNextAcks(*builder_) != none);
|
||||
auto writeResult = ackScheduler.writeNextAcks(*builder_);
|
||||
ASSERT_FALSE(writeResult.hasError());
|
||||
ASSERT_TRUE(writeResult.value() != none);
|
||||
ASSERT_EQ(builder_->frames_.size(), 1);
|
||||
|
||||
auto ackFrame = builder_->frames_[0].asWriteAckFrame();
|
||||
@ -3053,7 +3066,9 @@ TEST_F(
|
||||
AckScheduler ackScheduler(*conn_, ackState_);
|
||||
ASSERT_TRUE(ackScheduler.hasPendingAcks());
|
||||
|
||||
ASSERT_TRUE(ackScheduler.writeNextAcks(*builder_) != none);
|
||||
auto writeResult = ackScheduler.writeNextAcks(*builder_);
|
||||
ASSERT_FALSE(writeResult.hasError());
|
||||
ASSERT_TRUE(writeResult.value() != none);
|
||||
ASSERT_EQ(builder_->frames_.size(), 1);
|
||||
|
||||
auto ackFrame = builder_->frames_[0].asWriteAckFrame();
|
||||
@ -3088,7 +3103,9 @@ TEST_F(QuicAckSchedulerTest, AckExtendedNotSentIfECNFeatureNotSupported) {
|
||||
AckScheduler ackScheduler(*conn_, ackState_);
|
||||
ASSERT_TRUE(ackScheduler.hasPendingAcks());
|
||||
|
||||
ASSERT_TRUE(ackScheduler.writeNextAcks(*builder_) != none);
|
||||
auto writeResult = ackScheduler.writeNextAcks(*builder_);
|
||||
ASSERT_FALSE(writeResult.hasError());
|
||||
ASSERT_TRUE(writeResult.value() != none);
|
||||
ASSERT_EQ(builder_->frames_.size(), 1);
|
||||
|
||||
auto ackFrame = builder_->frames_[0].asWriteAckFrame();
|
||||
@ -3127,7 +3144,9 @@ TEST_F(QuicAckSchedulerTest, AckExtendedWithAllFeatures) {
|
||||
AckScheduler ackScheduler(*conn_, ackState_);
|
||||
ASSERT_TRUE(ackScheduler.hasPendingAcks());
|
||||
|
||||
ASSERT_TRUE(ackScheduler.writeNextAcks(*builder_) != none);
|
||||
auto writeResult = ackScheduler.writeNextAcks(*builder_);
|
||||
ASSERT_FALSE(writeResult.hasError());
|
||||
ASSERT_TRUE(writeResult.value() != none);
|
||||
ASSERT_EQ(builder_->frames_.size(), 1);
|
||||
|
||||
auto ackFrame = builder_->frames_[0].asWriteAckFrame();
|
||||
@ -3166,7 +3185,9 @@ TEST_F(QuicAckSchedulerTest, AckExtendedTakesPrecedenceOverECN) {
|
||||
AckScheduler ackScheduler(*conn_, ackState_);
|
||||
ASSERT_TRUE(ackScheduler.hasPendingAcks());
|
||||
|
||||
ASSERT_TRUE(ackScheduler.writeNextAcks(*builder_) != none);
|
||||
auto writeResult = ackScheduler.writeNextAcks(*builder_);
|
||||
ASSERT_FALSE(writeResult.hasError());
|
||||
ASSERT_TRUE(writeResult.value() != none);
|
||||
ASSERT_EQ(builder_->frames_.size(), 1);
|
||||
|
||||
auto ackFrame = builder_->frames_[0].asWriteAckFrame();
|
||||
@ -3205,7 +3226,9 @@ TEST_F(QuicAckSchedulerTest, AckExtendedTakesPrecedenceOverReceiveTimestamps) {
|
||||
AckScheduler ackScheduler(*conn_, ackState_);
|
||||
ASSERT_TRUE(ackScheduler.hasPendingAcks());
|
||||
|
||||
ASSERT_TRUE(ackScheduler.writeNextAcks(*builder_) != none);
|
||||
auto writeResult = ackScheduler.writeNextAcks(*builder_);
|
||||
ASSERT_FALSE(writeResult.hasError());
|
||||
ASSERT_TRUE(writeResult.value() != none);
|
||||
ASSERT_EQ(builder_->frames_.size(), 1);
|
||||
|
||||
auto ackFrame = builder_->frames_[0].asWriteAckFrame();
|
||||
|
@ -141,7 +141,7 @@ auto buildEmptyPacket(
|
||||
conn.udpSendPacketLen,
|
||||
std::move(*header),
|
||||
getAckState(conn, pnSpace).largestAckedByPeer.value_or(0));
|
||||
builder.encodePacketHeader();
|
||||
CHECK(!builder.encodePacketHeader().hasError());
|
||||
DCHECK(builder.canBuildPacket());
|
||||
return std::move(builder).buildPacket();
|
||||
}
|
||||
|
@ -285,12 +285,12 @@ class QuicTypedTransportTestBase : protected QuicTransportTestClass {
|
||||
peerPacketNumStore.nextAppDataPacketNum++);
|
||||
RegularQuicPacketBuilder builder(
|
||||
getConn().udpSendPacketLen, std::move(header), 0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
CHECK(!builder.encodePacketHeader().hasError());
|
||||
CHECK(builder.canBuildPacket());
|
||||
|
||||
StopSendingFrame stopSendingFrame(
|
||||
streamId, GenericApplicationErrorCode::UNKNOWN);
|
||||
writeSimpleFrame(stopSendingFrame, builder);
|
||||
CHECK(!writeSimpleFrame(stopSendingFrame, builder).hasError());
|
||||
|
||||
auto buf = quic::test::packetToBuf(std::move(builder).buildPacket());
|
||||
buf->coalesce();
|
||||
@ -309,12 +309,12 @@ class QuicTypedTransportTestBase : protected QuicTransportTestClass {
|
||||
peerPacketNumStore.nextAppDataPacketNum++);
|
||||
RegularQuicPacketBuilder builder(
|
||||
getConn().udpSendPacketLen, std::move(header), 0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
CHECK(!builder.encodePacketHeader().hasError());
|
||||
CHECK(builder.canBuildPacket());
|
||||
|
||||
RstStreamFrame rstStreamFrame(
|
||||
streamId, GenericApplicationErrorCode::UNKNOWN, offset);
|
||||
writeFrame(rstStreamFrame, builder);
|
||||
CHECK(!writeFrame(rstStreamFrame, builder).hasError());
|
||||
|
||||
auto buf = quic::test::packetToBuf(std::move(builder).buildPacket());
|
||||
buf->coalesce();
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
namespace quic {
|
||||
|
||||
folly::Expected<size_t, TransportErrorCode> getQuicIntegerSize(uint64_t value) {
|
||||
folly::Expected<size_t, QuicError> getQuicIntegerSize(uint64_t value) {
|
||||
if (value <= kOneByteLimit) {
|
||||
return 1;
|
||||
} else if (value <= kTwoByteLimit) {
|
||||
@ -21,22 +21,8 @@ folly::Expected<size_t, TransportErrorCode> getQuicIntegerSize(uint64_t value) {
|
||||
} else if (value <= kEightByteLimit) {
|
||||
return 8;
|
||||
}
|
||||
return folly::makeUnexpected(TransportErrorCode::INTERNAL_ERROR);
|
||||
}
|
||||
|
||||
size_t getQuicIntegerSizeThrows(uint64_t value) {
|
||||
if (value <= kOneByteLimit) {
|
||||
return 1;
|
||||
} else if (value <= kTwoByteLimit) {
|
||||
return 2;
|
||||
} else if (value <= kFourByteLimit) {
|
||||
return 4;
|
||||
} else if (value <= kEightByteLimit) {
|
||||
return 8;
|
||||
}
|
||||
throw QuicTransportException(
|
||||
folly::to<std::string>("Value too large: ", value),
|
||||
TransportErrorCode::INTERNAL_ERROR);
|
||||
return folly::makeUnexpected(
|
||||
QuicError(TransportErrorCode::INTERNAL_ERROR, "Cannot encode value"));
|
||||
}
|
||||
|
||||
uint8_t decodeQuicIntegerLength(uint8_t firstByte) {
|
||||
@ -84,12 +70,14 @@ Optional<std::pair<uint64_t, size_t>> decodeQuicInteger(
|
||||
|
||||
QuicInteger::QuicInteger(uint64_t value) : value_(value) {}
|
||||
|
||||
size_t QuicInteger::getSize() const {
|
||||
folly::Expected<size_t, QuicError> QuicInteger::getSize() const {
|
||||
auto size = getQuicIntegerSize(value_);
|
||||
if (size.hasError()) {
|
||||
LOG(ERROR) << "Value too large value=" << value_;
|
||||
throw QuicTransportException(
|
||||
folly::to<std::string>("Value too large ", value_), size.error());
|
||||
std::string errorMsg = "Value too large ";
|
||||
errorMsg += std::to_string(value_);
|
||||
return folly::makeUnexpected(
|
||||
QuicError(TransportErrorCode::INTERNAL_ERROR, std::move(errorMsg)));
|
||||
}
|
||||
return size.value();
|
||||
}
|
||||
|
@ -114,14 +114,8 @@ uint8_t decodeQuicIntegerLength(uint8_t firstByte);
|
||||
* if value is too large to be represented with the variable
|
||||
* length encoding
|
||||
*/
|
||||
folly::Expected<size_t, TransportErrorCode> getQuicIntegerSize(uint64_t value);
|
||||
|
||||
/**
|
||||
* Returns number of bytes needed to encode value as a QUIC integer, or throws
|
||||
* an exception if value is too large to be represented with the variable
|
||||
* length encoding
|
||||
*/
|
||||
size_t getQuicIntegerSizeThrows(uint64_t value);
|
||||
[[nodiscard]] folly::Expected<size_t, QuicError> getQuicIntegerSize(
|
||||
uint64_t value);
|
||||
|
||||
/**
|
||||
* A better API for dealing with QUIC integers for encoding.
|
||||
@ -151,7 +145,7 @@ class QuicInteger {
|
||||
* Returns the number of bytes needed to represent the QUIC integer in
|
||||
* its encoded form.
|
||||
**/
|
||||
size_t getSize() const;
|
||||
[[nodiscard]] folly::Expected<size_t, QuicError> getSize() const;
|
||||
|
||||
/**
|
||||
* Returns the real value of the QUIC integer that it was instantiated with.
|
||||
|
@ -13,9 +13,9 @@
|
||||
#include <quic/codec/PacketNumber.h>
|
||||
|
||||
namespace quic {
|
||||
|
||||
template <typename BufOp = BufAppender>
|
||||
PacketNumEncodingResult encodeLongHeaderHelper(
|
||||
[[nodiscard]] folly::Expected<PacketNumEncodingResult, QuicError>
|
||||
encodeLongHeaderHelper(
|
||||
const LongHeader& longHeader,
|
||||
BufOp& bufop,
|
||||
uint32_t& spaceCounter,
|
||||
@ -43,8 +43,11 @@ PacketNumEncodingResult encodeLongHeaderHelper(
|
||||
if (isInitial) {
|
||||
// For initial packets, we write both the token length and the token itself.
|
||||
uint64_t tokenLength = token.size();
|
||||
QuicInteger tokenLengthInt(tokenLength);
|
||||
tokenHeaderLength = tokenLengthInt.getSize() + tokenLength;
|
||||
auto tokenLengthInt = QuicInteger(tokenLength).getSize();
|
||||
if (tokenLengthInt.hasError()) {
|
||||
return folly::makeUnexpected(tokenLengthInt.error());
|
||||
}
|
||||
tokenHeaderLength = tokenLengthInt.value() + tokenLength;
|
||||
} else if (isRetry) {
|
||||
// For retry packets, we write only the token.
|
||||
tokenHeaderLength = token.size();
|
||||
@ -280,11 +283,17 @@ RegularQuicPacketBuilder::Packet RegularQuicPacketBuilder::buildPacket() && {
|
||||
return Packet(std::move(packet_), std::move(header_), std::move(body_));
|
||||
}
|
||||
|
||||
void RegularQuicPacketBuilder::encodeLongHeader(
|
||||
folly::Expected<folly::Unit, QuicError>
|
||||
RegularQuicPacketBuilder::encodeLongHeader(
|
||||
const LongHeader& longHeader,
|
||||
PacketNum largestAckedPacketNum) {
|
||||
packetNumberEncoding_ = encodeLongHeaderHelper(
|
||||
auto encodingResult = encodeLongHeaderHelper(
|
||||
longHeader, headerAppender_, remainingBytes_, largestAckedPacketNum);
|
||||
if (encodingResult.hasError()) {
|
||||
return folly::makeUnexpected(encodingResult.error());
|
||||
}
|
||||
packetNumberEncoding_ = std::move(encodingResult.value());
|
||||
return folly::unit;
|
||||
}
|
||||
|
||||
void RegularQuicPacketBuilder::encodeShortHeader(
|
||||
@ -578,7 +587,7 @@ RetryPacketBuilder::RetryPacketBuilder(
|
||||
writeRetryPacket();
|
||||
}
|
||||
|
||||
void RetryPacketBuilder::writeRetryPacket() {
|
||||
folly::Expected<folly::Unit, QuicError> RetryPacketBuilder::writeRetryPacket() {
|
||||
packetBuf_ = folly::IOBuf::create(kAppenderGrowthSize);
|
||||
|
||||
// Encode the portion of the retry packet that comes before the
|
||||
@ -591,7 +600,11 @@ void RetryPacketBuilder::writeRetryPacket() {
|
||||
0 /* packet number, can be arbitrary for retry packets */,
|
||||
quicVersion_,
|
||||
retryToken_);
|
||||
encodeLongHeaderHelper(header, appender, remainingBytes_, 0);
|
||||
auto encodeResult =
|
||||
encodeLongHeaderHelper(header, appender, remainingBytes_, 0);
|
||||
if (encodeResult.hasError()) {
|
||||
return folly::makeUnexpected(encodeResult.error());
|
||||
}
|
||||
packetBuf_->coalesce();
|
||||
|
||||
// Encode the integrity tag.
|
||||
@ -603,6 +616,7 @@ void RetryPacketBuilder::writeRetryPacket() {
|
||||
BufAppender appender2(packetBuf_.get(), kRetryIntegrityTagLen);
|
||||
appender2.push(integrityTag_.data(), integrityTag_.size());
|
||||
}
|
||||
return folly::unit;
|
||||
}
|
||||
|
||||
bool RetryPacketBuilder::canBuildPacket() const noexcept {
|
||||
@ -828,23 +842,33 @@ InplaceQuicPacketBuilder::~InplaceQuicPacketBuilder() {
|
||||
releaseOutputBufferInternal();
|
||||
}
|
||||
|
||||
void RegularQuicPacketBuilder::encodePacketHeader() {
|
||||
folly::Expected<folly::Unit, QuicError>
|
||||
RegularQuicPacketBuilder::encodePacketHeader() {
|
||||
CHECK(!packetNumberEncoding_.hasValue());
|
||||
if (packet_.header.getHeaderForm() == HeaderForm::Long) {
|
||||
LongHeader& longHeader = *packet_.header.asLong();
|
||||
encodeLongHeader(longHeader, largestAckedPacketNum_);
|
||||
auto result = encodeLongHeader(longHeader, largestAckedPacketNum_);
|
||||
if (result.hasError()) {
|
||||
return folly::makeUnexpected(result.error());
|
||||
}
|
||||
} else {
|
||||
ShortHeader& shortHeader = *packet_.header.asShort();
|
||||
encodeShortHeader(shortHeader, largestAckedPacketNum_);
|
||||
}
|
||||
return folly::unit;
|
||||
}
|
||||
|
||||
void InplaceQuicPacketBuilder::encodePacketHeader() {
|
||||
folly::Expected<folly::Unit, QuicError>
|
||||
InplaceQuicPacketBuilder::encodePacketHeader() {
|
||||
CHECK(!packetNumberEncoding_.hasValue());
|
||||
if (packet_.header.getHeaderForm() == HeaderForm::Long) {
|
||||
LongHeader& longHeader = *packet_.header.asLong();
|
||||
packetNumberEncoding_ = encodeLongHeaderHelper(
|
||||
auto encodingResult = encodeLongHeaderHelper(
|
||||
longHeader, bufWriter_, remainingBytes_, largestAckedPacketNum_);
|
||||
if (encodingResult.hasError()) {
|
||||
return folly::makeUnexpected(encodingResult.error());
|
||||
}
|
||||
packetNumberEncoding_ = std::move(encodingResult.value());
|
||||
if (longHeader.getHeaderType() != LongHeader::Types::Retry) {
|
||||
// Remember the position to write packet number and packet length.
|
||||
packetLenOffset_ = bufWriter_.getBytesWritten();
|
||||
@ -867,6 +891,7 @@ void InplaceQuicPacketBuilder::encodePacketHeader() {
|
||||
}
|
||||
}
|
||||
bodyStart_ = bufWriter_.tail();
|
||||
return folly::unit;
|
||||
}
|
||||
|
||||
} // namespace quic
|
||||
|
@ -61,7 +61,8 @@ class PacketBuilderInterface {
|
||||
|
||||
[[nodiscard]] virtual uint32_t remainingSpaceInPkt() const = 0;
|
||||
|
||||
virtual void encodePacketHeader() = 0;
|
||||
[[nodiscard]] virtual folly::Expected<folly::Unit, QuicError>
|
||||
encodePacketHeader() = 0;
|
||||
|
||||
// Functions to write bytes to the packet
|
||||
virtual void writeBE(uint8_t data) = 0;
|
||||
@ -132,7 +133,8 @@ class InplaceQuicPacketBuilder final : public PacketBuilderInterface {
|
||||
// PacketBuilderInterface
|
||||
[[nodiscard]] uint32_t remainingSpaceInPkt() const override;
|
||||
|
||||
void encodePacketHeader() override;
|
||||
[[nodiscard]] folly::Expected<folly::Unit, QuicError> encodePacketHeader()
|
||||
override;
|
||||
|
||||
void writeBE(uint8_t data) override;
|
||||
void writeBE(uint16_t data) override;
|
||||
@ -210,7 +212,8 @@ class RegularQuicPacketBuilder final : public PacketBuilderInterface {
|
||||
|
||||
[[nodiscard]] uint32_t getHeaderBytes() const override;
|
||||
|
||||
void encodePacketHeader() override;
|
||||
[[nodiscard]] folly::Expected<folly::Unit, QuicError> encodePacketHeader()
|
||||
override;
|
||||
|
||||
// PacketBuilderInterface
|
||||
[[nodiscard]] uint32_t remainingSpaceInPkt() const override;
|
||||
@ -253,7 +256,7 @@ class RegularQuicPacketBuilder final : public PacketBuilderInterface {
|
||||
void releaseOutputBuffer() && override;
|
||||
|
||||
private:
|
||||
void encodeLongHeader(
|
||||
[[nodiscard]] folly::Expected<folly::Unit, QuicError> encodeLongHeader(
|
||||
const LongHeader& longHeader,
|
||||
PacketNum largestAckedPacketNum);
|
||||
void encodeShortHeader(
|
||||
@ -432,7 +435,7 @@ class RetryPacketBuilder {
|
||||
[[nodiscard]] bool canBuildPacket() const noexcept;
|
||||
|
||||
private:
|
||||
void writeRetryPacket();
|
||||
folly::Expected<folly::Unit, QuicError> writeRetryPacket();
|
||||
|
||||
Buf packetBuf_;
|
||||
|
||||
@ -481,7 +484,8 @@ class PacketBuilderWrapper : public PacketBuilderInterface {
|
||||
: 0;
|
||||
}
|
||||
|
||||
void encodePacketHeader() override {
|
||||
[[nodiscard]] folly::Expected<folly::Unit, QuicError> encodePacketHeader()
|
||||
override {
|
||||
CHECK(false)
|
||||
<< "We only support wrapping builder that has already encoded header";
|
||||
}
|
||||
|
@ -153,17 +153,23 @@ PacketRebuilder::rebuildFromPacket(OutstandingPacketWrapper& packet) {
|
||||
}
|
||||
auto cryptoWriteResult =
|
||||
writeCryptoFrame(cryptoFrame.offset, *buf, builder_);
|
||||
bool ret = cryptoWriteResult.has_value() &&
|
||||
if (cryptoWriteResult.hasError()) {
|
||||
return folly::makeUnexpected(cryptoWriteResult.error());
|
||||
}
|
||||
|
||||
cryptoWriteResult->offset == cryptoFrame.offset &&
|
||||
cryptoWriteResult->len == cryptoFrame.len;
|
||||
bool ret = cryptoWriteResult.value()->offset == cryptoFrame.offset &&
|
||||
cryptoWriteResult.value()->len == cryptoFrame.len;
|
||||
notPureAck |= ret;
|
||||
writeSuccess = ret;
|
||||
break;
|
||||
}
|
||||
case QuicWriteFrame::Type::MaxDataFrame: {
|
||||
shouldWriteWindowUpdate = true;
|
||||
auto ret = 0 != writeFrame(generateMaxDataFrame(conn_), builder_);
|
||||
auto writeResult = writeFrame(generateMaxDataFrame(conn_), builder_);
|
||||
if (writeResult.hasError()) {
|
||||
return folly::makeUnexpected(writeResult.error());
|
||||
}
|
||||
bool ret = writeResult.value() != 0;
|
||||
windowUpdateWritten |= ret;
|
||||
notPureAck |= ret;
|
||||
writeSuccess = true;
|
||||
@ -187,8 +193,12 @@ PacketRebuilder::rebuildFromPacket(OutstandingPacketWrapper& packet) {
|
||||
break;
|
||||
}
|
||||
shouldWriteWindowUpdate = true;
|
||||
bool ret =
|
||||
0 != writeFrame(generateMaxStreamDataFrame(*stream), builder_);
|
||||
auto writeResult =
|
||||
writeFrame(generateMaxStreamDataFrame(*stream), builder_);
|
||||
if (writeResult.hasError()) {
|
||||
return folly::makeUnexpected(writeResult.error());
|
||||
}
|
||||
bool ret = writeResult.value() != 0;
|
||||
windowUpdateWritten |= ret;
|
||||
notPureAck |= ret;
|
||||
writeSuccess = true;
|
||||
@ -196,12 +206,20 @@ PacketRebuilder::rebuildFromPacket(OutstandingPacketWrapper& packet) {
|
||||
}
|
||||
case QuicWriteFrame::Type::PaddingFrame: {
|
||||
const PaddingFrame& paddingFrame = *frame.asPaddingFrame();
|
||||
writeSuccess = writeFrame(paddingFrame, builder_) != 0;
|
||||
auto writeResult = writeFrame(paddingFrame, builder_);
|
||||
if (writeResult.hasError()) {
|
||||
return folly::makeUnexpected(writeResult.error());
|
||||
}
|
||||
writeSuccess = writeResult.value() != 0;
|
||||
break;
|
||||
}
|
||||
case QuicWriteFrame::Type::PingFrame: {
|
||||
const PingFrame& pingFrame = *frame.asPingFrame();
|
||||
writeSuccess = writeFrame(pingFrame, builder_) != 0;
|
||||
auto writeResult = writeFrame(pingFrame, builder_);
|
||||
if (writeResult.hasError()) {
|
||||
return folly::makeUnexpected(writeResult.error());
|
||||
}
|
||||
writeSuccess = writeResult.value() != 0;
|
||||
notPureAck |= writeSuccess;
|
||||
break;
|
||||
}
|
||||
@ -213,8 +231,12 @@ PacketRebuilder::rebuildFromPacket(OutstandingPacketWrapper& packet) {
|
||||
writeSuccess = true;
|
||||
break;
|
||||
}
|
||||
bool ret =
|
||||
writeSimpleFrame(std::move(*updatedSimpleFrame), builder_) != 0;
|
||||
auto writeResult =
|
||||
writeSimpleFrame(std::move(*updatedSimpleFrame), builder_);
|
||||
if (writeResult.hasError()) {
|
||||
return folly::makeUnexpected(writeResult.error());
|
||||
}
|
||||
bool ret = writeResult.value() != 0;
|
||||
notPureAck |= ret;
|
||||
writeSuccess = ret;
|
||||
break;
|
||||
@ -224,7 +246,11 @@ PacketRebuilder::rebuildFromPacket(OutstandingPacketWrapper& packet) {
|
||||
writeSuccess = true;
|
||||
break;
|
||||
default: {
|
||||
bool ret = writeFrame(QuicWriteFrame(frame), builder_) != 0;
|
||||
auto writeResult = writeFrame(QuicWriteFrame(frame), builder_);
|
||||
if (writeResult.hasError()) {
|
||||
return folly::makeUnexpected(writeResult.error());
|
||||
}
|
||||
bool ret = writeResult.value() != 0;
|
||||
notPureAck |= ret;
|
||||
writeSuccess = ret;
|
||||
break;
|
||||
@ -245,7 +271,10 @@ PacketRebuilder::rebuildFromPacket(OutstandingPacketWrapper& packet) {
|
||||
conn_,
|
||||
protectionTypeToPacketNumberSpace(packetHeader.getProtectionType()));
|
||||
AckScheduler ackScheduler(conn_, ackState);
|
||||
ackScheduler.writeNextAcks(builder_);
|
||||
auto writeResult = ackScheduler.writeNextAcks(builder_);
|
||||
if (writeResult.hasError()) {
|
||||
return folly::makeUnexpected(writeResult.error());
|
||||
}
|
||||
}
|
||||
|
||||
// We shouldn't clone if:
|
||||
@ -259,7 +288,10 @@ PacketRebuilder::rebuildFromPacket(OutstandingPacketWrapper& packet) {
|
||||
if (encryptionLevel == EncryptionLevel::Initial) {
|
||||
// Pad anything else that's left.
|
||||
while (builder_.remainingSpaceInPkt() > 0) {
|
||||
writeFrame(PaddingFrame(), builder_);
|
||||
auto writeResult = writeFrame(PaddingFrame(), builder_);
|
||||
if (writeResult.hasError()) {
|
||||
return folly::makeUnexpected(writeResult.error());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -14,7 +14,6 @@
|
||||
#include <quic/common/IntervalSet.h>
|
||||
#include <quic/state/TransportSettings.h>
|
||||
#include <sys/types.h>
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
|
||||
namespace quic {
|
||||
@ -25,7 +24,7 @@ namespace quic {
|
||||
* The input parameter is the frame to be written to the output appender.
|
||||
*
|
||||
*/
|
||||
size_t writeSimpleFrame(
|
||||
[[nodiscard]] folly::Expected<size_t, QuicError> writeSimpleFrame(
|
||||
QuicSimpleFrame&& frame,
|
||||
PacketBuilderInterface& builder);
|
||||
|
||||
@ -35,7 +34,9 @@ size_t writeSimpleFrame(
|
||||
* The input parameter is the frame to be written to the output appender.
|
||||
*
|
||||
*/
|
||||
size_t writeFrame(QuicWriteFrame&& frame, PacketBuilderInterface& builder);
|
||||
[[nodiscard]] folly::Expected<size_t, QuicError> writeFrame(
|
||||
QuicWriteFrame&& frame,
|
||||
PacketBuilderInterface& builder);
|
||||
|
||||
/**
|
||||
* Write a complete stream frame header into builder
|
||||
@ -76,7 +77,8 @@ void writeStreamFrameData(
|
||||
* written. The caller should check the structure to confirm how many bytes were
|
||||
* written.
|
||||
*/
|
||||
Optional<WriteCryptoFrame> writeCryptoFrame(
|
||||
[[nodiscard]] folly::Expected<Optional<WriteCryptoFrame>, QuicError>
|
||||
writeCryptoFrame(
|
||||
uint64_t offsetIn,
|
||||
const ChainedByteRangeHead& data,
|
||||
PacketBuilderInterface& builder);
|
||||
@ -97,7 +99,8 @@ Optional<WriteCryptoFrame> writeCryptoFrame(
|
||||
* written to the appender. Returns an empty optional if an ack block could not
|
||||
* be written.
|
||||
*/
|
||||
Optional<WriteAckFrameResult> writeAckFrame(
|
||||
[[nodiscard]] folly::Expected<Optional<WriteAckFrameResult>, QuicError>
|
||||
writeAckFrame(
|
||||
const WriteAckFrameMetaData& ackFrameMetaData,
|
||||
PacketBuilderInterface& builder,
|
||||
FrameType frameType = FrameType::ACK,
|
||||
@ -109,7 +112,8 @@ Optional<WriteAckFrameResult> writeAckFrame(
|
||||
/**
|
||||
* Helper functions to write the fields for ACK_RECEIVE_TIMESTAMPS frame
|
||||
*/
|
||||
size_t computeSizeUsedByRecvdTimestamps(quic::WriteAckFrame& writeAckFrame);
|
||||
[[nodiscard]] folly::Expected<size_t, QuicError>
|
||||
computeSizeUsedByRecvdTimestamps(quic::WriteAckFrame& writeAckFrame);
|
||||
|
||||
} // namespace quic
|
||||
|
||||
|
@ -96,7 +96,10 @@ class MockQuicPacketBuilder : public PacketBuilderInterface {
|
||||
MOCK_METHOD(uint32_t, getHeaderBytes, (), (const));
|
||||
MOCK_METHOD(bool, hasFramesPending, (), (const));
|
||||
MOCK_METHOD(void, releaseOutputBufferMock, ());
|
||||
MOCK_METHOD(void, encodePacketHeader, ());
|
||||
MOCK_METHOD(
|
||||
(folly::Expected<folly::Unit, QuicError>),
|
||||
encodePacketHeader,
|
||||
());
|
||||
|
||||
void releaseOutputBuffer() && override {
|
||||
releaseOutputBufferMock();
|
||||
|
@ -49,7 +49,7 @@ TEST_F(QuicHeaderCodecTest, ShortHeaderTest) {
|
||||
ShortHeader(
|
||||
ProtectionType::KeyPhaseZero, getTestConnectionId(), packetNum),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
auto result = parseHeader(packet.header);
|
||||
auto& header = result->parsedHeader;
|
||||
|
@ -94,7 +94,10 @@ TEST_P(QuicIntegerEncodeTest, GetSize) {
|
||||
auto size = getQuicIntegerSize(GetParam().decoded);
|
||||
if (GetParam().error) {
|
||||
EXPECT_TRUE(size.hasError());
|
||||
EXPECT_EQ(size.error(), TransportErrorCode::INTERNAL_ERROR);
|
||||
ASSERT_NE(size.error().code.asTransportErrorCode(), nullptr);
|
||||
EXPECT_EQ(
|
||||
*size.error().code.asTransportErrorCode(),
|
||||
TransportErrorCode::INTERNAL_ERROR);
|
||||
return;
|
||||
}
|
||||
EXPECT_EQ(*size, GetParam().hexEncoded.size() / 2);
|
||||
|
@ -246,10 +246,12 @@ TEST_P(QuicPacketBuilderTest, ShortHeaderRegularPacket) {
|
||||
ShortHeader(ProtectionType::KeyPhaseZero, connId, pktNum),
|
||||
largestAckedPacketNum,
|
||||
2000);
|
||||
builder->encodePacketHeader();
|
||||
auto encodeResult = builder->encodePacketHeader();
|
||||
ASSERT_FALSE(encodeResult.hasError());
|
||||
|
||||
// write out at least one frame
|
||||
writeFrame(PaddingFrame(), *builder);
|
||||
auto writeFrameResult = writeFrame(PaddingFrame(), *builder);
|
||||
ASSERT_FALSE(writeFrameResult.hasError());
|
||||
EXPECT_TRUE(builder->canBuildPacket());
|
||||
auto builtOut = std::move(*builder).buildPacket();
|
||||
auto resultRegularPacket = builtOut.packet;
|
||||
@ -305,10 +307,12 @@ TEST_P(QuicPacketBuilderTest, EnforcePacketSizeWithCipherOverhead) {
|
||||
largestAckedPacketNum,
|
||||
2000);
|
||||
builder->accountForCipherOverhead(cipherOverhead);
|
||||
builder->encodePacketHeader();
|
||||
auto encodeResult = builder->encodePacketHeader();
|
||||
ASSERT_FALSE(encodeResult.hasError());
|
||||
|
||||
// write out at least one frame
|
||||
writeFrame(PaddingFrame(), *builder);
|
||||
auto writeFrameResult = writeFrame(PaddingFrame(), *builder);
|
||||
ASSERT_FALSE(writeFrameResult.hasError());
|
||||
EXPECT_TRUE(builder->canBuildPacket());
|
||||
auto builtOut = std::move(*builder).buildPacket();
|
||||
|
||||
@ -351,7 +355,8 @@ TEST_P(QuicPacketBuilderTest, ShortHeaderWithNoFrames) {
|
||||
ShortHeader(ProtectionType::KeyPhaseZero, connId, pktNum),
|
||||
0 /*largestAckedPacketNum*/,
|
||||
kDefaultUDPSendPacketLen);
|
||||
builder->encodePacketHeader();
|
||||
auto encodeResult = builder->encodePacketHeader();
|
||||
ASSERT_FALSE(encodeResult.hasError());
|
||||
|
||||
EXPECT_TRUE(builder->canBuildPacket());
|
||||
auto builtOut = std::move(*builder).buildPacket();
|
||||
@ -383,10 +388,12 @@ TEST_P(QuicPacketBuilderTest, TestPaddingAccountsForCipherOverhead) {
|
||||
ShortHeader(ProtectionType::KeyPhaseZero, connId, pktNum),
|
||||
largestAckedPacketNum,
|
||||
kDefaultUDPSendPacketLen);
|
||||
builder->encodePacketHeader();
|
||||
auto encodeResult = builder->encodePacketHeader();
|
||||
ASSERT_FALSE(encodeResult.hasError());
|
||||
builder->accountForCipherOverhead(cipherOverhead);
|
||||
EXPECT_TRUE(builder->canBuildPacket());
|
||||
writeFrame(PaddingFrame(), *builder);
|
||||
auto writeFrameResult = writeFrame(PaddingFrame(), *builder);
|
||||
ASSERT_FALSE(writeFrameResult.hasError());
|
||||
auto builtOut = std::move(*builder).buildPacket();
|
||||
auto resultRegularPacket = builtOut.packet;
|
||||
// We should have padded the remaining bytes with Padding frames.
|
||||
@ -410,9 +417,11 @@ TEST_P(QuicPacketBuilderTest, TestPaddingRespectsRemainingBytes) {
|
||||
ShortHeader(ProtectionType::KeyPhaseZero, connId, pktNum),
|
||||
largestAckedPacketNum,
|
||||
2000);
|
||||
builder->encodePacketHeader();
|
||||
auto encodeResult = builder->encodePacketHeader();
|
||||
ASSERT_FALSE(encodeResult.hasError());
|
||||
EXPECT_TRUE(builder->canBuildPacket());
|
||||
writeFrame(PaddingFrame(), *builder);
|
||||
auto writeFrameResult = writeFrame(PaddingFrame(), *builder);
|
||||
ASSERT_FALSE(writeFrameResult.hasError());
|
||||
auto builtOut = std::move(*builder).buildPacket();
|
||||
auto resultRegularPacket = builtOut.packet;
|
||||
|
||||
@ -451,14 +460,14 @@ TEST_P(QuicPacketBuilderTest, LongHeaderBytesCounting) {
|
||||
std::move(header),
|
||||
largestAcked,
|
||||
kDefaultUDPSendPacketLen);
|
||||
builder->encodePacketHeader();
|
||||
ASSERT_FALSE(builder->encodePacketHeader().hasError());
|
||||
auto expectedWrittenHeaderFieldLen = sizeof(uint8_t) +
|
||||
sizeof(QuicVersionType) + sizeof(uint8_t) + clientCid.size() +
|
||||
sizeof(uint8_t) + serverCid.size();
|
||||
auto estimatedHeaderBytes = builder->getHeaderBytes();
|
||||
EXPECT_GT(
|
||||
estimatedHeaderBytes, expectedWrittenHeaderFieldLen + kMaxPacketLenSize);
|
||||
writeFrame(PaddingFrame(), *builder);
|
||||
ASSERT_FALSE(writeFrame(PaddingFrame(), *builder).hasError());
|
||||
EXPECT_LE(
|
||||
std::move(*builder).buildPacket().header.computeChainDataLength(),
|
||||
estimatedHeaderBytes);
|
||||
@ -474,9 +483,9 @@ TEST_P(QuicPacketBuilderTest, ShortHeaderBytesCounting) {
|
||||
ShortHeader(ProtectionType::KeyPhaseZero, cid, pktNum),
|
||||
largestAcked,
|
||||
2000);
|
||||
builder->encodePacketHeader();
|
||||
ASSERT_FALSE(builder->encodePacketHeader().hasError());
|
||||
auto headerBytes = builder->getHeaderBytes();
|
||||
writeFrame(PaddingFrame(), *builder);
|
||||
ASSERT_FALSE(writeFrame(PaddingFrame(), *builder).hasError());
|
||||
EXPECT_EQ(
|
||||
std::move(*builder).buildPacket().header.computeChainDataLength(),
|
||||
headerBytes);
|
||||
@ -503,9 +512,9 @@ TEST_P(QuicPacketBuilderTest, InplaceBuilderReleaseBufferInBuild) {
|
||||
1000,
|
||||
ShortHeader(ProtectionType::KeyPhaseZero, getTestConnectionId(), 0),
|
||||
0);
|
||||
builder->encodePacketHeader();
|
||||
ASSERT_FALSE(builder->encodePacketHeader().hasError());
|
||||
EXPECT_FALSE(bufAccessor.ownsBuffer());
|
||||
writeFrame(PaddingFrame(), *builder);
|
||||
ASSERT_FALSE(writeFrame(PaddingFrame(), *builder).hasError());
|
||||
std::move(*builder).buildPacket();
|
||||
EXPECT_TRUE(bufAccessor.ownsBuffer());
|
||||
}
|
||||
@ -518,10 +527,10 @@ TEST_F(QuicPacketBuilderTest, BuildTwoInplaces) {
|
||||
1000,
|
||||
ShortHeader(ProtectionType::KeyPhaseZero, getTestConnectionId(), 0),
|
||||
0);
|
||||
builder1->encodePacketHeader();
|
||||
ASSERT_FALSE(builder1->encodePacketHeader().hasError());
|
||||
auto headerBytes = builder1->getHeaderBytes();
|
||||
for (size_t i = 0; i < 20; i++) {
|
||||
writeFrame(PaddingFrame(), *builder1);
|
||||
ASSERT_FALSE(writeFrame(PaddingFrame(), *builder1).hasError());
|
||||
}
|
||||
EXPECT_EQ(headerBytes, builder1->getHeaderBytes());
|
||||
auto builtOut1 = std::move(*builder1).buildPacket();
|
||||
@ -534,10 +543,10 @@ TEST_F(QuicPacketBuilderTest, BuildTwoInplaces) {
|
||||
1000,
|
||||
ShortHeader(ProtectionType::KeyPhaseZero, getTestConnectionId(), 0),
|
||||
0);
|
||||
builder2->encodePacketHeader();
|
||||
ASSERT_FALSE(builder2->encodePacketHeader().hasError());
|
||||
EXPECT_EQ(headerBytes, builder2->getHeaderBytes());
|
||||
for (size_t i = 0; i < 40; i++) {
|
||||
writeFrame(PaddingFrame(), *builder2);
|
||||
ASSERT_FALSE(writeFrame(PaddingFrame(), *builder2).hasError());
|
||||
}
|
||||
auto builtOut2 = std::move(*builder2).buildPacket();
|
||||
EXPECT_EQ(1, builtOut2.packet.frames.size());
|
||||
@ -558,7 +567,7 @@ TEST_F(QuicPacketBuilderTest, InplaceBuilderShorterHeaderBytes) {
|
||||
ShortHeader(ProtectionType::KeyPhaseZero, connId, packetNum),
|
||||
largestAckedPacketNum,
|
||||
kDefaultUDPSendPacketLen);
|
||||
inplaceBuilder->encodePacketHeader();
|
||||
ASSERT_FALSE(inplaceBuilder->encodePacketHeader().hasError());
|
||||
EXPECT_EQ(2 + connId.size(), inplaceBuilder->getHeaderBytes());
|
||||
}
|
||||
|
||||
@ -578,7 +587,7 @@ TEST_F(QuicPacketBuilderTest, InplaceBuilderLongHeaderBytes) {
|
||||
QuicVersion::MVFST),
|
||||
largestAckedPacketNum,
|
||||
kDefaultUDPSendPacketLen);
|
||||
inplaceBuilder->encodePacketHeader();
|
||||
ASSERT_FALSE(inplaceBuilder->encodePacketHeader().hasError());
|
||||
EXPECT_EQ(
|
||||
9 /* initial + version + cid + cid + token length */ + srcConnId.size() +
|
||||
destConnId.size() + kMaxPacketLenSize,
|
||||
@ -761,8 +770,8 @@ TEST_P(QuicPacketBuilderTest, PadUpLongHeaderPacket) {
|
||||
QuicVersion::MVFST),
|
||||
largestAcked,
|
||||
kDefaultUDPSendPacketLen);
|
||||
builder->encodePacketHeader();
|
||||
writeFrame(PingFrame(), *builder);
|
||||
ASSERT_FALSE(builder->encodePacketHeader().hasError());
|
||||
ASSERT_FALSE(writeFrame(PingFrame(), *builder).hasError());
|
||||
EXPECT_TRUE(builder->canBuildPacket());
|
||||
auto builtOut = std::move(*builder).buildPacket();
|
||||
auto resultPacket = builtOut.packet;
|
||||
@ -794,10 +803,10 @@ TEST_P(QuicPacketBuilderTest, TestCipherOverhead) {
|
||||
QuicVersion::MVFST),
|
||||
largestAcked,
|
||||
kDefaultUDPSendPacketLen);
|
||||
builder->encodePacketHeader();
|
||||
ASSERT_FALSE(builder->encodePacketHeader().hasError());
|
||||
builder->accountForCipherOverhead(cipherOverhead);
|
||||
while (builder->canBuildPacket()) {
|
||||
writeFrame(PingFrame(), *builder);
|
||||
ASSERT_FALSE(writeFrame(PingFrame(), *builder).hasError());
|
||||
}
|
||||
auto builtOut = std::move(*builder).buildPacket();
|
||||
auto resultRegularPacket = builtOut.packet;
|
||||
|
@ -44,7 +44,7 @@ TEST_F(QuicPacketRebuilderTest, RebuildEmpty) {
|
||||
kDefaultUDPSendPacketLen,
|
||||
ShortHeader(ProtectionType::KeyPhaseZero, getTestConnectionId(), 0),
|
||||
0 /* largestAcked */);
|
||||
regularBuilder.encodePacketHeader();
|
||||
ASSERT_FALSE(regularBuilder.encodePacketHeader().hasError());
|
||||
QuicConnectionStateBase conn(QuicNodeType::Client);
|
||||
PacketRebuilder rebuilder(regularBuilder, conn);
|
||||
auto packet = std::move(regularBuilder).buildPacket();
|
||||
@ -69,10 +69,11 @@ TEST_F(QuicPacketRebuilderTest, RebuildSmallInitial) {
|
||||
kDefaultUDPSendPacketLen, std::move(initialHeader2), 0);
|
||||
|
||||
PingFrame pingFrame{};
|
||||
writeFrame(pingFrame, regularBuilder1);
|
||||
ASSERT_FALSE(writeFrame(pingFrame, regularBuilder1).hasError());
|
||||
MaxStreamsFrame maxStreamsFrame(4321, true);
|
||||
writeFrame(QuicSimpleFrame(maxStreamsFrame), regularBuilder1);
|
||||
regularBuilder1.encodePacketHeader();
|
||||
ASSERT_FALSE(
|
||||
writeFrame(QuicSimpleFrame(maxStreamsFrame), regularBuilder1).hasError());
|
||||
ASSERT_FALSE(regularBuilder1.encodePacketHeader().hasError());
|
||||
QuicConnectionStateBase conn(QuicNodeType::Client);
|
||||
PacketRebuilder rebuilder(regularBuilder2, conn);
|
||||
auto packet = std::move(regularBuilder1).buildPacket();
|
||||
@ -80,7 +81,7 @@ TEST_F(QuicPacketRebuilderTest, RebuildSmallInitial) {
|
||||
EXPECT_FALSE(packet.header.empty());
|
||||
ASSERT_EQ(packet.packet.frames.size(), 2);
|
||||
EXPECT_FALSE(packet.body.empty());
|
||||
regularBuilder2.encodePacketHeader();
|
||||
ASSERT_FALSE(regularBuilder2.encodePacketHeader().hasError());
|
||||
auto rebuildResult = rebuilder.rebuildFromPacket(outstanding);
|
||||
ASSERT_FALSE(rebuildResult.hasError());
|
||||
ASSERT_TRUE(rebuildResult.value().hasValue());
|
||||
@ -99,7 +100,7 @@ TEST_F(QuicPacketRebuilderTest, RebuildPacket) {
|
||||
ProtectionType::KeyPhaseZero, getTestConnectionId(), 0);
|
||||
RegularQuicPacketBuilder regularBuilder1(
|
||||
kDefaultUDPSendPacketLen, std::move(shortHeader1), 0 /* largestAcked */);
|
||||
regularBuilder1.encodePacketHeader();
|
||||
ASSERT_FALSE(regularBuilder1.encodePacketHeader().hasError());
|
||||
// Get a bunch frames
|
||||
ConnectionCloseFrame connCloseFrame(
|
||||
QuicErrorCode(TransportErrorCode::FRAME_ENCODING_ERROR),
|
||||
@ -131,10 +132,11 @@ TEST_F(QuicPacketRebuilderTest, RebuildPacket) {
|
||||
PingFrame pingFrame{};
|
||||
// Write them with a regular builder
|
||||
// Write the ACK frame first since it has special rebuilder handling.
|
||||
writeAckFrame(ackMeta, regularBuilder1);
|
||||
writeFrame(connCloseFrame, regularBuilder1);
|
||||
writeFrame(QuicSimpleFrame(maxStreamsFrame), regularBuilder1);
|
||||
writeFrame(pingFrame, regularBuilder1);
|
||||
ASSERT_FALSE(writeAckFrame(ackMeta, regularBuilder1).hasError());
|
||||
ASSERT_FALSE(writeFrame(connCloseFrame, regularBuilder1).hasError());
|
||||
ASSERT_FALSE(
|
||||
writeFrame(QuicSimpleFrame(maxStreamsFrame), regularBuilder1).hasError());
|
||||
ASSERT_FALSE(writeFrame(pingFrame, regularBuilder1).hasError());
|
||||
writeStreamFrameHeader(
|
||||
regularBuilder1,
|
||||
streamId,
|
||||
@ -145,10 +147,12 @@ TEST_F(QuicPacketRebuilderTest, RebuildPacket) {
|
||||
none /* skipLenHint */);
|
||||
writeStreamFrameData(
|
||||
regularBuilder1, buf->clone(), buf->computeChainDataLength());
|
||||
writeFrame(maxDataFrame, regularBuilder1);
|
||||
writeFrame(maxStreamDataFrame, regularBuilder1);
|
||||
writeCryptoFrame(
|
||||
cryptoOffset, ChainedByteRangeHead(cryptoBuf), regularBuilder1);
|
||||
ASSERT_FALSE(writeFrame(maxDataFrame, regularBuilder1).hasError());
|
||||
ASSERT_FALSE(writeFrame(maxStreamDataFrame, regularBuilder1).hasError());
|
||||
ASSERT_FALSE(
|
||||
writeCryptoFrame(
|
||||
cryptoOffset, ChainedByteRangeHead(cryptoBuf), regularBuilder1)
|
||||
.hasError());
|
||||
auto packet1 = std::move(regularBuilder1).buildPacket();
|
||||
ASSERT_EQ(8, packet1.packet.frames.size());
|
||||
stream->retransmissionBuffer.emplace(
|
||||
@ -171,7 +175,7 @@ TEST_F(QuicPacketRebuilderTest, RebuildPacket) {
|
||||
ProtectionType::KeyPhaseZero, getTestConnectionId(), 0);
|
||||
RegularQuicPacketBuilder regularBuilder2(
|
||||
kDefaultUDPSendPacketLen, std::move(shortHeader2), 0 /* largestAcked */);
|
||||
regularBuilder2.encodePacketHeader();
|
||||
ASSERT_FALSE(regularBuilder2.encodePacketHeader().hasError());
|
||||
PacketRebuilder rebuilder(regularBuilder2, conn);
|
||||
auto outstanding = makeDummyOutstandingPacket(packet1.packet, 1000);
|
||||
auto rebuildResult = rebuilder.rebuildFromPacket(outstanding);
|
||||
@ -261,7 +265,7 @@ TEST_F(QuicPacketRebuilderTest, RebuildAfterResetStream) {
|
||||
ProtectionType::KeyPhaseZero, getTestConnectionId(), 0);
|
||||
RegularQuicPacketBuilder regularBuilder1(
|
||||
kDefaultUDPSendPacketLen, std::move(shortHeader1), 0 /* largestAcked */);
|
||||
regularBuilder1.encodePacketHeader();
|
||||
ASSERT_FALSE(regularBuilder1.encodePacketHeader().hasError());
|
||||
QuicServerConnectionState conn(
|
||||
FizzServerQuicHandshakeContext::Builder().build());
|
||||
ASSERT_FALSE(
|
||||
@ -289,7 +293,7 @@ TEST_F(QuicPacketRebuilderTest, RebuildAfterResetStream) {
|
||||
ProtectionType::KeyPhaseZero, getTestConnectionId(), 0);
|
||||
RegularQuicPacketBuilder regularBuilder2(
|
||||
kDefaultUDPSendPacketLen, std::move(shortHeader2), 0 /* largestAcked */);
|
||||
regularBuilder2.encodePacketHeader();
|
||||
ASSERT_FALSE(regularBuilder2.encodePacketHeader().hasError());
|
||||
PacketRebuilder rebuilder(regularBuilder2, conn);
|
||||
auto outstanding = makeDummyOutstandingPacket(packet1.packet, 1000);
|
||||
auto rebuildResult = rebuilder.rebuildFromPacket(outstanding);
|
||||
@ -302,7 +306,7 @@ TEST_F(QuicPacketRebuilderTest, FinOnlyStreamRebuild) {
|
||||
ProtectionType::KeyPhaseZero, getTestConnectionId(), 0);
|
||||
RegularQuicPacketBuilder regularBuilder1(
|
||||
kDefaultUDPSendPacketLen, std::move(shortHeader1), 0 /* largestAcked */);
|
||||
regularBuilder1.encodePacketHeader();
|
||||
ASSERT_FALSE(regularBuilder1.encodePacketHeader().hasError());
|
||||
QuicServerConnectionState conn(
|
||||
FizzServerQuicHandshakeContext::Builder().build());
|
||||
ASSERT_FALSE(
|
||||
@ -325,7 +329,7 @@ TEST_F(QuicPacketRebuilderTest, FinOnlyStreamRebuild) {
|
||||
ProtectionType::KeyPhaseZero, getTestConnectionId(), 0);
|
||||
RegularQuicPacketBuilder regularBuilder2(
|
||||
kDefaultUDPSendPacketLen, std::move(shortHeader2), 0 /* largestAcked */);
|
||||
regularBuilder2.encodePacketHeader();
|
||||
ASSERT_FALSE(regularBuilder2.encodePacketHeader().hasError());
|
||||
PacketRebuilder rebuilder(regularBuilder2, conn);
|
||||
auto outstanding = makeDummyOutstandingPacket(packet1.packet, 2000);
|
||||
auto rebuildResult = rebuilder.rebuildFromPacket(outstanding);
|
||||
@ -350,7 +354,7 @@ TEST_F(QuicPacketRebuilderTest, RebuildDataStreamAndEmptyCryptoStream) {
|
||||
ProtectionType::KeyPhaseZero, getTestConnectionId(), 0);
|
||||
RegularQuicPacketBuilder regularBuilder1(
|
||||
kDefaultUDPSendPacketLen, std::move(shortHeader1), 0 /* largestAcked */);
|
||||
regularBuilder1.encodePacketHeader();
|
||||
ASSERT_FALSE(regularBuilder1.encodePacketHeader().hasError());
|
||||
// Get a bunch frames
|
||||
QuicServerConnectionState conn(
|
||||
FizzServerQuicHandshakeContext::Builder().build());
|
||||
@ -374,8 +378,10 @@ TEST_F(QuicPacketRebuilderTest, RebuildDataStreamAndEmptyCryptoStream) {
|
||||
none /* skipLenHint */);
|
||||
writeStreamFrameData(
|
||||
regularBuilder1, buf->clone(), buf->computeChainDataLength());
|
||||
writeCryptoFrame(
|
||||
cryptoOffset, ChainedByteRangeHead(cryptoBuf), regularBuilder1);
|
||||
ASSERT_FALSE(
|
||||
writeCryptoFrame(
|
||||
cryptoOffset, ChainedByteRangeHead(cryptoBuf), regularBuilder1)
|
||||
.hasError());
|
||||
auto packet1 = std::move(regularBuilder1).buildPacket();
|
||||
ASSERT_EQ(2, packet1.packet.frames.size());
|
||||
stream->retransmissionBuffer.emplace(
|
||||
@ -391,7 +397,7 @@ TEST_F(QuicPacketRebuilderTest, RebuildDataStreamAndEmptyCryptoStream) {
|
||||
ProtectionType::KeyPhaseZero, getTestConnectionId(), 0);
|
||||
RegularQuicPacketBuilder regularBuilder2(
|
||||
kDefaultUDPSendPacketLen, std::move(shortHeader2), 0 /* largestAcked */);
|
||||
regularBuilder2.encodePacketHeader();
|
||||
ASSERT_FALSE(regularBuilder2.encodePacketHeader().hasError());
|
||||
PacketRebuilder rebuilder(regularBuilder2, conn);
|
||||
auto outstanding = makeDummyOutstandingPacket(packet1.packet, 1000);
|
||||
auto rebuildResult = rebuilder.rebuildFromPacket(outstanding);
|
||||
@ -418,7 +424,7 @@ TEST_F(QuicPacketRebuilderTest, CannotRebuildEmptyCryptoStream) {
|
||||
ProtectionType::KeyPhaseZero, getTestConnectionId(), 0);
|
||||
RegularQuicPacketBuilder regularBuilder1(
|
||||
kDefaultUDPSendPacketLen, std::move(shortHeader1), 0 /* largestAcked */);
|
||||
regularBuilder1.encodePacketHeader();
|
||||
ASSERT_FALSE(regularBuilder1.encodePacketHeader().hasError());
|
||||
// Get a bunch frames
|
||||
QuicServerConnectionState conn(
|
||||
FizzServerQuicHandshakeContext::Builder().build());
|
||||
@ -426,8 +432,10 @@ TEST_F(QuicPacketRebuilderTest, CannotRebuildEmptyCryptoStream) {
|
||||
auto cryptoBuf = folly::IOBuf::copyBuffer("NewSessionTicket");
|
||||
|
||||
// Write them with a regular builder
|
||||
writeCryptoFrame(
|
||||
cryptoOffset, ChainedByteRangeHead(cryptoBuf), regularBuilder1);
|
||||
ASSERT_FALSE(
|
||||
writeCryptoFrame(
|
||||
cryptoOffset, ChainedByteRangeHead(cryptoBuf), regularBuilder1)
|
||||
.hasError());
|
||||
auto packet1 = std::move(regularBuilder1).buildPacket();
|
||||
ASSERT_EQ(1, packet1.packet.frames.size());
|
||||
// Do not add the buf to crypto stream's retransmission buffer,
|
||||
@ -438,7 +446,7 @@ TEST_F(QuicPacketRebuilderTest, CannotRebuildEmptyCryptoStream) {
|
||||
ProtectionType::KeyPhaseZero, getTestConnectionId(), 0);
|
||||
RegularQuicPacketBuilder regularBuilder2(
|
||||
kDefaultUDPSendPacketLen, std::move(shortHeader2), 0 /* largestAcked */);
|
||||
regularBuilder2.encodePacketHeader();
|
||||
ASSERT_FALSE(regularBuilder2.encodePacketHeader().hasError());
|
||||
PacketRebuilder rebuilder(regularBuilder2, conn);
|
||||
auto outstanding = makeDummyOutstandingPacket(packet1.packet, 1000);
|
||||
auto rebuildResult = rebuilder.rebuildFromPacket(outstanding);
|
||||
@ -451,7 +459,7 @@ TEST_F(QuicPacketRebuilderTest, CannotRebuild) {
|
||||
ProtectionType::KeyPhaseZero, getTestConnectionId(), 0);
|
||||
RegularQuicPacketBuilder regularBuilder1(
|
||||
kDefaultUDPSendPacketLen, std::move(shortHeader1), 0 /* largestAcked */);
|
||||
regularBuilder1.encodePacketHeader();
|
||||
ASSERT_FALSE(regularBuilder1.encodePacketHeader().hasError());
|
||||
// Get a bunch frames
|
||||
ConnectionCloseFrame connCloseFrame(
|
||||
QuicErrorCode(TransportErrorCode::FRAME_ENCODING_ERROR),
|
||||
@ -476,10 +484,10 @@ TEST_F(QuicPacketRebuilderTest, CannotRebuild) {
|
||||
folly::IOBuf::copyBuffer("You can't deny you are looking for the sunset");
|
||||
PingFrame pingFrame;
|
||||
// Write them with a regular builder
|
||||
writeFrame(connCloseFrame, regularBuilder1);
|
||||
writeFrame(maxStreamIdFrame, regularBuilder1);
|
||||
writeFrame(pingFrame, regularBuilder1);
|
||||
writeAckFrame(ackMeta, regularBuilder1);
|
||||
ASSERT_FALSE(writeFrame(connCloseFrame, regularBuilder1).hasError());
|
||||
ASSERT_FALSE(writeFrame(maxStreamIdFrame, regularBuilder1).hasError());
|
||||
ASSERT_FALSE(writeFrame(pingFrame, regularBuilder1).hasError());
|
||||
ASSERT_FALSE(writeAckFrame(ackMeta, regularBuilder1).hasError());
|
||||
writeStreamFrameHeader(
|
||||
regularBuilder1,
|
||||
streamId,
|
||||
@ -507,7 +515,7 @@ TEST_F(QuicPacketRebuilderTest, CannotRebuild) {
|
||||
2,
|
||||
std::move(shortHeader2),
|
||||
0 /* largestAcked */);
|
||||
regularBuilder2.encodePacketHeader();
|
||||
ASSERT_FALSE(regularBuilder2.encodePacketHeader().hasError());
|
||||
PacketRebuilder rebuilder(regularBuilder2, conn);
|
||||
auto outstanding = makeDummyOutstandingPacket(packet1.packet, 1000);
|
||||
auto rebuildResult = rebuilder.rebuildFromPacket(outstanding);
|
||||
@ -520,9 +528,9 @@ TEST_F(QuicPacketRebuilderTest, CloneCounter) {
|
||||
ProtectionType::KeyPhaseZero, getTestConnectionId(), 0);
|
||||
RegularQuicPacketBuilder regularBuilder(
|
||||
kDefaultUDPSendPacketLen, std::move(shortHeader1), 0 /* largestAcked */);
|
||||
regularBuilder.encodePacketHeader();
|
||||
ASSERT_FALSE(regularBuilder.encodePacketHeader().hasError());
|
||||
MaxDataFrame maxDataFrame(31415926);
|
||||
writeFrame(maxDataFrame, regularBuilder);
|
||||
ASSERT_FALSE(writeFrame(maxDataFrame, regularBuilder).hasError());
|
||||
auto packet = std::move(regularBuilder).buildPacket();
|
||||
auto outstandingPacket = makeDummyOutstandingPacket(packet.packet, 1000);
|
||||
QuicServerConnectionState conn(
|
||||
@ -531,7 +539,7 @@ TEST_F(QuicPacketRebuilderTest, CloneCounter) {
|
||||
ProtectionType::KeyPhaseZero, getTestConnectionId(), 0);
|
||||
RegularQuicPacketBuilder regularBuilder2(
|
||||
kDefaultUDPSendPacketLen, std::move(shortHeader2), 0 /* largestAcked */);
|
||||
regularBuilder2.encodePacketHeader();
|
||||
ASSERT_FALSE(regularBuilder2.encodePacketHeader().hasError());
|
||||
PacketRebuilder rebuilder(regularBuilder2, conn);
|
||||
ASSERT_FALSE(rebuilder.rebuildFromPacket(outstandingPacket).hasError());
|
||||
EXPECT_TRUE(outstandingPacket.maybeClonedPacketIdentifier.has_value());
|
||||
@ -543,9 +551,9 @@ TEST_F(QuicPacketRebuilderTest, PurePingWillRebuild) {
|
||||
ProtectionType::KeyPhaseZero, getTestConnectionId(), 0);
|
||||
RegularQuicPacketBuilder regularBuilder(
|
||||
kDefaultUDPSendPacketLen, std::move(shortHeader1), 0);
|
||||
regularBuilder.encodePacketHeader();
|
||||
ASSERT_FALSE(regularBuilder.encodePacketHeader().hasError());
|
||||
PingFrame pingFrame;
|
||||
writeFrame(pingFrame, regularBuilder);
|
||||
ASSERT_FALSE(writeFrame(pingFrame, regularBuilder).hasError());
|
||||
auto packet = std::move(regularBuilder).buildPacket();
|
||||
auto outstandingPacket = makeDummyOutstandingPacket(packet.packet, 50);
|
||||
EXPECT_EQ(1, outstandingPacket.packet.frames.size());
|
||||
@ -555,7 +563,7 @@ TEST_F(QuicPacketRebuilderTest, PurePingWillRebuild) {
|
||||
ProtectionType::KeyPhaseZero, getTestConnectionId(), 0);
|
||||
RegularQuicPacketBuilder regularBuilder2(
|
||||
kDefaultUDPSendPacketLen, std::move(shortHeader2), 0);
|
||||
regularBuilder2.encodePacketHeader();
|
||||
ASSERT_FALSE(regularBuilder2.encodePacketHeader().hasError());
|
||||
PacketRebuilder rebuilder(regularBuilder2, conn);
|
||||
auto rebuildResult = rebuilder.rebuildFromPacket(outstandingPacket);
|
||||
ASSERT_FALSE(rebuildResult.hasError());
|
||||
@ -579,7 +587,7 @@ TEST_F(QuicPacketRebuilderTest, LastStreamFrameSkipLen) {
|
||||
ProtectionType::KeyPhaseZero, getTestConnectionId(), 0);
|
||||
RegularQuicPacketBuilder regularBuilder(
|
||||
kDefaultUDPSendPacketLen, std::move(shortHeader), 0);
|
||||
regularBuilder.encodePacketHeader();
|
||||
ASSERT_FALSE(regularBuilder.encodePacketHeader().hasError());
|
||||
writeStreamFrameHeader(
|
||||
regularBuilder,
|
||||
streamId,
|
||||
@ -633,7 +641,9 @@ TEST_F(QuicPacketRebuilderTest, LastStreamFrameSkipLen) {
|
||||
EXPECT_CALL(mockBuilder, write(_))
|
||||
.Times(4)
|
||||
.WillRepeatedly(Invoke([&](const QuicInteger& quicInt) {
|
||||
packetLimit -= quicInt.getSize();
|
||||
auto sizeResult = quicInt.getSize();
|
||||
ASSERT_FALSE(sizeResult.hasError());
|
||||
packetLimit -= sizeResult.value();
|
||||
}));
|
||||
|
||||
PacketRebuilder rebuilder(mockBuilder, conn);
|
||||
@ -656,7 +666,7 @@ TEST_F(QuicPacketRebuilderTest, LastStreamFrameFinOnlySkipLen) {
|
||||
ProtectionType::KeyPhaseZero, getTestConnectionId(), 0);
|
||||
RegularQuicPacketBuilder regularBuilder(
|
||||
kDefaultUDPSendPacketLen, std::move(shortHeader), 0);
|
||||
regularBuilder.encodePacketHeader();
|
||||
ASSERT_FALSE(regularBuilder.encodePacketHeader().hasError());
|
||||
writeStreamFrameHeader(
|
||||
regularBuilder,
|
||||
streamId,
|
||||
@ -710,7 +720,9 @@ TEST_F(QuicPacketRebuilderTest, LastStreamFrameFinOnlySkipLen) {
|
||||
EXPECT_CALL(mockBuilder, write(_))
|
||||
.Times(5)
|
||||
.WillRepeatedly(Invoke([&](const QuicInteger& quicInt) {
|
||||
packetLimit -= quicInt.getSize();
|
||||
auto sizeResult = quicInt.getSize();
|
||||
ASSERT_FALSE(sizeResult.hasError());
|
||||
packetLimit -= sizeResult.value();
|
||||
}));
|
||||
|
||||
PacketRebuilder rebuilder(mockBuilder, conn);
|
||||
|
@ -199,10 +199,13 @@ TEST_F(QuicReadCodecTest, LongHeaderPacketLenMismatch) {
|
||||
|
||||
RegularQuicPacketBuilder builder(
|
||||
kDefaultUDPSendPacketLen, std::move(headerIn), 0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
auto encodeResult = builder.encodePacketHeader();
|
||||
ASSERT_FALSE(encodeResult.hasError());
|
||||
builder.accountForCipherOverhead(0);
|
||||
auto cryptoFrameBuf = folly::IOBuf::copyBuffer("CHLO");
|
||||
writeCryptoFrame(0, ChainedByteRangeHead(cryptoFrameBuf), builder);
|
||||
auto writeResult =
|
||||
writeCryptoFrame(0, ChainedByteRangeHead(cryptoFrameBuf), builder);
|
||||
ASSERT_FALSE(writeResult.hasError());
|
||||
auto packet = packetToBuf(std::move(builder).buildPacket());
|
||||
auto packetQueue = bufToQueue(std::move(packet));
|
||||
|
||||
@ -280,7 +283,8 @@ TEST_F(QuicReadCodecTest, StreamWithShortHeaderOnlyHeader) {
|
||||
ShortHeader header(ProtectionType::KeyPhaseZero, connId, packetNum);
|
||||
RegularQuicPacketBuilder builder(
|
||||
kDefaultUDPSendPacketLen, std::move(header), 0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
auto encodeResult = builder.encodePacketHeader();
|
||||
ASSERT_FALSE(encodeResult.hasError());
|
||||
auto packetBuf = packetToBuf(std::move(builder).buildPacket());
|
||||
|
||||
auto aead = std::make_unique<MockAead>();
|
||||
|
@ -158,12 +158,13 @@ void setupCommonExpects(MockQuicPacketBuilder& pktBuilder) {
|
||||
pktBuilder.appender_.push(data, len);
|
||||
pktBuilder.remaining_ -= len;
|
||||
})));
|
||||
|
||||
EXPECT_CALL(pktBuilder, write(_))
|
||||
.WillRepeatedly(Invoke([&](const QuicInteger& quicInteger) {
|
||||
auto size = quicInteger.getSize();
|
||||
ASSERT_FALSE(size.hasError());
|
||||
quicInteger.encode(
|
||||
[&](auto val) { pktBuilder.appender_.writeBE(val); });
|
||||
pktBuilder.remaining_ -= quicInteger.getSize();
|
||||
pktBuilder.remaining_ -= *size;
|
||||
}));
|
||||
}
|
||||
|
||||
@ -224,8 +225,10 @@ size_t computeBytesForOptionalAckFields(
|
||||
|
||||
if (frameType == FrameType::ACK_EXTENDED) {
|
||||
// Account for the extended ack header if it is included into the ack.
|
||||
sizeConsumed += getQuicIntegerSizeThrows(
|
||||
ackFrameWriteResult.extendedAckFeaturesEnabled);
|
||||
auto sizeResult =
|
||||
getQuicIntegerSize(ackFrameWriteResult.extendedAckFeaturesEnabled);
|
||||
CHECK(!sizeResult.hasError());
|
||||
sizeConsumed += sizeResult.value();
|
||||
}
|
||||
|
||||
if (frameType == FrameType::ACK_RECEIVE_TIMESTAMPS ||
|
||||
@ -250,27 +253,41 @@ size_t computeBytesForOptionalAckFields(
|
||||
// 1. last received packet's timestamp delta,
|
||||
// 2. last received packet's number,
|
||||
// 3. count of timestamp ranges
|
||||
sizeConsumed +=
|
||||
getQuicIntegerSizeThrows(
|
||||
lastTimeStampDelta
|
||||
.count()) + // latest received packet timestamp delta
|
||||
getQuicIntegerSizeThrows(lastPktNum) + // latest received packet number
|
||||
getQuicIntegerSizeThrows(
|
||||
numRanges); // count of ack_receive_timestamp ranges
|
||||
auto lastTimeDeltaSizeResult =
|
||||
getQuicIntegerSize(lastTimeStampDelta.count());
|
||||
CHECK(!lastTimeDeltaSizeResult.hasError());
|
||||
auto lastPktNumSizeResult = getQuicIntegerSize(lastPktNum);
|
||||
CHECK(!lastPktNumSizeResult.hasError());
|
||||
auto numRangesSizeResult = getQuicIntegerSize(numRanges);
|
||||
CHECK(!numRangesSizeResult.hasError());
|
||||
|
||||
sizeConsumed += lastTimeDeltaSizeResult
|
||||
.value() + // latest received packet timestamp delta
|
||||
lastPktNumSizeResult.value() + // latest received packet number
|
||||
numRangesSizeResult.value(); // count of ack_receive_timestamp ranges
|
||||
|
||||
if (numRanges > 0) {
|
||||
sizeConsumed +=
|
||||
auto sizeUsedResult =
|
||||
computeSizeUsedByRecvdTimestamps(ackFrameWriteResult.writeAckFrame);
|
||||
CHECK(!sizeUsedResult.hasError());
|
||||
sizeConsumed += sizeUsedResult.value();
|
||||
};
|
||||
}
|
||||
|
||||
if (shouldHaveECN) {
|
||||
// Account for ECN count fields if they are included into the ack.
|
||||
sizeConsumed += getQuicIntegerSizeThrows(
|
||||
ackFrameMetadata.ackState.ecnECT0CountReceived) +
|
||||
getQuicIntegerSizeThrows(
|
||||
ackFrameMetadata.ackState.ecnECT1CountReceived) +
|
||||
getQuicIntegerSizeThrows(ackFrameMetadata.ackState.ecnCECountReceived);
|
||||
auto ect0SizeResult =
|
||||
getQuicIntegerSize(ackFrameMetadata.ackState.ecnECT0CountReceived);
|
||||
CHECK(!ect0SizeResult.hasError());
|
||||
auto ect1SizeResult =
|
||||
getQuicIntegerSize(ackFrameMetadata.ackState.ecnECT1CountReceived);
|
||||
CHECK(!ect1SizeResult.hasError());
|
||||
auto ceSizeResult =
|
||||
getQuicIntegerSize(ackFrameMetadata.ackState.ecnCECountReceived);
|
||||
CHECK(!ceSizeResult.hasError());
|
||||
|
||||
sizeConsumed +=
|
||||
ect0SizeResult.value() + ect1SizeResult.value() + ceSizeResult.value();
|
||||
}
|
||||
return sizeConsumed;
|
||||
}
|
||||
@ -383,13 +400,16 @@ TEST_P(QuicWriteCodecExtendedAckTest, WriteWithFeatures) {
|
||||
// There is 1 gap => each represented by 2 bytes => 2 bytes
|
||||
// 2 byte for first ack block length, then 2 bytes for the next len => 4 bytes
|
||||
// total 11 bytes for base ACK. Extended frame size is added below.
|
||||
auto ackFrameWriteResult = *writeAckFrame(
|
||||
auto ackFrameWriteResultExpected = writeAckFrame(
|
||||
ackFrameMetaData,
|
||||
pktBuilder,
|
||||
frameType,
|
||||
defaultAckReceiveTimestmpsConfig,
|
||||
kMaxReceivedPktsTimestampsStored,
|
||||
extendedAckSupport);
|
||||
ASSERT_FALSE(ackFrameWriteResultExpected.hasError());
|
||||
ASSERT_TRUE(ackFrameWriteResultExpected.value().has_value());
|
||||
auto& ackFrameWriteResult = ackFrameWriteResultExpected.value().value();
|
||||
auto addlBytesConsumed = computeBytesForOptionalAckFields(
|
||||
ackFrameMetaData, ackFrameWriteResult, frameType);
|
||||
EXPECT_EQ(11 + addlBytesConsumed, ackFrameWriteResult.bytesWritten);
|
||||
@ -1020,7 +1040,9 @@ TEST_F(QuicWriteCodecTest, WriteStreamFrameHeadeSkipLen) {
|
||||
EXPECT_CALL(pktBuilder, write(_))
|
||||
.Times(2)
|
||||
.WillRepeatedly(Invoke([&](const QuicInteger& quicInt) {
|
||||
packetLimit -= quicInt.getSize();
|
||||
auto size = quicInt.getSize();
|
||||
ASSERT_FALSE(size.hasError());
|
||||
packetLimit -= size.value();
|
||||
}));
|
||||
StreamId streamId = 0;
|
||||
uint64_t offset = 10;
|
||||
@ -1047,7 +1069,8 @@ TEST_F(QuicWriteCodecTest, WriteStreamFrameHeadeNotSkipLen) {
|
||||
EXPECT_CALL(pktBuilder, write(_))
|
||||
.Times(3)
|
||||
.WillRepeatedly(Invoke([&](const QuicInteger& quicInt) {
|
||||
packetLimit -= quicInt.getSize();
|
||||
ASSERT_FALSE(quicInt.getSize().hasError());
|
||||
packetLimit -= quicInt.getSize().value();
|
||||
}));
|
||||
StreamId streamId = 0;
|
||||
uint64_t offset = 10;
|
||||
@ -1074,7 +1097,8 @@ TEST_F(QuicWriteCodecTest, WriteStreamFrameHeadeLengthHintTrue) {
|
||||
EXPECT_CALL(pktBuilder, write(_))
|
||||
.Times(2)
|
||||
.WillRepeatedly(Invoke([&](const QuicInteger& quicInt) {
|
||||
packetLimit -= quicInt.getSize();
|
||||
ASSERT_FALSE(quicInt.getSize().hasError());
|
||||
packetLimit -= quicInt.getSize().value();
|
||||
}));
|
||||
StreamId streamId = 0;
|
||||
uint64_t offset = 10;
|
||||
@ -1101,7 +1125,8 @@ TEST_F(QuicWriteCodecTest, WriteStreamFrameHeadeLengthHintFalse) {
|
||||
EXPECT_CALL(pktBuilder, write(_))
|
||||
.Times(3)
|
||||
.WillRepeatedly(Invoke([&](const QuicInteger& quicInt) {
|
||||
packetLimit -= quicInt.getSize();
|
||||
ASSERT_FALSE(quicInt.getSize().hasError());
|
||||
packetLimit -= quicInt.getSize().value();
|
||||
}));
|
||||
StreamId streamId = 0;
|
||||
uint64_t offset = 10;
|
||||
@ -1132,14 +1157,14 @@ TEST_P(QuicWriteCodecTest, AckFrameGapExceedsRepresentation) {
|
||||
.connTime = connTime,
|
||||
};
|
||||
|
||||
EXPECT_THROW(
|
||||
writeAckFrame(
|
||||
ackFrameMetaData,
|
||||
pktBuilder,
|
||||
frameType,
|
||||
defaultAckReceiveTimestmpsConfig,
|
||||
0),
|
||||
QuicTransportException);
|
||||
auto result = writeAckFrame(
|
||||
ackFrameMetaData,
|
||||
pktBuilder,
|
||||
frameType,
|
||||
defaultAckReceiveTimestmpsConfig,
|
||||
0);
|
||||
ASSERT_TRUE(result.hasError());
|
||||
ASSERT_NE(result.error().code.asTransportErrorCode(), nullptr);
|
||||
}
|
||||
|
||||
TEST_P(QuicWriteCodecTest, AckFrameVeryLargeAckRange) {
|
||||
@ -1193,12 +1218,15 @@ TEST_P(QuicWriteCodecTest, AckFrameVeryLargeAckRange) {
|
||||
.ackDelayExponent = static_cast<uint8_t>(kDefaultAckDelayExponent),
|
||||
.connTime = connTime,
|
||||
};
|
||||
auto ackFrameWriteResult = *writeAckFrame(
|
||||
auto ackFrameWriteResultExpected = writeAckFrame(
|
||||
ackFrameMetaData,
|
||||
pktBuilder,
|
||||
frameType,
|
||||
defaultAckReceiveTimestmpsConfig,
|
||||
kMaxReceivedPktsTimestampsStored);
|
||||
ASSERT_FALSE(ackFrameWriteResultExpected.hasError());
|
||||
ASSERT_TRUE(ackFrameWriteResultExpected.value().has_value());
|
||||
auto& ackFrameWriteResult = ackFrameWriteResultExpected.value().value();
|
||||
auto addlBytesConsumed = computeBytesForOptionalAckFields(
|
||||
ackFrameMetaData, ackFrameWriteResult, frameType);
|
||||
|
||||
@ -1227,7 +1255,6 @@ TEST_P(QuicWriteCodecTest, AckFrameVeryLargeAckRange) {
|
||||
assertsOnDecodedReceiveTimestamps(
|
||||
ackFrameMetaData,
|
||||
ackFrameWriteResult.writeAckFrame,
|
||||
|
||||
decodedAckFrame,
|
||||
1 /* timestamp ranges count */,
|
||||
kMaxReceivedPktsTimestampsStored /* timestamps count */,
|
||||
@ -1264,7 +1291,8 @@ TEST_P(QuicWriteCodecTest, AckFrameNotEnoughForAnything) {
|
||||
frameType,
|
||||
defaultAckReceiveTimestmpsConfig,
|
||||
kMaxReceivedPktsTimestampsStored);
|
||||
EXPECT_FALSE(result.has_value());
|
||||
EXPECT_FALSE(result.hasError());
|
||||
EXPECT_FALSE(result.value().has_value());
|
||||
EXPECT_EQ(pktBuilder.remainingSpaceInPkt(), 4);
|
||||
}
|
||||
|
||||
@ -1294,13 +1322,16 @@ TEST_P(QuicWriteCodecTest, WriteSimpleAckFrame) {
|
||||
// There is 1 gap => each represented by 2 bytes => 2 bytes
|
||||
// 2 byte for first ack block length, then 2 bytes for the next len => 4 bytes
|
||||
// total 11 bytes
|
||||
auto ackFrameWriteResult = *writeAckFrame(
|
||||
auto ackFrameWriteResultExpected = writeAckFrame(
|
||||
ackFrameMetaData,
|
||||
pktBuilder,
|
||||
frameType,
|
||||
defaultAckReceiveTimestmpsConfig,
|
||||
kMaxReceivedPktsTimestampsStored,
|
||||
extendedAckSupport);
|
||||
ASSERT_FALSE(ackFrameWriteResultExpected.hasError());
|
||||
ASSERT_TRUE(ackFrameWriteResultExpected.value().has_value());
|
||||
auto& ackFrameWriteResult = ackFrameWriteResultExpected.value().value();
|
||||
auto addlBytesConsumed = computeBytesForOptionalAckFields(
|
||||
ackFrameMetaData, ackFrameWriteResult, frameType);
|
||||
EXPECT_EQ(11 + addlBytesConsumed, ackFrameWriteResult.bytesWritten);
|
||||
@ -1369,12 +1400,14 @@ TEST_P(QuicWriteCodecTest, WriteAckFrameWillSaveAckDelay) {
|
||||
.connTime = connTime,
|
||||
};
|
||||
|
||||
auto ackFrameWriteResult = *writeAckFrame(
|
||||
auto ackFrameWriteResult = writeAckFrame(
|
||||
ackFrameMetaData,
|
||||
pktBuilder,
|
||||
frameType,
|
||||
defaultAckReceiveTimestmpsConfig,
|
||||
kMaxReceivedPktsTimestampsStored);
|
||||
ASSERT_FALSE(ackFrameWriteResult.hasError());
|
||||
ASSERT_TRUE(ackFrameWriteResult.value().has_value());
|
||||
auto builtOut = std::move(pktBuilder).buildTestPacket();
|
||||
auto regularPacket = builtOut.first;
|
||||
WriteAckFrame& ackFrame = *regularPacket.frames.back().asWriteAckFrame();
|
||||
@ -1422,12 +1455,15 @@ TEST_P(QuicWriteCodecTest, VerifyNumAckBlocksSizeAccounted) {
|
||||
// There is 1 gap => each represented by 2 bytes => 2 bytes
|
||||
// 2 byte for first ack block length, then 2 bytes for the next len => 4 bytes
|
||||
// total 11 bytes
|
||||
auto ackFrameWriteResult = *writeAckFrame(
|
||||
auto ackFrameWriteResultExpected = writeAckFrame(
|
||||
ackFrameMetaData,
|
||||
pktBuilder,
|
||||
frameType,
|
||||
defaultAckReceiveTimestmpsConfig,
|
||||
kMaxReceivedPktsTimestampsStored);
|
||||
ASSERT_FALSE(ackFrameWriteResultExpected.hasError());
|
||||
ASSERT_TRUE(ackFrameWriteResultExpected.value().has_value());
|
||||
auto& ackFrameWriteResult = ackFrameWriteResultExpected.value().value();
|
||||
auto addlBytesConsumed = computeBytesForOptionalAckFields(
|
||||
ackFrameMetaData, ackFrameWriteResult, frameType);
|
||||
auto builtOut = std::move(pktBuilder).buildTestPacket();
|
||||
@ -1585,12 +1621,15 @@ TEST_P(QuicWriteCodecTest, OnlyAckLargestPacket) {
|
||||
.connTime = connTime,
|
||||
};
|
||||
|
||||
auto ackFrameWriteResult = *writeAckFrame(
|
||||
auto ackFrameWriteResultExpected = writeAckFrame(
|
||||
ackFrameMetaData,
|
||||
pktBuilder,
|
||||
frameType,
|
||||
defaultAckReceiveTimestmpsConfig,
|
||||
kMaxReceivedPktsTimestampsStored);
|
||||
ASSERT_FALSE(ackFrameWriteResultExpected.hasError());
|
||||
ASSERT_TRUE(ackFrameWriteResultExpected.value().has_value());
|
||||
auto& ackFrameWriteResult = ackFrameWriteResultExpected.value().value();
|
||||
auto addlBytesConsumed = computeBytesForOptionalAckFields(
|
||||
ackFrameMetaData, ackFrameWriteResult, frameType);
|
||||
|
||||
@ -1628,7 +1667,6 @@ TEST_P(QuicWriteCodecTest, OnlyAckLargestPacket) {
|
||||
assertsOnDecodedReceiveTimestamps(
|
||||
ackFrameMetaData,
|
||||
ackFrameWriteResult.writeAckFrame,
|
||||
|
||||
decodedAckFrame,
|
||||
1 /* timestamp ranges count */,
|
||||
1 /* timestamps count */,
|
||||
@ -1686,13 +1724,16 @@ TEST_P(QuicWriteCodecTest, WriteSomeAckBlocks) {
|
||||
.connTime = connTime,
|
||||
};
|
||||
|
||||
auto ackFrameWriteResult = *writeAckFrame(
|
||||
auto ackFrameWriteResultExpected = writeAckFrame(
|
||||
ackFrameMetaData,
|
||||
pktBuilder,
|
||||
frameType,
|
||||
defaultAckReceiveTimestmpsConfig,
|
||||
kMaxReceivedPktsTimestampsStored,
|
||||
extendedAckSupport);
|
||||
ASSERT_FALSE(ackFrameWriteResultExpected.hasError());
|
||||
ASSERT_TRUE(ackFrameWriteResultExpected.value().has_value());
|
||||
auto& ackFrameWriteResult = ackFrameWriteResultExpected.value().value();
|
||||
auto addlBytesConsumed = computeBytesForOptionalAckFields(
|
||||
ackFrameMetaData, ackFrameWriteResult, frameType);
|
||||
|
||||
@ -1730,7 +1771,6 @@ TEST_P(QuicWriteCodecTest, WriteSomeAckBlocks) {
|
||||
assertsOnDecodedReceiveTimestamps(
|
||||
ackFrameMetaData,
|
||||
ackFrameWriteResult.writeAckFrame,
|
||||
|
||||
decodedAckFrame,
|
||||
0 /* timestamp ranges count */,
|
||||
0 /* timestamps count */,
|
||||
@ -1765,7 +1805,8 @@ TEST_P(QuicWriteCodecTest, NoSpaceForAckBlockSection) {
|
||||
frameType,
|
||||
defaultAckReceiveTimestmpsConfig,
|
||||
kMaxReceivedPktsTimestampsStored);
|
||||
EXPECT_FALSE(ackFrameWriteResult.has_value());
|
||||
ASSERT_FALSE(ackFrameWriteResult.hasError());
|
||||
EXPECT_FALSE(ackFrameWriteResult.value().hasValue());
|
||||
}
|
||||
|
||||
TEST_P(QuicWriteCodecTest, OnlyHasSpaceForFirstAckBlock) {
|
||||
@ -1802,12 +1843,15 @@ TEST_P(QuicWriteCodecTest, OnlyHasSpaceForFirstAckBlock) {
|
||||
.connTime = connTime,
|
||||
};
|
||||
|
||||
auto ackFrameWriteResult = *writeAckFrame(
|
||||
auto ackFrameWriteResultExpected = writeAckFrame(
|
||||
ackFrameMetaData,
|
||||
pktBuilder,
|
||||
frameType,
|
||||
defaultAckReceiveTimestmpsConfig,
|
||||
kMaxReceivedPktsTimestampsStored);
|
||||
ASSERT_FALSE(ackFrameWriteResultExpected.hasError());
|
||||
ASSERT_TRUE(ackFrameWriteResultExpected.value().hasValue());
|
||||
auto& ackFrameWriteResult = ackFrameWriteResultExpected.value().value();
|
||||
auto addlBytesConsumed = computeBytesForOptionalAckFields(
|
||||
ackFrameMetaData, ackFrameWriteResult, frameType);
|
||||
|
||||
@ -1875,13 +1919,16 @@ TEST_P(QuicWriteCodecTest, WriteAckFrameWithMultipleTimestampRanges) {
|
||||
.connTime = connTime,
|
||||
};
|
||||
|
||||
auto ackFrameWriteResult = *writeAckFrame(
|
||||
auto ackFrameWriteResultExpected = writeAckFrame(
|
||||
ackFrameMetaData,
|
||||
pktBuilder,
|
||||
frameType,
|
||||
defaultAckReceiveTimestmpsConfig,
|
||||
50, /*maxRecvTimestampsToSend*/
|
||||
extendedAckSupport);
|
||||
ASSERT_FALSE(ackFrameWriteResultExpected.hasError());
|
||||
ASSERT_TRUE(ackFrameWriteResultExpected.value().hasValue());
|
||||
auto& ackFrameWriteResult = ackFrameWriteResultExpected.value().value();
|
||||
auto addlBytesConsumed = computeBytesForOptionalAckFields(
|
||||
ackFrameMetaData, ackFrameWriteResult, frameType);
|
||||
|
||||
@ -1969,13 +2016,16 @@ TEST_P(
|
||||
// - 3 bytes for the ECN counts (all 0 in this test)
|
||||
pktBuilder.remaining_ = 84;
|
||||
}
|
||||
auto ackFrameWriteResult = *writeAckFrame(
|
||||
auto ackFrameWriteResultExpected = writeAckFrame(
|
||||
ackFrameMetaData,
|
||||
pktBuilder,
|
||||
frameType,
|
||||
defaultAckReceiveTimestmpsConfig,
|
||||
100,
|
||||
extendedAckSupport);
|
||||
ASSERT_FALSE(ackFrameWriteResultExpected.hasError());
|
||||
ASSERT_TRUE(ackFrameWriteResultExpected.value().has_value());
|
||||
auto& ackFrameWriteResult = ackFrameWriteResultExpected.value().value();
|
||||
auto addlBytesConsumed = computeBytesForOptionalAckFields(
|
||||
ackFrameMetaData, ackFrameWriteResult, frameType);
|
||||
|
||||
@ -2045,7 +2095,9 @@ TEST_F(QuicWriteCodecTest, WriteMaxStreamData) {
|
||||
StreamId id = 1;
|
||||
uint64_t offset = 0x08;
|
||||
MaxStreamDataFrame maxStreamDataFrame(id, offset);
|
||||
auto bytesWritten = writeFrame(maxStreamDataFrame, pktBuilder);
|
||||
auto bytesWrittenExpected = writeFrame(maxStreamDataFrame, pktBuilder);
|
||||
ASSERT_FALSE(bytesWrittenExpected.hasError());
|
||||
auto bytesWritten = bytesWrittenExpected.value();
|
||||
|
||||
auto builtOut = std::move(pktBuilder).buildTestPacket();
|
||||
auto regularPacket = builtOut.first;
|
||||
@ -2072,14 +2124,17 @@ TEST_F(QuicWriteCodecTest, NoSpaceForMaxStreamData) {
|
||||
pktBuilder.remaining_ = 1;
|
||||
setupCommonExpects(pktBuilder);
|
||||
MaxStreamDataFrame maxStreamDataFrame(1, 0x08);
|
||||
EXPECT_EQ(0, writeFrame(maxStreamDataFrame, pktBuilder));
|
||||
ASSERT_FALSE(writeFrame(maxStreamDataFrame, pktBuilder).hasError());
|
||||
EXPECT_EQ(0, writeFrame(maxStreamDataFrame, pktBuilder).value());
|
||||
}
|
||||
|
||||
TEST_F(QuicWriteCodecTest, WriteMaxData) {
|
||||
MockQuicPacketBuilder pktBuilder;
|
||||
setupCommonExpects(pktBuilder);
|
||||
MaxDataFrame maxDataFrame(1000);
|
||||
auto bytesWritten = writeFrame(maxDataFrame, pktBuilder);
|
||||
auto bytesWrittenExpected = writeFrame(maxDataFrame, pktBuilder);
|
||||
ASSERT_FALSE(bytesWrittenExpected.hasError());
|
||||
auto bytesWritten = bytesWrittenExpected.value();
|
||||
|
||||
auto builtOut = std::move(pktBuilder).buildTestPacket();
|
||||
auto regularPacket = builtOut.first;
|
||||
@ -2101,7 +2156,8 @@ TEST_F(QuicWriteCodecTest, NoSpaceForMaxData) {
|
||||
pktBuilder.remaining_ = 0;
|
||||
setupCommonExpects(pktBuilder);
|
||||
MaxDataFrame maxDataFrame(1000);
|
||||
EXPECT_EQ(0, writeFrame(maxDataFrame, pktBuilder));
|
||||
ASSERT_FALSE(writeFrame(maxDataFrame, pktBuilder).hasError());
|
||||
EXPECT_EQ(0, writeFrame(maxDataFrame, pktBuilder).value());
|
||||
}
|
||||
|
||||
TEST_F(QuicWriteCodecTest, WriteMaxStreamId) {
|
||||
@ -2111,8 +2167,10 @@ TEST_F(QuicWriteCodecTest, WriteMaxStreamId) {
|
||||
uint64_t maxStream = i;
|
||||
bool isBidirectional = true;
|
||||
MaxStreamsFrame maxStreamsFrame(maxStream, isBidirectional);
|
||||
auto bytesWritten =
|
||||
auto bytesWrittenExpected =
|
||||
writeFrame(QuicSimpleFrame(maxStreamsFrame), pktBuilder);
|
||||
ASSERT_FALSE(bytesWrittenExpected.hasError());
|
||||
auto bytesWritten = bytesWrittenExpected.value();
|
||||
|
||||
auto builtOut = std::move(pktBuilder).buildTestPacket();
|
||||
auto regularPacket = builtOut.first;
|
||||
@ -2142,8 +2200,10 @@ TEST_F(QuicWriteCodecTest, WriteUniMaxStreamId) {
|
||||
uint64_t maxStream = i;
|
||||
bool isBidirectional = false;
|
||||
MaxStreamsFrame maxStreamsFrame(maxStream, isBidirectional);
|
||||
auto bytesWritten =
|
||||
auto bytesWrittenExpected =
|
||||
writeFrame(QuicSimpleFrame(maxStreamsFrame), pktBuilder);
|
||||
ASSERT_FALSE(bytesWrittenExpected.hasError());
|
||||
auto bytesWritten = bytesWrittenExpected.value();
|
||||
|
||||
auto builtOut = std::move(pktBuilder).buildTestPacket();
|
||||
auto regularPacket = builtOut.first;
|
||||
@ -2170,18 +2230,22 @@ TEST_F(QuicWriteCodecTest, NoSpaceForMaxStreamId) {
|
||||
pktBuilder.remaining_ = 0;
|
||||
setupCommonExpects(pktBuilder);
|
||||
StreamId maxStream = 0x1234;
|
||||
MaxStreamsFrame maxStreamIdFrame(maxStream, true);
|
||||
EXPECT_EQ(0, writeFrame(QuicSimpleFrame(maxStreamIdFrame), pktBuilder));
|
||||
auto result =
|
||||
writeFrame(QuicSimpleFrame(MaxStreamsFrame(maxStream, true)), pktBuilder);
|
||||
ASSERT_FALSE(result.hasError());
|
||||
EXPECT_EQ(0, result.value());
|
||||
}
|
||||
|
||||
TEST_F(QuicWriteCodecTest, WriteConnClose) {
|
||||
MockQuicPacketBuilder pktBuilder;
|
||||
setupCommonExpects(pktBuilder);
|
||||
std::string reasonPhrase("You are fired");
|
||||
ConnectionCloseFrame connectionCloseFrame(
|
||||
QuicErrorCode(TransportErrorCode::PROTOCOL_VIOLATION), reasonPhrase);
|
||||
auto connCloseBytesWritten =
|
||||
writeFrame(std::move(connectionCloseFrame), pktBuilder);
|
||||
auto connCloseBytesWrittenExpected = writeFrame(
|
||||
ConnectionCloseFrame(
|
||||
QuicErrorCode(TransportErrorCode::PROTOCOL_VIOLATION), reasonPhrase),
|
||||
pktBuilder);
|
||||
ASSERT_FALSE(connCloseBytesWrittenExpected.hasError());
|
||||
auto connCloseBytesWritten = connCloseBytesWrittenExpected.value();
|
||||
|
||||
auto builtOut = std::move(pktBuilder).buildTestPacket();
|
||||
auto regularPacket = builtOut.first;
|
||||
@ -2213,9 +2277,11 @@ TEST_F(QuicWriteCodecTest, DecodeConnCloseLarge) {
|
||||
setupCommonExpects(pktBuilder);
|
||||
std::string reasonPhrase;
|
||||
reasonPhrase.resize(kMaxReasonPhraseLength + 10);
|
||||
ConnectionCloseFrame connectionCloseFrame(
|
||||
QuicErrorCode(TransportErrorCode::PROTOCOL_VIOLATION), reasonPhrase);
|
||||
writeFrame(connectionCloseFrame, pktBuilder);
|
||||
auto result = writeFrame(
|
||||
ConnectionCloseFrame(
|
||||
QuicErrorCode(TransportErrorCode::PROTOCOL_VIOLATION), reasonPhrase),
|
||||
pktBuilder);
|
||||
ASSERT_FALSE(result.hasError());
|
||||
auto builtOut = std::move(pktBuilder).buildTestPacket();
|
||||
auto regularPacket = builtOut.first;
|
||||
auto& resultConnCloseFrame =
|
||||
@ -2236,9 +2302,12 @@ TEST_F(QuicWriteCodecTest, NoSpaceConnClose) {
|
||||
pktBuilder.remaining_ = 2;
|
||||
setupCommonExpects(pktBuilder);
|
||||
std::string reasonPhrase("You are all fired");
|
||||
ConnectionCloseFrame connCloseFrame(
|
||||
QuicErrorCode(TransportErrorCode::PROTOCOL_VIOLATION), reasonPhrase);
|
||||
EXPECT_EQ(0, writeFrame(std::move(connCloseFrame), pktBuilder));
|
||||
auto result = writeFrame(
|
||||
ConnectionCloseFrame(
|
||||
QuicErrorCode(TransportErrorCode::PROTOCOL_VIOLATION), reasonPhrase),
|
||||
pktBuilder);
|
||||
ASSERT_FALSE(result.hasError());
|
||||
EXPECT_EQ(0, result.value());
|
||||
}
|
||||
|
||||
TEST_F(QuicWriteCodecTest, DecodeAppCloseLarge) {
|
||||
@ -2250,7 +2319,8 @@ TEST_F(QuicWriteCodecTest, DecodeAppCloseLarge) {
|
||||
QuicErrorCode(GenericApplicationErrorCode::UNKNOWN),
|
||||
reasonPhrase,
|
||||
quic::FrameType::CONNECTION_CLOSE_APP_ERR);
|
||||
writeFrame(std::move(applicationCloseFrame), pktBuilder);
|
||||
auto result = writeFrame(std::move(applicationCloseFrame), pktBuilder);
|
||||
ASSERT_FALSE(result.hasError());
|
||||
|
||||
auto builtOut = std::move(pktBuilder).buildTestPacket();
|
||||
auto regularPacket = builtOut.first;
|
||||
@ -2269,7 +2339,9 @@ TEST_F(QuicWriteCodecTest, DecodeAppCloseLarge) {
|
||||
TEST_F(QuicWriteCodecTest, WritePing) {
|
||||
MockQuicPacketBuilder pktBuilder;
|
||||
setupCommonExpects(pktBuilder);
|
||||
auto pingBytesWritten = writeFrame(PingFrame(), pktBuilder);
|
||||
auto pingBytesWrittenExpected = writeFrame(PingFrame(), pktBuilder);
|
||||
ASSERT_FALSE(pingBytesWrittenExpected.hasError());
|
||||
auto pingBytesWritten = pingBytesWrittenExpected.value();
|
||||
|
||||
auto builtOut = std::move(pktBuilder).buildTestPacket();
|
||||
auto regularPacket = builtOut.first;
|
||||
@ -2292,13 +2364,17 @@ TEST_F(QuicWriteCodecTest, NoSpaceForPing) {
|
||||
MockQuicPacketBuilder pktBuilder;
|
||||
pktBuilder.remaining_ = 0;
|
||||
setupCommonExpects(pktBuilder);
|
||||
EXPECT_EQ(0, writeFrame(PingFrame(), pktBuilder));
|
||||
auto result = writeFrame(PingFrame(), pktBuilder);
|
||||
ASSERT_FALSE(result.hasError());
|
||||
EXPECT_EQ(0, result.value());
|
||||
}
|
||||
|
||||
TEST_F(QuicWriteCodecTest, WritePadding) {
|
||||
MockQuicPacketBuilder pktBuilder;
|
||||
setupCommonExpects(pktBuilder);
|
||||
auto paddingBytesWritten = writeFrame(PaddingFrame(), pktBuilder);
|
||||
auto paddingBytesWrittenExpected = writeFrame(PaddingFrame(), pktBuilder);
|
||||
ASSERT_FALSE(paddingBytesWrittenExpected.hasError());
|
||||
auto paddingBytesWritten = paddingBytesWrittenExpected.value();
|
||||
|
||||
auto builtOut = std::move(pktBuilder).buildTestPacket();
|
||||
auto regularPacket = builtOut.first;
|
||||
@ -2320,7 +2396,9 @@ TEST_F(QuicWriteCodecTest, NoSpaceForPadding) {
|
||||
pktBuilder.remaining_ = 0;
|
||||
setupCommonExpects(pktBuilder);
|
||||
PaddingFrame paddingFrame;
|
||||
EXPECT_EQ(0, writeFrame(paddingFrame, pktBuilder));
|
||||
auto result = writeFrame(paddingFrame, pktBuilder);
|
||||
ASSERT_FALSE(result.hasError());
|
||||
EXPECT_EQ(0, result.value());
|
||||
}
|
||||
|
||||
TEST_F(QuicWriteCodecTest, WriteStreamBlocked) {
|
||||
@ -2329,7 +2407,9 @@ TEST_F(QuicWriteCodecTest, WriteStreamBlocked) {
|
||||
StreamId blockedId = 0xF00D;
|
||||
uint64_t blockedOffset = 0x1111;
|
||||
StreamDataBlockedFrame blockedFrame(blockedId, blockedOffset);
|
||||
auto blockedBytesWritten = writeFrame(blockedFrame, pktBuilder);
|
||||
auto blockedBytesWrittenExpected = writeFrame(blockedFrame, pktBuilder);
|
||||
ASSERT_FALSE(blockedBytesWrittenExpected.hasError());
|
||||
auto blockedBytesWritten = blockedBytesWrittenExpected.value();
|
||||
|
||||
auto builtOut = std::move(pktBuilder).buildTestPacket();
|
||||
auto regularPacket = builtOut.first;
|
||||
@ -2354,7 +2434,9 @@ TEST_F(QuicWriteCodecTest, NoSpaceForBlockedStream) {
|
||||
StreamId blockedStream = 0x01;
|
||||
uint64_t blockedOffset = 0x1111;
|
||||
StreamDataBlockedFrame blockedFrame(blockedStream, blockedOffset);
|
||||
EXPECT_EQ(0, writeFrame(blockedFrame, pktBuilder));
|
||||
auto result = writeFrame(blockedFrame, pktBuilder);
|
||||
ASSERT_FALSE(result.hasError());
|
||||
EXPECT_EQ(0, result.value());
|
||||
}
|
||||
|
||||
TEST_F(QuicWriteCodecTest, WriteRstStream) {
|
||||
@ -2364,7 +2446,9 @@ TEST_F(QuicWriteCodecTest, WriteRstStream) {
|
||||
ApplicationErrorCode errorCode = GenericApplicationErrorCode::UNKNOWN;
|
||||
uint64_t offset = 0xF00D;
|
||||
RstStreamFrame rstStreamFrame(id, errorCode, offset);
|
||||
auto rstStreamBytesWritten = writeFrame(rstStreamFrame, pktBuilder);
|
||||
auto rstStreamBytesWrittenExpected = writeFrame(rstStreamFrame, pktBuilder);
|
||||
ASSERT_FALSE(rstStreamBytesWrittenExpected.hasError());
|
||||
auto rstStreamBytesWritten = rstStreamBytesWrittenExpected.value();
|
||||
|
||||
auto builtOut = std::move(pktBuilder).buildTestPacket();
|
||||
auto regularPacket = builtOut.first;
|
||||
@ -2394,7 +2478,9 @@ TEST_F(QuicWriteCodecTest, NoSpaceForRst) {
|
||||
ApplicationErrorCode errorCode = GenericApplicationErrorCode::UNKNOWN;
|
||||
uint64_t offset = 0xF00D;
|
||||
RstStreamFrame rstStreamFrame(id, errorCode, offset);
|
||||
EXPECT_EQ(0, writeFrame(rstStreamFrame, pktBuilder));
|
||||
auto result = writeFrame(rstStreamFrame, pktBuilder);
|
||||
ASSERT_FALSE(result.hasError());
|
||||
EXPECT_EQ(0, result.value());
|
||||
}
|
||||
|
||||
TEST_F(QuicWriteCodecTest, WriteRstStreamAt) {
|
||||
@ -2405,7 +2491,9 @@ TEST_F(QuicWriteCodecTest, WriteRstStreamAt) {
|
||||
uint64_t finalSize = 0xF00D;
|
||||
uint64_t reliableSize = 0xF00C;
|
||||
RstStreamFrame rstStreamFrame(id, errorCode, finalSize, reliableSize);
|
||||
auto rstStreamBytesWritten = writeFrame(rstStreamFrame, pktBuilder);
|
||||
auto rstStreamBytesWrittenExpected = writeFrame(rstStreamFrame, pktBuilder);
|
||||
ASSERT_FALSE(rstStreamBytesWrittenExpected.hasError());
|
||||
auto rstStreamBytesWritten = rstStreamBytesWrittenExpected.value();
|
||||
|
||||
auto builtOut = std::move(pktBuilder).buildTestPacket();
|
||||
auto regularPacket = builtOut.first;
|
||||
@ -2434,7 +2522,9 @@ TEST_F(QuicWriteCodecTest, WriteBlockedFrame) {
|
||||
setupCommonExpects(pktBuilder);
|
||||
uint64_t blockedOffset = 0x11111;
|
||||
DataBlockedFrame blockedFrame(blockedOffset);
|
||||
auto bytesWritten = writeFrame(blockedFrame, pktBuilder);
|
||||
auto bytesWrittenExpected = writeFrame(blockedFrame, pktBuilder);
|
||||
ASSERT_FALSE(bytesWrittenExpected.hasError());
|
||||
auto bytesWritten = bytesWrittenExpected.value();
|
||||
|
||||
auto builtOut = std::move(pktBuilder).buildTestPacket();
|
||||
auto regularPacket = builtOut.first;
|
||||
@ -2456,7 +2546,9 @@ TEST_F(QuicWriteCodecTest, NoSpaceForBlocked) {
|
||||
setupCommonExpects(pktBuilder);
|
||||
uint64_t blockedOffset = 0x11111;
|
||||
DataBlockedFrame blockedFrame(blockedOffset);
|
||||
EXPECT_EQ(0, writeFrame(blockedFrame, pktBuilder));
|
||||
auto result = writeFrame(blockedFrame, pktBuilder);
|
||||
ASSERT_FALSE(result.hasError());
|
||||
EXPECT_EQ(0, result.value());
|
||||
}
|
||||
|
||||
TEST_F(QuicWriteCodecTest, WriteStreamIdNeeded) {
|
||||
@ -2464,7 +2556,10 @@ TEST_F(QuicWriteCodecTest, WriteStreamIdNeeded) {
|
||||
setupCommonExpects(pktBuilder);
|
||||
StreamId blockedStreamId = 0x211;
|
||||
MaxStreamsFrame streamIdNeeded(blockedStreamId, true);
|
||||
auto bytesWritten = writeFrame(QuicSimpleFrame(streamIdNeeded), pktBuilder);
|
||||
auto bytesWrittenExpected =
|
||||
writeFrame(QuicSimpleFrame(streamIdNeeded), pktBuilder);
|
||||
ASSERT_FALSE(bytesWrittenExpected.hasError());
|
||||
auto bytesWritten = bytesWrittenExpected.value();
|
||||
|
||||
auto builtOut = std::move(pktBuilder).buildTestPacket();
|
||||
auto regularPacket = builtOut.first;
|
||||
@ -2489,7 +2584,9 @@ TEST_F(QuicWriteCodecTest, NoSpaceForStreamIdNeeded) {
|
||||
setupCommonExpects(pktBuilder);
|
||||
StreamId blockedStreamId = 0x211;
|
||||
MaxStreamsFrame streamIdNeeded(blockedStreamId, true);
|
||||
EXPECT_EQ(0, writeFrame(QuicSimpleFrame(streamIdNeeded), pktBuilder));
|
||||
auto result = writeFrame(QuicSimpleFrame(streamIdNeeded), pktBuilder);
|
||||
ASSERT_FALSE(result.hasError());
|
||||
EXPECT_EQ(0, result.value());
|
||||
}
|
||||
|
||||
TEST_F(QuicWriteCodecTest, WriteNewConnId) {
|
||||
@ -2498,7 +2595,10 @@ TEST_F(QuicWriteCodecTest, WriteNewConnId) {
|
||||
StatelessResetToken token;
|
||||
memset(token.data(), 'a', token.size());
|
||||
NewConnectionIdFrame newConnId(1, 0, getTestConnectionId(), token);
|
||||
auto bytesWritten = writeFrame(QuicSimpleFrame(newConnId), pktBuilder);
|
||||
auto bytesWrittenExpected =
|
||||
writeFrame(QuicSimpleFrame(newConnId), pktBuilder);
|
||||
ASSERT_FALSE(bytesWrittenExpected.hasError());
|
||||
auto bytesWritten = bytesWrittenExpected.value();
|
||||
|
||||
auto builtOut = std::move(pktBuilder).buildTestPacket();
|
||||
auto regularPacket = builtOut.first;
|
||||
@ -2528,10 +2628,11 @@ TEST_F(QuicWriteCodecTest, WriteRetireConnId) {
|
||||
setupCommonExpects(pktBuilder);
|
||||
RetireConnectionIdFrame retireConnId(3);
|
||||
auto bytesWritten = writeFrame(QuicSimpleFrame(retireConnId), pktBuilder);
|
||||
ASSERT_FALSE(bytesWritten.hasError());
|
||||
|
||||
auto builtOut = std::move(pktBuilder).buildTestPacket();
|
||||
auto regularPacket = builtOut.first;
|
||||
EXPECT_EQ(bytesWritten, 2);
|
||||
EXPECT_EQ(bytesWritten.value(), 2);
|
||||
RetireConnectionIdFrame resultRetireConnIdFrame =
|
||||
*regularPacket.frames[0].asQuicSimpleFrame()->asRetireConnectionIdFrame();
|
||||
EXPECT_EQ(resultRetireConnIdFrame.sequenceNumber, 3);
|
||||
@ -2555,10 +2656,11 @@ TEST_F(QuicWriteCodecTest, WriteStopSending) {
|
||||
|
||||
StopSendingFrame stopSending(streamId, errorCode);
|
||||
auto bytesWritten = writeSimpleFrame(stopSending, pktBuilder);
|
||||
ASSERT_FALSE(bytesWritten.hasError());
|
||||
|
||||
auto builtOut = std::move(pktBuilder).buildTestPacket();
|
||||
auto regularPacket = builtOut.first;
|
||||
EXPECT_EQ(bytesWritten, 10);
|
||||
EXPECT_EQ(bytesWritten.value(), 10);
|
||||
|
||||
auto wireBuf = std::move(builtOut.second);
|
||||
BufQueue queue;
|
||||
@ -2577,7 +2679,8 @@ TEST_F(QuicWriteCodecTest, NoSpaceForNewConnId) {
|
||||
setupCommonExpects(pktBuilder);
|
||||
NewConnectionIdFrame newConnId(
|
||||
1, 0, getTestConnectionId(), StatelessResetToken());
|
||||
EXPECT_EQ(0, writeFrame(QuicSimpleFrame(newConnId), pktBuilder));
|
||||
ASSERT_FALSE(writeFrame(QuicSimpleFrame(newConnId), pktBuilder).hasError());
|
||||
EXPECT_EQ(0, writeFrame(QuicSimpleFrame(newConnId), pktBuilder).value());
|
||||
}
|
||||
|
||||
TEST_F(QuicWriteCodecTest, WritePathChallenge) {
|
||||
@ -2587,7 +2690,8 @@ TEST_F(QuicWriteCodecTest, WritePathChallenge) {
|
||||
uint64_t pathData = 0x64;
|
||||
PathChallengeFrame pathChallenge(pathData);
|
||||
auto bytesWritten = writeSimpleFrame(pathChallenge, pktBuilder);
|
||||
EXPECT_EQ(bytesWritten, 9);
|
||||
ASSERT_FALSE(bytesWritten.hasError());
|
||||
EXPECT_EQ(bytesWritten.value(), 9);
|
||||
|
||||
auto builtOut = std::move(pktBuilder).buildTestPacket();
|
||||
|
||||
@ -2614,7 +2718,8 @@ TEST_F(QuicWriteCodecTest, WritePathResponse) {
|
||||
uint64_t pathData = 0x64;
|
||||
PathResponseFrame pathResponse(pathData);
|
||||
auto bytesWritten = writeSimpleFrame(pathResponse, pktBuilder);
|
||||
EXPECT_EQ(bytesWritten, 9);
|
||||
ASSERT_FALSE(bytesWritten.hasError());
|
||||
EXPECT_EQ(bytesWritten.value(), 9);
|
||||
|
||||
auto builtOut = std::move(pktBuilder).buildTestPacket();
|
||||
|
||||
@ -2700,7 +2805,10 @@ TEST_F(QuicWriteCodecTest, WriteAckFrequencyFrame) {
|
||||
frame.reorderThreshold = 50; // Length: 1
|
||||
|
||||
auto dataLen = writeSimpleFrame(frame, pktBuilder);
|
||||
ASSERT_EQ(dataLen, 10); // Based upon the values passed above + 2 (frame-type)
|
||||
ASSERT_FALSE(dataLen.hasError());
|
||||
ASSERT_EQ(
|
||||
dataLen.value(),
|
||||
10); // Based upon the values passed above + 2 (frame-type)
|
||||
|
||||
auto outputBuf = pktBuilder.data_->clone();
|
||||
EXPECT_EQ(outputBuf->computeChainDataLength(), 10);
|
||||
|
@ -21,7 +21,7 @@ std::pair<uint8_t, Buf> encodeShortHeader(const ShortHeader& header) {
|
||||
ShortHeader headerCopy = header;
|
||||
RegularQuicPacketBuilder builder(
|
||||
kDefaultUDPSendPacketLen, std::move(headerCopy), 0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
CHECK(!builder.encodePacketHeader().hasError());
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
Buf out;
|
||||
folly::io::Cursor cursor(&packet.header);
|
||||
@ -61,7 +61,7 @@ folly::Expected<ParsedLongHeaderResult, TransportErrorCode> makeLongHeader(
|
||||
packetType == LongHeader::Types::Retry ? std::move(headerRetry)
|
||||
: std::move(headerRegular),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
CHECK(!builder.encodePacketHeader().hasError());
|
||||
auto packet = packetToBuf(std::move(builder).buildPacket());
|
||||
folly::io::Cursor cursor(packet.get());
|
||||
uint8_t initialByte = cursor.readBE<uint8_t>();
|
||||
|
@ -132,7 +132,7 @@ RegularQuicPacketBuilder::Packet AckPacketBuilder::build() && {
|
||||
std::move(*header),
|
||||
getAckState(*CHECK_NOTNULL(dstConn), ackPnSpace)
|
||||
.largestAckScheduled.value_or(0));
|
||||
builder.encodePacketHeader();
|
||||
CHECK(!builder.encodePacketHeader().hasError());
|
||||
if (maybeAead) {
|
||||
builder.accountForCipherOverhead(maybeAead.value()->getCipherOverhead());
|
||||
}
|
||||
@ -145,7 +145,7 @@ RegularQuicPacketBuilder::Packet AckPacketBuilder::build() && {
|
||||
static_cast<uint8_t>(
|
||||
CHECK_NOTNULL(dstConn)->transportSettings.ackDelayExponent),
|
||||
TimePoint()};
|
||||
writeAckFrame(ackData, builder);
|
||||
CHECK(!writeAckFrame(ackData, builder).hasError());
|
||||
return std::move(builder).buildPacket();
|
||||
}
|
||||
|
||||
|
@ -305,7 +305,7 @@ RegularQuicPacketBuilder::Packet createStreamPacket(
|
||||
builder.reset(new RegularQuicPacketBuilder(
|
||||
packetSizeLimit, std::move(header), largestAcked));
|
||||
}
|
||||
builder->encodePacketHeader();
|
||||
CHECK(!builder->encodePacketHeader().hasError());
|
||||
builder->accountForCipherOverhead(cipherOverhead);
|
||||
auto res = *writeStreamFrameHeader(
|
||||
*builder,
|
||||
@ -353,7 +353,7 @@ RegularQuicPacketBuilder::Packet createInitialCryptoPacket(
|
||||
if (!builder) {
|
||||
builder = &fallbackBuilder;
|
||||
}
|
||||
builder->encodePacketHeader();
|
||||
CHECK(!builder->encodePacketHeader().hasError());
|
||||
builder->accountForCipherOverhead(aead.getCipherOverhead());
|
||||
auto res = writeCryptoFrame(offset, data, *builder);
|
||||
CHECK(res.hasValue()) << "failed to write crypto frame";
|
||||
@ -396,7 +396,7 @@ RegularQuicPacketBuilder::Packet createCryptoPacket(
|
||||
}
|
||||
RegularQuicPacketBuilder builder(
|
||||
packetSizeLimit, std::move(*header), largestAcked);
|
||||
builder.encodePacketHeader();
|
||||
CHECK(!builder.encodePacketHeader().hasError());
|
||||
builder.accountForCipherOverhead(aead.getCipherOverhead());
|
||||
auto res = writeCryptoFrame(offset, data, builder);
|
||||
CHECK(res.hasValue()) << "failed to write crypto frame";
|
||||
|
@ -38,7 +38,7 @@ bool PacketGroupWriter::writeSingleQuicPacket(
|
||||
std::move(shortHeader),
|
||||
largestAckedByPeer,
|
||||
0);
|
||||
builder.encodePacketHeader();
|
||||
CHECK(!builder.encodePacketHeader().hasError());
|
||||
builder.accountForCipherOverhead(aead.getCipherOverhead());
|
||||
// frontend has already limited the length to flow control, thus
|
||||
// flowControlLen == length
|
||||
|
@ -54,8 +54,8 @@ DSRStreamFrameScheduler::enrichAndAddSendInstruction(
|
||||
* same backend. Thus one SendInstruction can only have one stream. So this API
|
||||
* only write a single stream.
|
||||
*/
|
||||
DSRStreamFrameScheduler::SchedulingResult DSRStreamFrameScheduler::writeStream(
|
||||
DSRPacketBuilderBase& builder) {
|
||||
folly::Expected<DSRStreamFrameScheduler::SchedulingResult, QuicError>
|
||||
DSRStreamFrameScheduler::writeStream(DSRPacketBuilderBase& builder) {
|
||||
SchedulingResult result;
|
||||
auto& writeQueue = conn_.streamManager->writeQueue();
|
||||
const auto& levelIter = std::find_if(
|
||||
@ -78,7 +78,7 @@ DSRStreamFrameScheduler::SchedulingResult DSRStreamFrameScheduler::writeStream(
|
||||
CHECK(stream->hasSchedulableDsr());
|
||||
if (hasLossBufMeta) {
|
||||
SendInstruction::Builder instructionBuilder(conn_, streamId);
|
||||
auto encodedSize = writeDSRStreamFrame(
|
||||
auto encodedSizeExpected = writeDSRStreamFrame(
|
||||
builder,
|
||||
instructionBuilder,
|
||||
streamId,
|
||||
@ -88,6 +88,12 @@ DSRStreamFrameScheduler::SchedulingResult DSRStreamFrameScheduler::writeStream(
|
||||
.length, // flowControlLen shouldn't be used to limit loss write
|
||||
stream->lossBufMetas.front().eof,
|
||||
stream->currentWriteOffset + stream->pendingWrites.chainLength());
|
||||
|
||||
if (encodedSizeExpected.hasError()) {
|
||||
return folly::makeUnexpected(encodedSizeExpected.error());
|
||||
}
|
||||
|
||||
auto encodedSize = encodedSizeExpected.value();
|
||||
if (encodedSize > 0) {
|
||||
if (builder.remainingSpace() < encodedSize) {
|
||||
return result;
|
||||
@ -123,7 +129,7 @@ DSRStreamFrameScheduler::SchedulingResult DSRStreamFrameScheduler::writeStream(
|
||||
bool canWriteFin = stream->finalWriteOffset.has_value() &&
|
||||
stream->writeBufMeta.length <= flowControlLen;
|
||||
SendInstruction::Builder instructionBuilder(conn_, streamId);
|
||||
auto encodedSize = writeDSRStreamFrame(
|
||||
auto encodedSizeExpected = writeDSRStreamFrame(
|
||||
builder,
|
||||
instructionBuilder,
|
||||
streamId,
|
||||
@ -132,6 +138,12 @@ DSRStreamFrameScheduler::SchedulingResult DSRStreamFrameScheduler::writeStream(
|
||||
flowControlLen,
|
||||
canWriteFin,
|
||||
stream->currentWriteOffset + stream->pendingWrites.chainLength());
|
||||
|
||||
if (encodedSizeExpected.hasError()) {
|
||||
return folly::makeUnexpected(encodedSizeExpected.error());
|
||||
}
|
||||
|
||||
auto encodedSize = encodedSizeExpected.value();
|
||||
if (encodedSize > 0) {
|
||||
if (builder.remainingSpace() < encodedSize) {
|
||||
return result;
|
||||
|
@ -31,7 +31,8 @@ class DSRStreamFrameScheduler {
|
||||
};
|
||||
|
||||
// Write a single stream's data into builder.
|
||||
SchedulingResult writeStream(DSRPacketBuilderBase& builder);
|
||||
[[nodiscard]] folly::Expected<SchedulingResult, QuicError> writeStream(
|
||||
DSRPacketBuilderBase& builder);
|
||||
|
||||
private:
|
||||
void enrichInstruction(
|
||||
|
@ -9,7 +9,8 @@
|
||||
#include <quic/dsr/frontend/WriteCodec.h>
|
||||
|
||||
namespace quic {
|
||||
uint32_t writeDSRStreamFrame(
|
||||
|
||||
folly::Expected<uint32_t, QuicError> writeDSRStreamFrame(
|
||||
DSRPacketBuilderBase& packetBuilder,
|
||||
SendInstruction::Builder& instructionBuilder,
|
||||
StreamId id,
|
||||
@ -22,13 +23,17 @@ uint32_t writeDSRStreamFrame(
|
||||
return 0;
|
||||
}
|
||||
if (writeBufferLen == 0 && !fin) {
|
||||
throw QuicInternalException(
|
||||
"No data or fin supplied when writing stream.",
|
||||
LocalErrorCode::INTERNAL_ERROR);
|
||||
return folly::makeUnexpected(QuicError(
|
||||
TransportErrorCode::INTERNAL_ERROR,
|
||||
"No data or fin supplied when writing stream."));
|
||||
}
|
||||
|
||||
QuicInteger idInt(id);
|
||||
uint64_t headerSize = sizeof(uint8_t) + idInt.getSize();
|
||||
auto idIntSize = idInt.getSize();
|
||||
if (idIntSize.hasError()) {
|
||||
return folly::makeUnexpected(idIntSize.error());
|
||||
}
|
||||
uint64_t headerSize = sizeof(uint8_t) + idIntSize.value();
|
||||
if (packetBuilder.remainingSpace() < headerSize) {
|
||||
VLOG(4) << "No space in packet for stream header. stream=" << id
|
||||
<< " limit=" << packetBuilder.remainingSpace();
|
||||
@ -37,7 +42,11 @@ uint32_t writeDSRStreamFrame(
|
||||
|
||||
QuicInteger offsetInt(offset);
|
||||
if (offset != 0) {
|
||||
headerSize += offsetInt.getSize();
|
||||
auto offsetIntSize = offsetInt.getSize();
|
||||
if (offsetIntSize.hasError()) {
|
||||
return folly::makeUnexpected(offsetIntSize.error());
|
||||
}
|
||||
headerSize += offsetIntSize.value();
|
||||
}
|
||||
instructionBuilder.setStreamOffset(offset);
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include <quic/dsr/frontend/PacketBuilder.h>
|
||||
|
||||
namespace quic {
|
||||
uint32_t writeDSRStreamFrame(
|
||||
[[nodiscard]] folly::Expected<uint32_t, QuicError> writeDSRStreamFrame(
|
||||
DSRPacketBuilderBase& packetBuilder,
|
||||
SendInstruction::Builder& instructionBuilder,
|
||||
StreamId id,
|
||||
|
@ -50,7 +50,10 @@ folly::Expected<uint64_t, QuicError> writePacketizationRequest(
|
||||
getAckState(connection, PacketNumberSpace::AppData)
|
||||
.largestAckedByPeer.value_or(0));
|
||||
auto schedulerResult = scheduler.writeStream(packetBuilder);
|
||||
if (!schedulerResult.writeSuccess) {
|
||||
if (schedulerResult.hasError()) {
|
||||
return folly::makeUnexpected(schedulerResult.error());
|
||||
}
|
||||
if (!schedulerResult->writeSuccess) {
|
||||
/**
|
||||
* Scheduling can fail when we:
|
||||
* (1) run out of flow control
|
||||
@ -61,19 +64,19 @@ folly::Expected<uint64_t, QuicError> writePacketizationRequest(
|
||||
*
|
||||
* At least for (1) and (3), we should flush the sender.
|
||||
*/
|
||||
if (schedulerResult.sender) {
|
||||
senders.insert(schedulerResult.sender);
|
||||
if (schedulerResult->sender) {
|
||||
senders.insert(schedulerResult->sender);
|
||||
}
|
||||
return packetCounter;
|
||||
}
|
||||
CHECK(schedulerResult.sender);
|
||||
CHECK(schedulerResult->sender);
|
||||
auto packet = std::move(packetBuilder).buildPacket();
|
||||
// The contract is that if scheduler can schedule, builder has to be able to
|
||||
// build.
|
||||
CHECK_GT(packet.encodedSize, 0u);
|
||||
bool instructionAddError = false;
|
||||
for (const auto& instruction : packet.sendInstructions) {
|
||||
if (!schedulerResult.sender->addSendInstruction(instruction)) {
|
||||
if (!schedulerResult->sender->addSendInstruction(instruction)) {
|
||||
instructionAddError = true;
|
||||
break;
|
||||
}
|
||||
@ -101,12 +104,13 @@ folly::Expected<uint64_t, QuicError> writePacketizationRequest(
|
||||
|
||||
if (instructionAddError) {
|
||||
// TODO: Support empty write loop detection
|
||||
senders.insert(schedulerResult.sender);
|
||||
senders.insert(schedulerResult->sender);
|
||||
return packetCounter;
|
||||
}
|
||||
++packetCounter;
|
||||
senders.insert(schedulerResult.sender);
|
||||
senders.insert(schedulerResult->sender);
|
||||
}
|
||||
return packetCounter;
|
||||
}
|
||||
|
||||
} // namespace quic
|
||||
|
@ -52,7 +52,9 @@ TEST_F(SchedulerTest, ScheduleStream) {
|
||||
writtenLength = instruction.len;
|
||||
EXPECT_FALSE(instruction.fin);
|
||||
}));
|
||||
EXPECT_TRUE(scheduler.writeStream(builder_).writeSuccess);
|
||||
auto result = scheduler.writeStream(builder_);
|
||||
ASSERT_FALSE(result.hasError());
|
||||
EXPECT_TRUE(result.value().writeSuccess);
|
||||
|
||||
auto writtenMeta = stream->writeBufMeta.split(writtenLength);
|
||||
auto nextExpectedOffset = stream->writeBufMeta.offset;
|
||||
@ -79,7 +81,9 @@ TEST_F(SchedulerTest, ScheduleStream) {
|
||||
writtenLength = instruction.len;
|
||||
EXPECT_TRUE(instruction.fin);
|
||||
}));
|
||||
EXPECT_TRUE(scheduler.writeStream(builder_).writeSuccess);
|
||||
result = scheduler.writeStream(builder_);
|
||||
ASSERT_FALSE(result.hasError());
|
||||
EXPECT_TRUE(result.value().writeSuccess);
|
||||
|
||||
auto nextWrittenMeta = stream->writeBufMeta.split(writtenLength);
|
||||
EXPECT_EQ(stream->writeBufMeta.length, 0);
|
||||
|
@ -41,19 +41,19 @@ class WriteCodecTest : public DSRCommonTestFixture {
|
||||
TEST_F(WriteCodecTest, NoPacketSize) {
|
||||
packetSize_ = 0;
|
||||
auto instructionBuilder = createBuilder();
|
||||
EXPECT_EQ(
|
||||
0,
|
||||
writeDSRStreamFrame(
|
||||
builder_, instructionBuilder, 0, 0, 100, 100, true, 3));
|
||||
auto result = writeDSRStreamFrame(
|
||||
builder_, instructionBuilder, 0, 0, 100, 100, true, 3);
|
||||
ASSERT_FALSE(result.hasError());
|
||||
EXPECT_EQ(0, result.value());
|
||||
}
|
||||
|
||||
TEST_F(WriteCodecTest, TooSmallPacketSize) {
|
||||
packetSize_ = 1;
|
||||
auto instructionBuilder = createBuilder();
|
||||
EXPECT_EQ(
|
||||
0,
|
||||
writeDSRStreamFrame(
|
||||
builder_, instructionBuilder, 0, 0, 100, 100, true, 1));
|
||||
auto result = writeDSRStreamFrame(
|
||||
builder_, instructionBuilder, 0, 0, 100, 100, true, 1);
|
||||
ASSERT_FALSE(result.hasError());
|
||||
EXPECT_EQ(0, result.value());
|
||||
}
|
||||
|
||||
TEST_F(WriteCodecTest, RegularWrite) {
|
||||
@ -73,8 +73,9 @@ TEST_F(WriteCodecTest, RegularWrite) {
|
||||
flowControlLen,
|
||||
fin,
|
||||
bufMetaStartingOffset);
|
||||
ASSERT_FALSE(result.hasError());
|
||||
auto sendInstruction = instructionBuilder.build();
|
||||
EXPECT_GT(result, 0);
|
||||
EXPECT_GT(result.value(), 0);
|
||||
EXPECT_EQ(stream, sendInstruction.streamId);
|
||||
EXPECT_EQ(offset, sendInstruction.streamOffset);
|
||||
EXPECT_EQ(dataLen, sendInstruction.len);
|
||||
@ -99,8 +100,9 @@ TEST_F(WriteCodecTest, PacketSizeLimit) {
|
||||
flowControlLen,
|
||||
fin,
|
||||
bufMetaStartingOffset);
|
||||
ASSERT_FALSE(result.hasError());
|
||||
auto sendInstruction = instructionBuilder.build();
|
||||
EXPECT_GT(result, 0);
|
||||
EXPECT_GT(result.value(), 0);
|
||||
EXPECT_EQ(stream, sendInstruction.streamId);
|
||||
EXPECT_EQ(offset, sendInstruction.streamOffset);
|
||||
EXPECT_GT(dataLen, sendInstruction.len);
|
||||
@ -125,8 +127,9 @@ TEST_F(WriteCodecTest, FlowControlLimit) {
|
||||
flowControlLen,
|
||||
fin,
|
||||
bufMetaStartingOffset);
|
||||
ASSERT_FALSE(result.hasError());
|
||||
auto sendInstruction = instructionBuilder.build();
|
||||
EXPECT_GT(result, 0);
|
||||
EXPECT_GT(result.value(), 0);
|
||||
EXPECT_EQ(stream, sendInstruction.streamId);
|
||||
EXPECT_EQ(offset, sendInstruction.streamOffset);
|
||||
EXPECT_EQ(flowControlLen, sendInstruction.len);
|
||||
@ -152,7 +155,8 @@ TEST_F(WriteCodecTest, NoSpaceForData) {
|
||||
flowControlLen,
|
||||
fin,
|
||||
bufMetaStartingOffset);
|
||||
EXPECT_EQ(0, result);
|
||||
ASSERT_FALSE(result.hasError());
|
||||
EXPECT_EQ(0, result.value());
|
||||
}
|
||||
|
||||
TEST_F(WriteCodecTest, CanHaveOneByteData) {
|
||||
@ -173,8 +177,9 @@ TEST_F(WriteCodecTest, CanHaveOneByteData) {
|
||||
flowControlLen,
|
||||
fin,
|
||||
bufMetaStartingOffset);
|
||||
ASSERT_FALSE(result.hasError());
|
||||
auto sendInstruction = instructionBuilder.build();
|
||||
EXPECT_GT(result, 0);
|
||||
EXPECT_GT(result.value(), 0);
|
||||
EXPECT_EQ(stream, sendInstruction.streamId);
|
||||
EXPECT_EQ(offset, sendInstruction.streamOffset);
|
||||
EXPECT_EQ(1, sendInstruction.len);
|
||||
@ -191,17 +196,17 @@ TEST_F(WriteCodecTest, PacketSpaceEqStreamHeaderSize) {
|
||||
uint64_t bufMetaStartingOffset = 333;
|
||||
auto instructionBuilder = createBuilder();
|
||||
packetSize_ = 2;
|
||||
EXPECT_EQ(
|
||||
0,
|
||||
writeDSRStreamFrame(
|
||||
builder_,
|
||||
instructionBuilder,
|
||||
stream,
|
||||
offset,
|
||||
dataLen,
|
||||
flowControlLen,
|
||||
fin,
|
||||
bufMetaStartingOffset));
|
||||
auto result = writeDSRStreamFrame(
|
||||
builder_,
|
||||
instructionBuilder,
|
||||
stream,
|
||||
offset,
|
||||
dataLen,
|
||||
flowControlLen,
|
||||
fin,
|
||||
bufMetaStartingOffset);
|
||||
ASSERT_FALSE(result.hasError());
|
||||
EXPECT_EQ(0, result.value());
|
||||
}
|
||||
|
||||
TEST_F(WriteCodecTest, PacketSpaceEqStreamHeaderSizeWithFIN) {
|
||||
@ -222,8 +227,9 @@ TEST_F(WriteCodecTest, PacketSpaceEqStreamHeaderSizeWithFIN) {
|
||||
flowControlLen,
|
||||
fin,
|
||||
bufMetaStartingOffset);
|
||||
ASSERT_FALSE(result.hasError());
|
||||
auto sendInstruction = instructionBuilder.build();
|
||||
EXPECT_GT(result, 0);
|
||||
EXPECT_GT(result.value(), 0);
|
||||
EXPECT_EQ(stream, sendInstruction.streamId);
|
||||
EXPECT_EQ(offset, sendInstruction.streamOffset);
|
||||
EXPECT_EQ(0, sendInstruction.len);
|
||||
@ -248,8 +254,9 @@ TEST_F(WriteCodecTest, WriteFIN) {
|
||||
flowControlLen,
|
||||
fin,
|
||||
bufMetaStartingOffset);
|
||||
ASSERT_FALSE(result.hasError());
|
||||
auto sendInstruction = instructionBuilder.build();
|
||||
EXPECT_GT(result, 0);
|
||||
EXPECT_GT(result.value(), 0);
|
||||
EXPECT_EQ(stream, sendInstruction.streamId);
|
||||
EXPECT_EQ(offset, sendInstruction.streamOffset);
|
||||
EXPECT_EQ(10, sendInstruction.len);
|
||||
@ -274,8 +281,9 @@ TEST_F(WriteCodecTest, FINWithoutData) {
|
||||
flowControlLen,
|
||||
fin,
|
||||
bufMetaStartingOffset);
|
||||
ASSERT_FALSE(result.hasError());
|
||||
auto sendInstruction = instructionBuilder.build();
|
||||
EXPECT_GT(result, 0);
|
||||
EXPECT_GT(result.value(), 0);
|
||||
EXPECT_EQ(stream, sendInstruction.streamId);
|
||||
EXPECT_EQ(offset, sendInstruction.streamOffset);
|
||||
EXPECT_EQ(0, sendInstruction.len);
|
||||
@ -291,16 +299,15 @@ TEST_F(WriteCodecTest, NoFINNoData) {
|
||||
uint64_t flowControlLen = 10;
|
||||
uint64_t bufMetaStartingOffset = 333;
|
||||
auto instructionBuilder = createBuilder();
|
||||
EXPECT_THROW(
|
||||
writeDSRStreamFrame(
|
||||
builder_,
|
||||
instructionBuilder,
|
||||
stream,
|
||||
offset,
|
||||
dataLen,
|
||||
flowControlLen,
|
||||
fin,
|
||||
bufMetaStartingOffset),
|
||||
QuicInternalException);
|
||||
EXPECT_TRUE(writeDSRStreamFrame(
|
||||
builder_,
|
||||
instructionBuilder,
|
||||
stream,
|
||||
offset,
|
||||
dataLen,
|
||||
flowControlLen,
|
||||
fin,
|
||||
bufMetaStartingOffset)
|
||||
.hasError());
|
||||
}
|
||||
} // namespace quic::test
|
||||
|
@ -2629,12 +2629,13 @@ TEST_F(QuicClientTransportAfterStartTest, RecvNewConnectionIdValid) {
|
||||
ShortHeader header(ProtectionType::KeyPhaseZero, *conn.clientConnectionId, 1);
|
||||
RegularQuicPacketBuilder builder(
|
||||
conn.udpSendPacketLen, std::move(header), 0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
|
||||
auto token = StatelessResetToken{1, 9, 2, 0};
|
||||
NewConnectionIdFrame newConnId(1, 0, ConnectionId({2, 4, 2, 3}), token);
|
||||
writeSimpleFrame(QuicSimpleFrame(newConnId), builder);
|
||||
ASSERT_FALSE(
|
||||
writeSimpleFrame(QuicSimpleFrame(newConnId), builder).hasError());
|
||||
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
auto data = packetToBuf(packet);
|
||||
@ -2669,7 +2670,7 @@ TEST_F(QuicClientTransportAfterStartTest, ShortHeaderPacketWithNoFrames) {
|
||||
client->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
Buf buf = packetToBuf(std::move(builder).buildPacket());
|
||||
buf->coalesce();
|
||||
@ -2695,11 +2696,12 @@ TEST_F(
|
||||
ShortHeader header(ProtectionType::KeyPhaseZero, *conn.clientConnectionId, 1);
|
||||
RegularQuicPacketBuilder builder(
|
||||
conn.udpSendPacketLen, std::move(header), 0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
NewConnectionIdFrame newConnId(
|
||||
1, 0, ConnectionId({2, 4, 2, 3}), StatelessResetToken());
|
||||
writeSimpleFrame(QuicSimpleFrame(newConnId), builder);
|
||||
ASSERT_FALSE(
|
||||
writeSimpleFrame(QuicSimpleFrame(newConnId), builder).hasError());
|
||||
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
auto data = packetToBuf(packet);
|
||||
@ -2716,11 +2718,12 @@ TEST_F(QuicClientTransportAfterStartTest, RecvNewConnectionIdInvalidRetire) {
|
||||
ShortHeader header(ProtectionType::KeyPhaseZero, *conn.clientConnectionId, 1);
|
||||
RegularQuicPacketBuilder builder(
|
||||
conn.udpSendPacketLen, std::move(header), 0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
NewConnectionIdFrame newConnId(
|
||||
1, 3, ConnectionId({2, 4, 2, 3}), StatelessResetToken());
|
||||
writeSimpleFrame(QuicSimpleFrame(newConnId), builder);
|
||||
ASSERT_FALSE(
|
||||
writeSimpleFrame(QuicSimpleFrame(newConnId), builder).hasError());
|
||||
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
auto data = packetToBuf(packet);
|
||||
@ -2740,11 +2743,12 @@ TEST_F(QuicClientTransportAfterStartTest, RecvNewConnectionIdUsing0LenCid) {
|
||||
ShortHeader header(ProtectionType::KeyPhaseZero, *conn.clientConnectionId, 1);
|
||||
RegularQuicPacketBuilder builder(
|
||||
conn.udpSendPacketLen, std::move(header), 0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
NewConnectionIdFrame newConnId(
|
||||
1, 0, ConnectionId({2, 4, 2, 3}), StatelessResetToken());
|
||||
writeSimpleFrame(QuicSimpleFrame(newConnId), builder);
|
||||
ASSERT_FALSE(
|
||||
writeSimpleFrame(QuicSimpleFrame(newConnId), builder).hasError());
|
||||
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
auto data = packetToBuf(packet);
|
||||
@ -2771,10 +2775,11 @@ TEST_F(
|
||||
ShortHeader header(ProtectionType::KeyPhaseZero, *conn.clientConnectionId, 1);
|
||||
RegularQuicPacketBuilder builder(
|
||||
conn.udpSendPacketLen, std::move(header), 0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
NewConnectionIdFrame newConnId(1, 0, connId2, StatelessResetToken());
|
||||
writeSimpleFrame(QuicSimpleFrame(newConnId), builder);
|
||||
ASSERT_FALSE(
|
||||
writeSimpleFrame(QuicSimpleFrame(newConnId), builder).hasError());
|
||||
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
auto data = packetToBuf(packet);
|
||||
@ -2796,10 +2801,11 @@ TEST_F(
|
||||
ShortHeader header(ProtectionType::KeyPhaseZero, *conn.clientConnectionId, 1);
|
||||
RegularQuicPacketBuilder builder(
|
||||
conn.udpSendPacketLen, std::move(header), 0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
NewConnectionIdFrame newConnId(2, 0, connId2, StatelessResetToken());
|
||||
writeSimpleFrame(QuicSimpleFrame(newConnId), builder);
|
||||
ASSERT_FALSE(
|
||||
writeSimpleFrame(QuicSimpleFrame(newConnId), builder).hasError());
|
||||
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
auto data = packetToBuf(packet);
|
||||
@ -2925,10 +2931,11 @@ TEST_F(QuicClientTransportAfterStartTest, RecvPathChallengeNoAvailablePeerIds) {
|
||||
ShortHeader header(ProtectionType::KeyPhaseZero, *conn.clientConnectionId, 1);
|
||||
RegularQuicPacketBuilder builder(
|
||||
conn.udpSendPacketLen, std::move(header), 0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
PathChallengeFrame pathChallenge(123);
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
writeSimpleFrame(QuicSimpleFrame(pathChallenge), builder);
|
||||
ASSERT_FALSE(
|
||||
writeSimpleFrame(QuicSimpleFrame(pathChallenge), builder).hasError());
|
||||
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
auto data = packetToBuf(packet);
|
||||
@ -2952,10 +2959,11 @@ TEST_F(QuicClientTransportAfterStartTest, RecvPathChallengeAvailablePeerId) {
|
||||
ShortHeader header(ProtectionType::KeyPhaseZero, *conn.clientConnectionId, 1);
|
||||
RegularQuicPacketBuilder builder(
|
||||
conn.udpSendPacketLen, std::move(header), 0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
PathChallengeFrame pathChallenge(123);
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
writeSimpleFrame(QuicSimpleFrame(pathChallenge), builder);
|
||||
ASSERT_FALSE(
|
||||
writeSimpleFrame(QuicSimpleFrame(pathChallenge), builder).hasError());
|
||||
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
auto data = packetToBuf(packet);
|
||||
@ -3614,9 +3622,9 @@ TEST_F(
|
||||
client->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
writeFrame(rstFrame, builder);
|
||||
ASSERT_FALSE(writeFrame(rstFrame, builder).hasError());
|
||||
auto packet = packetToBuf(std::move(builder).buildPacket());
|
||||
EXPECT_THROW(deliverData(packet->coalesce()), std::runtime_error);
|
||||
}
|
||||
@ -3632,9 +3640,9 @@ TEST_F(QuicClientTransportAfterStartTest, ReceiveReliableRst) {
|
||||
client->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
writeFrame(rstFrame, builder);
|
||||
ASSERT_FALSE(writeFrame(rstFrame, builder).hasError());
|
||||
auto packet = packetToBuf(std::move(builder).buildPacket());
|
||||
deliverDataWithoutErrorCheck(packet->coalesce());
|
||||
EXPECT_EQ(
|
||||
@ -3656,8 +3664,8 @@ TEST_F(
|
||||
client->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
writeFrame(rstFrame, builder);
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ASSERT_FALSE(writeFrame(rstFrame, builder).hasError());
|
||||
auto packet = packetToBuf(std::move(builder).buildPacket());
|
||||
deliverData(packet->coalesce());
|
||||
|
||||
@ -3670,8 +3678,8 @@ TEST_F(
|
||||
client->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder2.encodePacketHeader();
|
||||
writeFrame(rstFrame, builder2);
|
||||
ASSERT_FALSE(builder2.encodePacketHeader().hasError());
|
||||
ASSERT_FALSE(writeFrame(rstFrame, builder2).hasError());
|
||||
|
||||
auto data = folly::IOBuf::copyBuffer("hello");
|
||||
writeStreamFrameHeader(
|
||||
@ -3724,9 +3732,9 @@ TEST_F(QuicClientTransportAfterStartTest, ReceiveRstStreamAfterEom) {
|
||||
ProtectionType::KeyPhaseZero, *originalConnId, appDataPacketNum++);
|
||||
RegularQuicPacketBuilder builder(
|
||||
client->getConn().udpSendPacketLen, std::move(header), 0);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
writeFrame(rstFrame, builder);
|
||||
ASSERT_FALSE(writeFrame(rstFrame, builder).hasError());
|
||||
auto packet2 = packetToBuf(std::move(builder).buildPacket());
|
||||
deliverData(packet2->coalesce());
|
||||
|
||||
@ -4171,15 +4179,14 @@ TEST_F(QuicClientTransportVersionAndRetryTest, UnencryptedAckData) {
|
||||
version);
|
||||
RegularQuicPacketBuilder builder(
|
||||
kDefaultUDPSendPacketLen, std::move(header), 0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
DCHECK(builder.canBuildPacket());
|
||||
// WriteAckFrameMetaData ackData(acks, 0us, 0);
|
||||
WriteAckFrameState writeAckState = {.acks = acks};
|
||||
WriteAckFrameMetaData ackData = {
|
||||
.ackState = writeAckState,
|
||||
.ackDelay = 0us,
|
||||
.ackDelayExponent = static_cast<uint8_t>(kDefaultAckDelayExponent)};
|
||||
writeAckFrame(ackData, builder);
|
||||
ASSERT_FALSE(writeAckFrame(ackData, builder).hasError());
|
||||
auto packet = packetToBufCleartext(
|
||||
std::move(builder).buildPacket(),
|
||||
getInitialCipher(),
|
||||
@ -4198,9 +4205,9 @@ TEST_F(QuicClientTransportVersionAndRetryTest, UnencryptedPing) {
|
||||
version);
|
||||
RegularQuicPacketBuilder builder(
|
||||
kDefaultUDPSendPacketLen, std::move(header), 0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
DCHECK(builder.canBuildPacket());
|
||||
writeFrame(PingFrame(), builder);
|
||||
ASSERT_FALSE(writeFrame(PingFrame(), builder).hasError());
|
||||
auto packet = packetToBufCleartext(
|
||||
std::move(builder).buildPacket(),
|
||||
getInitialCipher(),
|
||||
@ -4226,9 +4233,9 @@ Buf getHandshakePacketWithFrame(
|
||||
kDefaultUDPSendPacketLen,
|
||||
std::move(header),
|
||||
packetNum / 2 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
CHECK(!builder.encodePacketHeader().hasError());
|
||||
builder.accountForCipherOverhead(serverWriteCipher.getCipherOverhead());
|
||||
writeFrame(std::move(frame), builder);
|
||||
CHECK(!writeFrame(std::move(frame), builder).hasError());
|
||||
return packetToBufCleartext(
|
||||
std::move(builder).buildPacket(),
|
||||
serverWriteCipher,
|
||||
@ -4548,11 +4555,11 @@ TEST_F(QuicClientTransportAfterStartTest, ReceiveConnectionClose) {
|
||||
ProtectionType::KeyPhaseZero, *originalConnId, appDataPacketNum++);
|
||||
RegularQuicPacketBuilder builder(
|
||||
client->getConn().udpSendPacketLen, std::move(header), 0);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ConnectionCloseFrame connClose(
|
||||
QuicErrorCode(TransportErrorCode::NO_ERROR),
|
||||
"Stand clear of the closing doors, please");
|
||||
writeFrame(std::move(connClose), builder);
|
||||
ASSERT_FALSE(writeFrame(std::move(connClose), builder).hasError());
|
||||
auto packet = packetToBuf(std::move(builder).buildPacket());
|
||||
EXPECT_CALL(clientConnCallback, onConnectionEnd());
|
||||
deliverDataWithoutErrorCheck(packet->coalesce());
|
||||
@ -4575,11 +4582,11 @@ TEST_F(QuicClientTransportAfterStartTest, ReceiveApplicationClose) {
|
||||
ProtectionType::KeyPhaseZero, *originalConnId, appDataPacketNum++);
|
||||
RegularQuicPacketBuilder builder(
|
||||
client->getConn().udpSendPacketLen, std::move(header), 0);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ConnectionCloseFrame appClose(
|
||||
QuicErrorCode(GenericApplicationErrorCode::UNKNOWN),
|
||||
"Stand clear of the closing doors, please");
|
||||
writeFrame(std::move(appClose), builder);
|
||||
ASSERT_FALSE(writeFrame(std::move(appClose), builder).hasError());
|
||||
auto packet = packetToBuf(std::move(builder).buildPacket());
|
||||
EXPECT_FALSE(client->isClosed());
|
||||
socketWrites.clear();
|
||||
@ -4614,10 +4621,10 @@ TEST_F(QuicClientTransportAfterStartTest, ReceiveApplicationCloseNoError) {
|
||||
ProtectionType::KeyPhaseZero, *originalConnId, appDataPacketNum++);
|
||||
RegularQuicPacketBuilder builder(
|
||||
client->getConn().udpSendPacketLen, std::move(header), 0);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ConnectionCloseFrame appClose(
|
||||
QuicErrorCode(GenericApplicationErrorCode::NO_ERROR), "No Error");
|
||||
writeFrame(std::move(appClose), builder);
|
||||
ASSERT_FALSE(writeFrame(std::move(appClose), builder).hasError());
|
||||
auto packet = packetToBuf(std::move(builder).buildPacket());
|
||||
EXPECT_FALSE(client->isClosed());
|
||||
socketWrites.clear();
|
||||
@ -4799,8 +4806,8 @@ TEST_F(QuicClientTransportAfterStartTest, PingIsTreatedAsRetransmittable) {
|
||||
client->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
writeFrame(pingFrame, builder);
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ASSERT_FALSE(writeFrame(pingFrame, builder).hasError());
|
||||
auto packet = packetToBuf(std::move(builder).buildPacket());
|
||||
deliverData(packet->coalesce());
|
||||
EXPECT_TRUE(client->getConn().pendingEvents.scheduleAckTimeout);
|
||||
@ -4814,13 +4821,13 @@ TEST_F(QuicClientTransportAfterStartTest, ReceiveDatagramFrameAndDiscard) {
|
||||
client->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
|
||||
EXPECT_CALL(*quicStats_, onDatagramDroppedOnRead()).Times(1);
|
||||
StringPiece datagramPayload = "do not rely on me. I am unreliable";
|
||||
DatagramFrame datagramFrame(
|
||||
datagramPayload.size(), IOBuf::copyBuffer(datagramPayload));
|
||||
writeFrame(datagramFrame, builder);
|
||||
ASSERT_FALSE(writeFrame(datagramFrame, builder).hasError());
|
||||
auto packet = packetToBuf(std::move(builder).buildPacket());
|
||||
deliverData(packet->coalesce());
|
||||
ASSERT_EQ(client->getConn().datagramState.readBuffer.size(), 0);
|
||||
@ -4844,12 +4851,12 @@ TEST_F(QuicClientTransportAfterStartTest, ReceiveDatagramFrameAndStore) {
|
||||
client->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
|
||||
StringPiece datagramPayload = "do not rely on me. I am unreliable";
|
||||
DatagramFrame datagramFrame(
|
||||
datagramPayload.size(), IOBuf::copyBuffer(datagramPayload));
|
||||
writeFrame(datagramFrame, builder);
|
||||
ASSERT_FALSE(writeFrame(datagramFrame, builder).hasError());
|
||||
auto packet = packetToBuf(std::move(builder).buildPacket());
|
||||
deliverData(packet->coalesce());
|
||||
if (i < conn.datagramState.maxReadBufferSize) {
|
||||
@ -4877,11 +4884,11 @@ TEST_F(
|
||||
client->getConn().udpSendPacketLen,
|
||||
std::move(header1),
|
||||
0 /* largestAcked */);
|
||||
builder1.encodePacketHeader();
|
||||
ASSERT_FALSE(builder1.encodePacketHeader().hasError());
|
||||
StringPiece datagramPayload1 = "first";
|
||||
DatagramFrame datagramFrame1(
|
||||
datagramPayload1.size(), IOBuf::copyBuffer(datagramPayload1));
|
||||
writeFrame(datagramFrame1, builder1);
|
||||
ASSERT_FALSE(writeFrame(datagramFrame1, builder1).hasError());
|
||||
auto packet1 = packetToBuf(std::move(builder1).buildPacket());
|
||||
EXPECT_CALL(*quicStats_, onDatagramRead(_))
|
||||
.Times(1)
|
||||
@ -4897,11 +4904,11 @@ TEST_F(
|
||||
client->getConn().udpSendPacketLen,
|
||||
std::move(header2),
|
||||
0 /* largestAcked */);
|
||||
builder2.encodePacketHeader();
|
||||
ASSERT_FALSE(builder2.encodePacketHeader().hasError());
|
||||
StringPiece datagramPayload2 = "second";
|
||||
DatagramFrame datagramFrame2(
|
||||
datagramPayload2.size(), IOBuf::copyBuffer(datagramPayload2));
|
||||
writeFrame(datagramFrame2, builder2);
|
||||
ASSERT_FALSE(writeFrame(datagramFrame2, builder2).hasError());
|
||||
auto packet2 = packetToBuf(std::move(builder2).buildPacket());
|
||||
EXPECT_CALL(*quicStats_, onDatagramDroppedOnRead()).Times(1);
|
||||
EXPECT_CALL(*quicStats_, onDatagramRead(_))
|
||||
|
@ -241,7 +241,7 @@ PacketNum QuicLossFunctionsTest::sendPacket(
|
||||
conn.udpSendPacketLen,
|
||||
std::move(*header),
|
||||
getAckState(conn, packetNumberSpace).largestAckedByPeer.value_or(0));
|
||||
builder.encodePacketHeader();
|
||||
CHECK(!builder.encodePacketHeader().hasError());
|
||||
EXPECT_TRUE(builder.canBuildPacket());
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
if (forcedSize) {
|
||||
|
@ -984,9 +984,9 @@ TEST_F(QuicServerWorkerTest, BlockedSourcePort) {
|
||||
|
||||
RegularQuicPacketBuilder builder(
|
||||
kDefaultUDPSendPacketLen, std::move(header), 0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
while (builder.remainingSpaceInPkt() > 0) {
|
||||
writeFrame(PaddingFrame(), builder);
|
||||
ASSERT_FALSE(writeFrame(PaddingFrame(), builder).hasError());
|
||||
}
|
||||
auto packet = packetToReceivedUdpPacket(std::move(builder).buildPacket());
|
||||
worker_->handleNetworkData(blockedSrcPort, packet);
|
||||
@ -1003,9 +1003,9 @@ TEST_F(QuicServerWorkerTest, ZeroLengthConnectionId) {
|
||||
|
||||
RegularQuicPacketBuilder builder(
|
||||
kDefaultUDPSendPacketLen, std::move(header), 0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
while (builder.remainingSpaceInPkt() > 0) {
|
||||
writeFrame(PaddingFrame(), builder);
|
||||
ASSERT_FALSE(writeFrame(PaddingFrame(), builder).hasError());
|
||||
}
|
||||
auto packet = packetToReceivedUdpPacket(std::move(builder).buildPacket());
|
||||
worker_->handleNetworkData(kClientAddr, packet);
|
||||
@ -1021,7 +1021,7 @@ TEST_F(QuicServerWorkerTest, ClientInitialCounting) {
|
||||
LongHeader::Types::Initial, srcConnId, destConnId, num, version);
|
||||
RegularQuicPacketBuilder initialBuilder(
|
||||
kDefaultUDPSendPacketLen, std::move(initialHeader), 0);
|
||||
initialBuilder.encodePacketHeader();
|
||||
ASSERT_FALSE(initialBuilder.encodePacketHeader().hasError());
|
||||
auto initialPacket =
|
||||
packetToReceivedUdpPacket((std::move(initialBuilder).buildPacket()));
|
||||
EXPECT_CALL(*quicStats_, onClientInitialReceived(QuicVersion::MVFST))
|
||||
@ -1035,7 +1035,7 @@ TEST_F(QuicServerWorkerTest, ClientInitialCounting) {
|
||||
LongHeader::Types::Initial, srcConnId, destConnId, bignum, version);
|
||||
RegularQuicPacketBuilder initialBuilderBigNum(
|
||||
kDefaultUDPSendPacketLen, std::move(initialHeaderBigNum), 0);
|
||||
initialBuilderBigNum.encodePacketHeader();
|
||||
ASSERT_FALSE(initialBuilderBigNum.encodePacketHeader().hasError());
|
||||
auto initialPacketBigNum = packetToReceivedUdpPacket(
|
||||
(std::move(initialBuilderBigNum).buildPacket()));
|
||||
EXPECT_CALL(*quicStats_, onClientInitialReceived(QuicVersion::MVFST))
|
||||
@ -1047,7 +1047,7 @@ TEST_F(QuicServerWorkerTest, ClientInitialCounting) {
|
||||
LongHeader::Types::Handshake, srcConnId, destConnId, num, version);
|
||||
RegularQuicPacketBuilder handshakeBuilder(
|
||||
kDefaultUDPSendPacketLen, std::move(handshakeHeader), 0);
|
||||
handshakeBuilder.encodePacketHeader();
|
||||
ASSERT_FALSE(handshakeBuilder.encodePacketHeader().hasError());
|
||||
auto handshakePacket =
|
||||
packetToReceivedUdpPacket((std::move(handshakeBuilder).buildPacket()));
|
||||
EXPECT_CALL(*quicStats_, onClientInitialReceived(_)).Times(0);
|
||||
@ -1068,9 +1068,9 @@ TEST_F(QuicServerWorkerTest, ConnectionIdTooShort) {
|
||||
|
||||
RegularQuicPacketBuilder builder(
|
||||
kDefaultUDPSendPacketLen, std::move(header), 0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
while (builder.remainingSpaceInPkt() > 0) {
|
||||
writeFrame(PaddingFrame(), builder);
|
||||
ASSERT_FALSE(writeFrame(PaddingFrame(), builder).hasError());
|
||||
}
|
||||
auto packet = packetToReceivedUdpPacket((std::move(builder).buildPacket()));
|
||||
worker_->handleNetworkData(kClientAddr, packet);
|
||||
@ -1091,9 +1091,9 @@ TEST_F(QuicServerWorkerTest, FailToParseConnectionId) {
|
||||
LongHeader::Types::Initial, srcConnId, dstConnId, num, version);
|
||||
RegularQuicPacketBuilder builder(
|
||||
kDefaultUDPSendPacketLen, std::move(header), 0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
while (builder.remainingSpaceInPkt() > 0) {
|
||||
writeFrame(PaddingFrame(), builder);
|
||||
ASSERT_FALSE(writeFrame(PaddingFrame(), builder).hasError());
|
||||
}
|
||||
auto packet = packetToBuf(std::move(builder).buildPacket());
|
||||
// To force dropping path, set initial to false
|
||||
@ -1130,9 +1130,9 @@ TEST_F(QuicServerWorkerTest, ConnectionIdTooShortDispatch) {
|
||||
|
||||
RegularQuicPacketBuilder builder(
|
||||
kDefaultUDPSendPacketLen, std::move(header), 0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
while (builder.remainingSpaceInPkt() > 0) {
|
||||
writeFrame(PaddingFrame(), builder);
|
||||
ASSERT_FALSE(writeFrame(PaddingFrame(), builder).hasError());
|
||||
}
|
||||
auto packet = packetToBuf(std::move(builder).buildPacket());
|
||||
RoutingData routingData(HeaderForm::Long, true, false, dstConnId, srcConnId);
|
||||
@ -1158,9 +1158,9 @@ TEST_F(QuicServerWorkerTest, ConnectionIdTooLargeDispatch) {
|
||||
|
||||
RegularQuicPacketBuilder builder(
|
||||
kDefaultUDPSendPacketLen, std::move(header), 0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
while (builder.remainingSpaceInPkt() > 0) {
|
||||
writeFrame(PaddingFrame(), builder);
|
||||
ASSERT_FALSE(writeFrame(PaddingFrame(), builder).hasError());
|
||||
}
|
||||
auto packet = packetToBuf(std::move(builder).buildPacket());
|
||||
RoutingData routingData(HeaderForm::Long, true, false, dstConnId, srcConnId);
|
||||
@ -1201,7 +1201,7 @@ TEST_F(QuicServerWorkerTest, PacketAfterShutdown) {
|
||||
|
||||
RegularQuicPacketBuilder builder(
|
||||
kDefaultUDPSendPacketLen, std::move(header), 0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
auto packet = packetToReceivedUdpPacket((std::move(builder).buildPacket()));
|
||||
worker_->handleNetworkData(kClientAddr, packet);
|
||||
eventbase_.terminateLoopSoon();
|
||||
@ -1459,7 +1459,7 @@ auto createInitialStream(
|
||||
pktHeaderType == LongHeader::Types::Retry ? std::move(headerRetry)
|
||||
: std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
CHECK(!builder.encodePacketHeader().hasError());
|
||||
auto streamData = data.clone();
|
||||
auto res = writeStreamFrameHeader(
|
||||
builder,
|
||||
@ -1540,9 +1540,9 @@ class QuicServerWorkerRetryTest : public QuicServerWorkerTest {
|
||||
|
||||
RegularQuicPacketBuilder initialBuilder(
|
||||
kDefaultUDPSendPacketLen, std::move(initialHeader), 0);
|
||||
initialBuilder.encodePacketHeader();
|
||||
CHECK(!initialBuilder.encodePacketHeader().hasError());
|
||||
while (initialBuilder.remainingSpaceInPkt() > 0) {
|
||||
writeFrame(PaddingFrame(), initialBuilder);
|
||||
CHECK(!writeFrame(PaddingFrame(), initialBuilder).hasError());
|
||||
}
|
||||
auto initialPacket = packetToBuf(std::move(initialBuilder).buildPacket());
|
||||
RoutingData routingData(
|
||||
|
@ -81,7 +81,8 @@ TEST_F(QuicServerTransportTest, TestReadMultipleStreams) {
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
auto encodeResult = builder.encodePacketHeader();
|
||||
ASSERT_FALSE(encodeResult.hasError());
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
|
||||
auto buf1 = IOBuf::copyBuffer("Aloha");
|
||||
@ -437,13 +438,13 @@ TEST_F(QuicServerTransportTest, ReceivePacketAfterLocalError) {
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
|
||||
// Deliver a reset to non existent stream to trigger a local conn error
|
||||
StreamId streamId = 0x01;
|
||||
RstStreamFrame rstFrame(streamId, GenericApplicationErrorCode::UNKNOWN, 0);
|
||||
writeFrame(std::move(rstFrame), builder);
|
||||
ASSERT_FALSE(writeFrame(std::move(rstFrame), builder).hasError());
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
deliverDataWithoutErrorCheck(packetToBuf(packet));
|
||||
EXPECT_TRUE(verifyFramePresent(
|
||||
@ -460,9 +461,9 @@ TEST_F(QuicServerTransportTest, ReceivePacketAfterLocalError) {
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header2),
|
||||
0 /* largestAcked */);
|
||||
builder2.encodePacketHeader();
|
||||
ASSERT_FALSE(builder2.encodePacketHeader().hasError());
|
||||
RstStreamFrame rstFrame2(streamId, GenericApplicationErrorCode::UNKNOWN, 0);
|
||||
writeFrame(std::move(rstFrame2), builder2);
|
||||
ASSERT_FALSE(writeFrame(std::move(rstFrame2), builder2).hasError());
|
||||
auto packet2 = std::move(builder2).buildPacket();
|
||||
deliverDataWithoutErrorCheck(packetToBuf(packet2));
|
||||
EXPECT_TRUE(hasNotReceivedNewPacketsSinceLastCloseSent(server->getConn()));
|
||||
@ -484,13 +485,13 @@ TEST_F(QuicServerTransportTest, ReceiveCloseAfterLocalError) {
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
|
||||
// Deliver a reset to non existent stream to trigger a local conn error
|
||||
StreamId streamId = 0x01;
|
||||
RstStreamFrame rstFrame(streamId, GenericApplicationErrorCode::UNKNOWN, 0);
|
||||
writeFrame(std::move(rstFrame), builder);
|
||||
ASSERT_FALSE(writeFrame(std::move(rstFrame), builder).hasError());
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
deliverDataWithoutErrorCheck(packetToBuf(packet));
|
||||
EXPECT_TRUE(verifyFramePresent(
|
||||
@ -511,11 +512,11 @@ TEST_F(QuicServerTransportTest, ReceiveCloseAfterLocalError) {
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header2),
|
||||
0 /* largestAcked */);
|
||||
builder2.encodePacketHeader();
|
||||
ASSERT_FALSE(builder2.encodePacketHeader().hasError());
|
||||
std::string errMsg = "Mind the gap";
|
||||
ConnectionCloseFrame connClose(
|
||||
QuicErrorCode(TransportErrorCode::NO_ERROR), errMsg);
|
||||
writeFrame(std::move(connClose), builder2);
|
||||
ASSERT_FALSE(writeFrame(std::move(connClose), builder2).hasError());
|
||||
|
||||
auto packet2 = std::move(builder2).buildPacket();
|
||||
deliverDataWithoutErrorCheck(packetToBuf(packet2));
|
||||
@ -552,23 +553,24 @@ TEST_F(QuicServerTransportTest, NoDataExceptCloseProcessedAfterClosing) {
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
|
||||
auto buf = folly::IOBuf::copyBuffer("hello");
|
||||
writeStreamFrameHeader(
|
||||
builder,
|
||||
4,
|
||||
0,
|
||||
buf->computeChainDataLength(),
|
||||
buf->computeChainDataLength(),
|
||||
true,
|
||||
none /* skipLenHint */);
|
||||
ASSERT_FALSE(writeStreamFrameHeader(
|
||||
builder,
|
||||
4,
|
||||
0,
|
||||
buf->computeChainDataLength(),
|
||||
buf->computeChainDataLength(),
|
||||
true,
|
||||
none /* skipLenHint */)
|
||||
.hasError());
|
||||
writeStreamFrameData(builder, buf->clone(), buf->computeChainDataLength());
|
||||
std::string errMsg = "Mind the gap";
|
||||
ConnectionCloseFrame connClose(
|
||||
QuicErrorCode(TransportErrorCode::NO_ERROR), errMsg);
|
||||
writeFrame(std::move(connClose), builder);
|
||||
ASSERT_FALSE(writeFrame(std::move(connClose), builder).hasError());
|
||||
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
|
||||
@ -725,11 +727,11 @@ TEST_F(QuicServerTransportTest, RecvRstStreamFrameNonexistClientStream) {
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
|
||||
RstStreamFrame rstFrame(streamId, GenericApplicationErrorCode::UNKNOWN, 0);
|
||||
writeFrame(std::move(rstFrame), builder);
|
||||
ASSERT_FALSE(writeFrame(std::move(rstFrame), builder).hasError());
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
deliverData(packetToBuf(packet));
|
||||
|
||||
@ -754,8 +756,8 @@ TEST_F(QuicServerTransportTest, ReceiveRstStreamNonExistentAndOtherFrame) {
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
writeFrame(rstFrame, builder);
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ASSERT_FALSE(writeFrame(rstFrame, builder).hasError());
|
||||
auto packet = packetToBuf(std::move(builder).buildPacket());
|
||||
deliverData(std::move(packet));
|
||||
|
||||
@ -770,18 +772,19 @@ TEST_F(QuicServerTransportTest, ReceiveRstStreamNonExistentAndOtherFrame) {
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header2),
|
||||
0 /* largestAcked */);
|
||||
builder2.encodePacketHeader();
|
||||
writeFrame(rstFrame, builder2);
|
||||
ASSERT_FALSE(builder2.encodePacketHeader().hasError());
|
||||
ASSERT_FALSE(writeFrame(rstFrame, builder2).hasError());
|
||||
|
||||
auto data = folly::IOBuf::copyBuffer("hello");
|
||||
writeStreamFrameHeader(
|
||||
builder2,
|
||||
streamId,
|
||||
0,
|
||||
data->computeChainDataLength(),
|
||||
data->computeChainDataLength(),
|
||||
false,
|
||||
none /* skipLenHint */);
|
||||
ASSERT_FALSE(writeStreamFrameHeader(
|
||||
builder2,
|
||||
streamId,
|
||||
0,
|
||||
data->computeChainDataLength(),
|
||||
data->computeChainDataLength(),
|
||||
false,
|
||||
none /* skipLenHint */)
|
||||
.hasError());
|
||||
writeStreamFrameData(builder2, data->clone(), data->computeChainDataLength());
|
||||
auto packetObject = std::move(builder2).buildPacket();
|
||||
auto packet2 = packetToBuf(std::move(packetObject));
|
||||
@ -802,12 +805,12 @@ TEST_F(QuicServerTransportTest, RecvRstStreamFrameNonexistServerStream) {
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
|
||||
StreamId streamId = 0x01;
|
||||
RstStreamFrame rstFrame(streamId, GenericApplicationErrorCode::UNKNOWN, 0);
|
||||
writeFrame(std::move(rstFrame), builder);
|
||||
ASSERT_FALSE(writeFrame(std::move(rstFrame), builder).hasError());
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
EXPECT_THROW(deliverData(packetToBuf(packet)), std::runtime_error);
|
||||
}
|
||||
@ -851,14 +854,14 @@ TEST_F(QuicServerTransportTest, RecvRstStreamFrame) {
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
|
||||
RstStreamFrame rstFrame(
|
||||
streamId,
|
||||
GenericApplicationErrorCode::UNKNOWN,
|
||||
words.at(0).length() + words.at(1).length());
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
writeFrame(std::move(rstFrame), builder);
|
||||
ASSERT_FALSE(writeFrame(std::move(rstFrame), builder).hasError());
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
deliverData(packetToBuf(packet));
|
||||
|
||||
@ -892,11 +895,11 @@ TEST_F(QuicServerTransportTest, RecvReliableRstStreamFrame) {
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
|
||||
RstStreamFrame rstFrame(streamId, GenericApplicationErrorCode::UNKNOWN, 5, 5);
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
writeFrame(std::move(rstFrame), builder);
|
||||
ASSERT_FALSE(writeFrame(std::move(rstFrame), builder).hasError());
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
deliverDataWithoutErrorCheck(packetToBuf(packet));
|
||||
EXPECT_EQ(
|
||||
@ -940,11 +943,12 @@ TEST_F(QuicServerTransportTest, RecvStopSendingFrame) {
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
StopSendingFrame stopSendingFrame(
|
||||
streamId, GenericApplicationErrorCode::UNKNOWN);
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
writeFrame(QuicSimpleFrame(stopSendingFrame), builder);
|
||||
ASSERT_FALSE(
|
||||
writeFrame(QuicSimpleFrame(stopSendingFrame), builder).hasError());
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
EXPECT_CALL(
|
||||
connCallback,
|
||||
@ -989,12 +993,13 @@ TEST_F(QuicServerTransportTest, RecvStopSendingFrameAfterCloseStream) {
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
|
||||
StopSendingFrame stopSendingFrame(
|
||||
streamId, GenericApplicationErrorCode::UNKNOWN);
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
writeFrame(QuicSimpleFrame(stopSendingFrame), builder);
|
||||
ASSERT_FALSE(
|
||||
writeFrame(QuicSimpleFrame(stopSendingFrame), builder).hasError());
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
server->resetStream(streamId, GenericApplicationErrorCode::UNKNOWN);
|
||||
EXPECT_CALL(connCallback, onStopSending(_, _)).Times(0);
|
||||
@ -1038,11 +1043,11 @@ TEST_F(QuicServerTransportTest, RecvInvalidMaxStreamData) {
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
|
||||
MaxStreamDataFrame maxStreamDataFrame(streamId, 100);
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
writeFrame(std::move(maxStreamDataFrame), builder);
|
||||
ASSERT_FALSE(writeFrame(std::move(maxStreamDataFrame), builder).hasError());
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
EXPECT_THROW(deliverData(packetToBuf(packet)), std::runtime_error);
|
||||
}
|
||||
@ -1083,7 +1088,7 @@ TEST_F(QuicServerTransportTest, RecvStopSendingFrameAfterHalfCloseRemote) {
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
|
||||
StopSendingFrame stopSendingFrame(
|
||||
streamId, GenericApplicationErrorCode::UNKNOWN);
|
||||
@ -1100,7 +1105,8 @@ TEST_F(QuicServerTransportTest, RecvStopSendingFrameAfterHalfCloseRemote) {
|
||||
auto dataLen = *res;
|
||||
ASSERT_TRUE(dataLen.has_value());
|
||||
ASSERT_EQ(*dataLen, 0);
|
||||
writeFrame(QuicSimpleFrame(stopSendingFrame), builder);
|
||||
ASSERT_FALSE(
|
||||
writeFrame(QuicSimpleFrame(stopSendingFrame), builder).hasError());
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
EXPECT_CALL(
|
||||
connCallback,
|
||||
@ -1119,12 +1125,13 @@ TEST_F(QuicServerTransportTest, RecvStopSendingBeforeStream) {
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
|
||||
StopSendingFrame stopSendingFrame(
|
||||
streamId, GenericApplicationErrorCode::UNKNOWN);
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
writeFrame(QuicSimpleFrame(stopSendingFrame), builder);
|
||||
ASSERT_FALSE(
|
||||
writeFrame(QuicSimpleFrame(stopSendingFrame), builder).hasError());
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
EXPECT_CALL(connCallback, onNewBidirectionalStream(streamId));
|
||||
EXPECT_CALL(
|
||||
@ -1185,15 +1192,17 @@ TEST_F(QuicServerTransportTest, RecvStopSendingFrameAfterReset) {
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
|
||||
StopSendingFrame stopSendingFrame1(
|
||||
streamId1, GenericApplicationErrorCode::UNKNOWN);
|
||||
StopSendingFrame stopSendingFrame2(
|
||||
streamId2, GenericApplicationErrorCode::UNKNOWN);
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
writeFrame(QuicSimpleFrame(stopSendingFrame1), builder);
|
||||
writeFrame(QuicSimpleFrame(stopSendingFrame2), builder);
|
||||
ASSERT_FALSE(
|
||||
writeFrame(QuicSimpleFrame(stopSendingFrame1), builder).hasError());
|
||||
ASSERT_FALSE(
|
||||
writeFrame(QuicSimpleFrame(stopSendingFrame2), builder).hasError());
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
EXPECT_CALL(
|
||||
connCallback, onStopSending(_, GenericApplicationErrorCode::UNKNOWN))
|
||||
@ -1218,11 +1227,12 @@ TEST_F(QuicServerTransportTest, StopSendingLoss) {
|
||||
std::move(header),
|
||||
server->getConn().ackStates.appDataAckState.largestAckedByPeer.value_or(
|
||||
0));
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
StopSendingFrame stopSendingFrame(
|
||||
streamId, GenericApplicationErrorCode::UNKNOWN);
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
writeFrame(QuicSimpleFrame(stopSendingFrame), builder);
|
||||
ASSERT_FALSE(
|
||||
writeFrame(QuicSimpleFrame(stopSendingFrame), builder).hasError());
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
ASSERT_FALSE(markPacketLoss(server->getNonConstConn(), packet.packet, false)
|
||||
.hasError());
|
||||
@ -1249,11 +1259,12 @@ TEST_F(QuicServerTransportTest, StopSendingLossAfterStreamClosed) {
|
||||
std::move(header),
|
||||
server->getConn().ackStates.appDataAckState.largestAckedByPeer.value_or(
|
||||
0));
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
StopSendingFrame stopSendingFrame(
|
||||
streamId, GenericApplicationErrorCode::UNKNOWN);
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
writeFrame(QuicSimpleFrame(stopSendingFrame), builder);
|
||||
ASSERT_FALSE(
|
||||
writeFrame(QuicSimpleFrame(stopSendingFrame), builder).hasError());
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
|
||||
// clear out all the streams, this is not a great way to simulate closed
|
||||
@ -1338,10 +1349,11 @@ TEST_F(QuicServerTransportTest, RecvPathChallenge) {
|
||||
ProtectionType::KeyPhaseZero, *conn.serverConnectionId, 10);
|
||||
RegularQuicPacketBuilder builder(
|
||||
conn.udpSendPacketLen, std::move(header), 0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
PathChallengeFrame pathChallenge(123);
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
writeSimpleFrame(QuicSimpleFrame(pathChallenge), builder);
|
||||
ASSERT_FALSE(
|
||||
writeSimpleFrame(QuicSimpleFrame(pathChallenge), builder).hasError());
|
||||
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
|
||||
@ -1393,11 +1405,11 @@ TEST_F(QuicServerTransportTest, ReceiveConnectionClose) {
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
std::string errMsg = "Stand clear of the closing doors, please";
|
||||
ConnectionCloseFrame connClose(
|
||||
QuicErrorCode(TransportErrorCode::NO_ERROR), errMsg);
|
||||
writeFrame(std::move(connClose), builder);
|
||||
ASSERT_FALSE(writeFrame(std::move(connClose), builder).hasError());
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
EXPECT_CALL(connCallback, onConnectionEnd());
|
||||
deliverDataWithoutErrorCheck(packetToBuf(packet));
|
||||
@ -1438,11 +1450,11 @@ TEST_F(QuicServerTransportTest, ReceiveConnectionCloseBeforeDatagram) {
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
StringPiece datagramPayload = "do not rely on me. I am unreliable";
|
||||
DatagramFrame datagramFrame(
|
||||
datagramPayload.size(), IOBuf::copyBuffer(datagramPayload));
|
||||
writeFrame(datagramFrame, builder);
|
||||
ASSERT_FALSE(writeFrame(datagramFrame, builder).hasError());
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
|
||||
EXPECT_CALL(*quicStats_, onDatagramRead(_)).Times(1);
|
||||
@ -1467,11 +1479,11 @@ TEST_F(QuicServerTransportTest, ReceiveConnectionCloseBeforeDatagram) {
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
std::string errMsg = "Stand clear of the closing doors, please";
|
||||
ConnectionCloseFrame connClose(
|
||||
QuicErrorCode(TransportErrorCode::NO_ERROR), errMsg);
|
||||
writeFrame(std::move(connClose), builder);
|
||||
ASSERT_FALSE(writeFrame(std::move(connClose), builder).hasError());
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
|
||||
// Build late datagram.
|
||||
@ -1483,11 +1495,11 @@ TEST_F(QuicServerTransportTest, ReceiveConnectionCloseBeforeDatagram) {
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header2),
|
||||
0 /* largestAcked */);
|
||||
builder2.encodePacketHeader();
|
||||
ASSERT_FALSE(builder2.encodePacketHeader().hasError());
|
||||
StringPiece datagramPayload = "do not rely on me. I am unreliable";
|
||||
DatagramFrame datagramFrame(
|
||||
datagramPayload.size(), IOBuf::copyBuffer(datagramPayload));
|
||||
writeFrame(datagramFrame, builder2);
|
||||
ASSERT_FALSE(writeFrame(datagramFrame, builder2).hasError());
|
||||
auto packet2 = std::move(builder2).buildPacket();
|
||||
|
||||
// Deliver conn close followed by late datagram.
|
||||
@ -1528,12 +1540,12 @@ TEST_F(QuicServerTransportTest, ReceiveApplicationClose) {
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
|
||||
std::string errMsg = "Stand clear of the closing doors, please";
|
||||
ConnectionCloseFrame appClose(
|
||||
QuicErrorCode(GenericApplicationErrorCode::UNKNOWN), errMsg);
|
||||
writeFrame(std::move(appClose), builder);
|
||||
ASSERT_FALSE(writeFrame(std::move(appClose), builder).hasError());
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
|
||||
EXPECT_CALL(
|
||||
@ -1569,11 +1581,11 @@ TEST_F(QuicServerTransportTest, ReceiveConnectionCloseTwice) {
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
std::string errMsg = "Mind the gap";
|
||||
ConnectionCloseFrame connClose(
|
||||
QuicErrorCode(TransportErrorCode::NO_ERROR), errMsg);
|
||||
writeFrame(std::move(connClose), builder);
|
||||
ASSERT_FALSE(writeFrame(std::move(connClose), builder).hasError());
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
EXPECT_CALL(connCallback, onConnectionEnd());
|
||||
deliverDataWithoutErrorCheck(packetToBuf(packet));
|
||||
@ -1832,7 +1844,7 @@ TEST_F(QuicServerTransportTest, ShortHeaderPacketWithNoFrames) {
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
Buf buf = packetToBuf(std::move(builder).buildPacket());
|
||||
|
||||
@ -1883,7 +1895,7 @@ TEST_F(QuicServerTransportTest, ShortHeaderPacketWithNoFramesAfterClose) {
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
Buf buf = packetToBuf(std::move(builder).buildPacket());
|
||||
buf->coalesce();
|
||||
@ -1949,10 +1961,10 @@ TEST_P(
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
|
||||
writeSimpleFrame(PathChallengeFrame(123), builder);
|
||||
ASSERT_FALSE(writeSimpleFrame(PathChallengeFrame(123), builder).hasError());
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
auto packetData = packetToBuf(packet);
|
||||
folly::SocketAddress newPeer("100.101.102.103", 23456);
|
||||
@ -2084,12 +2096,14 @@ TEST_P(QuicServerTransportAllowMigrationTest, MigrateToUnvalidatedPeer) {
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
|
||||
writeSimpleFrame(
|
||||
PathResponseFrame(server->getConn().outstandingPathValidation->pathData),
|
||||
builder);
|
||||
ASSERT_FALSE(writeSimpleFrame(
|
||||
PathResponseFrame(
|
||||
server->getConn().outstandingPathValidation->pathData),
|
||||
builder)
|
||||
.hasError());
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
deliverData(packetToBuf(packet), false, &newPeer);
|
||||
EXPECT_FALSE(server->getConn().outstandingPathValidation);
|
||||
@ -2167,12 +2181,14 @@ TEST_P(QuicServerTransportAllowMigrationTest, ResetPathRttPathResponse) {
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
|
||||
writeSimpleFrame(
|
||||
PathResponseFrame(server->getConn().outstandingPathValidation->pathData),
|
||||
builder);
|
||||
ASSERT_FALSE(writeSimpleFrame(
|
||||
PathResponseFrame(
|
||||
server->getConn().outstandingPathValidation->pathData),
|
||||
builder)
|
||||
.hasError());
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
deliverData(packetToBuf(packet), false, &newPeer);
|
||||
EXPECT_FALSE(server->getConn().outstandingPathValidation);
|
||||
@ -2235,13 +2251,15 @@ TEST_P(QuicServerTransportAllowMigrationTest, IgnoreInvalidPathResponse) {
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
|
||||
writeSimpleFrame(
|
||||
PathResponseFrame(
|
||||
server->getConn().outstandingPathValidation->pathData ^ 1),
|
||||
builder);
|
||||
ASSERT_FALSE(
|
||||
writeSimpleFrame(
|
||||
PathResponseFrame(
|
||||
server->getConn().outstandingPathValidation->pathData ^ 1),
|
||||
builder)
|
||||
.hasError());
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
deliverData(packetToBuf(packet), false, &newPeer);
|
||||
EXPECT_TRUE(server->getConn().outstandingPathValidation);
|
||||
@ -2293,11 +2311,13 @@ TEST_P(
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
writeSimpleFrame(
|
||||
PathResponseFrame(server->getConn().outstandingPathValidation->pathData),
|
||||
builder);
|
||||
ASSERT_FALSE(writeSimpleFrame(
|
||||
PathResponseFrame(
|
||||
server->getConn().outstandingPathValidation->pathData),
|
||||
builder)
|
||||
.hasError());
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
folly::SocketAddress newPeer2("200.101.102.103", 23456);
|
||||
try {
|
||||
@ -2387,12 +2407,13 @@ TEST_P(QuicServerTransportAllowMigrationTest, RetiringConnIdIssuesNewIds) {
|
||||
ProtectionType::KeyPhaseZero, nextConnId, clientNextAppDataPacketNum++);
|
||||
RegularQuicPacketBuilder builder(
|
||||
conn.udpSendPacketLen, std::move(header), 0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
|
||||
// build packet containing a frame retiring the initial server conn id
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
RetireConnectionIdFrame retireConnIdFrame(initialServerConnId.sequenceNumber);
|
||||
writeSimpleFrame(QuicSimpleFrame(retireConnIdFrame), builder);
|
||||
ASSERT_FALSE(
|
||||
writeSimpleFrame(QuicSimpleFrame(retireConnIdFrame), builder).hasError());
|
||||
auto retireConnIdPacket = std::move(builder).buildPacket();
|
||||
|
||||
/**
|
||||
@ -2426,12 +2447,13 @@ TEST_P(QuicServerTransportAllowMigrationTest, RetiringInvalidConnId) {
|
||||
clientNextAppDataPacketNum++);
|
||||
RegularQuicPacketBuilder builder(
|
||||
conn.udpSendPacketLen, std::move(header), 0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
|
||||
// build packet containing a frame retiring an invalid conn id / seq no
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
RetireConnectionIdFrame retireConnIdFrame(conn.nextSelfConnectionIdSequence);
|
||||
writeSimpleFrame(QuicSimpleFrame(retireConnIdFrame), builder);
|
||||
ASSERT_FALSE(
|
||||
writeSimpleFrame(QuicSimpleFrame(retireConnIdFrame), builder).hasError());
|
||||
auto retireConnIdPacket = std::move(builder).buildPacket();
|
||||
|
||||
// retiring invalid conn id should not invoke onConnectionIdRetired()
|
||||
@ -2468,12 +2490,13 @@ TEST_P(QuicServerTransportAllowMigrationTest, RetireConnIdOfContainingPacket) {
|
||||
clientNextAppDataPacketNum++);
|
||||
RegularQuicPacketBuilder builder(
|
||||
conn.udpSendPacketLen, std::move(header), 0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
|
||||
// build packet containing a frame retiring conn id of containing packet
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
RetireConnectionIdFrame retireConnIdFrame(0);
|
||||
writeSimpleFrame(QuicSimpleFrame(retireConnIdFrame), builder);
|
||||
ASSERT_FALSE(
|
||||
writeSimpleFrame(QuicSimpleFrame(retireConnIdFrame), builder).hasError());
|
||||
auto retireConnIdPacket = std::move(builder).buildPacket();
|
||||
|
||||
// parsing packet should throw an error
|
||||
@ -2503,12 +2526,13 @@ TEST_P(
|
||||
clientNextAppDataPacketNum++);
|
||||
RegularQuicPacketBuilder builder(
|
||||
conn.udpSendPacketLen, std::move(header), 0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
|
||||
// build packet containing a RETIRE_CONNECTION_ID frame
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
RetireConnectionIdFrame retireConnIdFrame(0);
|
||||
writeSimpleFrame(QuicSimpleFrame(retireConnIdFrame), builder);
|
||||
ASSERT_FALSE(
|
||||
writeSimpleFrame(QuicSimpleFrame(retireConnIdFrame), builder).hasError());
|
||||
auto retireConnIdPacket = std::move(builder).buildPacket();
|
||||
|
||||
// parsing packet should throw an error
|
||||
@ -3127,8 +3151,8 @@ TEST_F(QuicServerTransportTest, PingIsTreatedAsRetransmittable) {
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
writeFrame(pingFrame, builder);
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ASSERT_FALSE(writeFrame(pingFrame, builder).hasError());
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
deliverData(packetToBuf(packet));
|
||||
EXPECT_TRUE(server->getConn().pendingEvents.scheduleAckTimeout);
|
||||
@ -3150,8 +3174,8 @@ TEST_F(QuicServerTransportTest, ImmediateAckValid) {
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
writeFrame(immediateAckFrame, builder);
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ASSERT_FALSE(writeFrame(immediateAckFrame, builder).hasError());
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
ASSERT_NO_THROW(deliverData(packetToBuf(packet)));
|
||||
// An ACK has been scheduled for AppData number space.
|
||||
@ -3179,8 +3203,8 @@ TEST_F(QuicServerTransportTest, ImmediateAckProtocolViolation) {
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
writeFrame(immediateAckFrame, builder);
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ASSERT_FALSE(writeFrame(immediateAckFrame, builder).hasError());
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
// This should throw a protocol violation error
|
||||
ASSERT_THROW(deliverData(packetToBuf(packet)), std::runtime_error);
|
||||
@ -3202,11 +3226,11 @@ TEST_F(QuicServerTransportTest, ReceiveDatagramFrameAndDiscard) {
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
StringPiece datagramPayload = "do not rely on me. I am unreliable";
|
||||
DatagramFrame datagramFrame(
|
||||
datagramPayload.size(), IOBuf::copyBuffer(datagramPayload));
|
||||
writeFrame(datagramFrame, builder);
|
||||
ASSERT_FALSE(writeFrame(datagramFrame, builder).hasError());
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
EXPECT_CALL(*quicStats_, onDatagramDroppedOnRead()).Times(1);
|
||||
deliverData(packetToBuf(packet));
|
||||
@ -3232,11 +3256,11 @@ TEST_F(QuicServerTransportTest, ReceiveDatagramFrameAndStore) {
|
||||
server->getConn().udpSendPacketLen,
|
||||
std::move(header),
|
||||
0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
StringPiece datagramPayload = "do not rely on me. I am unreliable";
|
||||
DatagramFrame datagramFrame(
|
||||
datagramPayload.size(), IOBuf::copyBuffer(datagramPayload));
|
||||
writeFrame(datagramFrame, builder);
|
||||
ASSERT_FALSE(writeFrame(datagramFrame, builder).hasError());
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
deliverData(packetToBuf(packet));
|
||||
if (i < conn.datagramState.maxReadBufferSize) {
|
||||
@ -3255,11 +3279,12 @@ TEST_F(QuicServerTransportTest, RecvNewConnectionIdValid) {
|
||||
ShortHeader header(ProtectionType::KeyPhaseZero, *conn.clientConnectionId, 1);
|
||||
RegularQuicPacketBuilder builder(
|
||||
conn.udpSendPacketLen, std::move(header), 0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
NewConnectionIdFrame newConnId(
|
||||
1, 0, ConnectionId({2, 4, 2, 3}), StatelessResetToken{9, 8, 7, 6});
|
||||
writeSimpleFrame(QuicSimpleFrame(newConnId), builder);
|
||||
ASSERT_FALSE(
|
||||
writeSimpleFrame(QuicSimpleFrame(newConnId), builder).hasError());
|
||||
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
|
||||
@ -3278,11 +3303,12 @@ TEST_F(QuicServerTransportTest, RecvNewConnectionIdTooManyReceivedIds) {
|
||||
ShortHeader header(ProtectionType::KeyPhaseZero, *conn.clientConnectionId, 1);
|
||||
RegularQuicPacketBuilder builder(
|
||||
conn.udpSendPacketLen, std::move(header), 0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
NewConnectionIdFrame newConnId(
|
||||
1, 0, ConnectionId({2, 4, 2, 3}), StatelessResetToken());
|
||||
writeSimpleFrame(QuicSimpleFrame(newConnId), builder);
|
||||
ASSERT_FALSE(
|
||||
writeSimpleFrame(QuicSimpleFrame(newConnId), builder).hasError());
|
||||
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
|
||||
@ -3298,11 +3324,12 @@ TEST_F(QuicServerTransportTest, RecvNewConnectionIdInvalidRetire) {
|
||||
ShortHeader header(ProtectionType::KeyPhaseZero, *conn.clientConnectionId, 1);
|
||||
RegularQuicPacketBuilder builder(
|
||||
conn.udpSendPacketLen, std::move(header), 0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
NewConnectionIdFrame newConnId(
|
||||
1, 3, ConnectionId({2, 4, 2, 3}), StatelessResetToken());
|
||||
writeSimpleFrame(QuicSimpleFrame(newConnId), builder);
|
||||
ASSERT_FALSE(
|
||||
writeSimpleFrame(QuicSimpleFrame(newConnId), builder).hasError());
|
||||
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
|
||||
@ -3320,10 +3347,11 @@ TEST_F(QuicServerTransportTest, RecvNewConnectionIdNoopValidDuplicate) {
|
||||
ShortHeader header(ProtectionType::KeyPhaseZero, *conn.clientConnectionId, 1);
|
||||
RegularQuicPacketBuilder builder(
|
||||
conn.udpSendPacketLen, std::move(header), 0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
NewConnectionIdFrame newConnId(1, 0, connId2, StatelessResetToken());
|
||||
writeSimpleFrame(QuicSimpleFrame(newConnId), builder);
|
||||
ASSERT_FALSE(
|
||||
writeSimpleFrame(QuicSimpleFrame(newConnId), builder).hasError());
|
||||
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
|
||||
@ -3341,10 +3369,11 @@ TEST_F(QuicServerTransportTest, RecvNewConnectionIdExceptionInvalidDuplicate) {
|
||||
ShortHeader header(ProtectionType::KeyPhaseZero, *conn.clientConnectionId, 1);
|
||||
RegularQuicPacketBuilder builder(
|
||||
conn.udpSendPacketLen, std::move(header), 0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
ASSERT_TRUE(builder.canBuildPacket());
|
||||
NewConnectionIdFrame newConnId(2, 0, connId2, StatelessResetToken());
|
||||
writeSimpleFrame(QuicSimpleFrame(newConnId), builder);
|
||||
ASSERT_FALSE(
|
||||
writeSimpleFrame(QuicSimpleFrame(newConnId), builder).hasError());
|
||||
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
|
||||
@ -3625,14 +3654,14 @@ TEST_F(QuicUnencryptedServerTransportTest, TestUnencryptedAck) {
|
||||
QuicVersion::MVFST);
|
||||
RegularQuicPacketBuilder builder(
|
||||
kDefaultUDPSendPacketLen, std::move(header), 0 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
DCHECK(builder.canBuildPacket());
|
||||
WriteAckFrameState writeAckState = {.acks = acks};
|
||||
WriteAckFrameMetaData ackData = {
|
||||
.ackState = writeAckState,
|
||||
.ackDelay = 0us,
|
||||
.ackDelayExponent = static_cast<uint8_t>(kDefaultAckDelayExponent)};
|
||||
writeAckFrame(ackData, builder);
|
||||
ASSERT_FALSE(writeAckFrame(ackData, builder).hasError());
|
||||
auto packet = packetToBufCleartext(
|
||||
std::move(builder).buildPacket(),
|
||||
*getInitialCipher(),
|
||||
@ -3837,7 +3866,8 @@ TEST_F(
|
||||
RegularQuicPacketBuilder builder(
|
||||
kDefaultUDPSendPacketLen, std::move(header), /*largestAckedPacketNum=*/0);
|
||||
RetireConnectionIdFrame retireConnIdFrame(0);
|
||||
writeSimpleFrame(QuicSimpleFrame(retireConnIdFrame), builder);
|
||||
ASSERT_FALSE(
|
||||
writeSimpleFrame(QuicSimpleFrame(retireConnIdFrame), builder).hasError());
|
||||
|
||||
// add some data
|
||||
auto data = IOBuf::copyBuffer("hello!");
|
||||
@ -3856,7 +3886,7 @@ TEST_F(
|
||||
data->clone(),
|
||||
std::min(folly::to<size_t>(dataLen), data->computeChainDataLength()));
|
||||
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
builder.accountForCipherOverhead(0);
|
||||
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
@ -3880,7 +3910,8 @@ TEST_F(
|
||||
server->getConn().supportedVersions[0]);
|
||||
RegularQuicPacketBuilder builder(
|
||||
kDefaultUDPSendPacketLen, std::move(header), /*largestAcked=*/0);
|
||||
writeSimpleFrame(PathResponseFrame(0xaabbccddeeff), builder);
|
||||
ASSERT_FALSE(
|
||||
writeSimpleFrame(PathResponseFrame(0xaabbccddeeff), builder).hasError());
|
||||
|
||||
// add some data
|
||||
auto data = IOBuf::copyBuffer("hello!");
|
||||
@ -3899,7 +3930,7 @@ TEST_F(
|
||||
data->clone(),
|
||||
std::min(folly::to<size_t>(dataLen), data->computeChainDataLength()));
|
||||
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
builder.accountForCipherOverhead(0);
|
||||
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
@ -3923,7 +3954,9 @@ TEST_F(
|
||||
server->getConn().supportedVersions[0]);
|
||||
RegularQuicPacketBuilder builder(
|
||||
kDefaultUDPSendPacketLen, std::move(header), /*largestAcked=*/0);
|
||||
writeSimpleFrame(NewTokenFrame(IOBuf::copyBuffer("token!")), builder);
|
||||
ASSERT_FALSE(
|
||||
writeSimpleFrame(NewTokenFrame(IOBuf::copyBuffer("token!")), builder)
|
||||
.hasError());
|
||||
|
||||
// add some data
|
||||
auto data = IOBuf::copyBuffer("hello!");
|
||||
@ -3942,7 +3975,7 @@ TEST_F(
|
||||
data->clone(),
|
||||
std::min(folly::to<size_t>(dataLen), data->computeChainDataLength()));
|
||||
|
||||
builder.encodePacketHeader();
|
||||
ASSERT_FALSE(builder.encodePacketHeader().hasError());
|
||||
builder.accountForCipherOverhead(0);
|
||||
|
||||
auto packet = std::move(builder).buildPacket();
|
||||
@ -4652,9 +4685,9 @@ Buf getHandshakePacketWithFrame(
|
||||
kDefaultUDPSendPacketLen,
|
||||
std::move(header),
|
||||
clientPacketNum / 2 /* largestAcked */);
|
||||
builder.encodePacketHeader();
|
||||
CHECK(!builder.encodePacketHeader().hasError());
|
||||
builder.accountForCipherOverhead(clientWriteCipher.getCipherOverhead());
|
||||
writeFrame(std::move(frame), builder);
|
||||
CHECK(!writeFrame(std::move(frame), builder).hasError());
|
||||
return packetToBufCleartext(
|
||||
std::move(builder).buildPacket(),
|
||||
clientWriteCipher,
|
||||
|
@ -4525,7 +4525,7 @@ class AckEventForAppDataTest : public Test {
|
||||
conn_->udpSendPacketLen,
|
||||
std::move(*header),
|
||||
getAckState(*conn_, pnSpace).largestAckedByPeer.value_or(0));
|
||||
builder.encodePacketHeader();
|
||||
CHECK(!builder.encodePacketHeader().hasError());
|
||||
DCHECK(builder.canBuildPacket());
|
||||
return std::move(builder).buildPacket();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user