Skip to content

NODERAWSOCKETS: make setsockopt/getsockopt symmetric - #27921

Merged
sbc100 merged 3 commits into
emscripten-core:mainfrom
guybedford:sockopts
Oct 8, 2026
Merged

sbc100 merged 3 commits into
emscripten-core:mainfrom
guybedford:sockopts

Conversation

@guybedford

Copy link
Copy Markdown
Collaborator

This makes setsockopt and getsockopt consistent under -sNODERAWSOCKETS, resolves #27888.

Previously setsockopt accepted any unknown option silently while getsockopt returned ENOPROTOOPT for it, so a value that had just been set successfully could not be read back (e.g. SO_RCVTIMEO). SO_REUSEADDR also always read back as 1 but was never actually applied to UDP binds.

  • SO_RCVTIMEO/SO_SNDTIMEO are stored and reported as a struct timeval, validated as the kernel does (EINVAL on a short length, EDOM on an out-of-range tv_usec). Nothing blocks in this backend, so this matches kernel semantics for an O_NONBLOCK socket, where the timeout is stored but never fires.
  • SO_REUSEADDR and SO_REUSEPORT are now passed to the UDP bind (both the public dgram and udp_wrap paths), so datagram sockets can share a port. IPV6_V6ONLY is passed through for UDP too.
  • SO_ACCEPTCONN, SO_DOMAIN and SO_PROTOCOL are reported.
  • Options that are not modelled now fail with ENOPROTOOPT in setsockopt as well, so everything accepted can be read back.

test_socket_options.c is extended to cover the above and a new test_udp_reuseaddr.c checks that two UDP sockets with the option can bind the same port while a third without it gets EADDRINUSE. Both tests also pass natively on Linux.

Made with AI assistance under my review

Comment thread src/lib/libsockfs_node.js Resolved
Comment thread src/lib/libsockfs_node.js Resolved
Comment thread src/lib/libsockfs_node.js Resolved
Comment thread src/lib/libsockfs_node.js Resolved
Comment thread src/lib/libsockfs_node.js Resolved
Comment thread src/lib/libsockfs_node.js Resolved
Comment thread test/sockets/test_udp_reuseaddr.c Resolved
Store and report SO_RCVTIMEO/SO_SNDTIMEO (struct timeval); report
SO_ACCEPTCONN, SO_DOMAIN and SO_PROTOCOL; reject options that are not
modelled with ENOPROTOOPT instead of accepting them silently.
SO_REUSEADDR/SO_REUSEPORT are now actually applied to UDP binds so
datagram sockets can share a port.

Fixes emscripten-core#27888
@sbc100
sbc100 enabled auto-merge (squash) October 8, 2026 22:04
@sbc100
sbc100 merged commit fc88964 into emscripten-core:main Oct 8, 2026
41 checks passed
guybedford added a commit that referenced this pull request Nov 3, 2026
This adds UDP multicast group membership to `-sNODERAWSOCKETS`.

Since #27921, `setsockopt` rejects options it doesn't model, so
`IP_ADD_MEMBERSHIP` and its IPv6 equivalent now fail with `ENOPROTOOPT`.
Before, they were silently accepted and had no effect.

Group membership is now modelled on both the dgram and udp_wrap
backends, which both expose `addMembership`/`dropMembership`:

* `IP_ADD_MEMBERSHIP`/`IP_DROP_MEMBERSHIP` (`struct ip_mreq`, or
`ip_mreqn` with an interface address) and
`IPV6_JOIN_GROUP`/`IPV6_LEAVE_GROUP`
* a join made before `bind()` is applied once the socket is bound, since
otherwise libuv would auto-bind it to an ephemeral port
* groups are joined again on the new socket that a UDP re-connect swaps
in (#28146)
* node picks the interface by address (IPv4) or by name (IPv6), so an
interface given only by index returns `ENODEV`
* as on Linux, the options are set-only, and `getsockopt` rejects them

`test_noderawsockets_udp_multicast_membership` covers join and leave,
the kernel's `EADDRINUSE` on a duplicate join and `EADDRNOTAVAIL` on
leaving a group that wasn't joined, a join before `bind()`, and a short
`optlen`. The IPv6 part is skipped on hosts without an IPv6 multicast
route.
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.

NODERAWSOCKETS: setsockopt(SO_RCVTIMEO/SO_SNDTIMEO) succeeds but getsockopt fails with ENOPROTOOPT

2 participants