Description
https://docs.rs/rustix/0.38.42/rustix/net/sockopt/index.html
Many of the supposed netlink protocols are in reality netlink specific socket options, which are also completely missing in the sockopt module
https://docs.rs/rustix/0.38.42/rustix/net/netlink/constant.ADD_MEMBERSHIP.html
https://docs.rs/rustix/0.38.42/rustix/net/netlink/constant.DROP_MEMBERSHIP.html
https://docs.rs/rustix/0.38.42/rustix/net/netlink/constant.LIST_MEMBERSHIPS.html
https://docs.rs/rustix/0.38.42/rustix/net/netlink/constant.BROADCAST_ERROR.html
https://docs.rs/rustix/0.38.42/rustix/net/netlink/constant.NO_ENOBUFS.html
https://docs.rs/rustix/0.38.42/rustix/net/netlink/constant.CAP_ACK.html
https://docs.rs/rustix/0.38.42/rustix/net/netlink/constant.EXT_ACK.html
https://docs.rs/rustix/0.38.42/rustix/net/netlink/constant.GET_STRICT_CHK.html
https://docs.rs/rustix/0.38.42/rustix/net/netlink/constant.LISTEN_ALL_NSID.html
https://docs.rs/rustix/0.38.42/rustix/net/netlink/constant.PKTINFO.html
all of these are socket options described in netlink.7
or the netlink handbook.
Additionally, when I read rustix was low-level and "aims to provide safe and idiomatic Rust interfaces to low-level syscalls", I was surprised to find no direct interface to many syscalls, but instead high level wrappers exclusively exposing specific subsets of them that rustix knows about, and nothing for those it doesn't.
I was expecting a lower level API to syscalls like this, with all the benefits of type, memory, and I/O safety rustix provides over the raw syscalls and bare integers, but that doesn't seem to be a design goal for rustix.
Activity
sunfishcode commentedon Jan 6, 2025
I don't know how it could be possible to expose a lower-level API while still having any of the benefits of type, memory, or I/O safety. To provide a safe interface, rustix has to know which arguments are pointers, which are file descriptors, what memory is to be mutated, and so on.
Rustix once attempted to expose only typed interfaces to ioctls for this reason, however there are just too many ioctls for it to be practical to cover them all, so Rustix now exposes a generic
ioctl
function. I've been resisting doing this for exotic socket features, but there have been a lot of requests for a lot of various socket features, so I've now changed my mind.It's telling that the very first sentence in the netlink book describes netlink as an ioctl replacement.
I would like to add a feature to Rustix that just exposes raw socket features as an unsafe interface. We can still add safe interfaces for features as we're able to, but the unsafe interface will be there for everything else. I don't yet know what that should look like, and would appreciate any help anyone might be able to offer.
DianaNites commentedon Jan 6, 2025
Unless I'm mistaken, all of this is known in advance and perfectly safe for at least
setsockopt
/getsockopt
, which will also safely return errors for invalid options, levels, and values?AIUI socket options are at least always plain old data, so in my mind this can be a perfectly safe interface taking opaque bytes, unless theres some evil socket options that modify
optval
onsetsockopt
it can always be immutable(despite it being defined withconst void
in the man page), andgetsockopt
is always mutable, with construction/buffer sizing left to the caller and perhaps helpers provided by rustix for the times when it isnt just a boolean int?(e.g. IP_ADD_MEMBERSHIP).This leaves all the benefits of the errno handling, I/O safety for the passed FD, memory safety for the buffers, type safety for the levels and option names, with corresponding Raw types and
from_raw
functions.Protocol::from_raw
is safe and these could be too?The levels and option names can even be paired into some sort of
SocketOption
type. Something like(pseudo-code)This is still low level in the sense of being a straight-forward wrapper around the direct syscall which the caller still needs to know how to use, but is perfectly safe in rust terms and lagely benefits from the various other safeties(type, I/O) and clear intent signaling of rustix, and can form the basis of a higher level wrapper that knows about the option/value pairing from rustix or other crates.(I don't think its rustix style, but I like the idea of type-state generics for this.)
sunfishcode commentedon Jan 8, 2025
That's a good point. And I guess it's ok even if Linux adds arbitrary new types in the future, because users still need an
unsafe
block to convert from bytes into pointers orOwnedFd
s or whatever else. So this sounds like a good direction to go in.Remove netlink protocol constants that are actually socket options
Remove netlink protocol constants that are actually socket options (#…