From 4bf112b6d9f450f2ee8eb5665eb4f3f9d4ecbed4 Mon Sep 17 00:00:00 2001 From: Wiebe Cazemier Date: Sun, 26 Jun 2022 22:38:47 +0200 Subject: [PATCH] Separate DISCONNECT packet parsing and handling --- mqttpacket.cpp | 35 +++++++++++++++++++++++++---------- mqttpacket.h | 1 + packetdatatypes.h | 9 +++++++++ 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/mqttpacket.cpp b/mqttpacket.cpp index 301697f..946edcf 100644 --- a/mqttpacket.cpp +++ b/mqttpacket.cpp @@ -812,19 +812,23 @@ void MqttPacket::handleExtendedAuth() } } -void MqttPacket::handleDisconnect() +DisconnectData MqttPacket::parseDisconnectData() { + if (this->packetType != PacketType::DISCONNECT) + throw std::runtime_error("Packet must be disconnect packet."); + if (first_byte & 0b1111) throw ProtocolError("Disconnect packet first 4 bits should be 0.", ReasonCodes::MalformedPacket); - ReasonCodes reasonCode = ReasonCodes::Success; - std::string reasonString; + setPosToDataStart(); + + DisconnectData result; if (this->protocolVersion >= ProtocolVersion::Mqtt5) { if (!atEnd()) { - reasonCode = static_cast(readByte()); + result.reasonCode = static_cast(readByte()); const size_t proplen = decodeVariableByteIntAtPos(); const size_t prop_end_at = pos + proplen; @@ -839,12 +843,13 @@ void MqttPacket::handleDisconnect() { const Settings *settings = ThreadGlobals::getSettings(); const uint32_t session_expire = std::min(readFourBytesToUint32(), settings->getExpireSessionAfterSeconds()); - sender->getSession()->setSessionExpiryInterval(session_expire); + result.session_expiry_interval = session_expire; + result.session_expiry_interval_set = true; break; } case Mqtt5Properties::ReasonString: { - reasonString = readBytesToString(); + result.reasonString = readBytesToString(); break; } case Mqtt5Properties::ServerReference: @@ -862,15 +867,25 @@ void MqttPacket::handleDisconnect() } } - std::string disconnectReason = formatString("MQTT Disconnect received (code %d).", static_cast(reasonCode)); + return result; +} + +void MqttPacket::handleDisconnect() +{ + DisconnectData data = parseDisconnectData(); + + std::string disconnectReason = formatString("MQTT Disconnect received (code %d).", static_cast(data.reasonCode)); + + if (!data.reasonString.empty()) + disconnectReason += data.reasonString; - if (!reasonString.empty()) - disconnectReason += reasonString; + if (data.session_expiry_interval_set) + sender->getSession()->setSessionExpiryInterval(data.session_expiry_interval); logger->logf(LOG_NOTICE, "Client '%s' cleanly disconnecting", sender->repr().c_str()); sender->setDisconnectReason(disconnectReason); sender->markAsDisconnecting(); - if (reasonCode == ReasonCodes::Success) + if (data.reasonCode == ReasonCodes::Success) sender->clearWill(); ThreadGlobals::getThreadData()->removeClientQueued(sender); } diff --git a/mqttpacket.h b/mqttpacket.h index bae2273..e6ba3a6 100644 --- a/mqttpacket.h +++ b/mqttpacket.h @@ -113,6 +113,7 @@ public: ConnectData parseConnectData(); void handleConnect(); void handleExtendedAuth(); + DisconnectData parseDisconnectData(); void handleDisconnect(); void handleSubscribe(); void handleUnsubscribe(); diff --git a/packetdatatypes.h b/packetdatatypes.h index 279f8e0..adce03f 100644 --- a/packetdatatypes.h +++ b/packetdatatypes.h @@ -38,5 +38,14 @@ struct ConnectData ConnectData(); }; +struct DisconnectData +{ + ReasonCodes reasonCode = ReasonCodes::Success; + std::string reasonString; + + bool session_expiry_interval_set = false; + uint32_t session_expiry_interval = 0; +}; + #endif // PACKETDATATYPES_H -- libgit2 0.21.4