MoQRelay::publishNamespace's forwarding loop (relay/MoQRelay.cpp, from aea21fb) picks the draft-16+
bidi NAMESPACE path vs. the draft ≤15 separate-stream PUBLISH_NAMESPACE path by testing if
(info.namespacePublishHandle). It assumes the handle is null for draft ≤15, but
MoQRelaySession::handleSubscribeNamespace always constructs/stores a MoQNamespacePublishHandle
regardless of negotiated version. So when a draft-14 subscriber's SUBSCRIBE_NAMESPACE is matched by a
later announce, the relay calls namespacePublishHandle->namespaceMsg(), which dispatches to the base
SubNSReply::namespaceMsg (MoQSession.h) — an XLOG(FATAL) << "Unimplemented" stub — aborting the
relay (SIGABRT).
Fix (two layers):
-
Gate the bidi branch on getDraftMajorVersion(getNegotiatedVersion()) >= 16 (the sibling
publishNamespaceDone path already does this), and/or only populate the handle for draft 16+.
-
Defense in depth: base SubNSReply::namespaceMsg/namespaceDoneMsg should return a WriteResult error
instead of XLOG(FATAL), so a mis-route degrades gracefully rather than crashing.
Repro: draft ≤15 leaf sends SUBSCRIBE_NAMESPACE → publisher announces matching namespace → relay
aborts. Seen via moqx relay_chain Direction 4 (--publish) when the leaf negotiates draft-14.
MoQRelay::publishNamespace's forwarding loop (relay/MoQRelay.cpp, from aea21fb) picks the draft-16+
bidi NAMESPACE path vs. the draft ≤15 separate-stream PUBLISH_NAMESPACE path by testing if
(info.namespacePublishHandle). It assumes the handle is null for draft ≤15, but
MoQRelaySession::handleSubscribeNamespace always constructs/stores a MoQNamespacePublishHandle
regardless of negotiated version. So when a draft-14 subscriber's SUBSCRIBE_NAMESPACE is matched by a
later announce, the relay calls namespacePublishHandle->namespaceMsg(), which dispatches to the base
SubNSReply::namespaceMsg (MoQSession.h) — an XLOG(FATAL) << "Unimplemented" stub — aborting the
relay (SIGABRT).
Fix (two layers):
Gate the bidi branch on getDraftMajorVersion(getNegotiatedVersion()) >= 16 (the sibling
publishNamespaceDone path already does this), and/or only populate the handle for draft 16+.
Defense in depth: base SubNSReply::namespaceMsg/namespaceDoneMsg should return a WriteResult error
instead of XLOG(FATAL), so a mis-route degrades gracefully rather than crashing.
Repro: draft ≤15 leaf sends SUBSCRIBE_NAMESPACE → publisher announces matching namespace → relay
aborts. Seen via moqx relay_chain Direction 4 (--publish) when the leaf negotiates draft-14.