diff --git a/nestsClient/src/commonMain/kotlin/com/vitorpamplona/nestsclient/moq/lite/MoqLiteMessages.kt b/nestsClient/src/commonMain/kotlin/com/vitorpamplona/nestsclient/moq/lite/MoqLiteMessages.kt index 59d8af06d..b55f2e0ee 100644 --- a/nestsClient/src/commonMain/kotlin/com/vitorpamplona/nestsclient/moq/lite/MoqLiteMessages.kt +++ b/nestsClient/src/commonMain/kotlin/com/vitorpamplona/nestsclient/moq/lite/MoqLiteMessages.kt @@ -21,22 +21,38 @@ package com.vitorpamplona.nestsclient.moq.lite /** - * moq-lite ALPN strings. The on-the-wire framing for Subscribe / Group - * / Announce did NOT change between Lite-03 and Lite-04, so advertising - * both via `wt-available-protocols` is safe — the relay picks whichever - * it prefers and our existing codec paths handle either. We keep 03 in - * the list as the previously-tested target until the production relay's - * Lite-04 path has interop coverage. + * moq-lite ALPN strings. ONLY [LITE_03] is wire-compatible with the + * codec in [MoqLiteCodec]; the other constants are kept for + * documentation and future codec upgrades. + * + * Subscribe / Group framing is identical across Lite-03 and Lite-04, + * but Lite-04 reshapes Announce.hops into an `OriginList` + * (`kixelated/moq` commit 45db108, "moq-lite/moq-relay: hop-based + * clustering"), adds an `exclude_hop` field to AnnounceInterest, and + * adds an `rtt` field to Probe. A relay that picks Lite-04 with our + * Lite-03 codec on the wire desyncs on the first Announce exchange. + * Don't add [LITE_04] to `wt-available-protocols` until + * [MoqLiteCodec] is version-aware and [MoqLiteAnnounce.hops] is a + * list rather than a single varint. * * `"moql"` is the legacy combined ALPN that requires an in-band SETUP * exchange — kept here for completeness; not advertised by the * factory. * - * Source: `kixelated/moq-rs/rs/moq-lite/src/version.rs:21-26`, - * `@moq/lite/connection/connect.js:277`. + * Source: `kixelated/moq/rs/moq-lite/src/lite/version.rs`, + * `kixelated/moq/rs/moq-lite/src/lite/announce.rs:11-105`, + * `kixelated/moq/rs/moq-lite/src/lite/probe.rs:9-55`. */ object MoqLiteAlpn { const val LITE_03: String = "moq-lite-03" + + /** + * `moq-lite-04` ALPN string. Wire-incompatible with [MoqLiteCodec] + * today — see the object kdoc for the codec diff. Defined here so + * a future patch that lands version-aware Announce / Probe codecs + * can drop it into the [QuicWebTransportFactory] sub-protocol list + * without re-deriving the constant. + */ const val LITE_04: String = "moq-lite-04" const val LEGACY: String = "moql" } diff --git a/nestsClient/src/jvmAndroid/kotlin/com/vitorpamplona/nestsclient/transport/QuicWebTransportFactory.kt b/nestsClient/src/jvmAndroid/kotlin/com/vitorpamplona/nestsclient/transport/QuicWebTransportFactory.kt index f305fc24c..4f5fe7e59 100644 --- a/nestsClient/src/jvmAndroid/kotlin/com/vitorpamplona/nestsclient/transport/QuicWebTransportFactory.kt +++ b/nestsClient/src/jvmAndroid/kotlin/com/vitorpamplona/nestsclient/transport/QuicWebTransportFactory.kt @@ -91,18 +91,26 @@ class QuicWebTransportFactory( * `connection closed err=invalid value` on the relay side and a stalled * subscribe / `subscribe stream FIN before reply` on the client side. * - * `moq-lite-04` is also advertised because the production relay - * (moq.nostrnests.com) and the kixelated browser client both ship - * Lite-04 now; without it in our list a Lite-04-only deployment - * would refuse the CONNECT. The on-the-wire framing for Subscribe / - * Group / Announce did NOT change between Lite-03 and Lite-04, so - * our existing codec handles either selection. List `moq-lite-03` - * first because it's our previously-tested negotiation target — - * a relay that supports both should pick the listed-first option, - * and a Lite-04-only relay falls through to the second entry. + * **Lite-04 is intentionally NOT advertised** even though the kixelated + * browser client now ships it. Lite-04 reshapes the on-the-wire + * Announce.hops field from a single varint count into a full + * `OriginList` (`kixelated/moq` commit 45db108, "moq-lite/moq-relay: + * hop-based clustering"), adds an `exclude_hop` field to + * AnnounceInterest, and adds an `rtt` field to Probe — Subscribe and + * Group framing are unchanged but Announce framing diverges. Our codec + * speaks pure Lite-03; if a Lite-04-preferring relay picks + * `moq-lite-04` from our advertised list, the very first Announce + * exchange would desync (we'd encode/read a bare hops varint where + * the peer expects `len + len × u62`) and the connection would abort. + * Until [com.vitorpamplona.nestsclient.moq.lite.MoqLiteCodec] gains + * version-aware Announce / AnnounceInterest / Probe paths and + * [com.vitorpamplona.nestsclient.moq.lite.MoqLiteAnnounce.hops] + * becomes a list, advertising Lite-04 is a footgun. See + * [com.vitorpamplona.nestsclient.moq.lite.MoqLiteAlpn] for the + * known-version constants. */ private val webTransportSubProtocols: List = - listOf(MoqLiteAlpn.LITE_03, MoqLiteAlpn.LITE_04), + listOf(MoqLiteAlpn.LITE_03), ) : WebTransportFactory { override suspend fun connect( authority: String,