diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2018-08-19 18:34:46 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-08-19 18:34:46 +0200 |
| commit | 08b1d83a46848dd7bd778aeae67a1e529e95d8cd (patch) | |
| tree | 9153a34f91860b175afb24f904fd50ac09e77c4e /src/libstd/net | |
| parent | ac64ef33756d05557153e00211cdf8fcf65d4be3 (diff) | |
| parent | b355906919927ab3c879becd14392f023af883a1 (diff) | |
| download | rust-08b1d83a46848dd7bd778aeae67a1e529e95d8cd.tar.gz rust-08b1d83a46848dd7bd778aeae67a1e529e95d8cd.zip | |
Merge branch 'master' into feature/core_convert_id
Diffstat (limited to 'src/libstd/net')
| -rw-r--r-- | src/libstd/net/addr.rs | 12 | ||||
| -rw-r--r-- | src/libstd/net/ip.rs | 313 | ||||
| -rw-r--r-- | src/libstd/net/mod.rs | 58 | ||||
| -rw-r--r-- | src/libstd/net/parser.rs | 26 | ||||
| -rw-r--r-- | src/libstd/net/tcp.rs | 85 | ||||
| -rw-r--r-- | src/libstd/net/udp.rs | 89 |
6 files changed, 377 insertions, 206 deletions
diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs index 1ca7e66ed9c..e80c3eeb876 100644 --- a/src/libstd/net/addr.rs +++ b/src/libstd/net/addr.rs @@ -12,10 +12,11 @@ use fmt; use hash; use io; use mem; -use net::{lookup_host, ntoh, hton, IpAddr, Ipv4Addr, Ipv6Addr}; +use net::{ntoh, hton, IpAddr, Ipv4Addr, Ipv6Addr}; use option; use sys::net::netc as c; use sys_common::{FromInner, AsInner, IntoInner}; +use sys_common::net::lookup_host; use vec; use iter; use slice; @@ -26,6 +27,9 @@ use slice; /// as possibly some version-dependent additional information. See [`SocketAddrV4`]'s and /// [`SocketAddrV6`]'s respective documentation for more details. /// +/// The size of a `SocketAddr` instance may vary depending on the target operating +/// system. +/// /// [IP address]: ../../std/net/enum.IpAddr.html /// [`SocketAddrV4`]: ../../std/net/struct.SocketAddrV4.html /// [`SocketAddrV6`]: ../../std/net/struct.SocketAddrV6.html @@ -59,6 +63,9 @@ pub enum SocketAddr { /// /// See [`SocketAddr`] for a type encompassing both IPv4 and IPv6 socket addresses. /// +/// The size of a `SocketAddrV4` struct may vary depending on the target operating +/// system. +/// /// [IETF RFC 793]: https://tools.ietf.org/html/rfc793 /// [IPv4 address]: ../../std/net/struct.Ipv4Addr.html /// [`SocketAddr`]: ../../std/net/enum.SocketAddr.html @@ -86,6 +93,9 @@ pub struct SocketAddrV4 { inner: c::sockaddr_in } /// /// See [`SocketAddr`] for a type encompassing both IPv4 and IPv6 socket addresses. /// +/// The size of a `SocketAddrV6` struct may vary depending on the target operating +/// system. +/// /// [IETF RFC 2553, Section 3.3]: https://tools.ietf.org/html/rfc2553#section-3.3 /// [IPv6 address]: ../../std/net/struct.Ipv6Addr.html /// [`SocketAddr`]: ../../std/net/enum.SocketAddr.html diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index 0d73a6f4fd7..9a610cd7d6b 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -16,8 +16,6 @@ use cmp::Ordering; use fmt; use hash; -use mem; -use net::{hton, ntoh}; use sys::net::netc as c; use sys_common::{AsInner, FromInner}; @@ -26,6 +24,9 @@ use sys_common::{AsInner, FromInner}; /// This enum can contain either an [`Ipv4Addr`] or an [`Ipv6Addr`], see their /// respective documentation for more details. /// +/// The size of an `IpAddr` instance may vary depending on the target operating +/// system. +/// /// [`Ipv4Addr`]: ../../std/net/struct.Ipv4Addr.html /// [`Ipv6Addr`]: ../../std/net/struct.Ipv6Addr.html /// @@ -61,6 +62,9 @@ pub enum IpAddr { /// /// See [`IpAddr`] for a type encompassing both IPv4 and IPv6 addresses. /// +/// The size of an `Ipv4Addr` struct may vary depending on the target operating +/// system. +/// /// [IETF RFC 791]: https://tools.ietf.org/html/rfc791 /// [`IpAddr`]: ../../std/net/enum.IpAddr.html /// @@ -93,6 +97,9 @@ pub struct Ipv4Addr { /// /// See [`IpAddr`] for a type encompassing both IPv4 and IPv6 addresses. /// +/// The size of an `Ipv6Addr` struct may vary depending on the target operating +/// system. +/// /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291 /// [`IpAddr`]: ../../std/net/enum.IpAddr.html /// @@ -153,9 +160,9 @@ impl IpAddr { /// ``` #[stable(feature = "ip_shared", since = "1.12.0")] pub fn is_unspecified(&self) -> bool { - match *self { - IpAddr::V4(ref a) => a.is_unspecified(), - IpAddr::V6(ref a) => a.is_unspecified(), + match self { + IpAddr::V4(ip) => ip.is_unspecified(), + IpAddr::V6(ip) => ip.is_unspecified(), } } @@ -178,9 +185,9 @@ impl IpAddr { /// ``` #[stable(feature = "ip_shared", since = "1.12.0")] pub fn is_loopback(&self) -> bool { - match *self { - IpAddr::V4(ref a) => a.is_loopback(), - IpAddr::V6(ref a) => a.is_loopback(), + match self { + IpAddr::V4(ip) => ip.is_loopback(), + IpAddr::V6(ip) => ip.is_loopback(), } } @@ -207,9 +214,9 @@ impl IpAddr { /// } /// ``` pub fn is_global(&self) -> bool { - match *self { - IpAddr::V4(ref a) => a.is_global(), - IpAddr::V6(ref a) => a.is_global(), + match self { + IpAddr::V4(ip) => ip.is_global(), + IpAddr::V6(ip) => ip.is_global(), } } @@ -232,9 +239,9 @@ impl IpAddr { /// ``` #[stable(feature = "ip_shared", since = "1.12.0")] pub fn is_multicast(&self) -> bool { - match *self { - IpAddr::V4(ref a) => a.is_multicast(), - IpAddr::V6(ref a) => a.is_multicast(), + match self { + IpAddr::V4(ip) => ip.is_multicast(), + IpAddr::V6(ip) => ip.is_multicast(), } } @@ -261,9 +268,9 @@ impl IpAddr { /// } /// ``` pub fn is_documentation(&self) -> bool { - match *self { - IpAddr::V4(ref a) => a.is_documentation(), - IpAddr::V6(ref a) => a.is_documentation(), + match self { + IpAddr::V4(ip) => ip.is_documentation(), + IpAddr::V6(ip) => ip.is_documentation(), } } @@ -286,7 +293,7 @@ impl IpAddr { /// ``` #[stable(feature = "ipaddr_checker", since = "1.16.0")] pub fn is_ipv4(&self) -> bool { - match *self { + match self { IpAddr::V4(_) => true, IpAddr::V6(_) => false, } @@ -311,7 +318,7 @@ impl IpAddr { /// ``` #[stable(feature = "ipaddr_checker", since = "1.16.0")] pub fn is_ipv6(&self) -> bool { - match *self { + match self { IpAddr::V4(_) => false, IpAddr::V6(_) => true, } @@ -331,18 +338,21 @@ impl Ipv4Addr { /// let addr = Ipv4Addr::new(127, 0, 0, 1); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr { + #[rustc_const_unstable(feature = "const_ip")] + pub const fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr { Ipv4Addr { inner: c::in_addr { - s_addr: hton(((a as u32) << 24) | - ((b as u32) << 16) | - ((c as u32) << 8) | - (d as u32)), + s_addr: u32::to_be( + ((a as u32) << 24) | + ((b as u32) << 16) | + ((c as u32) << 8) | + (d as u32) + ), } } } - /// Creates a new IPv4 address with the address pointing to localhost: 127.0.0.1. + /// An IPv4 address with the address pointing to localhost: 127.0.0.1. /// /// # Examples /// @@ -350,17 +360,15 @@ impl Ipv4Addr { /// #![feature(ip_constructors)] /// use std::net::Ipv4Addr; /// - /// let addr = Ipv4Addr::localhost(); + /// let addr = Ipv4Addr::LOCALHOST; /// assert_eq!(addr, Ipv4Addr::new(127, 0, 0, 1)); /// ``` #[unstable(feature = "ip_constructors", reason = "requires greater scrutiny before stabilization", issue = "44582")] - pub fn localhost() -> Ipv4Addr { - Ipv4Addr::new(127, 0, 0, 1) - } + pub const LOCALHOST: Self = Ipv4Addr::new(127, 0, 0, 1); - /// Creates a new IPv4 address representing an unspecified address: 0.0.0.0 + /// An IPv4 address representing an unspecified address: 0.0.0.0 /// /// # Examples /// @@ -368,15 +376,29 @@ impl Ipv4Addr { /// #![feature(ip_constructors)] /// use std::net::Ipv4Addr; /// - /// let addr = Ipv4Addr::unspecified(); + /// let addr = Ipv4Addr::UNSPECIFIED; /// assert_eq!(addr, Ipv4Addr::new(0, 0, 0, 0)); /// ``` #[unstable(feature = "ip_constructors", reason = "requires greater scrutiny before stabilization", issue = "44582")] - pub fn unspecified() -> Ipv4Addr { - Ipv4Addr::new(0, 0, 0, 0) - } + pub const UNSPECIFIED: Self = Ipv4Addr::new(0, 0, 0, 0); + + /// An IPv4 address representing the broadcast address: 255.255.255.255 + /// + /// # Examples + /// + /// ``` + /// #![feature(ip_constructors)] + /// use std::net::Ipv4Addr; + /// + /// let addr = Ipv4Addr::BROADCAST; + /// assert_eq!(addr, Ipv4Addr::new(255, 255, 255, 255)); + /// ``` + #[unstable(feature = "ip_constructors", + reason = "requires greater scrutiny before stabilization", + issue = "44582")] + pub const BROADCAST: Self = Ipv4Addr::new(255, 255, 255, 255); /// Returns the four eight-bit integers that make up this address. /// @@ -390,7 +412,7 @@ impl Ipv4Addr { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn octets(&self) -> [u8; 4] { - let bits = ntoh(self.inner.s_addr); + let bits = u32::from_be(self.inner.s_addr); [(bits >> 24) as u8, (bits >> 16) as u8, (bits >> 8) as u8, bits as u8] } @@ -461,11 +483,11 @@ impl Ipv4Addr { /// ``` #[stable(since = "1.7.0", feature = "ip_17")] pub fn is_private(&self) -> bool { - match (self.octets()[0], self.octets()[1]) { - (10, _) => true, - (172, b) if b >= 16 && b <= 31 => true, - (192, 168) => true, - _ => false + match self.octets() { + [10, ..] => true, + [172, b, ..] if b >= 16 && b <= 31 => true, + [192, 168, ..] => true, + _ => false, } } @@ -487,7 +509,10 @@ impl Ipv4Addr { /// ``` #[stable(since = "1.7.0", feature = "ip_17")] pub fn is_link_local(&self) -> bool { - self.octets()[0] == 169 && self.octets()[1] == 254 + match self.octets() { + [169, 254, ..] => true, + _ => false, + } } /// Returns [`true`] if the address appears to be globally routable. @@ -564,8 +589,7 @@ impl Ipv4Addr { /// ``` #[stable(since = "1.7.0", feature = "ip_17")] pub fn is_broadcast(&self) -> bool { - self.octets()[0] == 255 && self.octets()[1] == 255 && - self.octets()[2] == 255 && self.octets()[3] == 255 + self == &Self::BROADCAST } /// Returns [`true`] if this address is in a range designated for documentation. @@ -591,11 +615,11 @@ impl Ipv4Addr { /// ``` #[stable(since = "1.7.0", feature = "ip_17")] pub fn is_documentation(&self) -> bool { - match(self.octets()[0], self.octets()[1], self.octets()[2], self.octets()[3]) { - (192, 0, 2, _) => true, - (198, 51, 100, _) => true, - (203, 0, 113, _) => true, - _ => false + match self.octets() { + [192, 0, 2, _] => true, + [198, 51, 100, _] => true, + [203, 0, 113, _] => true, + _ => false, } } @@ -645,9 +669,9 @@ impl Ipv4Addr { #[stable(feature = "ip_addr", since = "1.7.0")] impl fmt::Display for IpAddr { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - match *self { - IpAddr::V4(ref a) => a.fmt(fmt), - IpAddr::V6(ref a) => a.fmt(fmt), + match self { + IpAddr::V4(ip) => ip.fmt(fmt), + IpAddr::V6(ip) => ip.fmt(fmt), } } } @@ -696,8 +720,8 @@ impl PartialEq for Ipv4Addr { #[stable(feature = "ip_cmp", since = "1.16.0")] impl PartialEq<Ipv4Addr> for IpAddr { fn eq(&self, other: &Ipv4Addr) -> bool { - match *self { - IpAddr::V4(ref v4) => v4 == other, + match self { + IpAddr::V4(v4) => v4 == other, IpAddr::V6(_) => false, } } @@ -706,8 +730,8 @@ impl PartialEq<Ipv4Addr> for IpAddr { #[stable(feature = "ip_cmp", since = "1.16.0")] impl PartialEq<IpAddr> for Ipv4Addr { fn eq(&self, other: &IpAddr) -> bool { - match *other { - IpAddr::V4(ref v4) => self == v4, + match other { + IpAddr::V4(v4) => self == v4, IpAddr::V6(_) => false, } } @@ -734,8 +758,8 @@ impl PartialOrd for Ipv4Addr { #[stable(feature = "ip_cmp", since = "1.16.0")] impl PartialOrd<Ipv4Addr> for IpAddr { fn partial_cmp(&self, other: &Ipv4Addr) -> Option<Ordering> { - match *self { - IpAddr::V4(ref v4) => v4.partial_cmp(other), + match self { + IpAddr::V4(v4) => v4.partial_cmp(other), IpAddr::V6(_) => Some(Ordering::Greater), } } @@ -744,8 +768,8 @@ impl PartialOrd<Ipv4Addr> for IpAddr { #[stable(feature = "ip_cmp", since = "1.16.0")] impl PartialOrd<IpAddr> for Ipv4Addr { fn partial_cmp(&self, other: &IpAddr) -> Option<Ordering> { - match *other { - IpAddr::V4(ref v4) => self.partial_cmp(v4), + match other { + IpAddr::V4(v4) => self.partial_cmp(v4), IpAddr::V6(_) => Some(Ordering::Less), } } @@ -754,7 +778,7 @@ impl PartialOrd<IpAddr> for Ipv4Addr { #[stable(feature = "rust1", since = "1.0.0")] impl Ord for Ipv4Addr { fn cmp(&self, other: &Ipv4Addr) -> Ordering { - ntoh(self.inner.s_addr).cmp(&ntoh(other.inner.s_addr)) + u32::from_be(self.inner.s_addr).cmp(&u32::from_be(other.inner.s_addr)) } } @@ -769,7 +793,16 @@ impl FromInner<c::in_addr> for Ipv4Addr { #[stable(feature = "ip_u32", since = "1.1.0")] impl From<Ipv4Addr> for u32 { - /// It performs the conversion in network order (big-endian). + /// Convert an `Ipv4Addr` into a host byte order `u32`. + /// + /// # Examples + /// + /// ``` + /// use std::net::Ipv4Addr; + /// + /// let addr = Ipv4Addr::new(13, 12, 11, 10); + /// assert_eq!(0x0d0c0b0au32, u32::from(addr)); + /// ``` fn from(ip: Ipv4Addr) -> u32 { let ip = ip.octets(); ((ip[0] as u32) << 24) + ((ip[1] as u32) << 16) + ((ip[2] as u32) << 8) + (ip[3] as u32) @@ -778,7 +811,16 @@ impl From<Ipv4Addr> for u32 { #[stable(feature = "ip_u32", since = "1.1.0")] impl From<u32> for Ipv4Addr { - /// It performs the conversion in network order (big-endian). + /// Convert a host byte order `u32` into an `Ipv4Addr`. + /// + /// # Examples + /// + /// ``` + /// use std::net::Ipv4Addr; + /// + /// let addr = Ipv4Addr::from(0x0d0c0b0au32); + /// assert_eq!(Ipv4Addr::new(13, 12, 11, 10), addr); + /// ``` fn from(ip: u32) -> Ipv4Addr { Ipv4Addr::new((ip >> 24) as u8, (ip >> 16) as u8, (ip >> 8) as u8, ip as u8) } @@ -786,6 +828,14 @@ impl From<u32> for Ipv4Addr { #[stable(feature = "from_slice_v4", since = "1.9.0")] impl From<[u8; 4]> for Ipv4Addr { + /// # Examples + /// + /// ``` + /// use std::net::Ipv4Addr; + /// + /// let addr = Ipv4Addr::from([13u8, 12u8, 11u8, 10u8]); + /// assert_eq!(Ipv4Addr::new(13, 12, 11, 10), addr); + /// ``` fn from(octets: [u8; 4]) -> Ipv4Addr { Ipv4Addr::new(octets[0], octets[1], octets[2], octets[3]) } @@ -793,6 +843,16 @@ impl From<[u8; 4]> for Ipv4Addr { #[stable(feature = "ip_from_slice", since = "1.17.0")] impl From<[u8; 4]> for IpAddr { + /// Create an `IpAddr::V4` from a four element byte array. + /// + /// # Examples + /// + /// ``` + /// use std::net::{IpAddr, Ipv4Addr}; + /// + /// let addr = IpAddr::from([13u8, 12u8, 11u8, 10u8]); + /// assert_eq!(IpAddr::V4(Ipv4Addr::new(13, 12, 11, 10)), addr); + /// ``` fn from(octets: [u8; 4]) -> IpAddr { IpAddr::V4(Ipv4Addr::from(octets)) } @@ -811,21 +871,27 @@ impl Ipv6Addr { /// let addr = Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, - h: u16) -> Ipv6Addr { - let mut addr: c::in6_addr = unsafe { mem::zeroed() }; - addr.s6_addr = [(a >> 8) as u8, a as u8, - (b >> 8) as u8, b as u8, - (c >> 8) as u8, c as u8, - (d >> 8) as u8, d as u8, - (e >> 8) as u8, e as u8, - (f >> 8) as u8, f as u8, - (g >> 8) as u8, g as u8, - (h >> 8) as u8, h as u8]; - Ipv6Addr { inner: addr } + #[rustc_const_unstable(feature = "const_ip")] + pub const fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, + g: u16, h: u16) -> Ipv6Addr { + Ipv6Addr { + inner: c::in6_addr { + s6_addr: [ + (a >> 8) as u8, a as u8, + (b >> 8) as u8, b as u8, + (c >> 8) as u8, c as u8, + (d >> 8) as u8, d as u8, + (e >> 8) as u8, e as u8, + (f >> 8) as u8, f as u8, + (g >> 8) as u8, g as u8, + (h >> 8) as u8, h as u8 + ], + } + } + } - /// Creates a new IPv6 address representing localhost: `::1`. + /// An IPv6 address representing localhost: `::1`. /// /// # Examples /// @@ -833,17 +899,15 @@ impl Ipv6Addr { /// #![feature(ip_constructors)] /// use std::net::Ipv6Addr; /// - /// let addr = Ipv6Addr::localhost(); + /// let addr = Ipv6Addr::LOCALHOST; /// assert_eq!(addr, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)); /// ``` #[unstable(feature = "ip_constructors", reason = "requires greater scrutiny before stabilization", issue = "44582")] - pub fn localhost() -> Ipv6Addr { - Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1) - } + pub const LOCALHOST: Self = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1); - /// Creates a new IPv6 address representing the unspecified address: `::` + /// An IPv6 address representing the unspecified address: `::` /// /// # Examples /// @@ -851,15 +915,13 @@ impl Ipv6Addr { /// #![feature(ip_constructors)] /// use std::net::Ipv6Addr; /// - /// let addr = Ipv6Addr::unspecified(); + /// let addr = Ipv6Addr::UNSPECIFIED; /// assert_eq!(addr, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)); /// ``` #[unstable(feature = "ip_constructors", reason = "requires greater scrutiny before stabilization", issue = "44582")] - pub fn unspecified() -> Ipv6Addr { - Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0) - } + pub const UNSPECIFIED: Self = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0); /// Returns the eight 16-bit segments that make up this address. /// @@ -1276,9 +1338,9 @@ impl PartialEq for Ipv6Addr { #[stable(feature = "ip_cmp", since = "1.16.0")] impl PartialEq<IpAddr> for Ipv6Addr { fn eq(&self, other: &IpAddr) -> bool { - match *other { + match other { IpAddr::V4(_) => false, - IpAddr::V6(ref v6) => self == v6, + IpAddr::V6(v6) => self == v6, } } } @@ -1286,9 +1348,9 @@ impl PartialEq<IpAddr> for Ipv6Addr { #[stable(feature = "ip_cmp", since = "1.16.0")] impl PartialEq<Ipv6Addr> for IpAddr { fn eq(&self, other: &Ipv6Addr) -> bool { - match *self { + match self { IpAddr::V4(_) => false, - IpAddr::V6(ref v6) => v6 == other, + IpAddr::V6(v6) => v6 == other, } } } @@ -1313,9 +1375,9 @@ impl PartialOrd for Ipv6Addr { #[stable(feature = "ip_cmp", since = "1.16.0")] impl PartialOrd<Ipv6Addr> for IpAddr { fn partial_cmp(&self, other: &Ipv6Addr) -> Option<Ordering> { - match *self { + match self { IpAddr::V4(_) => Some(Ordering::Less), - IpAddr::V6(ref v6) => v6.partial_cmp(other), + IpAddr::V6(v6) => v6.partial_cmp(other), } } } @@ -1323,9 +1385,9 @@ impl PartialOrd<Ipv6Addr> for IpAddr { #[stable(feature = "ip_cmp", since = "1.16.0")] impl PartialOrd<IpAddr> for Ipv6Addr { fn partial_cmp(&self, other: &IpAddr) -> Option<Ordering> { - match *other { + match other { IpAddr::V4(_) => Some(Ordering::Greater), - IpAddr::V6(ref v6) => self.partial_cmp(v6), + IpAddr::V6(v6) => self.partial_cmp(v6), } } } @@ -1346,7 +1408,7 @@ impl FromInner<c::in6_addr> for Ipv6Addr { } } -#[unstable(feature = "i128", issue = "35118")] +#[stable(feature = "i128", since = "1.26.0")] impl From<Ipv6Addr> for u128 { fn from(ip: Ipv6Addr) -> u128 { let ip = ip.segments(); @@ -1355,7 +1417,7 @@ impl From<Ipv6Addr> for u128 { ((ip[6] as u128) << 16) + (ip[7] as u128) } } -#[unstable(feature = "i128", issue = "35118")] +#[stable(feature = "i128", since = "1.26.0")] impl From<u128> for Ipv6Addr { fn from(ip: u128) -> Ipv6Addr { Ipv6Addr::new( @@ -1369,8 +1431,7 @@ impl From<u128> for Ipv6Addr { #[stable(feature = "ipv6_from_octets", since = "1.9.0")] impl From<[u8; 16]> for Ipv6Addr { fn from(octets: [u8; 16]) -> Ipv6Addr { - let mut inner: c::in6_addr = unsafe { mem::zeroed() }; - inner.s6_addr = octets; + let inner = c::in6_addr { s6_addr: octets }; Ipv6Addr::from_inner(inner) } } @@ -1386,6 +1447,27 @@ impl From<[u16; 8]> for Ipv6Addr { #[stable(feature = "ip_from_slice", since = "1.17.0")] impl From<[u8; 16]> for IpAddr { + /// Create an `IpAddr::V6` from a sixteen element byte array. + /// + /// # Examples + /// + /// ``` + /// use std::net::{IpAddr, Ipv6Addr}; + /// + /// let addr = IpAddr::from([ + /// 25u8, 24u8, 23u8, 22u8, 21u8, 20u8, 19u8, 18u8, + /// 17u8, 16u8, 15u8, 14u8, 13u8, 12u8, 11u8, 10u8, + /// ]); + /// assert_eq!( + /// IpAddr::V6(Ipv6Addr::new( + /// 0x1918, 0x1716, + /// 0x1514, 0x1312, + /// 0x1110, 0x0f0e, + /// 0x0d0c, 0x0b0a + /// )), + /// addr + /// ); + /// ``` fn from(octets: [u8; 16]) -> IpAddr { IpAddr::V6(Ipv6Addr::from(octets)) } @@ -1393,6 +1475,27 @@ impl From<[u8; 16]> for IpAddr { #[stable(feature = "ip_from_slice", since = "1.17.0")] impl From<[u16; 8]> for IpAddr { + /// Create an `IpAddr::V6` from an eight element 16-bit array. + /// + /// # Examples + /// + /// ``` + /// use std::net::{IpAddr, Ipv6Addr}; + /// + /// let addr = IpAddr::from([ + /// 525u16, 524u16, 523u16, 522u16, + /// 521u16, 520u16, 519u16, 518u16, + /// ]); + /// assert_eq!( + /// IpAddr::V6(Ipv6Addr::new( + /// 0x20d, 0x20c, + /// 0x20b, 0x20a, + /// 0x209, 0x208, + /// 0x207, 0x206 + /// )), + /// addr + /// ); + /// ``` fn from(segments: [u16; 8]) -> IpAddr { IpAddr::V6(Ipv6Addr::from(segments)) } @@ -1759,18 +1862,20 @@ mod tests { #[test] fn ipv4_from_constructors() { - assert_eq!(Ipv4Addr::localhost(), Ipv4Addr::new(127, 0, 0, 1)); - assert!(Ipv4Addr::localhost().is_loopback()); - assert_eq!(Ipv4Addr::unspecified(), Ipv4Addr::new(0, 0, 0, 0)); - assert!(Ipv4Addr::unspecified().is_unspecified()); + assert_eq!(Ipv4Addr::LOCALHOST, Ipv4Addr::new(127, 0, 0, 1)); + assert!(Ipv4Addr::LOCALHOST.is_loopback()); + assert_eq!(Ipv4Addr::UNSPECIFIED, Ipv4Addr::new(0, 0, 0, 0)); + assert!(Ipv4Addr::UNSPECIFIED.is_unspecified()); + assert_eq!(Ipv4Addr::BROADCAST, Ipv4Addr::new(255, 255, 255, 255)); + assert!(Ipv4Addr::BROADCAST.is_broadcast()); } #[test] fn ipv6_from_contructors() { - assert_eq!(Ipv6Addr::localhost(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)); - assert!(Ipv6Addr::localhost().is_loopback()); - assert_eq!(Ipv6Addr::unspecified(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)); - assert!(Ipv6Addr::unspecified().is_unspecified()); + assert_eq!(Ipv6Addr::LOCALHOST, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)); + assert!(Ipv6Addr::LOCALHOST.is_loopback()); + assert_eq!(Ipv6Addr::UNSPECIFIED, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)); + assert!(Ipv6Addr::UNSPECIFIED.is_unspecified()); } #[test] diff --git a/src/libstd/net/mod.rs b/src/libstd/net/mod.rs index 9fcb93e2032..be4bcee8a68 100644 --- a/src/libstd/net/mod.rs +++ b/src/libstd/net/mod.rs @@ -38,9 +38,7 @@ #![stable(feature = "rust1", since = "1.0.0")] -use fmt; use io::{self, Error, ErrorKind}; -use sys_common::net as net_imp; #[stable(feature = "rust1", since = "1.0.0")] pub use self::ip::{IpAddr, Ipv4Addr, Ipv6Addr, Ipv6MulticastScope}; @@ -128,59 +126,3 @@ fn each_addr<A: ToSocketAddrs, F, T>(addr: A, mut f: F) -> io::Result<T> "could not resolve to any addresses") })) } - -/// An iterator over `SocketAddr` values returned from a host lookup operation. -#[unstable(feature = "lookup_host", reason = "unsure about the returned \ - iterator and returning socket \ - addresses", - issue = "27705")] -pub struct LookupHost(net_imp::LookupHost); - -#[unstable(feature = "lookup_host", reason = "unsure about the returned \ - iterator and returning socket \ - addresses", - issue = "27705")] -impl Iterator for LookupHost { - type Item = SocketAddr; - fn next(&mut self) -> Option<SocketAddr> { self.0.next() } -} - -#[unstable(feature = "lookup_host", reason = "unsure about the returned \ - iterator and returning socket \ - addresses", - issue = "27705")] -impl fmt::Debug for LookupHost { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.pad("LookupHost { .. }") - } -} - -/// Resolve the host specified by `host` as a number of `SocketAddr` instances. -/// -/// This method may perform a DNS query to resolve `host` and may also inspect -/// system configuration to resolve the specified hostname. -/// -/// The returned iterator will skip over any unknown addresses returned by the -/// operating system. -/// -/// # Examples -/// -/// ```no_run -/// #![feature(lookup_host)] -/// -/// use std::net; -/// -/// # fn foo() -> std::io::Result<()> { -/// for host in net::lookup_host("rust-lang.org")? { -/// println!("found address: {}", host); -/// } -/// # Ok(()) -/// # } -/// ``` -#[unstable(feature = "lookup_host", reason = "unsure about the returned \ - iterator and returning socket \ - addresses", - issue = "27705")] -pub fn lookup_host(host: &str) -> io::Result<LookupHost> { - net_imp::lookup_host(host).map(LookupHost) -} diff --git a/src/libstd/net/parser.rs b/src/libstd/net/parser.rs index 261d44eebaa..cf3e5354a31 100644 --- a/src/libstd/net/parser.rs +++ b/src/libstd/net/parser.rs @@ -53,15 +53,12 @@ impl<'a> Parser<'a> { F: FnOnce(&mut Parser) -> Option<T>, { self.read_atomically(move |p| { - match cb(p) { - Some(x) => if p.is_eof() {Some(x)} else {None}, - None => None, - } + cb(p).filter(|_| p.is_eof()) }) } // Return result of first successful parser - fn read_or<T>(&mut self, parsers: &mut [Box<FnMut(&mut Parser) -> Option<T> + 'static>]) + fn read_or<T>(&mut self, parsers: &mut [Box<dyn FnMut(&mut Parser) -> Option<T> + 'static>]) -> Option<T> { for pf in parsers { if let Some(r) = self.read_atomically(|p: &mut Parser| pf(p)) { @@ -372,6 +369,25 @@ impl FromStr for SocketAddr { /// [`IpAddr`], [`Ipv4Addr`], [`Ipv6Addr`], [`SocketAddr`], [`SocketAddrV4`], and /// [`SocketAddrV6`]. /// +/// # Potential causes +/// +/// `AddrParseError` may be thrown because the provided string does not parse as the given type, +/// often because it includes information only handled by a different address type. +/// +/// ```should_panic +/// use std::net::IpAddr; +/// let _foo: IpAddr = "127.0.0.1:8080".parse().expect("Cannot handle the socket port"); +/// ``` +/// +/// [`IpAddr`] doesn't handle the port. Use [`SocketAddr`] instead. +/// +/// ``` +/// use std::net::SocketAddr; +/// +/// // No problem, the `panic!` message has disappeared. +/// let _foo: SocketAddr = "127.0.0.1:8080".parse().expect("unreachable panic"); +/// ``` +/// /// [`FromStr`]: ../../std/str/trait.FromStr.html /// [`IpAddr`]: ../../std/net/enum.IpAddr.html /// [`Ipv4Addr`]: ../../std/net/struct.Ipv4Addr.html diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs index 78235ea1b4b..75c7a3d9280 100644 --- a/src/libstd/net/tcp.rs +++ b/src/libstd/net/tcp.rs @@ -72,7 +72,7 @@ pub struct TcpStream(net_imp::TcpStream); /// /// # Examples /// -/// ``` +/// ```no_run /// # use std::io; /// use std::net::{TcpListener, TcpStream}; /// @@ -80,15 +80,15 @@ pub struct TcpStream(net_imp::TcpStream); /// // ... /// } /// -/// # fn process() -> io::Result<()> { -/// let listener = TcpListener::bind("127.0.0.1:80").unwrap(); +/// fn main() -> io::Result<()> { +/// let listener = TcpListener::bind("127.0.0.1:80")?; /// -/// // accept connections and process them serially -/// for stream in listener.incoming() { -/// handle_client(stream?); +/// // accept connections and process them serially +/// for stream in listener.incoming() { +/// handle_client(stream?); +/// } +/// Ok(()) /// } -/// # Ok(()) -/// # } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub struct TcpListener(net_imp::TcpListener); @@ -259,19 +259,21 @@ impl TcpStream { /// Sets the read timeout to the timeout specified. /// /// If the value specified is [`None`], then [`read`] calls will block - /// indefinitely. It is an error to pass the zero `Duration` to this - /// method. + /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is + /// passed to this method. /// - /// # Note + /// # Platform-specific behavior /// /// Platforms may return a different error code whenever a read times out as /// a result of setting this option. For example Unix typically returns an /// error of the kind [`WouldBlock`], but Windows may return [`TimedOut`]. /// /// [`None`]: ../../std/option/enum.Option.html#variant.None + /// [`Err`]: ../../std/result/enum.Result.html#variant.Err /// [`read`]: ../../std/io/trait.Read.html#tymethod.read /// [`WouldBlock`]: ../../std/io/enum.ErrorKind.html#variant.WouldBlock /// [`TimedOut`]: ../../std/io/enum.ErrorKind.html#variant.TimedOut + /// [`Duration`]: ../../std/time/struct.Duration.html /// /// # Examples /// @@ -282,6 +284,20 @@ impl TcpStream { /// .expect("Couldn't connect to the server..."); /// stream.set_read_timeout(None).expect("set_read_timeout call failed"); /// ``` + /// + /// An [`Err`] is returned if the zero [`Duration`] is passed to this + /// method: + /// + /// ```no_run + /// use std::io; + /// use std::net::TcpStream; + /// use std::time::Duration; + /// + /// let stream = TcpStream::connect("127.0.0.1:8080").unwrap(); + /// let result = stream.set_read_timeout(Some(Duration::new(0, 0))); + /// let err = result.unwrap_err(); + /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput) + /// ``` #[stable(feature = "socket_timeout", since = "1.4.0")] pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> { self.0.set_read_timeout(dur) @@ -290,16 +306,17 @@ impl TcpStream { /// Sets the write timeout to the timeout specified. /// /// If the value specified is [`None`], then [`write`] calls will block - /// indefinitely. It is an error to pass the zero [`Duration`] to this - /// method. + /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is + /// passed to this method. /// - /// # Note + /// # Platform-specific behavior /// /// Platforms may return a different error code whenever a write times out /// as a result of setting this option. For example Unix typically returns /// an error of the kind [`WouldBlock`], but Windows may return [`TimedOut`]. /// /// [`None`]: ../../std/option/enum.Option.html#variant.None + /// [`Err`]: ../../std/result/enum.Result.html#variant.Err /// [`write`]: ../../std/io/trait.Write.html#tymethod.write /// [`Duration`]: ../../std/time/struct.Duration.html /// [`WouldBlock`]: ../../std/io/enum.ErrorKind.html#variant.WouldBlock @@ -314,6 +331,20 @@ impl TcpStream { /// .expect("Couldn't connect to the server..."); /// stream.set_write_timeout(None).expect("set_write_timeout call failed"); /// ``` + /// + /// An [`Err`] is returned if the zero [`Duration`] is passed to this + /// method: + /// + /// ```no_run + /// use std::io; + /// use std::net::TcpStream; + /// use std::time::Duration; + /// + /// let stream = TcpStream::connect("127.0.0.1:8080").unwrap(); + /// let result = stream.set_write_timeout(Some(Duration::new(0, 0))); + /// let err = result.unwrap_err(); + /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput) + /// ``` #[stable(feature = "socket_timeout", since = "1.4.0")] pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> { self.0.set_write_timeout(dur) @@ -323,7 +354,7 @@ impl TcpStream { /// /// If the timeout is [`None`], then [`read`] calls will block indefinitely. /// - /// # Note + /// # Platform-specific behavior /// /// Some platforms do not provide access to the current timeout. /// @@ -349,7 +380,7 @@ impl TcpStream { /// /// If the timeout is [`None`], then [`write`] calls will block indefinitely. /// - /// # Note + /// # Platform-specific behavior /// /// Some platforms do not provide access to the current timeout. /// @@ -896,7 +927,7 @@ mod tests { use time::{Instant, Duration}; use thread; - fn each_ip(f: &mut FnMut(SocketAddr)) { + fn each_ip(f: &mut dyn FnMut(SocketAddr)) { f(next_test_ip4()); f(next_test_ip6()); } @@ -1545,6 +1576,26 @@ mod tests { drop(listener); } + // Ensure the `set_read_timeout` and `set_write_timeout` calls return errors + // when passed zero Durations + #[test] + fn test_timeout_zero_duration() { + let addr = next_test_ip4(); + + let listener = t!(TcpListener::bind(&addr)); + let stream = t!(TcpStream::connect(&addr)); + + let result = stream.set_write_timeout(Some(Duration::new(0, 0))); + let err = result.unwrap_err(); + assert_eq!(err.kind(), ErrorKind::InvalidInput); + + let result = stream.set_read_timeout(Some(Duration::new(0, 0))); + let err = result.unwrap_err(); + assert_eq!(err.kind(), ErrorKind::InvalidInput); + + drop(listener); + } + #[test] fn nodelay() { let addr = next_test_ip4(); diff --git a/src/libstd/net/udp.rs b/src/libstd/net/udp.rs index fc7f9205d06..0ebe3284b4f 100644 --- a/src/libstd/net/udp.rs +++ b/src/libstd/net/udp.rs @@ -44,22 +44,22 @@ use time::Duration; /// ```no_run /// use std::net::UdpSocket; /// -/// # fn foo() -> std::io::Result<()> { -/// { -/// let mut socket = UdpSocket::bind("127.0.0.1:34254")?; +/// fn main() -> std::io::Result<()> { +/// { +/// let mut socket = UdpSocket::bind("127.0.0.1:34254")?; /// -/// // Receives a single datagram message on the socket. If `buf` is too small to hold -/// // the message, it will be cut off. -/// let mut buf = [0; 10]; -/// let (amt, src) = socket.recv_from(&mut buf)?; +/// // Receives a single datagram message on the socket. If `buf` is too small to hold +/// // the message, it will be cut off. +/// let mut buf = [0; 10]; +/// let (amt, src) = socket.recv_from(&mut buf)?; /// -/// // Redeclare `buf` as slice of the received data and send reverse data back to origin. -/// let buf = &mut buf[..amt]; -/// buf.reverse(); -/// socket.send_to(buf, &src)?; -/// # Ok(()) -/// } // the socket is closed here -/// # } +/// // Redeclare `buf` as slice of the received data and send reverse data back to origin. +/// let buf = &mut buf[..amt]; +/// buf.reverse(); +/// socket.send_to(buf, &src)?; +/// } // the socket is closed here +/// Ok(()) +/// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub struct UdpSocket(net_imp::UdpSocket); @@ -228,16 +228,17 @@ impl UdpSocket { /// Sets the read timeout to the timeout specified. /// /// If the value specified is [`None`], then [`read`] calls will block - /// indefinitely. It is an error to pass the zero [`Duration`] to this - /// method. + /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is + /// passed to this method. /// - /// # Note + /// # Platform-specific behavior /// /// Platforms may return a different error code whenever a read times out as /// a result of setting this option. For example Unix typically returns an /// error of the kind [`WouldBlock`], but Windows may return [`TimedOut`]. /// /// [`None`]: ../../std/option/enum.Option.html#variant.None + /// [`Err`]: ../../std/result/enum.Result.html#variant.Err /// [`read`]: ../../std/io/trait.Read.html#tymethod.read /// [`Duration`]: ../../std/time/struct.Duration.html /// [`WouldBlock`]: ../../std/io/enum.ErrorKind.html#variant.WouldBlock @@ -251,6 +252,20 @@ impl UdpSocket { /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address"); /// socket.set_read_timeout(None).expect("set_read_timeout call failed"); /// ``` + /// + /// An [`Err`] is returned if the zero [`Duration`] is passed to this + /// method: + /// + /// ```no_run + /// use std::io; + /// use std::net::UdpSocket; + /// use std::time::Duration; + /// + /// let socket = UdpSocket::bind("127.0.0.1:34254").unwrap(); + /// let result = socket.set_read_timeout(Some(Duration::new(0, 0))); + /// let err = result.unwrap_err(); + /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput) + /// ``` #[stable(feature = "socket_timeout", since = "1.4.0")] pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> { self.0.set_read_timeout(dur) @@ -259,16 +274,17 @@ impl UdpSocket { /// Sets the write timeout to the timeout specified. /// /// If the value specified is [`None`], then [`write`] calls will block - /// indefinitely. It is an error to pass the zero [`Duration`] to this - /// method. + /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is + /// passed to this method. /// - /// # Note + /// # Platform-specific behavior /// /// Platforms may return a different error code whenever a write times out /// as a result of setting this option. For example Unix typically returns /// an error of the kind [`WouldBlock`], but Windows may return [`TimedOut`]. /// /// [`None`]: ../../std/option/enum.Option.html#variant.None + /// [`Err`]: ../../std/result/enum.Result.html#variant.Err /// [`write`]: ../../std/io/trait.Write.html#tymethod.write /// [`Duration`]: ../../std/time/struct.Duration.html /// [`WouldBlock`]: ../../std/io/enum.ErrorKind.html#variant.WouldBlock @@ -282,6 +298,20 @@ impl UdpSocket { /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address"); /// socket.set_write_timeout(None).expect("set_write_timeout call failed"); /// ``` + /// + /// An [`Err`] is returned if the zero [`Duration`] is passed to this + /// method: + /// + /// ```no_run + /// use std::io; + /// use std::net::UdpSocket; + /// use std::time::Duration; + /// + /// let socket = UdpSocket::bind("127.0.0.1:34254").unwrap(); + /// let result = socket.set_write_timeout(Some(Duration::new(0, 0))); + /// let err = result.unwrap_err(); + /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput) + /// ``` #[stable(feature = "socket_timeout", since = "1.4.0")] pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> { self.0.set_write_timeout(dur) @@ -796,7 +826,7 @@ mod tests { use time::{Instant, Duration}; use thread; - fn each_ip(f: &mut FnMut(SocketAddr, SocketAddr)) { + fn each_ip(f: &mut dyn FnMut(SocketAddr, SocketAddr)) { f(next_test_ip4(), next_test_ip4()); f(next_test_ip6(), next_test_ip6()); } @@ -1024,6 +1054,23 @@ mod tests { assert!(start.elapsed() > Duration::from_millis(400)); } + // Ensure the `set_read_timeout` and `set_write_timeout` calls return errors + // when passed zero Durations + #[test] + fn test_timeout_zero_duration() { + let addr = next_test_ip4(); + + let socket = t!(UdpSocket::bind(&addr)); + + let result = socket.set_write_timeout(Some(Duration::new(0, 0))); + let err = result.unwrap_err(); + assert_eq!(err.kind(), ErrorKind::InvalidInput); + + let result = socket.set_read_timeout(Some(Duration::new(0, 0))); + let err = result.unwrap_err(); + assert_eq!(err.kind(), ErrorKind::InvalidInput); + } + #[test] fn connect_send_recv() { let addr = next_test_ip4(); |
