simps / mqtt

🕹 MQTT Protocol Analysis and Coroutine Client for PHP. Support for 3.1, 3.1.1 and 5.0 versions of the MQTT protocol.
https://mqtt.simps.io
Apache License 2.0
358 stars 58 forks source link

PUBLISH with not enough remaining read buffer length was sent. #79

Closed mpouwels closed 2 years ago

mpouwels commented 2 years ago

Hi Guys,

We have a weird issue using your package with MQTTv5 enabled.

When sending a message to the broker containing properties; content_type, correlation_data and response_topic in most cases the payload results in a Malformed Packet.

Some test brokers send us the following message: PUBLISH with not enough remaining read buffer length was sent.

We can backtrace this issue to < 127 (or the equivalent of 128 bytes as package length)

Once we manually add extra data to the properties to match 128, 256, 512, 1024 bytes etc. the package is OK and will be send without any error.

We have set Client::SYNC_CLIENT_TYPE as we use PHPFPM.

Do you have any clue?

Kr, Michel

sy-records commented 2 years ago

Hi,there. Can you tell me your swoole version? And reproducible code or tcpdump grab package.

mpouwels commented 2 years ago

Hi,

Hereby the Swoole version and Wireshark dump

Schermafbeelding 2022-07-29 om 17 12 04

Schermafbeelding 2022-07-29 om 17 11 36

sy-records commented 2 years ago

OK, I got it. Can you give me a reproducible code?

mpouwels commented 2 years ago

Hi,

Thanks for helping me/us out!

Hereby 2 examples, the first one is working (because of the short property values), the second isn't

<?php

use Simps\MQTT\Client;
use Simps\MQTT\Config\ClientConfig;

const SWOOLE_MQTT_CONFIG = [
    'open_mqtt_protocol' => true,
    'package_max_length' => 2 * 1024 * 1024,
    'connect_timeout' => 5.0,
    'write_timeout' => 5.0,
    'read_timeout' => 5.0,
];

$clientId = "-USERNAME-" . round(microtime(true)*1000);
$config = new ClientConfig();

$config->setUserName('')
    ->setPassword('')
    ->setClientId('')
    ->setKeepAlive(10)
    ->setDelay(3000)
    ->setMaxAttempts(5)
    ->setProtocolName('MQTT')
    ->setProperties([
        'session_expiry_interval' => 60,
        'receive_maximum' => 65535,
        'topic_alias_maximum' => 65535,
    ]) 
    ->setProtocolLevel(5)
    ->setSwooleConfig(SWOOLE_MQTT_CONFIG);

$client = new Client('broker.hivemq.com', 1883, $config, Client::SYNC_CLIENT_TYPE);

$client->connect();

$response = $client->publish(
    'Test topic', // Topic
    '{"time":' . time() . '}', // Message
    1, // Qos
    0, // Dup
    0, // Retain
    [
        'content_type' => utf8_encode('This is the content'),
        'correlation_data' => utf8_encode('This is the correlation data'),
        'response_topic' => utf8_encode('Resp. topic')
    ] // Properties
);
var_dump($response);

Wireshark:

Schermafbeelding 2022-07-29 om 21 24 07

NOT WORKING:

<?php

use Simps\MQTT\Client;
use Simps\MQTT\Config\ClientConfig;

const SWOOLE_MQTT_CONFIG = [
    'open_mqtt_protocol' => true,
    'package_max_length' => 2 * 1024 * 1024,
    'connect_timeout' => 5.0,
    'write_timeout' => 5.0,
    'read_timeout' => 5.0,
];

$clientId = "-USERNAME-" . round(microtime(true)*1000);
$config = new ClientConfig();

$config->setUserName('')
    ->setPassword('')
    ->setClientId('')
    ->setKeepAlive(10)
    ->setDelay(3000)
    ->setMaxAttempts(5)
    ->setProtocolName('MQTT')
    ->setProperties([
        'session_expiry_interval' => 60,
        'receive_maximum' => 65535,
        'topic_alias_maximum' => 65535,
    ]) 
    ->setProtocolLevel(5)
    ->setSwooleConfig(SWOOLE_MQTT_CONFIG);

$client = new Client('broker.hivemq.com', 1883, $config, Client::SYNC_CLIENT_TYPE);

$client->connect();

$response = $client->publish(
    'Test topic', // Topic
    '{"time":' . time() . '}', // Message
    1, // Qos
    0, // Dup
    0, // Retain
    [
        'content_type' => utf8_encode('This is the extra long content type string'),
       'correlation_data' => utf8_encode('11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111'),
        'response_topic' => utf8_encode('Resp. topic bla bla bla')
    ] // Properties
);
var_dump($response);

Wireshark:

Schermafbeelding 2022-07-29 om 21 24 49
sy-records commented 2 years ago

@mpouwels Thanks for the feedback, I fixed it in #80, can you try it?

mpouwels commented 2 years ago

Hi @sy-records, many thanks for your quick response and fix! Just tested it and it works like a charm!