Commit 0e79ef5d7d441f5e742ab230c90781b8f7607644

Authored by Wiebe Cazemier
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.
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);