Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
ca39ae6
Fix Coverity scan issues
embhorn Oct 19, 2026
e7347bb
F-15990 - Avoid double close of a rejected broker socket
embhorn Oct 19, 2026
6b72d90
F-15405 - Publish the Will for non-zero v5 DISCONNECT reason codes
embhorn Oct 19, 2026
6217995
F-15988 - Publish the old v5 Will on session takeover when required
embhorn Oct 19, 2026
d043220
F-15376 - Persist subscriptions when the SUBACK or UNSUBACK is deferred
embhorn Oct 19, 2026
9ee1d89
F-15989 - Release the inbound QoS 2 id when the PUBLISH topic copy fails
embhorn Oct 19, 2026
d790647
F-15991 - Keep the CONNECT Session Expiry when reclaiming an orphan
embhorn Oct 19, 2026
351a464
F-14357 - Send the first payload chunk when the PUBLISH header fills …
embhorn Oct 19, 2026
638f0b8
F-15377 - Report a zero-byte blocking socket write as a network error
embhorn Oct 19, 2026
00a1f61
F-15378 - Add MQTT-SN test for a zero-byte automatic response write
embhorn Oct 19, 2026
08ce42a
F-13833 - Give MQTT v5 Will Properties their own property scope
embhorn Oct 19, 2026
1931ae9
F-13835 - Skip broker PUBLISH writes whose payload was clamped to tx_buf
embhorn Oct 19, 2026
da26830
F-13801 - Queue QoS 1/2 Wills for offline persistent subscribers
embhorn Oct 19, 2026
a2c7188
F-15404 - Apply Message Expiry to dynamic broker queued deliveries
embhorn Oct 19, 2026
6aa3fea
Doc changes
embhorn Oct 19, 2026
908c70d
F-13808 - Reject a zero Receive Maximum in the property encoder
embhorn Oct 19, 2026
b9695a0
F-12452 - Reject reserved MQTT-SN TopicIdType values in encoders
embhorn Oct 19, 2026
e32ed3e
F-14609 - Reject AUTH packets that omit the Authentication Method
embhorn Oct 19, 2026
a5f7729
F-14585 - Mark the client disconnected when msg_cb abandons a payload
embhorn Oct 19, 2026
d2ebb5c
F-13834 - Reject v5 SUBACK and UNSUBACK without a Property Length
embhorn Oct 19, 2026
8ce7681
F-12464 - Refuse a v5 PUBLISH when the quota lock cannot be taken
embhorn Oct 20, 2026
ff139fb
F-12468 - Let SN_Client_WillTopicUpdate send the empty Will delete
embhorn Oct 20, 2026
9e4748e
Restore MqttProps_FindType and require an AUTH method with properties
embhorn Oct 20, 2026
233cec3
F-15375 - Accept only lowercase hex in POSIX persist record names
embhorn Oct 20, 2026
0daebf1
F-12450 - Check the property identifier against the Property Length
embhorn Oct 20, 2026
d3bdc0c
F-12449 - Read client flags under lockClient in KeepAlive and WaitType
embhorn Oct 20, 2026
27fcb81
F-13805 - Report native semaphore init failures from wm_SemInit
embhorn Oct 20, 2026
fb8db6e
F-14358 - Reset SN_Client_Connect state when the Will exchange fails
embhorn Oct 20, 2026
2837eaf
F-15374 - Reset ack wait state after Subscribe, Unsubscribe and Publish
embhorn Oct 20, 2026
bf7b5c8
F-16042 - Record PUBREL replay only for the client's own QoS 2 publishes
embhorn Oct 20, 2026
f152cc7
F-15403 - Send CONNACK 0x01 when an unsupported-level CONNECT won't d…
embhorn Oct 20, 2026
82ff725
F-13809 - Reject unassigned CONNACK return and reason codes in the cl…
embhorn Oct 20, 2026
d862777
F-14621 - Escape client IDs in persistence restore log messages
embhorn Oct 20, 2026
0095f7e
F-12451 - Check restored OUTQ packet IDs against the record key
embhorn Oct 20, 2026
8c23557
F-11491 - Report oversized POSIX persist records instead of truncating
embhorn Oct 20, 2026
c48c5c7
F-14195 - Send a v5 DISCONNECT reason before closing on broker errors
embhorn Oct 20, 2026
cb85c9a
F-13257 - Wipe restored topic copies freed on malformed persist records
embhorn Oct 20, 2026
ebdb03b
F-13875 - Wipe CONNECT credentials when a refused CONNACK is deferred
embhorn Oct 20, 2026
445666d
F-13258 - Wipe the client tx and rx buffers in MqttClient_DeInit
embhorn Oct 20, 2026
6ceeb80
F-14386 - Wipe the AES-GCM context after persist record crypto
embhorn Oct 20, 2026
89f377f
F-13875 - Run the deferred refused CONNACK test only in nonblock builds
embhorn Oct 20, 2026
7e09290
F-14183 - Wipe the whole tx_buf when a WILLMSG cannot be encoded
embhorn Oct 20, 2026
8ec6e59
F-13803 - Reject POSIX persist keys longer than the file name limit
embhorn Oct 20, 2026
5488ccd
F-13249 - Deliver MQTT-SN QoS 2 retransmits to the application once
embhorn Oct 20, 2026
3fd5afd
Reset the MQTT-SN wait state once a packet has been handled
embhorn Oct 20, 2026
8097a45
F-13249 - Drop the msgSN reset workaround from the SN QoS 2 test
embhorn Oct 20, 2026
b21f2c0
F-14584 - Fail a blocking wait that times out partway through a packet
embhorn Oct 20, 2026
96f3a8f
F-14610 - Hold back other packets until an enhanced-auth CONNACK
embhorn Oct 20, 2026
a1f0df5
F-16041 - Refuse new persistent sessions at the dynamic broker cap
embhorn Oct 20, 2026
774e19f
F-13806 - Add MqttClient_NetDisconnect_Wait and document the race
embhorn Oct 20, 2026
3e56ca7
F-5117 - Wait for an in-flight reader before unlinking a pending resp…
embhorn Oct 22, 2026
53b4775
Fixes from review
embhorn Oct 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/broker-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ jobs:
cflags: ""
wolfmqtt_opts: "--enable-broker --enable-v5 --enable-broker-persist --disable-broker-retained"
check_units: "yes"
- name: "Broker with persist + nonblock"
cflags: ""
wolfmqtt_opts: "--enable-broker --enable-v5 --enable-broker-persist --enable-nonblock"
check_units: "yes"

