Skip to content

Conversation

@larseggert
Copy link
Contributor

@larseggert larseggert commented Dec 4, 2025

Add runtime dispatch between Apple's private sendmsg_x/recvmsg_x APIs (fast path) and standard sendmsg/recvmsg (slow path). The fast path is disabled by default and must be explicitly enabled by callers.

These private APIs may crash on unsupported OS versions, so callers must verify availability before enabling. A C ABI function is provided for embedders (e.g., Firefox) to enable the fast path after probing externally.

Key changes:

  • Add set_apple_fast_path_available() to enable fast path at runtime
  • Add C ABI quinn_udp_set_apple_fast_path_available() for FFI callers
  • Split send/recv into fast path (send_via_sendmsg_x, recv_via_recvmsg_x)
    and slow path (send_single, recv_single) variants
  • Add prepare_msg_x/prepare_recv_x for msghdr_x preparation
  • Update gso::max_gso_segments() to return 1 when fast path is disabled

@larseggert
Copy link
Contributor Author

@mxinden thinking about this some more, I wonder if we need to pass in the sockets from Gecko (due to Rust code limitations around socket creation), or if we should even do this probe entirely in Gecko and simply runtime-configure which Apple datapath quinn-udp should use?

@djc
Copy link
Member

djc commented Dec 5, 2025

(due to Rust code limitations around socket creation)

What do you mean?

@djc
Copy link
Member

djc commented Dec 5, 2025

I think each of this should be a separate commit:

  • Extract decode_cmsg helper to reduce duplication in recv decoding
  • Make decode_recv generic over MsgHdr trait

It probably also makes sense to split some of this out:

  • Split fast path (send_via_sendmsg_x/recv_via_recvmsg_x) from slow path (send_single/recv_single) for runtime dispatch

@larseggert
Copy link
Contributor Author

(due to Rust code limitations around socket creation)

What do you mean?

Gecko is sandboxing all Rust code (and other third-party code) so it cannot open sockets.

@larseggert
Copy link
Contributor Author

@djc I'll do some refactoring on this next week per your suggestions.

@larseggert
Copy link
Contributor Author

Gecko is sandboxing all Rust code (and other third-party code) so it cannot open sockets.

FWIW, I just build Firefox with this PR and it does run (and detect the fast Apple datapath after the probe), so something has changed related to the sandbox 🎉

larseggert added a commit to larseggert/quinn that referenced this pull request Dec 9, 2025
Extract control message decoding logic into dedicated helper functions.

This refactoring prepares the codebase for future work that will make
`decode_recv` generic over the `MsgHdr` trait, enabling shared decoding
logic between `libc::msghdr` and `msghdr_x` message types.

Broken out of quinn-rs#2463 as suggested by @djc.
larseggert added a commit to larseggert/quinn that referenced this pull request Dec 9, 2025
Replace conditional compilation on the `hdr` parameter with a generic type bound `M: cmsg::MsgHdr<ControlMessage = libc::cmsghdr>`. This enables `decode_recv` to work with both `libc::msghdr` and `msghdr_x` message types.

Broken out of quinn-rs#2463 as suggested by @djc.
larseggert added a commit to larseggert/quinn that referenced this pull request Dec 9, 2025
Separate the fast path (`msghdr_x`-based) and slow path (`msghdr`-based)
implementations to prepare for runtime dispatch between them.

Broken out of quinn-rs#2463 as suggested by @djc.
github-merge-queue bot pushed a commit that referenced this pull request Dec 28, 2025
Replace conditional compilation on the `hdr` parameter with a generic type bound `M: cmsg::MsgHdr<ControlMessage = libc::cmsghdr>`. This enables `decode_recv` to work with both `libc::msghdr` and `msghdr_x` message types.

Broken out of #2463 as suggested by @djc.
@mxinden
Copy link
Collaborator

mxinden commented Jan 6, 2026

Concerning the usage of quinn-udp in Firefox only:

Gecko is sandboxing all Rust code (and other third-party code) so it cannot open sockets.

FWIW, I just build Firefox with this PR and it does run (and detect the fast Apple datapath after the probe), so something has changed related to the sandbox 🎉

Referencing a discussion out-of-band. The "sandboxing" is happening at compile time.

https://github.com/mozilla-firefox/firefox/blob/43c97a062976252bce5968555060136810099ac2/python/mozbuild/mozbuild/action/check_binary.py#L209-L278

There is also the runtime sandboxing of the process. Though as far as I am aware, that isn't enabled by default.

https://github.com/mozilla-firefox/firefox/blob/main/security/sandbox/linux/SandboxFilter.cpp

@larseggert
Copy link
Contributor Author

ACK. I will revamp this once back from vacation.

@Ralith
Copy link
Collaborator

Ralith commented Jan 10, 2026

These APIs may crash on unsupported OS versions

What sort of crash, specifically? I hope we're not invoking UB or risking a collision with application signal handlers or something.

@larseggert
Copy link
Contributor Author

The concern is that Apple would eliminate or change the signature of the syscalls.

@Ralith
Copy link
Collaborator

Ralith commented Jan 10, 2026

That would make a call UB, right? Can we rely on the exit code we get from the subprocess in that case?

@larseggert larseggert force-pushed the feat-apple-probe-fast branch from 3100deb to 16d148e Compare January 20, 2026 07:30
@larseggert larseggert marked this pull request as draft January 20, 2026 07:30
@larseggert
Copy link
Contributor Author

I'll investigate if we can move the probe function into neqo/Gecko, and instead have some sort of flag in quinn for whether the fast datapath should be used. Marking this PR as draft until then.

@larseggert larseggert force-pushed the feat-apple-probe-fast branch 2 times, most recently from 086b2ba to 534b208 Compare January 20, 2026 11:49
Add runtime dispatch between Apple's private `sendmsg_x`/`recvmsg_x` APIs
(fast path) and standard `sendmsg`/`recvmsg` (slow path). The fast path
is disabled by default and must be explicitly enabled by callers.

These private APIs may crash on unsupported OS versions, so callers must
verify availability before enabling. A C ABI function is provided for
embedders (e.g., Firefox) to enable the fast path after probing externally.

Key changes:
- Add `set_apple_fast_path_available()` to enable fast path at runtime
- Add C ABI `quinn_udp_set_apple_fast_path_available()` for FFI callers
- Split send/recv into fast path (`send_via_sendmsg_x`, `recv_via_recvmsg_x`)
  and slow path (`send_single`, `recv_single`) variants
- Add `prepare_msg_x`/`prepare_recv_x` for `msghdr_x` preparation
- Update `gso::max_gso_segments()` to return 1 when fast path is disabled
@larseggert larseggert force-pushed the feat-apple-probe-fast branch from 534b208 to e6c7997 Compare January 20, 2026 11:51
@larseggert larseggert changed the title feat(quinn-udp): add runtime probe for Apple fast datapath APIs feat(quinn-udp): add opt-in Apple fast UDP datapath Jan 20, 2026
@larseggert
Copy link
Contributor Author

OK, I revamped this and moved the entire logic for deciding whether the fast datapath should be used out of quinn-udp.

@larseggert larseggert marked this pull request as ready for review January 20, 2026 11:53
@larseggert
Copy link
Contributor Author

@mxinden please check the current revision.

larseggert added a commit to larseggert/quinn that referenced this pull request Jan 22, 2026
Separate the fast path (`msghdr_x`-based) and slow path (`msghdr`-based)
implementations to prepare for runtime dispatch between them.

Broken out of quinn-rs#2463 as suggested by @djc.
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.

4 participants