]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: mqtt: support mqtt_is_valid and mqtt_field_value converters for MQTTv3.1
authorDhruv Jain <dhruv.jain93@gmail.com>
Mon, 21 Mar 2022 14:34:00 +0000 (20:04 +0530)
committerChristopher Faulet <cfaulet@haproxy.com>
Tue, 22 Mar 2022 08:25:52 +0000 (09:25 +0100)
In MQTTv3.1, protocol name is "MQIsdp" and protocol level is 3. The mqtt
converters(mqtt_is_valid and mqtt_field_value) did not work for clients on
mqttv3.1 because the mqtt_parse_connect() marked the CONNECT message invalid
if either the protocol name is not "MQTT" or the protocol version is other than
v3.1.1 or v5.0. To fix it, we have added the mqttv3.1 protocol name and version
as part of the checks.

This patch fixes the mqtt converters to support mqttv3.1 clients as well (issue #1600).
It must be backported to 2.4.

include/haproxy/mqtt-t.h
reg-tests/converter/mqtt.vtc
src/mqtt.c

index 9377021782b3f255dc2614de8ee5769284258024..710fd87db4f54ac68f146e9f4381b33c87413481 100644 (file)
@@ -27,6 +27,7 @@
 /* MQTT protocol version
  * In MQTT 3.1.1, version is called "level"
  */
+#define MQTT_VERSION_3_1      3
 #define MQTT_VERSION_3_1_1    4
 #define MQTT_VERSION_5_0      5
 
index 60458a3fec8a7953e70f3936b34883ad5e776d1b..fc3dacae1498cf2a489c49cc09347e6d73235cd2 100644 (file)
@@ -42,6 +42,11 @@ server s1 {
     recv 22
     sendhex "21020000"
     expect_close
+
+    # MQTT 3.1 CONNECT packet (id: test_sub - username: test - passwd: passwd)
+    accept
+    recv 38
+    sendhex "20020000"
 } -start
 
 server s2 {
@@ -225,3 +230,9 @@ client c2_50_1 -connect ${h1_fe2_sock} {
     recv 39
     expect_close
 } -run
+
+client c3_31_1 -connect ${h1_fe1_sock} {
+    # Valid MQTT 3.1 CONNECT packet (id: test_sub - username: test - passwd: passwd)
+    sendhex "102400064d514973647003c200000008746573745f7375620004746573740006706173737764"
+    recv 4
+} -run
\ No newline at end of file
index ebdb57d4e34e72670df77c9bdb851c676497c350..5688296e52bc66152a4445d4480a0f36e8dc0410 100644 (file)
@@ -40,14 +40,14 @@ uint8_t mqtt_cpt_flags[MQTT_CPT_ENTRIES] = {
 const struct ist mqtt_fields_string[MQTT_FN_ENTRIES] = {
        [MQTT_FN_INVALID]                            = IST(""),
 
-       /* it's MQTT 3.1.1 and 5.0, those fields have no unique id, so we use strings */
+       /* it's MQTT 3.1, 3.1.1 and 5.0, those fields have no unique id, so we use strings */
        [MQTT_FN_FLAGS]                              = IST("flags"),
-       [MQTT_FN_REASON_CODE]                        = IST("reason_code"),       /* MQTT 3.1.1: return_code */
+       [MQTT_FN_REASON_CODE]                        = IST("reason_code"),       /* MQTT 3.1 and 3.1.1: return_code */
        [MQTT_FN_PROTOCOL_NAME]                      = IST("protocol_name"),
        [MQTT_FN_PROTOCOL_VERSION]                   = IST("protocol_version"),  /* MQTT 3.1.1: protocol_level */
        [MQTT_FN_CLIENT_IDENTIFIER]                  = IST("client_identifier"),
        [MQTT_FN_WILL_TOPIC]                         = IST("will_topic"),
-       [MQTT_FN_WILL_PAYLOAD]                       = IST("will_payload"),      /* MQTT 3.1.1: will_message */
+       [MQTT_FN_WILL_PAYLOAD]                       = IST("will_payload"),      /* MQTT 3.1 and 3.1.1: will_message */
        [MQTT_FN_USERNAME]                           = IST("username"),
        [MQTT_FN_PASSWORD]                           = IST("password"),
        [MQTT_FN_KEEPALIVE]                          = IST("keepalive"),
@@ -695,6 +695,7 @@ struct ist mqtt_field_value(struct ist msg, int type, int fieldname_id)
 }
 
 /* Parses a CONNECT packet :
+ *   https://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/mqtt-v3r1.html#connect
  *   https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718028
  *   https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901033
  *
@@ -718,14 +719,15 @@ static int mqtt_parse_connect(struct ist parser, struct mqtt_pkt *mpkt)
         */
        /* read protocol_name */
        parser = mqtt_read_string(parser, &mpkt->data.connect.var_hdr.protocol_name);
-       if (!isttest(parser) || !isteqi(mpkt->data.connect.var_hdr.protocol_name, ist("MQTT")))
+       if (!isttest(parser) || !(isteqi(mpkt->data.connect.var_hdr.protocol_name, ist("MQTT")) || isteqi(mpkt->data.connect.var_hdr.protocol_name, ist("MQIsdp"))))
                goto end;
 
        /* read protocol_version */
        parser = mqtt_read_1byte_int(parser, &mpkt->data.connect.var_hdr.protocol_version);
        if (!isttest(parser))
                goto end;
-       if (mpkt->data.connect.var_hdr.protocol_version != MQTT_VERSION_3_1_1 &&
+       if (mpkt->data.connect.var_hdr.protocol_version != MQTT_VERSION_3_1 &&
+           mpkt->data.connect.var_hdr.protocol_version != MQTT_VERSION_3_1_1 &&
            mpkt->data.connect.var_hdr.protocol_version != MQTT_VERSION_5_0)
                goto end;