Repository navigation
fix(netwatch): set SO_RECV_ANYIF on Apple UDP sockets - #248
Conversation
cf28e57 to
9eefd3f
Compare
There was a problem hiding this comment.
The only thing that was concerning me about this PR was whether enabling this unconditionally could have bad side-effects, but it turns out there's lots of precedence in enabling this in widely used apple tools:
- Apple's DCHPv4 client
- Apple's DHCPv6 client
- MacOS
pingandping6 - Another P2P networking library NewNode
- Yggdrasil from Matrix
So that looks fine.
(The reason I looked into this was because in theory you could also implement this using the configure socket hook. But obviously that then would be opt-in.)
This is the right pattern. It's also what a bunch of MacOS tools are doing, and debug is the correct level IMO. |
I think we can merge as-is, but upstreaming could be worth either way? Seems like socket2 accepts PRs for options like these. |
Closes #246.
On macOS and iOS, traffic arriving on a restricted interface such as AWDL (
awdl0) is delivered only to sockets that setSO_RECV_ANYIF. This sets it inSocketState::bindon Apple targets, before theconfigure_sockethook runs. Ifsetsockoptfails it's logged at debug and the bind carries on as before.HUMAN NOTE:
multi-decade programmer, writing rust since 2022 -- but this is AI assisted work. I AM NOT a sockets guru -- so this COULD break something somewhere for anybody using #[cfg(target_vendor = "apple")]. it is a NOOP on all other platforms. probably the most controversial thing is do you want that "debug!("failed to set SO_RECV_ANYIF: {:?}", err);" line or not ;)
API Changes
None.
Notes & open questions
unsafetoudp.rs: onelibc::setsockoptcall, plus agetsockoptin the test. As far as I can find, no safe API can set this option.libc,socket2andnixdon't defineSO_RECV_ANYIF, so it's a local const (0x1104, from<sys/socket.h>).socket2's genericsetsockoptispub(crate), andnix'ssockopt_impl!expands to the sameunsafeblock inside netwatch. Each block has aSAFETYcomment. If you'd rather, I can upstream the constant tolibcand a setter tosocket2, so this becomes a safe call.test_bind_sets_recv_anyifreads the option back through the configure-socket hook, for v4 and v6. Whether AWDL then delivers can't be checked on one machine. The manual check and before/after numbers are in Apple: sockets need SO_RECV_ANYIF to receive over AWDL (and link-local addresses are never advertised) #246.cargo makeon macOS: fmt-check, check and test (30/30) pass. clippy and doc fail on warnings ininterfaces/bsd.rs, a file this PR doesn't touch:unused_asyncondefault_route(:40) and unclosed<must …>tags in a doc comment (:519–525). clippy fails the same way onmain. I've left them alone here; happy to send a separate fix if you'd like.Change checklist
proposed change and wrote an as clear and concise description as
they could.
intented effect.
cargo makepasses locally.