diff --git a/quic/api/QuicTransportFunctions.cpp b/quic/api/QuicTransportFunctions.cpp index 34bf02720..8804d07fa 100644 --- a/quic/api/QuicTransportFunctions.cpp +++ b/quic/api/QuicTransportFunctions.cpp @@ -96,7 +96,8 @@ void handleNewStreamDataWritten( // Idealy we should also check this data doesn't exist in either retx buffer // or loss buffer, but that's an expensive search. stream.currentWriteOffset += frameLen; - auto bufWritten = stream.writeBuffer.split(folly::to(frameLen)); + auto bufWritten = stream.writeBuffer.splitAtMost(folly::to(frameLen)); + DCHECK_EQ(bufWritten->computeChainDataLength(), frameLen); stream.currentWriteOffset += frameFin ? 1 : 0; CHECK(stream.retransmissionBuffer .emplace( @@ -126,7 +127,7 @@ void handleRetransmissionWritten( stream.lossBuffer.erase(lossBufferIter); } else { lossBufferIter->offset += frameLen; - bufWritten = lossBufferIter->data.split(frameLen); + bufWritten = lossBufferIter->data.splitAtMost(frameLen); } CHECK(stream.retransmissionBuffer .emplace( diff --git a/quic/api/test/CMakeLists.txt b/quic/api/test/CMakeLists.txt index 5d0c5d488..855749f85 100644 --- a/quic/api/test/CMakeLists.txt +++ b/quic/api/test/CMakeLists.txt @@ -16,6 +16,7 @@ quic_add_test(TARGET QuicTransportTest QuicTransportTest.cpp DEPENDS Folly::folly + mvfst_bufutil mvfst_transport mvfst_server mvfst_state_stream_functions diff --git a/quic/api/test/QuicTransportTest.cpp b/quic/api/test/QuicTransportTest.cpp index 460d05bcd..a0a975570 100644 --- a/quic/api/test/QuicTransportTest.cpp +++ b/quic/api/test/QuicTransportTest.cpp @@ -11,11 +11,11 @@ #include #include -#include #include #include #include #include +#include #include #include #include @@ -307,7 +307,7 @@ void verifyCorrectness( EXPECT_EQ(finExpected, finSet); // Verify retransmissionBuffer: EXPECT_FALSE(stream->retransmissionBuffer.empty()); - IOBufQueue retxBufCombined; + BufQueue retxBufCombined; std::vector rtxCopy; for (auto& itr : stream->retransmissionBuffer) { rtxCopy.push_back(StreamBuffer( @@ -380,9 +380,6 @@ TEST_F(QuicTransportTest, NotAppLimitedWithLoss) { auto stream = transport_->createBidirectionalStream().value(); auto lossStream = transport_->createBidirectionalStream().value(); conn.streamManager->addLoss(lossStream); - conn.streamManager->getStream(lossStream) - ->lossBuffer.emplace_back( - IOBuf::copyBuffer("Mountains may depart"), 0, false); transport_->writeChain( stream, IOBuf::copyBuffer("An elephant sitting still"), diff --git a/quic/client/CMakeLists.txt b/quic/client/CMakeLists.txt index 10c1162a9..7e04ed605 100644 --- a/quic/client/CMakeLists.txt +++ b/quic/client/CMakeLists.txt @@ -26,6 +26,7 @@ target_compile_options( add_dependencies( mvfst_client + mvfst_bufutil mvfst_flowcontrol mvfst_happyeyeballs mvfst_loss diff --git a/quic/client/QuicClientTransport.cpp b/quic/client/QuicClientTransport.cpp index 97c7053fc..d44aef149 100644 --- a/quic/client/QuicClientTransport.cpp +++ b/quic/client/QuicClientTransport.cpp @@ -96,7 +96,7 @@ QuicClientTransport::~QuicClientTransport() { void QuicClientTransport::processUDPData( const folly::SocketAddress& peer, NetworkDataSingle&& networkData) { - folly::IOBufQueue udpData{folly::IOBufQueue::cacheChainLength()}; + BufQueue udpData; udpData.append(std::move(networkData.data)); if (!conn_->version) { @@ -129,7 +129,7 @@ void QuicClientTransport::processUDPData( void QuicClientTransport::processPacketData( const folly::SocketAddress& peer, TimePoint receiveTimePoint, - folly::IOBufQueue& packetQueue) { + BufQueue& packetQueue) { auto packetSize = packetQueue.chainLength(); if (packetSize == 0) { return; diff --git a/quic/client/QuicClientTransport.h b/quic/client/QuicClientTransport.h index 1d25897e6..46fad9ebc 100644 --- a/quic/client/QuicClientTransport.h +++ b/quic/client/QuicClientTransport.h @@ -15,6 +15,7 @@ #include #include #include +#include namespace quic { @@ -159,7 +160,7 @@ class QuicClientTransport void processPacketData( const folly::SocketAddress& peer, TimePoint receiveTimePoint, - folly::IOBufQueue& packetQueue); + BufQueue& packetQueue); void startCryptoHandshake(); diff --git a/quic/client/test/CMakeLists.txt b/quic/client/test/CMakeLists.txt index 9d3c4f0d5..141cebdda 100644 --- a/quic/client/test/CMakeLists.txt +++ b/quic/client/test/CMakeLists.txt @@ -13,6 +13,7 @@ quic_add_test(TARGET QuicClientTransportTest DEPENDS Folly::folly ${LIBGMOCK_LIBRARIES} + mvfst_bufutil mvfst_client mvfst_codec_types mvfst_handshake diff --git a/quic/client/test/QuicClientTransportTest.cpp b/quic/client/test/QuicClientTransportTest.cpp index 299a7e024..d5eb872e6 100644 --- a/quic/client/test/QuicClientTransportTest.cpp +++ b/quic/client/test/QuicClientTransportTest.cpp @@ -338,7 +338,7 @@ class QuicClientTransportIntegrationTest : public TestWithParam { class StreamData { public: - folly::IOBufQueue data{folly::IOBufQueue::cacheChainLength()}; + BufQueue data; folly::Promise promise; StreamId id; @@ -3115,7 +3115,7 @@ TEST_F(QuicClientTransportAfterStartTest, ReadStreamCoalescedMany) { auto expected = IOBuf::copyBuffer("hello"); EXPECT_CALL(readCb, readAvailable(streamId)).Times(0); FizzCryptoFactory cryptoFactory; - IOBufQueue packets{IOBufQueue::cacheChainLength()}; + BufQueue packets; for (int i = 0; i < kMaxNumCoalescedPackets; i++) { auto garbage = IOBuf::copyBuffer("garbage"); auto initialCipher = cryptoFactory.getServerInitialCipher( diff --git a/quic/codec/CMakeLists.txt b/quic/codec/CMakeLists.txt index 070ccaaa3..ffd9c194a 100644 --- a/quic/codec/CMakeLists.txt +++ b/quic/codec/CMakeLists.txt @@ -189,6 +189,7 @@ target_compile_options( add_dependencies( mvfst_codec + mvfst_bufutil mvfst_constants mvfst_codec_decode mvfst_codec_types diff --git a/quic/codec/Decode.cpp b/quic/codec/Decode.cpp index 11d15d90d..c5846eafc 100644 --- a/quic/codec/Decode.cpp +++ b/quic/codec/Decode.cpp @@ -337,7 +337,7 @@ ReadStreamFrame decodeStreamFrame( } // If dataLength > data's actual length then the cursor will throw. queue.trimStart(cursor - queue.front()); - data = queue.split(dataLength->first); + data = queue.splitAtMost(dataLength->first); } else { // Missing Data Length field doesn't mean no data. It means the rest of the // frame are all data. diff --git a/quic/codec/QuicPacketBuilder.h b/quic/codec/QuicPacketBuilder.h index df0b72a17..d84a60588 100644 --- a/quic/codec/QuicPacketBuilder.h +++ b/quic/codec/QuicPacketBuilder.h @@ -37,7 +37,7 @@ constexpr auto kLongHeaderHeaderSize = sizeof(uint8_t) /* Type bytes */ + constexpr auto kCipherOverheadHeuristic = 16; // TODO: i'm sure this isn't the optimal value: -// IOBufQueue growth byte size for in PacketBuilder: +// Appender growth byte size for in PacketBuilder: constexpr size_t kAppenderGrowthSize = 100; class PacketBuilderInterface { diff --git a/quic/codec/QuicReadCodec.cpp b/quic/codec/QuicReadCodec.cpp index a57e02a5f..a67a21cbc 100644 --- a/quic/codec/QuicReadCodec.cpp +++ b/quic/codec/QuicReadCodec.cpp @@ -23,7 +23,7 @@ namespace quic { QuicReadCodec::QuicReadCodec(QuicNodeType nodeType) : nodeType_(nodeType) {} folly::Optional -QuicReadCodec::tryParsingVersionNegotiation(folly::IOBufQueue& queue) { +QuicReadCodec::tryParsingVersionNegotiation(BufQueue& queue) { folly::io::Cursor cursor(queue.front()); if (!cursor.canAdvance(sizeof(uint8_t))) { return folly::none; @@ -47,7 +47,7 @@ QuicReadCodec::tryParsingVersionNegotiation(folly::IOBufQueue& queue) { } CodecResult QuicReadCodec::parseLongHeaderPacket( - folly::IOBufQueue& queue, + BufQueue& queue, const AckStates& ackStates) { folly::io::Cursor cursor(queue.front()); auto initialByte = cursor.readBE(); @@ -57,7 +57,7 @@ CodecResult QuicReadCodec::parseLongHeaderPacket( // We've failed to parse the long header, so we have no idea where this // packet ends. Clear the queue since no other data in this packet is // parse-able. - queue.clear(); + queue.move(); return CodecResult(Nothing()); } if (longHeaderInvariant->invariant.version == @@ -67,7 +67,7 @@ CodecResult QuicReadCodec::parseLongHeaderPacket( // function. // Since VN is not allowed to be coalesced with another packet // type, we clear out the buffer to avoid anyone else parsing it. - queue.clear(); + queue.move(); return CodecResult(Nothing()); } auto type = parseLongHeaderType(initialByte); @@ -79,7 +79,7 @@ CodecResult QuicReadCodec::parseLongHeaderPacket( // We've failed to parse the long header, so we have no idea where this // packet ends. Clear the queue since no other data in this packet is // parse-able. - queue.clear(); + queue.move(); return CodecResult(Nothing()); } // As soon as we have parsed out the long header we can split off any @@ -96,10 +96,10 @@ CodecResult QuicReadCodec::parseLongHeaderPacket( packetNumberOffset + parsedLongHeader->packetLength.packetLength; if (queue.chainLength() < currentPacketLen) { // Packet appears truncated, there's no parse-able data left. - queue.clear(); + queue.move(); return CodecResult(Nothing()); } - auto currentPacketData = queue.split(currentPacketLen); + auto currentPacketData = queue.splitAtMost(currentPacketLen); cursor.reset(currentPacketData.get()); cursor.skip(packetNumberOffset); // Sample starts after the max packet number size. This ensures that we @@ -108,7 +108,7 @@ CodecResult QuicReadCodec::parseLongHeaderPacket( VLOG(4) << "Dropping packet, not enough for packet number " << connIdToHex(); // Packet appears truncated, there's no parse-able data left. - queue.clear(); + queue.move(); return CodecResult(Nothing()); } cursor.skip(kMaxPacketNumEncodingSize); @@ -116,7 +116,7 @@ CodecResult QuicReadCodec::parseLongHeaderPacket( if (!cursor.canAdvance(sample.size())) { VLOG(4) << "Dropping packet, sample too small " << connIdToHex(); // Packet appears truncated, there's no parse-able data left. - queue.clear(); + queue.move(); return CodecResult(Nothing()); } cursor.pull(sample.data(), sample.size()); @@ -197,10 +197,10 @@ CodecResult QuicReadCodec::parseLongHeaderPacket( initialByteRange.data()[0], packetNumberByteRange, expectedNextPacketNum); longHeader.setPacketNumber(packetNum.first); - folly::IOBufQueue decryptQueue{folly::IOBufQueue::cacheChainLength()}; + BufQueue decryptQueue; decryptQueue.append(std::move(currentPacketData)); size_t aadLen = packetNumberOffset + packetNum.second; - auto headerData = decryptQueue.split(aadLen); + auto headerData = decryptQueue.splitAtMost(aadLen); // parsing verifies that packetLength >= packet number length. auto encryptedData = decryptQueue.splitAtMost( parsedLongHeader->packetLength.packetLength - packetNum.second); @@ -233,7 +233,7 @@ CodecResult QuicReadCodec::parseLongHeaderPacket( } CodecResult QuicReadCodec::parsePacket( - folly::IOBufQueue& queue, + BufQueue& queue, const AckStates& ackStates, size_t dstConnIdSize) { if (queue.empty()) { @@ -272,7 +272,7 @@ CodecResult QuicReadCodec::parsePacket( VLOG(10) << "Dropping packet, too small for sample " << connIdToHex(); // There's not enough space for the short header packet, clear the queue // to indicate there's no more parse-able data. - queue.clear(); + queue.move(); return CodecResult(Nothing()); } // Take it out of the queue so we can do some writing. diff --git a/quic/codec/QuicReadCodec.h b/quic/codec/QuicReadCodec.h index f2cf74120..cee458443 100644 --- a/quic/codec/QuicReadCodec.h +++ b/quic/codec/QuicReadCodec.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -94,7 +95,7 @@ class QuicReadCodec { * before the version is negotiated to detect VN. */ virtual CodecResult parsePacket( - folly::IOBufQueue& queue, + BufQueue& queue, const AckStates& ackStates, size_t dstConnIdSize = kDefaultConnectionIdSize); @@ -105,7 +106,7 @@ class QuicReadCodec { * a VN packet or is invalid. */ folly::Optional tryParsingVersionNegotiation( - folly::IOBufQueue& queue); + BufQueue& queue); const Aead* getOneRttReadCipher() const; const Aead* getZeroRttReadCipher() const; @@ -151,7 +152,7 @@ class QuicReadCodec { private: CodecResult parseLongHeaderPacket( - folly::IOBufQueue& queue, + BufQueue& queue, const AckStates& ackStates); std::string connIdToHex(); diff --git a/quic/codec/test/CMakeLists.txt b/quic/codec/test/CMakeLists.txt index 1dc902ff4..65d2173cb 100644 --- a/quic/codec/test/CMakeLists.txt +++ b/quic/codec/test/CMakeLists.txt @@ -32,6 +32,7 @@ quic_add_test(TARGET QuicWriteCodecTest QuicWriteCodecTest.cpp DEPENDS Folly::folly + mvfst_bufutil mvfst_codec mvfst_codec_decode mvfst_codec_types diff --git a/quic/codec/test/QuicReadCodecTest.cpp b/quic/codec/test/QuicReadCodecTest.cpp index 25e3e9375..0b99edfaa 100644 --- a/quic/codec/test/QuicReadCodecTest.cpp +++ b/quic/codec/test/QuicReadCodecTest.cpp @@ -124,6 +124,37 @@ TEST_F(QuicReadCodecTest, RetryPacketTest) { EXPECT_EQ(headerOut.getToken(), expected); } +TEST_F(QuicReadCodecTest, LongHeaderPacketLenMismatch) { + LongHeader headerIn( + LongHeader::Types::Initial, + getTestConnectionId(70), + getTestConnectionId(90), + 321, + QuicVersion::MVFST, + std::string("fluffydog"), + getTestConnectionId(110)); + + RegularQuicPacketBuilder builder( + kDefaultUDPSendPacketLen, std::move(headerIn), 0 /* largestAcked */); + builder.setCipherOverhead(0); + writeCryptoFrame(0, folly::IOBuf::copyBuffer("CHLO"), builder); + auto packet = packetToBuf(std::move(builder).buildPacket()); + auto packetQueue = bufToQueue(std::move(packet)); + + auto tmp = packetQueue.move(); + tmp->coalesce(); + tmp->trimEnd(1); + packetQueue.append(std::move(tmp)); + + AckStates ackStates; + auto codec = makeUnencryptedCodec(); + codec->setInitialReadCipher(createNoOpAead()); + codec->setInitialHeaderCipher(test::createNoOpHeaderCipher()); + auto result = codec->parsePacket(packetQueue, ackStates); + auto nothing = result.nothing(); + EXPECT_NE(nothing, nullptr); +} + TEST_F(QuicReadCodecTest, EmptyVersionNegotiationPacketTest) { auto srcConnId = getTestConnectionId(0), destConnId = getTestConnectionId(1); std::vector versions; diff --git a/quic/codec/test/QuicWriteCodecTest.cpp b/quic/codec/test/QuicWriteCodecTest.cpp index 854d116c8..017dd2cb6 100644 --- a/quic/codec/test/QuicWriteCodecTest.cpp +++ b/quic/codec/test/QuicWriteCodecTest.cpp @@ -9,13 +9,13 @@ #include #include #include -#include #include #include #include #include #include #include +#include #include using namespace quic; diff --git a/quic/common/BufUtil.cpp b/quic/common/BufUtil.cpp index 6673f9394..0eb1e9761 100644 --- a/quic/common/BufUtil.cpp +++ b/quic/common/BufUtil.cpp @@ -4,13 +4,10 @@ namespace quic { -Buf BufQueue::split(size_t len) { +Buf BufQueue::splitAtMost(size_t len) { Buf result; folly::IOBuf* current = chain_.get(); - if (current == nullptr && len > 0) { - throw std::underflow_error( - "Attempt to remove more bytes than are present in BufQueue"); - } else if (current == nullptr) { + if (current == nullptr) { DCHECK_EQ(chainLength_, 0); return folly::IOBuf::create(0); } @@ -43,12 +40,16 @@ Buf BufQueue::split(size_t len) { } current = current->next(); if (current == chain_.get()) { - throw std::underflow_error( - "Attempt to remove more bytes than are present in BufQueue"); + break; } } - chainLength_ -= len; - DCHECK(chainLength_ == 0 || chain_); + if (remaining > 0) { + // We did not find all the data we needed, so we are going to consume the + // entire chain instead. + result = std::move(chain_); + } + chainLength_ -= (len - remaining); + DCHECK_EQ(chainLength_, chain_ ? chain_->computeChainDataLength() : 0); if (UNLIKELY(result == nullptr)) { return folly::IOBuf::create(0); } diff --git a/quic/common/BufUtil.h b/quic/common/BufUtil.h index a40c982db..a14fc7a82 100644 --- a/quic/common/BufUtil.h +++ b/quic/common/BufUtil.h @@ -50,7 +50,7 @@ class BufQueue { return chain_.get(); } - Buf split(size_t n); + Buf splitAtMost(size_t n); size_t trimStartAtMost(size_t amount); diff --git a/quic/common/test/BufUtilTest.cpp b/quic/common/test/BufUtilTest.cpp index 7932a1ba9..e0772c5e9 100644 --- a/quic/common/test/BufUtilTest.cpp +++ b/quic/common/test/BufUtilTest.cpp @@ -78,55 +78,59 @@ TEST(BufQueue, Split) { checkConsistency(queue); EXPECT_EQ(12, queue.front()->computeChainDataLength()); - unique_ptr prefix(queue.split(1)); + unique_ptr prefix(queue.splitAtMost(1)); checkConsistency(queue); EXPECT_EQ(1, prefix->computeChainDataLength()); EXPECT_EQ(11, queue.front()->computeChainDataLength()); - prefix = queue.split(2); + prefix = queue.splitAtMost(2); checkConsistency(queue); EXPECT_EQ(2, prefix->computeChainDataLength()); EXPECT_EQ(9, queue.front()->computeChainDataLength()); - prefix = queue.split(3); + prefix = queue.splitAtMost(3); checkConsistency(queue); EXPECT_EQ(3, prefix->computeChainDataLength()); EXPECT_EQ(6, queue.front()->computeChainDataLength()); - prefix = queue.split(1); + prefix = queue.splitAtMost(1); checkConsistency(queue); EXPECT_EQ(1, prefix->computeChainDataLength()); EXPECT_EQ(5, queue.front()->computeChainDataLength()); - prefix = queue.split(5); + prefix = queue.splitAtMost(5); checkConsistency(queue); EXPECT_EQ(5, prefix->computeChainDataLength()); EXPECT_EQ((IOBuf*)nullptr, queue.front()); queue.append(IOBuf::copyBuffer(SCL("Hello,"))); - prefix = queue.split(3); + prefix = queue.splitAtMost(3); EXPECT_EQ(3, prefix->computeChainDataLength()); EXPECT_EQ(3, queue.chainLength()); checkConsistency(queue); queue.append(IOBuf::copyBuffer(SCL(" World"))); checkConsistency(queue); - EXPECT_THROW({ prefix = queue.split(13); }, std::underflow_error); + + prefix = queue.splitAtMost(13); + EXPECT_EQ(9, prefix->computeChainDataLength()); + EXPECT_EQ(0, queue.chainLength()); checkConsistency(queue); } TEST(BufQueue, SplitZero) { BufQueue queue; queue.append(IOBuf::copyBuffer(SCL("Hello world"))); - auto buf = queue.split(0); + auto buf = queue.splitAtMost(0); EXPECT_EQ(buf->computeChainDataLength(), 0); } TEST(BufQueue, SplitEmpty) { BufQueue queue; - auto buf = queue.split(0); + auto buf = queue.splitAtMost(0); EXPECT_EQ(buf->computeChainDataLength(), 0); } -TEST(BufQueue, SplitEmptyInvalid) { +TEST(BufQueue, SplitEmptt) { BufQueue queue; - EXPECT_THROW(queue.split(1), std::underflow_error); + auto res = queue.splitAtMost(1); + EXPECT_EQ(res->computeChainDataLength(), 0); } TEST(BufQueue, TrimStartAtMost) { diff --git a/quic/common/test/TestUtils.cpp b/quic/common/test/TestUtils.cpp index dc6a10179..07232ec85 100644 --- a/quic/common/test/TestUtils.cpp +++ b/quic/common/test/TestUtils.cpp @@ -556,8 +556,8 @@ CongestionController::AckEvent makeAck( return ack; } -folly::IOBufQueue bufToQueue(Buf buf) { - folly::IOBufQueue queue{folly::IOBufQueue::cacheChainLength()}; +BufQueue bufToQueue(Buf buf) { + BufQueue queue; buf->coalesce(); queue.append(std::move(buf)); return queue; diff --git a/quic/common/test/TestUtils.h b/quic/common/test/TestUtils.h index 5740d42a1..3d8fe71cc 100644 --- a/quic/common/test/TestUtils.h +++ b/quic/common/test/TestUtils.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -224,7 +225,7 @@ CongestionController::AckEvent makeAck( TimePoint ackedTime, TimePoint sendTime); -folly::IOBufQueue bufToQueue(Buf buf); +BufQueue bufToQueue(Buf buf); StatelessResetToken generateStatelessResetToken(); diff --git a/quic/samples/echo/EchoClient.h b/quic/samples/echo/EchoClient.h index d451f83da..a292f0e59 100644 --- a/quic/samples/echo/EchoClient.h +++ b/quic/samples/echo/EchoClient.h @@ -19,6 +19,7 @@ #include #include #include +#include #include namespace quic { @@ -155,7 +156,7 @@ class EchoClient : public quic::QuicSocket::ConnectionCallback, ~EchoClient() override = default; private: - void sendMessage(quic::StreamId id, folly::IOBufQueue& data) { + void sendMessage(quic::StreamId id, BufQueue& data) { auto message = data.move(); auto res = quicClient_->writeChain(id, message->clone(), true, false); if (res.hasError()) { @@ -178,7 +179,7 @@ class EchoClient : public quic::QuicSocket::ConnectionCallback, uint16_t port_; bool prEnabled_; std::shared_ptr quicClient_; - std::map pendingOutput_; + std::map pendingOutput_; std::map recvOffsets_; }; } // namespace samples diff --git a/quic/samples/echo/EchoHandler.h b/quic/samples/echo/EchoHandler.h index a1c52fbea..d14e638ba 100644 --- a/quic/samples/echo/EchoHandler.h +++ b/quic/samples/echo/EchoHandler.h @@ -10,8 +10,8 @@ #include -#include #include +#include namespace quic { namespace samples { @@ -19,7 +19,7 @@ class EchoHandler : public quic::QuicSocket::ConnectionCallback, public quic::QuicSocket::ReadCallback, public quic::QuicSocket::WriteCallback { public: - using StreamData = std::pair; + using StreamData = std::pair; explicit EchoHandler(folly::EventBase* evbIn, bool prEnabled = false) : evb(evbIn), prEnabled_(prEnabled) {} @@ -62,10 +62,7 @@ class EchoHandler : public quic::QuicSocket::ConnectionCallback, return; } if (input_.find(id) == input_.end()) { - input_.emplace( - id, - std::make_pair( - folly::IOBufQueue(folly::IOBufQueue::cacheChainLength()), false)); + input_.emplace(id, std::make_pair(BufQueue(), false)); } quic::Buf data = std::move(res.value().first); bool eof = res.value().second; @@ -145,7 +142,7 @@ class EchoHandler : public quic::QuicSocket::ConnectionCallback, } } - originalData.split(toSplit); + originalData.splitAtMost(toSplit); auto res = sock->writeChain(id, originalData.move(), true, false, nullptr); if (res.hasError()) { diff --git a/quic/server/state/ServerStateMachine.cpp b/quic/server/state/ServerStateMachine.cpp index e4fff926d..295b6a344 100644 --- a/quic/server/state/ServerStateMachine.cpp +++ b/quic/server/state/ServerStateMachine.cpp @@ -8,6 +8,7 @@ #include +#include #include #include #include @@ -604,7 +605,7 @@ void onServerReadDataFromOpen( initialDestinationConnectionId, version); conn.peerAddress = conn.originalPeerAddress; } - folly::IOBufQueue udpData{folly::IOBufQueue::cacheChainLength()}; + BufQueue udpData; udpData.append(std::move(readData.networkData.data)); for (uint16_t processedPackets = 0; !udpData.empty() && processedPackets < kMaxNumCoalescedPackets; @@ -1043,7 +1044,7 @@ void onServerReadDataFromClosed( QuicServerConnectionState& conn, ServerEvents::ReadData& readData) { CHECK_EQ(conn.state, ServerState::Closed); - folly::IOBufQueue udpData{folly::IOBufQueue::cacheChainLength()}; + BufQueue udpData; udpData.append(std::move(readData.networkData.data)); auto packetSize = udpData.empty() ? 0 : udpData.chainLength(); if (!conn.readCodec) { diff --git a/quic/server/test/QuicSocketTest.cpp b/quic/server/test/QuicSocketTest.cpp index fed1c4206..185d822e1 100644 --- a/quic/server/test/QuicSocketTest.cpp +++ b/quic/server/test/QuicSocketTest.cpp @@ -10,7 +10,6 @@ #include #include -#include #include #include diff --git a/quic/state/QuicStreamFunctions.cpp b/quic/state/QuicStreamFunctions.cpp index 6d33adc9d..adf490cae 100644 --- a/quic/state/QuicStreamFunctions.cpp +++ b/quic/state/QuicStreamFunctions.cpp @@ -248,7 +248,8 @@ std::pair readDataInOrderFromReadBuffer( if (sinkData) { curr->data.trimStart(toRead); } else { - splice = curr->data.split(toRead); + splice = curr->data.splitAtMost(toRead); + DCHECK_EQ(splice->computeChainDataLength(), toRead); } curr->offset += toRead; if (curr->data.chainLength() == 0) { diff --git a/quic/state/StateData.h b/quic/state/StateData.h index 38d53f6e6..de38a6bfd 100644 --- a/quic/state/StateData.h +++ b/quic/state/StateData.h @@ -10,7 +10,6 @@ #include #include -#include #include #include #include