-
Notifications
You must be signed in to change notification settings - Fork 67
Closed
Description
The problem code is here:
Lines 87 to 142 in 77a6eb4
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.
Metadata
Metadata
Assignees
Labels
No labels