Skip to content

fix MQTT v5 client conformance violations in native and wasm clients - #164

Merged
fabracht merged 2 commits into
mainfrom
client-conformance-fixes
Sep 24, 2026
Merged

fabracht merged 2 commits into
mainfrom
client-conformance-fixes

Conversation

@fabracht

Copy link
Copy Markdown
Contributor

A client-side audit drove the real clients against a raw-byte fake broker for each of the 149 MQTT v5.0 normative statements that apply to a client. The native MqttClient failed about 40 MUST statements, and the wasm client had most of the same defects. All of them are fixed here, and each one is pinned by a test named after its OASIS statement ID.

Native client (mqtt5 0.41.0)

  • Unacked QoS 1/2 PUBLISH and PUBREL are now resent on session resume, with DUP=1, their original ids and order, and within the new Receive Maximum. QoS 1 entries are now released on PUBACK.
  • Packet ids are no longer reused while in flight. The send quota is reset per connection. The offline queue now goes through the normal publish path.
  • Outbound validation added for topic names, topic filters, $share filters, Topic Alias limits, Retain Available, Wildcard/Shared/SubId Available, Maximum Packet Size on SUBSCRIBE/UNSUBSCRIBE, and wildcard Response Topics.
  • Inbound checks added: reserved flags, Topic Alias resolution and limits, Receive Maximum (0x93), Maximum Packet Size (0x95), Subscription Identifier 0, and Request Problem Information=0.
  • On a protocol error the client now sends DISCONNECT with the right reason code, flushes it, and closes the connection. A server DISCONNECT also closes it. Nothing is written after the client's own DISCONNECT.
  • With deferred ack enabled, acks go out in arrival order.
  • WebSocket reads now reassemble packets from the byte stream. A text frame closes the connection, and a Ping frame no longer drops the session.
  • CONNECT now carries RPI, RRI and user properties. The client never sends AUTH without an Authentication Method, and it adopts the Assigned Client Identifier.
  • [MQTT-3.2.2-4] is strict by default. The new ConnectOptions::resume_existing_session option lets a fresh client resume a broker-held session on purpose. The CLI --no-clean-start, the broker bridge and the in-process conformance client set it.

Wasm client (mqtt5-wasm 1.5.0)

  • The same classes of fixes, plus: the missing PUBACK for inbound QoS 1 is now sent, and the decoder no longer loses bytes when several packets arrive in one frame.
  • New resumeExistingSession option. The session-recovery and qos2-recovery examples are updated to use it.

Breaking

  • A fresh client now closes on Session Present=1 unless resume_existing_session is set.
  • ConnectOptions has a new field.
  • Invalid outbound requests are now rejected before anything is sent.
  • The deprecated session retained-message store is removed, along with WebSocketConfig::with_tls_verification and verify_tls.

Tests

  • crates/mqtt5/tests/conf_client_{a,b,c,d}.rs: 137 tests.
  • crates/mqtt5-wasm/tests/conformance_client.rs: 65 tests, run under Node through wasm-bindgen-test.
  • cargo make ci-verify passes. Clippy pedantic and fmt are clean.

Versions: mqtt5 0.41.0, mqtt5-protocol 0.15.2, mqttv5-cli 0.28.8, mqtt5-wasm 1.5.0.

Comment thread crates/mqtt5/tests/conf_client_a.rs Dismissed
Comment thread crates/mqtt5/tests/conf_client_a.rs Dismissed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants