From b6004e08c93b9b06c1a9980fe60814964499b0ad Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 17 Sep 2021 13:01:34 +0100 Subject: [PATCH] mqtt: allow indicating client_id is not on heap Not sure why we don't leave any freeing to the caller, but since we don't allow indicating that the provided client id should not be freed. --- include/libwebsockets/lws-mqtt.h | 6 +++++- lib/roles/mqtt/client/client-mqtt-handshake.c | 2 +- lib/roles/mqtt/client/client-mqtt.c | 10 +++++++--- lib/roles/mqtt/private-lib-roles-mqtt.h | 2 +- lib/secure-streams/protocols/ss-mqtt.c | 2 +- .../minimal-mqtt-client/minimal-mqtt-client.c | 1 + 6 files changed, 16 insertions(+), 7 deletions(-) diff --git a/include/libwebsockets/lws-mqtt.h b/include/libwebsockets/lws-mqtt.h index 462374d4f..71193e662 100644 --- a/include/libwebsockets/lws-mqtt.h +++ b/include/libwebsockets/lws-mqtt.h @@ -70,8 +70,10 @@ typedef struct lws_mqtt_client_connect_param_s { uint16_t keep_alive; /* MQTT keep alive interval in seconds */ - uint8_t clean_start; /* MQTT clean + uint8_t clean_start:1; /* MQTT clean session */ + uint8_t client_id_nofree:1; + /**< do not free the client id */ struct { const char *topic; const char *message; @@ -143,6 +145,8 @@ typedef enum { /* flags from byte 8 of C_TO_S CONNECT */ typedef enum { + LMQCFT_CLIENT_ID_NOFREE = (1 << 8), + /* only the low 8 are standardized and go out in the protocol */ LMQCFT_USERNAME = (1 << 7), LMQCFT_PASSWORD = (1 << 6), LMQCFT_WILL_RETAIN = (1 << 5), diff --git a/lib/roles/mqtt/client/client-mqtt-handshake.c b/lib/roles/mqtt/client/client-mqtt-handshake.c index 009838bef..ffdf262d5 100644 --- a/lib/roles/mqtt/client/client-mqtt-handshake.c +++ b/lib/roles/mqtt/client/client-mqtt-handshake.c @@ -77,7 +77,7 @@ lws_mqtt_client_send_connect(struct lws *wsi) *p++ = 'T'; *p++ = 'T'; *p++ = MQTT_VER_3_1_1; - *p++ = c->conn_flags; + *p++ = (uint8_t)c->conn_flags; lws_ser_wu16be(p, c->keep_alive_secs); p += 2; diff --git a/lib/roles/mqtt/client/client-mqtt.c b/lib/roles/mqtt/client/client-mqtt.c index 5ad4471a6..6529fdc99 100644 --- a/lib/roles/mqtt/client/client-mqtt.c +++ b/lib/roles/mqtt/client/client-mqtt.c @@ -120,7 +120,11 @@ lws_create_client_mqtt_object(const struct lws_client_connect_info *i, if (cp->clean_start || !(cp->client_id && cp->client_id[0])) c->conn_flags = LMQCFT_CLEAN_START; - lws_free((void *)cp->client_id); + if (cp->client_id_nofree) + c->conn_flags |= LMQCFT_CLIENT_ID_NOFREE; + + if (!(c->conn_flags & LMQCFT_CLIENT_ID_NOFREE)) + lws_free((void *)cp->client_id); c->keep_alive_secs = cp->keep_alive; c->aws_iot = cp->aws_iot; @@ -138,8 +142,8 @@ lws_create_client_mqtt_object(const struct lws_client_connect_info *i, if (!c->will.message) goto oom2; } - c->conn_flags = (uint8_t)(unsigned int)(c->conn_flags | ((cp->will_param.qos << 3) & LMQCFT_WILL_QOS_MASK)); - c->conn_flags |= (uint8_t)((!!cp->will_param.retain) * LMQCFT_WILL_RETAIN); + c->conn_flags = (uint16_t)(unsigned int)(c->conn_flags | ((cp->will_param.qos << 3) & LMQCFT_WILL_QOS_MASK)); + c->conn_flags |= (uint16_t)((!!cp->will_param.retain) * LMQCFT_WILL_RETAIN); } if (cp->username && diff --git a/lib/roles/mqtt/private-lib-roles-mqtt.h b/lib/roles/mqtt/private-lib-roles-mqtt.h index 4c225bb2b..a1f5d23c3 100644 --- a/lib/roles/mqtt/private-lib-roles-mqtt.h +++ b/lib/roles/mqtt/private-lib-roles-mqtt.h @@ -346,7 +346,7 @@ typedef struct lws_mqttc { uint8_t retain; } will; uint16_t keep_alive_secs; - uint8_t conn_flags; + uint16_t conn_flags; uint8_t aws_iot; } lws_mqttc_t; diff --git a/lib/secure-streams/protocols/ss-mqtt.c b/lib/secure-streams/protocols/ss-mqtt.c index 9c0ec0ee0..2c3c52222 100644 --- a/lib/secure-streams/protocols/ss-mqtt.c +++ b/lib/secure-streams/protocols/ss-mqtt.c @@ -490,7 +490,7 @@ secstream_connect_munge_mqtt(lws_ss_handle_t *h, char *buf, size_t len, } ct->ccp.keep_alive = h->policy->u.mqtt.keep_alive; - ct->ccp.clean_start = h->policy->u.mqtt.clean_start; + ct->ccp.clean_start = (h->policy->u.mqtt.clean_start & 1u); ct->ccp.will_param.qos = h->policy->u.mqtt.will_qos; ct->ccp.will_param.retain = h->policy->u.mqtt.will_retain; ct->ccp.aws_iot = h->policy->u.mqtt.aws_iot; diff --git a/minimal-examples/mqtt-client/minimal-mqtt-client/minimal-mqtt-client.c b/minimal-examples/mqtt-client/minimal-mqtt-client/minimal-mqtt-client.c index 948cbbda8..8eb954240 100644 --- a/minimal-examples/mqtt-client/minimal-mqtt-client/minimal-mqtt-client.c +++ b/minimal-examples/mqtt-client/minimal-mqtt-client/minimal-mqtt-client.c @@ -41,6 +41,7 @@ static const lws_mqtt_client_connect_param_t client_connect_param = { .client_id = "lwsMqttClient", .keep_alive = 60, .clean_start = 1, + .client_id_nofree = 1, .will_param = { .topic = "good/bye", .message = "sign-off",