From 75b93e040afde6bff84fdd24b8b555205a4624f8 Mon Sep 17 00:00:00 2001 From: Phil Dubach Date: Wed, 5 Apr 2017 14:43:55 -0700 Subject: [PATCH 1/3] Fix crash handling publish with invalid predef topic ID. --- rsmb/src/MQTTSProtocol.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/rsmb/src/MQTTSProtocol.c b/rsmb/src/MQTTSProtocol.c index 049dc68..889a9c2 100644 --- a/rsmb/src/MQTTSProtocol.c +++ b/rsmb/src/MQTTSProtocol.c @@ -715,16 +715,16 @@ int MQTTSProtocol_handlePublishes(void* pack, int sock, char* clientAddr, Client if (origPreDefinedTopicName) { expandedPreDefinedTopicName = MQTTSProtocol_replaceTopicNamePlaceholders(client, origPreDefinedTopicName) ; - } - // If original and expanded predef topic names are same, use expanded - // while it is already a copy of orig name - if (strcmp(origPreDefinedTopicName, expandedPreDefinedTopicName) == 0) - { - topicName = expandedPreDefinedTopicName ; - } else { - topicName = malloc(strlen(origPreDefinedTopicName)+1); - strcpy(topicName, origPreDefinedTopicName); + // If original and expanded predef topic names are same, use expanded + // while it is already a copy of orig name + if (strcmp(origPreDefinedTopicName, expandedPreDefinedTopicName) == 0) + { + topicName = expandedPreDefinedTopicName ; + } else { + topicName = malloc(strlen(origPreDefinedTopicName)+1); + strcpy(topicName, origPreDefinedTopicName); + } } } // Short topic names From d47e6d201554544dae81fe15605fbbc1424f8a13 Mon Sep 17 00:00:00 2001 From: Phil Dubach Date: Fri, 12 May 2017 12:20:55 -0700 Subject: [PATCH 2/3] Reuse existing topicid on subscribing to known topic When subscribing to a named topic check for existing registrations of the topic and reuse the existing topic ID on success, rather than blindly registering the topic. This avoids duplicate registrations of the same topic with different topic IDs. --- rsmb/src/MQTTSProtocol.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/rsmb/src/MQTTSProtocol.c b/rsmb/src/MQTTSProtocol.c index 889a9c2..b44f799 100644 --- a/rsmb/src/MQTTSProtocol.c +++ b/rsmb/src/MQTTSProtocol.c @@ -986,9 +986,17 @@ int MQTTSProtocol_handleSubscribes(void* pack, int sock, char* clientAddr, Clien // Topic name if (sub->flags.topicIdType == MQTTS_TOPIC_TYPE_NORMAL && !Topics_hasWildcards(topicName)) { - char* regTopicName = malloc(strlen(topicName)+1); - strcpy(regTopicName, topicName); - topicId = (MQTTSProtocol_registerTopic(client, regTopicName))->id; + ListElement* elem = NULL; + if ((elem = ListFindItem(client->registrations, topicName, registeredTopicNameCompare)) == NULL) + { + char* regTopicName = malloc(strlen(topicName)+1); + strcpy(regTopicName, topicName); + topicId = (MQTTSProtocol_registerTopic(client, regTopicName))->id; + } + else + { + topicId = ((Registration*)(elem->content))->id; + } } // Pre-defined topic else if (sub->flags.topicIdType == MQTTS_TOPIC_TYPE_PREDEFINED) From 57a07e4657c94704d02c027f3f002fa6f0331b5a Mon Sep 17 00:00:00 2001 From: Phil Dubach Date: Fri, 12 May 2017 18:45:05 -0700 Subject: [PATCH 3/3] Fix MQTTS not processing queued messages If a message gets queued for a client, because the maximum number of inflight messages has been reached, the server should attempt to dequeue and send that message whenever a publish is completed. Copy the relevant code from the plain MQTT handlePubacks and handlePubcomps functions. --- rsmb/src/MQTTSProtocol.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rsmb/src/MQTTSProtocol.c b/rsmb/src/MQTTSProtocol.c index b44f799..c16b8d2 100644 --- a/rsmb/src/MQTTSProtocol.c +++ b/rsmb/src/MQTTSProtocol.c @@ -802,6 +802,8 @@ int MQTTSProtocol_handlePubacks(void* pack, int sock, char* clientAddr, Clients* ListRemove(client->outboundMsgs, m); /* TODO: msgs counts */ /* (++state.msgs_sent);*/ + /* now there is space in the inflight message queue we can process any queued messages */ + MQTTProtocol_processQueued(client); } } MQTTSPacket_free_packet(pack); @@ -842,6 +844,8 @@ int MQTTSProtocol_handlePubcomps(void* pack, int sock, char* clientAddr, Clients ListRemove(client->outboundMsgs, m); /* TODO: msgs counts */ /*(++state.msgs_sent); */ + /* now there is space in the inflight message queue we can process any queued messages */ + MQTTProtocol_processQueued(client); } } }