diff --git a/docs/plans/2026-02-23-mqtt-connection-type-design.md b/docs/plans/2026-02-23-mqtt-connection-type-design.md index 80179d3..bd65506 100644 --- a/docs/plans/2026-02-23-mqtt-connection-type-design.md +++ b/docs/plans/2026-02-23-mqtt-connection-type-design.md @@ -1,18 +1,21 @@ # MQTT Connection Type Port Design ## Goal -Port MQTT-related connection type parity from Go into the .NET server for two scoped areas: +Port MQTT-related connection type parity from Go into the .NET server for three scoped areas: 1. JWT `allowed_connection_types` behavior for `MQTT` / `MQTT_WS` (plus existing known types). 2. `/connz` filtering by `mqtt_client`. +3. Full MQTT configuration parsing from `mqtt {}` config blocks (all Go `MQTTOpts` fields). ## Scope - In scope: - JWT allowed connection type normalization and enforcement semantics. - `/connz?mqtt_client=` option parsing and filtering. + - MQTT configuration model and config file parsing (all Go `MQTTOpts` fields). + - Expanded `MqttOptsVarz` monitoring output. - Unit/integration tests for new and updated behavior. - `differences.md` updates after implementation is verified. - Out of scope: - - Full MQTT transport implementation. + - Full MQTT transport implementation (listener, protocol parser, sessions). - WebSocket transport implementation. - Leaf/route/gateway transport plumbing. @@ -27,6 +30,8 @@ Port MQTT-related connection type parity from Go into the .NET server for two sc - Extend connz monitoring options to parse `mqtt_client` and apply exact-match filtering before sort/pagination. ## Components + +### JWT Connection-Type Enforcement - `src/NATS.Server/Auth/IAuthenticator.cs` - Extend `ClientAuthContext` with a connection-type value. - `src/NATS.Server/Auth/Jwt/JwtConnectionTypes.cs` (new) @@ -38,6 +43,8 @@ Port MQTT-related connection type parity from Go into the .NET server for two sc - Enforce against current `ClientAuthContext.ConnectionType`. - `src/NATS.Server/NatsClient.cs` - Populate auth context connection type (currently `STANDARD`). + +### Connz MQTT Client Filtering - `src/NATS.Server/Monitoring/Connz.cs` - Add `MqttClient` to `ConnzOptions` with JSON field `mqtt_client`. - `src/NATS.Server/Monitoring/ConnzHandler.cs` @@ -48,6 +55,30 @@ Port MQTT-related connection type parity from Go into the .NET server for two sc - `src/NATS.Server/NatsServer.cs` - Persist `MqttClient` into `ClosedClient` snapshot (empty for now). +### MQTT Configuration Parsing +- `src/NATS.Server/MqttOptions.cs` (new) + - Full model matching Go `MQTTOpts` struct (opts.go:613-707): + - Network: `Host`, `Port` + - Auth override: `NoAuthUser`, `Username`, `Password`, `Token`, `AuthTimeout` + - TLS: `TlsCert`, `TlsKey`, `TlsCaCert`, `TlsVerify`, `TlsTimeout`, `TlsMap`, `TlsPinnedCerts` + - JetStream: `JsDomain`, `StreamReplicas`, `ConsumerReplicas`, `ConsumerMemoryStorage`, `ConsumerInactiveThreshold` + - QoS: `AckWait`, `MaxAckPending`, `JsApiTimeout` +- `src/NATS.Server/NatsOptions.cs` + - Add `Mqtt` property of type `MqttOptions?`. +- `src/NATS.Server/Configuration/ConfigProcessor.cs` + - Add `ParseMqtt()` for `mqtt {}` config block with Go-compatible key aliases: + - `host`/`net` → Host, `listen` → Host+Port + - `ack_wait`/`ackwait` → AckWait + - `max_ack_pending`/`max_pending`/`max_inflight` → MaxAckPending + - `js_domain` → JsDomain + - `js_api_timeout`/`api_timeout` → JsApiTimeout + - `consumer_inactive_threshold`/`consumer_auto_cleanup` → ConsumerInactiveThreshold + - Nested `tls {}` and `authorization {}`/`authentication {}` blocks +- `src/NATS.Server/Monitoring/Varz.cs` + - Expand `MqttOptsVarz` from 3 fields to full monitoring-visible set. +- `src/NATS.Server/Monitoring/VarzHandler.cs` + - Populate expanded `MqttOptsVarz` from `NatsOptions.Mqtt`. + ## Data Flow 1. Client sends `CONNECT`. 2. `NatsClient.ProcessConnectAsync` builds `ClientAuthContext` with `ConnectionType=STANDARD`. @@ -73,6 +104,7 @@ Port MQTT-related connection type parity from Go into the .NET server for two sc - MQTT transport is not implemented yet in this repository. - Runtime connection type currently resolves to `STANDARD` in auth context. - `mqtt_client` values remain empty until MQTT path populates them. +- MQTT config is parsed and stored but no listener is started. ## Testing Strategy - `tests/NATS.Server.Tests/JwtAuthenticatorTests.cs` @@ -85,9 +117,16 @@ Port MQTT-related connection type parity from Go into the .NET server for two sc - `/connz?mqtt_client=` returns matching connections only. - `/connz?state=closed&mqtt_client=` filters closed snapshots. - non-existing ID yields empty connection set. +- `tests/NATS.Server.Tests/ConfigProcessorTests.cs` (or similar) + - Parse valid `mqtt {}` block with all fields. + - Parse config with aliases (ackwait vs ack_wait, host vs net, etc.). + - Parse nested `tls {}` and `authorization {}` blocks within mqtt. + - Varz MQTT section populated from config. ## Success Criteria - JWT `allowed_connection_types` behavior matches Go semantics for known/unknown mixing and unknown-only rejection. - `/connz` supports exact `mqtt_client` filtering for open and closed sets. +- `mqtt {}` config block parses all Go `MQTTOpts` fields with aliases. +- `MqttOptsVarz` includes full monitoring output. - Added tests pass. - `differences.md` accurately reflects implemented parity.