From cd01366279a35e12a39719b42b95c68dfcaa80f6 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Thu, 21 Jan 2016 19:47:38 +0100 Subject: [PATCH 1/3] Add `SocketAddr{,V4,V6}::set_port`. As demonstrated in the `resolve_socket_addr` change, this is less awkward than re-creating a new address from the other parts. --- src/libstd/net/addr.rs | 53 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 10 deletions(-) diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs index 751b9b1802c..6679201b3a5 100644 --- a/src/libstd/net/addr.rs +++ b/src/libstd/net/addr.rs @@ -75,6 +75,15 @@ impl SocketAddr { SocketAddr::V6(ref a) => a.port(), } } + + /// Change the port number associated with this socket address. + #[unstable(feature = "sockaddr_set_port", reason = "recent addition", issue = "0")] // FIXME add tracking issue + pub fn set_port(&mut self, new_port: u16) { + match *self { + SocketAddr::V4(ref mut a) => a.set_port(new_port), + SocketAddr::V6(ref mut a) => a.set_port(new_port), + } + } } impl SocketAddrV4 { @@ -102,6 +111,10 @@ impl SocketAddrV4 { /// Returns the port number associated with this socket address. #[stable(feature = "rust1", since = "1.0.0")] pub fn port(&self) -> u16 { ntoh(self.inner.sin_port) } + + /// Change the port number associated with this socket address. + #[unstable(feature = "sockaddr_set_port", reason = "recent addition", issue = "0")] // FIXME add tracking issue + pub fn set_port(&mut self, new_port: u16) { self.inner.sin_port = hton(new_port) } } impl SocketAddrV6 { @@ -134,6 +147,10 @@ impl SocketAddrV6 { #[stable(feature = "rust1", since = "1.0.0")] pub fn port(&self) -> u16 { ntoh(self.inner.sin6_port) } + /// Change the port number associated with this socket address. + #[unstable(feature = "sockaddr_set_port", reason = "recent addition", issue = "0")] // FIXME add tracking issue + pub fn set_port(&mut self, new_port: u16) { self.inner.sin6_port = hton(new_port) } + /// Returns the flow information associated with this address, /// corresponding to the `sin6_flowinfo` field in C. #[stable(feature = "rust1", since = "1.0.0")] @@ -385,16 +402,9 @@ impl ToSocketAddrs for (Ipv6Addr, u16) { fn resolve_socket_addr(s: &str, p: u16) -> io::Result> { let ips = try!(lookup_host(s)); let v: Vec<_> = try!(ips.map(|a| { - a.map(|a| { - match a { - SocketAddr::V4(ref a) => { - SocketAddr::V4(SocketAddrV4::new(*a.ip(), p)) - } - SocketAddr::V6(ref a) => { - SocketAddr::V6(SocketAddrV6::new(*a.ip(), p, a.flowinfo(), - a.scope_id())) - } - } + a.map(|mut a| { + a.set_port(p); + a }) }).collect()); Ok(v.into_iter()) @@ -511,4 +521,27 @@ mod tests { fn to_socket_addr_str_bad() { assert!(tsa("1200::AB00:1234::2552:7777:1313:34300").is_err()); } + + #[test] + fn set_port() { + let mut v4 = SocketAddrV4::new(Ipv4Addr::new(77, 88, 21, 11), 80); + assert_eq!(v4.port(), 80); + v4.set_port(443); + assert_eq!(v4.port(), 443); + + let mut addr = SocketAddr::V4(v4); + assert_eq!(addr.port(), 443); + addr.set_port(8080); + assert_eq!(addr.port(), 8080); + + let mut v6 = SocketAddrV6::new(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 80, 0, 0); + assert_eq!(v6.port(), 80); + v6.set_port(443); + assert_eq!(v6.port(), 443); + + let mut addr = SocketAddr::V6(v6); + assert_eq!(addr.port(), 443); + addr.set_port(8080); + assert_eq!(addr.port(), 8080); + } } From 5a249abba720b58bbbd23e8b0f532bd7a6ea61de Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Thu, 11 Feb 2016 14:56:08 +0100 Subject: [PATCH 2/3] Add `SocketAddr{,V4,V6}::set_ip`. --- src/libstd/net/addr.rs | 55 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs index 6679201b3a5..296cd276ddb 100644 --- a/src/libstd/net/addr.rs +++ b/src/libstd/net/addr.rs @@ -67,6 +67,17 @@ impl SocketAddr { } } + /// Change the IP address associated with this socket address. + #[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")] + pub fn set_ip(&mut self, new_ip: IpAddr) { + // `match (*self, new_ip)` would have us mutate a copy of self only to throw it away. + match (self, new_ip) { + (&mut SocketAddr::V4(ref mut a), IpAddr::V4(new_ip)) => a.set_ip(new_ip), + (&mut SocketAddr::V6(ref mut a), IpAddr::V6(new_ip)) => a.set_ip(new_ip), + (self_, new_ip) => *self_ = Self::new(new_ip, self_.port()), + } + } + /// Returns the port number associated with this socket address. #[stable(feature = "rust1", since = "1.0.0")] pub fn port(&self) -> u16 { @@ -77,7 +88,7 @@ impl SocketAddr { } /// Change the port number associated with this socket address. - #[unstable(feature = "sockaddr_set_port", reason = "recent addition", issue = "0")] // FIXME add tracking issue + #[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")] pub fn set_port(&mut self, new_port: u16) { match *self { SocketAddr::V4(ref mut a) => a.set_port(new_port), @@ -108,12 +119,16 @@ impl SocketAddrV4 { } } + /// Change the IP address associated with this socket address. + #[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")] + pub fn set_ip(&mut self, new_ip: Ipv4Addr) { self.inner.sin_addr = *new_ip.as_inner() } + /// Returns the port number associated with this socket address. #[stable(feature = "rust1", since = "1.0.0")] pub fn port(&self) -> u16 { ntoh(self.inner.sin_port) } /// Change the port number associated with this socket address. - #[unstable(feature = "sockaddr_set_port", reason = "recent addition", issue = "0")] // FIXME add tracking issue + #[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")] pub fn set_port(&mut self, new_port: u16) { self.inner.sin_port = hton(new_port) } } @@ -143,12 +158,16 @@ impl SocketAddrV6 { } } + /// Change the IP address associated with this socket address. + #[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")] + pub fn set_ip(&mut self, new_ip: Ipv6Addr) { self.inner.sin6_addr = *new_ip.as_inner() } + /// Returns the port number associated with this socket address. #[stable(feature = "rust1", since = "1.0.0")] pub fn port(&self) -> u16 { ntoh(self.inner.sin6_port) } /// Change the port number associated with this socket address. - #[unstable(feature = "sockaddr_set_port", reason = "recent addition", issue = "0")] // FIXME add tracking issue + #[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")] pub fn set_port(&mut self, new_port: u16) { self.inner.sin6_port = hton(new_port) } /// Returns the flow information associated with this address, @@ -522,6 +541,36 @@ mod tests { assert!(tsa("1200::AB00:1234::2552:7777:1313:34300").is_err()); } + #[test] + fn set_ip() { + fn ip4(low: u8) -> Ipv4Addr { Ipv4Addr::new(77, 88, 21, low) } + fn ip6(low: u16) -> Ipv6Addr { Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, low) } + + let mut v4 = SocketAddrV4::new(ip4(11), 80); + assert_eq!(v4.ip(), &ip4(11)); + v4.set_ip(ip4(12)); + assert_eq!(v4.ip(), &ip4(12)); + + let mut addr = SocketAddr::V4(v4); + assert_eq!(addr.ip(), IpAddr::V4(ip4(12))); + addr.set_ip(IpAddr::V4(ip4(13))); + assert_eq!(addr.ip(), IpAddr::V4(ip4(13))); + addr.set_ip(IpAddr::V6(ip6(14))); + assert_eq!(addr.ip(), IpAddr::V6(ip6(14))); + + let mut v6 = SocketAddrV6::new(ip6(1), 80, 0, 0); + assert_eq!(v6.ip(), &ip6(1)); + v6.set_ip(ip6(2)); + assert_eq!(v6.ip(), &ip6(2)); + + let mut addr = SocketAddr::V6(v6); + assert_eq!(addr.ip(), IpAddr::V6(ip6(2))); + addr.set_ip(IpAddr::V6(ip6(3))); + assert_eq!(addr.ip(), IpAddr::V6(ip6(3))); + addr.set_ip(IpAddr::V4(ip4(4))); + assert_eq!(addr.ip(), IpAddr::V4(ip4(4))); + } + #[test] fn set_port() { let mut v4 = SocketAddrV4::new(Ipv4Addr::new(77, 88, 21, 11), 80); From 3de820ee7912f46761ca4f0c50f67164aaa5f42f Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Thu, 11 Feb 2016 15:36:10 +0100 Subject: [PATCH 3/3] Add SocketAddrV6::set_flowinfo and set_scope_id --- src/libstd/net/addr.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs index 296cd276ddb..89c51c70843 100644 --- a/src/libstd/net/addr.rs +++ b/src/libstd/net/addr.rs @@ -175,10 +175,22 @@ impl SocketAddrV6 { #[stable(feature = "rust1", since = "1.0.0")] pub fn flowinfo(&self) -> u32 { ntoh(self.inner.sin6_flowinfo) } + /// Change the flow information associated with this socket address. + #[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")] + pub fn set_flowinfo(&mut self, new_flowinfo: u32) { + self.inner.sin6_flowinfo = hton(new_flowinfo) + } + /// Returns the scope ID associated with this address, /// corresponding to the `sin6_scope_id` field in C. #[stable(feature = "rust1", since = "1.0.0")] pub fn scope_id(&self) -> u32 { ntoh(self.inner.sin6_scope_id) } + + /// Change the scope ID associated with this socket address. + #[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")] + pub fn set_scope_id(&mut self, new_scope_id: u32) { + self.inner.sin6_scope_id = hton(new_scope_id) + } } impl FromInner for SocketAddrV4 { @@ -593,4 +605,20 @@ mod tests { addr.set_port(8080); assert_eq!(addr.port(), 8080); } + + #[test] + fn set_flowinfo() { + let mut v6 = SocketAddrV6::new(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 80, 10, 0); + assert_eq!(v6.flowinfo(), 10); + v6.set_flowinfo(20); + assert_eq!(v6.flowinfo(), 20); + } + + #[test] + fn set_scope_id() { + let mut v6 = SocketAddrV6::new(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 80, 0, 10); + assert_eq!(v6.scope_id(), 10); + v6.set_scope_id(20); + assert_eq!(v6.scope_id(), 20); + } }