Skip to content

Commit 1004527

Browse files
martindukecopybara-github
authored andcommitted
Allow MoqtClient and MoqtServer to control session parameters.
This will enable partial object delivery on the relay, but is generally useful functionality. PiperOrigin-RevId: 903589067
1 parent c8ff6dc commit 1004527

7 files changed

Lines changed: 106 additions & 19 deletions

File tree

quiche/quic/moqt/test_tools/moqt_session_peer.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,10 @@ class MoqtSessionPeer {
258258
static MoqtSession::ControlStream* GetControlStream(MoqtSession* session) {
259259
return session->control_stream_.GetIfAvailable();
260260
}
261+
262+
static const MoqtSessionParameters& GetParameters(MoqtSession* session) {
263+
return session->parameters_;
264+
}
261265
};
262266

263267
} // namespace moqt::test

quiche/quic/moqt/tools/moqt_client.cc

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
#include "quiche/quic/moqt/moqt_messages.h"
2222
#include "quiche/quic/moqt/moqt_quic_config.h"
2323
#include "quiche/quic/moqt/moqt_session.h"
24+
#include "quiche/quic/moqt/moqt_session_callbacks.h"
25+
#include "quiche/quic/moqt/moqt_session_interface.h"
2426
#include "quiche/quic/platform/api/quic_socket_address.h"
2527
#include "quiche/quic/tools/quic_default_client.h"
2628
#include "quiche/quic/tools/quic_event_loop_tools.h"
@@ -34,11 +36,14 @@ namespace moqt {
3436
MoqtClient::MoqtClient(quic::QuicSocketAddress peer_address,
3537
const quic::QuicServerId& server_id,
3638
std::unique_ptr<quic::ProofVerifier> proof_verifier,
37-
quic::QuicEventLoop* event_loop)
39+
quic::QuicEventLoop* event_loop,
40+
MoqtSessionParameters parameters)
3841
: spdy_client_(peer_address, server_id, GetMoqtSupportedQuicVersions(),
39-
event_loop, std::move(proof_verifier)) {
42+
event_loop, std::move(proof_verifier)),
43+
parameters_(parameters) {
4044
TuneQuicConfig(*spdy_client_.config());
4145
spdy_client_.set_enable_web_transport(true);
46+
parameters_.perspective = quic::Perspective::IS_CLIENT;
4247
}
4348

