Skip to content

Fix MQTTv5 QoS 2 CONNACK interop and add WOLFMQTT_MAX_QOS build cap#537

Open
dgarske wants to merge 6 commits into
wolfSSL:masterfrom
dgarske:broker_fixes
Open

Fix MQTTv5 QoS 2 CONNACK interop and add WOLFMQTT_MAX_QOS build cap#537
dgarske wants to merge 6 commits into
wolfSSL:masterfrom
dgarske:broker_fixes

Conversation

@dgarske
Copy link
Copy Markdown
Member

@dgarske dgarske commented May 13, 2026

  • Fix MQTTv5 QoS 2 interop: stop emitting Maximum QoS = 2 in CONNACK ([MQTT-3.2.2.3.4] Protocol Error; mosquitto disconnects).
  • Add WOLFMQTT_MAX_QOS (0/1/2, default 2) wired through configure.ac (--enable-max-qos=N) and CMake (-DWOLFMQTT_MAX_QOS=N).
  • Capped builds compile out the broker QoS-2 state machine (PUBREC/PUBREL/PUBCOMP, inbound dedup), cap subscribe grants and will QoS, and DISCONNECT QoS > cap publishes with reason 0x9B QoS Not Supported. Client clamps max_qos against the build cap. ~2.6 KB .text savings at MAX_QOS=1.
  • CI: broker-check.yml adds MAX_QOS=0/1/2 entries (capped = build-only since broker.test has QoS-2 cases); cmake-build.yml now a matrix over the same values.
  • Minor: CMake broker+TLS include-order fix.

@dgarske dgarske self-assigned this May 13, 2026
Copilot AI review requested due to automatic review settings May 13, 2026 16:52
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Removes an invalid MQTT v5 CONNACK property that violated the spec and caused strict clients to disconnect.

Changes:

  • Drop emission of MQTT_PROP_MAX_QOS = 2 in CONNACK, which is a protocol error per [MQTT-3.2.2.3.4].
  • Add an explanatory comment documenting why the property is intentionally omitted.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@embhorn
Copy link
Copy Markdown
Member

embhorn commented May 13, 2026

Should this be a compile-time configuration option for the broker? Then if QoS-2 is max, don't send the property.

dgarske added 5 commits May 13, 2026 15:23
Builds with -DWOLFMQTT_MAX_QOS=1 (or 0) now compile out the broker's
inbound QoS-2 dedup state, BrokerHandle_PublishRel / PublishRec, and
the PUBLISH_REC/REL/COMP dispatch cases; subscribe grants are capped
at the build's max; PUBLISH at QoS > cap is rejected with a v5
DISCONNECT reason 0x9B (QoS Not Supported); will QoS is clamped on
CONNECT. Client side clamps initial max_qos and post-CONNACK property
value against the same cap so MqttPublishMsg rejects out-of-range
publishes locally.

Default build (WOLFMQTT_MAX_QOS=2) is unchanged: broker.test passes
in full, no behavior change.

Measured code-size delta on src/.libs/mqtt_broker (.text):
  default 48178 -> capped 45587 (-2591 bytes / -5.4%).

Verified against mosquitto_pub -q 2: capped broker disconnects with
"Message QoS not supported on broker, try a lower QoS."
… mqtt_types.h and reorder includes in mqtt_broker.c
@dgarske dgarske changed the title Fix for MQTTv5 QoS 2 interop Fix MQTTv5 QoS 2 CONNACK interop and add WOLFMQTT_MAX_QOS build cap May 14, 2026
@dgarske dgarske assigned embhorn and unassigned dgarske May 14, 2026
@dgarske dgarske requested review from Copilot and embhorn May 14, 2026 20:29
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 13 comments.

