Skip to content

Commit 3826266

Browse files
committed
Replace transmuting with better winapi union handling
1 parent ba9a2f9 commit 3826266

File tree

1 file changed

+21
-6
lines changed

1 file changed

+21
-6
lines changed

src/sys/windows/net.rs

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ use std::net::SocketAddr;
44
use std::sync::Once;
55

66
use winapi::ctypes::c_int;
7-
use winapi::shared::inaddr::IN_ADDR;
8-
use winapi::shared::in6addr::IN6_ADDR;
7+
use winapi::shared::inaddr::{in_addr_S_un, IN_ADDR};
8+
use winapi::shared::in6addr::{in6_addr_u, IN6_ADDR};
99
use winapi::shared::ws2def::{AF_INET, AF_INET6, ADDRESS_FAMILY, SOCKADDR, SOCKADDR_IN};
10-
use winapi::shared::ws2ipdef::SOCKADDR_IN6_LH;
10+
use winapi::shared::ws2ipdef::{SOCKADDR_IN6_LH, SOCKADDR_IN6_LH_u};
1111
use winapi::um::winsock2::{ioctlsocket, socket, FIONBIO, INVALID_SOCKET, SOCKET};
1212

1313
/// Initialise the network stack for Windows.
@@ -65,7 +65,11 @@ pub(crate) fn socket_addr(addr: &SocketAddr) -> (SocketAddrCRepr, c_int) {
6565
SocketAddr::V4(ref addr) => {
6666
// `s_addr` is stored as BE on all machine and the array is in BE order.
6767
// So the native endian conversion method is used so that it's never swapped.
68-
let sin_addr = IN_ADDR { S_un: unsafe { mem::transmute(u32::from_ne_bytes(addr.ip().octets())) } };
68+
let sin_addr = unsafe {
69+
let mut s_un = mem::zeroed::<in_addr_S_un>();
70+
*s_un.S_addr_mut() = u32::from_ne_bytes(addr.ip().octets());
71+
IN_ADDR { S_un: s_un }
72+
};
6973

7074
let sockaddr_in = SOCKADDR_IN {
7175
sin_family: AF_INET as ADDRESS_FAMILY,
@@ -78,12 +82,23 @@ pub(crate) fn socket_addr(addr: &SocketAddr) -> (SocketAddrCRepr, c_int) {
7882
(sockaddr, mem::size_of::<SOCKADDR_IN>() as c_int)
7983
},
8084
SocketAddr::V6(ref addr) => {
85+
let sin6_addr = unsafe {
86+
let mut u = mem::zeroed::<in6_addr_u>();
87+
*u.Byte_mut() = addr.ip().octets();
88+
IN6_ADDR { u }
89+
};
90+
let u = unsafe {
91+
let mut u = mem::zeroed::<SOCKADDR_IN6_LH_u>();
92+
*u.sin6_scope_id_mut() = addr.scope_id();
93+
u
94+
};
95+
8196
let sockaddr_in6 = SOCKADDR_IN6_LH {
8297
sin6_family: AF_INET6 as ADDRESS_FAMILY,
8398
sin6_port: addr.port().to_be(),
84-
sin6_addr: IN6_ADDR { u: unsafe { mem::transmute(addr.ip().octets()) } },
99+
sin6_addr,
85100
sin6_flowinfo: addr.flowinfo(),
86-
u: unsafe { mem::transmute(addr.scope_id()) },
101+
u,
87102
};
88103

89104
let sockaddr = SocketAddrCRepr { v6: sockaddr_in6 };

0 commit comments

Comments
 (0)