Skip to content

Commit

Permalink
Convert SocketAddrV* -> SockAddr safely
Browse files Browse the repository at this point in the history
  • Loading branch information
faern committed Nov 6, 2020
1 parent 99da5c2 commit 7c25373
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 17 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ features = ["handleapi", "ws2def", "ws2ipdef", "ws2tcpip", "minwindef"]

[target."cfg(any(unix, target_os = \"redox\"))".dependencies]
cfg-if = "0.1.6"
libc = "0.2.66"
libc = { version = "0.2.66", features = ["align"] }

[target."cfg(target_os = \"redox\")".dependencies]
redox_syscall = "0.1.38"
Expand Down
47 changes: 31 additions & 16 deletions src/sockaddr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@ use std::ptr;

#[cfg(any(unix, target_os = "redox"))]
use libc::{
sa_family_t, sockaddr, sockaddr_in, sockaddr_in6, sockaddr_storage, socklen_t, AF_INET,
AF_INET6,
in6_addr, in_addr, sa_family_t, sockaddr, sockaddr_in, sockaddr_in6, sockaddr_storage,
socklen_t, AF_INET, AF_INET6,
};
#[cfg(windows)]
use winapi::shared::in6addr::IN6_ADDR as in6_addr;
#[cfg(windows)]
use winapi::shared::inaddr::IN_ADDR as in_addr;
#[cfg(windows)]
use winapi::shared::ws2def::{
ADDRESS_FAMILY as sa_family_t, AF_INET, AF_INET6, SOCKADDR as sockaddr,
SOCKADDR_IN as sockaddr_in, SOCKADDR_STORAGE as sockaddr_storage,
Expand Down Expand Up @@ -168,33 +172,44 @@ impl SockAddr {
}
}

// SocketAddrV4 and SocketAddrV6 are just wrappers around sockaddr_in and sockaddr_in6

// check to make sure that the sizes at least match up
fn _size_checks(v4: SocketAddrV4, v6: SocketAddrV6) {
unsafe {
mem::transmute::<SocketAddrV4, sockaddr_in>(v4);
mem::transmute::<SocketAddrV6, sockaddr_in6>(v6);
}
}

impl From<SocketAddrV4> for SockAddr {
fn from(addr: SocketAddrV4) -> SockAddr {
let sin_addr = in_addr {
s_addr: u32::from_ne_bytes(addr.ip().octets()),
};

let sockaddr_in = sockaddr_in {
sin_family: AF_INET as sa_family_t,
sin_port: addr.port().to_be(),
sin_addr,
..unsafe { mem::zeroed() }
};

unsafe {
SockAddr::from_raw_parts(
&addr as *const _ as *const _,
mem::size_of::<SocketAddrV4>() as socklen_t,
&sockaddr_in as *const _ as *const _,
mem::size_of::<sockaddr_in>() as socklen_t,
)
}
}
}

impl From<SocketAddrV6> for SockAddr {
fn from(addr: SocketAddrV6) -> SockAddr {
let sockaddr_in6 = sockaddr_in6 {
sin6_family: AF_INET6 as sa_family_t,
sin6_port: addr.port().to_be(),
sin6_addr: in6_addr {
s6_addr: addr.ip().octets(),
},
sin6_flowinfo: addr.flowinfo(),
sin6_scope_id: addr.scope_id(),
..unsafe { mem::zeroed() }
};
unsafe {
SockAddr::from_raw_parts(
&addr as *const _ as *const _,
mem::size_of::<SocketAddrV6>() as socklen_t,
&sockaddr_in6 as *const _ as *const _,
mem::size_of::<sockaddr_in6>() as socklen_t,
)
}
}
Expand Down

0 comments on commit 7c25373

Please sign in to comment.