Skip to content

Commit 3fe0503

Browse files
committed
Auto merge of #335 - kamalmarhubi:sin6-flowinfo-scope-id, r=fiveop
socket: Respect IPv6 flowinfo and scope_id in InetAddr::from_std Fixes #329
2 parents a09d07b + 6d01a26 commit 3fe0503

File tree

2 files changed

+44
-7
lines changed

2 files changed

+44
-7
lines changed

src/sys/socket/addr.rs

+20-6
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,26 @@ pub enum InetAddr {
3636

3737
impl InetAddr {
3838
pub fn from_std(std: &net::SocketAddr) -> InetAddr {
39-
let ip = match *std {
40-
net::SocketAddr::V4(ref addr) => IpAddr::V4(Ipv4Addr::from_std(&addr.ip())),
41-
net::SocketAddr::V6(ref addr) => IpAddr::V6(Ipv6Addr::from_std(&addr.ip())),
42-
};
43-
44-
InetAddr::new(ip, std.port())
39+
match *std {
40+
net::SocketAddr::V4(ref addr) => {
41+
InetAddr::V4(libc::sockaddr_in {
42+
sin_family: AddressFamily::Inet as sa_family_t,
43+
sin_port: addr.port().to_be(), // network byte order
44+
sin_addr: Ipv4Addr::from_std(addr.ip()).0,
45+
.. unsafe { mem::zeroed() }
46+
})
47+
}
48+
net::SocketAddr::V6(ref addr) => {
49+
InetAddr::V6(libc::sockaddr_in6 {
50+
sin6_family: AddressFamily::Inet6 as sa_family_t,
51+
sin6_port: addr.port().to_be(), // network byte order
52+
sin6_addr: Ipv6Addr::from_std(addr.ip()).0,
53+
sin6_flowinfo: addr.flowinfo(), // host byte order
54+
sin6_scope_id: addr.scope_id(), // host byte order
55+
.. unsafe { mem::zeroed() }
56+
})
57+
}
58+
}
4559
}
4660

4761
pub fn new(ip: IpAddr, port: u16) -> InetAddr {

test/sys/test_socket.rs

+24-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use nix::sys::socket::{InetAddr, UnixAddr, getsockname};
2-
use std::{mem, net};
2+
use std::mem;
3+
use std::net::{self, Ipv6Addr, SocketAddr, SocketAddrV6};
34
use std::path::Path;
45
use std::str::FromStr;
56
use std::os::unix::io::{AsRawFd, RawFd};
@@ -28,6 +29,28 @@ pub fn test_inetv4_addr_to_sock_addr() {
2829
assert_eq!(actual, inet);
2930
}
3031

32+
#[test]
33+
pub fn test_inetv6_addr_to_sock_addr() {
34+
let port: u16 = 3000;
35+
let flowinfo: u32 = 1;
36+
let scope_id: u32 = 2;
37+
let ip: Ipv6Addr = "fe80::1".parse().unwrap();
38+
39+
let actual = SocketAddr::V6(SocketAddrV6::new(ip, port, flowinfo, scope_id));
40+
let addr = InetAddr::from_std(&actual);
41+
42+
match addr {
43+
InetAddr::V6(addr) => {
44+
assert_eq!(addr.sin6_port, port.to_be());
45+
assert_eq!(addr.sin6_flowinfo, flowinfo);
46+
assert_eq!(addr.sin6_scope_id, scope_id);
47+
}
48+
_ => panic!("nope"),
49+
}
50+
51+
assert_eq!(actual, addr.to_std());
52+
}
53+
3154
#[test]
3255
pub fn test_path_to_sock_addr() {
3356
let actual = Path::new("/foo/bar");

0 commit comments

Comments
 (0)