Skip to content

Commit e7768a2

Browse files
committed
Split addr2raw up into separate platform functions
1 parent 575dffd commit e7768a2

File tree

1 file changed

+108
-79
lines changed

1 file changed

+108
-79
lines changed

src/socket.rs

+108-79
Original file line numberDiff line numberDiff line change
@@ -101,88 +101,117 @@ impl SocketAddrCRepr {
101101
}
102102

103103
fn addr2raw(addr: &SocketAddr) -> (SocketAddrCRepr, c::socklen_t) {
104-
match *addr {
105-
SocketAddr::V4(addr) => {
106-
// `s_addr` is stored as BE on all machine and the array is in BE order.
107-
// So just transmuting the octects to the `u32` representation works.
108-
#[cfg(unix)]
109-
let sin_addr = c::in_addr {
110-
s_addr: unsafe { mem::transmute::<_, u32>(addr.ip().octets()) },
111-
};
112-
#[cfg(windows)]
113-
let sin_addr = unsafe {
114-
let mut s_un = mem::zeroed::<c::in_addr_S_un>();
115-
*s_un.S_addr_mut() = mem::transmute::<_, u32>(addr.ip().octets());
116-
c::IN_ADDR { S_un: s_un }
117-
};
118-
119-
let sockaddr_in = c::sockaddr_in {
120-
sin_family: c::AF_INET as c::sa_family_t,
121-
sin_port: addr.port().to_be(),
122-
sin_addr,
123-
sin_zero: [0; 8],
124-
#[cfg(any(
125-
target_os = "dragonfly",
126-
target_os = "freebsd",
127-
target_os = "ios",
128-
target_os = "macos",
129-
target_os = "netbsd",
130-
target_os = "openbsd"
131-
))]
132-
sin_len: 0,
133-
};
134-
135-
let sockaddr = SocketAddrCRepr { v4: sockaddr_in };
136-
(sockaddr, mem::size_of::<c::sockaddr_in>() as c::socklen_t)
137-
}
138-
SocketAddr::V6(addr) => {
139-
#[cfg(unix)]
140-
let sin6_addr = {
141-
let mut sin6_addr = unsafe { mem::zeroed::<c::in6_addr>() };
142-
sin6_addr.s6_addr = addr.ip().octets();
143-
sin6_addr
144-
};
145-
#[cfg(windows)]
146-
let sin6_addr = unsafe {
147-
let mut u = mem::zeroed::<c::in6_addr_u>();
148-
*u.Byte_mut() = addr.ip().octets();
149-
c::IN6_ADDR { u }
150-
};
151-
#[cfg(windows)]
152-
let u = unsafe {
153-
let mut u = mem::zeroed::<c::SOCKADDR_IN6_LH_u>();
154-
*u.sin6_scope_id_mut() = addr.scope_id();
155-
u
156-
};
157-
158-
let sockaddr_in6 = c::sockaddr_in6 {
159-
sin6_family: c::AF_INET6 as c::sa_family_t,
160-
sin6_port: addr.port().to_be(),
161-
sin6_addr,
162-
sin6_flowinfo: addr.flowinfo(),
163-
#[cfg(unix)]
164-
sin6_scope_id: addr.scope_id(),
165-
#[cfg(windows)]
166-
u,
167-
#[cfg(any(
168-
target_os = "dragonfly",
169-
target_os = "freebsd",
170-
target_os = "ios",
171-
target_os = "macos",
172-
target_os = "netbsd",
173-
target_os = "openbsd"
174-
))]
175-
sin6_len: 0,
176-
#[cfg(any(target_os = "solaris", target_os = "illumos"))]
177-
__sin6_src_id: 0,
178-
};
179-
180-
let sockaddr = SocketAddrCRepr { v6: sockaddr_in6 };
181-
(sockaddr, mem::size_of::<c::sockaddr_in6>() as c::socklen_t)
182-
}
104+
match addr {
105+
SocketAddr::V4(v4) => addr2raw_v4(v4),
106+
SocketAddr::V6(v6) => addr2raw_v6(v6),
183107
}
184108
}
185109

