diff --git a/src/MQTTAsyncUtils.c b/src/MQTTAsyncUtils.c index 98507bdf..f0f8ecc5 100644 --- a/src/MQTTAsyncUtils.c +++ b/src/MQTTAsyncUtils.c @@ -2262,13 +2262,17 @@ thread_return_type WINAPI MQTTAsync_receiveThread(void* n) else if (pack->header.bits.type == DISCONNECT) { Ack* disc = (Ack*)pack; + int discrc = 0; + discrc = disc->rc; if (m->disconnected) { Log(TRACE_MIN, -1, "Calling disconnected for client %s", m->c->clientID); (*(m->disconnected))(m->disconnected_context, &disc->properties, disc->rc); } - MQTTPacket_freeAck(disc); + rc = MQTTProtocol_handleDisconnects(pack, m->c->net.socket); + m->c->connected = 0; /* don't send disconnect packet back */ + nextOrClose(m, discrc, "Received disconnect"); } } } diff --git a/src/MQTTPacket.c b/src/MQTTPacket.c index 296bf31b..6c9a6c5f 100644 --- a/src/MQTTPacket.c +++ b/src/MQTTPacket.c @@ -816,10 +816,11 @@ void* MQTTPacket_ack(int MQTTVersion, unsigned char aHeader, char* data, size_t pack->rc = MQTTREASONCODE_SUCCESS; pack->properties = props; - if (datalen > 2) + /* disconnect has no msgid */ + if (datalen > 2 || (pack->header.bits.type == DISCONNECT && datalen > 0)) pack->rc = readChar(&curdata); /* reason code */ - if (datalen > 3) + if (datalen > 3 || (pack->header.bits.type == DISCONNECT && datalen > 1)) { if (MQTTProperties_read(&pack->properties, &curdata, enddata) != 1) { diff --git a/src/MQTTProtocolOut.c b/src/MQTTProtocolOut.c index a3dc787a..733a3392 100644 --- a/src/MQTTProtocolOut.c +++ b/src/MQTTProtocolOut.c @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009, 2020 IBM Corp. + * Copyright (c) 2009, 2021 IBM Corp., Ian Craggs * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 @@ -443,3 +443,24 @@ int MQTTProtocol_handleUnsubacks(void* pack, int sock) return rc; } + +/** + * Process an incoming disconnect packet for a socket + * @param pack pointer to the disconnect packet + * @param sock the socket on which the packet was received + * @return completion code + */ +int MQTTProtocol_handleDisconnects(void* pack, int sock) +{ + Ack* disconnect = (Ack*)pack; + Clients* client = NULL; + int rc = TCPSOCKET_COMPLETE; + + FUNC_ENTRY; + client = (Clients*)(ListFindItem(bstate->clients, &sock, clientSocketCompare)->content); + Log(LOG_PROTOCOL, 30, NULL, sock, client->clientID, disconnect->rc); + MQTTPacket_freeAck(disconnect); + FUNC_EXIT_RC(rc); + return rc; +} + diff --git a/src/MQTTProtocolOut.h b/src/MQTTProtocolOut.h index a31e2e57..d8f43d73 100644 --- a/src/MQTTProtocolOut.h +++ b/src/MQTTProtocolOut.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009, 2020 IBM Corp. + * Copyright (c) 2009, 2021 IBM Corp., Ian Craggs * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 @@ -60,5 +60,6 @@ int MQTTProtocol_subscribe(Clients* client, List* topics, List* qoss, int msgID, int MQTTProtocol_handleSubacks(void* pack, int sock); int MQTTProtocol_unsubscribe(Clients* client, List* topics, int msgID, MQTTProperties* props); int MQTTProtocol_handleUnsubacks(void* pack, int sock); +int MQTTProtocol_handleDisconnects(void* pack, int sock); #endif diff --git a/src/Messages.c b/src/Messages.c index 299612d9..1b47fadf 100644 --- a/src/Messages.c +++ b/src/Messages.c @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009, 2020 IBM Corp. + * Copyright (c) 2009, 2021 IBM Corp., Ian Craggs * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 @@ -66,6 +66,7 @@ static const char *protocol_message_list[] = "%d %s -> PUBLISH qos: 0 retained: %d rc: %d payload len(%d): %.*s", /* 27 */ "%d %s -> DISCONNECT (%d)", /* 28 */ "Socket error for client identifier %s, socket %d, peer address %s; ending connection", /* 29 */ + "%d %s <- DISCONNECT (%d)", /* 30 */ }; static const char *trace_message_list[] =