mosquitto icon indicating copy to clipboard operation
mosquitto copied to clipboard

Malformed packet error at connection time when QOS level is 1 (At least once) and MQTT version 3.1

Open garinocyr opened this issue 2 years ago • 5 comments

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) MQTT_connect_message
  • Wireshark trace for connection request from mosquitto_pub using option "-V mqttv31" (Linux CentOS 7) MQTT_connect_message_mosquitto_pub
  • 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

garinocyr avatar Apr 27 '22 07:04 garinocyr

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").

ptjm avatar Apr 29 '22 19:04 ptjm

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.

garinocyr avatar May 02 '22 07:05 garinocyr

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

Daedaluz avatar May 02 '22 07:05 Daedaluz

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)?

garinocyr avatar May 06 '22 08:05 garinocyr

@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.

nXtArtur avatar Jun 24 '22 15:06 nXtArtur