-
Notifications
You must be signed in to change notification settings - Fork 231
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
No sound way to zero-copy from socketaddr_in #323
Comments
On Unix it's a 128 bytes, so I don't really see much of a difference...
Have you tried
How would that fix it? you still need a pointer/reference to |
In this case I'm getting a linked list of minimally-sized
That's more or less what I'm suggesting, yes. As a point of order, I'm going to switch to non-shouty-case from here, because the discussion applies broadly to POSIX as well. To reiterate,
Making SockAddr itself generic over e.g. |
Let's take a step back then. What are you trying to do with the
I don't think it needs to be that complicated I think the following will do: struct SocketAddrRef<'a> {
storage: *const (), // Can be one of the socket address storage types (`sockaddr_in`, `sockaddr_in6`, `sockaddr_storage`, etc.)
len: usize, // Must be `>= size_of::<sa_family_t>()`.
_phantom: PhantomData<&'a ()>,
}
impl<'a> SocketAddrRef<'a> {
/// # Safety
///
/// Caller must ensure the pointer and length are correct and valid for the duration of `'a`.
unsafe fn new<'a>(storage: *const (), len: usize) -> SocketAddrRef<'a> {
debug_assert!(len >= size_of::<sa_family_t>());
SocketAddrRef { storage, len, _phantom: PhantomData }
}
} |
Yeah, I think that would work. Would you suggest then implementing As to what we're trying to do, we have some unsafe code that's trying to extract IP addresses from those FFI structs. The legacy code was doing a transmute directly into |
Yes, something like the following. match unsafe { std::ptr::read(self.storage as *const libc::sa_family_t) {
AF_INET6 => // ...
} But note that
We went through the same problem (#122). I'm wondering where |
Yeah I think more I was trying to get folks thinking about a non-owned |
This is most painful on Windows, where SOCKADDR_STORAGE is 132 bytes long.
Consider the following naive example code, where the SOCKADDR pointer here is a pointer to an ipv4/ipv6 address obtained via syscall:
The issue is that
SOCKADDR_STORAGE
is larger thanSOCKADDR
, the pointer is only guaranteed to be valid throughlength
bytes, and so casting it to*const SOCKADDR_STORAGE
and dereferencing immediately introduces UB.The correct code looks more like this:
Since the backing storage for SockAddr is owning, we have to make a copy. It's incredibly awkward and a bit slower. And that's just so we can safely invoke the nice parsing logic in
as_socket()
.To fix this we'd probably have to add a SockAddrRef<'a> type that doesn't own its backing storage. If that's not immediately feasible, providing a constructor that performs this unsafe copy inside socket2 would also solve the immediate issue.
The text was updated successfully, but these errors were encountered: