Update MoQT ANNOUNCE-related messages to draft-11. PiperOrigin-RevId: 781194184
diff --git a/quiche/quic/moqt/moqt_framer.cc b/quiche/quic/moqt/moqt_framer.cc index 1d5225c..803ab62 100644 --- a/quiche/quic/moqt/moqt_framer.cc +++ b/quiche/quic/moqt/moqt_framer.cc
@@ -563,6 +563,7 @@ return quiche::QuicheBuffer(); } return SerializeControlMessage(MoqtMessageType::kAnnounce, + WireVarInt62(message.request_id), WireTrackNamespace(message.track_namespace), WireKeyValuePairList(parameters)); } @@ -570,16 +571,21 @@ quiche::QuicheBuffer MoqtFramer::SerializeAnnounceOk( const MoqtAnnounceOk& message) { return SerializeControlMessage(MoqtMessageType::kAnnounceOk, - WireTrackNamespace(message.track_namespace)); + WireVarInt62(message.request_id)); } quiche::QuicheBuffer MoqtFramer::SerializeAnnounceError( const MoqtAnnounceError& message) { return SerializeControlMessage( - MoqtMessageType::kAnnounceError, - WireTrackNamespace(message.track_namespace), + MoqtMessageType::kAnnounceError, WireVarInt62(message.request_id), WireVarInt62(message.error_code), - WireStringWithVarInt62Length(message.reason_phrase)); + WireStringWithVarInt62Length(message.error_reason)); +} + +quiche::QuicheBuffer MoqtFramer::SerializeUnannounce( + const MoqtUnannounce& message) { + return SerializeControlMessage(MoqtMessageType::kUnannounce, + WireTrackNamespace(message.track_namespace)); } quiche::QuicheBuffer MoqtFramer::SerializeAnnounceCancel( @@ -588,7 +594,7 @@ MoqtMessageType::kAnnounceCancel, WireTrackNamespace(message.track_namespace), WireVarInt62(message.error_code), - WireStringWithVarInt62Length(message.reason_phrase)); + WireStringWithVarInt62Length(message.error_reason)); } quiche::QuicheBuffer MoqtFramer::SerializeTrackStatusRequest( @@ -607,12 +613,6 @@ WireKeyValuePairList(parameters)); } -quiche::QuicheBuffer MoqtFramer::SerializeUnannounce( - const MoqtUnannounce& message) { - return SerializeControlMessage(MoqtMessageType::kUnannounce, - WireTrackNamespace(message.track_namespace)); -} - quiche::QuicheBuffer MoqtFramer::SerializeTrackStatus( const MoqtTrackStatus& message) { KeyValuePairList parameters;
diff --git a/quiche/quic/moqt/moqt_framer.h b/quiche/quic/moqt/moqt_framer.h index d001464..a573ca4 100644 --- a/quiche/quic/moqt/moqt_framer.h +++ b/quiche/quic/moqt/moqt_framer.h
@@ -49,11 +49,11 @@ quiche::QuicheBuffer SerializeAnnounce(const MoqtAnnounce& message); quiche::QuicheBuffer SerializeAnnounceOk(const MoqtAnnounceOk& message); quiche::QuicheBuffer SerializeAnnounceError(const MoqtAnnounceError& message); + quiche::QuicheBuffer SerializeUnannounce(const MoqtUnannounce& message); quiche::QuicheBuffer SerializeAnnounceCancel( const MoqtAnnounceCancel& message); quiche::QuicheBuffer SerializeTrackStatusRequest( const MoqtTrackStatusRequest& message); - quiche::QuicheBuffer SerializeUnannounce(const MoqtUnannounce& message); quiche::QuicheBuffer SerializeTrackStatus(const MoqtTrackStatus& message); quiche::QuicheBuffer SerializeGoAway(const MoqtGoAway& message); quiche::QuicheBuffer SerializeSubscribeAnnounces(
diff --git a/quiche/quic/moqt/moqt_messages.h b/quiche/quic/moqt/moqt_messages.h index cd008cb..455ad9b 100644 --- a/quiche/quic/moqt/moqt_messages.h +++ b/quiche/quic/moqt/moqt_messages.h
@@ -622,24 +622,31 @@ }; struct QUICHE_EXPORT MoqtAnnounce { + uint64_t request_id; TrackNamespace track_namespace; VersionSpecificParameters parameters; }; struct QUICHE_EXPORT MoqtAnnounceOk { - TrackNamespace track_namespace; + uint64_t request_id; }; struct QUICHE_EXPORT MoqtAnnounceError { - TrackNamespace track_namespace; + uint64_t request_id; RequestErrorCode error_code; - std::string reason_phrase; + std::string error_reason; }; struct QUICHE_EXPORT MoqtUnannounce { TrackNamespace track_namespace; }; +struct QUICHE_EXPORT MoqtAnnounceCancel { + TrackNamespace track_namespace; + RequestErrorCode error_code; + std::string error_reason; +}; + enum class QUICHE_EXPORT MoqtTrackStatusCode : uint64_t { kInProgress = 0x0, kDoesNotExist = 0x1, @@ -674,12 +681,6 @@ VersionSpecificParameters parameters; }; -struct QUICHE_EXPORT MoqtAnnounceCancel { - TrackNamespace track_namespace; - RequestErrorCode error_code; - std::string reason_phrase; -}; - struct QUICHE_EXPORT MoqtGoAway { std::string new_session_uri; };
diff --git a/quiche/quic/moqt/moqt_parser.cc b/quiche/quic/moqt/moqt_parser.cc index 9e1a0b0..d8d96b6 100644 --- a/quiche/quic/moqt/moqt_parser.cc +++ b/quiche/quic/moqt/moqt_parser.cc
@@ -588,7 +588,8 @@ size_t MoqtControlParser::ProcessAnnounce(quic::QuicDataReader& reader) { MoqtAnnounce announce; - if (!ReadTrackNamespace(reader, announce.track_namespace)) { + if (!reader.ReadVarInt62(&announce.request_id) || + !ReadTrackNamespace(reader, announce.track_namespace)) { return 0; } KeyValuePairList parameters; @@ -610,7 +611,7 @@ size_t MoqtControlParser::ProcessAnnounceOk(quic::QuicDataReader& reader) { MoqtAnnounceOk announce_ok; - if (!ReadTrackNamespace(reader, announce_ok.track_namespace)) { + if (!reader.ReadVarInt62(&announce_ok.request_id)) { return 0; } visitor_.OnAnnounceOkMessage(announce_ok); @@ -619,12 +620,10 @@ size_t MoqtControlParser::ProcessAnnounceError(quic::QuicDataReader& reader) { MoqtAnnounceError announce_error; - if (!ReadTrackNamespace(reader, announce_error.track_namespace)) { - return 0; - } uint64_t error_code; - if (!reader.ReadVarInt62(&error_code) || - !reader.ReadStringVarInt62(announce_error.reason_phrase)) { + if (!reader.ReadVarInt62(&announce_error.request_id) || + !reader.ReadVarInt62(&error_code) || + !reader.ReadStringVarInt62(announce_error.error_reason)) { return 0; } announce_error.error_code = static_cast<RequestErrorCode>(error_code); @@ -639,7 +638,7 @@ } uint64_t error_code; if (!reader.ReadVarInt62(&error_code) || - !reader.ReadStringVarInt62(announce_cancel.reason_phrase)) { + !reader.ReadStringVarInt62(announce_cancel.error_reason)) { return 0; } announce_cancel.error_code = static_cast<RequestErrorCode>(error_code);
diff --git a/quiche/quic/moqt/moqt_parser_test.cc b/quiche/quic/moqt/moqt_parser_test.cc index b527d59..3624c7d 100644 --- a/quiche/quic/moqt/moqt_parser_test.cc +++ b/quiche/quic/moqt/moqt_parser_test.cc
@@ -807,8 +807,8 @@ webtransport::test::InMemoryStream stream(/*stream_id=*/0); MoqtControlParser parser(kWebTrans, &stream, visitor_); char announce[] = { - 0x06, 0x00, 0x14, 0x01, 0x03, 0x66, 0x6f, - 0x6f, // track_namespace = "foo" + 0x06, 0x00, 0x15, 0x02, 0x01, 0x03, 0x66, + 0x6f, 0x6f, // track_namespace = "foo" 0x02, // 2 params 0x01, 0x05, 0x03, 0x00, 0x62, 0x61, 0x72, // authorization = "bar" 0x01, 0x05, 0x03, 0x00, 0x62, 0x61, 0x72, // authorization = "bar" @@ -822,8 +822,8 @@ webtransport::test::InMemoryStream stream(/*stream_id=*/0); MoqtControlParser parser(kWebTrans, &stream, visitor_); char announce[] = { - 0x06, 0x00, 0x10, 0x01, 0x03, 0x66, 0x6f, - 0x6f, // track_namespace = "foo" + 0x06, 0x00, 0x11, 0x02, 0x01, 0x03, 0x66, + 0x6f, 0x6f, // track_namespace = "foo" 0x02, // 2 params 0x01, 0x05, 0x03, 0x00, 0x62, 0x61, 0x72, // authorization_info = "bar" 0x02, 0x67, 0x10, // delivery_timeout = 10000 @@ -1268,22 +1268,22 @@ } // All messages with TrackNamespace use ReadTrackNamespace too check this. Use -// ANNOUNCE_OK for the test because it's small. +// ANNOUNCE. TEST_F(MoqtMessageSpecificTest, NamespaceTooSmall) { webtransport::test::InMemoryStream stream(/*stream_id=*/0); MoqtControlParser parser(kRawQuic, &stream, visitor_); - char announce_ok[] = { - 0x07, 0x00, 0x03, // type, length - 0x01, 0x01, 'a', // 1 namespace element + char announce[7] = { + 0x06, 0x00, 0x04, 0x02, // request_id = 2 + 0x01, 0x00, // one empty namespace element + 0x00, // no parameters }; - stream.Receive(absl::string_view(announce_ok, sizeof(announce_ok)), false); + stream.Receive(absl::string_view(announce, sizeof(announce)), false); parser.ReadAndDispatchMessages(); EXPECT_EQ(visitor_.messages_received_, 1); EXPECT_EQ(visitor_.parsing_error_, std::nullopt); - announce_ok[2] -= 2; // Remove one element. - announce_ok[3] = 0x00; - stream.Receive(absl::string_view(announce_ok, sizeof(announce_ok) - 2), - false); + --announce[2]; // Remove one element. + --announce[4]; + stream.Receive(absl::string_view(announce, sizeof(announce) - 1), false); parser.ReadAndDispatchMessages(); EXPECT_EQ(visitor_.messages_received_, 1); EXPECT_EQ(visitor_.parsing_error_, "Invalid number of namespace elements"); @@ -1292,22 +1292,18 @@ TEST_F(MoqtMessageSpecificTest, NamespaceTooLarge) { webtransport::test::InMemoryStream stream(/*stream_id=*/0); MoqtControlParser parser(kRawQuic, &stream, visitor_); - char announce_ok[70] = { - 0x07, 0x00, 0x41, // type, length = 65 - 0x20, // 32 namespace elements. This is the maximum. + char announce[39] = { + 0x06, 0x00, 0x23, 0x02, // type, length = 35, request_id = 2 + 0x20, // 32 namespace elements. This is the maximum. }; - for (size_t i = 4; i < sizeof(announce_ok); i = i + 2) { - announce_ok[i] = 0x01; - announce_ok[i + 1] = 'a' + i; - } - stream.Receive(absl::string_view(announce_ok, sizeof(announce_ok) - 2), - false); + // 32 empty namespace elements + no parameters. + stream.Receive(absl::string_view(announce, sizeof(announce) - 1), false); parser.ReadAndDispatchMessages(); EXPECT_EQ(visitor_.messages_received_, 1); EXPECT_EQ(visitor_.parsing_error_, std::nullopt); - announce_ok[2] += 2; // Add one element. - ++announce_ok[3]; - stream.Receive(absl::string_view(announce_ok, sizeof(announce_ok)), false); + ++announce[2]; // Add one element. + ++announce[4]; + stream.Receive(absl::string_view(announce, sizeof(announce)), false); parser.ReadAndDispatchMessages(); EXPECT_EQ(visitor_.messages_received_, 1); EXPECT_EQ(visitor_.parsing_error_, "Invalid number of namespace elements");
diff --git a/quiche/quic/moqt/moqt_session.cc b/quiche/quic/moqt/moqt_session.cc index 6a31483..e58a988 100644 --- a/quiche/quic/moqt/moqt_session.cc +++ b/quiche/quic/moqt/moqt_session.cc
@@ -295,9 +295,22 @@ if (outgoing_announces_.contains(track_namespace)) { std::move(announce_callback)( track_namespace, - MoqtAnnounceErrorReason{ - RequestErrorCode::kInternalError, - "ANNOUNCE message already outstanding for namespace"}); + MoqtAnnounceErrorReason{RequestErrorCode::kInternalError, + "ANNOUNCE already outstanding for namespace"}); + return; + } + if (next_request_id_ >= peer_max_request_id_) { + if (!last_requests_blocked_sent_.has_value() || + peer_max_request_id_ > *last_requests_blocked_sent_) { + MoqtRequestsBlocked requests_blocked; + requests_blocked.max_request_id = peer_max_request_id_; + SendControlMessage(framer_.SerializeRequestsBlocked(requests_blocked)); + last_requests_blocked_sent_ = peer_max_request_id_; + } + QUIC_DLOG(INFO) << ENDPOINT << "Tried to send ANNOUNCE with ID " + << next_request_id_ + << " which is greater than the maximum ID " + << peer_max_request_id_; return; } if (received_goaway_ || sent_goaway_) { @@ -305,11 +318,14 @@ return; } MoqtAnnounce message; + message.request_id = next_request_id_; + next_request_id_ += 2; message.track_namespace = track_namespace; message.parameters = parameters; SendControlMessage(framer_.SerializeAnnounce(message)); QUIC_DLOG(INFO) << ENDPOINT << "Sent ANNOUNCE message for " << message.track_namespace; + pending_outgoing_announces_[message.request_id] = track_namespace; outgoing_announces_[track_namespace] = std::move(announce_callback); } @@ -1165,12 +1181,15 @@ void MoqtSession::ControlStream::OnAnnounceMessage( const MoqtAnnounce& message) { + if (!session_->ValidateRequestId(message.request_id)) { + return; + } if (session_->sent_goaway_) { QUIC_DLOG(INFO) << ENDPOINT << "Received an ANNOUNCE after GOAWAY"; MoqtAnnounceError error; - error.track_namespace = message.track_namespace; + error.request_id = message.request_id; error.error_code = RequestErrorCode::kUnauthorized; - error.reason_phrase = "ANNOUNCE after GOAWAY"; + error.error_reason = "ANNOUNCE after GOAWAY"; SendOrBufferMessage(session_->framer_.SerializeAnnounceError(error)); return; } @@ -1179,14 +1198,14 @@ message.parameters); if (error.has_value()) { MoqtAnnounceError reply; - reply.track_namespace = message.track_namespace; + reply.request_id = message.request_id; reply.error_code = error->error_code; - reply.reason_phrase = error->reason_phrase; + reply.error_reason = error->reason_phrase; SendOrBufferMessage(session_->framer_.SerializeAnnounceError(reply)); return; } MoqtAnnounceOk ok; - ok.track_namespace = message.track_namespace; + ok.request_id = message.request_id; SendOrBufferMessage(session_->framer_.SerializeAnnounceOk(ok)); } @@ -1194,24 +1213,41 @@ // ERROR, we immediately destroy the state. void MoqtSession::ControlStream::OnAnnounceOkMessage( const MoqtAnnounceOk& message) { - auto it = session_->outgoing_announces_.find(message.track_namespace); - if (it == session_->outgoing_announces_.end()) { - return; // State might have been destroyed due to UNANNOUNCE. + auto it = session_->pending_outgoing_announces_.find(message.request_id); + if (it == session_->pending_outgoing_announces_.end()) { + session_->Error(MoqtError::kProtocolViolation, + "Received ANNOUNCE_OK for unknown request_id"); + return; } - std::move(it->second)(message.track_namespace, std::nullopt); + TrackNamespace track_namespace = it->second; + session_->pending_outgoing_announces_.erase(it); + auto callback_it = session_->outgoing_announces_.find(track_namespace); + if (callback_it == session_->outgoing_announces_.end()) { + // It might have already been destroyed due to UNANNOUNCE. + return; + } + std::move(callback_it->second)(track_namespace, std::nullopt); } void MoqtSession::ControlStream::OnAnnounceErrorMessage( const MoqtAnnounceError& message) { - auto it = session_->outgoing_announces_.find(message.track_namespace); - if (it == session_->outgoing_announces_.end()) { + auto it = session_->pending_outgoing_announces_.find(message.request_id); + if (it == session_->pending_outgoing_announces_.end()) { + session_->Error(MoqtError::kProtocolViolation, + "Received ANNOUNCE_ERROR for unknown request_id"); + return; + } + TrackNamespace track_namespace = it->second; + session_->pending_outgoing_announces_.erase(it); + auto it2 = session_->outgoing_announces_.find(track_namespace); + if (it2 == session_->outgoing_announces_.end()) { return; // State might have been destroyed due to UNANNOUNCE. } - std::move(it->second)( - message.track_namespace, + std::move(it2->second)( + track_namespace, MoqtAnnounceErrorReason{message.error_code, - std::string(message.reason_phrase)}); - session_->outgoing_announces_.erase(it); + std::string(message.error_reason)}); + session_->outgoing_announces_.erase(it2); } void MoqtSession::ControlStream::OnAnnounceCancelMessage( @@ -1227,7 +1263,7 @@ std::move(it->second)( message.track_namespace, MoqtAnnounceErrorReason{message.error_code, - std::string(message.reason_phrase)}); + std::string(message.error_reason)}); session_->outgoing_announces_.erase(it); }
diff --git a/quiche/quic/moqt/moqt_session.h b/quiche/quic/moqt/moqt_session.h index 775ed5e..d88742a 100644 --- a/quiche/quic/moqt/moqt_session.h +++ b/quiche/quic/moqt/moqt_session.h
@@ -819,11 +819,12 @@ absl::flat_hash_map<FullTrackName, MoqtPublishingMonitorInterface*> monitoring_interfaces_for_published_tracks_; - // Indexed by track namespace. If the value is not nullptr, no OK or ERROR - // has been received. The entry is deleted after sending UNANNOUNCE or - // receiving ANNOUNCE_CANCEL. + // Outgoing ANNOUNCE for which no OK or ERROR has been received. + absl::flat_hash_map<uint64_t, TrackNamespace> pending_outgoing_announces_; + // All outgoing ANNOUNCE. absl::flat_hash_map<TrackNamespace, MoqtOutgoingAnnounceCallback> outgoing_announces_; + // The value is nullptr after OK or ERROR is received. The entry is deleted // when sending UNSUBSCRIBE_ANNOUNCES, to make sure the application doesn't // unsubscribe from something that it isn't subscribed to. ANNOUNCEs that
diff --git a/quiche/quic/moqt/moqt_session_test.cc b/quiche/quic/moqt/moqt_session_test.cc index a89bf05..03cb3ae 100644 --- a/quiche/quic/moqt/moqt_session_test.cc +++ b/quiche/quic/moqt/moqt_session_test.cc
@@ -364,7 +364,7 @@ VersionSpecificParameters()); MoqtAnnounceOk ok = { - TrackNamespace("foo"), + /*request_id=*/0, }; EXPECT_CALL(announce_resolved_callback, Call(_, _)) .WillOnce([&](TrackNamespace track_namespace, @@ -377,7 +377,7 @@ MoqtAnnounceCancel cancel = { TrackNamespace("foo"), RequestErrorCode::kInternalError, - /*reason_phrase=*/"Test error", + /*error_reason=*/"Test error", }; EXPECT_CALL(announce_resolved_callback, Call(_, _)) .WillOnce([&](TrackNamespace track_namespace, @@ -407,7 +407,7 @@ VersionSpecificParameters()); MoqtAnnounceOk ok = { - TrackNamespace{"foo"}, + /*request_id=*/0, }; EXPECT_CALL(announce_resolved_callback, Call(_, _)) .WillOnce([&](TrackNamespace track_namespace, @@ -440,7 +440,7 @@ VersionSpecificParameters()); MoqtAnnounceError error = { - /*track_namespace=*/TrackNamespace{"foo"}, + /*request_id=*/0, /*error_code=*/RequestErrorCode::kInternalError, /*reason_phrase=*/"Test error", }; @@ -893,15 +893,15 @@ auto parameters = std::make_optional<VersionSpecificParameters>( AuthTokenType::kOutOfBand, "foo"); MoqtAnnounce announce = { + /*request_id=*/1, track_namespace, *parameters, }; EXPECT_CALL(session_callbacks_.incoming_announce_callback, Call(track_namespace, parameters)) .WillOnce(Return(std::nullopt)); - EXPECT_CALL( - mock_stream_, - Writev(SerializedControlMessage(MoqtAnnounceOk{track_namespace}), _)); + EXPECT_CALL(mock_stream_, + Writev(SerializedControlMessage(MoqtAnnounceOk{1}), _)); stream_input->OnAnnounceMessage(announce); MoqtUnannounce unannounce = { track_namespace, @@ -920,15 +920,15 @@ auto parameters = std::make_optional<VersionSpecificParameters>( AuthTokenType::kOutOfBand, "foo"); MoqtAnnounce announce = { + /*request_id=*/1, track_namespace, *parameters, }; EXPECT_CALL(session_callbacks_.incoming_announce_callback, Call(track_namespace, parameters)) .WillOnce(Return(std::nullopt)); - EXPECT_CALL( - mock_stream_, - Writev(SerializedControlMessage(MoqtAnnounceOk{track_namespace}), _)); + EXPECT_CALL(mock_stream_, + Writev(SerializedControlMessage(MoqtAnnounceOk{1}), _)); stream_input->OnAnnounceMessage(announce); EXPECT_CALL(mock_stream_, Writev(SerializedControlMessage(MoqtAnnounceCancel{ @@ -947,6 +947,7 @@ auto parameters = std::make_optional<VersionSpecificParameters>( AuthTokenType::kOutOfBand, "foo"); MoqtAnnounce announce = { + /*request_id=*/1, track_namespace, *parameters, }; @@ -957,11 +958,10 @@ EXPECT_CALL(session_callbacks_.incoming_announce_callback, Call(track_namespace, parameters)) .WillOnce(Return(error)); - EXPECT_CALL( - mock_stream_, - Writev(SerializedControlMessage(MoqtAnnounceError{ - track_namespace, error.error_code, error.reason_phrase}), - _)); + EXPECT_CALL(mock_stream_, + Writev(SerializedControlMessage(MoqtAnnounceError{ + 1, error.error_code, error.reason_phrase}), + _)); stream_input->OnAnnounceMessage(announce); } @@ -3196,11 +3196,11 @@ EXPECT_CALL(mock_stream_, Writev(ControlMessageOfType(MoqtMessageType::kAnnounceError), _)); stream_input->OnAnnounceMessage( - MoqtAnnounce(TrackNamespace("foo"), VersionSpecificParameters())); + MoqtAnnounce(3, TrackNamespace("foo"), VersionSpecificParameters())); EXPECT_CALL(mock_stream_, Writev(ControlMessageOfType(MoqtMessageType::kFetchError), _)); MoqtFetch fetch = DefaultFetch(); - fetch.request_id = 3; + fetch.request_id = 5; stream_input->OnFetchMessage(fetch); EXPECT_CALL( mock_stream_,
diff --git a/quiche/quic/moqt/test_tools/moqt_test_message.h b/quiche/quic/moqt/test_tools/moqt_test_message.h index fcfbce5..cee1e60 100644 --- a/quiche/quic/moqt/test_tools/moqt_test_message.h +++ b/quiche/quic/moqt/test_tools/moqt_test_message.h
@@ -813,32 +813,37 @@ bool EqualFieldValues(MessageStructuredData& values) const override { auto cast = std::get<MoqtAnnounce>(values); + if (cast.request_id != announce_.request_id) { + QUIC_LOG(INFO) << "ANNOUNCE request ID mismatch"; + return false; + } if (cast.track_namespace != announce_.track_namespace) { - QUIC_LOG(INFO) << "ANNOUNCE MESSAGE track namespace mismatch"; + QUIC_LOG(INFO) << "ANNOUNCE track namespace mismatch"; return false; } if (cast.parameters != announce_.parameters) { - QUIC_LOG(INFO) << "ANNOUNCE MESSAGE parameter mismatch"; + QUIC_LOG(INFO) << "ANNOUNCE parameter mismatch"; return false; } return true; } - void ExpandVarints() override { ExpandVarintsImpl("vv---vvv-----"); } + void ExpandVarints() override { ExpandVarintsImpl("vvv---vvv-----"); } MessageStructuredData structured_data() const override { return TestMessageBase::MessageStructuredData(announce_); } private: - uint8_t raw_packet_[16] = { - 0x06, 0x00, 0x0d, 0x01, 0x03, 0x66, 0x6f, - 0x6f, // track_namespace = "foo" + uint8_t raw_packet_[17] = { + 0x06, 0x00, 0x0e, 0x02, // request_id = 2 + 0x01, 0x03, 0x66, 0x6f, 0x6f, // track_namespace = "foo" 0x01, // 1 parameter 0x01, 0x05, 0x03, 0x00, 0x62, 0x61, 0x72, // authorization_tag = "bar" }; MoqtAnnounce announce_ = { + /*request_id=*/2, TrackNamespace{"foo"}, VersionSpecificParameters(AuthTokenType::kOutOfBand, "bar"), }; @@ -852,27 +857,26 @@ bool EqualFieldValues(MessageStructuredData& values) const override { auto cast = std::get<MoqtAnnounceOk>(values); - if (cast.track_namespace != announce_ok_.track_namespace) { - QUIC_LOG(INFO) << "ANNOUNCE OK MESSAGE track namespace mismatch"; + if (cast.request_id != announce_ok_.request_id) { + QUIC_LOG(INFO) << "ANNOUNCE OK MESSAGE request ID mismatch"; return false; } return true; } - void ExpandVarints() override { ExpandVarintsImpl("vv---"); } + void ExpandVarints() override { ExpandVarintsImpl("v"); } MessageStructuredData structured_data() const override { return TestMessageBase::MessageStructuredData(announce_ok_); } private: - uint8_t raw_packet_[8] = { - 0x07, 0x00, 0x05, 0x01, - 0x03, 0x66, 0x6f, 0x6f, // track_namespace = "foo" + uint8_t raw_packet_[4] = { + 0x07, 0x00, 0x01, 0x01, // request_id = 1 }; MoqtAnnounceOk announce_ok_ = { - TrackNamespace("foo"), + /*request_id=*/1, }; }; @@ -884,37 +888,36 @@ bool EqualFieldValues(MessageStructuredData& values) const override { auto cast = std::get<MoqtAnnounceError>(values); - if (cast.track_namespace != announce_error_.track_namespace) { - QUIC_LOG(INFO) << "ANNOUNCE ERROR track namespace mismatch"; + if (cast.request_id != announce_error_.request_id) { + QUIC_LOG(INFO) << "ANNOUNCE_ERROR request ID mismatch"; return false; } if (cast.error_code != announce_error_.error_code) { - QUIC_LOG(INFO) << "ANNOUNCE ERROR error code mismatch"; + QUIC_LOG(INFO) << "ANNOUNCE_ERROR error code mismatch"; return false; } - if (cast.reason_phrase != announce_error_.reason_phrase) { - QUIC_LOG(INFO) << "ANNOUNCE ERROR reason phrase mismatch"; + if (cast.error_reason != announce_error_.error_reason) { + QUIC_LOG(INFO) << "ANNOUNCE_ERROR error reason mismatch"; return false; } return true; } - void ExpandVarints() override { ExpandVarintsImpl("vv---vv---"); } + void ExpandVarints() override { ExpandVarintsImpl("vvv---"); } MessageStructuredData structured_data() const override { return TestMessageBase::MessageStructuredData(announce_error_); } private: - uint8_t raw_packet_[13] = { - 0x08, 0x00, 0x0a, 0x01, - 0x03, 0x66, 0x6f, 0x6f, // track_namespace = "foo" + uint8_t raw_packet_[9] = { + 0x08, 0x00, 0x06, 0x01, // request_id = 1 0x03, // error_code = 3 0x03, 0x62, 0x61, 0x72, // reason_phrase = "bar" }; MoqtAnnounceError announce_error_ = { - TrackNamespace("foo"), + /*request_id=*/1, RequestErrorCode::kNotSupported, /*reason_phrase=*/"bar", }; @@ -936,7 +939,7 @@ QUIC_LOG(INFO) << "ANNOUNCE CANCEL error code mismatch"; return false; } - if (cast.reason_phrase != announce_cancel_.reason_phrase) { + if (cast.error_reason != announce_cancel_.error_reason) { QUIC_LOG(INFO) << "ANNOUNCE CANCEL reason phrase mismatch"; return false; } @@ -954,13 +957,13 @@ 0x0c, 0x00, 0x0a, 0x01, 0x03, 0x66, 0x6f, 0x6f, // track_namespace = "foo" 0x03, // error_code = 3 - 0x03, 0x62, 0x61, 0x72, // reason_phrase = "bar" + 0x03, 0x62, 0x61, 0x72, // error_reason = "bar" }; MoqtAnnounceCancel announce_cancel_ = { TrackNamespace("foo"), RequestErrorCode::kNotSupported, - /*reason_phrase=*/"bar", + /*error_reason=*/"bar", }; };