mosquitto
mosquitto copied to clipboard
Malformed packet error at connection time when QOS level is 1 (At least once) and MQTT version 3.1
Environment
- System running Mosquitto: Linux CentOS 7
- Using docker image: eclipse-mosquitto:latest (2.0.14)
- System trying to connect and publish MQTT topics: OpenVMS 8.4
- Library used to connect and publish MQTT topics: librabbitmq with plugin MQTT (version 3.1)
Describe the bug
- When connecting to Mosquitto, a connection failure occurs with the following trace in Mosquitto log file
...
2022-04-26T16:42:52: New connection from xxx.xxx.xxx.xxx:61289 on port 1883.
2022-04-26T16:42:52: Client <unknown> disconnected due to malformed packet.
...
- Default QOS level set at connection time by librabbitmq is 1 (At least once)
Expected behaviour
- Connection success with no malformed packet error raised
Remarks
- This bug does not occur with Mosquitto version 1.3.5 (build date 2014-10-08 22:00:48+0000)
Analysis
- Wireshark trace for connection request from librabbitmq (OpenVMS 8.4)
- Wireshark trace for connection request from mosquitto_pub using option "-V mqttv31" (Linux CentOS 7)
- There is a difference with the QOS level value in the fixed header
- librabbitmq sets it to 1 (At least once)
- mosquitto_pub sets it to 0 (At most once)
- Modifying the MQTT message generated by librabbitmq (using Wireshark trace and TCPReplay tool) with QOS level set to 1 makes Mosquitto 2.0.14 accept connection
- The MQTT version 3.1 specification does not mention the obligation to set the QOS level value to 0 for CONNECT message type
The problem is with the first byte of the message (labelled by wireshark as "Header flags"). The one that's failing has 0x12, but this is invalid -- there are no flags defined for CONNECT, so the only valid control byte for a connect message is 0x10. Mosquitto closes the connection as required by the spec (section 2.2.2 "If invalid flags are received, the receiver MUST close the Network Connection").
Thanks a lot for your time and answer!
The problem here is with MQTT version 3.1. Reading the specification (cf. https://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/mqtt-v3r1.html#connect from https://mqtt.org/mqtt-specification/ link), it is not invalid to have header flags set as they are not used in the CONNECT message (see section 3.1. CONNECT - Client requests a connection to a server / Fixed header). For CONNECT message, Mosquitto should simply ignore them and allow connection anyway. This is the behaviour of Mosquitto version 1.3.5.
the specification you link also states:
2.6. Unused bits
Any bits marked as unused should be set to zero (0).
Probably later clarified / extended to the section 2.2.2 referred to by @ptjm in MQTT v3.1.1 spec
Funny note; I don't see the 2.6 section in the TOC.
Edit: I'll put a link here
I'm afraid the MQTT 3.1 specification leads to interpretation. The section 2.6 uses "should" and not "must", which does not have the same meaning in RFC key words.
Is there any chance to see a fix for this issue to match the behaviour of Mosquitto version 1.3.5 (issue does not appear with this version)?
@ralight The same problem I have with the publish command with an MQTT Client V3.1.1 to Mosquitto Broker V2.0.14, when QOS=1, with the Ack:
Frame 21861: 134 bytes on wire (1072 bits), 134 bytes captured (1072 bits) on interface \Device\NPF_Loopback, id 0 Null/Loopback Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1 Transmission Control Protocol, Src Port: 23943, Dst Port: 1883, Seq: 160, Ack: 66, Len: 90 MQ Telemetry Transport Protocol, Publish Message Header Flags: 0x32, Message Type: Publish Message, QoS Level: At least once delivery (Acknowledged deliver) 0011 .... = Message Type: Publish Message (3) .... 0... = DUP Flag: Not set .... .01. = QoS Level: At least once delivery (Acknowledged deliver) (1) .... ...0 = Retain: Not set Msg Len: 44 Topic Length: 28 Topic: Topic1/Topic2/topic2/topic14 Message Identifier: 1
Frame 21865: 46 bytes on wire (368 bits), 46 bytes captured (368 bits) on interface \Device\NPF_Loopback, id 0 Null/Loopback Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1 Transmission Control Protocol, Src Port: 23943, Dst Port: 1883, Seq: 250, Ack: 70, Len: 2 MQ Telemetry Transport Protocol, Publish Ack Header Flags: 0x40, Message Type: Publish Ack 0100 .... = Message Type: Publish Ack (4) .... 0000 = Reserved: 0 Msg Len: 0 [Malformed Packet: MQTT] [Expert Info (Error/Malformed): Malformed Packet (Exception occurred)] [Malformed Packet (Exception occurred)] [Severity level: Error] [Group: Malformed] [Community ID: 1:F5Gaa7BogGEjvzRNcDMCnDhD4do=]
Set QOS=0 at publish, it is accepted by the Mosquitto Broker V2.0.14.