6.6 KiB
6.6 KiB
MQTT Connection Type Port Design
Goal
Port MQTT-related connection type parity from Go into the .NET server for three scoped areas:
- JWT
allowed_connection_typesbehavior forMQTT/MQTT_WS(plus existing known types). /connzfiltering bymqtt_client.- Full MQTT configuration parsing from
mqtt {}config blocks (all GoMQTTOptsfields).
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
MQTTOptsfields). - Expanded
MqttOptsVarzmonitoring output. - Unit/integration tests for new and updated behavior.
differences.mdupdates after implementation is verified.
- Out of scope:
- Full MQTT transport implementation (listener, protocol parser, sessions).
- WebSocket transport implementation.
- Leaf/route/gateway transport plumbing.
Architecture
- Add an auth-facing connection-type model that can be passed through
ClientAuthContext. - Implement Go-style allowed connection type conversion and matching in
JwtAuthenticator:- normalize input to uppercase.
- retain recognized types.
- collect unknown types as non-fatal if at least one valid type remains.
- reject when only unknown types are present.
- enforce current connection type against the resulting allowed set.
- Extend connz monitoring options to parse
mqtt_clientand apply exact-match filtering before sort/pagination.
Components
JWT Connection-Type Enforcement
src/NATS.Server/Auth/IAuthenticator.cs- Extend
ClientAuthContextwith a connection-type value.
- Extend
src/NATS.Server/Auth/Jwt/JwtConnectionTypes.cs(new)- Canonical constants for known connection types:
STANDARD,WEBSOCKET,LEAFNODE,LEAFNODE_WS,MQTT,MQTT_WS,INPROCESS.
- Helper(s) for normalization and validation behavior.
- Canonical constants for known connection types:
src/NATS.Server/Auth/JwtAuthenticator.cs- Evaluate
userClaims.Nats?.AllowedConnectionTypesusing Go-compatible semantics. - Enforce against current
ClientAuthContext.ConnectionType.
- Evaluate
src/NATS.Server/NatsClient.cs- Populate auth context connection type (currently
STANDARD).
- Populate auth context connection type (currently
Connz MQTT Client Filtering
src/NATS.Server/Monitoring/Connz.cs- Add
MqttClienttoConnzOptionswith JSON fieldmqtt_client.
- Add
src/NATS.Server/Monitoring/ConnzHandler.cs- Parse
mqtt_clientquery param. - Filter connection list by exact
MqttClientmatch when provided.
- Parse
src/NATS.Server/Monitoring/ClosedClient.cs- Add
MqttClientfield to closed snapshots.
- Add
src/NATS.Server/NatsServer.cs- Persist
MqttClientintoClosedClientsnapshot (empty for now).
- Persist
MQTT Configuration Parsing
src/NATS.Server/MqttOptions.cs(new)- Full model matching Go
MQTTOptsstruct (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
- Network:
- Full model matching Go
src/NATS.Server/NatsOptions.cs- Add
Mqttproperty of typeMqttOptions?.
- Add
src/NATS.Server/Configuration/ConfigProcessor.cs- Add
ParseMqtt()formqtt {}config block with Go-compatible key aliases:host/net→ Host,listen→ Host+Portack_wait/ackwait→ AckWaitmax_ack_pending/max_pending/max_inflight→ MaxAckPendingjs_domain→ JsDomainjs_api_timeout/api_timeout→ JsApiTimeoutconsumer_inactive_threshold/consumer_auto_cleanup→ ConsumerInactiveThreshold- Nested
tls {}andauthorization {}/authentication {}blocks
- Add
src/NATS.Server/Monitoring/Varz.cs- Expand
MqttOptsVarzfrom 3 fields to full monitoring-visible set.
- Expand
src/NATS.Server/Monitoring/VarzHandler.cs- Populate expanded
MqttOptsVarzfromNatsOptions.Mqtt.
- Populate expanded
Data Flow
- Client sends
CONNECT. NatsClient.ProcessConnectAsyncbuildsClientAuthContextwithConnectionType=STANDARD.AuthServiceinvokesJwtAuthenticatorfor JWT-based auth.JwtAuthenticator:- converts
allowed_connection_typesto valid/unknown buckets. - rejects unknown-only lists.
- enforces connection-type membership when valid list is non-empty.
- converts
- Monitoring request
/connz:ConnzHandler.ParseQueryParamsreadsmqtt_client.- open/closed conn rows are materialized.
- rows are filtered on exact
MqttClientwhen filter is present. - sorting and pagination run on filtered results.
Error Handling and Compatibility
- Auth failures remain non-throwing (
Authenticatereturnsnull). - Unknown connection type tokens in JWT are tolerated only when at least one known allowed type remains.
- Unknown-only allowed lists are rejected to avoid unintended allow-all behavior.
mqtt_clientquery parsing is lenient and string-based; empty filter means no filter.- Existing JSON schema compatibility is preserved.
Current Runtime Limitation (Explicit)
- MQTT transport is not implemented yet in this repository.
- Runtime connection type currently resolves to
STANDARDin auth context. mqtt_clientvalues 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- allow
STANDARDfor current client context. - reject
MQTTfor current client context. - allow mixed known+unknown when current type is known allowed.
- reject unknown-only list.
- validate case normalization behavior.
- allow
tests/NATS.Server.Tests/MonitorTests.cs/connz?mqtt_client=<id>returns matching connections only./connz?state=closed&mqtt_client=<id>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 {}andauthorization {}blocks within mqtt. - Varz MQTT section populated from config.
- Parse valid
Success Criteria
- JWT
allowed_connection_typesbehavior matches Go semantics for known/unknown mixing and unknown-only rejection. /connzsupports exactmqtt_clientfiltering for open and closed sets.mqtt {}config block parses all GoMQTTOptsfields with aliases.MqttOptsVarzincludes full monitoring output.- Added tests pass.
differences.mdaccurately reflects implemented parity.