MEDIUM: mqtt: support mqtt_is_valid and mqtt_field_value converters for MQTTv3.1

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.
This commit is contained in:
Dhruv Jain 2022-03-21 20:04:00 +05:30 committed by Christopher Faulet
parent 76fc07e9a0
commit 1295798139
3 changed files with 19 additions and 5 deletions

View File

@ -27,6 +27,7 @@
/* MQTT protocol version /* MQTT protocol version
* In MQTT 3.1.1, version is called "level" * 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_3_1_1 4
#define MQTT_VERSION_5_0 5 #define MQTT_VERSION_5_0 5

View File

@ -42,6 +42,11 @@ server s1 {
recv 22 recv 22
sendhex "21020000" sendhex "21020000"
expect_close expect_close
# MQTT 3.1 CONNECT packet (id: test_sub - username: test - passwd: passwd)
accept
recv 38
sendhex "20020000"
} -start } -start
server s2 { server s2 {
@ -225,3 +230,9 @@ client c2_50_1 -connect ${h1_fe2_sock} {
recv 39 recv 39
expect_close expect_close
} -run } -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

View File

@ -40,14 +40,14 @@ uint8_t mqtt_cpt_flags[MQTT_CPT_ENTRIES] = {
const struct ist mqtt_fields_string[MQTT_FN_ENTRIES] = { const struct ist mqtt_fields_string[MQTT_FN_ENTRIES] = {
[MQTT_FN_INVALID] = IST(""), [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_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_NAME] = IST("protocol_name"),
[MQTT_FN_PROTOCOL_VERSION] = IST("protocol_version"), /* MQTT 3.1.1: protocol_level */ [MQTT_FN_PROTOCOL_VERSION] = IST("protocol_version"), /* MQTT 3.1.1: protocol_level */
[MQTT_FN_CLIENT_IDENTIFIER] = IST("client_identifier"), [MQTT_FN_CLIENT_IDENTIFIER] = IST("client_identifier"),
[MQTT_FN_WILL_TOPIC] = IST("will_topic"), [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_USERNAME] = IST("username"),
[MQTT_FN_PASSWORD] = IST("password"), [MQTT_FN_PASSWORD] = IST("password"),
[MQTT_FN_KEEPALIVE] = IST("keepalive"), [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 : /* 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/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 * 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 */ /* read protocol_name */
parser = mqtt_read_string(parser, &mpkt->data.connect.var_hdr.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; goto end;
/* read protocol_version */ /* read protocol_version */
parser = mqtt_read_1byte_int(parser, &mpkt->data.connect.var_hdr.protocol_version); parser = mqtt_read_1byte_int(parser, &mpkt->data.connect.var_hdr.protocol_version);
if (!isttest(parser)) if (!isttest(parser))
goto end; 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) mpkt->data.connect.var_hdr.protocol_version != MQTT_VERSION_5_0)
goto end; goto end;