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:
parent
9d01e09025
commit
d153b04ec4
@ -92,6 +92,7 @@ PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 200
|
||||
PointerAlignment: Left
|
||||
ReflowComments: true
|
||||
SeparateDefinitionBlocks: Always
|
||||
SortIncludes: true
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterCStyleCast: false
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -92,6 +92,7 @@ class SinglePacketInplaceBatchWriter : public IOBufBatchWriter {
|
||||
public:
|
||||
explicit SinglePacketInplaceBatchWriter(QuicConnectionStateBase& conn)
|
||||
: conn_(conn) {}
|
||||
|
||||
~SinglePacketInplaceBatchWriter() override = default;
|
||||
|
||||
void reset() override;
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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>),
|
||||
|
@ -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>));
|
||||
|
@ -753,6 +753,7 @@ TEST_F(QuicPacketSchedulerTest, DoNotCloneProcessedClonedPacket) {
|
||||
class CloneAllPacketsWithCryptoFrameTest
|
||||
: public QuicPacketSchedulerTest,
|
||||
public WithParamInterface<std::tuple<bool, bool>> {};
|
||||
|
||||
TEST_P(
|
||||
CloneAllPacketsWithCryptoFrameTest,
|
||||
TestCloneAllPacketsWithCryptoFrameTrueFalse) {
|
||||
|
@ -44,6 +44,7 @@ class QuicStreamAsyncTransportTest : public Test {
|
||||
QuicStreamAsyncTransportTest() {
|
||||
clientQuicEvb_ = std::make_shared<FollyQuicEventBase>(&clientEvb_);
|
||||
}
|
||||
|
||||
void SetUp() override {
|
||||
createServer();
|
||||
connect();
|
||||
|
@ -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());
|
||||
|
@ -67,6 +67,7 @@ class QuicTransportTest : public Test {
|
||||
QuicTransportTest() {
|
||||
qEvb_ = std::make_shared<FollyQuicEventBase>(&evb_);
|
||||
}
|
||||
|
||||
~QuicTransportTest() override = default;
|
||||
|
||||
void SetUp() override {
|
||||
|
@ -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;
|
||||
|
@ -29,6 +29,7 @@ void QuicClientAsyncTransport::onNewBidirectionalStream(
|
||||
StreamId /*id*/) noexcept {
|
||||
CHECK(false);
|
||||
}
|
||||
|
||||
void QuicClientAsyncTransport::onNewUnidirectionalStream(
|
||||
StreamId /*id*/) noexcept {
|
||||
CHECK(false);
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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_;
|
||||
|
@ -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<
|
||||
|
@ -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,
|
||||
|
@ -42,6 +42,7 @@ struct CodecParameters {
|
||||
CodecParameters(uint8_t peerAckDelayExponentIn, QuicVersion versionIn)
|
||||
: peerAckDelayExponent(peerAckDelayExponentIn), version(versionIn) {}
|
||||
};
|
||||
|
||||
struct ParsedLongHeaderInvariant {
|
||||
uint8_t initialByte;
|
||||
LongHeaderInvariant invariant;
|
||||
|
@ -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;
|
||||
|
@ -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)) {}
|
||||
};
|
||||
|
||||
|
@ -112,6 +112,7 @@ Optional<WriteAckFrameResult> writeAckFrame(
|
||||
size_t computeSizeUsedByRecvdTimestamps(quic::WriteAckFrame& writeAckFrame);
|
||||
|
||||
} // namespace quic
|
||||
|
||||
// namespace quic
|
||||
// namespace quic
|
||||
// namespace quic
|
||||
|
@ -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,
|
||||
|
@ -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) {
|
||||
|
@ -27,6 +27,7 @@ struct IntegerParams {
|
||||
};
|
||||
|
||||
class QuicIntegerDecodeTest : public TestWithParam<IntegerParams> {};
|
||||
|
||||
class QuicIntegerEncodeTest : public TestWithParam<IntegerParams> {};
|
||||
|
||||
TEST_P(QuicIntegerDecodeTest, DecodeTrim) {
|
||||
|
@ -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,
|
||||
|
@ -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) {}
|
||||
|
||||
|
@ -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>{});
|
||||
|
@ -114,6 +114,7 @@ class FunctionLooper : public QuicEventBaseLoopCallback,
|
||||
QuicTimer::SharedPtr pacingTimer_;
|
||||
TimePoint nextPacingTime_;
|
||||
const LooperType type_;
|
||||
|
||||
struct {
|
||||
bool running_ : 1;
|
||||
bool inLoopBody_ : 1;
|
||||
|
@ -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>
|
||||
|
@ -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,
|
||||
|
@ -121,9 +121,11 @@ class FollyQuicEventBase : public QuicEventBase {
|
||||
[[nodiscard]] bool isScheduled() const {
|
||||
return isScheduledImpl();
|
||||
}
|
||||
|
||||
void cancelTimeout() noexcept {
|
||||
return cancelImpl();
|
||||
}
|
||||
|
||||
QuicTimerCallback* callback_;
|
||||
};
|
||||
|
||||
|
@ -47,6 +47,7 @@ void HighResQuicTimer::scheduleTimeout(
|
||||
}
|
||||
return wheelTimer_->scheduleTimeout(wrapper, timeout);
|
||||
}
|
||||
|
||||
HighResQuicTimer::~HighResQuicTimer() {
|
||||
// Resetting the wheel timer cancels all pending timeouts.
|
||||
wheelTimer_.reset();
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
namespace {
|
||||
constexpr size_t kLen = 50;
|
||||
|
||||
template <typename T>
|
||||
void prepareDeque(T& d, size_t count) {
|
||||
size_t counter = 0;
|
||||
|
@ -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)
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
|
@ -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));
|
||||
|
@ -221,6 +221,7 @@ class FollyQuicAsyncUDPSocket : public QuicAsyncUDPSocketImpl {
|
||||
wrappedReadCallback_ = readCallback;
|
||||
parentSocket_ = parentSocket;
|
||||
}
|
||||
|
||||
void getReadBuffer(void** buf, size_t* len) noexcept override;
|
||||
|
||||
void onDataAvailable(
|
||||
|
@ -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) {}
|
||||
|
||||
|
@ -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_();
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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_;
|
||||
|
@ -29,6 +29,7 @@ struct StaticCwndCongestionController : public CongestionController {
|
||||
*/
|
||||
struct CwndInBytes {
|
||||
explicit CwndInBytes(uint64_t bytes) : bytes(bytes) {}
|
||||
|
||||
const uint64_t bytes;
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -114,6 +114,7 @@ struct PacketizationRequest {
|
||||
len(lenIn),
|
||||
fin(finIn),
|
||||
payloadOffset(payloadOffsetIn) {}
|
||||
|
||||
PacketNum packetNum;
|
||||
PacketNum largestAckedPacketNum;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 {}
|
||||
};
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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)) {}
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -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_);
|
||||
|
@ -60,6 +60,7 @@ class Handshake {
|
||||
std::string pskType;
|
||||
std::string echStatus;
|
||||
};
|
||||
|
||||
[[nodiscard]] virtual TLSSummary getTLSSummary() const = 0;
|
||||
};
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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) {
|
||||
|
@ -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(
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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(
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -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(
|
||||
|
@ -14,6 +14,7 @@ namespace {
|
||||
|
||||
using namespace quic;
|
||||
using Identifier = quic::PriorityQueue::Identifier;
|
||||
|
||||
class HTTPPriorityQueueTest : public testing::Test {
|
||||
protected:
|
||||
HTTPPriorityQueue queue_;
|
||||
|
@ -94,6 +94,7 @@ BENCHMARK(incremental, n) {
|
||||
benchmarkPriority(96, true);
|
||||
}
|
||||
}
|
||||
|
||||
BENCHMARK(sequential8, n) {
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
benchmarkPriority(8, false);
|
||||
|
@ -50,9 +50,11 @@ class QuicHandshakeSocketHolder
|
||||
}
|
||||
delete this;
|
||||
}
|
||||
|
||||
void onReplaySafe() noexcept override {
|
||||
// Unused for server
|
||||
}
|
||||
|
||||
void onTransportReady() noexcept override {
|
||||
quicSocket_->setConnectionSetupCallback(nullptr);
|
||||
if (callback_) {
|
||||
|
@ -14,6 +14,7 @@ namespace quic {
|
||||
class QuicReusePortUDPSocketFactory : public QuicUDPSocketFactory {
|
||||
public:
|
||||
~QuicReusePortUDPSocketFactory() override {}
|
||||
|
||||
QuicReusePortUDPSocketFactory(bool reusePort = true, bool reuseAddr = false)
|
||||
: reusePort_(reusePort), reuseAddr_(reuseAddr) {}
|
||||
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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; }};
|
||||
|
@ -20,6 +20,7 @@ struct GetBetterWindowsTimers {
|
||||
GetBetterWindowsTimers() {
|
||||
CHECK_EQ(timeBeginPeriod(1), TIMERR_NOERROR);
|
||||
}
|
||||
|
||||
~GetBetterWindowsTimers() {
|
||||
timeEndPeriod(1);
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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_;
|
||||
|
@ -14,6 +14,7 @@ namespace quic {
|
||||
class QuicSharedUDPSocketFactory : public QuicUDPSocketFactory {
|
||||
public:
|
||||
~QuicSharedUDPSocketFactory() override {}
|
||||
|
||||
QuicSharedUDPSocketFactory() {}
|
||||
|
||||
std::unique_ptr<FollyAsyncUDPSocketAlias> make(folly::EventBase* evb, int fd)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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";
|
||||
|
@ -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
|
||||
|
@ -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&) {}
|
||||
|
@ -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,
|
||||
|
@ -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>());
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user