Update MOQT to draft-03 wire image. Does not add ANNOUNCE_CANCEL because it does not have a code point. Not in production PiperOrigin-RevId: 615417995
diff --git a/quiche/quic/moqt/moqt_framer.cc b/quiche/quic/moqt/moqt_framer.cc index 9137418..05a0440 100644 --- a/quiche/quic/moqt/moqt_framer.cc +++ b/quiche/quic/moqt/moqt_framer.cc
@@ -34,6 +34,7 @@ using ::quiche::WireOptional; using ::quiche::WireSpan; using ::quiche::WireStringWithVarInt62Length; +using ::quiche::WireUint8; using ::quiche::WireVarInt62; // Encoding for MOQT Locations: @@ -288,9 +289,17 @@ quiche::QuicheBuffer MoqtFramer::SerializeSubscribeOk( const MoqtSubscribeOk& message) { + if (message.largest_id.has_value()) { + return Serialize(WireVarInt62(MoqtMessageType::kSubscribeOk), + WireVarInt62(message.subscribe_id), + WireVarInt62(message.expires.ToMilliseconds()), + WireUint8(1), WireVarInt62(message.largest_id->group), + WireVarInt62(message.largest_id->object)); + } return Serialize(WireVarInt62(MoqtMessageType::kSubscribeOk), WireVarInt62(message.subscribe_id), - WireVarInt62(message.expires.ToMilliseconds())); + WireVarInt62(message.expires.ToMilliseconds()), + WireUint8(0)); } quiche::QuicheBuffer MoqtFramer::SerializeSubscribeError( @@ -308,21 +317,20 @@ WireVarInt62(message.subscribe_id)); } -quiche::QuicheBuffer MoqtFramer::SerializeSubscribeFin( - const MoqtSubscribeFin& message) { - return Serialize(WireVarInt62(MoqtMessageType::kSubscribeFin), - WireVarInt62(message.subscribe_id), - WireVarInt62(message.final_group), - WireVarInt62(message.final_object)); -} - -quiche::QuicheBuffer MoqtFramer::SerializeSubscribeRst( - const MoqtSubscribeRst& message) { +quiche::QuicheBuffer MoqtFramer::SerializeSubscribeDone( + const MoqtSubscribeDone& message) { + if (message.final_id.has_value()) { + return Serialize(WireVarInt62(MoqtMessageType::kSubscribeDone), + WireVarInt62(message.subscribe_id), + WireVarInt62(message.status_code), + WireStringWithVarInt62Length(message.reason_phrase), + WireUint8(1), WireVarInt62(message.final_id->group), + WireVarInt62(message.final_id->object)); + } return Serialize( - WireVarInt62(MoqtMessageType::kSubscribeRst), - WireVarInt62(message.subscribe_id), WireVarInt62(message.error_code), - WireStringWithVarInt62Length(message.reason_phrase), - WireVarInt62(message.final_group), WireVarInt62(message.final_object)); + WireVarInt62(MoqtMessageType::kSubscribeDone), + WireVarInt62(message.subscribe_id), WireVarInt62(message.status_code), + WireStringWithVarInt62Length(message.reason_phrase), WireUint8(0)); } quiche::QuicheBuffer MoqtFramer::SerializeAnnounce(
diff --git a/quiche/quic/moqt/moqt_framer.h b/quiche/quic/moqt/moqt_framer.h index bf17364..7f19fa8 100644 --- a/quiche/quic/moqt/moqt_framer.h +++ b/quiche/quic/moqt/moqt_framer.h
@@ -46,8 +46,7 @@ quiche::QuicheBuffer SerializeSubscribeError( const MoqtSubscribeError& message); quiche::QuicheBuffer SerializeUnsubscribe(const MoqtUnsubscribe& message); - quiche::QuicheBuffer SerializeSubscribeFin(const MoqtSubscribeFin& message); - quiche::QuicheBuffer SerializeSubscribeRst(const MoqtSubscribeRst& message); + quiche::QuicheBuffer SerializeSubscribeDone(const MoqtSubscribeDone& message); quiche::QuicheBuffer SerializeAnnounce(const MoqtAnnounce& message); quiche::QuicheBuffer SerializeAnnounceOk(const MoqtAnnounceOk& message); quiche::QuicheBuffer SerializeAnnounceError(const MoqtAnnounceError& message);
diff --git a/quiche/quic/moqt/moqt_framer_test.cc b/quiche/quic/moqt/moqt_framer_test.cc index 36ab8ea..607e1db 100644 --- a/quiche/quic/moqt/moqt_framer_test.cc +++ b/quiche/quic/moqt/moqt_framer_test.cc
@@ -35,8 +35,7 @@ MoqtMessageType::kSubscribeOk, MoqtMessageType::kSubscribeError, MoqtMessageType::kUnsubscribe, - MoqtMessageType::kSubscribeFin, - MoqtMessageType::kSubscribeRst, + MoqtMessageType::kSubscribeDone, MoqtMessageType::kAnnounce, MoqtMessageType::kAnnounceOk, MoqtMessageType::kAnnounceError, @@ -126,13 +125,9 @@ auto data = std::get<MoqtUnsubscribe>(structured_data); return framer_.SerializeUnsubscribe(data); } - case MoqtMessageType::kSubscribeFin: { - auto data = std::get<MoqtSubscribeFin>(structured_data); - return framer_.SerializeSubscribeFin(data); - } - case MoqtMessageType::kSubscribeRst: { - auto data = std::get<MoqtSubscribeRst>(structured_data); - return framer_.SerializeSubscribeRst(data); + case MoqtMessageType::kSubscribeDone: { + auto data = std::get<MoqtSubscribeDone>(structured_data); + return framer_.SerializeSubscribeDone(data); } case MoqtMessageType::kAnnounce: { auto data = std::get<MoqtAnnounce>(structured_data);
diff --git a/quiche/quic/moqt/moqt_integration_test.cc b/quiche/quic/moqt/moqt_integration_test.cc index 2905bd2..8691be6 100644 --- a/quiche/quic/moqt/moqt_integration_test.cc +++ b/quiche/quic/moqt/moqt_integration_test.cc
@@ -120,9 +120,9 @@ public: void CreateDefaultEndpoints() { client_ = std::make_unique<ClientEndpoint>( - &test_harness_.simulator(), "Client", "Server", MoqtVersion::kDraft02); + &test_harness_.simulator(), "Client", "Server", MoqtVersion::kDraft03); server_ = std::make_unique<ServerEndpoint>( - &test_harness_.simulator(), "Server", "Client", MoqtVersion::kDraft02); + &test_harness_.simulator(), "Server", "Client", MoqtVersion::kDraft03); test_harness_.set_client(client_.get()); test_harness_.set_server(server_.get()); } @@ -173,7 +173,7 @@ &test_harness_.simulator(), "Client", "Server", MoqtVersion::kUnrecognizedVersionForTests); server_ = std::make_unique<ServerEndpoint>( - &test_harness_.simulator(), "Server", "Client", MoqtVersion::kDraft02); + &test_harness_.simulator(), "Server", "Client", MoqtVersion::kDraft03); test_harness_.set_client(client_.get()); test_harness_.set_server(server_.get()); WireUpEndpoints();
diff --git a/quiche/quic/moqt/moqt_messages.cc b/quiche/quic/moqt/moqt_messages.cc index ab18885..fba312b 100644 --- a/quiche/quic/moqt/moqt_messages.cc +++ b/quiche/quic/moqt/moqt_messages.cc
@@ -28,10 +28,8 @@ return "SUBSCRIBE_ERROR"; case MoqtMessageType::kUnsubscribe: return "UNSUBSCRIBE"; - case MoqtMessageType::kSubscribeFin: - return "SUBSCRIBE_FIN"; - case MoqtMessageType::kSubscribeRst: - return "SUBSCRIBE_RST"; + case MoqtMessageType::kSubscribeDone: + return "SUBSCRIBE_DONE"; case MoqtMessageType::kAnnounce: return "ANNOUNCE"; case MoqtMessageType::kAnnounceOk:
diff --git a/quiche/quic/moqt/moqt_messages.h b/quiche/quic/moqt/moqt_messages.h index 67c9f1c..eef04cc 100644 --- a/quiche/quic/moqt/moqt_messages.h +++ b/quiche/quic/moqt/moqt_messages.h
@@ -27,7 +27,7 @@ } enum class MoqtVersion : uint64_t { - kDraft02 = 0xff000002, + kDraft03 = 0xff000003, kUnrecognizedVersionForTests = 0xfe0000ff, }; @@ -57,8 +57,7 @@ kAnnounceError = 0x08, kUnannounce = 0x09, kUnsubscribe = 0x0a, - kSubscribeFin = 0x0b, - kSubscribeRst = 0x0c, + kSubscribeDone = 0x0b, kGoAway = 0x10, kClientSetup = 0x40, kServerSetup = 0x41, @@ -251,6 +250,8 @@ uint64_t subscribe_id; // The message uses ms, but expires is in us. quic::QuicTimeDelta expires = quic::QuicTimeDelta::FromMilliseconds(0); + // If ContextExists on the wire is zero, largest_id has no value. + std::optional<FullSequence> largest_id; }; enum class QUICHE_EXPORT SubscribeErrorCode : uint64_t { @@ -270,18 +271,21 @@ uint64_t subscribe_id; }; -struct QUICHE_EXPORT MoqtSubscribeFin { - uint64_t subscribe_id; - uint64_t final_group; - uint64_t final_object; +enum class QUICHE_EXPORT SubscribeDoneCode : uint64_t { + kUnsubscribed = 0x0, + kInternalError = 0x1, + kUnauthorized = 0x2, + kTrackEnded = 0x3, + kSubscriptionEnded = 0x4, + kGoingAway = 0x5, + kExpired = 0x6, }; -struct QUICHE_EXPORT MoqtSubscribeRst { +struct QUICHE_EXPORT MoqtSubscribeDone { uint64_t subscribe_id; - uint64_t error_code; + uint64_t status_code; std::string reason_phrase; - uint64_t final_group; - uint64_t final_object; + std::optional<FullSequence> final_id; }; struct QUICHE_EXPORT MoqtAnnounce {
diff --git a/quiche/quic/moqt/moqt_parser.cc b/quiche/quic/moqt/moqt_parser.cc index 616a9ed..1e8cf8a 100644 --- a/quiche/quic/moqt/moqt_parser.cc +++ b/quiche/quic/moqt/moqt_parser.cc
@@ -166,10 +166,8 @@ return ProcessSubscribeError(reader); case MoqtMessageType::kUnsubscribe: return ProcessUnsubscribe(reader); - case MoqtMessageType::kSubscribeFin: - return ProcessSubscribeFin(reader); - case MoqtMessageType::kSubscribeRst: - return ProcessSubscribeRst(reader); + case MoqtMessageType::kSubscribeDone: + return ProcessSubscribeDone(reader); case MoqtMessageType::kAnnounce: return ProcessAnnounce(reader); case MoqtMessageType::kAnnounceOk: @@ -434,11 +432,24 @@ size_t MoqtParser::ProcessSubscribeOk(quic::QuicDataReader& reader) { MoqtSubscribeOk subscribe_ok; uint64_t milliseconds; + uint8_t content_exists; if (!reader.ReadVarInt62(&subscribe_ok.subscribe_id) || - !reader.ReadVarInt62(&milliseconds)) { + !reader.ReadVarInt62(&milliseconds) || + !reader.ReadUInt8(&content_exists)) { + return 0; + } + if (content_exists > 1) { + ParseError("SUBSCRIBE_OK ContentExists has invalid value"); return 0; } subscribe_ok.expires = quic::QuicTimeDelta::FromMilliseconds(milliseconds); + if (content_exists) { + subscribe_ok.largest_id = FullSequence(); + if (!reader.ReadVarInt62(&subscribe_ok.largest_id->group) || + !reader.ReadVarInt62(&subscribe_ok.largest_id->object)) { + return 0; + } + } visitor_.OnSubscribeOkMessage(subscribe_ok); return reader.PreviouslyReadPayload().length(); } @@ -466,27 +477,27 @@ return reader.PreviouslyReadPayload().length(); } -size_t MoqtParser::ProcessSubscribeFin(quic::QuicDataReader& reader) { - MoqtSubscribeFin subscribe_fin; - if (!reader.ReadVarInt62(&subscribe_fin.subscribe_id) || - !reader.ReadVarInt62(&subscribe_fin.final_group) || - !reader.ReadVarInt62(&subscribe_fin.final_object)) { +size_t MoqtParser::ProcessSubscribeDone(quic::QuicDataReader& reader) { + MoqtSubscribeDone subscribe_done; + uint8_t content_exists; + if (!reader.ReadVarInt62(&subscribe_done.subscribe_id) || + !reader.ReadVarInt62(&subscribe_done.status_code) || + !reader.ReadStringVarInt62(subscribe_done.reason_phrase) || + !reader.ReadUInt8(&content_exists)) { return 0; } - visitor_.OnSubscribeFinMessage(subscribe_fin); - return reader.PreviouslyReadPayload().length(); -} - -size_t MoqtParser::ProcessSubscribeRst(quic::QuicDataReader& reader) { - MoqtSubscribeRst subscribe_rst; - if (!reader.ReadVarInt62(&subscribe_rst.subscribe_id) || - !reader.ReadVarInt62(&subscribe_rst.error_code) || - !reader.ReadStringVarInt62(subscribe_rst.reason_phrase) || - !reader.ReadVarInt62(&subscribe_rst.final_group) || - !reader.ReadVarInt62(&subscribe_rst.final_object)) { + if (content_exists > 1) { + ParseError("SUBSCRIBE_DONE ContentExists has invalid value"); return 0; } - visitor_.OnSubscribeRstMessage(subscribe_rst); + if (content_exists == 1) { + subscribe_done.final_id = FullSequence(); + if (!reader.ReadVarInt62(&subscribe_done.final_id->group) || + !reader.ReadVarInt62(&subscribe_done.final_id->object)) { + return 0; + } + } + visitor_.OnSubscribeDoneMessage(subscribe_done); return reader.PreviouslyReadPayload().length(); }
diff --git a/quiche/quic/moqt/moqt_parser.h b/quiche/quic/moqt/moqt_parser.h index 4cd19ca..084e6fe 100644 --- a/quiche/quic/moqt/moqt_parser.h +++ b/quiche/quic/moqt/moqt_parser.h
@@ -38,8 +38,7 @@ virtual void OnSubscribeOkMessage(const MoqtSubscribeOk& message) = 0; virtual void OnSubscribeErrorMessage(const MoqtSubscribeError& message) = 0; virtual void OnUnsubscribeMessage(const MoqtUnsubscribe& message) = 0; - virtual void OnSubscribeFinMessage(const MoqtSubscribeFin& message) = 0; - virtual void OnSubscribeRstMessage(const MoqtSubscribeRst& message) = 0; + virtual void OnSubscribeDoneMessage(const MoqtSubscribeDone& message) = 0; virtual void OnAnnounceMessage(const MoqtAnnounce& message) = 0; virtual void OnAnnounceOkMessage(const MoqtAnnounceOk& message) = 0; virtual void OnAnnounceErrorMessage(const MoqtAnnounceError& message) = 0; @@ -90,8 +89,7 @@ size_t ProcessSubscribeOk(quic::QuicDataReader& reader); size_t ProcessSubscribeError(quic::QuicDataReader& reader); size_t ProcessUnsubscribe(quic::QuicDataReader& reader); - size_t ProcessSubscribeFin(quic::QuicDataReader& reader); - size_t ProcessSubscribeRst(quic::QuicDataReader& reader); + size_t ProcessSubscribeDone(quic::QuicDataReader& reader); size_t ProcessAnnounce(quic::QuicDataReader& reader); size_t ProcessAnnounceOk(quic::QuicDataReader& reader); size_t ProcessAnnounceError(quic::QuicDataReader& reader);
diff --git a/quiche/quic/moqt/moqt_parser_test.cc b/quiche/quic/moqt/moqt_parser_test.cc index 3572ae8..9d0f992 100644 --- a/quiche/quic/moqt/moqt_parser_test.cc +++ b/quiche/quic/moqt/moqt_parser_test.cc
@@ -42,8 +42,7 @@ MoqtMessageType::kSubscribeOk, MoqtMessageType::kSubscribeError, MoqtMessageType::kUnsubscribe, - MoqtMessageType::kSubscribeFin, - MoqtMessageType::kSubscribeRst, + MoqtMessageType::kSubscribeDone, MoqtMessageType::kAnnounce, MoqtMessageType::kAnnounceOk, MoqtMessageType::kAnnounceError, @@ -129,10 +128,7 @@ void OnUnsubscribeMessage(const MoqtUnsubscribe& message) override { OnControlMessage(message); } - void OnSubscribeFinMessage(const MoqtSubscribeFin& message) override { - OnControlMessage(message); - } - void OnSubscribeRstMessage(const MoqtSubscribeRst& message) override { + void OnSubscribeDoneMessage(const MoqtSubscribeDone& message) override { OnControlMessage(message); } void OnAnnounceMessage(const MoqtAnnounce& message) override { @@ -868,4 +864,26 @@ EXPECT_TRUE(payload.empty()); } +TEST_F(MoqtMessageSpecificTest, SubscribeOkInvalidContentExists) { + MoqtParser parser(kRawQuic, visitor_); + SubscribeOkMessage subscribe_ok; + subscribe_ok.SetInvalidContentExists(); + parser.ProcessData(subscribe_ok.PacketSample(), false); + EXPECT_EQ(visitor_.messages_received_, 0); + EXPECT_TRUE(visitor_.parsing_error_.has_value()); + EXPECT_EQ(*visitor_.parsing_error_, + "SUBSCRIBE_OK ContentExists has invalid value"); +} + +TEST_F(MoqtMessageSpecificTest, SubscribeDoneInvalidContentExists) { + MoqtParser parser(kRawQuic, visitor_); + SubscribeDoneMessage subscribe_done; + subscribe_done.SetInvalidContentExists(); + parser.ProcessData(subscribe_done.PacketSample(), false); + EXPECT_EQ(visitor_.messages_received_, 0); + EXPECT_TRUE(visitor_.parsing_error_.has_value()); + EXPECT_EQ(*visitor_.parsing_error_, + "SUBSCRIBE_DONE ContentExists has invalid value"); +} + } // namespace moqt::test
diff --git a/quiche/quic/moqt/moqt_session.cc b/quiche/quic/moqt/moqt_session.cc index 3442e04..dcbbf61 100644 --- a/quiche/quic/moqt/moqt_session.cc +++ b/quiche/quic/moqt/moqt_session.cc
@@ -734,6 +734,7 @@ for (auto& [name, track] : session_->local_tracks_) { track.DeleteWindow(message.subscribe_id); } + // TODO(martinduke): Send SUBSCRIBE_DONE in response. } void MoqtSession::Stream::OnAnnounceMessage(const MoqtAnnounce& message) {
diff --git a/quiche/quic/moqt/moqt_session.h b/quiche/quic/moqt/moqt_session.h index 48504b7..08eb658 100644 --- a/quiche/quic/moqt/moqt_session.h +++ b/quiche/quic/moqt/moqt_session.h
@@ -168,8 +168,8 @@ void OnSubscribeOkMessage(const MoqtSubscribeOk& message) override; void OnSubscribeErrorMessage(const MoqtSubscribeError& message) override; void OnUnsubscribeMessage(const MoqtUnsubscribe& message) override; - void OnSubscribeFinMessage(const MoqtSubscribeFin& /*message*/) override {} - void OnSubscribeRstMessage(const MoqtSubscribeRst& /*message*/) override {} + void OnSubscribeDoneMessage(const MoqtSubscribeDone& /*message*/) override { + } void OnAnnounceMessage(const MoqtAnnounce& message) override; void OnAnnounceOkMessage(const MoqtAnnounceOk& message) override; void OnAnnounceErrorMessage(const MoqtAnnounceError& message) override;
diff --git a/quiche/quic/moqt/moqt_session_test.cc b/quiche/quic/moqt/moqt_session_test.cc index dfc0336..5cac2fe 100644 --- a/quiche/quic/moqt/moqt_session_test.cc +++ b/quiche/quic/moqt/moqt_session_test.cc
@@ -42,7 +42,7 @@ constexpr webtransport::StreamId kOutgoingUniStreamId = 14; constexpr MoqtSessionParameters default_parameters = { - /*version=*/MoqtVersion::kDraft02, + /*version=*/MoqtVersion::kDraft03, /*perspective=*/quic::Perspective::IS_CLIENT, /*using_webtrans=*/true, /*path=*/std::string(), @@ -185,7 +185,7 @@ &session_, visitor.get()); // Handle the server setup MoqtServerSetup setup = { - MoqtVersion::kDraft02, + MoqtVersion::kDraft03, MoqtRole::kPubSub, }; EXPECT_CALL(session_callbacks_.session_established_callback, Call()).Times(1); @@ -194,7 +194,7 @@ TEST_F(MoqtSessionTest, OnClientSetup) { MoqtSessionParameters server_parameters = { - /*version=*/MoqtVersion::kDraft02, + /*version=*/MoqtVersion::kDraft03, /*perspective=*/quic::Perspective::IS_SERVER, /*using_webtrans=*/true, /*path=*/"", @@ -206,7 +206,7 @@ std::unique_ptr<MoqtParserVisitor> stream_input = MoqtSessionPeer::CreateControlStream(&server_session, &mock_stream); MoqtClientSetup setup = { - /*supported_versions=*/{MoqtVersion::kDraft02}, + /*supported_versions=*/{MoqtVersion::kDraft03}, /*role=*/MoqtRole::kPubSub, /*path=*/std::nullopt, }; @@ -607,7 +607,7 @@ TEST_F(MoqtSessionTest, IncomingPartialObjectNoBuffer) { MoqtSessionParameters parameters = { - /*version=*/MoqtVersion::kDraft02, + /*version=*/MoqtVersion::kDraft03, /*perspective=*/quic::Perspective::IS_CLIENT, /*using_webtrans=*/true, /*path=*/"", @@ -685,6 +685,7 @@ MoqtSubscribeOk ok = { /*subscribe_id=*/1, /*expires=*/quic::QuicTimeDelta::FromMilliseconds(0), + /*largest_id=*/std::nullopt, }; StrictMock<webtransport::test::MockStream> mock_control_stream; std::unique_ptr<MoqtParserVisitor> control_stream = @@ -853,6 +854,7 @@ MoqtSubscribeOk ok = { /*subscribe_id=*/1, /*expires=*/quic::QuicTimeDelta::FromMilliseconds(0), + /*largest_id=*/std::nullopt, }; StrictMock<webtransport::test::MockStream> mock_control_stream; std::unique_ptr<MoqtParserVisitor> control_stream = @@ -1016,7 +1018,7 @@ TEST_F(MoqtSessionTest, OneBidirectionalStreamServer) { MoqtSessionParameters server_parameters = { - /*version=*/MoqtVersion::kDraft02, + /*version=*/MoqtVersion::kDraft03, /*perspective=*/quic::Perspective::IS_SERVER, /*using_webtrans=*/true, /*path=*/"", @@ -1028,7 +1030,7 @@ std::unique_ptr<MoqtParserVisitor> stream_input = MoqtSessionPeer::CreateControlStream(&server_session, &mock_stream); MoqtClientSetup setup = { - /*supported_versions*/ {MoqtVersion::kDraft02}, + /*supported_versions*/ {MoqtVersion::kDraft03}, /*role=*/MoqtRole::kPubSub, /*path=*/std::nullopt, };
diff --git a/quiche/quic/moqt/test_tools/moqt_test_message.h b/quiche/quic/moqt/test_tools/moqt_test_message.h index 156b874..98dee0f 100644 --- a/quiche/quic/moqt/test_tools/moqt_test_message.h +++ b/quiche/quic/moqt/test_tools/moqt_test_message.h
@@ -36,9 +36,9 @@ typedef absl::variant<MoqtClientSetup, MoqtServerSetup, MoqtObject, MoqtSubscribe, MoqtSubscribeOk, MoqtSubscribeError, - MoqtUnsubscribe, MoqtSubscribeFin, MoqtSubscribeRst, - MoqtAnnounce, MoqtAnnounceOk, MoqtAnnounceError, - MoqtUnannounce, MoqtGoAway> + MoqtUnsubscribe, MoqtSubscribeDone, MoqtAnnounce, + MoqtAnnounceOk, MoqtAnnounceError, MoqtUnannounce, + MoqtGoAway> MessageStructuredData; // The total actual size of the message. @@ -513,23 +513,34 @@ QUIC_LOG(INFO) << "SUBSCRIBE OK expiration mismatch"; return false; } + if (cast.largest_id != subscribe_ok_.largest_id) { + QUIC_LOG(INFO) << "SUBSCRIBE OK largest ID mismatch"; + return false; + } return true; } - void ExpandVarints() override { ExpandVarintsImpl("vvv"); } + void ExpandVarints() override { ExpandVarintsImpl("vvv-vv"); } MessageStructuredData structured_data() const override { return TestMessageBase::MessageStructuredData(subscribe_ok_); } + void SetInvalidContentExists() { + raw_packet_[3] = 0x02; + SetWireImage(raw_packet_, sizeof(raw_packet_)); + } + private: - uint8_t raw_packet_[3] = { + uint8_t raw_packet_[6] = { 0x04, 0x01, 0x03, // subscribe_id = 1, expires = 3 + 0x01, 0x0c, 0x14, // largest_group_id = 12, largest_object_id = 20, }; MoqtSubscribeOk subscribe_ok_ = { /*subscribe_id=*/1, /*expires=*/quic::QuicTimeDelta::FromMilliseconds(3), + /*largest_id=*/FullSequence(12, 20), }; }; @@ -613,101 +624,56 @@ }; }; -class QUICHE_NO_EXPORT SubscribeFinMessage : public TestMessageBase { +class QUICHE_NO_EXPORT SubscribeDoneMessage : public TestMessageBase { public: - SubscribeFinMessage() : TestMessageBase(MoqtMessageType::kSubscribeFin) { + SubscribeDoneMessage() : TestMessageBase(MoqtMessageType::kSubscribeDone) { SetWireImage(raw_packet_, sizeof(raw_packet_)); } bool EqualFieldValues(MessageStructuredData& values) const override { - auto cast = std::get<MoqtSubscribeFin>(values); - if (cast.subscribe_id != subscribe_fin_.subscribe_id) { - QUIC_LOG(INFO) << "SUBSCRIBE_FIN subscribe ID mismatch"; + auto cast = std::get<MoqtSubscribeDone>(values); + if (cast.subscribe_id != subscribe_done_.subscribe_id) { + QUIC_LOG(INFO) << "SUBSCRIBE_DONE subscribe ID mismatch"; return false; } - if (cast.final_group != subscribe_fin_.final_group) { - QUIC_LOG(INFO) << "SUBSCRIBE_FIN final group mismatch"; + if (cast.status_code != subscribe_done_.status_code) { + QUIC_LOG(INFO) << "SUBSCRIBE_DONE status code mismatch"; return false; } - if (cast.final_object != subscribe_fin_.final_object) { - QUIC_LOG(INFO) << "SUBSCRIBE_FIN final object mismatch"; + if (cast.reason_phrase != subscribe_done_.reason_phrase) { + QUIC_LOG(INFO) << "SUBSCRIBE_DONE reason phrase mismatch"; + return false; + } + if (cast.final_id != subscribe_done_.final_id) { + QUIC_LOG(INFO) << "SUBSCRIBE_DONE final ID mismatch"; return false; } return true; } - void ExpandVarints() override { ExpandVarintsImpl("vvvv"); } + void ExpandVarints() override { ExpandVarintsImpl("vvvv---vv"); } MessageStructuredData structured_data() const override { - return TestMessageBase::MessageStructuredData(subscribe_fin_); + return TestMessageBase::MessageStructuredData(subscribe_done_); } - private: - uint8_t raw_packet_[4] = { - 0x0b, 0x03, // subscribe_id = 3 - 0x08, // final_group = 8 - 0x0c, // final_object = 12 - }; - - MoqtSubscribeFin subscribe_fin_ = { - /*subscribe_id=*/3, - /*final_group=*/8, - /*final_object=*/12, - }; -}; - -class QUICHE_NO_EXPORT SubscribeRstMessage : public TestMessageBase { - public: - SubscribeRstMessage() : TestMessageBase(MoqtMessageType::kSubscribeRst) { + void SetInvalidContentExists() { + raw_packet_[6] = 0x02; SetWireImage(raw_packet_, sizeof(raw_packet_)); } - bool EqualFieldValues(MessageStructuredData& values) const override { - auto cast = std::get<MoqtSubscribeRst>(values); - if (cast.subscribe_id != subscribe_rst_.subscribe_id) { - QUIC_LOG(INFO) << "SUBSCRIBE_RST subscribe ID mismatch"; - return false; - } - if (cast.error_code != subscribe_rst_.error_code) { - QUIC_LOG(INFO) << "SUBSCRIBE_RST error code mismatch"; - return false; - } - if (cast.reason_phrase != subscribe_rst_.reason_phrase) { - QUIC_LOG(INFO) << "SUBSCRIBE_RST reason phrase mismatch"; - return false; - } - if (cast.final_group != subscribe_rst_.final_group) { - QUIC_LOG(INFO) << "SUBSCRIBE_RST final group mismatch"; - return false; - } - if (cast.final_object != subscribe_rst_.final_object) { - QUIC_LOG(INFO) << "SUBSCRIBE_RST final object mismatch"; - return false; - } - return true; - } - - void ExpandVarints() override { ExpandVarintsImpl("vvvv--vv"); } - - MessageStructuredData structured_data() const override { - return TestMessageBase::MessageStructuredData(subscribe_rst_); - } - private: - uint8_t raw_packet_[8] = { - 0x0c, 0x02, // subscribe_id = 2 - 0x03, // error_code = 3 + uint8_t raw_packet_[9] = { + 0x0b, 0x02, 0x03, // subscribe_id = 2, error_code = 3, 0x02, 0x68, 0x69, // reason_phrase = "hi" - 0x08, // final_group = 8 - 0x0c, // final_object = 12 + 0x01, 0x08, 0x0c, // final_id = (8,12) }; - MoqtSubscribeRst subscribe_rst_ = { + MoqtSubscribeDone subscribe_done_ = { /*subscribe_id=*/2, /*error_code=*/3, /*reason_phrase=*/"hi", - /*final_group=*/8, - /*final_object=*/12, + /*final_id=*/FullSequence(8, 12), }; }; @@ -901,10 +867,8 @@ return std::make_unique<SubscribeErrorMessage>(); case MoqtMessageType::kUnsubscribe: return std::make_unique<UnsubscribeMessage>(); - case MoqtMessageType::kSubscribeFin: - return std::make_unique<SubscribeFinMessage>(); - case MoqtMessageType::kSubscribeRst: - return std::make_unique<SubscribeRstMessage>(); + case MoqtMessageType::kSubscribeDone: + return std::make_unique<SubscribeDoneMessage>(); case MoqtMessageType::kAnnounce: return std::make_unique<AnnounceMessage>(); case MoqtMessageType::kAnnounceOk:
diff --git a/quiche/quic/moqt/tools/moqt_client.cc b/quiche/quic/moqt/tools/moqt_client.cc index 754b68d..4920c16 100644 --- a/quiche/quic/moqt/tools/moqt_client.cc +++ b/quiche/quic/moqt/tools/moqt_client.cc
@@ -89,7 +89,7 @@ } MoqtSessionParameters parameters; - parameters.version = MoqtVersion::kDraft02; + parameters.version = MoqtVersion::kDraft03; parameters.perspective = quic::Perspective::IS_CLIENT, parameters.using_webtrans = true; parameters.path = "";
diff --git a/quiche/quic/moqt/tools/moqt_server.cc b/quiche/quic/moqt/tools/moqt_server.cc index d12847c..9a60977 100644 --- a/quiche/quic/moqt/tools/moqt_server.cc +++ b/quiche/quic/moqt/tools/moqt_server.cc
@@ -33,7 +33,7 @@ parameters.perspective = quic::Perspective::IS_SERVER; parameters.path = path; parameters.using_webtrans = true; - parameters.version = MoqtVersion::kDraft02; + parameters.version = MoqtVersion::kDraft03; parameters.deliver_partial_objects = false; auto moqt_session = std::make_unique<MoqtSession>(session, parameters); std::move (*configurator)(moqt_session.get());