The problem code is here:
|
fn addr2raw(addr: &SocketAddr) -> (*const c::sockaddr, c::socklen_t) { |
|
match *addr { |
|
SocketAddr::V4(ref a) => { |
|
(a as *const _ as *const _, mem::size_of_val(a) as c::socklen_t) |
|
} |
|
SocketAddr::V6(ref a) => { |
|
(a as *const _ as *const _, mem::size_of_val(a) as c::socklen_t) |
|
} |
|
} |
|
} |
|
|
|
fn raw2addr(storage: &c::sockaddr_storage, len: c::socklen_t) -> io::Result<SocketAddr> { |
|
match storage.ss_family as c_int { |
|
c::AF_INET => { |
|
unsafe { |
|
assert!(len as usize >= mem::size_of::<c::sockaddr_in>()); |
|
let sa = storage as *const _ as *const c::sockaddr_in; |
|
let bits = c::sockaddr_in_u32(&(*sa)); |
|
let ip = Ipv4Addr::new((bits >> 24) as u8, |
|
(bits >> 16) as u8, |
|
(bits >> 8) as u8, |
|
bits as u8); |
|
Ok(SocketAddr::V4(SocketAddrV4::new(ip, ::ntoh((*sa).sin_port)))) |
|
} |
|
} |
|
c::AF_INET6 => { |
|
unsafe { |
|
assert!(len as usize >= mem::size_of::<c::sockaddr_in6>()); |
|
|
|
let sa = storage as *const _ as *const c::sockaddr_in6; |
|
#[cfg(windows)] let arr = (*sa).sin6_addr.u.Byte(); |
|
#[cfg(not(windows))] let arr = (*sa).sin6_addr.s6_addr; |
|
|
|
let ip = Ipv6Addr::new( |
|
(arr[0] as u16) << 8 | (arr[1] as u16), |
|
(arr[2] as u16) << 8 | (arr[3] as u16), |
|
(arr[4] as u16) << 8 | (arr[5] as u16), |
|
(arr[6] as u16) << 8 | (arr[7] as u16), |
|
(arr[8] as u16) << 8 | (arr[9] as u16), |
|
(arr[10] as u16) << 8 | (arr[11] as u16), |
|
(arr[12] as u16) << 8 | (arr[13] as u16), |
|
(arr[14] as u16) << 8 | (arr[15] as u16), |
|
); |
|
|
|
#[cfg(windows)] let sin6_scope_id = *(*sa).u.sin6_scope_id(); |
|
#[cfg(not(windows))] let sin6_scope_id = (*sa).sin6_scope_id; |
|
|
|
Ok(SocketAddr::V6(SocketAddrV6::new(ip, |
|
::ntoh((*sa).sin6_port), |
|
(*sa).sin6_flowinfo, |
|
sin6_scope_id))) |
|
} |
|
} |
|
_ => Err(io::Error::new(io::ErrorKind::InvalidInput, "invalid argument")), |
|
} |
|
} |
It assumes that the layout of std::net::SocketAddrV{4,6} matches libc::sockaddr, but this can't be assumed.
Related issues: tokio-rs/mio#1386, rust-lang/socket2#119, rust-lang/rust#78802.
Mio has roughly the same code, this was fixed in tokio-rs/mio#1388, for socket2: rust-lang/socket2#120.
The problem code is here:
net2-rs/src/socket.rs
Lines 87 to 142 in 77a6eb4
It assumes that the layout of
std::net::SocketAddrV{4,6}matcheslibc::sockaddr, but this can't be assumed.Related issues: tokio-rs/mio#1386, rust-lang/socket2#119, rust-lang/rust#78802.
Mio has roughly the same code, this was fixed in tokio-rs/mio#1388, for socket2: rust-lang/socket2#120.