4449
void MoqtClient::Connect(std::string path, MoqtSessionCallbacks callbacks) {
@@ -101,8 +106,6 @@ absl::Status MoqtClient::ConnectInner(std::string path,
101106
return absl::InternalError("Failed to initialize WebTransport session");
102107
}
103108

104-
MoqtSessionParameters parameters(quic::Perspective::IS_CLIENT);
105-
106109
// Ensure that we never have a dangling pointer to the session.
107110
MoqtSessionDeletedCallback deleted_callback =
108111
std::move(callbacks.session_deleted_callback);
@@ -113,7 +116,7 @@ absl::Status MoqtClient::ConnectInner(std::string path,
113116
};
114117

115118
auto session = std::make_unique<MoqtSession>(
116-
web_transport, parameters,
119+
web_transport, parameters_,
117120
spdy_client_.default_network_helper()->event_loop()->CreateAlarmFactory(),
118121
std::move(callbacks));
119122
session_ = session.get();

quiche/quic/moqt/tools/moqt_client.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "quiche/quic/core/quic_session.h"
1616
#include "quiche/quic/moqt/moqt_session.h"
1717
#include "quiche/quic/moqt/moqt_session_callbacks.h"
18+
#include "quiche/quic/moqt/moqt_session_interface.h"
1819
#include "quiche/quic/platform/api/quic_socket_address.h"
1920
#include "quiche/quic/tools/quic_default_client.h"
2021
#include "quiche/common/platform/api/quiche_export.h"
@@ -27,7 +28,8 @@ class QUICHE_EXPORT MoqtClient {
2728
MoqtClient(quic::QuicSocketAddress peer_address,
2829
const quic::QuicServerId& server_id,
2930
std::unique_ptr<quic::ProofVerifier> proof_verifier,
30-
quic::QuicEventLoop* event_loop);
31+
quic::QuicEventLoop* event_loop,
32+
MoqtSessionParameters parameters = MoqtSessionParameters());
3133

3234
// Establishes the connection to the specified endpoint. The errors are
3335
// returned via the session termination callback.
@@ -40,6 +42,7 @@ class QUICHE_EXPORT MoqtClient {
4042
absl::Status ConnectInner(std::string path, MoqtSessionCallbacks& callbacks);
4143

4244
quic::QuicDefaultClient spdy_client_;
45+
MoqtSessionParameters parameters_;
4346
MoqtSession* session_ = nullptr;
4447
};
4548

quiche/quic/moqt/tools/moqt_end_to_end_test.cc

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "quiche/quic/core/io/quic_event_loop.h"
2121
#include "quiche/quic/core/quic_server_id.h"
2222
#include "quiche/quic/moqt/moqt_session.h"
23+
#include "quiche/quic/moqt/test_tools/moqt_session_peer.h"
2324
#include "quiche/quic/moqt/tools/moqt_client.h"
2425
#include "quiche/quic/moqt/tools/moqt_server.h"
2526
#include "quiche/quic/platform/api/quic_ip_address.h"
@@ -127,5 +128,50 @@ TEST_F(MoqtEndToEndTest, HandshakeFailed404) {
127128
EXPECT_TRUE(success);
128129
}
129130

131+
TEST_F(MoqtEndToEndTest, CustomParametersHandshake) {
132+
MoqtSessionParameters server_parameters;
133+
server_parameters.deliver_partial_objects = true;
134+
MoqtSession* server_session = nullptr;
135+
auto server_backend = [&](absl::string_view /*path*/)
136+
-> absl::StatusOr<MoqtConfigureSessionCallback> {
137+
return [&](MoqtSession* session) {
138+
server_session = session;
139+
session->callbacks().session_terminated_callback = [](absl::string_view) {
140+
};
141+
};
142+
};
143+
MoqtServer custom_server(
144+
quic::test::crypto_test_utils::ProofSourceForTesting(),
145+
std::move(server_backend), server_parameters);
146+
quic::QuicIpAddress host = quic::TestLoopback();
147+
QUICHE_CHECK_OK(custom_server.CreateUDPSocketAndListen(
148+
quic::QuicSocketAddress(host, /*port=*/0)));
149+
quic::QuicSocketAddress custom_server_address(host, custom_server.port());
150+
151+
MoqtSessionParameters client_parameters;
152+
client_parameters.max_request_id = 200;
153+
MoqtClient client(custom_server_address,
154+
quic::QuicServerId("test.example.com", 443),
155+
quic::test::crypto_test_utils::ProofVerifierForTesting(),
156+
custom_server.event_loop(), client_parameters);
157+
158+
MoqtSessionCallbacks callbacks;
159+
bool established = false;
160+
callbacks.session_established_callback = [&] { established = true; };
161+
callbacks.session_terminated_callback = UnexpectedClose;
162+
client.Connect("/test", std::move(callbacks));
163+
164+
bool success = quic::ProcessEventsUntil(custom_server.event_loop(), [&] {
165+
return established && server_session != nullptr;
166+
});
167+
EXPECT_TRUE(success);
168+
ASSERT_NE(client.session(), nullptr);
169+
EXPECT_EQ(MoqtSessionPeer::GetParameters(client.session()).max_request_id,
170+
200);
171+
ASSERT_NE(server_session, nullptr);
172+
EXPECT_TRUE(
173+
MoqtSessionPeer::GetParameters(server_session).deliver_partial_objects);
174+
}
175+
130176
} // namespace
131177
} // namespace moqt::test