Comment thread src/mqtt_broker.c
Comment on lines +3715 to +3726
if (pub.qos > WOLFMQTT_MAX_QOS) {
WBLOG_ERR(broker,
"broker: PUBLISH QoS %d exceeds WOLFMQTT_MAX_QOS=%d sock=%d",
pub.qos, WOLFMQTT_MAX_QOS, (int)bc->sock);
#ifdef WOLFMQTT_V5
if (bc->protocol_level >= MQTT_CONNECT_PROTOCOL_LEVEL_5) {
(void)BrokerSend_Disconnect(bc, MQTT_REASON_QOS_NOT_SUPPORTED);
}
#endif
rc = MQTT_CODE_ERROR_MALFORMED_DATA;
goto publish_cleanup;
}
Comment thread src/mqtt_broker.c
Comment on lines +3276 to +3278
* sent Will QoS > advertised Max QoS would already be in
* Protocol Error territory, but for v3.1.1 (no advertisement)
* we silently downgrade rather than rejecting CONNECT. */
Comment thread wolfmqtt/mqtt_packet.h
Comment on lines +200 to +207
* Define in user_settings.h to compile a QoS-capped client/broker. Wired
* into broker CONNACK Maximum QoS property emission today; broader code
* gating lives on the mqtt_qos_max branch. */
#ifndef WOLFMQTT_MAX_QOS
#define WOLFMQTT_MAX_QOS 2
#endif
#if (WOLFMQTT_MAX_QOS < 0) || (WOLFMQTT_MAX_QOS > 2)
#error "WOLFMQTT_MAX_QOS must be 0, 1, or 2"
Comment thread wolfmqtt/mqtt_packet.h
/* Maximum QoS supported by this build. Legal values: 0, 1, 2. Default 2.
* Define in user_settings.h to compile a QoS-capped client/broker. Wired
* into broker CONNACK Maximum QoS property emission today; broader code
* gating lives on the mqtt_qos_max branch. */
Comment on lines +58 to +61
- name: "Broker MAX_QOS=1 (build only)"
cflags: ""
wolfmqtt_opts: "--enable-v5 --enable-broker --enable-max-qos=1"
skip_broker_test: "yes"
Comment thread scripts/broker.test
T12_PROPS=yes
grep -q "Property CB: Type 37" "${TMP_DIR}/t12.log" 2>/dev/null || T12_PROPS=no
grep -q "Property CB: Type 36" "${TMP_DIR}/t12.log" 2>/dev/null || T12_PROPS=no
grep -q "Property CB: Type 40" "${TMP_DIR}/t12.log" 2>/dev/null || T12_PROPS=no
Comment on lines +17 to +19
# Smoke-build the CMake project under each WOLFMQTT_MAX_QOS value
# to keep the build-option plumbing exercised. "" means leave the
# cache value at its 2 default.
Comment thread src/mqtt_broker.c
Comment on lines 27 to +28
#include "wolfmqtt/mqtt_broker.h"
#include "wolfmqtt/mqtt_types.h"
Comment thread wolfmqtt/mqtt_broker.h
Comment on lines +26 to +31
#if !defined(WOLFMQTT_USER_SETTINGS) && \
!defined(_WIN32) && !defined(USE_WINDOWS_API)
/* If options.h is missing use the "./configure" script. Otherwise, copy
* the template "wolfmqtt/options.h.in" into "wolfmqtt/options.h" */
#include <wolfmqtt/options.h>
#endif
Comment thread src/mqtt_broker.c
Comment on lines +3461 to +3472
/* [MQTT-3.2.2.3.4] Maximum QoS property MUST be 0 or 1. Absence
* of the property signals server supports Maximum QoS 2. Emitting
* Maximum QoS = 2 is a Protocol Error and strict v5 clients (e.g.
* mosquitto) will disconnect on receipt. Emit the property only
* when this build caps below QoS 2 via WOLFMQTT_MAX_QOS. */
#if WOLFMQTT_MAX_QOS < 2
prop = MqttProps_Add(&ack.props);
if (prop != NULL) {
prop->type = MQTT_PROP_MAX_QOS;
prop->data_byte = MQTT_QOS_2;
prop->data_byte = (byte)WOLFMQTT_MAX_QOS;
}
#endif
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.

3 participants