Update MoQT SUBSCRIBE_ANNOUNCES to draft-11. PiperOrigin-RevId: 781206674
diff --git a/quiche/quic/moqt/moqt_framer.cc b/quiche/quic/moqt/moqt_framer.cc index 803ab62..769c51c 100644 --- a/quiche/quic/moqt/moqt_framer.cc +++ b/quiche/quic/moqt/moqt_framer.cc
@@ -648,6 +648,7 @@ return quiche::QuicheBuffer(); } return SerializeControlMessage(MoqtMessageType::kSubscribeAnnounces, + WireVarInt62(message.request_id), WireTrackNamespace(message.track_namespace), WireKeyValuePairList(parameters)); } @@ -655,16 +656,15 @@ quiche::QuicheBuffer MoqtFramer::SerializeSubscribeAnnouncesOk( const MoqtSubscribeAnnouncesOk& message) { return SerializeControlMessage(MoqtMessageType::kSubscribeAnnouncesOk, - WireTrackNamespace(message.track_namespace)); + WireVarInt62(message.request_id)); } quiche::QuicheBuffer MoqtFramer::SerializeSubscribeAnnouncesError( const MoqtSubscribeAnnouncesError& message) { return SerializeControlMessage( MoqtMessageType::kSubscribeAnnouncesError, - WireTrackNamespace(message.track_namespace), - WireVarInt62(message.error_code), - WireStringWithVarInt62Length(message.reason_phrase)); + WireVarInt62(message.request_id), WireVarInt62(message.error_code), + WireStringWithVarInt62Length(message.error_reason)); } quiche::QuicheBuffer MoqtFramer::SerializeUnsubscribeAnnounces(
diff --git a/quiche/quic/moqt/moqt_messages.h b/quiche/quic/moqt/moqt_messages.h index 455ad9b..2e6960d 100644 --- a/quiche/quic/moqt/moqt_messages.h +++ b/quiche/quic/moqt/moqt_messages.h
@@ -686,18 +686,19 @@ }; struct QUICHE_EXPORT MoqtSubscribeAnnounces { + uint64_t request_id; TrackNamespace track_namespace; VersionSpecificParameters parameters; }; struct QUICHE_EXPORT MoqtSubscribeAnnouncesOk { - TrackNamespace track_namespace; + uint64_t request_id; }; struct QUICHE_EXPORT MoqtSubscribeAnnouncesError { - TrackNamespace track_namespace; + uint64_t request_id; RequestErrorCode error_code; - std::string reason_phrase; + std::string error_reason; }; struct QUICHE_EXPORT MoqtUnsubscribeAnnounces {
diff --git a/quiche/quic/moqt/moqt_parser.cc b/quiche/quic/moqt/moqt_parser.cc index d8d96b6..968a9e5 100644 --- a/quiche/quic/moqt/moqt_parser.cc +++ b/quiche/quic/moqt/moqt_parser.cc
@@ -720,7 +720,8 @@ size_t MoqtControlParser::ProcessSubscribeAnnounces( quic::QuicDataReader& reader) { MoqtSubscribeAnnounces subscribe_announces; - if (!ReadTrackNamespace(reader, subscribe_announces.track_namespace)) { + if (!reader.ReadVarInt62(&subscribe_announces.request_id) || + !ReadTrackNamespace(reader, subscribe_announces.track_namespace)) { return 0; } KeyValuePairList parameters; @@ -743,7 +744,7 @@ size_t MoqtControlParser::ProcessSubscribeAnnouncesOk( quic::QuicDataReader& reader) { MoqtSubscribeAnnouncesOk subscribe_namespace_ok; - if (!ReadTrackNamespace(reader, subscribe_namespace_ok.track_namespace)) { + if (!reader.ReadVarInt62(&subscribe_namespace_ok.request_id)) { return 0; } visitor_.OnSubscribeAnnouncesOkMessage(subscribe_namespace_ok); @@ -754,9 +755,9 @@ quic::QuicDataReader& reader) { MoqtSubscribeAnnouncesError subscribe_namespace_error; uint64_t error_code; - if (!ReadTrackNamespace(reader, subscribe_namespace_error.track_namespace) || + if (!reader.ReadVarInt62(&subscribe_namespace_error.request_id) || !reader.ReadVarInt62(&error_code) || - !reader.ReadStringVarInt62(subscribe_namespace_error.reason_phrase)) { + !reader.ReadStringVarInt62(subscribe_namespace_error.error_reason)) { return 0; } subscribe_namespace_error.error_code =
diff --git a/quiche/quic/moqt/moqt_session.cc b/quiche/quic/moqt/moqt_session.cc index e58a988..2a202ed 100644 --- a/quiche/quic/moqt/moqt_session.cc +++ b/quiche/quic/moqt/moqt_session.cc
@@ -264,13 +264,37 @@ << "Tried to send SUBSCRIBE_ANNOUNCES after GOAWAY"; return false; } + 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 SUBSCRIBE_ANNOUNCES with ID " + << next_request_id_ + << " which is greater than the maximum ID " + << peer_max_request_id_; + return false; + } + if (outgoing_subscribe_announces_.contains(track_namespace)) { + std::move(callback)( + track_namespace, RequestErrorCode::kInternalError, + "SUBSCRIBE_ANNOUNCES already outstanding for namespace"); + return false; + } MoqtSubscribeAnnounces message; + message.request_id = next_request_id_; + next_request_id_ += 2; message.track_namespace = track_namespace; message.parameters = parameters; SendControlMessage(framer_.SerializeSubscribeAnnounces(message)); QUIC_DLOG(INFO) << ENDPOINT << "Sent SUBSCRIBE_ANNOUNCES message for " << message.track_namespace; - outgoing_subscribe_announces_[track_namespace] = std::move(callback); + pending_outgoing_subscribe_announces_[message.request_id] = + PendingSubscribeAnnouncesData{track_namespace, std::move(callback)}; + outgoing_subscribe_announces_.emplace(track_namespace); return true; } @@ -1322,14 +1346,17 @@ void MoqtSession::ControlStream::OnSubscribeAnnouncesMessage( const MoqtSubscribeAnnounces& message) { + if (!session_->ValidateRequestId(message.request_id)) { + return; + } // TODO(martinduke): Handle authentication. if (session_->sent_goaway_) { QUIC_DLOG(INFO) << ENDPOINT << "Received a SUBSCRIBE_ANNOUNCES after GOAWAY"; MoqtSubscribeAnnouncesError error; - error.track_namespace = message.track_namespace; + error.request_id = message.request_id; error.error_code = RequestErrorCode::kUnauthorized; - error.reason_phrase = "SUBSCRIBE_ANNOUNCES after GOAWAY"; + error.error_reason = "SUBSCRIBE_ANNOUNCES after GOAWAY"; SendOrBufferMessage( session_->framer_.SerializeSubscribeAnnouncesError(error)); return; @@ -1339,49 +1366,45 @@ message.track_namespace, message.parameters); if (result.has_value()) { MoqtSubscribeAnnouncesError error; - error.track_namespace = message.track_namespace; + error.request_id = message.request_id; error.error_code = result->error_code; - error.reason_phrase = result->reason_phrase; + error.error_reason = result->reason_phrase; SendOrBufferMessage( session_->framer_.SerializeSubscribeAnnouncesError(error)); return; } MoqtSubscribeAnnouncesOk ok; - ok.track_namespace = message.track_namespace; + ok.request_id = message.request_id; SendOrBufferMessage(session_->framer_.SerializeSubscribeAnnouncesOk(ok)); } void MoqtSession::ControlStream::OnSubscribeAnnouncesOkMessage( const MoqtSubscribeAnnouncesOk& message) { auto it = - session_->outgoing_subscribe_announces_.find(message.track_namespace); - if (it == session_->outgoing_subscribe_announces_.end()) { + session_->pending_outgoing_subscribe_announces_.find(message.request_id); + if (it == session_->pending_outgoing_subscribe_announces_.end()) { + session_->Error(MoqtError::kProtocolViolation, + "Received SUBSCRIBE_ANNOUNCES_OK for unknown request_id"); return; // UNSUBSCRIBE_ANNOUNCES may already have deleted the entry. } - if (it->second == nullptr) { - session_->Error(MoqtError::kProtocolViolation, - "Two responses to SUBSCRIBE_ANNOUNCES"); - return; - } - std::move(it->second)(message.track_namespace, std::nullopt, ""); - it->second = nullptr; + std::move(it->second.callback)(it->second.track_namespace, std::nullopt, ""); + session_->pending_outgoing_subscribe_announces_.erase(it); } void MoqtSession::ControlStream::OnSubscribeAnnouncesErrorMessage( const MoqtSubscribeAnnouncesError& message) { auto it = - session_->outgoing_subscribe_announces_.find(message.track_namespace); - if (it == session_->outgoing_subscribe_announces_.end()) { + session_->pending_outgoing_subscribe_announces_.find(message.request_id); + if (it == session_->pending_outgoing_subscribe_announces_.end()) { + session_->Error( + MoqtError::kProtocolViolation, + "Received SUBSCRIBE_ANNOUNCES_ERROR for unknown request_id"); return; // UNSUBSCRIBE_ANNOUNCES may already have deleted the entry. } - if (it->second == nullptr) { - session_->Error(MoqtError::kProtocolViolation, - "Two responses to SUBSCRIBE_ANNOUNCES"); - return; - } - std::move(it->second)(message.track_namespace, message.error_code, - absl::string_view(message.reason_phrase)); - session_->outgoing_subscribe_announces_.erase(it); + std::move(it->second.callback)(it->second.track_namespace, message.error_code, + absl::string_view(message.error_reason)); + session_->outgoing_subscribe_announces_.erase(it->second.track_namespace); + session_->pending_outgoing_subscribe_announces_.erase(it); } void MoqtSession::ControlStream::OnUnsubscribeAnnouncesMessage(
diff --git a/quiche/quic/moqt/moqt_session.h b/quiche/quic/moqt/moqt_session.h index d88742a..924674f 100644 --- a/quiche/quic/moqt/moqt_session.h +++ b/quiche/quic/moqt/moqt_session.h
@@ -829,8 +829,13 @@ // when sending UNSUBSCRIBE_ANNOUNCES, to make sure the application doesn't // unsubscribe from something that it isn't subscribed to. ANNOUNCEs that // result from this subscription use incoming_announce_callback. - absl::flat_hash_map<TrackNamespace, MoqtOutgoingSubscribeAnnouncesCallback> - outgoing_subscribe_announces_; + struct PendingSubscribeAnnouncesData { + TrackNamespace track_namespace; + MoqtOutgoingSubscribeAnnouncesCallback callback; + }; + absl::flat_hash_map<uint64_t, PendingSubscribeAnnouncesData> + pending_outgoing_subscribe_announces_; + absl::flat_hash_set<TrackNamespace> outgoing_subscribe_announces_; // The minimum request ID the peer can use that is monotonically increasing. uint64_t next_incoming_request_id_ = 0;
diff --git a/quiche/quic/moqt/moqt_session_test.cc b/quiche/quic/moqt/moqt_session_test.cc index 03cb3ae..32400fc 100644 --- a/quiche/quic/moqt/moqt_session_test.cc +++ b/quiche/quic/moqt/moqt_session_test.cc
@@ -55,12 +55,14 @@ constexpr webtransport::StreamId kIncomingUniStreamId = 15; constexpr webtransport::StreamId kOutgoingUniStreamId = 14; +constexpr uint64_t kDefaultLocalRequestId = 0; +constexpr uint64_t kDefaultPeerRequestId = 1; FullTrackName kDefaultTrackName() { return FullTrackName("foo", "bar"); } -MoqtSubscribe DefaultSubscribe() { +MoqtSubscribe DefaultSubscribe(uint64_t request_id) { MoqtSubscribe subscribe = { - /*request_id=*/1, + request_id, /*track_alias=*/2, kDefaultTrackName(), /*subscriber_priority=*/0x80, @@ -74,13 +76,24 @@ return subscribe; } +// The usual test case is that a SUBSCRIBE is coming in. +MoqtSubscribe DefaultSubscribe() { + return DefaultSubscribe(kDefaultPeerRequestId); +} + +// Used when a test sets up a remote track. +MoqtSubscribe DefaultLocalSubscribe() { + return DefaultSubscribe(kDefaultLocalRequestId); +} + MoqtFetch DefaultFetch() { MoqtFetch fetch = { - /*request_id=*/1, + kDefaultPeerRequestId, /*subscriber_priority=*/0x80, /*group_order=*/std::nullopt, /*fetch=*/ - StandaloneFetch(kDefaultTrackName(), Location(0, 0), 1, std::nullopt), + StandaloneFetch(kDefaultTrackName(), Location(0, 0), + kDefaultPeerRequestId, std::nullopt), /*parameters=*/VersionSpecificParameters(), }; return fetch; @@ -471,7 +484,8 @@ EXPECT_CALL(mock_stream_, Writev(ControlMessageOfType(MoqtMessageType::kSubscribeOk), _)); listener->OnSubscribeAccepted(); - EXPECT_NE(MoqtSessionPeer::GetSubscription(&session_, 1), nullptr); + EXPECT_NE(MoqtSessionPeer::GetSubscription(&session_, kDefaultPeerRequestId), + nullptr); } TEST_F(MoqtSessionTest, AsynchronousSubscribeReturnsError) { @@ -490,7 +504,8 @@ listener->OnSubscribeRejected( MoqtSubscribeErrorReason(RequestErrorCode::kInternalError, "Test error"), request.track_alias); - EXPECT_EQ(MoqtSessionPeer::GetSubscription(&session_, 1), nullptr); + EXPECT_EQ(MoqtSessionPeer::GetSubscription(&session_, kDefaultPeerRequestId), + nullptr); } TEST_F(MoqtSessionTest, SubscribeForPast) { @@ -579,7 +594,7 @@ // Peer unsubscribes. MoqtUnsubscribe unsubscribe = { - /*request_id=*/1, + kDefaultPeerRequestId, }; stream_input->OnUnsubscribeMessage(unsubscribe); EXPECT_EQ(MoqtSessionPeer::GetSubscription(&session_, 1), nullptr); @@ -893,15 +908,17 @@ auto parameters = std::make_optional<VersionSpecificParameters>( AuthTokenType::kOutOfBand, "foo"); MoqtAnnounce announce = { - /*request_id=*/1, + kDefaultPeerRequestId, 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{1}), _)); + EXPECT_CALL( + mock_stream_, + Writev(SerializedControlMessage(MoqtAnnounceOk{kDefaultPeerRequestId}), + _)); stream_input->OnAnnounceMessage(announce); MoqtUnannounce unannounce = { track_namespace, @@ -920,15 +937,17 @@ auto parameters = std::make_optional<VersionSpecificParameters>( AuthTokenType::kOutOfBand, "foo"); MoqtAnnounce announce = { - /*request_id=*/1, + kDefaultPeerRequestId, 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{1}), _)); + EXPECT_CALL( + mock_stream_, + Writev(SerializedControlMessage(MoqtAnnounceOk{kDefaultPeerRequestId}), + _)); stream_input->OnAnnounceMessage(announce); EXPECT_CALL(mock_stream_, Writev(SerializedControlMessage(MoqtAnnounceCancel{ @@ -947,7 +966,7 @@ auto parameters = std::make_optional<VersionSpecificParameters>( AuthTokenType::kOutOfBand, "foo"); MoqtAnnounce announce = { - /*request_id=*/1, + kDefaultPeerRequestId, track_namespace, *parameters, }; @@ -958,10 +977,11 @@ EXPECT_CALL(session_callbacks_.incoming_announce_callback, Call(track_namespace, parameters)) .WillOnce(Return(error)); - EXPECT_CALL(mock_stream_, - Writev(SerializedControlMessage(MoqtAnnounceError{ - 1, error.error_code, error.reason_phrase}), - _)); + EXPECT_CALL( + mock_stream_, + Writev(SerializedControlMessage(MoqtAnnounceError{ + kDefaultPeerRequestId, error.error_code, error.reason_phrase}), + _)); stream_input->OnAnnounceMessage(announce); } @@ -984,7 +1004,7 @@ }, VersionSpecificParameters()); MoqtSubscribeAnnouncesOk ok = { - /*track_namespace=*/track_namespace, + kDefaultLocalRequestId, }; stream_input->OnSubscribeAnnouncesOkMessage(ok); EXPECT_TRUE(got_callback); @@ -1015,7 +1035,7 @@ }, VersionSpecificParameters()); MoqtSubscribeAnnouncesError error = { - track_namespace, + kDefaultLocalRequestId, RequestErrorCode::kInvalidRange, /*reason_phrase=*/"deadbeef", }; @@ -1111,7 +1131,8 @@ MockSubscribeRemoteTrackVisitor visitor_; FullTrackName ftn("foo", "bar"); std::string payload = "deadbeef"; - MoqtSessionPeer::CreateRemoteTrack(&session_, DefaultSubscribe(), &visitor_); + MoqtSessionPeer::CreateRemoteTrack(&session_, DefaultLocalSubscribe(), + &visitor_); MoqtObject object = { /*track_alias=*/2, /*group_sequence=*/0, @@ -1140,7 +1161,7 @@ // SUBSCRIBE_OK arrives MoqtSubscribeOk ok = { - /*request_id=*/1, + kDefaultLocalRequestId, /*expires=*/quic::QuicTimeDelta::FromMilliseconds(0), /*group_order=*/MoqtDeliveryOrder::kAscending, /*largest_location=*/std::nullopt, @@ -1156,7 +1177,8 @@ MockSubscribeRemoteTrackVisitor visitor; FullTrackName ftn("foo", "bar"); std::string payload = "deadbeef"; - MoqtSessionPeer::CreateRemoteTrack(&session_, DefaultSubscribe(), &visitor); + MoqtSessionPeer::CreateRemoteTrack(&session_, DefaultLocalSubscribe(), + &visitor); MoqtObject object = { /*track_alias=*/2, /*group_sequence=*/0, @@ -1185,7 +1207,7 @@ // SUBSCRIBE_ERROR arrives MoqtSubscribeError subscribe_error = { - /*request_id=*/1, + kDefaultLocalRequestId, /*error_code=*/RequestErrorCode::kRetryTrackAlias, /*reason_phrase=*/"foo", /*track_alias =*/3, @@ -1203,11 +1225,12 @@ TEST_F(MoqtSessionTest, SubscribeErrorWithTrackAlias) { MockSubscribeRemoteTrackVisitor visitor; - MoqtSessionPeer::CreateRemoteTrack(&session_, DefaultSubscribe(), &visitor); + MoqtSessionPeer::CreateRemoteTrack(&session_, DefaultLocalSubscribe(), + &visitor); // SUBSCRIBE_ERROR arrives MoqtSubscribeError subscribe_error = { - /*request_id=*/1, + kDefaultLocalRequestId, /*error_code=*/RequestErrorCode::kRetryTrackAlias, /*reason_phrase=*/"foo", /*track_alias =*/3, @@ -1223,11 +1246,12 @@ TEST_F(MoqtSessionTest, SubscribeErrorWithBadTrackAlias) { MockSubscribeRemoteTrackVisitor visitor; - MoqtSessionPeer::CreateRemoteTrack(&session_, DefaultSubscribe(), &visitor); + MoqtSessionPeer::CreateRemoteTrack(&session_, DefaultLocalSubscribe(), + &visitor); // SUBSCRIBE_ERROR arrives MoqtSubscribeError subscribe_error = { - /*request_id=*/1, + kDefaultLocalRequestId, /*error_code=*/RequestErrorCode::kRetryTrackAlias, /*reason_phrase=*/"foo", /*track_alias =*/2, @@ -2572,6 +2596,7 @@ auto parameters = std::make_optional<VersionSpecificParameters>( AuthTokenType::kOutOfBand, "foo"); MoqtSubscribeAnnounces announces = { + /*request_id=*/1, track_namespace, *parameters, }; @@ -2599,6 +2624,7 @@ auto parameters = std::make_optional<VersionSpecificParameters>( AuthTokenType::kOutOfBand, "foo"); MoqtSubscribeAnnounces announces = { + /*request_id=*/1, track_namespace, *parameters, }; @@ -3206,8 +3232,7 @@ mock_stream_, Writev(ControlMessageOfType(MoqtMessageType::kSubscribeAnnouncesError), _)); - stream_input->OnSubscribeAnnouncesMessage( - MoqtSubscribeAnnounces(TrackNamespace("foo"))); + stream_input->OnSubscribeAnnouncesMessage(MoqtSubscribeAnnounces(7)); // Block all outgoing SUBSCRIBE, ANNOUNCE, GOAWAY,etc. EXPECT_CALL(mock_stream_, Writev).Times(0); MockSubscribeRemoteTrackVisitor remote_track_visitor;
diff --git a/quiche/quic/moqt/test_tools/moqt_test_message.h b/quiche/quic/moqt/test_tools/moqt_test_message.h index cee1e60..1039053 100644 --- a/quiche/quic/moqt/test_tools/moqt_test_message.h +++ b/quiche/quic/moqt/test_tools/moqt_test_message.h
@@ -1133,6 +1133,10 @@ bool EqualFieldValues(MessageStructuredData& values) const override { auto cast = std::get<MoqtSubscribeAnnounces>(values); + if (cast.request_id != subscribe_namespace_.request_id) { + QUIC_LOG(INFO) << "SUBSCRIBE_NAMESPACE request_id mismatch"; + return false; + } if (cast.track_namespace != subscribe_namespace_.track_namespace) { QUIC_LOG(INFO) << "SUBSCRIBE_NAMESPACE track namespace mismatch"; return false; @@ -1144,20 +1148,22 @@ return true; } - void ExpandVarints() override { ExpandVarintsImpl("vv---vvv-----"); } + void ExpandVarints() override { ExpandVarintsImpl("vvv---vvv-----"); } MessageStructuredData structured_data() const override { return TestMessageBase::MessageStructuredData(subscribe_namespace_); } private: - uint8_t raw_packet_[16] = { - 0x11, 0x00, 0x0d, 0x01, 0x03, 0x66, 0x6f, 0x6f, // namespace = "foo" - 0x01, // 1 parameter + uint8_t raw_packet_[17] = { + 0x11, 0x00, 0x0e, 0x01, // request_id = 1 + 0x01, 0x03, 0x66, 0x6f, 0x6f, // namespace = "foo" + 0x01, // 1 parameter 0x01, 0x05, 0x03, 0x00, 0x62, 0x61, 0x72, // authorization_tag = "bar" }; MoqtSubscribeAnnounces subscribe_namespace_ = { + /*request_id=*/1, TrackNamespace("foo"), VersionSpecificParameters(AuthTokenType::kOutOfBand, "bar"), }; @@ -1171,26 +1177,26 @@ bool EqualFieldValues(MessageStructuredData& values) const override { auto cast = std::get<MoqtSubscribeAnnouncesOk>(values); - if (cast.track_namespace != subscribe_namespace_ok_.track_namespace) { - QUIC_LOG(INFO) << "SUBSCRIBE_NAMESPACE_OK track namespace mismatch"; + if (cast.request_id != subscribe_namespace_ok_.request_id) { + QUIC_LOG(INFO) << "SUBSCRIBE_NAMESPACE_OK 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(subscribe_namespace_ok_); } private: - uint8_t raw_packet_[8] = { - 0x12, 0x00, 0x05, 0x01, 0x03, 0x66, 0x6f, 0x6f, // namespace = "foo" + uint8_t raw_packet_[4] = { + 0x12, 0x00, 0x01, 0x01, // request_id = 1 }; MoqtSubscribeAnnouncesOk subscribe_namespace_ok_ = { - TrackNamespace("foo"), + /*request_id=*/1, }; }; @@ -1202,39 +1208,38 @@ bool EqualFieldValues(MessageStructuredData& values) const override { auto cast = std::get<MoqtSubscribeAnnouncesError>(values); - if (cast.track_namespace != subscribe_namespace_error_.track_namespace) { - QUIC_LOG(INFO) << "SUBSCRIBE_NAMESPACE_ERROR track namespace mismatch"; + if (cast.request_id != subscribe_namespace_error_.request_id) { + QUIC_LOG(INFO) << "SUBSCRIBE_NAMESPACE_ERROR request_id mismatch"; return false; } if (cast.error_code != subscribe_namespace_error_.error_code) { QUIC_LOG(INFO) << "SUBSCRIBE_NAMESPACE_ERROR error code mismatch"; return false; } - if (cast.reason_phrase != subscribe_namespace_error_.reason_phrase) { - QUIC_LOG(INFO) << "SUBSCRIBE_NAMESPACE_ERROR reason phrase mismatch"; + if (cast.error_reason != subscribe_namespace_error_.error_reason) { + QUIC_LOG(INFO) << "SUBSCRIBE_NAMESPACE_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(subscribe_namespace_error_); } private: - uint8_t raw_packet_[13] = { - 0x13, 0x00, 0x0a, 0x01, - 0x03, 0x66, 0x6f, 0x6f, // track_namespace = "foo" + uint8_t raw_packet_[9] = { + 0x13, 0x00, 0x06, 0x01, // request_id = 1 0x01, // error_code = 1 - 0x03, 0x62, 0x61, 0x72, // reason_phrase = "bar" + 0x03, 0x62, 0x61, 0x72, // error_reason = "bar" }; MoqtSubscribeAnnouncesError subscribe_namespace_error_ = { - TrackNamespace("foo"), + /*request_id=*/1, /*error_code=*/RequestErrorCode::kUnauthorized, - /*reason_phrase=*/"bar", + /*error_reason=*/"bar", }; };