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 41 initialBufferSize(settings->clientInitialBufferSize), // The client is constructed in the main thread, so we need to use its settings copy
42 42 maxOutgoingPacketSize(settings->maxPacketSize), // Same as initialBufferSize comment.
43 43 maxIncomingPacketSize(settings->maxPacketSize),
  44 + maxIncomingTopicAliasValue(settings->maxIncomingTopicAliasValue), // Retaining snapshot of current setting, to not confuse clients when the setting changes.
44 45 ioWrapper(ssl, websocket, initialBufferSize, this),
45 46 readbuf(initialBufferSize),
46 47 writebuf(initialBufferSize),
... ... @@ -377,11 +378,9 @@ void Client::setTopicAlias(const uint16_t alias_id, const std::string &topic)
377 378 if (topic.empty())
378 379 return;
379 380  
380   - const Settings *settings = ThreadGlobals::getSettings();
381   -
382 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 384 ReasonCodes::TopicAliasInvalid);
386 385  
387 386 this->incomingTopicAliases[alias_id] = topic;
... ... @@ -402,6 +401,15 @@ uint32_t Client::getMaxIncomingPacketSize() const
402 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 413 void Client::sendOrQueueWill()
406 414 {
407 415 if (!this->threadData)
... ...
client.h
... ... @@ -68,6 +68,7 @@ class Client
68 68 const uint32_t maxIncomingPacketSize;
69 69  
70 70 uint16_t maxOutgoingTopicAliasValue = 0;
  71 + const uint16_t maxIncomingTopicAliasValue;
71 72  
72 73 IoWrapper ioWrapper;
73 74 std::string transportStr;
... ... @@ -169,6 +170,7 @@ public:
169 170 const std::string &getTopicAlias(const uint16_t id);
170 171  
171 172 uint32_t getMaxIncomingPacketSize() const;
  173 + uint16_t getMaxIncomingTopicAliasValue() const;
172 174  
173 175 void sendOrQueueWill();
174 176 void serverInitiatedDisconnect(ReasonCodes reason);
... ...
mqttpacket.cpp
... ... @@ -622,7 +622,7 @@ void MqttPacket::handleConnect()
622 622 connAck->propertyBuilder->writeMaxPacketSize(sender->getMaxIncomingPacketSize());
623 623 if (clientIdGenerated)
624 624 connAck->propertyBuilder->writeAssignedClientId(client_id);
625   - connAck->propertyBuilder->writeMaxTopicAliases(settings.maxIncomingTopicAliasValue);
  625 + connAck->propertyBuilder->writeMaxTopicAliases(sender->getMaxIncomingTopicAliasValue());
626 626 connAck->propertyBuilder->writeWildcardSubscriptionAvailable(1);
627 627 connAck->propertyBuilder->writeSubscriptionIdentifiersAvailable(0);
628 628 connAck->propertyBuilder->writeSharedSubscriptionAvailable(0);
... ...