Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/MoqxRelayServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,9 @@ quic::TransportSettings
buildTransportSettings(const config::QuicConfig& quic, const config::MvfstConfig& mvfst) {
// Start with MoQServer's optimized defaults, then apply config overrides.
quic::TransportSettings ts;
// WebTransport over HTTP/3 draft-16 section 3.1 requires reset_stream_at.
// Advertising support is safe for native MoQT peers that do not enable it.
ts.advertisedReliableResetStreamSupport = true;
ts.defaultCongestionController = quic::CongestionControlType::Copa;
ts.pacingEnabled = mvfst.pacingEnabled;
ts.maxCwndInMss = mvfst.maxCwndInMss;
Expand Down
5 changes: 5 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,11 @@ moqx_add_gtest(moqx_relay_context_test
moxygen::moxygen_events_moq_folly_executor_impl
)

moqx_add_gtest(moqx_relay_server_test
SRCS MoqxRelayServerTest.cpp
LIBS moqx_core moqx_test_main moxygen::moxygen_util_quic_connector
)

# Registers an integration test once per QUIC stack. The mvfst run keeps the
# plain name; the picoquic run gets a _picoquic suffix and selects the stack
# through MOQ_HARNESS_QUIC_STACK, which the Python harness and the shell tests
Expand Down
111 changes: 111 additions & 0 deletions test/MoqxRelayServerTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
* Copyright (c) OpenMOQ contributors.
* This source code is licensed under the Apache 2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

#include "MoqxRelayServer.h"

#include <folly/coro/BlockingWait.h>
#include <folly/coro/Sleep.h>
#include <folly/io/IOBuf.h>
#include <folly/portability/GTest.h>
#include <moxygen/util/InsecureVerifierDangerousDoNotUseInProduction.h>
#include <moxygen/util/QuicConnector.h>
#include <quic/client/QuicClientTransport.h>
#include <quic/state/StateData.h>

#include <chrono>
#include <memory>
#include <string>

namespace openmoq::moqx::test {
namespace {

class MoqxRelayServerTest : public ::testing::Test {
protected:
void SetUp() override {
config::ListenerConfig listener;
listener.address = folly::SocketAddress("::1", 0);
listener.tlsMode = config::Insecure{};
listener.endpoint = "/moq";
listener.moqtVersions = "18";
Comment thread
coderabbitai[bot] marked this conversation as resolved.
auto context = std::make_shared<MoqxRelayContext>(
folly::F14FastMap<std::string, config::ServiceConfig>{},
"test-relay"
);
server_ = std::make_unique<MoqxRelayServer>(listener, std::move(context), &ioExecutor_);
server_->start();
}

void TearDown() override {
if (client_) {
client_->closeNow({});
client_.reset();
}
if (server_) {
server_->stop();
server_.reset();
}
clientEvb_.loop();
}

void connect(const std::string& alpn, bool reliableResetSupport) {
quic::TransportSettings settings;
settings.advertisedReliableResetStreamSupport = reliableResetSupport;
client_ = folly::coro::blockingWait(
moxygen::QuicConnector::connectQuic(
&clientEvb_,
server_->getAddress(),
std::chrono::seconds(5),
std::make_shared<moxygen::test::InsecureVerifierDangerousDoNotUseInProduction>(),
{alpn},
settings
),
&clientEvb_
);
}

folly::EventBase clientEvb_;
folly::IOThreadPoolExecutor ioExecutor_{1};
std::unique_ptr<MoqxRelayServer> server_;
std::shared_ptr<quic::QuicClientTransport> client_;
};

TEST_F(MoqxRelayServerTest, AdvertisesReliableResetSupportForWebTransport) {
connect("h3", true);

ASSERT_NE(client_, nullptr);
ASSERT_NE(client_->getState(), nullptr);
EXPECT_TRUE(client_->getState()->peerAdvertisedReliableStreamResetSupport);
}

TEST_F(MoqxRelayServerTest, AcceptsHttp3PeerWithoutReliableResetSupport) {
connect("h3", false);

ASSERT_NE(client_, nullptr);
EXPECT_TRUE(client_->good());
}

TEST_F(MoqxRelayServerTest, ReliableResetKeepsConnectionOpen) {
connect("h3", true);
ASSERT_NE(client_, nullptr);
ASSERT_TRUE(client_->getState()->peerAdvertisedReliableStreamResetSupport);

auto stream = client_->createUnidirectionalStream();
ASSERT_TRUE(stream.has_value());
// Reserved HTTP/3 stream type 0x21, which the server must ignore.
ASSERT_TRUE(client_->writeChain(*stream, folly::IOBuf::copyBuffer("\x21reliable"), false));
ASSERT_TRUE(client_->updateReliableDeliveryCheckpoint(*stream));
ASSERT_TRUE(client_->writeChain(*stream, folly::IOBuf::copyBuffer("unreliable"), false));
ASSERT_TRUE(client_->resetStreamReliably(*stream, quic::ApplicationErrorCode(0x10c)));

folly::coro::blockingWait(folly::coro::sleep(std::chrono::seconds(1)), &clientEvb_);

EXPECT_TRUE(client_->good());
EXPECT_FALSE(client_->getState()->localConnectionError.has_value());
EXPECT_FALSE(client_->getState()->peerConnectionError.has_value());
}

} // namespace
} // namespace openmoq::moqx::test
Loading