1
0
mirror of https://github.com/facebookincubator/mvfst.git synced 2025-04-18 17:24:03 +03:00

Add SeparateDefinitionBlocks to clang-format

Summary: As in title.

Reviewed By: kvtsoy

Differential Revision: D72543602

fbshipit-source-id: 6190b7fa541b1535eab565bac3da159c85781c0e
This commit is contained in:
Matt Joras 2025-04-07 13:20:35 -07:00 committed by Facebook GitHub Bot
parent 9d01e09025
commit d153b04ec4
111 changed files with 381 additions and 0 deletions

View File

@ -92,6 +92,7 @@ PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Left
ReflowComments: true
SeparateDefinitionBlocks: Always
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false

View File

@ -78,6 +78,7 @@ QuicBatchingMode getQuicBatchingMode(uint32_t val) {
return QuicBatchingMode::BATCHING_MODE_NONE;
}
std::vector<QuicVersion> filterSupportedVersions(
const std::vector<QuicVersion>& versions) {
std::vector<QuicVersion> filteredVersions;

View File

@ -28,7 +28,9 @@ DECLARE_VARIANT_TYPE(QuicErrorCode, QUIC_ERROR_CODE)
struct QuicError {
QuicError(QuicErrorCode codeIn, std::string&& messageIn)
: code(codeIn), message(std::move(messageIn)) {}
explicit QuicError(QuicErrorCode codeIn) : code(codeIn) {}
bool operator==(const QuicError& other) const {
return code == other.code && message == other.message;
}

View File

@ -92,6 +92,7 @@ class SinglePacketInplaceBatchWriter : public IOBufBatchWriter {
public:
explicit SinglePacketInplaceBatchWriter(QuicConnectionStateBase& conn)
: conn_(conn) {}
~SinglePacketInplaceBatchWriter() override = default;
void reset() override;

View File

@ -26,6 +26,7 @@ class GSOPacketBatchWriter : public IOBufBatchWriter {
QuicAsyncUDPSocket* /*unused*/) override;
ssize_t write(QuicAsyncUDPSocket& sock, const folly::SocketAddress& address)
override;
void setTxTime(std::chrono::microseconds txTime) override {
txTime_ = txTime;
}
@ -126,6 +127,7 @@ class SendmmsgGSOPacketBatchWriter : public BatchWriter {
bool valid() const {
return idx_ >= 0;
}
int idx_ = -1;
};

View File

@ -396,6 +396,7 @@ class QuicSocketLite {
*/
using PeekIterator = CircularDeque<StreamBuffer>::const_iterator;
class PeekCallback {
public:
virtual ~PeekCallback() = default;
@ -467,6 +468,7 @@ class QuicSocketLite {
void onByteEventRegistered(ByteEvent /* byteEvent */) final {
// Not supported
}
void onByteEvent(ByteEvent byteEvent) final {
CHECK_EQ((int)ByteEvent::Type::ACK, (int)byteEvent.type); // sanity
onDeliveryAck(byteEvent.id, byteEvent.offset, byteEvent.srtt);

View File

@ -336,6 +336,7 @@ class QuicTransportBaseLite : virtual public QuicSocketLite,
void timeoutExpired() noexcept override {
transport_->keepaliveTimeoutExpired();
}
void callbackCanceled() noexcept override {
// Specifically do nothing since if we got canceled we shouldn't write.
}
@ -816,6 +817,7 @@ class QuicTransportBaseLite : virtual public QuicSocketLite,
struct ByteEventDetail {
ByteEventDetail(uint64_t offsetIn, ByteEventCallback* callbackIn)
: offset(offsetIn), callback(callbackIn) {}
uint64_t offset;
ByteEventCallback* callback;
};

View File

@ -115,11 +115,13 @@ class MockQuicSocket : public QuicSocket {
(folly::Expected<folly::Unit, LocalErrorCode>),
setMaxPacingRate,
(uint64_t));
folly::Expected<folly::Unit, LocalErrorCode>
setKnob(uint64_t knobSpace, uint64_t knobId, Buf knobBlob) override {
SharedBuf sharedBlob(knobBlob.release());
return setKnob(knobSpace, knobId, sharedBlob);
}
MOCK_METHOD(
(folly::Expected<folly::Unit, LocalErrorCode>),
setKnob,
@ -145,6 +147,7 @@ class MockQuicSocket : public QuicSocket {
void,
setConnectionCallback,
(folly::MaybeManagedPtr<ConnectionCallback>));
void setEarlyDataAppParamsFunctions(
folly::Function<bool(const Optional<std::string>&, const Buf&) const>
validator,
@ -152,6 +155,7 @@ class MockQuicSocket : public QuicSocket {
earlyDataAppParamsValidator_ = std::move(validator);
earlyDataAppParamsGetter_ = std::move(getter);
}
MOCK_METHOD(
(folly::Expected<folly::Unit, LocalErrorCode>),
pauseRead,
@ -164,6 +168,7 @@ class MockQuicSocket : public QuicSocket {
(folly::Expected<folly::Unit, LocalErrorCode>),
stopSending,
(StreamId, ApplicationErrorCode));
folly::Expected<std::pair<Buf, bool>, LocalErrorCode> read(
StreamId id,
size_t maxRead) override {
@ -174,6 +179,7 @@ class MockQuicSocket : public QuicSocket {
return std::pair<Buf, bool>(Buf(res.value().first), res.value().second);
}
}
using ReadResult =
folly::Expected<std::pair<folly::IOBuf*, bool>, LocalErrorCode>;
MOCK_METHOD(ReadResult, readNaked, (StreamId, size_t));
@ -242,11 +248,13 @@ class MockQuicSocket : public QuicSocket {
getNumByteEventCallbacksForStream,
(const ByteEvent::Type, const StreamId),
(const));
folly::Expected<folly::Unit, LocalErrorCode>
writeChain(StreamId id, Buf data, bool eof, ByteEventCallback* cb) override {
SharedBuf sharedData(data.release());
return writeChain(id, sharedData, eof, cb);
}
MOCK_METHOD(
WriteResult,
writeChain,
@ -349,11 +357,13 @@ class MockQuicSocket : public QuicSocket {
setDatagramCallback,
(DatagramCallback*));
MOCK_METHOD(uint16_t, getDatagramSizeLimit, (), (const));
folly::Expected<folly::Unit, LocalErrorCode> writeDatagram(
Buf data) override {
SharedBuf sharedData(data.release());
return writeDatagram(sharedData);
}
MOCK_METHOD(WriteResult, writeDatagram, (SharedBuf));
MOCK_METHOD(
(folly::Expected<std::vector<ReadDatagram>, LocalErrorCode>),

View File

@ -278,6 +278,7 @@ class MockQuicTransport : public QuicServerTransport {
NetworkData&& networkData) noexcept override {
onNetworkData(peer, networkData);
}
MOCK_METHOD(void, setBufAccessor, (BufAccessor*));
MOCK_METHOD(void, addPacketProcessor, (std::shared_ptr<PacketProcessor>));

View File

@ -753,6 +753,7 @@ TEST_F(QuicPacketSchedulerTest, DoNotCloneProcessedClonedPacket) {
class CloneAllPacketsWithCryptoFrameTest
: public QuicPacketSchedulerTest,
public WithParamInterface<std::tuple<bool, bool>> {};
TEST_P(
CloneAllPacketsWithCryptoFrameTest,
TestCloneAllPacketsWithCryptoFrameTrueFalse) {

View File

@ -44,6 +44,7 @@ class QuicStreamAsyncTransportTest : public Test {
QuicStreamAsyncTransportTest() {
clientQuicEvb_ = std::make_shared<FollyQuicEventBase>(&clientEvb_);
}
void SetUp() override {
createServer();
connect();

View File

@ -160,7 +160,9 @@ MaxStreamsFrame decodeMaxStreamsFrame(folly::io::Cursor& cursor) {
class TestPingCallback : public QuicSocket::PingCallback {
public:
void pingAcknowledged() noexcept override {}
void pingTimeout() noexcept override {}
void onPing() noexcept override {}
};
@ -175,10 +177,12 @@ class TestByteEventCallback : public ByteEventCallback {
EXPECT_TRUE(byteEventTracker_.find(event) == byteEventTracker_.end());
byteEventTracker_[event] = Status::REGISTERED;
}
void onByteEvent(ByteEvent event) override {
EXPECT_TRUE(byteEventTracker_.find(event) != byteEventTracker_.end());
byteEventTracker_[event] = Status::RECEIVED;
}
void onByteEventCanceled(ByteEventCancellation cancellation) override {
const ByteEvent& event = cancellation;
EXPECT_TRUE(byteEventTracker_.find(event) != byteEventTracker_.end());

View File

@ -67,6 +67,7 @@ class QuicTransportTest : public Test {
QuicTransportTest() {
qEvb_ = std::make_shared<FollyQuicEventBase>(&evb_);
}
~QuicTransportTest() override = default;
void SetUp() override {

View File

@ -52,6 +52,7 @@ class QuicTypedTransportTest : public virtual testing::Test,
public QuicTypedTransportTestBase<T> {
public:
~QuicTypedTransportTest() override = default;
void SetUp() override {
// trigger setup of the underlying transport
QuicTypedTransportTestBase<T>::SetUp();
@ -88,6 +89,7 @@ template <typename T>
class QuicTypedTransportAfterStartTest : public QuicTypedTransportTest<T> {
public:
~QuicTypedTransportAfterStartTest() override = default;
void SetUp() override {
QuicTypedTransportTest<T>::SetUp();
QuicTypedTransportTestBase<T>::startTransport();
@ -1520,6 +1522,7 @@ TYPED_TEST(QuicTypedTransportAfterStartTest, InitiateFirstKeyUpdateSuccess) {
template <typename T>
struct AckEventMatcherBuilder {
using Builder = AckEventMatcherBuilder;
Builder&& setExpectedAckedIntervals(
std::vector<
typename QuicTypedTransportTest<T>::NewOutstandingPacketInterval>
@ -1527,6 +1530,7 @@ struct AckEventMatcherBuilder {
maybeExpectedAckedIntervals = std::move(expectedAckedIntervals);
return std::move(*this);
}
Builder&& setExpectedAckedIntervals(
std::vector<Optional<
typename QuicTypedTransportTest<T>::NewOutstandingPacketInterval>>
@ -1541,49 +1545,59 @@ struct AckEventMatcherBuilder {
maybeExpectedAckedIntervals = std::move(expectedAckedIntervals);
return std::move(*this);
}
Builder&& setExpectedNumAckedPackets(const uint64_t expectedNumAckedPackets) {
maybeExpectedNumAckedPackets = expectedNumAckedPackets;
return std::move(*this);
}
Builder&& setAckTime(TimePoint ackTime) {
maybeAckTime = ackTime;
return std::move(*this);
}
Builder&& setAckDelay(std::chrono::microseconds ackDelay) {
maybeAckDelay = ackDelay;
return std::move(*this);
}
Builder&& setLargestAckedPacket(quic::PacketNum largestAckedPacketIn) {
maybeLargestAckedPacket = largestAckedPacketIn;
return std::move(*this);
}
Builder&& setLargestNewlyAckedPacket(
quic::PacketNum largestNewlyAckedPacketIn) {
maybeLargestNewlyAckedPacket = largestNewlyAckedPacketIn;
return std::move(*this);
}
Builder&& setRtt(const OptionalMicros& rttIn) {
maybeRtt = rttIn;
CHECK(!noRtt);
return std::move(*this);
}
Builder&& setRttNoAckDelay(const OptionalMicros& rttNoAckDelayIn) {
maybeRttNoAckDelay = rttNoAckDelayIn;
CHECK(!noRtt);
CHECK(!noRttWithNoAckDelay);
return std::move(*this);
}
Builder&& setNoRtt() {
noRtt = true;
CHECK(!maybeRtt);
CHECK(!maybeRttNoAckDelay);
return std::move(*this);
}
Builder&& setNoRttWithNoAckDelay() {
noRttWithNoAckDelay = true;
CHECK(!maybeRttNoAckDelay);
return std::move(*this);
}
auto build() && {
CHECK(
noRtt ||
@ -1676,6 +1690,7 @@ struct AckEventMatcherBuilder {
FAIL(); // unhandled typed test
}
}
explicit AckEventMatcherBuilder() = default;
Optional<std::vector<
@ -1697,15 +1712,18 @@ struct ReceivedUdpPacketMatcherBuilder {
using Builder = ReceivedUdpPacketMatcherBuilder;
using Obj =
quic::SocketObserverInterface::PacketsReceivedEvent::ReceivedUdpPacket;
Builder&& setExpectedPacketReceiveTime(
const TimePoint expectedPacketReceiveTime) {
maybeExpectedPacketReceiveTime = expectedPacketReceiveTime;
return std::move(*this);
}
Builder&& setExpectedPacketNumBytes(const uint64_t expectedPacketNumBytes) {
maybeExpectedPacketNumBytes = expectedPacketNumBytes;
return std::move(*this);
}
Builder&& setExpectedTosValue(const uint8_t expectedTosValue) {
maybeExpectedTosValue = expectedTosValue;
return std::move(*this);
@ -1748,6 +1766,7 @@ struct ReceivedUdpPacketMatcherBuilder {
FAIL(); // unhandled typed test
}
}
explicit ReceivedUdpPacketMatcherBuilder() = default;
Optional<TimePoint> maybeExpectedPacketReceiveTime;
@ -1784,6 +1803,7 @@ class QuicTypedTransportAfterStartTestForObservers
: public QuicTypedTransportTestForObservers<T> {
public:
~QuicTypedTransportAfterStartTestForObservers() override = default;
void SetUp() override {
QuicTypedTransportTestForObservers<T>::SetUp();
QuicTypedTransportTestForObservers<T>::startTransport();
@ -3123,6 +3143,7 @@ TYPED_TEST(
PacketNumberSpace pnSpace{PacketNumberSpace::Initial};
PacketNum packetNum{0};
};
InSequence s;
LegacyObserver::EventSet eventSet;
@ -3225,6 +3246,7 @@ TYPED_TEST(
PacketNumberSpace pnSpace{PacketNumberSpace::Initial};
PacketNum packetNum{0};
};
InSequence s;
LegacyObserver::EventSet eventSet;

View File

@ -29,6 +29,7 @@ void QuicClientAsyncTransport::onNewBidirectionalStream(
StreamId /*id*/) noexcept {
CHECK(false);
}
void QuicClientAsyncTransport::onNewUnidirectionalStream(
StreamId /*id*/) noexcept {
CHECK(false);

View File

@ -36,11 +36,15 @@ class QuicClientAsyncTransport : public QuicStreamAsyncTransport,
void onNewUnidirectionalStream(StreamId id) noexcept override;
void onStopSending(StreamId id, ApplicationErrorCode error) noexcept override;
void onConnectionEnd() noexcept override;
void onConnectionSetupError(QuicError code) noexcept override {
onConnectionError(std::move(code));
}
void onConnectionError(QuicError code) noexcept override;
void onConnectionEnd(QuicError /* error */) noexcept override {}
void onTransportReady() noexcept override;
};
} // namespace quic

View File

@ -1234,7 +1234,9 @@ void QuicClientTransportLite::recvMsg(
vec.iov_len = readBufferSize;
sockaddr* rawAddr{nullptr};
struct sockaddr_storage addrStorage {};
if (!server) {
rawAddr = reinterpret_cast<sockaddr*>(&addrStorage);
rawAddr->sa_family = sock.getLocalAddressFamily();
@ -1242,7 +1244,9 @@ void QuicClientTransportLite::recvMsg(
int flags = 0;
QuicAsyncUDPSocket::ReadCallback::OnDataAvailableParams params;
struct msghdr msg {};
msg.msg_name = rawAddr;
msg.msg_namelen = rawAddr ? kAddrLen : 0;
msg.msg_iov = &vec;
@ -1369,7 +1373,9 @@ void QuicClientTransportLite::recvFrom(
Buf readBuffer = folly::IOBuf::createCombined(readBufferSize);
sockaddr* rawAddr{nullptr};
struct sockaddr_storage addrStorage {};
if (!server) {
rawAddr = reinterpret_cast<sockaddr*>(&addrStorage);
rawAddr->sa_family = sock.getLocalAddressFamily();

View File

@ -142,6 +142,7 @@ class QuicClientTransportLite
Accepted,
Rejected
};
/**
* Returns the state of the 0RTT attempt if there was one.
*/
@ -167,10 +168,12 @@ class QuicClientTransportLite
// QuicAsyncUDPSocket::ReadCallback
void onReadClosed() noexcept override {}
void onReadError(const folly::AsyncSocketException&) noexcept override;
// QuicAsyncUDPSocket::ErrMessageCallback
void errMessage(const cmsghdr& cmsg) noexcept override;
void errMessageError(const folly::AsyncSocketException&) noexcept override {}
void setSupportedVersions(const std::vector<QuicVersion>& versions) override;

View File

@ -85,8 +85,11 @@ class QuicConnector : private quic::QuicSocket::ConnectionSetupCallback,
// QuicSocket::ConnectionSetupCallback overrides.
void onFirstPeerPacketProcessed() noexcept override {}
void onConnectionSetupError(QuicError code) noexcept override;
void onTransportReady() noexcept override {}
void onReplaySafe() noexcept override;
Callback* cb_;

View File

@ -17,6 +17,7 @@
#include <quic/handshake/TransportParameters.h>
using namespace ::testing;
namespace quic::test {
namespace {
@ -283,6 +284,7 @@ TEST_F(
processServerInitialParams(clientConn, serverTransportParams, 0);
EXPECT_FALSE(clientConn.peerAdvertisedReliableStreamResetSupport);
}
TEST_F(ClientStateMachineTest, TestProcessReliableStreamResetNonEmptyParam) {
QuicClientConnectionState clientConn(
FizzClientQuicHandshakeContext::Builder().build());
@ -332,6 +334,7 @@ struct maxStreamGroupsAdvertizedtestStruct {
uint64_t peerMaxGroupsIn;
OptionalIntegral<uint64_t> expectedTransportSettingVal;
};
class ClientStateMachineMaxStreamGroupsAdvertizedParamTest
: public ClientStateMachineTest,
public ::testing::WithParamInterface<

View File

@ -37,15 +37,18 @@ class MockClientHandshake : public ClientHandshake {
public:
MockClientHandshake(QuicClientConnectionState* conn)
: ClientHandshake(conn) {}
~MockClientHandshake() override {
destroy();
}
// Legacy workaround for move-only types
void doHandshake(
std::unique_ptr<folly::IOBuf> data,
EncryptionLevel encryptionLevel) override {
doHandshakeImpl(data.get(), encryptionLevel);
}
MOCK_METHOD(void, doHandshakeImpl, (folly::IOBuf*, EncryptionLevel));
MOCK_METHOD(
bool,

View File

@ -42,6 +42,7 @@ struct CodecParameters {
CodecParameters(uint8_t peerAckDelayExponentIn, QuicVersion versionIn)
: peerAckDelayExponent(peerAckDelayExponentIn), version(versionIn) {}
};
struct ParsedLongHeaderInvariant {
uint8_t initialByte;
LongHeaderInvariant invariant;

View File

@ -139,9 +139,11 @@ class InplaceQuicPacketBuilder final : public PacketBuilderInterface {
void writeBE(uint64_t data) override;
void write(const QuicInteger& quicInteger) override;
void appendBytes(PacketNum value, uint8_t byteNumber) override;
void appendBytes(BufAppender&, PacketNum, uint8_t) override {
CHECK(false) << "Invalid appender";
}
void appendBytes(BufWriter& writer, PacketNum value, uint8_t byteNumber)
override;
void insert(std::unique_ptr<folly::IOBuf> buf) override;
@ -220,9 +222,11 @@ class RegularQuicPacketBuilder final : public PacketBuilderInterface {
void appendBytes(PacketNum value, uint8_t byteNumber) override;
void appendBytes(BufAppender& appender, PacketNum value, uint8_t byteNumber)
override;
void appendBytes(BufWriter&, PacketNum, uint8_t) override {
CHECK(false) << "Invalid BufWriter";
}
void insert(std::unique_ptr<folly::IOBuf> buf) override;
void insert(std::unique_ptr<folly::IOBuf> buf, size_t limit) override;
void insert(const BufQueue& buf, size_t limit) override;

View File

@ -39,11 +39,13 @@ struct Nothing {
PacketDropReason reason;
Nothing() : reason(PacketDropReason::UNEXPECTED_NOTHING) {}
explicit Nothing(PacketDropReason reasonIn) : reason(reasonIn) {}
};
struct CodecError {
QuicError error;
explicit CodecError(QuicError errorIn) : error(std::move(errorIn)) {}
};

View File

@ -112,6 +112,7 @@ Optional<WriteAckFrameResult> writeAckFrame(
size_t computeSizeUsedByRecvdTimestamps(quic::WriteAckFrame& writeAckFrame);
} // namespace quic
// namespace quic
// namespace quic
// namespace quic

View File

@ -54,6 +54,7 @@ using AckBlocks = IntervalSet<PacketNum, 1, IntervalSetVec>;
struct PaddingFrame {
// How many contiguous padding frames this represents.
uint16_t numFrames{1};
bool operator==(const PaddingFrame& rhs) const {
return numFrames == rhs.numFrames;
}
@ -193,6 +194,7 @@ struct ReadAckFrame {
uint32_t ecnECT0Count{0};
uint32_t ecnECT1Count{0};
uint32_t ecnCECount{0};
bool operator==(const ReadAckFrame& /*rhs*/) const {
// Can't compare ackBlocks, function is just here to appease compiler.
return false;
@ -213,6 +215,7 @@ struct WriteAckFrame {
uint32_t ecnECT0Count{0};
uint32_t ecnECT1Count{0};
uint32_t ecnCECount{0};
bool operator==(const WriteAckFrame& /*rhs*/) const {
// Can't compare ackBlocks, function is just here to appease compiler.
return false;
@ -283,6 +286,7 @@ struct WriteAckFrameResult {
size_t timestampRangesWritten;
size_t timestampsWritten;
uint64_t extendedAckFeaturesEnabled;
WriteAckFrameResult(
uint64_t bytesWrittenIn,
WriteAckFrame writeAckFrameIn,
@ -674,6 +678,7 @@ struct NewConnectionIdFrame {
struct RetireConnectionIdFrame {
uint64_t sequenceNumber;
explicit RetireConnectionIdFrame(uint64_t sequenceNumberIn)
: sequenceNumber(sequenceNumberIn) {}
@ -979,7 +984,9 @@ struct LongHeader {
token_(
other.token_ ? std::make_unique<std::string>(*other.token_)
: nullptr) {}
LongHeader(LongHeader&& other) = default;
LongHeader& operator=(const LongHeader& other) {
packetSequenceNum_ = other.packetSequenceNum_;
longHeaderType_ = other.longHeaderType_;
@ -987,19 +994,23 @@ struct LongHeader {
token_ = std::make_unique<std::string>(*other.token_);
return *this;
}
LongHeader& operator=(LongHeader&& other) = default;
Types getHeaderType() const noexcept;
const ConnectionId& getSourceConnId() const;
const ConnectionId& getDestinationConnId() const;
QuicVersion getVersion() const;
// Note this is defined in the header so it is inlined for performance.
PacketNumberSpace getPacketNumberSpace() const {
return typeToPacketNumberSpace(longHeaderType_);
}
ProtectionType getProtectionType() const;
bool hasToken() const;
const std::string& getToken() const;
// Note this is defined in the header so it is inlined for performance.
PacketNum getPacketSequenceNum() const {
return packetSequenceNum_;
@ -1045,12 +1056,15 @@ struct ShortHeader {
PacketNum packetNum);
ProtectionType getProtectionType() const;
PacketNumberSpace getPacketNumberSpace() const {
return PacketNumberSpace::AppData;
}
PacketNum getPacketSequenceNum() const {
return packetSequenceNum_;
}
const ConnectionId& getConnectionId() const;
void setPacketNumber(PacketNum packetNum);
@ -1098,8 +1112,10 @@ struct PacketHeader {
folly::assume_unreachable();
}
}
HeaderForm getHeaderForm() const;
ProtectionType getProtectionType() const;
// Note this is defined in the header so it is inlined for performance.
PacketNumberSpace getPacketNumberSpace() const {
switch (headerForm_) {
@ -1129,6 +1145,7 @@ PacketNumberSpace protectionTypeToPacketNumberSpace(ProtectionType type);
struct StreamTypeField {
public:
explicit StreamTypeField(uint8_t field) : field_(field) {}
bool hasFin() const;
bool hasDataLength() const;
bool hasOffset() const;
@ -1137,6 +1154,7 @@ struct StreamTypeField {
struct Builder {
public:
Builder() : field_(static_cast<uint8_t>(FrameType::STREAM)) {}
Builder& switchToStreamGroups();
Builder& setFin();
Builder& setOffset();
@ -1184,6 +1202,7 @@ struct RegularPacket {
struct RetryPacket {
using IntegrityTagType = std::array<uint8_t, kRetryIntegrityTagLen>;
RetryPacket(
LongHeader&& longHeaderIn,
IntegrityTagType integrityTagIn,

View File

@ -33,7 +33,9 @@ struct Packet32DecodeData {
};
class Packet8DecodeTest : public TestWithParam<Packet8DecodeData> {};
class Packet16DecodeTest : public TestWithParam<Packet16DecodeData> {};
class Packet32DecodeTest : public TestWithParam<Packet32DecodeData> {};
TEST_P(Packet8DecodeTest, Decode) {

View File

@ -27,6 +27,7 @@ struct IntegerParams {
};
class QuicIntegerDecodeTest : public TestWithParam<IntegerParams> {};
class QuicIntegerEncodeTest : public TestWithParam<IntegerParams> {};
TEST_P(QuicIntegerDecodeTest, DecodeTrim) {

View File

@ -166,11 +166,13 @@ void setupCommonExpects(MockQuicPacketBuilder& pktBuilder) {
pktBuilder.remaining_ -= quicInteger.getSize();
}));
}
using PacketsReceivedTimestampsDeque =
CircularDeque<WriteAckFrameState::ReceivedPacket>;
const auto kDefaultTimestampsDelta = 10us;
const AckReceiveTimestampsConfig defaultAckReceiveTimestmpsConfig = {
.receiveTimestampsExponent = kDefaultReceiveTimestampsExponent};
PacketsReceivedTimestampsDeque populateReceiveTimestamps(
const AckBlocks& ackBlocks,
TimePoint connTime,

View File

@ -32,9 +32,11 @@ struct CircularDeque {
using difference_type = std::ptrdiff_t;
CircularDeque() = default;
CircularDeque(size_type n) {
resize(n);
}
CircularDeque(std::initializer_list<T> init);
CircularDeque(const CircularDeque& other) {
@ -72,6 +74,7 @@ struct CircularDeque {
folly::sizedFree(storage_, capacity_ * sizeof(T));
capacity_ = 0;
}
// Missing: more constructor overloads, and custom Allocator
bool operator==(const CircularDeque& other) const {
return size() == other.size() && std::equal(begin(), end(), other.begin());
@ -85,6 +88,7 @@ struct CircularDeque {
boost::random_access_traversal_tag> {
public:
CircularDequeIterator() : deque_(nullptr), index_(0) {}
CircularDequeIterator(const CircularDeque<U>* deque, size_type index)
: deque_(deque), index_(index) {}

View File

@ -23,14 +23,17 @@ class EnumArray : public std::array<V, size_t(K::MAX) + 1> {
public:
using IntType = typename std::underlying_type<K>::type;
static constexpr IntType ArraySize = IntType(K::MAX) + 1;
constexpr const V& operator[](K key) const {
size_t ik = keyToInt(key);
return this->std::array<V, size_t(K::MAX) + 1>::operator[](ik);
}
constexpr V& operator[](K key) {
size_t ik = keyToInt(key);
return this->std::array<V, size_t(K::MAX) + 1>::operator[](ik);
}
// Returns all valid values for the enum
FOLLY_NODISCARD constexpr std::array<K, ArraySize> keys() const {
return keyArrayHelper(std::make_integer_sequence<IntType, ArraySize>{});

View File

@ -114,6 +114,7 @@ class FunctionLooper : public QuicEventBaseLoopCallback,
QuicTimer::SharedPtr pacingTimer_;
TimePoint nextPacingTime_;
const LooperType type_;
struct {
bool running_ : 1;
bool inLoopBody_ : 1;

View File

@ -24,9 +24,11 @@ template <typename T, T Unit = (T)1>
struct Interval {
T start;
T end;
static constexpr T unitValue() {
return Unit;
}
Interval(const T& s, const T& e) : start(s), end(e) {
if (start > end) {
throw std::invalid_argument("Trying to construct invalid interval");
@ -136,4 +138,5 @@ class IntervalSet : private Container<Interval<T, Unit>> {
uint64_t insertVersion_{kDefaultIntervalSetVersion};
};
} // namespace quic
#include <quic/common/IntervalSet-inl.h>

View File

@ -55,7 +55,9 @@ struct ReceivedUdpPacket {
};
ReceivedUdpPacket() = default;
explicit ReceivedUdpPacket(Buf&& bufIn) : buf(std::move(bufIn)) {}
ReceivedUdpPacket(Buf&& bufIn, Timings timingsIn, uint8_t tosValueIn)
: buf(std::move(bufIn)),
timings(std::move(timingsIn)),
@ -70,6 +72,7 @@ struct ReceivedUdpPacket {
struct NetworkData {
NetworkData() = default;
NetworkData(
Buf&& buf,
const TimePoint& receiveTimePointIn,

View File

@ -121,9 +121,11 @@ class FollyQuicEventBase : public QuicEventBase {
[[nodiscard]] bool isScheduled() const {
return isScheduledImpl();
}
void cancelTimeout() noexcept {
return cancelImpl();
}
QuicTimerCallback* callback_;
};

View File

@ -47,6 +47,7 @@ void HighResQuicTimer::scheduleTimeout(
}
return wheelTimer_->scheduleTimeout(wrapper, timeout);
}
HighResQuicTimer::~HighResQuicTimer() {
// Resetting the wheel timer cancels all pending timeouts.
wheelTimer_.reset();

View File

@ -49,6 +49,7 @@ class LibevQuicEventBase
virtual ~EvLoopWeak() = default;
};
explicit LibevQuicEventBase(std::unique_ptr<EvLoopWeak> loop);
~LibevQuicEventBase() override;
@ -285,6 +286,7 @@ class LibevQuicEventBase
// cancelling it.
listHook_.unlink();
}
[[nodiscard]] bool isScheduledImpl() const noexcept override {
return listHook_.is_linked();
}

View File

@ -26,15 +26,19 @@ class QuicEventBaseLoopCallback {
delete implHandle;
}
}
virtual void runLoopCallback() noexcept = 0;
void cancelLoopCallback() noexcept {
if (implHandle) {
implHandle->cancelImpl();
}
}
[[nodiscard]] bool isLoopCallbackScheduled() const noexcept {
return implHandle ? implHandle->isScheduledImpl() : false;
}
class LoopCallbackImpl {
public:
virtual ~LoopCallbackImpl() = default;
@ -49,13 +53,16 @@ class QuicEventBaseLoopCallback {
class QuicTimerCallback {
public:
friend class QuicEventBase;
virtual ~QuicTimerCallback() {
if (implHandle) {
implHandle->cancelImpl();
delete implHandle;
}
}
virtual void timeoutExpired() noexcept = 0;
/// This callback was canceled. The default implementation is to just
/// proxy to `timeoutExpired` but if you care about the difference between
/// the timeout finishing or being canceled you can override this.

View File

@ -37,6 +37,7 @@ TEST(FollyQuicEventBaseTest, TestDeleteEvbInaCallback) {
class TestCallback : public quic::QuicEventBaseLoopCallback {
public:
explicit TestCallback(quic::FollyQuicEventBase* qEvb) : qEvb_(qEvb) {}
void runLoopCallback() noexcept override {
// This deletes the FollyQuicEventBase wrapper but leaves the
// underlying folly::EventBase alive.

View File

@ -17,6 +17,7 @@ class QuicEventBaseMock : public QuicEventBase {
void runInLoop(QuicEventBaseLoopCallback* cb, bool thisIteration) override {
runInLoopWithCbPtr(cb, thisIteration);
}
MOCK_METHOD((void), runInLoopWithCbPtr, (QuicEventBaseLoopCallback*, bool));
MOCK_METHOD((void), runInLoop, (folly::Function<void()>, bool));
MOCK_METHOD((void), runAfterDelay, (folly::Function<void()>, uint32_t));
@ -40,9 +41,11 @@ class QuicEventBaseMock : public QuicEventBase {
runImmediatelyOrRunInEventBaseThread,
(folly::Function<void()>),
(noexcept));
bool isInEventBaseThread() const override {
return true;
}
MOCK_METHOD(
(void),
scheduleTimeout,

View File

@ -34,6 +34,7 @@ TYPED_TEST_P(QuicEventBaseTest, NestedRunInLoopCallbackInThisIteration) {
class TestCallback : public quic::QuicEventBaseLoopCallback {
public:
explicit TestCallback(quic::QuicEventBase* qEvb) : qEvb_(qEvb) {}
void runLoopCallback() noexcept override {
auto currenCount = ++callbackCount_;
if (currenCount == 1) {
@ -68,6 +69,7 @@ TYPED_TEST_P(QuicEventBaseTest, NestedRunInLoopFuncInThisIteration) {
class TestCallback : public quic::QuicEventBaseLoopCallback {
public:
explicit TestCallback(quic::QuicEventBase* qEvb) : qEvb_(qEvb) {}
void runLoopCallback() noexcept override {
auto currenCount = ++callbackCount_;
if (currenCount == 1) {
@ -101,6 +103,7 @@ TYPED_TEST_P(QuicEventBaseTest, NestedRunInLoopCallbackInNextIteration) {
class TestCallback : public quic::QuicEventBaseLoopCallback {
public:
explicit TestCallback(quic::QuicEventBase* qEvb) : qEvb_(qEvb) {}
void runLoopCallback() noexcept override {
auto currenCount = ++callbackCount_;
if (currenCount == 1) {
@ -140,6 +143,7 @@ TYPED_TEST_P(QuicEventBaseTest, NestedRunInLoopFuncInNextIteration) {
class TestCallback : public quic::QuicEventBaseLoopCallback {
public:
explicit TestCallback(quic::QuicEventBase* qEvb) : qEvb_(qEvb) {}
void runLoopCallback() noexcept override {
auto currenCount = ++callbackCount_;
if (currenCount == 1) {
@ -172,6 +176,7 @@ TYPED_TEST_P(QuicEventBaseTest, NestedRunInLoopFuncInNextIteration) {
// Verify that the nested callback has been executed after the second loop.
EXPECT_EQ(cb->callbackCount_, 2);
}
// Tests end here
// All tests must be registered

View File

@ -12,6 +12,7 @@
namespace {
constexpr size_t kLen = 50;
template <typename T>
void prepareDeque(T& d, size_t count) {
size_t counter = 0;

View File

@ -40,7 +40,9 @@ bool verifyStorageContent(
struct TestObject {
TestObject() : val(0) {}
TestObject(int v, const std::string& w) : val(v), words(w) {}
~TestObject() = default;
TestObject(const TestObject& other)

View File

@ -15,6 +15,7 @@ class MockQuicAsyncUDPSocket : public quic::FollyQuicAsyncUDPSocket {
public:
explicit MockQuicAsyncUDPSocket(std::shared_ptr<quic::FollyQuicEventBase> evb)
: quic::FollyQuicAsyncUDPSocket(evb) {}
MOCK_METHOD2(
applyOptions,
void(const folly::SocketOptionMap&, folly::SocketOptionKey::ApplyPos));

View File

@ -338,6 +338,7 @@ bool writableContains(QuicStreamManager& streamManager, StreamId streamId);
class FizzCryptoTestFactory : public FizzCryptoFactory {
public:
FizzCryptoTestFactory() = default;
explicit FizzCryptoTestFactory(std::shared_ptr<fizz::Factory> fizzFactory) {
fizzFactory_ = std::move(fizzFactory);
}
@ -368,6 +369,7 @@ class FizzCryptoTestFactory : public FizzCryptoFactory {
class TestPacketBatchWriter : public IOBufBatchWriter {
public:
explicit TestPacketBatchWriter(int maxBufs) : maxBufs_(maxBufs) {}
~TestPacketBatchWriter() override {
CHECK_EQ(bufNum_, 0);
CHECK_EQ(bufSize_, 0);

View File

@ -17,6 +17,7 @@ namespace quic::test {
struct MockAsyncUDPSocket : public FollyQuicAsyncUDPSocket {
explicit MockAsyncUDPSocket(std::shared_ptr<FollyQuicEventBase> evb)
: FollyQuicAsyncUDPSocket(std::move(evb)) {}
~MockAsyncUDPSocket() override {}
MOCK_METHOD(void, init, (sa_family_t));

View File

@ -17,6 +17,7 @@ void FollyQuicAsyncUDPSocket::init(sa_family_t family) {
void FollyQuicAsyncUDPSocket::bind(const folly::SocketAddress& address) {
follySocket_.bind(address);
}
[[nodiscard]] bool FollyQuicAsyncUDPSocket::isBound() const {
return follySocket_.isBound();
}
@ -132,6 +133,7 @@ int FollyQuicAsyncUDPSocket::getGSO() {
int FollyQuicAsyncUDPSocket::getGRO() {
return follySocket_.getGRO();
}
bool FollyQuicAsyncUDPSocket::setGRO(bool bVal) {
return follySocket_.setGRO(bVal);
}
@ -162,9 +164,11 @@ void FollyQuicAsyncUDPSocket::attachEventBase(
evb_ = follyEvb;
follySocket_.attachEventBase(follyEvb->getBackingEventBase());
}
void FollyQuicAsyncUDPSocket::detachEventBase() {
follySocket_.detachEventBase();
}
[[nodiscard]] std::shared_ptr<QuicEventBase>
FollyQuicAsyncUDPSocket::getEventBase() const {
if (evb_) {
@ -176,9 +180,11 @@ FollyQuicAsyncUDPSocket::getEventBase() const {
void FollyQuicAsyncUDPSocket::setCmsgs(const folly::SocketCmsgMap& cmsgs) {
follySocket_.setCmsgs(cmsgs);
}
void FollyQuicAsyncUDPSocket::appendCmsgs(const folly::SocketCmsgMap& cmsgs) {
follySocket_.appendCmsgs(cmsgs);
}
void FollyQuicAsyncUDPSocket::setAdditionalCmsgsFunc(
folly::Function<Optional<folly::SocketCmsgMap>()>&& additionalCmsgsFunc) {
follySocket_.setAdditionalCmsgsFunc(std::move(additionalCmsgsFunc));

View File

@ -221,6 +221,7 @@ class FollyQuicAsyncUDPSocket : public QuicAsyncUDPSocketImpl {
wrappedReadCallback_ = readCallback;
parentSocket_ = parentSocket;
}
void getReadBuffer(void** buf, size_t* len) noexcept override;
void onDataAvailable(

View File

@ -53,6 +53,7 @@ class QuicAsyncUDPSocket {
CMSG_SPACE(sizeof(Timestamp)) + CMSG_SPACE(sizeof(uint8_t));
#endif
};
virtual ~ReadCallback() = default;
virtual void onReadClosed() noexcept = 0;
virtual void onReadError(const folly::AsyncSocketException&) noexcept = 0;
@ -182,8 +183,10 @@ class QuicAsyncUDPSocket {
struct WriteOptions {
WriteOptions() = default;
WriteOptions(int gsoVal, bool zerocopyVal)
: gso(gsoVal), zerocopy(zerocopyVal) {}
int gso{0};
bool zerocopy{false};
std::chrono::microseconds txTime{0};
@ -256,6 +259,7 @@ class QuicAsyncUDPSocket {
*/
struct RecvResult {
RecvResult() = default;
explicit RecvResult(NoReadReason noReadReason)
: maybeNoReadReason(noReadReason) {}

View File

@ -104,6 +104,7 @@ class MockErrMessageCallback
~MockErrMessageCallback() override = default;
MOCK_METHOD(void, errMessage_, (const cmsghdr&));
void errMessage(const cmsghdr& cmsg) noexcept override {
try {
errMessage_(cmsg);
@ -113,6 +114,7 @@ class MockErrMessageCallback
}
MOCK_METHOD(void, errMessageError_, (const folly::AsyncSocketException&));
void errMessageError(
const folly::AsyncSocketException& ex) noexcept override {
try {
@ -128,6 +130,7 @@ class MockUDPReadCallback : public quic::QuicAsyncUDPSocket::ReadCallback {
~MockUDPReadCallback() override = default;
MOCK_METHOD(void, getReadBuffer_, (void**, size_t*));
void getReadBuffer(void** buf, size_t* len) noexcept override {
try {
getReadBuffer_(buf, len);
@ -138,6 +141,7 @@ class MockUDPReadCallback : public quic::QuicAsyncUDPSocket::ReadCallback {
MOCK_METHOD(bool, shouldOnlyNotify, ());
MOCK_METHOD(void, onNotifyDataAvailable_, (quic::QuicAsyncUDPSocket&));
void onNotifyDataAvailable(quic::QuicAsyncUDPSocket& sock) noexcept override {
try {
onNotifyDataAvailable_(sock);
@ -150,6 +154,7 @@ class MockUDPReadCallback : public quic::QuicAsyncUDPSocket::ReadCallback {
void,
onDataAvailable_,
(const folly::SocketAddress&, size_t, bool, OnDataAvailableParams));
void onDataAvailable(
const folly::SocketAddress& client,
size_t len,
@ -163,6 +168,7 @@ class MockUDPReadCallback : public quic::QuicAsyncUDPSocket::ReadCallback {
}
MOCK_METHOD(void, onReadError_, (const folly::AsyncSocketException&));
void onReadError(const folly::AsyncSocketException& ex) noexcept override {
try {
onReadError_(ex);
@ -172,6 +178,7 @@ class MockUDPReadCallback : public quic::QuicAsyncUDPSocket::ReadCallback {
}
MOCK_METHOD(void, onReadClosed_, ());
void onReadClosed() noexcept override {
try {
onReadClosed_();

View File

@ -91,6 +91,7 @@ TYPED_TEST_P(QuicAsyncUDPSocketTest, TestUnsetErrCallback) {
class EvbTerminateTimeout : public quic::QuicTimerCallback {
public:
explicit EvbTerminateTimeout(quic::QuicEventBase* evb) : evb_(evb) {}
void timeoutExpired() noexcept override {
evb_->terminateLoopSoon();
}

View File

@ -35,11 +35,13 @@ constexpr std::array<float, kNumOfCycles> kPacingGainCycles =
constexpr std::chrono::milliseconds kProbeRttDuration{200};
// The cwnd gain to use when ccaConfig.largeProbeRttCwnd is set.
constexpr float kLargeProbeRttCwndGain = 0.75f;
// Bandwidth WindowFilter length, in unit of RTT. This value is from Chromium
// code. I don't know why.
constexpr uint8_t bandwidthWindowLength(const uint8_t numOfCycles) {
return numOfCycles + 2;
}
// RTT Sampler default expiration
constexpr std::chrono::seconds kDefaultRttSamplerExpiration{10};
// 64K, used in sendQuantum calculation:
@ -126,9 +128,11 @@ class BbrCongestionController : public CongestionController {
void onPacketAckOrLoss(
const AckEvent* FOLLY_NULLABLE,
const LossEvent* FOLLY_NULLABLE) override;
void onPacketAckOrLoss(Optional<AckEvent> ack, Optional<LossEvent> loss) {
onPacketAckOrLoss(ack.get_pointer(), loss.get_pointer());
}
uint64_t getWritableBytes() const noexcept override;
uint64_t getCongestionWindow() const noexcept override;

View File

@ -313,6 +313,7 @@ void Bbr2CongestionController::resetLowerBounds() {
bandwidthLo_.reset();
inflightLo_.reset();
}
void Bbr2CongestionController::enterStartup() {
state_ = State::Startup;
updatePacingAndCwndGain();
@ -419,6 +420,7 @@ void Bbr2CongestionController::restoreCwnd() {
cwndBytes_ = std::max(cwndBytes_, previousCwndBytes_);
VLOG(6) << "Restored cwnd: " << cwndBytes_;
}
void Bbr2CongestionController::exitProbeRtt() {
resetLowerBounds();
if (fullBwReached_) {
@ -526,6 +528,7 @@ void Bbr2CongestionController::updateAckAggregation() {
latestExtraAcked_ = std::min(latestExtraAcked_, cwndBytes_);
maxExtraAckedFilter_.Update(latestExtraAcked_, roundCount_);
}
void Bbr2CongestionController::checkStartupDone() {
checkStartupHighLoss();
@ -599,6 +602,7 @@ void Bbr2CongestionController::checkDrain() {
enterProbeBW(); /* BBR estimates the queue was drained */
}
}
void Bbr2CongestionController::updateProbeBwCyclePhase() {
/* The core state machine logic for ProbeBW: */
if (!fullBwReached_) {
@ -840,6 +844,7 @@ uint64_t Bbr2CongestionController::getProbeRTTCwnd() {
getBDPWithGain(kProbeRttCwndGain),
quic::kMinCwndInMssForBbr * conn_.udpSendPacketLen);
}
void Bbr2CongestionController::boundCwndForProbeRTT() {
if (state_ == State::ProbeRTT) {
cwndBytes_ = std::min(cwndBytes_, getProbeRTTCwnd());
@ -902,6 +907,7 @@ void Bbr2CongestionController::enterProbeBW() {
void Bbr2CongestionController::startRound() {
nextRoundDelivered_ = conn_.lossState.totalBytesAcked;
}
void Bbr2CongestionController::updateRound() {
auto pkt = currentAckEvent_->getLargestNewlyAckedPacket();
if (pkt && pkt->lastAckedPacketInfo &&
@ -936,6 +942,7 @@ void Bbr2CongestionController::startProbeBwDown() {
cycleCount_++;
}
}
void Bbr2CongestionController::startProbeBwCruise() {
state_ = State::ProbeBw_Cruise;
updatePacingAndCwndGain();
@ -949,6 +956,7 @@ void Bbr2CongestionController::startProbeBwRefill() {
updatePacingAndCwndGain();
startRound();
}
void Bbr2CongestionController::startProbeBwUp() {
probeBWCycleStart_ = Clock::now();
state_ = State::ProbeBw_Up;

View File

@ -35,6 +35,7 @@ class Copa : public CongestionController {
void onPacketAckOrLoss(
const AckEvent* FOLLY_NULLABLE,
const LossEvent* FOLLY_NULLABLE) override;
void onPacketAckOrLoss(Optional<AckEvent> ack, Optional<LossEvent> loss) {
onPacketAckOrLoss(ack.get_pointer(), loss.get_pointer());
}
@ -59,11 +60,13 @@ class Copa : public CongestionController {
struct VelocityState {
uint64_t velocity{1};
enum Direction {
None,
Up, // cwnd is increasing
Down, // cwnd is decreasing
};
Direction direction{None};
// number of rtts direction has remained same
uint64_t numTimesDirectionSame{0};
@ -71,6 +74,7 @@ class Copa : public CongestionController {
uint64_t lastRecordedCwndBytes;
Optional<TimePoint> lastCwndRecordTime{none};
};
void checkAndUpdateDirection(const TimePoint ackTime);
void changeDirection(
VelocityState::Direction newDirection,

View File

@ -26,6 +26,7 @@ class Copa2 : public CongestionController {
void onPacketAckOrLoss(
const AckEvent* FOLLY_NULLABLE,
const LossEvent* FOLLY_NULLABLE) override;
void onPacketAckOrLoss(Optional<AckEvent> ack, Optional<LossEvent> loss) {
onPacketAckOrLoss(ack.get_pointer(), loss.get_pointer());
}

View File

@ -24,6 +24,7 @@ class NewReno : public CongestionController {
void onPacketAckOrLoss(
const AckEvent* FOLLY_NULLABLE,
const LossEvent* FOLLY_NULLABLE) override;
void onPacketAckOrLoss(Optional<AckEvent> ack, Optional<LossEvent> loss) {
onPacketAckOrLoss(ack.get_pointer(), loss.get_pointer());
}

View File

@ -79,9 +79,11 @@ class Cubic : public CongestionController {
void onPacketAckOrLoss(
const AckEvent* FOLLY_NULLABLE,
const LossEvent* FOLLY_NULLABLE) override;
void onPacketAckOrLoss(Optional<AckEvent> ack, Optional<LossEvent> loss) {
onPacketAckOrLoss(ack.get_pointer(), loss.get_pointer());
}
void onRemoveBytesFromInflight(uint64_t) override;
void onPacketSent(const OutstandingPacketWrapper& packet) override;

View File

@ -144,6 +144,7 @@ class SimulatedTBF : private folly::BasicDynamicTokenBucket<
static double timePointToDouble(TimePoint timePoint) {
return std::chrono::duration<double>(timePoint.time_since_epoch()).count();
}
struct EmptyIntervalState {
std::shared_ptr<std::deque<TimeInterval>> emptyBucketTimeIntervals_;
Optional<TimePoint> maybeLastSendTimeBucketNotEmpty_;

View File

@ -29,6 +29,7 @@ struct StaticCwndCongestionController : public CongestionController {
*/
struct CwndInBytes {
explicit CwndInBytes(uint64_t bytes) : bytes(bytes) {}
const uint64_t bytes;
};

View File

@ -14,6 +14,7 @@
using namespace testing;
using namespace std::chrono_literals;
namespace {
// These values are the same as the ones in EcnL4sTracker.cpp
constexpr std::chrono::microseconds kRttVirtMin = 25ms;

View File

@ -28,7 +28,9 @@ class SimpleThrottlingSignalProvider : public PacketProcessor,
Optional<uint64_t> burstRateBytesPerSecond = none)
: stbf_(std::move(config)),
burstRateBytesPerSecond_(std::move(burstRateBytesPerSecond)) {}
~SimpleThrottlingSignalProvider() override = default;
void onPacketSent(const quic::OutstandingPacketWrapper& packet) override {
stbf_.consumeWithBorrowNonBlockingAndUpdateState(
packet.metadata.encodedSize, packet.metadata.time);

View File

@ -114,6 +114,7 @@ struct PacketizationRequest {
len(lenIn),
fin(finIn),
payloadOffset(payloadOffsetIn) {}
PacketNum packetNum;
PacketNum largestAckedPacketNum;

View File

@ -196,6 +196,7 @@ std::unique_ptr<Aead> FizzClientHandshake::buildAead(
return aead;
}
std::unique_ptr<PacketNumberCipher> FizzClientHandshake::buildHeaderCipher(
folly::ByteRange secret) {
return cryptoFactory_->makePacketNumberCipher(secret);

View File

@ -62,6 +62,7 @@ class QuicClientTransportIntegrationTest : public TestWithParam<TestingParams> {
QuicClientTransportIntegrationTest() {
qEvb_ = std::make_shared<FollyQuicEventBase>(&eventbase_);
}
void SetUp() override {
// Fizz is the hostname for the server cert.
hostname = "Fizz";
@ -1151,9 +1152,11 @@ TEST_F(QuicClientTransportTest, SocketClosedDuringOnTransportReady) {
MOCK_METHOD(void, onTransportReadyMock, (), (noexcept));
MOCK_METHOD(void, onReplaySafe, (), (noexcept));
MOCK_METHOD(void, onConnectionEnd, (), (noexcept));
void onConnectionSetupError(QuicError error) noexcept override {
onConnectionError(std::move(error));
}
MOCK_METHOD(void, onConnectionError, (QuicError), (noexcept));
private:
@ -1678,14 +1681,18 @@ class QuicClientTransportHappyEyeballsTest
client->start(&clientConnSetupCallback, &clientConnCallback);
EXPECT_EQ(conn.peerAddress, firstAddress);
EXPECT_EQ(conn.happyEyeballsState.secondPeerAddress, secondAddress);
// Give up first socket
union {
struct cmsghdr hdr;
unsigned char buf[CMSG_SPACE(sizeof(sock_extended_err))];
} cmsgbuf;
cmsgbuf.hdr.cmsg_level = SOL_IPV6;
cmsgbuf.hdr.cmsg_type = IPV6_RECVERR;
struct sock_extended_err err {};
err.ee_errno = EBADF;
auto dest = (struct sock_extended_err*)CMSG_DATA(&cmsgbuf.hdr);
*dest = err;
@ -1729,9 +1736,12 @@ class QuicClientTransportHappyEyeballsTest
struct cmsghdr hdr;
unsigned char buf[CMSG_SPACE(sizeof(sock_extended_err))];
} cmsgbuf;
cmsgbuf.hdr.cmsg_level = SOL_IPV6;
cmsgbuf.hdr.cmsg_type = IPV6_RECVERR;
struct sock_extended_err err {};
err.ee_errno = EBADF;
auto dest = (struct sock_extended_err*)CMSG_DATA(&cmsgbuf.hdr);
*dest = err;
@ -1770,13 +1780,17 @@ class QuicClientTransportHappyEyeballsTest
// Manually expire loss timeout to trigger write to both first and second
// socket
EXPECT_CALL(*sock, write(firstAddress, _, _));
union {
struct cmsghdr hdr;
unsigned char buf[CMSG_SPACE(sizeof(sock_extended_err))];
} cmsgbuf;
cmsgbuf.hdr.cmsg_level = SOL_IP;
cmsgbuf.hdr.cmsg_type = IP_RECVERR;
struct sock_extended_err err {};
err.ee_errno = EBADF;
auto dest = (struct sock_extended_err*)CMSG_DATA(&cmsgbuf.hdr);
*dest = err;
@ -1821,9 +1835,12 @@ class QuicClientTransportHappyEyeballsTest
struct cmsghdr hdr;
unsigned char buf[CMSG_SPACE(sizeof(sock_extended_err))];
} cmsgbuf;
cmsgbuf.hdr.cmsg_level = SOL_IP;
cmsgbuf.hdr.cmsg_type = IP_RECVERR;
struct sock_extended_err err {};
err.ee_errno = EBADF;
auto dest = (struct sock_extended_err*)CMSG_DATA(&cmsgbuf.hdr);
*dest = err;
@ -4700,6 +4717,7 @@ class TestCCFactory : public CongestionControllerFactory {
createdControllers++;
return std::make_unique<Cubic>(conn);
}
int createdControllers{0};
};
@ -5921,16 +5939,21 @@ TEST(AsyncUDPSocketTest, CloseMultipleTimes) {
class EmptyReadCallback : public QuicAsyncUDPSocket::ReadCallback {
public:
void getReadBuffer(void**, size_t*) noexcept override {}
void onDataAvailable(
const folly::SocketAddress&,
size_t,
bool,
OnDataAvailableParams) noexcept override {}
void onReadError(const AsyncSocketException&) noexcept override {}
void onReadClosed() noexcept override {}
bool shouldOnlyNotify() override {
return true;
}
void onNotifyDataAvailable(QuicAsyncUDPSocket&) noexcept override {}
};
@ -5938,6 +5961,7 @@ TEST(AsyncUDPSocketTest, CloseMultipleTimes) {
: public QuicAsyncUDPSocket::ErrMessageCallback {
public:
void errMessage(const cmsghdr&) noexcept override {}
void errMessageError(const AsyncSocketException&) noexcept override {}
};

View File

@ -353,6 +353,7 @@ class FakeOneRttHandshakeLayer : public FizzClientHandshake {
Optional<std::string> alpn_{folly::none};
FizzCryptoFactory cryptoFactory_;
const CryptoFactory& getCryptoFactory() const override {
return cryptoFactory_;
}
@ -361,22 +362,28 @@ class FakeOneRttHandshakeLayer : public FizzClientHandshake {
bool isTLSResumed() const override {
throw std::runtime_error("isTLSResumed not implemented");
}
EncryptionLevel getReadRecordLayerEncryptionLevel() override {
throw std::runtime_error(
"getReadRecordLayerEncryptionLevel not implemented");
}
const Optional<std::string>& getApplicationProtocol() const override {
return alpn_;
}
void processSocketData(folly::IOBufQueue&) override {
throw std::runtime_error("processSocketData not implemented");
}
bool matchEarlyParameters() override {
throw std::runtime_error("matchEarlyParameters not implemented");
}
std::unique_ptr<Aead> buildAead(CipherKind, folly::ByteRange) override {
return createNoOpAead();
}
std::unique_ptr<PacketNumberCipher> buildHeaderCipher(
folly::ByteRange) override {
throw std::runtime_error("buildHeaderCipher not implemented");

View File

@ -40,6 +40,7 @@ class FizzAead final : public Aead {
return fizzAead->inplaceEncrypt(
std::move(plaintext), associatedData, seqNum);
}
std::unique_ptr<folly::IOBuf> decrypt(
std::unique_ptr<folly::IOBuf>&& ciphertext,
const folly::IOBuf* associatedData,
@ -49,6 +50,7 @@ class FizzAead final : public Aead {
return fizzAead->decrypt(
std::move(ciphertext), associatedData, seqNum, options);
}
Optional<std::unique_ptr<folly::IOBuf>> tryDecrypt(
std::unique_ptr<folly::IOBuf>&& ciphertext,
const folly::IOBuf* associatedData,
@ -58,12 +60,14 @@ class FizzAead final : public Aead {
return fizzAead->tryDecrypt(
std::move(ciphertext), associatedData, seqNum, options);
}
size_t getCipherOverhead() const override {
return fizzAead->getCipherOverhead();
}
private:
std::unique_ptr<fizz::Aead> fizzAead;
explicit FizzAead(std::unique_ptr<fizz::Aead> fizzAeadIn)
: fizzAead(std::move(fizzAeadIn)) {}
};

View File

@ -96,6 +96,7 @@ std::unique_ptr<Aead> FizzServerHandshake::buildAead(folly::ByteRange secret) {
kQuicKeyLabel,
kQuicIVLabel));
}
std::unique_ptr<PacketNumberCipher> FizzServerHandshake::buildHeaderCipher(
folly::ByteRange secret) {
return cryptoFactory_->makePacketNumberCipher(secret);

View File

@ -26,6 +26,7 @@ class QuicFlowControlTest : public Test {
conn_, conn_.nodeType, conn_.transportSettings);
conn_.statsCallback = quicStats_.get();
}
std::unique_ptr<MockQuicStats> quicStats_;
QuicConnectionStateBase conn_{QuicNodeType::Client};
};
@ -367,6 +368,7 @@ TEST_F(QuicFlowControlTest, MaybeWriteBlockedAfterAPIWrite) {
maybeWriteBlockAfterAPIWrite(stream);
EXPECT_TRUE(conn_.streamManager->hasBlocked());
}
TEST_F(QuicFlowControlTest, UpdateFlowControlClearsStreamBlockedFlag) {
StreamId id = 3;
QuicStreamState stream(id, conn_);

View File

@ -60,6 +60,7 @@ class Handshake {
std::string pskType;
std::string echStatus;
};
[[nodiscard]] virtual TLSSummary getTLSSummary() const = 0;
};

View File

@ -50,6 +50,7 @@ class MockAead : public Aead {
const folly::IOBuf* associatedData,
uint64_t seqNum),
(const));
std::unique_ptr<folly::IOBuf> inplaceEncrypt(
std::unique_ptr<folly::IOBuf>&& plaintext,
const folly::IOBuf* associatedData,
@ -64,6 +65,7 @@ class MockAead : public Aead {
const folly::IOBuf* associatedData,
uint64_t seqNum),
(const));
std::unique_ptr<folly::IOBuf> decrypt(
std::unique_ptr<folly::IOBuf>&& ciphertext,
const folly::IOBuf* associatedData,
@ -78,6 +80,7 @@ class MockAead : public Aead {
const folly::IOBuf* associatedData,
uint64_t seqNum),
(const));
Optional<std::unique_ptr<folly::IOBuf>> tryDecrypt(
std::unique_ptr<folly::IOBuf>&& ciphertext,
const folly::IOBuf* associatedData,

View File

@ -21,6 +21,7 @@ void FileQLogger::setDcid(Optional<ConnectionId> connID) {
}
}
}
void FileQLogger::setScid(Optional<ConnectionId> connID) {
if (connID.hasValue()) {
scid = connID.value();
@ -304,6 +305,7 @@ void FileQLogger::addAppUnlimitedUpdate() {
std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::steady_clock::now().time_since_epoch())));
}
void FileQLogger::addPacingMetricUpdate(
uint64_t pacingBurstSizeIn,
std::chrono::microseconds pacingIntervalIn) {

View File

@ -28,6 +28,7 @@ class FileQLogger : public BaseQLogger {
using QLogger::TransportSummaryArgs;
std::vector<std::unique_ptr<QLogEvent>> logs;
FileQLogger(
VantagePoint vantagePointIn,
std::string protocolTypeIn = kHTTP3ProtocolType,
@ -46,6 +47,7 @@ class FileQLogger : public BaseQLogger {
finishStream();
}
}
void addPacket(const RegularQuicPacket& regularPacket, uint64_t packetSize)
override;
void addPacket(

View File

@ -43,6 +43,7 @@ class QLogger {
std::string reason,
bool drainConnection,
bool sendCloseImmediately) = 0;
struct TransportSummaryArgs {
uint64_t totalBytesSent{};
uint64_t totalBytesRecvd{};
@ -70,6 +71,7 @@ class QLogger {
std::string pskType;
std::string echStatus;
};
virtual void addTransportSummary(const TransportSummaryArgs& args) = 0;
virtual void addCongestionMetricUpdate(
uint64_t bytesInFlight,

View File

@ -251,6 +251,7 @@ void QLoggerCommon::addConnectionMigrationUpdate(bool intentionalMigration) {
logTrace(std::make_unique<quic::QLogConnectionMigrationEvent>(
intentionalMigration, vantagePoint, refTime));
}
void QLoggerCommon::addPathValidationEvent(bool success) {
auto refTime = std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::steady_clock::now().time_since_epoch());
@ -302,6 +303,7 @@ void QLoggerCommon::setDcid(folly::Optional<quic::ConnectionId> connID) {
dcid = connID;
}
}
void QLoggerCommon::setScid(folly::Optional<quic::ConnectionId> connID) {
if (connID.hasValue()) {
scid = connID;

View File

@ -26,6 +26,7 @@ class QLogFrame {
class PaddingFrameLog : public QLogFrame {
public:
uint64_t numFrames;
explicit PaddingFrameLog(uint64_t numFramesIn) : numFrames{numFramesIn} {}
~PaddingFrameLog() override = default;
@ -101,6 +102,7 @@ class MaxStreamsFrameLog : public QLogFrame {
MaxStreamsFrameLog(uint64_t maxStreamsIn, bool isForBidirectionalIn)
: maxStreams{maxStreamsIn}, isForBidirectional{isForBidirectionalIn} {}
~MaxStreamsFrameLog() override = default;
FOLLY_NODISCARD folly::dynamic toDynamic() const override;
};
@ -129,6 +131,7 @@ class DataBlockedFrameLog : public QLogFrame {
uint64_t dataLimit;
explicit DataBlockedFrameLog(uint64_t dataLimitIn) : dataLimit{dataLimitIn} {}
~DataBlockedFrameLog() override = default;
FOLLY_NODISCARD folly::dynamic toDynamic() const override;
};
@ -136,7 +139,9 @@ class DataBlockedFrameLog : public QLogFrame {
class NewTokenFrameLog : public QLogFrame {
public:
std::string token;
explicit NewTokenFrameLog(std::string tokenIn) : token(std::move(tokenIn)) {}
~NewTokenFrameLog() override = default;
FOLLY_NODISCARD folly::dynamic toDynamic() const override;
};
@ -152,6 +157,7 @@ class KnobFrameLog : public QLogFrame {
uint64_t knobIdIn,
size_t knobBlobLenIn)
: knobSpace(knobSpaceIn), knobId(knobIdIn), knobBlobLen(knobBlobLenIn) {}
~KnobFrameLog() override = default;
FOLLY_NODISCARD folly::dynamic toDynamic() const override;
};
@ -172,6 +178,7 @@ class AckFrequencyFrameLog : public QLogFrame {
packetTolerance(packetToleranceIn),
updateMaxAckDelay(updateMaxAckDelayIn),
reorderThreshold(reorderThresholdIn) {}
~AckFrequencyFrameLog() override = default;
FOLLY_NODISCARD folly::dynamic toDynamic() const override;
};
@ -190,6 +197,7 @@ class StreamDataBlockedFrameLog : public QLogFrame {
StreamDataBlockedFrameLog(StreamId streamIdIn, uint64_t dataLimitIn)
: streamId{streamIdIn}, dataLimit{dataLimitIn} {}
~StreamDataBlockedFrameLog() override = default;
FOLLY_NODISCARD folly::dynamic toDynamic() const override;
};
@ -225,6 +233,7 @@ class ReadAckFrameLog : public QLogFrame {
ecnECT0Count(ecnECT0CountIn),
ecnECT1Count(ecnECT1CountIn),
ecnCECount(ecnCECountIn) {}
~ReadAckFrameLog() override = default;
FOLLY_NODISCARD folly::dynamic toDynamic() const override;
};
@ -260,6 +269,7 @@ class WriteAckFrameLog : public QLogFrame {
ecnECT0Count(ecnECT0CountIn),
ecnECT1Count(ecnECT1CountIn),
ecnCECount(ecnCECountIn) {}
~WriteAckFrameLog() override = default;
FOLLY_NODISCARD folly::dynamic toDynamic() const override;
};
@ -277,6 +287,7 @@ class StreamFrameLog : public QLogFrame {
uint64_t lenIn,
bool finIn)
: streamId{streamIdIn}, offset{offsetIn}, len{lenIn}, fin{finIn} {}
~StreamFrameLog() override = default;
FOLLY_NODISCARD folly::dynamic toDynamic() const override;
@ -289,6 +300,7 @@ class CryptoFrameLog : public QLogFrame {
CryptoFrameLog(uint64_t offsetIn, uint64_t lenIn)
: offset{offsetIn}, len{lenIn} {}
~CryptoFrameLog() override = default;
FOLLY_NODISCARD folly::dynamic toDynamic() const override;
};
@ -300,6 +312,7 @@ class StopSendingFrameLog : public QLogFrame {
StopSendingFrameLog(StreamId streamIdIn, ApplicationErrorCode errorCodeIn)
: streamId{streamIdIn}, errorCode{errorCodeIn} {}
~StopSendingFrameLog() override = default;
FOLLY_NODISCARD folly::dynamic toDynamic() const override;
};
@ -309,6 +322,7 @@ class PathChallengeFrameLog : public QLogFrame {
uint64_t pathData;
explicit PathChallengeFrameLog(uint64_t pathDataIn) : pathData{pathDataIn} {}
~PathChallengeFrameLog() override = default;
FOLLY_NODISCARD folly::dynamic toDynamic() const override;
};
@ -318,6 +332,7 @@ class PathResponseFrameLog : public QLogFrame {
uint64_t pathData;
explicit PathResponseFrameLog(uint64_t pathDataIn) : pathData{pathDataIn} {}
~PathResponseFrameLog() override = default;
FOLLY_NODISCARD folly::dynamic toDynamic() const override;
};
@ -329,6 +344,7 @@ class NewConnectionIdFrameLog : public QLogFrame {
NewConnectionIdFrameLog(uint16_t sequenceIn, StatelessResetToken tokenIn)
: sequence{sequenceIn}, token{tokenIn} {}
~NewConnectionIdFrameLog() override = default;
FOLLY_NODISCARD folly::dynamic toDynamic() const override;
};
@ -373,6 +389,7 @@ class VersionNegotiationLog {
explicit VersionNegotiationLog(const std::vector<QuicVersion>& versionsIn)
: versions{versionsIn} {}
~VersionNegotiationLog() = default;
FOLLY_NODISCARD folly::dynamic toDynamic() const;
};

View File

@ -14,7 +14,9 @@ namespace quic::test {
class MockQLogger : public QLogger {
public:
MockQLogger() = delete;
MockQLogger(VantagePoint vp) : QLogger(vp, kHTTP3ProtocolType) {}
~MockQLogger() override = default;
MOCK_METHOD(void, addPacket, (const RegularQuicPacket&, uint64_t));
MOCK_METHOD(

View File

@ -66,21 +66,26 @@ class SocketObserverContainer : public SocketObserverContainerBaseT {
void attached(QuicSocketLite* obj) noexcept override {
observerAttach(obj);
}
void detached(QuicSocketLite* obj) noexcept override {
observerDetach(obj);
}
void destroyed(QuicSocketLite* obj, DestroyContext* /* ctx */) noexcept
override {
destroy(obj);
}
void addedToObserverContainer(
ObserverContainerBase* list) noexcept override {
CHECK(list->getObject());
}
void removedFromObserverContainer(
ObserverContainerBase* list) noexcept override {
CHECK(list->getObject());
}
void movedToObserverContainer(
ObserverContainerBase* oldList,
ObserverContainerBase* newList) noexcept override {

View File

@ -68,6 +68,7 @@ class SocketObserverInterface {
const CloseStartedEvent& left) {
return right.maybeCloseReason != left.maybeCloseReason;
}
friend auto operator==(
const CloseStartedEvent& right,
const CloseStartedEvent& left) {
@ -331,6 +332,7 @@ class SocketObserverInterface {
packetMetadata(std::move(pktMetadata)),
packetNum(packetNum),
pnSpace(pnSpace) {}
bool lostByTimeout{false};
bool lostByReorderThreshold{false};
const quic::OutstandingPacketMetadata packetMetadata;
@ -356,6 +358,7 @@ class SocketObserverInterface {
packetNum,
pnSpace);
}
const TimePoint lossTime;
std::vector<LostPacket> lostPackets;
};
@ -371,6 +374,7 @@ class SocketObserverInterface {
ackDelay(ackDelayIn),
metadata(pkt.metadata),
lastAckedPacketInfo(pkt.lastAckedPacketInfo) {}
TimePoint rcvTime;
std::chrono::microseconds rttSample;
std::chrono::microseconds ackDelay;
@ -398,6 +402,7 @@ class SocketObserverInterface {
packetNum,
pnSpace);
}
const TimePoint rcvTime;
std::vector<LostPacket> spuriousPackets;
};
@ -405,6 +410,7 @@ class SocketObserverInterface {
struct KnobFrameEvent {
explicit KnobFrameEvent(TimePoint rcvTimeIn, quic::KnobFrame knobFrame)
: rcvTime(rcvTimeIn), knobFrame(std::move(knobFrame)) {}
const TimePoint rcvTime;
const quic::KnobFrame knobFrame;
};
@ -434,6 +440,7 @@ class SocketObserverInterface {
: l4sWeight(l4sWeightIn),
newECT1Echoed(newECT1EchoedIn),
newCEEchoed(newCEEchoedIn) {}
double l4sWeight;
uint32_t newECT1Echoed;
uint32_t newCEEchoed;
@ -444,6 +451,7 @@ class SocketObserverInterface {
uint64_t packetsPerInterval,
std::chrono::microseconds interval)
: packetsPerInterval(packetsPerInterval), interval(interval) {}
uint64_t packetsPerInterval;
std::chrono::microseconds interval;
};

View File

@ -22,6 +22,7 @@ class HTTPPriorityQueue : public quic::PriorityQueue {
bool incremental : 1;
uint64_t index : 63;
};
using IndexMap =
folly::F14ValueMap<Identifier, IndexMapElem, Identifier::hash>;
@ -29,6 +30,7 @@ class HTTPPriorityQueue : public quic::PriorityQueue {
class Priority : public quic::PriorityQueue::Priority {
public:
using OrderId = uint64_t;
struct HTTPPriority {
uint8_t urgency : 3;
bool paused : 1;
@ -55,6 +57,7 @@ class HTTPPriorityQueue : public quic::PriorityQueue {
}
enum Paused { PAUSED };
/* implicit */ Priority(Paused) : Priority(0, false, 0) {
getFields().paused = true;
}
@ -187,6 +190,7 @@ class HTTPPriorityQueue : public quic::PriorityQueue {
// the heap.
struct Element {
Element(Priority p, Identifier i) : priority(std::move(p)), identifier(i) {}
Priority priority;
Identifier identifier;
@ -200,6 +204,7 @@ class HTTPPriorityQueue : public quic::PriorityQueue {
// sequential priorities are equal
return identifier.asUint64() < other.identifier.asUint64();
}
bool operator<=(const Element& other) const {
return !(other < *this);
}
@ -209,6 +214,7 @@ class HTTPPriorityQueue : public quic::PriorityQueue {
IndexMapElem elem;
IndexMap::const_iterator indexIt;
};
[[nodiscard]] quic::Optional<FindResult> find(Identifier id) const;
void addIndex(Identifier id, IndexMapElem indexElem);
void removeIndex(IndexMap::const_iterator it);

View File

@ -59,10 +59,12 @@ class PriorityQueue {
static constexpr uint64_t kTypeMask =
static_cast<uint64_t>(Type::UNINITIALIZED) << kTypeShift;
Identifier() = default;
static Identifier fromStreamID(uint64_t streamID) {
CHECK_LT(streamID, 1LLU << 62);
return Identifier(streamID);
}
static Identifier fromDatagramFlowID(uint32_t flowID) {
return Identifier((uint64_t(Type::DATAGRAM) << kTypeShift) | flowID);
}
@ -70,29 +72,37 @@ class PriorityQueue {
[[nodiscard]] Type getType() const {
return Type((value & kTypeMask) >> kTypeShift);
}
[[nodiscard]] bool isStreamID() const {
return getType() == Type::STREAM;
}
[[nodiscard]] bool isDatagramFlowID() const {
return getType() == Type::DATAGRAM;
}
[[nodiscard]] bool isInitialized() const {
return getType() != Type::UNINITIALIZED;
}
[[nodiscard]] uint64_t asStreamID() const {
CHECK(isStreamID());
return value & ~kTypeMask;
}
[[nodiscard]] uint32_t asDatagramFlowID() const {
CHECK(isDatagramFlowID());
return uint32_t(value); // truncating the top works
}
[[nodiscard]] uint64_t asUint64() const {
return value & ~kTypeMask;
}
bool operator==(const Identifier& other) const {
return value == other.value;
}
struct hash {
size_t operator()(const Identifier& id) const {
return std::hash<uint64_t>()(id.value);
@ -101,6 +111,7 @@ class PriorityQueue {
private:
explicit Identifier(uint64_t v) : value(v) {}
uint64_t value{uint64_t(Type::UNINITIALIZED) << kTypeShift};
};
@ -118,6 +129,7 @@ class PriorityQueue {
protected:
using StorageType = std::array<uint8_t, 16>;
template <typename T>
T& getPriority() {
static_assert(

View File

@ -14,6 +14,7 @@ namespace {
using namespace quic;
using Identifier = quic::PriorityQueue::Identifier;
class HTTPPriorityQueueTest : public testing::Test {
protected:
HTTPPriorityQueue queue_;

View File

@ -94,6 +94,7 @@ BENCHMARK(incremental, n) {
benchmarkPriority(96, true);
}
}
BENCHMARK(sequential8, n) {
for (size_t i = 0; i < n; i++) {
benchmarkPriority(8, false);

View File

@ -50,9 +50,11 @@ class QuicHandshakeSocketHolder
}
delete this;
}
void onReplaySafe() noexcept override {
// Unused for server
}
void onTransportReady() noexcept override {
quicSocket_->setConnectionSetupCallback(nullptr);
if (callback_) {

View File

@ -14,6 +14,7 @@ namespace quic {
class QuicReusePortUDPSocketFactory : public QuicUDPSocketFactory {
public:
~QuicReusePortUDPSocketFactory() override {}
QuicReusePortUDPSocketFactory(bool reusePort = true, bool reuseAddr = false)
: reusePort_(reusePort), reuseAddr_(reuseAddr) {}

View File

@ -29,6 +29,7 @@ FOLLY_GFLAGS_DEFINE_int32(
namespace {
using namespace quic;
// Determine which worker to route to
// This **MUST** be kept in sync with the BPF program (if supplied)
size_t getWorkerToRouteTo(
@ -57,6 +58,7 @@ void ownedEvbDeleter(folly::IOExecutor* evb) {
void unownedEvbDeleter(folly::IOExecutor*) {}
} // namespace
//
namespace quic {

View File

@ -377,6 +377,7 @@ class QuicServer : public QuicServerWorker::WorkerCallback,
std::unique_ptr<folly::EventBaseBackendBase> (*factory)();
bool supportsRecvmsgMultishot = false;
};
static EventBaseBackendDetails getEventBaseBackendDetails();
// helper function to initialize workers
@ -450,13 +451,16 @@ class QuicServer : public QuicServerWorker::WorkerCallback,
// address that the server is bound to
folly::SocketAddress boundAddress_;
folly::SocketOptionMap socketOptions_;
// Rate limits
struct RateLimit {
RateLimit(std::function<uint64_t()> c, std::chrono::seconds w)
: count(std::move(c)), window(w) {}
std::function<uint64_t()> count;
std::chrono::seconds window;
};
Optional<RateLimit> rateLimit_;
std::function<int()> unfinishedHandshakeLimitFn_{[]() { return 1048576; }};

View File

@ -20,6 +20,7 @@ struct GetBetterWindowsTimers {
GetBetterWindowsTimers() {
CHECK_EQ(timeBeginPeriod(1), TIMERR_NOERROR);
}
~GetBetterWindowsTimers() {
timeEndPeriod(1);
}

View File

@ -221,6 +221,7 @@ class QuicServerTransport
public:
explicit QuicEventBaseAsFollyExecutor(quic::QuicEventBase* eventBase)
: eventBase_(eventBase) {}
void add(folly::Func f) override {
eventBase_->runInLoop(std::move(f));
}

View File

@ -51,6 +51,7 @@ bool isValidConnIdLength(const quic::ConnectionId& connId) {
namespace quic {
std::atomic_int globalUnfinishedHandshakes{0};
int QuicServerWorker::getUnfinishedHandshakeCount() {
return globalUnfinishedHandshakes.load(std::memory_order_relaxed);
}
@ -1264,6 +1265,7 @@ void QuicServerWorker::setFizzContext(
std::shared_ptr<const fizz::server::FizzServerContext> ctx) {
ctx_ = ctx;
}
TransportSettings QuicServerWorker::validateTransportSettings(
TransportSettings transportSettings) {
if (transportSettings.batchingMode != QuicBatchingMode::BATCHING_MODE_GSO &&
@ -1588,6 +1590,7 @@ size_t QuicServerWorker::SourceIdentityHash::operator()(
std::array<unsigned char, kKeySize> key{};
struct sockaddr_storage storage {};
const auto& sockaddr = sid.first;
sockaddr.getAddress(&storage);
memcpy(key.data(), &storage, sizeof(struct sockaddr_storage));

View File

@ -53,6 +53,7 @@ class QuicServerWorker : public FollyAsyncUDPSocketAlias::ReadCallback,
MsgHdr() = delete;
~MsgHdr() override = default;
explicit MsgHdr(QuicServerWorker* worker) {
arg_ = worker;
freeFunc_ = MsgHdr::free;
@ -122,6 +123,7 @@ class QuicServerWorker : public FollyAsyncUDPSocketAlias::ReadCallback,
struct MultishotHdr : public folly::EventRecvmsgMultishotCallback::Hdr {
MultishotHdr() = delete;
~MultishotHdr() override = default;
explicit MultishotHdr(QuicServerWorker* worker) {
arg_ = worker;
freeFunc_ = MultishotHdr::free;
@ -437,6 +439,7 @@ class QuicServerWorker : public FollyAsyncUDPSocketAlias::ReadCallback,
struct SourceIdentityHash {
size_t operator()(const QuicServerTransport::SourceIdentity& sid) const;
};
using SrcToTransportMap = folly::F14FastMap<
QuicServerTransport::SourceIdentity,
QuicServerTransport::Ptr,
@ -452,6 +455,7 @@ class QuicServerWorker : public FollyAsyncUDPSocketAlias::ReadCallback,
FollyAsyncUDPSocketAlias::ReadCallback* getTakeoverHandlerCallback() {
return takeoverCB_.get();
}
// Handle the network data for a udp packet
// public so that it can be called by tests as well.
void handleNetworkData(
@ -667,7 +671,9 @@ class QuicServerWorker : public FollyAsyncUDPSocketAlias::ReadCallback,
// Handle takeover between processes
std::unique_ptr<TakeoverHandlerCallback> takeoverCB_;
enum ProcessId processId_ { ProcessId::ZERO };
TakeoverPacketHandler takeoverPktHandler_;
bool packetForwardingEnabled_{false};
QuicTimer::SharedPtr pacingTimer_;

View File

@ -14,6 +14,7 @@ namespace quic {
class QuicSharedUDPSocketFactory : public QuicUDPSocketFactory {
public:
~QuicSharedUDPSocketFactory() override {}
QuicSharedUDPSocketFactory() {}
std::unique_ptr<FollyAsyncUDPSocketAlias> make(folly::EventBase* evb, int fd)

View File

@ -57,16 +57,20 @@ class ServerTransportConnectionSetupCallback
void onNewBidirectionalStream(StreamId /*id*/) noexcept override {
CHECK(false);
}
void onNewUnidirectionalStream(StreamId /*id*/) noexcept override {
CHECK(false);
}
void onStopSending(StreamId /*id*/, ApplicationErrorCode /*error*/) noexcept
override {
CHECK(false);
}
void onConnectionEnd() noexcept override {
CHECK(false);
}
void onConnectionError(QuicError /*code*/) noexcept override {
CHECK(false);
}

View File

@ -20,6 +20,7 @@ void QuicServerAsyncTransport::onNewBidirectionalStream(StreamId id) noexcept {
CHECK_EQ(id, 0) << "only single stream w/ id=0 is supported";
setStreamId(id);
}
void QuicServerAsyncTransport::onNewUnidirectionalStream(
StreamId /*id*/) noexcept {
LOG(FATAL) << "Unidirectional stream not supported";

View File

@ -31,11 +31,15 @@ class QuicServerAsyncTransport : public QuicStreamAsyncTransport,
void onNewUnidirectionalStream(StreamId id) noexcept override;
void onStopSending(StreamId id, ApplicationErrorCode error) noexcept override;
void onConnectionEnd() noexcept override;
void onConnectionSetupError(QuicError code) noexcept override {
onConnectionError(std::move(code));
}
void onConnectionError(QuicError code) noexcept override;
void onConnectionEnd(QuicError /*error*/) noexcept override {}
void onTransportReady() noexcept override;
};
} // namespace quic

View File

@ -286,31 +286,40 @@ class ServerHandshakeTest : public Test {
}
void operator()(fizz::DeliverAppData&) {}
void operator()(fizz::WriteToSocket& write) {
clientWrites.push_back(std::move(write));
}
void operator()(fizz::client::ReportEarlyHandshakeSuccess&) {
earlyHandshakeSuccess = true;
}
void operator()(fizz::client::ReportHandshakeSuccess&) {
handshakeSuccess = true;
}
void operator()(fizz::client::ReportEarlyWriteFailed&) {
earlyWriteFailed = true;
}
void operator()(fizz::ReportError&) {
error = true;
}
void operator()(fizz::WaitForData&) {
waitForData = true;
fizzClient->waitForData();
}
void operator()(fizz::client::MutateState& mutator) {
mutator(clientState);
}
void operator()(fizz::client::NewCachedPsk& newCachedPsk) {
clientCtx->putPsk(hostname, std::move(newCachedPsk.psk));
}
void operator()(fizz::SecretAvailable&) {}
void operator()(fizz::EndOfData&) {}

View File

@ -74,6 +74,7 @@ TEST(ServerTransportParametersTest, TestGetExtensionsMissingClientParams) {
ConnectionId(std::vector<uint8_t>()));
EXPECT_THROW(ext.getExtensions(TestMessages::clientHello()), FizzException);
}
TEST(ServerTransportParametersTest, TestQuicV1RejectDraftExtensionNumber) {
ServerTransportParametersExtension ext(
QuicVersion::QUIC_V1,
@ -121,6 +122,7 @@ TEST(ServerTransportParametersTest, TestQuicV1RejectDuplicateExtensions) {
EXPECT_THROW(ext.getExtensions(chlo), FizzException);
}
TEST(ServerTransportParametersTest, TestQuicV1Fields) {
ServerTransportParametersExtension ext(
QuicVersion::QUIC_V1,

View File

@ -101,10 +101,12 @@ class MockWorkerCallback : public QuicServerWorker::WorkerCallback {
class MockQuicUDPSocketFactory : public QuicUDPSocketFactory {
public:
~MockQuicUDPSocketFactory() = default;
std::unique_ptr<FollyAsyncUDPSocketAlias> make(folly::EventBase* evb, int fd)
override {
return std::unique_ptr<FollyAsyncUDPSocketAlias>(_make(evb, fd));
}
MOCK_METHOD(FollyAsyncUDPSocketAlias*, _make, (folly::EventBase*, int));
};
@ -159,6 +161,7 @@ class MockQuicServerTransport : public QuicServerTransport {
nullptr,
nullptr,
nullptr) {}
MOCK_CONST_METHOD0(getOneRttCipherInfo, CipherInfo());
MOCK_CONST_METHOD0(getServerConnectionId, Optional<ConnectionId>());
MOCK_CONST_METHOD0(getClientConnectionId, Optional<ConnectionId>());

View File

@ -52,6 +52,7 @@ class ServerTransportParameters : public testing::Test {
void SetUp() override {
qEvb_ = std::make_shared<FollyQuicEventBase>(&evb_);
}
void TearDown() override {
if (client_) {
client_->close(none);

View File

@ -4669,6 +4669,7 @@ struct FizzHandshakeParam {
: chloSync(argCHLOSync),
cfinSync(argCFINSync),
acceptZeroRtt(argAcceptZeroRtt) {}
bool chloSync;
bool cfinSync;
bool acceptZeroRtt;
@ -5694,6 +5695,7 @@ class QuicServerTransportCertTest : public QuicServerTransportTest {
std::string getIdentity() const override {
return "";
}
std::optional<std::string> getDER() const override {
return std::nullopt;
}

View File

@ -131,6 +131,7 @@ class QuicServerTransportTestBase : public virtual testing::Test {
QuicServerTransportTestBase() {
qEvb_ = std::make_shared<FollyQuicEventBase>(&evb);
}
virtual ~QuicServerTransportTestBase() = default;
void SetUp() {

Some files were not shown because too many files have changed in this diff Show More