Repository navigation
Tracking Issue for feature(unix_socket_ancillary_data) #76915
Description
Activity
- addedC-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCCategory: An issue tracking the progress of sth. like the implementation of an RFC
on Sep 19, 2020 - addedI-libs-radarLibs issues that are tracked on the team's radar.Libs issues that are tracked on the team's radar.
on Nov 6, 2020 - addedA-ioArea: `std::io`, `std::fs`, `std::net` and `std::path`Area: `std::io`, `std::fs`, `std::net` and `std::path`O-unixOperating system: Unix-likeOperating system: Unix-like
on Jan 6, 2021 send_vectored_with_ancillaryshould switch to non-mutable references for its parameters, sincesendmsgdoesn't write through them.#79753 changes just the
bufsparameter, but it was closed for inactivity.(Edit: Hmm, actually changing the ancillary data too would require both a SocketAncillary and SocketAncillaryMut, like IoSlice. Probably not worth it there)
@tadeokondrak I open a new PR #82589.
Reacted by Tadeo KondrakI create a new PR to send and receive TTL for UdpSocket from the ancillary interface. #82858
What has to be done to stabilize this API?
Reacted by David L. L. ThomasI think the API still needs polish. All those niche socket features are tricky and right now it's probably not extensible enough for 3rd party libraries to fill platform-specific gaps such as flags or cmsgs only supported on one particular OS. These basically are wrappers for the
recvmsgandsndmsgsyscalls, we should expose them in a way that's forwards-compatible so we don't have to addrecv_vectored_with_ancillary_from_with_flagsor something like that in the future.Before stabilizing we should consider whether
recv_vectored_with_ancillary_fromshould gain another argument. I would recommend adding aReceiveOptionsargument that allows one to specify flags, similar toOpenOptions. The options could then be used to set linux'MSG_DONTWAIT,MSG_PEEKorMSG_ERRQUEUEfor example, maybe viacustom_flags()similar toOpenOptions. That way we don't have to support all OS-specific peculiarities.Or we could put the flags into
SocketAncillaryor at least reserve the right to do that in the future, but in that case the struct would need to be renamed because it would serve several purposes at once.Similar could be done for sending.
Additionally the
AncillaryDataenum should be marked as#[non_exhaustive]and maybe gain aUnknownvariant for things that the standard library doesn't support. And a way to get the raw ancillary message. That way one could for example decodestruct sock_extended_errin a 3rd party crate without waiting for std to implement it.What about CMSG_SPACE? Without it, we're forced to either guess or probe the appropriate buffer size.
https://man7.org/linux/man-pages/man3/cmsg.3.html SCM_RIGHTS example shows how it's used to compute the correct buffer size (with some tricky business wrt alignment).
Hi @tv42,
what are the difference betweenCMSG_SPACEandCMSG_LEN?Is there a function, which calculate the alignment for a struct to a specific address in Rust?
81 remaining items
Wouldn't it be better for
SocketAncillary'sadd_credsandadd_fdsto return aResult<(), NotEnoughSpaceErrror>instead of a bool?Reacted by LinkTedWould it be better for
SocketAncillary::newto take aMaybeUninitbuffer? I assume that the original buffer should not be read from after callingSocketAncillary::new. Also, this saves the initialization expense.When initializing a buffer that will contain a series of cmsghdr structures (e.g., to be sent with [sendmsg(2)](https://man7.org/linux/man-pages/man2/sendmsg.2.html)), that buffer should first be zero-initialized to ensure the correct operation of CMSG_NXTHDR().at least sending it requires zero-initialization anyway.
Reacted by LinkTedthat buffer should first be zero-initialized to ensure the
correct operation of CMSG_NXTHDR().Is that the responsibility of the caller of, or of
SocketAncillary::newitself? Because if this is a safety concern, how do you enforce it on the caller? Wouldn't a common mistake be to re-use the buffer for subsequentSocketAncillary::newcalls without resetting its contents?Reacted by Thayne McCombs and Ellen Emilia Anna ZscheileI see that it currently only includes
SO_PASSCRED. What is the reason for that, is support for the other socket options also planned? It seems a bit arbitrary to only support one option but not the others (which are also frequently used)- addedF-unix_socket_ancillary_data`#![feature(unix_socket_ancillary_data)]``#![feature(unix_socket_ancillary_data)]`
on Apr 30, 2025 Are there any reason this is implemented only for UDS datagram sockets but not TCP/UDP sockets?
It's a bit surprising to me that it is UDS sockets that first get their sendmsg/recvmsg operations implemented.Because some of the most common use cases for this, such as sending file descriptors, or the "credentials" of the peer process, only works for UDS
Reacted by Martin Habovštiak and Eyal KalderonHello,
I would like to submit the following proposals for your consideration:The former:
InSocketAncillarya pointer or reference to inner buffer should be exposed and a buffer length should be modifiable r i.e
fn get_ptr(&mut self) -> *mut u8; // or fn get_mut(&mut self) -> &mut [u8];
and
fn set_len(&mut self, len: usize) -> Result<()>
Both changes will allow to use theSocketAncillaryin the 3rd party code outside the STD, because at the moment I have to do bad things like:let anci_struct: *mut SocketAncillaryCover = ancillary as *mut _ as *mut SocketAncillaryCover; if ancillary.len() > 0 { msg.msg_controllen = ancillary.len(); msg.msg_control = unsafe { (&mut *anci_struct).buffer.as_mut_ptr().cast() }; }
The second thing:
InSocketAncillaryin a functionadd_fdsan argument fds accepts a slice ofRawFdas input. In my humble (of cause) opinion, the argument should be &[OwnedFd], since once the FD(s) have been sent, it should no longer be accessible.At the moment, the code looks lile:
let fds = [OwnedFd::from(a).into_raw_fd(), OwnedFd::from(b).into_raw_fd(), OwnedFd::from(aa).into_raw_fd()]; ancillary.add_fds(&fds[..]);
But the
into_raw_fd()function should be called inside theadd_to_ancillary_data()consuming the OwnedFd.I am continuing the maintenance of the crate "uds-fork" and those changes would suit the needs of the crate ancillary.rs
What's the status of this feature, and what are the alternatives in the meantime?
@Lancelotbronner What exactly are you looking for? I think "all of this" is already possible using libc or rustix. For example, here is some code to send and receive FDs using rustix.
Well for starters because the examples you've linked are a lot more code than what I got working with std, my only issue is that macOS support was removed.
Is there a source-compatible crate?
Reacted by Uli SchlachterWhat's the status on adding macOS support and standardizing this?
- addedT-libsRelevant to the library team, which will review and decide on the PR/issue.Relevant to the library team, which will review and decide on the PR/issue.and removedT-libs-api[DEPRECATED; DO NOT USE][DEPRECATED; DO NOT USE]
on Aug 12, 2026
View all comments
Tracking issue for
feature(unix_socket_ancillary_data)to extendUnixStreamandUnixDatagramto send and receive ancillary data. For example file descriptors.Unresolved Questions
SocketAncillarystruct before stabilization to ensure it is compatible with all OSes.fuchsia,haiku,illumos,ios,macosandsolarisdoes not haveMSG_CMSG_CLOEXECconstant inlibcfuchsiaanduclibc(x86_64) does not havecmsghdrstruct inlibclibcdoes not haveucredstruct for the target OSemscripten, butemscriptenhas this struct in the standard C libraryKnown bugs/issues
Implementation history