Skip to content

fix(udp): cap the payload at the server's advertised buffer - #142

Merged
JPHutchins merged 1 commit into
mainfrom
fix/udp-respect-server-buf-size
Sep 22, 2026
Merged

JPHutchins merged 1 commit into
mainfrom
fix/udp-respect-server-buf-size

Conversation

@JPHutchins

Copy link
Copy Markdown
Collaborator

Warning

LLM Disclosure

This PR was authored by claude-opus-5-5[1m] on behalf of @JPHutchins. A survey of Zephyr's SMP server transports for the #58 design found that smpclient's UDP transport ignores the server's advertised buffer, and @JPHutchins asked for a small fix to main.

SMPUDPTransport sized every message by the MSS alone, so the MCUmgr params that SMPClient reads on connect never reached it. Zephyr receives each UDP request into a single buffer of the advertised buf_size, so a request larger than that can't be received.

-        return self._mtu - overhead
+        return min(self._mtu - overhead, self._smp_server_transport_buffer_size or self._mtu)

Non-breaking. Before params are known, or when a server doesn't advertise them, the result is still the MSS. Zephyr's defaults (2048-byte buffer, 1500-byte MTU) behave exactly as before; only builds with a smaller buffer change.

Sources and verification
  • buf_size is CONFIG_MCUMGR_TRANSPORT_NETBUF_SIZE (os_mgmt.c). It defaults to 2048 with UDP and 384 without (Kconfig).
  • camas check green (ruff, pydoclint, mypy, pyright, tests).
  • New parametrized test test_max_unencoded_size_capped_by_server_buffer covers buf_size below, equal to, and above the MSS. Without the fix, it fails on the 384-byte case.
  • breaking: remove address from SMPClient; SMPTransport owns address #58 (on screaming-goblin) replaces this with UDP's own Auto() sizing arm, which uses the same arithmetic.

🤖 Generated with Claude Code

`SMPUDPTransport.max_unencoded_size` overrode the base implementation with
the MSS alone, so the MCUmgr parameters that `SMPClient` reads on connect
never reached the UDP transport: `initialize(buf_size)` stored the value and
nothing read it.

Zephyr's UDP SMP transport receives each request as a single datagram into
one MCUmgr buffer of `CONFIG_MCUMGR_TRANSPORT_NETBUF_SIZE` bytes, the value
advertised as `buf_size`. A request larger than that cannot be received. The
defaults (2048-byte buffer, 1500-byte MTU) hide this. A build that lowers the
buffer, e.g. to its 384-byte non-UDP default, does not.

The payload is now `min(MSS, buf_size)`. Before the params are known,
`buf_size or mtu` makes that the MSS, so nothing changes for a server that
does not advertise them.

Verified: `camas check` green; the new parametrized test fails on the 384-byte
case without the fix.

https://github.com/zephyrproject-rtos/zephyr/blob/70be2ff0b565a3313128f5577f51cfeb3ebcf602/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c#L551-L554
https://github.com/zephyrproject-rtos/zephyr/blob/70be2ff0b565a3313128f5577f51cfeb3ebcf602/subsys/mgmt/mcumgr/transport/Kconfig#L33-L58

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@JPHutchins
JPHutchins merged commit f4d5f08 into main Sep 22, 2026
29 checks passed
@JPHutchins JPHutchins mentioned this pull request Sep 22, 2026
5 tasks
JPHutchins added a commit that referenced this pull request Sep 23, 2026
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant