-
Notifications
You must be signed in to change notification settings - Fork 6.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MQTT publish causes unnecessary TCP segmentation #22679
Comments
It's not a bug but conscious use of a STREAM socket features.
In case you wanted to use a single socket call to send the data, you'd need to combine the header and payload in a single, continuous buffer. So you'd either need to make the user prepend the payload buffer with some spare bytes to fill in the header later (and thus increase the complexity for the user) or copy both, the generated header and the payload into a single, preallocated memory area (which might not sound like an issue for a 1-byte payload you describe, but bear in mind that MQTT allows up to nearly 256 MB of payload). We did not want to put any implementation-specific limitation on the payload size. With this approach you don't need to preallocate or copy anything, you just call the What we really miss here is a Nagle algorithm implementation at TCP layer, which would prevent us from sending small chunks of data into the network. But again, that's a feature request, not a bug. |
I see and get your point. It is just that the performance effect is quite nasty. Quick poll on e.g. paho MQTT C stack shows that they indeed use malloc+copy to construct the packet and it does not have this behavior. So is this approach out of the question here? Maybe behind some config flags? And it is true that API is now brain dead simple and better to keep it that way. But on the other hand, people are already used to
kind of stuff, so maybe that is not impossible either? Nagle probably wouldn't do anything in this case, as it kicks in only when there already is some data on the line. |
I see, indeed Nagle might not kick in in this particular case. The simplest approach I can see to tackle this issue is to provide a Kconfig switch (or even a runtime switch within This should have almost no impact on the implementation or the API, the only caveat would be on the user side, to provide large enough TX buffer to hold both, header and payload. The use case and limitations could be documented, so I don't see an issue here. I'd like to hear from others about the idea though. If we agree it could work like this, I can provide implementation, it should be pretty straightforward. |
What about using |
Yes, that should help in the TCP case. I'm only worried about other transports we have, TLS underneath just calls |
Add new transport handler for MQTT, with sendmsg-like functionality. This allows TCP transport to send PUBLISH packets w/o fragmentation at the TCP layer. Implement this new functionality for all existing transports. Fixes zephyrproject-rtos#22679 Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Add new transport handler for MQTT, with sendmsg-like functionality. This allows TCP transport to send PUBLISH packets w/o fragmentation at the TCP layer. Implement this new functionality for all existing transports. Fixes #22679 Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Add new transport handler for MQTT, with sendmsg-like functionality. This allows TCP transport to send PUBLISH packets w/o fragmentation at the TCP layer. Implement this new functionality for all existing transports. Fixes zephyrproject-rtos#22679 Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Describe the bug
For some reason MQTT publishing sends publish packet and its payload in separate packets code
So even if the payload is just 1 byte, then you'll have 2 TCP packets and (usually) 2 TCP ACKs flying in the air to get that one byte delivered. This is a bit of an issue if you are doing this on top of some low bandwidt IoT network.
Maybe there is a good reason to do this, but I can't figure out what that would be.(Just trying out zephyr for the first time)
To Reproduce
Run any MQTT publish code and see the tcpdump.
Expected behavior
One TCP segment to deliver MQTT publish+payload
Impact
Non-optimal network usage & battery consumption
The text was updated successfully, but these errors were encountered: