Commit 0e79ef5d7d441f5e742ab230c90781b8f7607644
1 parent
0c1a5dc4
Use snapshot of maxIncomingTopicAliasValue from settings in client
This fixes clients being disconnected after reducing the max value and reloading the settings.
Showing
3 changed files
with
15 additions
and
5 deletions
client.cpp
| @@ -41,6 +41,7 @@ Client::Client(int fd, std::shared_ptr<ThreadData> threadData, SSL *ssl, bool we | @@ -41,6 +41,7 @@ Client::Client(int fd, std::shared_ptr<ThreadData> threadData, SSL *ssl, bool we | ||
| 41 | initialBufferSize(settings->clientInitialBufferSize), // The client is constructed in the main thread, so we need to use its settings copy | 41 | initialBufferSize(settings->clientInitialBufferSize), // The client is constructed in the main thread, so we need to use its settings copy |
| 42 | maxOutgoingPacketSize(settings->maxPacketSize), // Same as initialBufferSize comment. | 42 | maxOutgoingPacketSize(settings->maxPacketSize), // Same as initialBufferSize comment. |
| 43 | maxIncomingPacketSize(settings->maxPacketSize), | 43 | maxIncomingPacketSize(settings->maxPacketSize), |
| 44 | + maxIncomingTopicAliasValue(settings->maxIncomingTopicAliasValue), // Retaining snapshot of current setting, to not confuse clients when the setting changes. | ||
| 44 | ioWrapper(ssl, websocket, initialBufferSize, this), | 45 | ioWrapper(ssl, websocket, initialBufferSize, this), |
| 45 | readbuf(initialBufferSize), | 46 | readbuf(initialBufferSize), |
| 46 | writebuf(initialBufferSize), | 47 | writebuf(initialBufferSize), |
| @@ -377,11 +378,9 @@ void Client::setTopicAlias(const uint16_t alias_id, const std::string &topic) | @@ -377,11 +378,9 @@ void Client::setTopicAlias(const uint16_t alias_id, const std::string &topic) | ||
| 377 | if (topic.empty()) | 378 | if (topic.empty()) |
| 378 | return; | 379 | return; |
| 379 | 380 | ||
| 380 | - const Settings *settings = ThreadGlobals::getSettings(); | ||
| 381 | - | ||
| 382 | // The specs actually say "The Client MUST NOT send a Topic Alias [...] to the Server greater than this value [Topic Alias Maximum]". So, it's not about count. | 381 | // The specs actually say "The Client MUST NOT send a Topic Alias [...] to the Server greater than this value [Topic Alias Maximum]". So, it's not about count. |
| 383 | - if (alias_id > settings->maxIncomingTopicAliasValue) | ||
| 384 | - throw ProtocolError(formatString("Client tried to set more topic aliases than the server max of %d per client", settings->maxIncomingTopicAliasValue), | 382 | + if (alias_id > this->maxIncomingTopicAliasValue) |
| 383 | + throw ProtocolError(formatString("Client tried to set more topic aliases than the server max of %d per client", this->maxIncomingTopicAliasValue), | ||
| 385 | ReasonCodes::TopicAliasInvalid); | 384 | ReasonCodes::TopicAliasInvalid); |
| 386 | 385 | ||
| 387 | this->incomingTopicAliases[alias_id] = topic; | 386 | this->incomingTopicAliases[alias_id] = topic; |
| @@ -402,6 +401,15 @@ uint32_t Client::getMaxIncomingPacketSize() const | @@ -402,6 +401,15 @@ uint32_t Client::getMaxIncomingPacketSize() const | ||
| 402 | return this->maxIncomingPacketSize; | 401 | return this->maxIncomingPacketSize; |
| 403 | } | 402 | } |
| 404 | 403 | ||
| 404 | +/** | ||
| 405 | + * @brief We use this to send back in the connack, so we know we don't race with the value from settings, which may change during the connection handshake. | ||
| 406 | + * @return | ||
| 407 | + */ | ||
| 408 | +uint16_t Client::getMaxIncomingTopicAliasValue() const | ||
| 409 | +{ | ||
| 410 | + return this->maxIncomingTopicAliasValue; | ||
| 411 | +} | ||
| 412 | + | ||
| 405 | void Client::sendOrQueueWill() | 413 | void Client::sendOrQueueWill() |
| 406 | { | 414 | { |
| 407 | if (!this->threadData) | 415 | if (!this->threadData) |
client.h
| @@ -68,6 +68,7 @@ class Client | @@ -68,6 +68,7 @@ class Client | ||
| 68 | const uint32_t maxIncomingPacketSize; | 68 | const uint32_t maxIncomingPacketSize; |
| 69 | 69 | ||
| 70 | uint16_t maxOutgoingTopicAliasValue = 0; | 70 | uint16_t maxOutgoingTopicAliasValue = 0; |
| 71 | + const uint16_t maxIncomingTopicAliasValue; | ||
| 71 | 72 | ||
| 72 | IoWrapper ioWrapper; | 73 | IoWrapper ioWrapper; |
| 73 | std::string transportStr; | 74 | std::string transportStr; |
| @@ -169,6 +170,7 @@ public: | @@ -169,6 +170,7 @@ public: | ||
| 169 | const std::string &getTopicAlias(const uint16_t id); | 170 | const std::string &getTopicAlias(const uint16_t id); |
| 170 | 171 | ||
| 171 | uint32_t getMaxIncomingPacketSize() const; | 172 | uint32_t getMaxIncomingPacketSize() const; |
| 173 | + uint16_t getMaxIncomingTopicAliasValue() const; | ||
| 172 | 174 | ||
| 173 | void sendOrQueueWill(); | 175 | void sendOrQueueWill(); |
| 174 | void serverInitiatedDisconnect(ReasonCodes reason); | 176 | void serverInitiatedDisconnect(ReasonCodes reason); |
mqttpacket.cpp
| @@ -622,7 +622,7 @@ void MqttPacket::handleConnect() | @@ -622,7 +622,7 @@ void MqttPacket::handleConnect() | ||
| 622 | connAck->propertyBuilder->writeMaxPacketSize(sender->getMaxIncomingPacketSize()); | 622 | connAck->propertyBuilder->writeMaxPacketSize(sender->getMaxIncomingPacketSize()); |
| 623 | if (clientIdGenerated) | 623 | if (clientIdGenerated) |
| 624 | connAck->propertyBuilder->writeAssignedClientId(client_id); | 624 | connAck->propertyBuilder->writeAssignedClientId(client_id); |
| 625 | - connAck->propertyBuilder->writeMaxTopicAliases(settings.maxIncomingTopicAliasValue); | 625 | + connAck->propertyBuilder->writeMaxTopicAliases(sender->getMaxIncomingTopicAliasValue()); |
| 626 | connAck->propertyBuilder->writeWildcardSubscriptionAvailable(1); | 626 | connAck->propertyBuilder->writeWildcardSubscriptionAvailable(1); |
| 627 | connAck->propertyBuilder->writeSubscriptionIdentifiersAvailable(0); | 627 | connAck->propertyBuilder->writeSubscriptionIdentifiersAvailable(0); |
| 628 | connAck->propertyBuilder->writeSharedSubscriptionAvailable(0); | 628 | connAck->propertyBuilder->writeSharedSubscriptionAvailable(0); |