steps:
- name: Install dependencies
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -138,4 +138,6 @@ tests/test_mqtt_sn_client_mt_only
tests/test_mqtt_sn_client_nodata
tests/unit_tests
tests/test_mqtt_props_init
tests/test_mqtt_sem_init
tests/test_broker_log
tests/test_mqtt_curl_init
32 changes: 30 additions & 2 deletions BROKER.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,11 +165,39 @@ script or installer inherits the ambient umask - under a relaxed umask such as
mkdir -p /var/lib/wolfmqtt && chmod 0700 /var/lib/wolfmqtt
```

The POSIX backend names each record after its key in hex, so a key can be at
most `(NAME_MAX - 8) / 2` bytes: 123 on filesystems with the usual 255-byte
`NAME_MAX`. Sessions and subscriptions are keyed by client ID, retained
messages by topic, and offline-queue entries by client ID plus 3 bytes. With
this backend a client ID longer than 120 bytes loses its queued messages across
a restart, one longer than 123 bytes loses its whole session, and a retained
message whose topic is longer than 123 bytes is not kept. The broker still
serves them from memory while it runs. Use a custom backend through
`MqttBroker_SetPersistHooks()` if longer identifiers must persist.

A custom backend must follow the same contract as the POSIX one. `kv_get`
treats `*inout_len` as the buffer capacity on input and sets the record length
on success, returns `MQTT_CODE_ERROR_NOT_FOUND` for a missing key, and returns
`MQTT_CODE_ERROR_OUT_OF_BUFFER` - never a truncated success - for a record
larger than the buffer. Every key `kv_iter` hands to its callback must be
accepted unchanged by `kv_get` and `kv_del`; the broker deletes records it
finds while iterating and repeats until none match.

| Macro | Default | Description |
|---|---|---|
| `BROKER_MAX_PERSIST_SESSIONS` | 64 | Dynamic-memory persistent sessions retained across restarts |
| `BROKER_MAX_PERSIST_SESSIONS` | 64 | Dynamic-memory persistent sessions (connected and offline); a new persistent CONNECT beyond it is refused, existing sessions are never evicted |
| `BROKER_MAX_OFFLINE_MSGS_PER_SUB` | 32 | Offline queue depth per session |
| `WOLFMQTT_BROKER_PERSIST_SCHEMA_VER` | 5 | On-disk record schema version |
| `WOLFMQTT_BROKER_PERSIST_SCHEMA_VER` | 6 | On-disk record schema version |

Because existing persistent sessions are never evicted, any client allowed to
connect can use up `BROKER_MAX_PERSIST_SESSIONS` by opening persistent sessions
under fresh client IDs (a v3.1.1 CleanSession 0 session never expires); after
that, persistent CONNECTs with new client IDs are refused until sessions end,
and with persistence enabled the sessions survive a restart. Clients that
resume their own session are unaffected. Configure broker credentials
(`-u`/`-P`), size the cap for the deployment, and prefer bounded v5 Session
Expiry Intervals where this matters. The previous drop-oldest
policy let the same client destroy other clients' saved sessions instead.

### Encryption at rest

Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ These are the network connect / disconnect interfaces that wrap the MqttNet call

* `int MqttClient_NetConnect(MqttClient *client, const char* host, word16 port, int timeout_ms, int use_tls, MqttTlsCb cb);`
* `int MqttClient_NetDisconnect(MqttClient *client);`
* `int MqttClient_NetDisconnect_Wait(MqttClient *client);` - like `MqttClient_NetDisconnect`, but in `WOLFMQTT_MULTITHREAD` builds waits for other threads' network I/O on the client to finish first. Do not call it from a message, property or publish payload callback; where thread identities are available it returns `MQTT_CODE_ERROR_STAT` there instead of deadlocking.

Helper functions:

Expand Down Expand Up @@ -225,6 +226,8 @@ The multi-threading feature can also be used with the non-blocking socket (--ena

If you are having issues with thread synchronization on Linux consider using not the conditional signal (`WOLFMQTT_NO_COND_SIGNAL`).

With `WOLFMQTT_NO_COND_SIGNAL`, or with `WOLFMQTT_USER_THREADING` unless `WOLFMQTT_SEM_SIGNAL` is defined, a write-only publish or `MqttClient_CancelMessage` whose response another thread is decoding waits for that thread to release the receive lock instead of being signalled. A thread that blocks in `MqttClient_WaitMessage` can then hold them up until its read returns.

### Atomic publish and subscribe examples
In the `examples/pub-sub` folder, there are two simple client examples:
* mqtt-pub - publishes to a topic
Expand Down
Loading
Loading