mirror of
https://github.com/qt/qtmqtt.git
synced 2026-10-25 16:16:26 +00:00
Limit MQTT packet size for MQTT 3.x connections
- Enforce the configured packet size limit locally for MQTT 3.1/3.1.1. - Close the connection if the broker sends a packet exceeding the limit. MQTT 3.1 and 3.1.1 have no way to tell the broker the maximum packet size the client accepts, so the limit can only be applied on the client side. This is helpful for clients on embedded devices, where memory is limited and a very large packet from the broker could exhaust it. [ChangeLog][QMqttClient] The maximumPacketSize connection property is now also enforced for MQTT 3.1 and 3.1.1 connections. Previously it was only honored for MQTT 5.0. The client now closes the connection if the broker sends a packet larger than this limit. This helps clients on embedded devices to protect their limited memory. The default behavior is unchanged: if no limit is set, only the protocol maximum of 256 MB applies. Change-Id: I26625325f490e2396fa493005c1f322253007a33 Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
This commit is contained in:
parent
457877b453
commit
51fe8b4f2e
@ -1970,18 +1970,25 @@ bool QMqttConnection::processDataHelper()
|
||||
if (m_missingData > 0) {
|
||||
// MQTT-2.1.4 The remaining length in the fixed header says where the message ends.
|
||||
const qint64 packetEnd = qint64(m_readPosition) + m_missingData;
|
||||
// 3.1.2.11.4 Maximum Packet Size
|
||||
// If client receives a packet whose size exceeds this limit,
|
||||
// this is a Protocol Error, the Client uses DISCONNECT with
|
||||
// Reason Code 0x95 (Packet too large),
|
||||
if (m_clientPrivate->m_protocolVersion == QMqttClient::MQTT_5_0
|
||||
&& (m_internalState == BrokerConnected
|
||||
|| m_internalState == BrokerWaitForConnectAck)) {
|
||||
if (m_internalState == BrokerConnected || m_internalState == BrokerWaitForConnectAck) {
|
||||
const quint32 maxSize = m_clientPrivate->m_connectionProperties.maximumPacketSize();
|
||||
if (maxSize > 0 && packetEnd > maxSize) {
|
||||
qCDebug(lcMqttConnection) << "Packet size exceeds the announced maximum.";
|
||||
m_clientPrivate->m_client->setError(QMqttClient::ProtocolViolation);
|
||||
sendControlDisconnect(QMqtt::ReasonCode::PacketTooLarge);
|
||||
qCDebug(lcMqttConnection) << "Packet size exceeds the maximum packet size.";
|
||||
if (m_clientPrivate->m_protocolVersion == QMqttClient::MQTT_5_0) {
|
||||
// MQTT 5: 3.1.2.11.4 Maximum Packet Size
|
||||
// If client receives a packet whose size exceeds this limit,
|
||||
// this is a Protocol Error, the Client uses DISCONNECT with
|
||||
// Reason Code 0x95 (Packet too large).
|
||||
m_clientPrivate->m_client->setError(QMqttClient::ProtocolViolation);
|
||||
sendControlDisconnect(QMqtt::ReasonCode::PacketTooLarge);
|
||||
} else {
|
||||
// MQTT 3.1 and 3.1.1 do not define a maximum packet size property, but we
|
||||
// can still enforce the limit locally and close the connection if the broker
|
||||
// attempts to send a packet that exceeds it.
|
||||
// There are no reason codes before MQTT 5.0, and a DISCONNECT is not
|
||||
// required. Just close the connection.
|
||||
closeConnection(QMqttClient::ProtocolViolation);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -304,6 +304,11 @@ void QMqttConnectionProperties::setMaximumReceive(quint16 maximumReceive)
|
||||
|
||||
If no maximum packet size is specified, no limit is imposed beyond the
|
||||
limitations of the protocol itself.
|
||||
|
||||
\note Since Qt 6.13, this limit can be applied to incoming packets
|
||||
when using MQTT 3.1 or MQTT 3.1.1. These protocol versions cannot announce
|
||||
the limit to the broker, but the client closes the connection with
|
||||
\l QMqttClient::ProtocolViolation when it receives a larger packet.
|
||||
*/
|
||||
void QMqttConnectionProperties::setMaximumPacketSize(quint32 packetSize)
|
||||
{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user