quiche/quic/moqt/tools/moqt_server.cc

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@
2727
#include "quiche/quic/core/quic_time.h"
2828
#include "quiche/quic/core/quic_types.h"
2929
#include "quiche/quic/core/quic_versions.h"
30-
#include "quiche/quic/moqt/moqt_messages.h"
3130
#include "quiche/quic/moqt/moqt_quic_config.h"
3231
#include "quiche/quic/moqt/moqt_session.h"
32+
#include "quiche/quic/moqt/moqt_session_interface.h"
3333
#include "quiche/quic/platform/api/quic_socket_address.h"
3434
#include "quiche/quic/tools/quic_simple_crypto_server_stream_helper.h"
3535
#include "quiche/common/quiche_status_utils.h"
@@ -47,8 +47,10 @@ std::string GenerateRandomTokenSecret() {
4747
}
4848

4949
quic::WebTransportHandlerFactoryCallback CreateWebTransportCallback(
50-
MoqtIncomingSessionCallback callback, quic::QuicEventLoop* event_loop) {
51-
return [event_loop = event_loop, callback = std::move(callback)](
50+
MoqtIncomingSessionCallback callback, quic::QuicEventLoop* event_loop,
51+
const MoqtSessionParameters& session_parameters) {
52+
return [event_loop = event_loop, callback = std::move(callback),
53+
parameters = session_parameters](
5254
webtransport::Session* session,
5355
const quic::WebTransportIncomingRequestDetails& details)
5456
-> absl::StatusOr<quic::WebTransportConnectResponse> {
@@ -58,8 +60,6 @@ quic::WebTransportHandlerFactoryCallback CreateWebTransportCallback(
5860
if (!configurator.ok()) {
5961
return configurator.status();
6062
}
61-
62-
MoqtSessionParameters parameters(quic::Perspective::IS_SERVER);
6363
auto moqt_session = std::make_unique<MoqtSession>(
6464
session, parameters, event_loop->CreateAlarmFactory());
6565
std::move (*configurator)(moqt_session.get());
@@ -72,7 +72,8 @@ quic::WebTransportHandlerFactoryCallback CreateWebTransportCallback(
7272
} // namespace
7373

7474
MoqtServer::MoqtServer(std::unique_ptr<quic::ProofSource> proof_source,
75-
MoqtIncomingSessionCallback callback)
75+
MoqtIncomingSessionCallback callback,
76+
MoqtSessionParameters session_parameters)
7677
: config_(GenerateQuicConfig()),
7778
crypto_config_(GenerateRandomTokenSecret(),
7879
quic::QuicRandom::GetInstance(), std::move(proof_source),
@@ -86,9 +87,11 @@ MoqtServer::MoqtServer(std::unique_ptr<quic::ProofSource> proof_source,
8687
std::make_unique<quic::QuicSimpleCryptoServerStreamHelper>(),
8788
event_loop_->CreateAlarmFactory(),
8889
quic::kQuicDefaultConnectionIdLength,
89-
connection_id_generator_) {
90-
dispatcher_.parameters().handler_factory =
91-
CreateWebTransportCallback(std::move(callback), event_loop_.get());
90+
connection_id_generator_),
91+
session_parameters_(session_parameters) {
92+
session_parameters_.perspective = quic::Perspective::IS_SERVER;
93+
dispatcher_.parameters().handler_factory = CreateWebTransportCallback(
94+
std::move(callback), event_loop_.get(), session_parameters_);
9295
dispatcher_.parameters().subprotocol_callback =
9396
+[](absl::Span<const absl::string_view> subprotocols) {
9497
return absl::c_find(subprotocols, kDefaultMoqtVersion) -

quiche/quic/moqt/tools/moqt_server.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "quiche/quic/core/quic_config.h"
2222
#include "quiche/quic/core/quic_version_manager.h"
2323
#include "quiche/quic/moqt/moqt_session.h"
24+
#include "quiche/quic/moqt/moqt_session_interface.h"
2425
#include "quiche/quic/platform/api/quic_socket_address.h"
2526
#include "quiche/common/platform/api/quiche_export.h"
2627
#include "quiche/common/quiche_callbacks.h"
@@ -43,8 +44,10 @@ using MoqtIncomingSessionCallback =
4344
// A simple MoQT server.
4445
class QUICHE_EXPORT MoqtServer {
4546
public:
46-
explicit MoqtServer(std::unique_ptr<quic::ProofSource> proof_source,
47-
MoqtIncomingSessionCallback callback);
47+
explicit MoqtServer(
48+
std::unique_ptr<quic::ProofSource> proof_source,
49+
MoqtIncomingSessionCallback callback,
50+
MoqtSessionParameters session_parameters = MoqtSessionParameters());
4851

4952
MoqtServer(const MoqtServer&) = delete;
5053
MoqtServer(MoqtServer&&) = delete;
@@ -65,6 +68,7 @@ class QUICHE_EXPORT MoqtServer {
6568
quic::DeterministicConnectionIdGenerator connection_id_generator_;
6669
std::unique_ptr<quic::QuicEventLoop> event_loop_;
6770
quic::WebTransportOnlyDispatcher dispatcher_;
71+
MoqtSessionParameters session_parameters_;
6872

6973
quic::OwnedSocketFd fd_;
7074
std::unique_ptr<quic::QuicServerIoHarness> io_;

quiche/quic/moqt/tools/moqt_server_test.cc

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,19 @@
66

77
#include <utility>
88

9-
#include "absl/base/nullability.h"
109
#include "absl/memory/memory.h"
1110
#include "absl/status/statusor.h"
1211
#include "absl/strings/string_view.h"
1312
#include "quiche/quic/core/http/web_transport_only_server_session.h"
1413
#include "quiche/quic/core/quic_alarm.h"
1514
#include "quiche/quic/core/quic_time.h"
15+
#include "quiche/quic/core/quic_types.h"
1616
#include "quiche/quic/moqt/moqt_session.h"
17+
#include "quiche/quic/moqt/moqt_session_interface.h"
1718
#include "quiche/quic/moqt/test_tools/moqt_session_peer.h"
1819
#include "quiche/quic/platform/api/quic_socket_address.h"
1920
#include "quiche/quic/platform/api/quic_test.h"
2021
#include "quiche/quic/test_tools/crypto_test_utils.h"
21-
#include "quiche/quic/tools/web_transport_only_backend.h"
2222
#include "quiche/common/http/http_header_block.h"
2323
#include "quiche/common/quiche_ip_address.h"
2424
#include "quiche/common/test_tools/quiche_test_utils.h"
@@ -79,4 +79,28 @@ TEST_F(MoqtServerTest, NewSessionHasAlarmFactory) {
7979
EXPECT_TRUE(alarm->IsSet());
8080
}
8181

82+
TEST_F(MoqtServerTest, CustomSessionParameters) {
83+
MoqtSessionParameters parameters;
84+
parameters.deliver_partial_objects = true;
85+
parameters.perspective = quic::Perspective::IS_CLIENT;
86+
MoqtServer server(
87+
quic::test::crypto_test_utils::ProofSourceForTesting(),
88+
[&](absl::string_view /*path*/) {
89+
return [&](MoqtSession* session) { session_ = session; };
90+
},
91+
parameters);
92+
quiche::HttpHeaderBlock headers;
93+
headers.AppendValueOrAddHeader(":path", "/foo");
94+
absl::StatusOr<quic::WebTransportConnectResponse> response =
95+
MoqtServerPeer::CallHandlerFactory(
96+
server, &mock_session_,
97+
quic::WebTransportIncomingRequestDetails{.headers =
98+
std::move(headers)});
99+
QUICHE_EXPECT_OK(response.status());
100+
ASSERT_NE(session_, nullptr);
101+
EXPECT_TRUE(MoqtSessionPeer::GetParameters(session_).deliver_partial_objects);
102+
EXPECT_EQ(MoqtSessionPeer::GetParameters(session_).perspective,
103+
quic::Perspective::IS_SERVER);
104+
}
105+
82106
} // namespace moqt::test

0 commit comments

Comments
 (0)