110+
#[cfg(unix)]
111+
fn addr2raw_v4(addr: &SocketAddrV4) -> (SocketAddrCRepr, c::socklen_t) {
112+
// `s_addr` is stored as BE on all machines and the array is in BE order.
113+
// So just transmuting the octects to the `u32` representation works.
114+
let sin_addr = c::in_addr {
115+
s_addr: unsafe { mem::transmute::<_, u32>(addr.ip().octets()) },
116+
};
117+
118+
let sockaddr = SocketAddrCRepr {
119+
v4: c::sockaddr_in {
120+
sin_family: c::AF_INET as c::sa_family_t,
121+
sin_port: addr.port().to_be(),
122+
sin_addr,
123+
sin_zero: [0; 8],
124+
#[cfg(any(
125+
target_os = "dragonfly",
126+
target_os = "freebsd",
127+
target_os = "ios",
128+
target_os = "macos",
129+
target_os = "netbsd",
130+
target_os = "openbsd"
131+
))]
132+
sin_len: 0,
133+
},
134+
};
135+
(sockaddr, mem::size_of::<c::sockaddr_in>() as c::socklen_t)
136+
}
137+
138+
#[cfg(windows)]
139+
fn addr2raw_v4(addr: &SocketAddrV4) -> (SocketAddrCRepr, c::socklen_t) {
140+
// `S_un` is stored as BE on all machines and the array is in BE order.
141+
// So just transmuting the octects to the `u32` representation works.
142+
let sin_addr = unsafe {
143+
let mut s_un = mem::zeroed::<c::in_addr_S_un>();
144+
*s_un.S_addr_mut() = mem::transmute::<_, u32>(addr.ip().octets());
145+
c::IN_ADDR { S_un: s_un }
146+
};
147+
148+
let sockaddr = SocketAddrCRepr {
149+
v4: c::sockaddr_in {
150+
sin_family: c::AF_INET as c::sa_family_t,
151+
sin_port: addr.port().to_be(),
152+
sin_addr,
153+
sin_zero: [0; 8],
154+
},
155+
};
156+
(sockaddr, mem::size_of::<c::sockaddr_in>() as c::socklen_t)
157+
}
158+
159+
#[cfg(unix)]
160+
fn addr2raw_v6(addr: &SocketAddrV6) -> (SocketAddrCRepr, c::socklen_t) {
161+
let sin6_addr = {
162+
let mut sin6_addr = unsafe { mem::zeroed::<c::in6_addr>() };
163+
sin6_addr.s6_addr = addr.ip().octets();
164+
sin6_addr
165+
};
166+
167+
let sockaddr = SocketAddrCRepr {
168+
v6: c::sockaddr_in6 {
169+
sin6_family: c::AF_INET6 as c::sa_family_t,
170+
sin6_port: addr.port().to_be(),
171+
sin6_addr,
172+
sin6_flowinfo: addr.flowinfo(),
173+
sin6_scope_id: addr.scope_id(),
174+
#[cfg(any(
175+
target_os = "dragonfly",
176+
target_os = "freebsd",
177+
target_os = "ios",
178+
target_os = "macos",
179+
target_os = "netbsd",
180+
target_os = "openbsd"
181+
))]
182+
sin6_len: 0,
183+
#[cfg(any(target_os = "solaris", target_os = "illumos"))]
184+
__sin6_src_id: 0,
185+
},
186+
};
187+
(sockaddr, mem::size_of::<c::sockaddr_in6>() as c::socklen_t)
188+
}
189+
190+
#[cfg(windows)]
191+
fn addr2raw_v6(addr: &SocketAddrV6) -> (SocketAddrCRepr, c::socklen_t) {
192+
let sin6_addr = unsafe {
193+
let mut u = mem::zeroed::<c::in6_addr_u>();
194+
*u.Byte_mut() = addr.ip().octets();
195+
c::IN6_ADDR { u }
196+
};
197+
let scope_id = unsafe {
198+
let mut u = mem::zeroed::<c::SOCKADDR_IN6_LH_u>();
199+
*u.sin6_scope_id_mut() = addr.scope_id();
200+
u
201+
};
202+
203+
let sockaddr = SocketAddrCRepr {
204+
v6: c::sockaddr_in6 {
205+
sin6_family: c::AF_INET6 as c::sa_family_t,
206+
sin6_port: addr.port().to_be(),
207+
sin6_addr,
208+
sin6_flowinfo: addr.flowinfo(),
209+
u: scope_id,
210+
},
211+
};
212+
(sockaddr, mem::size_of::<c::sockaddr_in6>() as c::socklen_t)
213+
}
214+
186215
fn raw2addr(storage: &c::sockaddr_storage, len: c::socklen_t) -> io::Result<SocketAddr> {
187216
match storage.ss_family as c_int {
188217
c::AF_INET => {

0 commit comments

Comments
 (0)