badeend opened PR #13934 from badeend:addr-checks to bytecodealliance:main:
Currently, the shared socket code (
crates/wasi/src/sockets/*) is modeled after the
p2 interface, with p3 bindings papering over the differences. Some
functionality is duplicated between thep2/*andp3/*implementations. This has
already caused bugs in the past.Since the p3 interface is strictly a superset of p2, I think it makes more sense to invert that relationship. This PR updates the shared code to become the canonical (p3-shaped)
implementation with the p3's bindings now a thin wrapper around it. All
p2-only behavior & state is moved into the p2 bindings layer. Think of: artificial restrictions like disallowing implicit
binds, and the start/finish async bookkeeping.Other notable changes:
Each socket now stores its own copy of the
WasiCtx's
socket_addr_checkat creation time, allowing all permission checks to live in
the shared socket code instead of being split across p2/p3. The p2
Networkresource is now just an unforgeable capability token (its
permission-checking responsibilities are gone).Removed the
Boundstate; whether a socket is bound is now determined
lazily viagetsockname/local_addrinstead of tracked explicitly.
This simplifies the implementation ofUdpSocket::send, allowing it to return a future that can run to completion independently, without needing to rendezvous back with the socket to update its state.Updated
SocketAddrUse:
- addedTcpListen,TcpAccept,UdpReceivechecks.
- replacedUdpConnectwith calls toUdpSendandUdpReceive. On UDP sockets, "connecting" is just a local operation that sets the default remote address for future sends and receives. It does not actually do any I/O on its own.
- Note to reviewer: this is a breaking change.
Tcp&UdpSocket::connectnow also issue a permission
check for the implicit bind that the OS performs when connecting an
unbound socket, matching the check already done for explicit binds. Following through the changes of https://github.com/bytecodealliance/wasmtime/pull/13677Removed the
StdViewtype introduced in https://github.com/bytecodealliance/wasmtime/pull/13872 infavour of direct usage ofBorrowedFdAdded test coverage for previously-untested behavior:
test_udp_disconnect_local_address(p2 & p3): disconnecting a UDP
socket should keep it bound. Exercises the removal of the explicitBound
state in favor of lazily-derived bound status.
test_udp_send_receive_multiple(p2): a singlesend/receivecall
can carry multiple datagrams at once (bulk send/receive over a
connectedstream()).
test_udp_receive_after_connect(p2): datagrams from different peers
queued before a socket is connected are correctly filtered so that
stream(Some(addr))only returns datagrams from the provided address.
All-in-all, the goal of this PR is to consolidate the socket code (even further) into a single place and make it less error-prone to maintain. I realize there's quite a bit of unannounced code movement here, so let me know what you think.
badeend requested pchickey for a review on PR #13934.
badeend requested wasmtime-wasi-reviewers for a review on PR #13934.
badeend requested wasmtime-core-reviewers for a review on PR #13934.
github-actions[bot] added the label wasi on PR #13934.
alexcrichton unassigned pchickey from PR #13934 wasi-sockets: Unify the p2 & p3 implementations.
alexcrichton requested alexcrichton for a review on PR #13934.
:thumbs_up: alexcrichton submitted PR review:
Thanks so much for this! This all sounds great to me and I think the refactoring's a good idea. Do you think long-term it would be possible to fold the
utils.rsmodule into the tcp/udp modules directly? That seems a vestige of a time where it was a home of common functionality between p2/p3, but nowadays that should just be{Tcp,Udp}Socket. (Fine to happen in a follow-up PR of course)
:speech_balloon: alexcrichton created PR review comment:
For this the handling of
finishis a bit subtle, but the basic idea is that this continues to do everything below and then instead of returningPendingat the last second it returnsCancelledinstead. That gives sort of a "final chance" to get everything completed
:speech_balloon: alexcrichton created PR review comment:
Similar comment to below on
finishhere
:speech_balloon: alexcrichton created PR review comment:
Similar comment to below on
finishhere
badeend updated PR #13934.
:memo: badeend submitted PR review.
:speech_balloon: badeend created PR review comment:
My reasoning was that; if the guest cancels the read/write, there's no point in us to querying the OS again for something the guest isn't interested in anymore. Which is why I had the early return.
But I'm fine with giving it one last poll. See latest commit.
badeend commented on PR #13934:
Do you think long-term it would be possible to fold the utils.rs module into the tcp/udp modules directly?
For the things that are explicitly marked as
tcp_*&udp_*; Yes, that should be possible.There are also a bunch of functions that are shared between tcp & udp, like:
- is_valid_address_family
- normalize_get_buffer_size
- get_ip_ttl
- unspecified_addr
- ..
For those , I think the best we can do is move them into mod.rs.
:memo: alexcrichton submitted PR review.
:speech_balloon: alexcrichton created PR review comment:
Yeah the intent of the guest is a bit ambiguous because it could mean "I still want to try to finish, but clear out otherwise" vs "I'm totally uninterested in the result just clean up" which is conflated right now
alexcrichton commented on PR #13934:
Makes sense yeah, not something worth proactively doing necessarily, just curious!
alexcrichton added PR #13934 wasi-sockets: Unify the p2 & p3 implementations to the merge queue.
:check: alexcrichton merged PR #13934.
alexcrichton removed PR #13934 wasi-sockets: Unify the p2 & p3 implementations from the merge queue.
Last updated: Jul 29 2026 at 05:03 UTC