aboutsummaryrefslogtreecommitdiff
path: root/ctr-std/src/net
diff options
context:
space:
mode:
Diffstat (limited to 'ctr-std/src/net')
-rw-r--r--ctr-std/src/net/addr.rs1077
-rw-r--r--ctr-std/src/net/ip.rs1940
-rw-r--r--ctr-std/src/net/mod.rs128
-rw-r--r--ctr-std/src/net/parser.rs414
-rw-r--r--ctr-std/src/net/tcp.rs1713
-rw-r--r--ctr-std/src/net/test.rs57
-rw-r--r--ctr-std/src/net/udp.rs1163
7 files changed, 0 insertions, 6492 deletions
diff --git a/ctr-std/src/net/addr.rs b/ctr-std/src/net/addr.rs
deleted file mode 100644
index e80c3ee..0000000
--- a/ctr-std/src/net/addr.rs
+++ /dev/null
@@ -1,1077 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use fmt;
-use hash;
-use io;
-use mem;
-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;
-
-/// An internet socket address, either IPv4 or IPv6.
-///
-/// Internet socket addresses consist of an [IP address], a 16-bit port number, as well
-/// 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
-///
-/// # Examples
-///
-/// ```
-/// use std::net::{IpAddr, Ipv4Addr, SocketAddr};
-///
-/// let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
-///
-/// assert_eq!("127.0.0.1:8080".parse(), Ok(socket));
-/// assert_eq!(socket.port(), 8080);
-/// assert_eq!(socket.is_ipv4(), true);
-/// ```
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub enum SocketAddr {
- /// An IPv4 socket address.
- #[stable(feature = "rust1", since = "1.0.0")]
- V4(#[stable(feature = "rust1", since = "1.0.0")] SocketAddrV4),
- /// An IPv6 socket address.
- #[stable(feature = "rust1", since = "1.0.0")]
- V6(#[stable(feature = "rust1", since = "1.0.0")] SocketAddrV6),
-}
-
-/// An IPv4 socket address.
-///
-/// IPv4 socket addresses consist of an [IPv4 address] and a 16-bit port number, as
-/// stated in [IETF RFC 793].
-///
-/// 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
-///
-/// # Examples
-///
-/// ```
-/// use std::net::{Ipv4Addr, SocketAddrV4};
-///
-/// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
-///
-/// assert_eq!("127.0.0.1:8080".parse(), Ok(socket));
-/// assert_eq!(socket.ip(), &Ipv4Addr::new(127, 0, 0, 1));
-/// assert_eq!(socket.port(), 8080);
-/// ```
-#[derive(Copy)]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct SocketAddrV4 { inner: c::sockaddr_in }
-
-/// An IPv6 socket address.
-///
-/// IPv6 socket addresses consist of an [Ipv6 address], a 16-bit port number, as well
-/// as fields containing the traffic class, the flow label, and a scope identifier
-/// (see [IETF RFC 2553, Section 3.3] for more details).
-///
-/// 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
-///
-/// # Examples
-///
-/// ```
-/// use std::net::{Ipv6Addr, SocketAddrV6};
-///
-/// let socket = SocketAddrV6::new(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), 8080, 0, 0);
-///
-/// assert_eq!("[2001:db8::1]:8080".parse(), Ok(socket));
-/// assert_eq!(socket.ip(), &Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1));
-/// assert_eq!(socket.port(), 8080);
-/// ```
-#[derive(Copy)]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct SocketAddrV6 { inner: c::sockaddr_in6 }
-
-impl SocketAddr {
- /// Creates a new socket address from an [IP address] and a port number.
- ///
- /// [IP address]: ../../std/net/enum.IpAddr.html
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::{IpAddr, Ipv4Addr, SocketAddr};
- ///
- /// let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
- /// assert_eq!(socket.ip(), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)));
- /// assert_eq!(socket.port(), 8080);
- /// ```
- #[stable(feature = "ip_addr", since = "1.7.0")]
- pub fn new(ip: IpAddr, port: u16) -> SocketAddr {
- match ip {
- IpAddr::V4(a) => SocketAddr::V4(SocketAddrV4::new(a, port)),
- IpAddr::V6(a) => SocketAddr::V6(SocketAddrV6::new(a, port, 0, 0)),
- }
- }
-
- /// Returns the IP address associated with this socket address.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::{IpAddr, Ipv4Addr, SocketAddr};
- ///
- /// let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
- /// assert_eq!(socket.ip(), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)));
- /// ```
- #[stable(feature = "ip_addr", since = "1.7.0")]
- pub fn ip(&self) -> IpAddr {
- match *self {
- SocketAddr::V4(ref a) => IpAddr::V4(*a.ip()),
- SocketAddr::V6(ref a) => IpAddr::V6(*a.ip()),
- }
- }
-
- /// Changes the IP address associated with this socket address.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::{IpAddr, Ipv4Addr, SocketAddr};
- ///
- /// let mut socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
- /// socket.set_ip(IpAddr::V4(Ipv4Addr::new(10, 10, 0, 1)));
- /// assert_eq!(socket.ip(), IpAddr::V4(Ipv4Addr::new(10, 10, 0, 1)));
- /// ```
- #[stable(feature = "sockaddr_setters", since = "1.9.0")]
- 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.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::{IpAddr, Ipv4Addr, SocketAddr};
- ///
- /// let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
- /// assert_eq!(socket.port(), 8080);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn port(&self) -> u16 {
- match *self {
- SocketAddr::V4(ref a) => a.port(),
- SocketAddr::V6(ref a) => a.port(),
- }
- }
-
- /// Changes the port number associated with this socket address.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::{IpAddr, Ipv4Addr, SocketAddr};
- ///
- /// let mut socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
- /// socket.set_port(1025);
- /// assert_eq!(socket.port(), 1025);
- /// ```
- #[stable(feature = "sockaddr_setters", since = "1.9.0")]
- 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),
- }
- }
-
- /// Returns [`true`] if the [IP address] in this `SocketAddr` is an
- /// [IPv4 address], and [`false`] otherwise.
- ///
- /// [`true`]: ../../std/primitive.bool.html
- /// [`false`]: ../../std/primitive.bool.html
- /// [IP address]: ../../std/net/enum.IpAddr.html
- /// [IPv4 address]: ../../std/net/enum.IpAddr.html#variant.V4
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::{IpAddr, Ipv4Addr, SocketAddr};
- ///
- /// fn main() {
- /// let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
- /// assert_eq!(socket.is_ipv4(), true);
- /// assert_eq!(socket.is_ipv6(), false);
- /// }
- /// ```
- #[stable(feature = "sockaddr_checker", since = "1.16.0")]
- pub fn is_ipv4(&self) -> bool {
- match *self {
- SocketAddr::V4(_) => true,
- SocketAddr::V6(_) => false,
- }
- }
-
- /// Returns [`true`] if the [IP address] in this `SocketAddr` is an
- /// [IPv6 address], and [`false`] otherwise.
- ///
- /// [`true`]: ../../std/primitive.bool.html
- /// [`false`]: ../../std/primitive.bool.html
- /// [IP address]: ../../std/net/enum.IpAddr.html
- /// [IPv6 address]: ../../std/net/enum.IpAddr.html#variant.V6
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::{IpAddr, Ipv6Addr, SocketAddr};
- ///
- /// fn main() {
- /// let socket = SocketAddr::new(
- /// IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 65535, 0, 1)), 8080);
- /// assert_eq!(socket.is_ipv4(), false);
- /// assert_eq!(socket.is_ipv6(), true);
- /// }
- /// ```
- #[stable(feature = "sockaddr_checker", since = "1.16.0")]
- pub fn is_ipv6(&self) -> bool {
- match *self {
- SocketAddr::V4(_) => false,
- SocketAddr::V6(_) => true,
- }
- }
-}
-
-impl SocketAddrV4 {
- /// Creates a new socket address from an [IPv4 address] and a port number.
- ///
- /// [IPv4 address]: ../../std/net/struct.Ipv4Addr.html
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::{SocketAddrV4, Ipv4Addr};
- ///
- /// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn new(ip: Ipv4Addr, port: u16) -> SocketAddrV4 {
- SocketAddrV4 {
- inner: c::sockaddr_in {
- sin_family: c::AF_INET as c::sa_family_t,
- sin_port: hton(port),
- sin_addr: *ip.as_inner(),
- .. unsafe { mem::zeroed() }
- },
- }
- }
-
- /// Returns the IP address associated with this socket address.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::{SocketAddrV4, Ipv4Addr};
- ///
- /// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
- /// assert_eq!(socket.ip(), &Ipv4Addr::new(127, 0, 0, 1));
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn ip(&self) -> &Ipv4Addr {
- unsafe {
- &*(&self.inner.sin_addr as *const c::in_addr as *const Ipv4Addr)
- }
- }
-
- /// Changes the IP address associated with this socket address.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::{SocketAddrV4, Ipv4Addr};
- ///
- /// let mut socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
- /// socket.set_ip(Ipv4Addr::new(192, 168, 0, 1));
- /// assert_eq!(socket.ip(), &Ipv4Addr::new(192, 168, 0, 1));
- /// ```
- #[stable(feature = "sockaddr_setters", since = "1.9.0")]
- 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.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::{SocketAddrV4, Ipv4Addr};
- ///
- /// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
- /// assert_eq!(socket.port(), 8080);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn port(&self) -> u16 {
- ntoh(self.inner.sin_port)
- }
-
- /// Changes the port number associated with this socket address.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::{SocketAddrV4, Ipv4Addr};
- ///
- /// let mut socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
- /// socket.set_port(4242);
- /// assert_eq!(socket.port(), 4242);
- /// ```
- #[stable(feature = "sockaddr_setters", since = "1.9.0")]
- pub fn set_port(&mut self, new_port: u16) {
- self.inner.sin_port = hton(new_port);
- }
-}
-
-impl SocketAddrV6 {
- /// Creates a new socket address from an [IPv6 address], a 16-bit port number,
- /// and the `flowinfo` and `scope_id` fields.
- ///
- /// For more information on the meaning and layout of the `flowinfo` and `scope_id`
- /// parameters, see [IETF RFC 2553, Section 3.3].
- ///
- /// [IETF RFC 2553, Section 3.3]: https://tools.ietf.org/html/rfc2553#section-3.3
- /// [IPv6 address]: ../../std/net/struct.Ipv6Addr.html
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::{SocketAddrV6, Ipv6Addr};
- ///
- /// let socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 0, 0);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn new(ip: Ipv6Addr, port: u16, flowinfo: u32, scope_id: u32)
- -> SocketAddrV6 {
- SocketAddrV6 {
- inner: c::sockaddr_in6 {
- sin6_family: c::AF_INET6 as c::sa_family_t,
- sin6_port: hton(port),
- sin6_addr: *ip.as_inner(),
- sin6_flowinfo: flowinfo,
- sin6_scope_id: scope_id,
- .. unsafe { mem::zeroed() }
- },
- }
- }
-
- /// Returns the IP address associated with this socket address.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::{SocketAddrV6, Ipv6Addr};
- ///
- /// let socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 0, 0);
- /// assert_eq!(socket.ip(), &Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn ip(&self) -> &Ipv6Addr {
- unsafe {
- &*(&self.inner.sin6_addr as *const c::in6_addr as *const Ipv6Addr)
- }
- }
-
- /// Changes the IP address associated with this socket address.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::{SocketAddrV6, Ipv6Addr};
- ///
- /// let mut socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 0, 0);
- /// socket.set_ip(Ipv6Addr::new(76, 45, 0, 0, 0, 0, 0, 0));
- /// assert_eq!(socket.ip(), &Ipv6Addr::new(76, 45, 0, 0, 0, 0, 0, 0));
- /// ```
- #[stable(feature = "sockaddr_setters", since = "1.9.0")]
- 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.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::{SocketAddrV6, Ipv6Addr};
- ///
- /// let socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 0, 0);
- /// assert_eq!(socket.port(), 8080);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn port(&self) -> u16 {
- ntoh(self.inner.sin6_port)
- }
-
- /// Changes the port number associated with this socket address.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::{SocketAddrV6, Ipv6Addr};
- ///
- /// let mut socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 0, 0);
- /// socket.set_port(4242);
- /// assert_eq!(socket.port(), 4242);
- /// ```
- #[stable(feature = "sockaddr_setters", since = "1.9.0")]
- pub fn set_port(&mut self, new_port: u16) {
- self.inner.sin6_port = hton(new_port);
- }
-
- /// Returns the flow information associated with this address.
- ///
- /// This information corresponds to the `sin6_flowinfo` field in C's `netinet/in.h`,
- /// as specified in [IETF RFC 2553, Section 3.3].
- /// It combines information about the flow label and the traffic class as specified
- /// in [IETF RFC 2460], respectively [Section 6] and [Section 7].
- ///
- /// [IETF RFC 2553, Section 3.3]: https://tools.ietf.org/html/rfc2553#section-3.3
- /// [IETF RFC 2460]: https://tools.ietf.org/html/rfc2460
- /// [Section 6]: https://tools.ietf.org/html/rfc2460#section-6
- /// [Section 7]: https://tools.ietf.org/html/rfc2460#section-7
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::{SocketAddrV6, Ipv6Addr};
- ///
- /// let socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 10, 0);
- /// assert_eq!(socket.flowinfo(), 10);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn flowinfo(&self) -> u32 {
- self.inner.sin6_flowinfo
- }
-
- /// Changes the flow information associated with this socket address.
- ///
- /// See the [`flowinfo`] method's documentation for more details.
- ///
- /// [`flowinfo`]: #method.flowinfo
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::{SocketAddrV6, Ipv6Addr};
- ///
- /// let mut socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 10, 0);
- /// socket.set_flowinfo(56);
- /// assert_eq!(socket.flowinfo(), 56);
- /// ```
- #[stable(feature = "sockaddr_setters", since = "1.9.0")]
- pub fn set_flowinfo(&mut self, new_flowinfo: u32) {
- self.inner.sin6_flowinfo = new_flowinfo;
- }
-
- /// Returns the scope ID associated with this address.
- ///
- /// This information corresponds to the `sin6_scope_id` field in C's `netinet/in.h`,
- /// as specified in [IETF RFC 2553, Section 3.3].
- ///
- /// [IETF RFC 2553, Section 3.3]: https://tools.ietf.org/html/rfc2553#section-3.3
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::{SocketAddrV6, Ipv6Addr};
- ///
- /// let socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 0, 78);
- /// assert_eq!(socket.scope_id(), 78);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn scope_id(&self) -> u32 {
- self.inner.sin6_scope_id
- }
-
- /// Change the scope ID associated with this socket address.
- ///
- /// See the [`scope_id`] method's documentation for more details.
- ///
- /// [`scope_id`]: #method.scope_id
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::{SocketAddrV6, Ipv6Addr};
- ///
- /// let mut socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 0, 78);
- /// socket.set_scope_id(42);
- /// assert_eq!(socket.scope_id(), 42);
- /// ```
- #[stable(feature = "sockaddr_setters", since = "1.9.0")]
- pub fn set_scope_id(&mut self, new_scope_id: u32) {
- self.inner.sin6_scope_id = new_scope_id;
- }
-}
-
-impl FromInner<c::sockaddr_in> for SocketAddrV4 {
- fn from_inner(addr: c::sockaddr_in) -> SocketAddrV4 {
- SocketAddrV4 { inner: addr }
- }
-}
-
-impl FromInner<c::sockaddr_in6> for SocketAddrV6 {
- fn from_inner(addr: c::sockaddr_in6) -> SocketAddrV6 {
- SocketAddrV6 { inner: addr }
- }
-}
-
-#[stable(feature = "ip_from_ip", since = "1.16.0")]
-impl From<SocketAddrV4> for SocketAddr {
- fn from(sock4: SocketAddrV4) -> SocketAddr {
- SocketAddr::V4(sock4)
- }
-}
-
-#[stable(feature = "ip_from_ip", since = "1.16.0")]
-impl From<SocketAddrV6> for SocketAddr {
- fn from(sock6: SocketAddrV6) -> SocketAddr {
- SocketAddr::V6(sock6)
- }
-}
-
-#[stable(feature = "addr_from_into_ip", since = "1.17.0")]
-impl<I: Into<IpAddr>> From<(I, u16)> for SocketAddr {
- fn from(pieces: (I, u16)) -> SocketAddr {
- SocketAddr::new(pieces.0.into(), pieces.1)
- }
-}
-
-impl<'a> IntoInner<(*const c::sockaddr, c::socklen_t)> for &'a SocketAddr {
- fn into_inner(self) -> (*const c::sockaddr, c::socklen_t) {
- match *self {
- SocketAddr::V4(ref a) => {
- (a as *const _ as *const _, mem::size_of_val(a) as c::socklen_t)
- }
- SocketAddr::V6(ref a) => {
- (a as *const _ as *const _, mem::size_of_val(a) as c::socklen_t)
- }
- }
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl fmt::Display for SocketAddr {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- match *self {
- SocketAddr::V4(ref a) => a.fmt(f),
- SocketAddr::V6(ref a) => a.fmt(f),
- }
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl fmt::Display for SocketAddrV4 {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "{}:{}", self.ip(), self.port())
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl fmt::Debug for SocketAddrV4 {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
- fmt::Display::fmt(self, fmt)
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl fmt::Display for SocketAddrV6 {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "[{}]:{}", self.ip(), self.port())
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl fmt::Debug for SocketAddrV6 {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
- fmt::Display::fmt(self, fmt)
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl Clone for SocketAddrV4 {
- fn clone(&self) -> SocketAddrV4 { *self }
-}
-#[stable(feature = "rust1", since = "1.0.0")]
-impl Clone for SocketAddrV6 {
- fn clone(&self) -> SocketAddrV6 { *self }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl PartialEq for SocketAddrV4 {
- fn eq(&self, other: &SocketAddrV4) -> bool {
- self.inner.sin_port == other.inner.sin_port &&
- self.inner.sin_addr.s_addr == other.inner.sin_addr.s_addr
- }
-}
-#[stable(feature = "rust1", since = "1.0.0")]
-impl PartialEq for SocketAddrV6 {
- fn eq(&self, other: &SocketAddrV6) -> bool {
- self.inner.sin6_port == other.inner.sin6_port &&
- self.inner.sin6_addr.s6_addr == other.inner.sin6_addr.s6_addr &&
- self.inner.sin6_flowinfo == other.inner.sin6_flowinfo &&
- self.inner.sin6_scope_id == other.inner.sin6_scope_id
- }
-}
-#[stable(feature = "rust1", since = "1.0.0")]
-impl Eq for SocketAddrV4 {}
-#[stable(feature = "rust1", since = "1.0.0")]
-impl Eq for SocketAddrV6 {}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl hash::Hash for SocketAddrV4 {
- fn hash<H: hash::Hasher>(&self, s: &mut H) {
- (self.inner.sin_port, self.inner.sin_addr.s_addr).hash(s)
- }
-}
-#[stable(feature = "rust1", since = "1.0.0")]
-impl hash::Hash for SocketAddrV6 {
- fn hash<H: hash::Hasher>(&self, s: &mut H) {
- (self.inner.sin6_port, &self.inner.sin6_addr.s6_addr,
- self.inner.sin6_flowinfo, self.inner.sin6_scope_id).hash(s)
- }
-}
-
-/// A trait for objects which can be converted or resolved to one or more
-/// [`SocketAddr`] values.
-///
-/// This trait is used for generic address resolution when constructing network
-/// objects. By default it is implemented for the following types:
-///
-/// * [`SocketAddr`]: [`to_socket_addrs`] is the identity function.
-///
-/// * [`SocketAddrV4`], [`SocketAddrV6`], `(`[`IpAddr`]`, `[`u16`]`)`,
-/// `(`[`Ipv4Addr`]`, `[`u16`]`)`, `(`[`Ipv6Addr`]`, `[`u16`]`)`:
-/// [`to_socket_addrs`] constructs a [`SocketAddr`] trivially.
-///
-/// * `(`[`&str`]`, `[`u16`]`)`: the string should be either a string representation
-/// of an [`IpAddr`] address as expected by [`FromStr`] implementation or a host
-/// name.
-///
-/// * [`&str`]: the string should be either a string representation of a
-/// [`SocketAddr`] as expected by its [`FromStr`] implementation or a string like
-/// `<host_name>:<port>` pair where `<port>` is a [`u16`] value.
-///
-/// This trait allows constructing network objects like [`TcpStream`] or
-/// [`UdpSocket`] easily with values of various types for the bind/connection
-/// address. It is needed because sometimes one type is more appropriate than
-/// the other: for simple uses a string like `"localhost:12345"` is much nicer
-/// than manual construction of the corresponding [`SocketAddr`], but sometimes
-/// [`SocketAddr`] value is *the* main source of the address, and converting it to
-/// some other type (e.g. a string) just for it to be converted back to
-/// [`SocketAddr`] in constructor methods is pointless.
-///
-/// Addresses returned by the operating system that are not IP addresses are
-/// silently ignored.
-///
-/// [`FromStr`]: ../../std/str/trait.FromStr.html
-/// [`IpAddr`]: ../../std/net/enum.IpAddr.html
-/// [`Ipv4Addr`]: ../../std/net/struct.Ipv4Addr.html
-/// [`Ipv6Addr`]: ../../std/net/struct.Ipv6Addr.html
-/// [`SocketAddr`]: ../../std/net/enum.SocketAddr.html
-/// [`SocketAddrV4`]: ../../std/net/struct.SocketAddrV4.html
-/// [`SocketAddrV6`]: ../../std/net/struct.SocketAddrV6.html
-/// [`&str`]: ../../std/primitive.str.html
-/// [`TcpStream`]: ../../std/net/struct.TcpStream.html
-/// [`to_socket_addrs`]: #tymethod.to_socket_addrs
-/// [`UdpSocket`]: ../../std/net/struct.UdpSocket.html
-/// [`u16`]: ../../std/primitive.u16.html
-///
-/// # Examples
-///
-/// Creating a [`SocketAddr`] iterator that yields one item:
-///
-/// ```
-/// use std::net::{ToSocketAddrs, SocketAddr};
-///
-/// let addr = SocketAddr::from(([127, 0, 0, 1], 443));
-/// let mut addrs_iter = addr.to_socket_addrs().unwrap();
-///
-/// assert_eq!(Some(addr), addrs_iter.next());
-/// assert!(addrs_iter.next().is_none());
-/// ```
-///
-/// Creating a [`SocketAddr`] iterator from a hostname:
-///
-/// ```no_run
-/// use std::net::{SocketAddr, ToSocketAddrs};
-///
-/// // assuming 'localhost' resolves to 127.0.0.1
-/// let mut addrs_iter = "localhost:443".to_socket_addrs().unwrap();
-/// assert_eq!(addrs_iter.next(), Some(SocketAddr::from(([127, 0, 0, 1], 443))));
-/// assert!(addrs_iter.next().is_none());
-///
-/// // assuming 'foo' does not resolve
-/// assert!("foo:443".to_socket_addrs().is_err());
-/// ```
-///
-/// Creating a [`SocketAddr`] iterator that yields multiple items:
-///
-/// ```
-/// use std::net::{SocketAddr, ToSocketAddrs};
-///
-/// let addr1 = SocketAddr::from(([0, 0, 0, 0], 80));
-/// let addr2 = SocketAddr::from(([127, 0, 0, 1], 443));
-/// let addrs = vec![addr1, addr2];
-///
-/// let mut addrs_iter = (&addrs[..]).to_socket_addrs().unwrap();
-///
-/// assert_eq!(Some(addr1), addrs_iter.next());
-/// assert_eq!(Some(addr2), addrs_iter.next());
-/// assert!(addrs_iter.next().is_none());
-/// ```
-///
-/// Attempting to create a [`SocketAddr`] iterator from an improperly formatted
-/// socket address `&str` (missing the port):
-///
-/// ```
-/// use std::io;
-/// use std::net::ToSocketAddrs;
-///
-/// let err = "127.0.0.1".to_socket_addrs().unwrap_err();
-/// assert_eq!(err.kind(), io::ErrorKind::InvalidInput);
-/// ```
-///
-/// [`TcpStream::connect`] is an example of an function that utilizes
-/// `ToSocketAddrs` as a trait bound on its parameter in order to accept
-/// different types:
-///
-/// ```no_run
-/// use std::net::{TcpStream, Ipv4Addr};
-///
-/// let stream = TcpStream::connect(("127.0.0.1", 443));
-/// // or
-/// let stream = TcpStream::connect("127.0.0.1:443");
-/// // or
-/// let stream = TcpStream::connect((Ipv4Addr::new(127, 0, 0, 1), 443));
-/// ```
-///
-/// [`TcpStream::connect`]: ../../std/net/struct.TcpStream.html#method.connect
-#[stable(feature = "rust1", since = "1.0.0")]
-pub trait ToSocketAddrs {
- /// Returned iterator over socket addresses which this type may correspond
- /// to.
- #[stable(feature = "rust1", since = "1.0.0")]
- type Iter: Iterator<Item=SocketAddr>;
-
- /// Converts this object to an iterator of resolved `SocketAddr`s.
- ///
- /// The returned iterator may not actually yield any values depending on the
- /// outcome of any resolution performed.
- ///
- /// Note that this function may block the current thread while resolution is
- /// performed.
- #[stable(feature = "rust1", since = "1.0.0")]
- fn to_socket_addrs(&self) -> io::Result<Self::Iter>;
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl ToSocketAddrs for SocketAddr {
- type Iter = option::IntoIter<SocketAddr>;
- fn to_socket_addrs(&self) -> io::Result<option::IntoIter<SocketAddr>> {
- Ok(Some(*self).into_iter())
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl ToSocketAddrs for SocketAddrV4 {
- type Iter = option::IntoIter<SocketAddr>;
- fn to_socket_addrs(&self) -> io::Result<option::IntoIter<SocketAddr>> {
- SocketAddr::V4(*self).to_socket_addrs()
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl ToSocketAddrs for SocketAddrV6 {
- type Iter = option::IntoIter<SocketAddr>;
- fn to_socket_addrs(&self) -> io::Result<option::IntoIter<SocketAddr>> {
- SocketAddr::V6(*self).to_socket_addrs()
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl ToSocketAddrs for (IpAddr, u16) {
- type Iter = option::IntoIter<SocketAddr>;
- fn to_socket_addrs(&self) -> io::Result<option::IntoIter<SocketAddr>> {
- let (ip, port) = *self;
- match ip {
- IpAddr::V4(ref a) => (*a, port).to_socket_addrs(),
- IpAddr::V6(ref a) => (*a, port).to_socket_addrs(),
- }
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl ToSocketAddrs for (Ipv4Addr, u16) {
- type Iter = option::IntoIter<SocketAddr>;
- fn to_socket_addrs(&self) -> io::Result<option::IntoIter<SocketAddr>> {
- let (ip, port) = *self;
- SocketAddrV4::new(ip, port).to_socket_addrs()
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl ToSocketAddrs for (Ipv6Addr, u16) {
- type Iter = option::IntoIter<SocketAddr>;
- fn to_socket_addrs(&self) -> io::Result<option::IntoIter<SocketAddr>> {
- let (ip, port) = *self;
- SocketAddrV6::new(ip, port, 0, 0).to_socket_addrs()
- }
-}
-
-fn resolve_socket_addr(s: &str, p: u16) -> io::Result<vec::IntoIter<SocketAddr>> {
- let ips = lookup_host(s)?;
- let v: Vec<_> = ips.map(|mut a| { a.set_port(p); a }).collect();
- Ok(v.into_iter())
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a> ToSocketAddrs for (&'a str, u16) {
- type Iter = vec::IntoIter<SocketAddr>;
- fn to_socket_addrs(&self) -> io::Result<vec::IntoIter<SocketAddr>> {
- let (host, port) = *self;
-
- // try to parse the host as a regular IP address first
- if let Ok(addr) = host.parse::<Ipv4Addr>() {
- let addr = SocketAddrV4::new(addr, port);
- return Ok(vec![SocketAddr::V4(addr)].into_iter())
- }
- if let Ok(addr) = host.parse::<Ipv6Addr>() {
- let addr = SocketAddrV6::new(addr, port, 0, 0);
- return Ok(vec![SocketAddr::V6(addr)].into_iter())
- }
-
- resolve_socket_addr(host, port)
- }
-}
-
-// accepts strings like 'localhost:12345'
-#[stable(feature = "rust1", since = "1.0.0")]
-impl ToSocketAddrs for str {
- type Iter = vec::IntoIter<SocketAddr>;
- fn to_socket_addrs(&self) -> io::Result<vec::IntoIter<SocketAddr>> {
- // try to parse as a regular SocketAddr first
- if let Some(addr) = self.parse().ok() {
- return Ok(vec![addr].into_iter());
- }
-
- macro_rules! try_opt {
- ($e:expr, $msg:expr) => (
- match $e {
- Some(r) => r,
- None => return Err(io::Error::new(io::ErrorKind::InvalidInput,
- $msg)),
- }
- )
- }
-
- // split the string by ':' and convert the second part to u16
- let mut parts_iter = self.rsplitn(2, ':');
- let port_str = try_opt!(parts_iter.next(), "invalid socket address");
- let host = try_opt!(parts_iter.next(), "invalid socket address");
- let port: u16 = try_opt!(port_str.parse().ok(), "invalid port value");
- resolve_socket_addr(host, port)
- }
-}
-
-#[stable(feature = "slice_to_socket_addrs", since = "1.8.0")]
-impl<'a> ToSocketAddrs for &'a [SocketAddr] {
- type Iter = iter::Cloned<slice::Iter<'a, SocketAddr>>;
-
- fn to_socket_addrs(&self) -> io::Result<Self::Iter> {
- Ok(self.iter().cloned())
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T: ToSocketAddrs + ?Sized> ToSocketAddrs for &'a T {
- type Iter = T::Iter;
- fn to_socket_addrs(&self) -> io::Result<T::Iter> {
- (**self).to_socket_addrs()
- }
-}
-
-#[stable(feature = "string_to_socket_addrs", since = "1.16.0")]
-impl ToSocketAddrs for String {
- type Iter = vec::IntoIter<SocketAddr>;
- fn to_socket_addrs(&self) -> io::Result<vec::IntoIter<SocketAddr>> {
- (&**self).to_socket_addrs()
- }
-}
-
-#[cfg(all(test, not(target_os = "emscripten")))]
-mod tests {
- use net::*;
- use net::test::{tsa, sa6, sa4};
-
- #[test]
- fn to_socket_addr_ipaddr_u16() {
- let a = Ipv4Addr::new(77, 88, 21, 11);
- let p = 12345;
- let e = SocketAddr::V4(SocketAddrV4::new(a, p));
- assert_eq!(Ok(vec![e]), tsa((a, p)));
- }
-
- #[test]
- fn to_socket_addr_str_u16() {
- let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 24352);
- assert_eq!(Ok(vec![a]), tsa(("77.88.21.11", 24352)));
-
- let a = sa6(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53);
- assert_eq!(Ok(vec![a]), tsa(("2a02:6b8:0:1::1", 53)));
-
- let a = sa4(Ipv4Addr::new(127, 0, 0, 1), 23924);
- assert!(tsa(("localhost", 23924)).unwrap().contains(&a));
- }
-
- #[test]
- fn to_socket_addr_str() {
- let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 24352);
- assert_eq!(Ok(vec![a]), tsa("77.88.21.11:24352"));
-
- let a = sa6(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53);
- assert_eq!(Ok(vec![a]), tsa("[2a02:6b8:0:1::1]:53"));
-
- let a = sa4(Ipv4Addr::new(127, 0, 0, 1), 23924);
- assert!(tsa("localhost:23924").unwrap().contains(&a));
- }
-
- #[test]
- fn to_socket_addr_string() {
- let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 24352);
- assert_eq!(Ok(vec![a]), tsa(&*format!("{}:{}", "77.88.21.11", "24352")));
- assert_eq!(Ok(vec![a]), tsa(&format!("{}:{}", "77.88.21.11", "24352")));
- assert_eq!(Ok(vec![a]), tsa(format!("{}:{}", "77.88.21.11", "24352")));
-
- let s = format!("{}:{}", "77.88.21.11", "24352");
- assert_eq!(Ok(vec![a]), tsa(s));
- // s has been moved into the tsa call
- }
-
- // FIXME: figure out why this fails on openbsd and bitrig and fix it
- #[test]
- #[cfg(not(any(windows, target_os = "openbsd", target_os = "bitrig")))]
- fn to_socket_addr_str_bad() {
- 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);
- 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);
- }
-
- #[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);
- }
-
- #[test]
- fn is_v4() {
- let v4 = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(77, 88, 21, 11), 80));
- assert!(v4.is_ipv4());
- assert!(!v4.is_ipv6());
- }
-
- #[test]
- fn is_v6() {
- let v6 = SocketAddr::V6(SocketAddrV6::new(
- Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 80, 10, 0));
- assert!(!v6.is_ipv4());
- assert!(v6.is_ipv6());
- }
-}
diff --git a/ctr-std/src/net/ip.rs b/ctr-std/src/net/ip.rs
deleted file mode 100644
index 9a610cd..0000000
--- a/ctr-std/src/net/ip.rs
+++ /dev/null
@@ -1,1940 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![unstable(feature = "ip", reason = "extra functionality has not been \
- scrutinized to the level that it should \
- be to be stable",
- issue = "27709")]
-
-use cmp::Ordering;
-use fmt;
-use hash;
-use sys::net::netc as c;
-use sys_common::{AsInner, FromInner};
-
-/// An IP address, either IPv4 or IPv6.
-///
-/// 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
-///
-/// # Examples
-///
-/// ```
-/// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
-///
-/// let localhost_v4 = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
-/// let localhost_v6 = IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
-///
-/// assert_eq!("127.0.0.1".parse(), Ok(localhost_v4));
-/// assert_eq!("::1".parse(), Ok(localhost_v6));
-///
-/// assert_eq!(localhost_v4.is_ipv6(), false);
-/// assert_eq!(localhost_v4.is_ipv4(), true);
-/// ```
-#[stable(feature = "ip_addr", since = "1.7.0")]
-#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, PartialOrd, Ord)]
-pub enum IpAddr {
- /// An IPv4 address.
- #[stable(feature = "ip_addr", since = "1.7.0")]
- V4(#[stable(feature = "ip_addr", since = "1.7.0")] Ipv4Addr),
- /// An IPv6 address.
- #[stable(feature = "ip_addr", since = "1.7.0")]
- V6(#[stable(feature = "ip_addr", since = "1.7.0")] Ipv6Addr),
-}
-
-/// An IPv4 address.
-///
-/// IPv4 addresses are defined as 32-bit integers in [IETF RFC 791].
-/// They are usually represented as four octets.
-///
-/// 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
-///
-/// # Textual representation
-///
-/// `Ipv4Addr` provides a [`FromStr`] implementation. The four octets are in decimal
-/// notation, divided by `.` (this is called "dot-decimal notation").
-///
-/// [`FromStr`]: ../../std/str/trait.FromStr.html
-///
-/// # Examples
-///
-/// ```
-/// use std::net::Ipv4Addr;
-///
-/// let localhost = Ipv4Addr::new(127, 0, 0, 1);
-/// assert_eq!("127.0.0.1".parse(), Ok(localhost));
-/// assert_eq!(localhost.is_loopback(), true);
-/// ```
-#[derive(Copy)]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct Ipv4Addr {
- inner: c::in_addr,
-}
-
-/// An IPv6 address.
-///
-/// IPv6 addresses are defined as 128-bit integers in [IETF RFC 4291].
-/// They are usually represented as eight 16-bit segments.
-///
-/// 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
-///
-/// # Textual representation
-///
-/// `Ipv6Addr` provides a [`FromStr`] implementation. There are many ways to represent
-/// an IPv6 address in text, but in general, each segments is written in hexadecimal
-/// notation, and segments are separated by `:`. For more information, see
-/// [IETF RFC 5952].
-///
-/// [`FromStr`]: ../../std/str/trait.FromStr.html
-/// [IETF RFC 5952]: https://tools.ietf.org/html/rfc5952
-///
-/// # Examples
-///
-/// ```
-/// use std::net::Ipv6Addr;
-///
-/// let localhost = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1);
-/// assert_eq!("::1".parse(), Ok(localhost));
-/// assert_eq!(localhost.is_loopback(), true);
-/// ```
-#[derive(Copy)]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct Ipv6Addr {
- inner: c::in6_addr,
-}
-
-#[allow(missing_docs)]
-#[derive(Copy, PartialEq, Eq, Clone, Hash, Debug)]
-pub enum Ipv6MulticastScope {
- InterfaceLocal,
- LinkLocal,
- RealmLocal,
- AdminLocal,
- SiteLocal,
- OrganizationLocal,
- Global
-}
-
-impl IpAddr {
- /// Returns [`true`] for the special 'unspecified' address.
- ///
- /// See the documentation for [`Ipv4Addr::is_unspecified`][IPv4] and
- /// [`Ipv6Addr::is_unspecified`][IPv6] for more details.
- ///
- /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_unspecified
- /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_unspecified
- /// [`true`]: ../../std/primitive.bool.html
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
- ///
- /// assert_eq!(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)).is_unspecified(), true);
- /// assert_eq!(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)).is_unspecified(), true);
- /// ```
- #[stable(feature = "ip_shared", since = "1.12.0")]
- pub fn is_unspecified(&self) -> bool {
- match self {
- IpAddr::V4(ip) => ip.is_unspecified(),
- IpAddr::V6(ip) => ip.is_unspecified(),
- }
- }
-
- /// Returns [`true`] if this is a loopback address.
- ///
- /// See the documentation for [`Ipv4Addr::is_loopback`][IPv4] and
- /// [`Ipv6Addr::is_loopback`][IPv6] for more details.
- ///
- /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_loopback
- /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_loopback
- /// [`true`]: ../../std/primitive.bool.html
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
- ///
- /// assert_eq!(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)).is_loopback(), true);
- /// assert_eq!(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0x1)).is_loopback(), true);
- /// ```
- #[stable(feature = "ip_shared", since = "1.12.0")]
- pub fn is_loopback(&self) -> bool {
- match self {
- IpAddr::V4(ip) => ip.is_loopback(),
- IpAddr::V6(ip) => ip.is_loopback(),
- }
- }
-
- /// Returns [`true`] if the address appears to be globally routable.
- ///
- /// See the documentation for [`Ipv4Addr::is_global`][IPv4] and
- /// [`Ipv6Addr::is_global`][IPv6] for more details.
- ///
- /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_global
- /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_global
- /// [`true`]: ../../std/primitive.bool.html
- ///
- /// # Examples
- ///
- /// ```
- /// #![feature(ip)]
- ///
- /// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
- ///
- /// fn main() {
- /// assert_eq!(IpAddr::V4(Ipv4Addr::new(80, 9, 12, 3)).is_global(), true);
- /// assert_eq!(IpAddr::V6(Ipv6Addr::new(0, 0, 0x1c9, 0, 0, 0xafc8, 0, 0x1)).is_global(),
- /// true);
- /// }
- /// ```
- pub fn is_global(&self) -> bool {
- match self {
- IpAddr::V4(ip) => ip.is_global(),
- IpAddr::V6(ip) => ip.is_global(),
- }
- }
-
- /// Returns [`true`] if this is a multicast address.
- ///
- /// See the documentation for [`Ipv4Addr::is_multicast`][IPv4] and
- /// [`Ipv6Addr::is_multicast`][IPv6] for more details.
- ///
- /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_multicast
- /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_multicast
- /// [`true`]: ../../std/primitive.bool.html
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
- ///
- /// assert_eq!(IpAddr::V4(Ipv4Addr::new(224, 254, 0, 0)).is_multicast(), true);
- /// assert_eq!(IpAddr::V6(Ipv6Addr::new(0xff00, 0, 0, 0, 0, 0, 0, 0)).is_multicast(), true);
- /// ```
- #[stable(feature = "ip_shared", since = "1.12.0")]
- pub fn is_multicast(&self) -> bool {
- match self {
- IpAddr::V4(ip) => ip.is_multicast(),
- IpAddr::V6(ip) => ip.is_multicast(),
- }
- }
-
- /// Returns [`true`] if this address is in a range designated for documentation.
- ///
- /// See the documentation for [`Ipv4Addr::is_documentation`][IPv4] and
- /// [`Ipv6Addr::is_documentation`][IPv6] for more details.
- ///
- /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_documentation
- /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_documentation
- /// [`true`]: ../../std/primitive.bool.html
- ///
- /// # Examples
- ///
- /// ```
- /// #![feature(ip)]
- ///
- /// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
- ///
- /// fn main() {
- /// assert_eq!(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 6)).is_documentation(), true);
- /// assert_eq!(IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0))
- /// .is_documentation(), true);
- /// }
- /// ```
- pub fn is_documentation(&self) -> bool {
- match self {
- IpAddr::V4(ip) => ip.is_documentation(),
- IpAddr::V6(ip) => ip.is_documentation(),
- }
- }
-
- /// Returns [`true`] if this address is an [IPv4 address], and [`false`] otherwise.
- ///
- /// [`true`]: ../../std/primitive.bool.html
- /// [`false`]: ../../std/primitive.bool.html
- /// [IPv4 address]: #variant.V4
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
- ///
- /// fn main() {
- /// assert_eq!(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 6)).is_ipv4(), true);
- /// assert_eq!(IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0)).is_ipv4(),
- /// false);
- /// }
- /// ```
- #[stable(feature = "ipaddr_checker", since = "1.16.0")]
- pub fn is_ipv4(&self) -> bool {
- match self {
- IpAddr::V4(_) => true,
- IpAddr::V6(_) => false,
- }
- }
-
- /// Returns [`true`] if this address is an [IPv6 address], and [`false`] otherwise.
- ///
- /// [`true`]: ../../std/primitive.bool.html
- /// [`false`]: ../../std/primitive.bool.html
- /// [IPv6 address]: #variant.V6
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
- ///
- /// fn main() {
- /// assert_eq!(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 6)).is_ipv6(), false);
- /// assert_eq!(IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0)).is_ipv6(),
- /// true);
- /// }
- /// ```
- #[stable(feature = "ipaddr_checker", since = "1.16.0")]
- pub fn is_ipv6(&self) -> bool {
- match self {
- IpAddr::V4(_) => false,
- IpAddr::V6(_) => true,
- }
- }
-}
-
-impl Ipv4Addr {
- /// Creates a new IPv4 address from four eight-bit octets.
- ///
- /// The result will represent the IP address `a`.`b`.`c`.`d`.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::Ipv4Addr;
- ///
- /// let addr = Ipv4Addr::new(127, 0, 0, 1);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[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: u32::to_be(
- ((a as u32) << 24) |
- ((b as u32) << 16) |
- ((c as u32) << 8) |
- (d as u32)
- ),
- }
- }
- }
-
- /// An IPv4 address with the address pointing to localhost: 127.0.0.1.
- ///
- /// # Examples
- ///
- /// ```
- /// #![feature(ip_constructors)]
- /// use std::net::Ipv4Addr;
- ///
- /// 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 const LOCALHOST: Self = Ipv4Addr::new(127, 0, 0, 1);
-
- /// An IPv4 address representing an unspecified address: 0.0.0.0
- ///
- /// # Examples
- ///
- /// ```
- /// #![feature(ip_constructors)]
- /// use std::net::Ipv4Addr;
- ///
- /// 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 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.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::Ipv4Addr;
- ///
- /// let addr = Ipv4Addr::new(127, 0, 0, 1);
- /// assert_eq!(addr.octets(), [127, 0, 0, 1]);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn octets(&self) -> [u8; 4] {
- let bits = u32::from_be(self.inner.s_addr);
- [(bits >> 24) as u8, (bits >> 16) as u8, (bits >> 8) as u8, bits as u8]
- }
-
- /// Returns [`true`] for the special 'unspecified' address (0.0.0.0).
- ///
- /// This property is defined in _UNIX Network Programming, Second Edition_,
- /// W. Richard Stevens, p. 891; see also [ip7].
- ///
- /// [ip7]: http://man7.org/linux/man-pages/man7/ip.7.html
- /// [`true`]: ../../std/primitive.bool.html
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::Ipv4Addr;
- ///
- /// assert_eq!(Ipv4Addr::new(0, 0, 0, 0).is_unspecified(), true);
- /// assert_eq!(Ipv4Addr::new(45, 22, 13, 197).is_unspecified(), false);
- /// ```
- #[stable(feature = "ip_shared", since = "1.12.0")]
- pub fn is_unspecified(&self) -> bool {
- self.inner.s_addr == 0
- }
-
- /// Returns [`true`] if this is a loopback address (127.0.0.0/8).
- ///
- /// This property is defined by [IETF RFC 1122].
- ///
- /// [IETF RFC 1122]: https://tools.ietf.org/html/rfc1122
- /// [`true`]: ../../std/primitive.bool.html
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::Ipv4Addr;
- ///
- /// assert_eq!(Ipv4Addr::new(127, 0, 0, 1).is_loopback(), true);
- /// assert_eq!(Ipv4Addr::new(45, 22, 13, 197).is_loopback(), false);
- /// ```
- #[stable(since = "1.7.0", feature = "ip_17")]
- pub fn is_loopback(&self) -> bool {
- self.octets()[0] == 127
- }
-
- /// Returns [`true`] if this is a private address.
- ///
- /// The private address ranges are defined in [IETF RFC 1918] and include:
- ///
- /// - 10.0.0.0/8
- /// - 172.16.0.0/12
- /// - 192.168.0.0/16
- ///
- /// [IETF RFC 1918]: https://tools.ietf.org/html/rfc1918
- /// [`true`]: ../../std/primitive.bool.html
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::Ipv4Addr;
- ///
- /// assert_eq!(Ipv4Addr::new(10, 0, 0, 1).is_private(), true);
- /// assert_eq!(Ipv4Addr::new(10, 10, 10, 10).is_private(), true);
- /// assert_eq!(Ipv4Addr::new(172, 16, 10, 10).is_private(), true);
- /// assert_eq!(Ipv4Addr::new(172, 29, 45, 14).is_private(), true);
- /// assert_eq!(Ipv4Addr::new(172, 32, 0, 2).is_private(), false);
- /// assert_eq!(Ipv4Addr::new(192, 168, 0, 2).is_private(), true);
- /// assert_eq!(Ipv4Addr::new(192, 169, 0, 2).is_private(), false);
- /// ```
- #[stable(since = "1.7.0", feature = "ip_17")]
- pub fn is_private(&self) -> bool {
- match self.octets() {
- [10, ..] => true,
- [172, b, ..] if b >= 16 && b <= 31 => true,
- [192, 168, ..] => true,
- _ => false,
- }
- }
-
- /// Returns [`true`] if the address is link-local (169.254.0.0/16).
- ///
- /// This property is defined by [IETF RFC 3927].
- ///
- /// [IETF RFC 3927]: https://tools.ietf.org/html/rfc3927
- /// [`true`]: ../../std/primitive.bool.html
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::Ipv4Addr;
- ///
- /// assert_eq!(Ipv4Addr::new(169, 254, 0, 0).is_link_local(), true);
- /// assert_eq!(Ipv4Addr::new(169, 254, 10, 65).is_link_local(), true);
- /// assert_eq!(Ipv4Addr::new(16, 89, 10, 65).is_link_local(), false);
- /// ```
- #[stable(since = "1.7.0", feature = "ip_17")]
- pub fn is_link_local(&self) -> bool {
- match self.octets() {
- [169, 254, ..] => true,
- _ => false,
- }
- }
-
- /// Returns [`true`] if the address appears to be globally routable.
- /// See [iana-ipv4-special-registry][ipv4-sr].
- ///
- /// The following return false:
- ///
- /// - private address (10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16)
- /// - the loopback address (127.0.0.0/8)
- /// - the link-local address (169.254.0.0/16)
- /// - the broadcast address (255.255.255.255/32)
- /// - test addresses used for documentation (192.0.2.0/24, 198.51.100.0/24 and 203.0.113.0/24)
- /// - the unspecified address (0.0.0.0)
- ///
- /// [ipv4-sr]: https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
- /// [`true`]: ../../std/primitive.bool.html
- ///
- /// # Examples
- ///
- /// ```
- /// #![feature(ip)]
- ///
- /// use std::net::Ipv4Addr;
- ///
- /// fn main() {
- /// assert_eq!(Ipv4Addr::new(10, 254, 0, 0).is_global(), false);
- /// assert_eq!(Ipv4Addr::new(192, 168, 10, 65).is_global(), false);
- /// assert_eq!(Ipv4Addr::new(172, 16, 10, 65).is_global(), false);
- /// assert_eq!(Ipv4Addr::new(0, 0, 0, 0).is_global(), false);
- /// assert_eq!(Ipv4Addr::new(80, 9, 12, 3).is_global(), true);
- /// }
- /// ```
- pub fn is_global(&self) -> bool {
- !self.is_private() && !self.is_loopback() && !self.is_link_local() &&
- !self.is_broadcast() && !self.is_documentation() && !self.is_unspecified()
- }
-
- /// Returns [`true`] if this is a multicast address (224.0.0.0/4).
- ///
- /// Multicast addresses have a most significant octet between 224 and 239,
- /// and is defined by [IETF RFC 5771].
- ///
- /// [IETF RFC 5771]: https://tools.ietf.org/html/rfc5771
- /// [`true`]: ../../std/primitive.bool.html
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::Ipv4Addr;
- ///
- /// assert_eq!(Ipv4Addr::new(224, 254, 0, 0).is_multicast(), true);
- /// assert_eq!(Ipv4Addr::new(236, 168, 10, 65).is_multicast(), true);
- /// assert_eq!(Ipv4Addr::new(172, 16, 10, 65).is_multicast(), false);
- /// ```
- #[stable(since = "1.7.0", feature = "ip_17")]
- pub fn is_multicast(&self) -> bool {
- self.octets()[0] >= 224 && self.octets()[0] <= 239
- }
-
- /// Returns [`true`] if this is a broadcast address (255.255.255.255).
- ///
- /// A broadcast address has all octets set to 255 as defined in [IETF RFC 919].
- ///
- /// [IETF RFC 919]: https://tools.ietf.org/html/rfc919
- /// [`true`]: ../../std/primitive.bool.html
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::Ipv4Addr;
- ///
- /// assert_eq!(Ipv4Addr::new(255, 255, 255, 255).is_broadcast(), true);
- /// assert_eq!(Ipv4Addr::new(236, 168, 10, 65).is_broadcast(), false);
- /// ```
- #[stable(since = "1.7.0", feature = "ip_17")]
- pub fn is_broadcast(&self) -> bool {
- self == &Self::BROADCAST
- }
-
- /// Returns [`true`] if this address is in a range designated for documentation.
- ///
- /// This is defined in [IETF RFC 5737]:
- ///
- /// - 192.0.2.0/24 (TEST-NET-1)
- /// - 198.51.100.0/24 (TEST-NET-2)
- /// - 203.0.113.0/24 (TEST-NET-3)
- ///
- /// [IETF RFC 5737]: https://tools.ietf.org/html/rfc5737
- /// [`true`]: ../../std/primitive.bool.html
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::Ipv4Addr;
- ///
- /// assert_eq!(Ipv4Addr::new(192, 0, 2, 255).is_documentation(), true);
- /// assert_eq!(Ipv4Addr::new(198, 51, 100, 65).is_documentation(), true);
- /// assert_eq!(Ipv4Addr::new(203, 0, 113, 6).is_documentation(), true);
- /// assert_eq!(Ipv4Addr::new(193, 34, 17, 19).is_documentation(), false);
- /// ```
- #[stable(since = "1.7.0", feature = "ip_17")]
- pub fn is_documentation(&self) -> bool {
- match self.octets() {
- [192, 0, 2, _] => true,
- [198, 51, 100, _] => true,
- [203, 0, 113, _] => true,
- _ => false,
- }
- }
-
- /// Converts this address to an IPv4-compatible [IPv6 address].
- ///
- /// a.b.c.d becomes ::a.b.c.d
- ///
- /// [IPv6 address]: ../../std/net/struct.Ipv6Addr.html
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::{Ipv4Addr, Ipv6Addr};
- ///
- /// assert_eq!(Ipv4Addr::new(192, 0, 2, 255).to_ipv6_compatible(),
- /// Ipv6Addr::new(0, 0, 0, 0, 0, 0, 49152, 767));
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn to_ipv6_compatible(&self) -> Ipv6Addr {
- Ipv6Addr::new(0, 0, 0, 0, 0, 0,
- ((self.octets()[0] as u16) << 8) | self.octets()[1] as u16,
- ((self.octets()[2] as u16) << 8) | self.octets()[3] as u16)
- }
-
- /// Converts this address to an IPv4-mapped [IPv6 address].
- ///
- /// a.b.c.d becomes ::ffff:a.b.c.d
- ///
- /// [IPv6 address]: ../../std/net/struct.Ipv6Addr.html
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::{Ipv4Addr, Ipv6Addr};
- ///
- /// assert_eq!(Ipv4Addr::new(192, 0, 2, 255).to_ipv6_mapped(),
- /// Ipv6Addr::new(0, 0, 0, 0, 0, 65535, 49152, 767));
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn to_ipv6_mapped(&self) -> Ipv6Addr {
- Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff,
- ((self.octets()[0] as u16) << 8) | self.octets()[1] as u16,
- ((self.octets()[2] as u16) << 8) | self.octets()[3] as u16)
- }
-}
-
-#[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(ip) => ip.fmt(fmt),
- IpAddr::V6(ip) => ip.fmt(fmt),
- }
- }
-}
-
-#[stable(feature = "ip_from_ip", since = "1.16.0")]
-impl From<Ipv4Addr> for IpAddr {
- fn from(ipv4: Ipv4Addr) -> IpAddr {
- IpAddr::V4(ipv4)
- }
-}
-
-#[stable(feature = "ip_from_ip", since = "1.16.0")]
-impl From<Ipv6Addr> for IpAddr {
- fn from(ipv6: Ipv6Addr) -> IpAddr {
- IpAddr::V6(ipv6)
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl fmt::Display for Ipv4Addr {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
- let octets = self.octets();
- write!(fmt, "{}.{}.{}.{}", octets[0], octets[1], octets[2], octets[3])
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl fmt::Debug for Ipv4Addr {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
- fmt::Display::fmt(self, fmt)
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl Clone for Ipv4Addr {
- fn clone(&self) -> Ipv4Addr { *self }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl PartialEq for Ipv4Addr {
- fn eq(&self, other: &Ipv4Addr) -> bool {
- self.inner.s_addr == other.inner.s_addr
- }
-}
-
-#[stable(feature = "ip_cmp", since = "1.16.0")]
-impl PartialEq<Ipv4Addr> for IpAddr {
- fn eq(&self, other: &Ipv4Addr) -> bool {
- match self {
- IpAddr::V4(v4) => v4 == other,
- IpAddr::V6(_) => false,
- }
- }
-}
-
-#[stable(feature = "ip_cmp", since = "1.16.0")]
-impl PartialEq<IpAddr> for Ipv4Addr {
- fn eq(&self, other: &IpAddr) -> bool {
- match other {
- IpAddr::V4(v4) => self == v4,
- IpAddr::V6(_) => false,
- }
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl Eq for Ipv4Addr {}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl hash::Hash for Ipv4Addr {
- fn hash<H: hash::Hasher>(&self, s: &mut H) {
- // `inner` is #[repr(packed)], so we need to copy `s_addr`.
- {self.inner.s_addr}.hash(s)
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl PartialOrd for Ipv4Addr {
- fn partial_cmp(&self, other: &Ipv4Addr) -> Option<Ordering> {
- Some(self.cmp(other))
- }
-}
-
-#[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(v4) => v4.partial_cmp(other),
- IpAddr::V6(_) => Some(Ordering::Greater),
- }
- }
-}
-
-#[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(v4) => self.partial_cmp(v4),
- IpAddr::V6(_) => Some(Ordering::Less),
- }
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl Ord for Ipv4Addr {
- fn cmp(&self, other: &Ipv4Addr) -> Ordering {
- u32::from_be(self.inner.s_addr).cmp(&u32::from_be(other.inner.s_addr))
- }
-}
-
-impl AsInner<c::in_addr> for Ipv4Addr {
- fn as_inner(&self) -> &c::in_addr { &self.inner }
-}
-impl FromInner<c::in_addr> for Ipv4Addr {
- fn from_inner(addr: c::in_addr) -> Ipv4Addr {
- Ipv4Addr { inner: addr }
- }
-}
-
-#[stable(feature = "ip_u32", since = "1.1.0")]
-impl From<Ipv4Addr> for u32 {
- /// 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)
- }
-}
-
-#[stable(feature = "ip_u32", since = "1.1.0")]
-impl From<u32> for Ipv4Addr {
- /// 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)
- }
-}
-
-#[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])
- }
-}
-
-#[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))
- }
-}
-
-impl Ipv6Addr {
- /// Creates a new IPv6 address from eight 16-bit segments.
- ///
- /// The result will represent the IP address a:b:c:d:e:f:g:h.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::Ipv6Addr;
- ///
- /// let addr = Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[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
- ],
- }
- }
-
- }
-
- /// An IPv6 address representing localhost: `::1`.
- ///
- /// # Examples
- ///
- /// ```
- /// #![feature(ip_constructors)]
- /// use std::net::Ipv6Addr;
- ///
- /// 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 const LOCALHOST: Self = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1);
-
- /// An IPv6 address representing the unspecified address: `::`
- ///
- /// # Examples
- ///
- /// ```
- /// #![feature(ip_constructors)]
- /// use std::net::Ipv6Addr;
- ///
- /// 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 const UNSPECIFIED: Self = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0);
-
- /// Returns the eight 16-bit segments that make up this address.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::Ipv6Addr;
- ///
- /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).segments(),
- /// [0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff]);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn segments(&self) -> [u16; 8] {
- let arr = &self.inner.s6_addr;
- [
- (arr[0] as u16) << 8 | (arr[1] as u16),
- (arr[2] as u16) << 8 | (arr[3] as u16),
- (arr[4] as u16) << 8 | (arr[5] as u16),
- (arr[6] as u16) << 8 | (arr[7] as u16),
- (arr[8] as u16) << 8 | (arr[9] as u16),
- (arr[10] as u16) << 8 | (arr[11] as u16),
- (arr[12] as u16) << 8 | (arr[13] as u16),
- (arr[14] as u16) << 8 | (arr[15] as u16),
- ]
- }
-
- /// Returns [`true`] for the special 'unspecified' address (::).
- ///
- /// This property is defined in [IETF RFC 4291].
- ///
- /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291
- /// [`true`]: ../../std/primitive.bool.html
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::Ipv6Addr;
- ///
- /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unspecified(), false);
- /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0).is_unspecified(), true);
- /// ```
- #[stable(since = "1.7.0", feature = "ip_17")]
- pub fn is_unspecified(&self) -> bool {
- self.segments() == [0, 0, 0, 0, 0, 0, 0, 0]
- }
-
- /// Returns [`true`] if this is a loopback address (::1).
- ///
- /// This property is defined in [IETF RFC 4291].
- ///
- /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291
- /// [`true`]: ../../std/primitive.bool.html
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::Ipv6Addr;
- ///
- /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_loopback(), false);
- /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0x1).is_loopback(), true);
- /// ```
- #[stable(since = "1.7.0", feature = "ip_17")]
- pub fn is_loopback(&self) -> bool {
- self.segments() == [0, 0, 0, 0, 0, 0, 0, 1]
- }
-
- /// Returns [`true`] if the address appears to be globally routable.
- ///
- /// The following return [`false`]:
- ///
- /// - the loopback address
- /// - link-local, site-local, and unique local unicast addresses
- /// - interface-, link-, realm-, admin- and site-local multicast addresses
- ///
- /// [`true`]: ../../std/primitive.bool.html
- /// [`false`]: ../../std/primitive.bool.html
- ///
- /// # Examples
- ///
- /// ```
- /// #![feature(ip)]
- ///
- /// use std::net::Ipv6Addr;
- ///
- /// fn main() {
- /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_global(), true);
- /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0x1).is_global(), false);
- /// assert_eq!(Ipv6Addr::new(0, 0, 0x1c9, 0, 0, 0xafc8, 0, 0x1).is_global(), true);
- /// }
- /// ```
- pub fn is_global(&self) -> bool {
- match self.multicast_scope() {
- Some(Ipv6MulticastScope::Global) => true,
- None => self.is_unicast_global(),
- _ => false
- }
- }
-
- /// Returns [`true`] if this is a unique local address (fc00::/7).
- ///
- /// This property is defined in [IETF RFC 4193].
- ///
- /// [IETF RFC 4193]: https://tools.ietf.org/html/rfc4193
- /// [`true`]: ../../std/primitive.bool.html
- ///
- /// # Examples
- ///
- /// ```
- /// #![feature(ip)]
- ///
- /// use std::net::Ipv6Addr;
- ///
- /// fn main() {
- /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unique_local(),
- /// false);
- /// assert_eq!(Ipv6Addr::new(0xfc02, 0, 0, 0, 0, 0, 0, 0).is_unique_local(), true);
- /// }
- /// ```
- pub fn is_unique_local(&self) -> bool {
- (self.segments()[0] & 0xfe00) == 0xfc00
- }
-
- /// Returns [`true`] if the address is unicast and link-local (fe80::/10).
- ///
- /// This property is defined in [IETF RFC 4291].
- ///
- /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291
- /// [`true`]: ../../std/primitive.bool.html
- ///
- /// # Examples
- ///
- /// ```
- /// #![feature(ip)]
- ///
- /// use std::net::Ipv6Addr;
- ///
- /// fn main() {
- /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unicast_link_local(),
- /// false);
- /// assert_eq!(Ipv6Addr::new(0xfe8a, 0, 0, 0, 0, 0, 0, 0).is_unicast_link_local(), true);
- /// }
- /// ```
- pub fn is_unicast_link_local(&self) -> bool {
- (self.segments()[0] & 0xffc0) == 0xfe80
- }
-
- /// Returns [`true`] if this is a deprecated unicast site-local address
- /// (fec0::/10).
- ///
- /// [`true`]: ../../std/primitive.bool.html
- ///
- /// # Examples
- ///
- /// ```
- /// #![feature(ip)]
- ///
- /// use std::net::Ipv6Addr;
- ///
- /// fn main() {
- /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unicast_site_local(),
- /// false);
- /// assert_eq!(Ipv6Addr::new(0xfec2, 0, 0, 0, 0, 0, 0, 0).is_unicast_site_local(), true);
- /// }
- /// ```
- pub fn is_unicast_site_local(&self) -> bool {
- (self.segments()[0] & 0xffc0) == 0xfec0
- }
-
- /// Returns [`true`] if this is an address reserved for documentation
- /// (2001:db8::/32).
- ///
- /// This property is defined in [IETF RFC 3849].
- ///
- /// [IETF RFC 3849]: https://tools.ietf.org/html/rfc3849
- /// [`true`]: ../../std/primitive.bool.html
- ///
- /// # Examples
- ///
- /// ```
- /// #![feature(ip)]
- ///
- /// use std::net::Ipv6Addr;
- ///
- /// fn main() {
- /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_documentation(),
- /// false);
- /// assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0).is_documentation(), true);
- /// }
- /// ```
- pub fn is_documentation(&self) -> bool {
- (self.segments()[0] == 0x2001) && (self.segments()[1] == 0xdb8)
- }
-
- /// Returns [`true`] if the address is a globally routable unicast address.
- ///
- /// The following return false:
- ///
- /// - the loopback address
- /// - the link-local addresses
- /// - the (deprecated) site-local addresses
- /// - unique local addresses
- /// - the unspecified address
- /// - the address range reserved for documentation
- ///
- /// [`true`]: ../../std/primitive.bool.html
- ///
- /// # Examples
- ///
- /// ```
- /// #![feature(ip)]
- ///
- /// use std::net::Ipv6Addr;
- ///
- /// fn main() {
- /// assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0).is_unicast_global(), false);
- /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unicast_global(),
- /// true);
- /// }
- /// ```
- pub fn is_unicast_global(&self) -> bool {
- !self.is_multicast()
- && !self.is_loopback() && !self.is_unicast_link_local()
- && !self.is_unicast_site_local() && !self.is_unique_local()
- && !self.is_unspecified() && !self.is_documentation()
- }
-
- /// Returns the address's multicast scope if the address is multicast.
- ///
- /// # Examples
- ///
- /// ```
- /// #![feature(ip)]
- ///
- /// use std::net::{Ipv6Addr, Ipv6MulticastScope};
- ///
- /// fn main() {
- /// assert_eq!(Ipv6Addr::new(0xff0e, 0, 0, 0, 0, 0, 0, 0).multicast_scope(),
- /// Some(Ipv6MulticastScope::Global));
- /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).multicast_scope(), None);
- /// }
- /// ```
- pub fn multicast_scope(&self) -> Option<Ipv6MulticastScope> {
- if self.is_multicast() {
- match self.segments()[0] & 0x000f {
- 1 => Some(Ipv6MulticastScope::InterfaceLocal),
- 2 => Some(Ipv6MulticastScope::LinkLocal),
- 3 => Some(Ipv6MulticastScope::RealmLocal),
- 4 => Some(Ipv6MulticastScope::AdminLocal),
- 5 => Some(Ipv6MulticastScope::SiteLocal),
- 8 => Some(Ipv6MulticastScope::OrganizationLocal),
- 14 => Some(Ipv6MulticastScope::Global),
- _ => None
- }
- } else {
- None
- }
- }
-
- /// Returns [`true`] if this is a multicast address (ff00::/8).
- ///
- /// This property is defined by [IETF RFC 4291].
- ///
- /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291
- /// [`true`]: ../../std/primitive.bool.html
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::Ipv6Addr;
- ///
- /// assert_eq!(Ipv6Addr::new(0xff00, 0, 0, 0, 0, 0, 0, 0).is_multicast(), true);
- /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_multicast(), false);
- /// ```
- #[stable(since = "1.7.0", feature = "ip_17")]
- pub fn is_multicast(&self) -> bool {
- (self.segments()[0] & 0xff00) == 0xff00
- }
-
- /// Converts this address to an [IPv4 address]. Returns [`None`] if this address is
- /// neither IPv4-compatible or IPv4-mapped.
- ///
- /// ::a.b.c.d and ::ffff:a.b.c.d become a.b.c.d
- ///
- /// [IPv4 address]: ../../std/net/struct.Ipv4Addr.html
- /// [`None`]: ../../std/option/enum.Option.html#variant.None
- ///
- /// # Examples
- ///
- /// ```
- /// use std::net::{Ipv4Addr, Ipv6Addr};
- ///
- /// assert_eq!(Ipv6Addr::new(0xff00, 0, 0, 0, 0, 0, 0, 0).to_ipv4(), None);
- /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).to_ipv4(),
- /// Some(Ipv4Addr::new(192, 10, 2, 255)));
- /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).to_ipv4(),
- /// Some(Ipv4Addr::new(0, 0, 0, 1)));
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn to_ipv4(&self) -> Option<Ipv4Addr> {
- match self.segments() {
- [0, 0, 0, 0, 0, f, g, h] if f == 0 || f == 0xffff => {
- Some(Ipv4Addr::new((g >> 8) as u8, g as u8,
- (h >> 8) as u8, h as u8))
- },
- _ => None
- }
- }
-
- /// Returns the sixteen eight-bit integers the IPv6 address consists of.
- ///
- /// ```
- /// use std::net::Ipv6Addr;
- ///
- /// assert_eq!(Ipv6Addr::new(0xff00, 0, 0, 0, 0, 0, 0, 0).octets(),
- /// [255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
- /// ```
- #[stable(feature = "ipv6_to_octets", since = "1.12.0")]
- pub fn octets(&self) -> [u8; 16] {
- self.inner.s6_addr
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl fmt::Display for Ipv6Addr {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
- match self.segments() {
- // We need special cases for :: and ::1, otherwise they're formatted
- // as ::0.0.0.[01]
- [0, 0, 0, 0, 0, 0, 0, 0] => write!(fmt, "::"),
- [0, 0, 0, 0, 0, 0, 0, 1] => write!(fmt, "::1"),
- // Ipv4 Compatible address
- [0, 0, 0, 0, 0, 0, g, h] => {
- write!(fmt, "::{}.{}.{}.{}", (g >> 8) as u8, g as u8,
- (h >> 8) as u8, h as u8)
- }
- // Ipv4-Mapped address
- [0, 0, 0, 0, 0, 0xffff, g, h] => {
- write!(fmt, "::ffff:{}.{}.{}.{}", (g >> 8) as u8, g as u8,
- (h >> 8) as u8, h as u8)
- },
- _ => {
- fn find_zero_slice(segments: &[u16; 8]) -> (usize, usize) {
- let mut longest_span_len = 0;
- let mut longest_span_at = 0;
- let mut cur_span_len = 0;
- let mut cur_span_at = 0;
-
- for i in 0..8 {
- if segments[i] == 0 {
- if cur_span_len == 0 {
- cur_span_at = i;
- }
-
- cur_span_len += 1;
-
- if cur_span_len > longest_span_len {
- longest_span_len = cur_span_len;
- longest_span_at = cur_span_at;
- }
- } else {
- cur_span_len = 0;
- cur_span_at = 0;
- }
- }
-
- (longest_span_at, longest_span_len)
- }
-
- let (zeros_at, zeros_len) = find_zero_slice(&self.segments());
-
- if zeros_len > 1 {
- fn fmt_subslice(segments: &[u16], fmt: &mut fmt::Formatter) -> fmt::Result {
- if !segments.is_empty() {
- write!(fmt, "{:x}", segments[0])?;
- for &seg in &segments[1..] {
- write!(fmt, ":{:x}", seg)?;
- }
- }
- Ok(())
- }
-
- fmt_subslice(&self.segments()[..zeros_at], fmt)?;
- fmt.write_str("::")?;
- fmt_subslice(&self.segments()[zeros_at + zeros_len..], fmt)
- } else {
- let &[a, b, c, d, e, f, g, h] = &self.segments();
- write!(fmt, "{:x}:{:x}:{:x}:{:x}:{:x}:{:x}:{:x}:{:x}",
- a, b, c, d, e, f, g, h)
- }
- }
- }
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl fmt::Debug for Ipv6Addr {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
- fmt::Display::fmt(self, fmt)
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl Clone for Ipv6Addr {
- fn clone(&self) -> Ipv6Addr { *self }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl PartialEq for Ipv6Addr {
- fn eq(&self, other: &Ipv6Addr) -> bool {
- self.inner.s6_addr == other.inner.s6_addr
- }
-}
-
-#[stable(feature = "ip_cmp", since = "1.16.0")]
-impl PartialEq<IpAddr> for Ipv6Addr {
- fn eq(&self, other: &IpAddr) -> bool {
- match other {
- IpAddr::V4(_) => false,
- IpAddr::V6(v6) => self == v6,
- }
- }
-}
-
-#[stable(feature = "ip_cmp", since = "1.16.0")]
-impl PartialEq<Ipv6Addr> for IpAddr {
- fn eq(&self, other: &Ipv6Addr) -> bool {
- match self {
- IpAddr::V4(_) => false,
- IpAddr::V6(v6) => v6 == other,
- }
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl Eq for Ipv6Addr {}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl hash::Hash for Ipv6Addr {
- fn hash<H: hash::Hasher>(&self, s: &mut H) {
- self.inner.s6_addr.hash(s)
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl PartialOrd for Ipv6Addr {
- fn partial_cmp(&self, other: &Ipv6Addr) -> Option<Ordering> {
- Some(self.cmp(other))
- }
-}
-
-#[stable(feature = "ip_cmp", since = "1.16.0")]
-impl PartialOrd<Ipv6Addr> for IpAddr {
- fn partial_cmp(&self, other: &Ipv6Addr) -> Option<Ordering> {
- match self {
- IpAddr::V4(_) => Some(Ordering::Less),
- IpAddr::V6(v6) => v6.partial_cmp(other),
- }
- }
-}
-
-#[stable(feature = "ip_cmp", since = "1.16.0")]
-impl PartialOrd<IpAddr> for Ipv6Addr {
- fn partial_cmp(&self, other: &IpAddr) -> Option<Ordering> {
- match other {
- IpAddr::V4(_) => Some(Ordering::Greater),
- IpAddr::V6(v6) => self.partial_cmp(v6),
- }
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl Ord for Ipv6Addr {
- fn cmp(&self, other: &Ipv6Addr) -> Ordering {
- self.segments().cmp(&other.segments())
- }
-}
-
-impl AsInner<c::in6_addr> for Ipv6Addr {
- fn as_inner(&self) -> &c::in6_addr { &self.inner }
-}
-impl FromInner<c::in6_addr> for Ipv6Addr {
- fn from_inner(addr: c::in6_addr) -> Ipv6Addr {
- Ipv6Addr { inner: addr }
- }
-}
-
-#[stable(feature = "i128", since = "1.26.0")]
-impl From<Ipv6Addr> for u128 {
- fn from(ip: Ipv6Addr) -> u128 {
- let ip = ip.segments();
- ((ip[0] as u128) << 112) + ((ip[1] as u128) << 96) + ((ip[2] as u128) << 80) +
- ((ip[3] as u128) << 64) + ((ip[4] as u128) << 48) + ((ip[5] as u128) << 32) +
- ((ip[6] as u128) << 16) + (ip[7] as u128)
- }
-}
-#[stable(feature = "i128", since = "1.26.0")]
-impl From<u128> for Ipv6Addr {
- fn from(ip: u128) -> Ipv6Addr {
- Ipv6Addr::new(
- (ip >> 112) as u16, (ip >> 96) as u16, (ip >> 80) as u16,
- (ip >> 64) as u16, (ip >> 48) as u16, (ip >> 32) as u16,
- (ip >> 16) as u16, ip as u16,
- )
- }
-}
-
-#[stable(feature = "ipv6_from_octets", since = "1.9.0")]
-impl From<[u8; 16]> for Ipv6Addr {
- fn from(octets: [u8; 16]) -> Ipv6Addr {
- let inner = c::in6_addr { s6_addr: octets };
- Ipv6Addr::from_inner(inner)
- }
-}
-
-#[stable(feature = "ipv6_from_segments", since = "1.16.0")]
-impl From<[u16; 8]> for Ipv6Addr {
- fn from(segments: [u16; 8]) -> Ipv6Addr {
- let [a, b, c, d, e, f, g, h] = segments;
- Ipv6Addr::new(a, b, c, d, e, f, g, h)
- }
-}
-
-
-#[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))
- }
-}
-
-#[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))
- }
-}
-
-// Tests for this module
-#[cfg(all(test, not(target_os = "emscripten")))]
-mod tests {
- use net::*;
- use net::Ipv6MulticastScope::*;
- use net::test::{tsa, sa6, sa4};
-
- #[test]
- fn test_from_str_ipv4() {
- assert_eq!(Ok(Ipv4Addr::new(127, 0, 0, 1)), "127.0.0.1".parse());
- assert_eq!(Ok(Ipv4Addr::new(255, 255, 255, 255)), "255.255.255.255".parse());
- assert_eq!(Ok(Ipv4Addr::new(0, 0, 0, 0)), "0.0.0.0".parse());
-
- // out of range
- let none: Option<Ipv4Addr> = "256.0.0.1".parse().ok();
- assert_eq!(None, none);
- // too short
- let none: Option<Ipv4Addr> = "255.0.0".parse().ok();
- assert_eq!(None, none);
- // too long
- let none: Option<Ipv4Addr> = "255.0.0.1.2".parse().ok();
- assert_eq!(None, none);
- // no number between dots
- let none: Option<Ipv4Addr> = "255.0..1".parse().ok();
- assert_eq!(None, none);
- }
-
- #[test]
- fn test_from_str_ipv6() {
- assert_eq!(Ok(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)), "0:0:0:0:0:0:0:0".parse());
- assert_eq!(Ok(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), "0:0:0:0:0:0:0:1".parse());
-
- assert_eq!(Ok(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), "::1".parse());
- assert_eq!(Ok(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)), "::".parse());
-
- assert_eq!(Ok(Ipv6Addr::new(0x2a02, 0x6b8, 0, 0, 0, 0, 0x11, 0x11)),
- "2a02:6b8::11:11".parse());
-
- // too long group
- let none: Option<Ipv6Addr> = "::00000".parse().ok();
- assert_eq!(None, none);
- // too short
- let none: Option<Ipv6Addr> = "1:2:3:4:5:6:7".parse().ok();
- assert_eq!(None, none);
- // too long
- let none: Option<Ipv6Addr> = "1:2:3:4:5:6:7:8:9".parse().ok();
- assert_eq!(None, none);
- // triple colon
- let none: Option<Ipv6Addr> = "1:2:::6:7:8".parse().ok();
- assert_eq!(None, none);
- // two double colons
- let none: Option<Ipv6Addr> = "1:2::6::8".parse().ok();
- assert_eq!(None, none);
- // `::` indicating zero groups of zeros
- let none: Option<Ipv6Addr> = "1:2:3:4::5:6:7:8".parse().ok();
- assert_eq!(None, none);
- }
-
- #[test]
- fn test_from_str_ipv4_in_ipv6() {
- assert_eq!(Ok(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 49152, 545)),
- "::192.0.2.33".parse());
- assert_eq!(Ok(Ipv6Addr::new(0, 0, 0, 0, 0, 0xFFFF, 49152, 545)),
- "::FFFF:192.0.2.33".parse());
- assert_eq!(Ok(Ipv6Addr::new(0x64, 0xff9b, 0, 0, 0, 0, 49152, 545)),
- "64:ff9b::192.0.2.33".parse());
- assert_eq!(Ok(Ipv6Addr::new(0x2001, 0xdb8, 0x122, 0xc000, 0x2, 0x2100, 49152, 545)),
- "2001:db8:122:c000:2:2100:192.0.2.33".parse());
-
- // colon after v4
- let none: Option<Ipv4Addr> = "::127.0.0.1:".parse().ok();
- assert_eq!(None, none);
- // not enough groups
- let none: Option<Ipv6Addr> = "1.2.3.4.5:127.0.0.1".parse().ok();
- assert_eq!(None, none);
- // too many groups
- let none: Option<Ipv6Addr> = "1.2.3.4.5:6:7:127.0.0.1".parse().ok();
- assert_eq!(None, none);
- }
-
- #[test]
- fn test_from_str_socket_addr() {
- assert_eq!(Ok(sa4(Ipv4Addr::new(77, 88, 21, 11), 80)),
- "77.88.21.11:80".parse());
- assert_eq!(Ok(SocketAddrV4::new(Ipv4Addr::new(77, 88, 21, 11), 80)),
- "77.88.21.11:80".parse());
- assert_eq!(Ok(sa6(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53)),
- "[2a02:6b8:0:1::1]:53".parse());
- assert_eq!(Ok(SocketAddrV6::new(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1,
- 0, 0, 0, 1), 53, 0, 0)),
- "[2a02:6b8:0:1::1]:53".parse());
- assert_eq!(Ok(sa6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0x7F00, 1), 22)),
- "[::127.0.0.1]:22".parse());
- assert_eq!(Ok(SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0,
- 0x7F00, 1), 22, 0, 0)),
- "[::127.0.0.1]:22".parse());
-
- // without port
- let none: Option<SocketAddr> = "127.0.0.1".parse().ok();
- assert_eq!(None, none);
- // without port
- let none: Option<SocketAddr> = "127.0.0.1:".parse().ok();
- assert_eq!(None, none);
- // wrong brackets around v4
- let none: Option<SocketAddr> = "[127.0.0.1]:22".parse().ok();
- assert_eq!(None, none);
- // port out of range
- let none: Option<SocketAddr> = "127.0.0.1:123456".parse().ok();
- assert_eq!(None, none);
- }
-
- #[test]
- fn ipv6_addr_to_string() {
- // ipv4-mapped address
- let a1 = Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc000, 0x280);
- assert_eq!(a1.to_string(), "::ffff:192.0.2.128");
-
- // ipv4-compatible address
- let a1 = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0xc000, 0x280);
- assert_eq!(a1.to_string(), "::192.0.2.128");
-
- // v6 address with no zero segments
- assert_eq!(Ipv6Addr::new(8, 9, 10, 11, 12, 13, 14, 15).to_string(),
- "8:9:a:b:c:d:e:f");
-
- // reduce a single run of zeros
- assert_eq!("ae::ffff:102:304",
- Ipv6Addr::new(0xae, 0, 0, 0, 0, 0xffff, 0x0102, 0x0304).to_string());
-
- // don't reduce just a single zero segment
- assert_eq!("1:2:3:4:5:6:0:8",
- Ipv6Addr::new(1, 2, 3, 4, 5, 6, 0, 8).to_string());
-
- // 'any' address
- assert_eq!("::", Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0).to_string());
-
- // loopback address
- assert_eq!("::1", Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).to_string());
-
- // ends in zeros
- assert_eq!("1::", Ipv6Addr::new(1, 0, 0, 0, 0, 0, 0, 0).to_string());
-
- // two runs of zeros, second one is longer
- assert_eq!("1:0:0:4::8", Ipv6Addr::new(1, 0, 0, 4, 0, 0, 0, 8).to_string());
-
- // two runs of zeros, equal length
- assert_eq!("1::4:5:0:0:8", Ipv6Addr::new(1, 0, 0, 4, 5, 0, 0, 8).to_string());
- }
-
- #[test]
- fn ipv4_to_ipv6() {
- assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x1234, 0x5678),
- Ipv4Addr::new(0x12, 0x34, 0x56, 0x78).to_ipv6_mapped());
- assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0x1234, 0x5678),
- Ipv4Addr::new(0x12, 0x34, 0x56, 0x78).to_ipv6_compatible());
- }
-
- #[test]
- fn ipv6_to_ipv4() {
- assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x1234, 0x5678).to_ipv4(),
- Some(Ipv4Addr::new(0x12, 0x34, 0x56, 0x78)));
- assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0x1234, 0x5678).to_ipv4(),
- Some(Ipv4Addr::new(0x12, 0x34, 0x56, 0x78)));
- assert_eq!(Ipv6Addr::new(0, 0, 1, 0, 0, 0, 0x1234, 0x5678).to_ipv4(),
- None);
- }
-
- #[test]
- fn ip_properties() {
- fn check4(octets: &[u8; 4], unspec: bool, loopback: bool,
- global: bool, multicast: bool, documentation: bool) {
- let ip = IpAddr::V4(Ipv4Addr::new(octets[0], octets[1], octets[2], octets[3]));
- assert_eq!(ip.is_unspecified(), unspec);
- assert_eq!(ip.is_loopback(), loopback);
- assert_eq!(ip.is_global(), global);
- assert_eq!(ip.is_multicast(), multicast);
- assert_eq!(ip.is_documentation(), documentation);
- }
-
- fn check6(str_addr: &str, unspec: bool, loopback: bool,
- global: bool, u_doc: bool, mcast: bool) {
- let ip = IpAddr::V6(str_addr.parse().unwrap());
- assert_eq!(ip.is_unspecified(), unspec);
- assert_eq!(ip.is_loopback(), loopback);
- assert_eq!(ip.is_global(), global);
- assert_eq!(ip.is_documentation(), u_doc);
- assert_eq!(ip.is_multicast(), mcast);
- }
-
- // address unspec loopbk global multicast doc
- check4(&[0, 0, 0, 0], true, false, false, false, false);
- check4(&[0, 0, 0, 1], false, false, true, false, false);
- check4(&[0, 1, 0, 0], false, false, true, false, false);
- check4(&[10, 9, 8, 7], false, false, false, false, false);
- check4(&[127, 1, 2, 3], false, true, false, false, false);
- check4(&[172, 31, 254, 253], false, false, false, false, false);
- check4(&[169, 254, 253, 242], false, false, false, false, false);
- check4(&[192, 0, 2, 183], false, false, false, false, true);
- check4(&[192, 1, 2, 183], false, false, true, false, false);
- check4(&[192, 168, 254, 253], false, false, false, false, false);
- check4(&[198, 51, 100, 0], false, false, false, false, true);
- check4(&[203, 0, 113, 0], false, false, false, false, true);
- check4(&[203, 2, 113, 0], false, false, true, false, false);
- check4(&[224, 0, 0, 0], false, false, true, true, false);
- check4(&[239, 255, 255, 255], false, false, true, true, false);
- check4(&[255, 255, 255, 255], false, false, false, false, false);
-
- // address unspec loopbk global doc mcast
- check6("::", true, false, false, false, false);
- check6("::1", false, true, false, false, false);
- check6("::0.0.0.2", false, false, true, false, false);
- check6("1::", false, false, true, false, false);
- check6("fc00::", false, false, false, false, false);
- check6("fdff:ffff::", false, false, false, false, false);
- check6("fe80:ffff::", false, false, false, false, false);
- check6("febf:ffff::", false, false, false, false, false);
- check6("fec0::", false, false, false, false, false);
- check6("ff01::", false, false, false, false, true);
- check6("ff02::", false, false, false, false, true);
- check6("ff03::", false, false, false, false, true);
- check6("ff04::", false, false, false, false, true);
- check6("ff05::", false, false, false, false, true);
- check6("ff08::", false, false, false, false, true);
- check6("ff0e::", false, false, true, false, true);
- check6("2001:db8:85a3::8a2e:370:7334", false, false, false, true, false);
- check6("102:304:506:708:90a:b0c:d0e:f10", false, false, true, false, false);
- }
-
- #[test]
- fn ipv4_properties() {
- fn check(octets: &[u8; 4], unspec: bool, loopback: bool,
- private: bool, link_local: bool, global: bool,
- multicast: bool, broadcast: bool, documentation: bool) {
- let ip = Ipv4Addr::new(octets[0], octets[1], octets[2], octets[3]);
- assert_eq!(octets, &ip.octets());
-
- assert_eq!(ip.is_unspecified(), unspec);
- assert_eq!(ip.is_loopback(), loopback);
- assert_eq!(ip.is_private(), private);
- assert_eq!(ip.is_link_local(), link_local);
- assert_eq!(ip.is_global(), global);
- assert_eq!(ip.is_multicast(), multicast);
- assert_eq!(ip.is_broadcast(), broadcast);
- assert_eq!(ip.is_documentation(), documentation);
- }
-
- // address unspec loopbk privt linloc global multicast brdcast doc
- check(&[0, 0, 0, 0], true, false, false, false, false, false, false, false);
- check(&[0, 0, 0, 1], false, false, false, false, true, false, false, false);
- check(&[0, 1, 0, 0], false, false, false, false, true, false, false, false);
- check(&[10, 9, 8, 7], false, false, true, false, false, false, false, false);
- check(&[127, 1, 2, 3], false, true, false, false, false, false, false, false);
- check(&[172, 31, 254, 253], false, false, true, false, false, false, false, false);
- check(&[169, 254, 253, 242], false, false, false, true, false, false, false, false);
- check(&[192, 0, 2, 183], false, false, false, false, false, false, false, true);
- check(&[192, 1, 2, 183], false, false, false, false, true, false, false, false);
- check(&[192, 168, 254, 253], false, false, true, false, false, false, false, false);
- check(&[198, 51, 100, 0], false, false, false, false, false, false, false, true);
- check(&[203, 0, 113, 0], false, false, false, false, false, false, false, true);
- check(&[203, 2, 113, 0], false, false, false, false, true, false, false, false);
- check(&[224, 0, 0, 0], false, false, false, false, true, true, false, false);
- check(&[239, 255, 255, 255], false, false, false, false, true, true, false, false);
- check(&[255, 255, 255, 255], false, false, false, false, false, false, true, false);
- }
-
- #[test]
- fn ipv6_properties() {
- fn check(str_addr: &str, octets: &[u8; 16], unspec: bool, loopback: bool,
- unique_local: bool, global: bool,
- u_link_local: bool, u_site_local: bool, u_global: bool, u_doc: bool,
- m_scope: Option<Ipv6MulticastScope>) {
- let ip: Ipv6Addr = str_addr.parse().unwrap();
- assert_eq!(str_addr, ip.to_string());
- assert_eq!(&ip.octets(), octets);
- assert_eq!(Ipv6Addr::from(*octets), ip);
-
- assert_eq!(ip.is_unspecified(), unspec);
- assert_eq!(ip.is_loopback(), loopback);
- assert_eq!(ip.is_unique_local(), unique_local);
- assert_eq!(ip.is_global(), global);
- assert_eq!(ip.is_unicast_link_local(), u_link_local);
- assert_eq!(ip.is_unicast_site_local(), u_site_local);
- assert_eq!(ip.is_unicast_global(), u_global);
- assert_eq!(ip.is_documentation(), u_doc);
- assert_eq!(ip.multicast_scope(), m_scope);
- assert_eq!(ip.is_multicast(), m_scope.is_some());
- }
-
- // unspec loopbk uniqlo global unill unisl uniglo doc mscope
- check("::", &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- true, false, false, false, false, false, false, false, None);
- check("::1", &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
- false, true, false, false, false, false, false, false, None);
- check("::0.0.0.2", &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],
- false, false, false, true, false, false, true, false, None);
- check("1::", &[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- false, false, false, true, false, false, true, false, None);
- check("fc00::", &[0xfc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- false, false, true, false, false, false, false, false, None);
- check("fdff:ffff::", &[0xfd, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- false, false, true, false, false, false, false, false, None);
- check("fe80:ffff::", &[0xfe, 0x80, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- false, false, false, false, true, false, false, false, None);
- check("febf:ffff::", &[0xfe, 0xbf, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- false, false, false, false, true, false, false, false, None);
- check("fec0::", &[0xfe, 0xc0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- false, false, false, false, false, true, false, false, None);
- check("ff01::", &[0xff, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- false, false, false, false, false, false, false, false, Some(InterfaceLocal));
- check("ff02::", &[0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- false, false, false, false, false, false, false, false, Some(LinkLocal));
- check("ff03::", &[0xff, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- false, false, false, false, false, false, false, false, Some(RealmLocal));
- check("ff04::", &[0xff, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- false, false, false, false, false, false, false, false, Some(AdminLocal));
- check("ff05::", &[0xff, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- false, false, false, false, false, false, false, false, Some(SiteLocal));
- check("ff08::", &[0xff, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- false, false, false, false, false, false, false, false, Some(OrganizationLocal));
- check("ff0e::", &[0xff, 0xe, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- false, false, false, true, false, false, false, false, Some(Global));
- check("2001:db8:85a3::8a2e:370:7334",
- &[0x20, 1, 0xd, 0xb8, 0x85, 0xa3, 0, 0, 0, 0, 0x8a, 0x2e, 3, 0x70, 0x73, 0x34],
- false, false, false, false, false, false, false, true, None);
- check("102:304:506:708:90a:b0c:d0e:f10",
- &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
- false, false, false, true, false, false, true, false, None);
- }
-
- #[test]
- fn to_socket_addr_socketaddr() {
- let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 12345);
- assert_eq!(Ok(vec![a]), tsa(a));
- }
-
- #[test]
- fn test_ipv4_to_int() {
- let a = Ipv4Addr::new(0x11, 0x22, 0x33, 0x44);
- assert_eq!(u32::from(a), 0x11223344);
- }
-
- #[test]
- fn test_int_to_ipv4() {
- let a = Ipv4Addr::new(0x11, 0x22, 0x33, 0x44);
- assert_eq!(Ipv4Addr::from(0x11223344), a);
- }
-
- #[test]
- fn test_ipv6_to_int() {
- let a = Ipv6Addr::new(0x1122, 0x3344, 0x5566, 0x7788, 0x99aa, 0xbbcc, 0xddee, 0xff11);
- assert_eq!(u128::from(a), 0x112233445566778899aabbccddeeff11u128);
- }
-
- #[test]
- fn test_int_to_ipv6() {
- let a = Ipv6Addr::new(0x1122, 0x3344, 0x5566, 0x7788, 0x99aa, 0xbbcc, 0xddee, 0xff11);
- assert_eq!(Ipv6Addr::from(0x112233445566778899aabbccddeeff11u128), a);
- }
-
- #[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::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());
- }
-
- #[test]
- fn ipv4_from_octets() {
- assert_eq!(Ipv4Addr::from([127, 0, 0, 1]), Ipv4Addr::new(127, 0, 0, 1))
- }
-
- #[test]
- fn ipv6_from_segments() {
- let from_u16s = Ipv6Addr::from([0x0011, 0x2233, 0x4455, 0x6677,
- 0x8899, 0xaabb, 0xccdd, 0xeeff]);
- let new = Ipv6Addr::new(0x0011, 0x2233, 0x4455, 0x6677,
- 0x8899, 0xaabb, 0xccdd, 0xeeff);
- assert_eq!(new, from_u16s);
- }
-
- #[test]
- fn ipv6_from_octets() {
- let from_u16s = Ipv6Addr::from([0x0011, 0x2233, 0x4455, 0x6677,
- 0x8899, 0xaabb, 0xccdd, 0xeeff]);
- let from_u8s = Ipv6Addr::from([0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
- 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff]);
- assert_eq!(from_u16s, from_u8s);
- }
-
- #[test]
- fn cmp() {
- let v41 = Ipv4Addr::new(100, 64, 3, 3);
- let v42 = Ipv4Addr::new(192, 0, 2, 2);
- let v61 = "2001:db8:f00::1002".parse::<Ipv6Addr>().unwrap();
- let v62 = "2001:db8:f00::2001".parse::<Ipv6Addr>().unwrap();
- assert!(v41 < v42);
- assert!(v61 < v62);
-
- assert_eq!(v41, IpAddr::V4(v41));
- assert_eq!(v61, IpAddr::V6(v61));
- assert!(v41 != IpAddr::V4(v42));
- assert!(v61 != IpAddr::V6(v62));
-
- assert!(v41 < IpAddr::V4(v42));
- assert!(v61 < IpAddr::V6(v62));
- assert!(IpAddr::V4(v41) < v42);
- assert!(IpAddr::V6(v61) < v62);
-
- assert!(v41 < IpAddr::V6(v61));
- assert!(IpAddr::V4(v41) < v61);
- }
-
- #[test]
- fn is_v4() {
- let ip = IpAddr::V4(Ipv4Addr::new(100, 64, 3, 3));
- assert!(ip.is_ipv4());
- assert!(!ip.is_ipv6());
- }
-
- #[test]
- fn is_v6() {
- let ip = IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x1234, 0x5678));
- assert!(!ip.is_ipv4());
- assert!(ip.is_ipv6());
- }
-}
diff --git a/ctr-std/src/net/mod.rs b/ctr-std/src/net/mod.rs
deleted file mode 100644
index be4bcee..0000000
--- a/ctr-std/src/net/mod.rs
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Networking primitives for TCP/UDP communication.
-//!
-//! This module provides networking functionality for the Transmission Control and User
-//! Datagram Protocols, as well as types for IP and socket addresses.
-//!
-//! # Organization
-//!
-//! * [`TcpListener`] and [`TcpStream`] provide functionality for communication over TCP
-//! * [`UdpSocket`] provides functionality for communication over UDP
-//! * [`IpAddr`] represents IP addresses of either IPv4 or IPv6; [`Ipv4Addr`] and
-//! [`Ipv6Addr`] are respectively IPv4 and IPv6 addresses
-//! * [`SocketAddr`] represents socket addresses of either IPv4 or IPv6; [`SocketAddrV4`]
-//! and [`SocketAddrV6`] are respectively IPv4 and IPv6 socket addresses
-//! * [`ToSocketAddrs`] is a trait that used for generic address resolution when interacting
-//! with networking objects like [`TcpListener`], [`TcpStream`] or [`UdpSocket`]
-//! * Other types are return or parameter types for various methods in this module
-//!
-//! [`IpAddr`]: ../../std/net/enum.IpAddr.html
-//! [`Ipv4Addr`]: ../../std/net/struct.Ipv4Addr.html
-//! [`Ipv6Addr`]: ../../std/net/struct.Ipv6Addr.html
-//! [`SocketAddr`]: ../../std/net/enum.SocketAddr.html
-//! [`SocketAddrV4`]: ../../std/net/struct.SocketAddrV4.html
-//! [`SocketAddrV6`]: ../../std/net/struct.SocketAddrV6.html
-//! [`TcpListener`]: ../../std/net/struct.TcpListener.html
-//! [`TcpStream`]: ../../std/net/struct.TcpStream.html
-//! [`ToSocketAddrs`]: ../../std/net/trait.ToSocketAddrs.html
-//! [`UdpSocket`]: ../../std/net/struct.UdpSocket.html
-
-#![stable(feature = "rust1", since = "1.0.0")]
-
-use io::{self, Error, ErrorKind};
-
-#[stable(feature = "rust1", since = "1.0.0")]
-pub use self::ip::{IpAddr, Ipv4Addr, Ipv6Addr, Ipv6MulticastScope};
-#[stable(feature = "rust1", since = "1.0.0")]
-pub use self::addr::{SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs};
-#[stable(feature = "rust1", since = "1.0.0")]
-pub use self::tcp::{TcpStream, TcpListener, Incoming};
-#[stable(feature = "rust1", since = "1.0.0")]
-pub use self::udp::UdpSocket;
-#[stable(feature = "rust1", since = "1.0.0")]
-pub use self::parser::AddrParseError;
-
-mod ip;
-mod addr;
-mod tcp;
-mod udp;
-mod parser;
-#[cfg(test)]
-mod test;
-
-/// Possible values which can be passed to the [`shutdown`] method of
-/// [`TcpStream`].
-///
-/// [`shutdown`]: struct.TcpStream.html#method.shutdown
-/// [`TcpStream`]: struct.TcpStream.html
-#[derive(Copy, Clone, PartialEq, Eq, Debug)]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub enum Shutdown {
- /// The reading portion of the [`TcpStream`] should be shut down.
- ///
- /// All currently blocked and future [reads] will return [`Ok(0)`].
- ///
- /// [`TcpStream`]: ../../std/net/struct.TcpStream.html
- /// [reads]: ../../std/io/trait.Read.html
- /// [`Ok(0)`]: ../../std/result/enum.Result.html#variant.Ok
- #[stable(feature = "rust1", since = "1.0.0")]
- Read,
- /// The writing portion of the [`TcpStream`] should be shut down.
- ///
- /// All currently blocked and future [writes] will return an error.
- ///
- /// [`TcpStream`]: ../../std/net/struct.TcpStream.html
- /// [writes]: ../../std/io/trait.Write.html
- #[stable(feature = "rust1", since = "1.0.0")]
- Write,
- /// Both the reading and the writing portions of the [`TcpStream`] should be shut down.
- ///
- /// See [`Shutdown::Read`] and [`Shutdown::Write`] for more information.
- ///
- /// [`TcpStream`]: ../../std/net/struct.TcpStream.html
- /// [`Shutdown::Read`]: #variant.Read
- /// [`Shutdown::Write`]: #variant.Write
- #[stable(feature = "rust1", since = "1.0.0")]
- Both,
-}
-
-#[doc(hidden)]
-trait NetInt {
- fn from_be(i: Self) -> Self;
- fn to_be(&self) -> Self;
-}
-macro_rules! doit {
- ($($t:ident)*) => ($(impl NetInt for $t {
- fn from_be(i: Self) -> Self { <$t>::from_be(i) }
- fn to_be(&self) -> Self { <$t>::to_be(*self) }
- })*)
-}
-doit! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize }
-
-fn hton<I: NetInt>(i: I) -> I { i.to_be() }
-fn ntoh<I: NetInt>(i: I) -> I { I::from_be(i) }
-
-fn each_addr<A: ToSocketAddrs, F, T>(addr: A, mut f: F) -> io::Result<T>
- where F: FnMut(&SocketAddr) -> io::Result<T>
-{
- let mut last_err = None;
- for addr in addr.to_socket_addrs()? {
- match f(&addr) {
- Ok(l) => return Ok(l),
- Err(e) => last_err = Some(e),
- }
- }
- Err(last_err.unwrap_or_else(|| {
- Error::new(ErrorKind::InvalidInput,
- "could not resolve to any addresses")
- }))
-}
diff --git a/ctr-std/src/net/parser.rs b/ctr-std/src/net/parser.rs
deleted file mode 100644
index cf3e535..0000000
--- a/ctr-std/src/net/parser.rs
+++ /dev/null
@@ -1,414 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! A private parser implementation of IPv4, IPv6, and socket addresses.
-//!
-//! This module is "publicly exported" through the `FromStr` implementations
-//! below.
-
-use error::Error;
-use fmt;
-use net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
-use str::FromStr;
-
-struct Parser<'a> {
- // parsing as ASCII, so can use byte array
- s: &'a [u8],
- pos: usize,
-}
-
-impl<'a> Parser<'a> {
- fn new(s: &'a str) -> Parser<'a> {
- Parser {
- s: s.as_bytes(),
- pos: 0,
- }
- }
-
- fn is_eof(&self) -> bool {
- self.pos == self.s.len()
- }
-
- // Commit only if parser returns Some
- fn read_atomically<T, F>(&mut self, cb: F) -> Option<T> where
- F: FnOnce(&mut Parser) -> Option<T>,
- {
- let pos = self.pos;
- let r = cb(self);
- if r.is_none() {
- self.pos = pos;
- }
- r
- }
-
- // Commit only if parser read till EOF
- fn read_till_eof<T, F>(&mut self, cb: F) -> Option<T> where
- F: FnOnce(&mut Parser) -> Option<T>,
- {
- self.read_atomically(move |p| {
- cb(p).filter(|_| p.is_eof())
- })
- }
-
- // Return result of first successful parser
- 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)) {
- return Some(r);
- }
- }
- None
- }
-
- // Apply 3 parsers sequentially
- fn read_seq_3<A, B, C, PA, PB, PC>(&mut self,
- pa: PA,
- pb: PB,
- pc: PC)
- -> Option<(A, B, C)> where
- PA: FnOnce(&mut Parser) -> Option<A>,
- PB: FnOnce(&mut Parser) -> Option<B>,
- PC: FnOnce(&mut Parser) -> Option<C>,
- {
- self.read_atomically(move |p| {
- let a = pa(p);
- let b = if a.is_some() { pb(p) } else { None };
- let c = if b.is_some() { pc(p) } else { None };
- match (a, b, c) {
- (Some(a), Some(b), Some(c)) => Some((a, b, c)),
- _ => None
- }
- })
- }
-
- // Read next char
- fn read_char(&mut self) -> Option<char> {
- if self.is_eof() {
- None
- } else {
- let r = self.s[self.pos] as char;
- self.pos += 1;
- Some(r)
- }
- }
-
- // Return char and advance iff next char is equal to requested
- fn read_given_char(&mut self, c: char) -> Option<char> {
- self.read_atomically(|p| {
- match p.read_char() {
- Some(next) if next == c => Some(next),
- _ => None,
- }
- })
- }
-
- // Read digit
- fn read_digit(&mut self, radix: u8) -> Option<u8> {
- fn parse_digit(c: char, radix: u8) -> Option<u8> {
- let c = c as u8;
- // assuming radix is either 10 or 16
- if c >= b'0' && c <= b'9' {
- Some(c - b'0')
- } else if radix > 10 && c >= b'a' && c < b'a' + (radix - 10) {
- Some(c - b'a' + 10)
- } else if radix > 10 && c >= b'A' && c < b'A' + (radix - 10) {
- Some(c - b'A' + 10)
- } else {
- None
- }
- }
-
- self.read_atomically(|p| {
- p.read_char().and_then(|c| parse_digit(c, radix))
- })
- }
-
- fn read_number_impl(&mut self, radix: u8, max_digits: u32, upto: u32) -> Option<u32> {
- let mut r = 0;
- let mut digit_count = 0;
- loop {
- match self.read_digit(radix) {
- Some(d) => {
- r = r * (radix as u32) + (d as u32);
- digit_count += 1;
- if digit_count > max_digits || r >= upto {
- return None
- }
- }
- None => {
- if digit_count == 0 {
- return None
- } else {
- return Some(r)
- }
- }
- };
- }
- }
-
- // Read number, failing if max_digits of number value exceeded
- fn read_number(&mut self, radix: u8, max_digits: u32, upto: u32) -> Option<u32> {
- self.read_atomically(|p| p.read_number_impl(radix, max_digits, upto))
- }
-
- fn read_ipv4_addr_impl(&mut self) -> Option<Ipv4Addr> {
- let mut bs = [0; 4];
- let mut i = 0;
- while i < 4 {
- if i != 0 && self.read_given_char('.').is_none() {
- return None;
- }
-
- bs[i] = self.read_number(10, 3, 0x100).map(|n| n as u8)?;
- i += 1;
- }
- Some(Ipv4Addr::new(bs[0], bs[1], bs[2], bs[3]))
- }
-
- // Read IPv4 address
- fn read_ipv4_addr(&mut self) -> Option<Ipv4Addr> {
- self.read_atomically(|p| p.read_ipv4_addr_impl())
- }
-
- fn read_ipv6_addr_impl(&mut self) -> Option<Ipv6Addr> {
- fn ipv6_addr_from_head_tail(head: &[u16], tail: &[u16]) -> Ipv6Addr {
- assert!(head.len() + tail.len() <= 8);
- let mut gs = [0; 8];
- gs[..head.len()].copy_from_slice(head);
- gs[(8 - tail.len()) .. 8].copy_from_slice(tail);
- Ipv6Addr::new(gs[0], gs[1], gs[2], gs[3], gs[4], gs[5], gs[6], gs[7])
- }
-
- fn read_groups(p: &mut Parser, groups: &mut [u16; 8], limit: usize)
- -> (usize, bool) {
- let mut i = 0;
- while i < limit {
- if i < limit - 1 {
- let ipv4 = p.read_atomically(|p| {
- if i == 0 || p.read_given_char(':').is_some() {
- p.read_ipv4_addr()
- } else {
- None
- }
- });
- if let Some(v4_addr) = ipv4 {
- let octets = v4_addr.octets();
- groups[i + 0] = ((octets[0] as u16) << 8) | (octets[1] as u16);
- groups[i + 1] = ((octets[2] as u16) << 8) | (octets[3] as u16);
- return (i + 2, true);
- }
- }
-
- let group = p.read_atomically(|p| {
- if i == 0 || p.read_given_char(':').is_some() {
- p.read_number(16, 4, 0x10000).map(|n| n as u16)
- } else {
- None
- }
- });
- match group {
- Some(g) => groups[i] = g,
- None => return (i, false)
- }
- i += 1;
- }
- (i, false)
- }
-
- let mut head = [0; 8];
- let (head_size, head_ipv4) = read_groups(self, &mut head, 8);
-
- if head_size == 8 {
- return Some(Ipv6Addr::new(
- head[0], head[1], head[2], head[3],
- head[4], head[5], head[6], head[7]))
- }
-
- // IPv4 part is not allowed before `::`
- if head_ipv4 {
- return None
- }
-
- // read `::` if previous code parsed less than 8 groups
- if !self.read_given_char(':').is_some() || !self.read_given_char(':').is_some() {
- return None;
- }
-
- let mut tail = [0; 8];
- // `::` indicates one or more groups of 16 bits of zeros
- let limit = 8 - (head_size + 1);
- let (tail_size, _) = read_groups(self, &mut tail, limit);
- Some(ipv6_addr_from_head_tail(&head[..head_size], &tail[..tail_size]))
- }
-
- fn read_ipv6_addr(&mut self) -> Option<Ipv6Addr> {
- self.read_atomically(|p| p.read_ipv6_addr_impl())
- }
-
- fn read_ip_addr(&mut self) -> Option<IpAddr> {
- let ipv4_addr = |p: &mut Parser| p.read_ipv4_addr().map(IpAddr::V4);
- let ipv6_addr = |p: &mut Parser| p.read_ipv6_addr().map(IpAddr::V6);
- self.read_or(&mut [Box::new(ipv4_addr), Box::new(ipv6_addr)])
- }
-
- fn read_socket_addr_v4(&mut self) -> Option<SocketAddrV4> {
- let ip_addr = |p: &mut Parser| p.read_ipv4_addr();
- let colon = |p: &mut Parser| p.read_given_char(':');
- let port = |p: &mut Parser| {
- p.read_number(10, 5, 0x10000).map(|n| n as u16)
- };
-
- self.read_seq_3(ip_addr, colon, port).map(|t| {
- let (ip, _, port): (Ipv4Addr, char, u16) = t;
- SocketAddrV4::new(ip, port)
- })
- }
-
- fn read_socket_addr_v6(&mut self) -> Option<SocketAddrV6> {
- let ip_addr = |p: &mut Parser| {
- let open_br = |p: &mut Parser| p.read_given_char('[');
- let ip_addr = |p: &mut Parser| p.read_ipv6_addr();
- let clos_br = |p: &mut Parser| p.read_given_char(']');
- p.read_seq_3(open_br, ip_addr, clos_br).map(|t| t.1)
- };
- let colon = |p: &mut Parser| p.read_given_char(':');
- let port = |p: &mut Parser| {
- p.read_number(10, 5, 0x10000).map(|n| n as u16)
- };
-
- self.read_seq_3(ip_addr, colon, port).map(|t| {
- let (ip, _, port): (Ipv6Addr, char, u16) = t;
- SocketAddrV6::new(ip, port, 0, 0)
- })
- }
-
- fn read_socket_addr(&mut self) -> Option<SocketAddr> {
- let v4 = |p: &mut Parser| p.read_socket_addr_v4().map(SocketAddr::V4);
- let v6 = |p: &mut Parser| p.read_socket_addr_v6().map(SocketAddr::V6);
- self.read_or(&mut [Box::new(v4), Box::new(v6)])
- }
-}
-
-#[stable(feature = "ip_addr", since = "1.7.0")]
-impl FromStr for IpAddr {
- type Err = AddrParseError;
- fn from_str(s: &str) -> Result<IpAddr, AddrParseError> {
- match Parser::new(s).read_till_eof(|p| p.read_ip_addr()) {
- Some(s) => Ok(s),
- None => Err(AddrParseError(()))
- }
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl FromStr for Ipv4Addr {
- type Err = AddrParseError;
- fn from_str(s: &str) -> Result<Ipv4Addr, AddrParseError> {
- match Parser::new(s).read_till_eof(|p| p.read_ipv4_addr()) {
- Some(s) => Ok(s),
- None => Err(AddrParseError(()))
- }
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl FromStr for Ipv6Addr {
- type Err = AddrParseError;
- fn from_str(s: &str) -> Result<Ipv6Addr, AddrParseError> {
- match Parser::new(s).read_till_eof(|p| p.read_ipv6_addr()) {
- Some(s) => Ok(s),
- None => Err(AddrParseError(()))
- }
- }
-}
-
-#[stable(feature = "socket_addr_from_str", since = "1.5.0")]
-impl FromStr for SocketAddrV4 {
- type Err = AddrParseError;
- fn from_str(s: &str) -> Result<SocketAddrV4, AddrParseError> {
- match Parser::new(s).read_till_eof(|p| p.read_socket_addr_v4()) {
- Some(s) => Ok(s),
- None => Err(AddrParseError(())),
- }
- }
-}
-
-#[stable(feature = "socket_addr_from_str", since = "1.5.0")]
-impl FromStr for SocketAddrV6 {
- type Err = AddrParseError;
- fn from_str(s: &str) -> Result<SocketAddrV6, AddrParseError> {
- match Parser::new(s).read_till_eof(|p| p.read_socket_addr_v6()) {
- Some(s) => Ok(s),
- None => Err(AddrParseError(())),
- }
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl FromStr for SocketAddr {
- type Err = AddrParseError;
- fn from_str(s: &str) -> Result<SocketAddr, AddrParseError> {
- match Parser::new(s).read_till_eof(|p| p.read_socket_addr()) {
- Some(s) => Ok(s),
- None => Err(AddrParseError(())),
- }
- }
-}
-
-/// An error which can be returned when parsing an IP address or a socket address.
-///
-/// This error is used as the error type for the [`FromStr`] implementation for
-/// [`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
-/// [`Ipv6Addr`]: ../../std/net/struct.Ipv6Addr.html
-/// [`SocketAddr`]: ../../std/net/enum.SocketAddr.html
-/// [`SocketAddrV4`]: ../../std/net/struct.SocketAddrV4.html
-/// [`SocketAddrV6`]: ../../std/net/struct.SocketAddrV6.html
-#[stable(feature = "rust1", since = "1.0.0")]
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct AddrParseError(());
-
-#[stable(feature = "addr_parse_error_error", since = "1.4.0")]
-impl fmt::Display for AddrParseError {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
- fmt.write_str(self.description())
- }
-}
-
-#[stable(feature = "addr_parse_error_error", since = "1.4.0")]
-impl Error for AddrParseError {
- fn description(&self) -> &str {
- "invalid IP address syntax"
- }
-}
diff --git a/ctr-std/src/net/tcp.rs b/ctr-std/src/net/tcp.rs
deleted file mode 100644
index 75c7a3d..0000000
--- a/ctr-std/src/net/tcp.rs
+++ /dev/null
@@ -1,1713 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use io::prelude::*;
-
-use fmt;
-use io::{self, Initializer};
-use net::{ToSocketAddrs, SocketAddr, Shutdown};
-use sys_common::net as net_imp;
-use sys_common::{AsInner, FromInner, IntoInner};
-use time::Duration;
-
-/// A TCP stream between a local and a remote socket.
-///
-/// After creating a `TcpStream` by either [`connect`]ing to a remote host or
-/// [`accept`]ing a connection on a [`TcpListener`], data can be transmitted
-/// by [reading] and [writing] to it.
-///
-/// The connection will be closed when the value is dropped. The reading and writing
-/// portions of the connection can also be shut down individually with the [`shutdown`]
-/// method.
-///
-/// The Transmission Control Protocol is specified in [IETF RFC 793].
-///
-/// [`accept`]: ../../std/net/struct.TcpListener.html#method.accept
-/// [`connect`]: #method.connect
-/// [IETF RFC 793]: https://tools.ietf.org/html/rfc793
-/// [reading]: ../../std/io/trait.Read.html
-/// [`shutdown`]: #method.shutdown
-/// [`TcpListener`]: ../../std/net/struct.TcpListener.html
-/// [writing]: ../../std/io/trait.Write.html
-///
-/// # Examples
-///
-/// ```no_run
-/// use std::io::prelude::*;
-/// use std::net::TcpStream;
-///
-/// {
-/// let mut stream = TcpStream::connect("127.0.0.1:34254").unwrap();
-///
-/// // ignore the Result
-/// let _ = stream.write(&[1]);
-/// let _ = stream.read(&mut [0; 128]); // ignore here too
-/// } // the stream is closed here
-/// ```
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct TcpStream(net_imp::TcpStream);
-
-/// A TCP socket server, listening for connections.
-///
-/// After creating a `TcpListener` by [`bind`]ing it to a socket address, it listens
-/// for incoming TCP connections. These can be accepted by calling [`accept`] or by
-/// iterating over the [`Incoming`] iterator returned by [`incoming`][`TcpListener::incoming`].
-///
-/// The socket will be closed when the value is dropped.
-///
-/// The Transmission Control Protocol is specified in [IETF RFC 793].
-///
-/// [`accept`]: #method.accept
-/// [`bind`]: #method.bind
-/// [IETF RFC 793]: https://tools.ietf.org/html/rfc793
-/// [`Incoming`]: ../../std/net/struct.Incoming.html
-/// [`TcpListener::incoming`]: #method.incoming
-///
-/// # Examples
-///
-/// ```no_run
-/// # use std::io;
-/// use std::net::{TcpListener, TcpStream};
-///
-/// fn handle_client(stream: TcpStream) {
-/// // ...
-/// }
-///
-/// 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?);
-/// }
-/// Ok(())
-/// }
-/// ```
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct TcpListener(net_imp::TcpListener);
-
-/// An iterator that infinitely [`accept`]s connections on a [`TcpListener`].
-///
-/// This `struct` is created by the [`incoming`] method on [`TcpListener`].
-/// See its documentation for more.
-///
-/// [`accept`]: ../../std/net/struct.TcpListener.html#method.accept
-/// [`incoming`]: ../../std/net/struct.TcpListener.html#method.incoming
-/// [`TcpListener`]: ../../std/net/struct.TcpListener.html
-#[stable(feature = "rust1", since = "1.0.0")]
-#[derive(Debug)]
-pub struct Incoming<'a> { listener: &'a TcpListener }
-
-impl TcpStream {
- /// Opens a TCP connection to a remote host.
- ///
- /// `addr` is an address of the remote host. Anything which implements
- /// [`ToSocketAddrs`] trait can be supplied for the address; see this trait
- /// documentation for concrete examples.
- ///
- /// If `addr` yields multiple addresses, `connect` will be attempted with
- /// each of the addresses until a connection is successful. If none of
- /// the addresses result in a successful connection, the error returned from
- /// the last connection attempt (the last address) is returned.
- ///
- /// [`ToSocketAddrs`]: ../../std/net/trait.ToSocketAddrs.html
- ///
- /// # Examples
- ///
- /// Open a TCP connection to `127.0.0.1:8080`:
- ///
- /// ```no_run
- /// use std::net::TcpStream;
- ///
- /// if let Ok(stream) = TcpStream::connect("127.0.0.1:8080") {
- /// println!("Connected to the server!");
- /// } else {
- /// println!("Couldn't connect to server...");
- /// }
- /// ```
- ///
- /// Open a TCP connection to `127.0.0.1:8080`. If the connection fails, open
- /// a TCP connection to `127.0.0.1:8081`:
- ///
- /// ```no_run
- /// use std::net::{SocketAddr, TcpStream};
- ///
- /// let addrs = [
- /// SocketAddr::from(([127, 0, 0, 1], 8080)),
- /// SocketAddr::from(([127, 0, 0, 1], 8081)),
- /// ];
- /// if let Ok(stream) = TcpStream::connect(&addrs[..]) {
- /// println!("Connected to the server!");
- /// } else {
- /// println!("Couldn't connect to server...");
- /// }
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn connect<A: ToSocketAddrs>(addr: A) -> io::Result<TcpStream> {
- super::each_addr(addr, net_imp::TcpStream::connect).map(TcpStream)
- }
-
- /// Opens a TCP connection to a remote host with a timeout.
- ///
- /// Unlike `connect`, `connect_timeout` takes a single [`SocketAddr`] since
- /// timeout must be applied to individual addresses.
- ///
- /// It is an error to pass a zero `Duration` to this function.
- ///
- /// Unlike other methods on `TcpStream`, this does not correspond to a
- /// single system call. It instead calls `connect` in nonblocking mode and
- /// then uses an OS-specific mechanism to await the completion of the
- /// connection request.
- ///
- /// [`SocketAddr`]: ../../std/net/enum.SocketAddr.html
- #[stable(feature = "tcpstream_connect_timeout", since = "1.21.0")]
- pub fn connect_timeout(addr: &SocketAddr, timeout: Duration) -> io::Result<TcpStream> {
- net_imp::TcpStream::connect_timeout(addr, timeout).map(TcpStream)
- }
-
- /// Returns the socket address of the remote peer of this TCP connection.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpStream};
- ///
- /// let stream = TcpStream::connect("127.0.0.1:8080")
- /// .expect("Couldn't connect to the server...");
- /// assert_eq!(stream.peer_addr().unwrap(),
- /// SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080)));
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn peer_addr(&self) -> io::Result<SocketAddr> {
- self.0.peer_addr()
- }
-
- /// Returns the socket address of the local half of this TCP connection.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::{IpAddr, Ipv4Addr, TcpStream};
- ///
- /// let stream = TcpStream::connect("127.0.0.1:8080")
- /// .expect("Couldn't connect to the server...");
- /// assert_eq!(stream.local_addr().unwrap().ip(),
- /// IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)));
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn local_addr(&self) -> io::Result<SocketAddr> {
- self.0.socket_addr()
- }
-
- /// Shuts down the read, write, or both halves of this connection.
- ///
- /// This function will cause all pending and future I/O on the specified
- /// portions to return immediately with an appropriate value (see the
- /// documentation of [`Shutdown`]).
- ///
- /// [`Shutdown`]: ../../std/net/enum.Shutdown.html
- ///
- /// # Platform-specific behavior
- ///
- /// Calling this function multiple times may result in different behavior,
- /// depending on the operating system. On Linux, the second call will
- /// return `Ok(())`, but on macOS, it will return `ErrorKind::NotConnected`.
- /// This may change in the future.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::{Shutdown, TcpStream};
- ///
- /// let stream = TcpStream::connect("127.0.0.1:8080")
- /// .expect("Couldn't connect to the server...");
- /// stream.shutdown(Shutdown::Both).expect("shutdown call failed");
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
- self.0.shutdown(how)
- }
-
- /// Creates a new independently owned handle to the underlying socket.
- ///
- /// The returned `TcpStream` is a reference to the same stream that this
- /// object references. Both handles will read and write the same stream of
- /// data, and options set on one stream will be propagated to the other
- /// stream.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::TcpStream;
- ///
- /// let stream = TcpStream::connect("127.0.0.1:8080")
- /// .expect("Couldn't connect to the server...");
- /// let stream_clone = stream.try_clone().expect("clone failed...");
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn try_clone(&self) -> io::Result<TcpStream> {
- self.0.duplicate().map(TcpStream)
- }
-
- /// Sets the read timeout to the timeout specified.
- ///
- /// If the value specified is [`None`], then [`read`] calls will block
- /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is
- /// passed to this method.
- ///
- /// # 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
- ///
- /// ```no_run
- /// use std::net::TcpStream;
- ///
- /// let stream = TcpStream::connect("127.0.0.1:8080")
- /// .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)
- }
-
- /// Sets the write timeout to the timeout specified.
- ///
- /// If the value specified is [`None`], then [`write`] calls will block
- /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is
- /// passed to this method.
- ///
- /// # 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
- /// [`TimedOut`]: ../../std/io/enum.ErrorKind.html#variant.TimedOut
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::TcpStream;
- ///
- /// let stream = TcpStream::connect("127.0.0.1:8080")
- /// .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)
- }
-
- /// Returns the read timeout of this socket.
- ///
- /// If the timeout is [`None`], then [`read`] calls will block indefinitely.
- ///
- /// # Platform-specific behavior
- ///
- /// Some platforms do not provide access to the current timeout.
- ///
- /// [`None`]: ../../std/option/enum.Option.html#variant.None
- /// [`read`]: ../../std/io/trait.Read.html#tymethod.read
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::TcpStream;
- ///
- /// let stream = TcpStream::connect("127.0.0.1:8080")
- /// .expect("Couldn't connect to the server...");
- /// stream.set_read_timeout(None).expect("set_read_timeout call failed");
- /// assert_eq!(stream.read_timeout().unwrap(), None);
- /// ```
- #[stable(feature = "socket_timeout", since = "1.4.0")]
- pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
- self.0.read_timeout()
- }
-
- /// Returns the write timeout of this socket.
- ///
- /// If the timeout is [`None`], then [`write`] calls will block indefinitely.
- ///
- /// # Platform-specific behavior
- ///
- /// Some platforms do not provide access to the current timeout.
- ///
- /// [`None`]: ../../std/option/enum.Option.html#variant.None
- /// [`write`]: ../../std/io/trait.Write.html#tymethod.write
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::TcpStream;
- ///
- /// let stream = TcpStream::connect("127.0.0.1:8080")
- /// .expect("Couldn't connect to the server...");
- /// stream.set_write_timeout(None).expect("set_write_timeout call failed");
- /// assert_eq!(stream.write_timeout().unwrap(), None);
- /// ```
- #[stable(feature = "socket_timeout", since = "1.4.0")]
- pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
- self.0.write_timeout()
- }
-
- /// Receives data on the socket from the remote address to which it is
- /// connected, without removing that data from the queue. On success,
- /// returns the number of bytes peeked.
- ///
- /// Successive calls return the same data. This is accomplished by passing
- /// `MSG_PEEK` as a flag to the underlying `recv` system call.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::TcpStream;
- ///
- /// let stream = TcpStream::connect("127.0.0.1:8000")
- /// .expect("couldn't bind to address");
- /// let mut buf = [0; 10];
- /// let len = stream.peek(&mut buf).expect("peek failed");
- /// ```
- #[stable(feature = "peek", since = "1.18.0")]
- pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
- self.0.peek(buf)
- }
-
- /// Sets the value of the `TCP_NODELAY` option on this socket.
- ///
- /// If set, this option disables the Nagle algorithm. This means that
- /// segments are always sent as soon as possible, even if there is only a
- /// small amount of data. When not set, data is buffered until there is a
- /// sufficient amount to send out, thereby avoiding the frequent sending of
- /// small packets.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::TcpStream;
- ///
- /// let stream = TcpStream::connect("127.0.0.1:8080")
- /// .expect("Couldn't connect to the server...");
- /// stream.set_nodelay(true).expect("set_nodelay call failed");
- /// ```
- #[stable(feature = "net2_mutators", since = "1.9.0")]
- pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
- self.0.set_nodelay(nodelay)
- }
-
- /// Gets the value of the `TCP_NODELAY` option on this socket.
- ///
- /// For more information about this option, see [`set_nodelay`][link].
- ///
- /// [link]: #method.set_nodelay
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::TcpStream;
- ///
- /// let stream = TcpStream::connect("127.0.0.1:8080")
- /// .expect("Couldn't connect to the server...");
- /// stream.set_nodelay(true).expect("set_nodelay call failed");
- /// assert_eq!(stream.nodelay().unwrap_or(false), true);
- /// ```
- #[stable(feature = "net2_mutators", since = "1.9.0")]
- pub fn nodelay(&self) -> io::Result<bool> {
- self.0.nodelay()
- }
-
- /// Sets the value for the `IP_TTL` option on this socket.
- ///
- /// This value sets the time-to-live field that is used in every packet sent
- /// from this socket.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::TcpStream;
- ///
- /// let stream = TcpStream::connect("127.0.0.1:8080")
- /// .expect("Couldn't connect to the server...");
- /// stream.set_ttl(100).expect("set_ttl call failed");
- /// ```
- #[stable(feature = "net2_mutators", since = "1.9.0")]
- pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
- self.0.set_ttl(ttl)
- }
-
- /// Gets the value of the `IP_TTL` option for this socket.
- ///
- /// For more information about this option, see [`set_ttl`][link].
- ///
- /// [link]: #method.set_ttl
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::TcpStream;
- ///
- /// let stream = TcpStream::connect("127.0.0.1:8080")
- /// .expect("Couldn't connect to the server...");
- /// stream.set_ttl(100).expect("set_ttl call failed");
- /// assert_eq!(stream.ttl().unwrap_or(0), 100);
- /// ```
- #[stable(feature = "net2_mutators", since = "1.9.0")]
- pub fn ttl(&self) -> io::Result<u32> {
- self.0.ttl()
- }
-
- /// Get the value of the `SO_ERROR` option on this socket.
- ///
- /// This will retrieve the stored error in the underlying socket, clearing
- /// the field in the process. This can be useful for checking errors between
- /// calls.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::TcpStream;
- ///
- /// let stream = TcpStream::connect("127.0.0.1:8080")
- /// .expect("Couldn't connect to the server...");
- /// stream.take_error().expect("No error was expected...");
- /// ```
- #[stable(feature = "net2_mutators", since = "1.9.0")]
- pub fn take_error(&self) -> io::Result<Option<io::Error>> {
- self.0.take_error()
- }
-
- /// Moves this TCP stream into or out of nonblocking mode.
- ///
- /// This will result in `read`, `write`, `recv` and `send` operations
- /// becoming nonblocking, i.e. immediately returning from their calls.
- /// If the IO operation is successful, `Ok` is returned and no further
- /// action is required. If the IO operation could not be completed and needs
- /// to be retried, an error with kind [`io::ErrorKind::WouldBlock`] is
- /// returned.
- ///
- /// On Unix platforms, calling this method corresponds to calling `fcntl`
- /// `FIONBIO`. On Windows calling this method corresponds to calling
- /// `ioctlsocket` `FIONBIO`.
- ///
- /// # Examples
- ///
- /// Reading bytes from a TCP stream in non-blocking mode:
- ///
- /// ```no_run
- /// use std::io::{self, Read};
- /// use std::net::TcpStream;
- ///
- /// let mut stream = TcpStream::connect("127.0.0.1:7878")
- /// .expect("Couldn't connect to the server...");
- /// stream.set_nonblocking(true).expect("set_nonblocking call failed");
- ///
- /// # fn wait_for_fd() { unimplemented!() }
- /// let mut buf = vec![];
- /// loop {
- /// match stream.read_to_end(&mut buf) {
- /// Ok(_) => break,
- /// Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
- /// // wait until network socket is ready, typically implemented
- /// // via platform-specific APIs such as epoll or IOCP
- /// wait_for_fd();
- /// }
- /// Err(e) => panic!("encountered IO error: {}", e),
- /// };
- /// };
- /// println!("bytes: {:?}", buf);
- /// ```
- ///
- /// [`io::ErrorKind::WouldBlock`]: ../io/enum.ErrorKind.html#variant.WouldBlock
- #[stable(feature = "net2_mutators", since = "1.9.0")]
- pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
- self.0.set_nonblocking(nonblocking)
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl Read for TcpStream {
- fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) }
-
- #[inline]
- unsafe fn initializer(&self) -> Initializer {
- Initializer::nop()
- }
-}
-#[stable(feature = "rust1", since = "1.0.0")]
-impl Write for TcpStream {
- fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
- fn flush(&mut self) -> io::Result<()> { Ok(()) }
-}
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a> Read for &'a TcpStream {
- fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) }
-
- #[inline]
- unsafe fn initializer(&self) -> Initializer {
- Initializer::nop()
- }
-}
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a> Write for &'a TcpStream {
- fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
- fn flush(&mut self) -> io::Result<()> { Ok(()) }
-}
-
-impl AsInner<net_imp::TcpStream> for TcpStream {
- fn as_inner(&self) -> &net_imp::TcpStream { &self.0 }
-}
-
-impl FromInner<net_imp::TcpStream> for TcpStream {
- fn from_inner(inner: net_imp::TcpStream) -> TcpStream { TcpStream(inner) }
-}
-
-impl IntoInner<net_imp::TcpStream> for TcpStream {
- fn into_inner(self) -> net_imp::TcpStream { self.0 }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl fmt::Debug for TcpStream {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- self.0.fmt(f)
- }
-}
-
-impl TcpListener {
- /// Creates a new `TcpListener` which will be bound to the specified
- /// address.
- ///
- /// The returned listener is ready for accepting connections.
- ///
- /// Binding with a port number of 0 will request that the OS assigns a port
- /// to this listener. The port allocated can be queried via the
- /// [`local_addr`] method.
- ///
- /// The address type can be any implementor of [`ToSocketAddrs`] trait. See
- /// its documentation for concrete examples.
- ///
- /// If `addr` yields multiple addresses, `bind` will be attempted with
- /// each of the addresses until one succeeds and returns the listener. If
- /// none of the addresses succeed in creating a listener, the error returned
- /// from the last attempt (the last address) is returned.
- ///
- /// [`local_addr`]: #method.local_addr
- /// [`ToSocketAddrs`]: ../../std/net/trait.ToSocketAddrs.html
- ///
- /// # Examples
- ///
- /// Create a TCP listener bound to `127.0.0.1:80`:
- ///
- /// ```no_run
- /// use std::net::TcpListener;
- ///
- /// let listener = TcpListener::bind("127.0.0.1:80").unwrap();
- /// ```
- ///
- /// Create a TCP listener bound to `127.0.0.1:80`. If that fails, create a
- /// TCP listener bound to `127.0.0.1:443`:
- ///
- /// ```no_run
- /// use std::net::{SocketAddr, TcpListener};
- ///
- /// let addrs = [
- /// SocketAddr::from(([127, 0, 0, 1], 80)),
- /// SocketAddr::from(([127, 0, 0, 1], 443)),
- /// ];
- /// let listener = TcpListener::bind(&addrs[..]).unwrap();
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<TcpListener> {
- super::each_addr(addr, net_imp::TcpListener::bind).map(TcpListener)
- }
-
- /// Returns the local socket address of this listener.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpListener};
- ///
- /// let listener = TcpListener::bind("127.0.0.1:8080").unwrap();
- /// assert_eq!(listener.local_addr().unwrap(),
- /// SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080)));
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn local_addr(&self) -> io::Result<SocketAddr> {
- self.0.socket_addr()
- }
-
- /// Creates a new independently owned handle to the underlying socket.
- ///
- /// The returned [`TcpListener`] is a reference to the same socket that this
- /// object references. Both handles can be used to accept incoming
- /// connections and options set on one listener will affect the other.
- ///
- /// [`TcpListener`]: ../../std/net/struct.TcpListener.html
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::TcpListener;
- ///
- /// let listener = TcpListener::bind("127.0.0.1:8080").unwrap();
- /// let listener_clone = listener.try_clone().unwrap();
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn try_clone(&self) -> io::Result<TcpListener> {
- self.0.duplicate().map(TcpListener)
- }
-
- /// Accept a new incoming connection from this listener.
- ///
- /// This function will block the calling thread until a new TCP connection
- /// is established. When established, the corresponding [`TcpStream`] and the
- /// remote peer's address will be returned.
- ///
- /// [`TcpStream`]: ../../std/net/struct.TcpStream.html
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::TcpListener;
- ///
- /// let listener = TcpListener::bind("127.0.0.1:8080").unwrap();
- /// match listener.accept() {
- /// Ok((_socket, addr)) => println!("new client: {:?}", addr),
- /// Err(e) => println!("couldn't get client: {:?}", e),
- /// }
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
- self.0.accept().map(|(a, b)| (TcpStream(a), b))
- }
-
- /// Returns an iterator over the connections being received on this
- /// listener.
- ///
- /// The returned iterator will never return [`None`] and will also not yield
- /// the peer's [`SocketAddr`] structure. Iterating over it is equivalent to
- /// calling [`accept`] in a loop.
- ///
- /// [`None`]: ../../std/option/enum.Option.html#variant.None
- /// [`SocketAddr`]: ../../std/net/enum.SocketAddr.html
- /// [`accept`]: #method.accept
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::TcpListener;
- ///
- /// let listener = TcpListener::bind("127.0.0.1:80").unwrap();
- ///
- /// for stream in listener.incoming() {
- /// match stream {
- /// Ok(stream) => {
- /// println!("new client!");
- /// }
- /// Err(e) => { /* connection failed */ }
- /// }
- /// }
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn incoming(&self) -> Incoming {
- Incoming { listener: self }
- }
-
- /// Sets the value for the `IP_TTL` option on this socket.
- ///
- /// This value sets the time-to-live field that is used in every packet sent
- /// from this socket.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::TcpListener;
- ///
- /// let listener = TcpListener::bind("127.0.0.1:80").unwrap();
- /// listener.set_ttl(100).expect("could not set TTL");
- /// ```
- #[stable(feature = "net2_mutators", since = "1.9.0")]
- pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
- self.0.set_ttl(ttl)
- }
-
- /// Gets the value of the `IP_TTL` option for this socket.
- ///
- /// For more information about this option, see [`set_ttl`][link].
- ///
- /// [link]: #method.set_ttl
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::TcpListener;
- ///
- /// let listener = TcpListener::bind("127.0.0.1:80").unwrap();
- /// listener.set_ttl(100).expect("could not set TTL");
- /// assert_eq!(listener.ttl().unwrap_or(0), 100);
- /// ```
- #[stable(feature = "net2_mutators", since = "1.9.0")]
- pub fn ttl(&self) -> io::Result<u32> {
- self.0.ttl()
- }
-
- #[stable(feature = "net2_mutators", since = "1.9.0")]
- #[rustc_deprecated(since = "1.16.0",
- reason = "this option can only be set before the socket is bound")]
- #[allow(missing_docs)]
- pub fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
- self.0.set_only_v6(only_v6)
- }
-
- #[stable(feature = "net2_mutators", since = "1.9.0")]
- #[rustc_deprecated(since = "1.16.0",
- reason = "this option can only be set before the socket is bound")]
- #[allow(missing_docs)]
- pub fn only_v6(&self) -> io::Result<bool> {
- self.0.only_v6()
- }
-
- /// Get the value of the `SO_ERROR` option on this socket.
- ///
- /// This will retrieve the stored error in the underlying socket, clearing
- /// the field in the process. This can be useful for checking errors between
- /// calls.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::TcpListener;
- ///
- /// let listener = TcpListener::bind("127.0.0.1:80").unwrap();
- /// listener.take_error().expect("No error was expected");
- /// ```
- #[stable(feature = "net2_mutators", since = "1.9.0")]
- pub fn take_error(&self) -> io::Result<Option<io::Error>> {
- self.0.take_error()
- }
-
- /// Moves this TCP stream into or out of nonblocking mode.
- ///
- /// This will result in the `accept` operation becoming nonblocking,
- /// i.e. immediately returning from their calls. If the IO operation is
- /// successful, `Ok` is returned and no further action is required. If the
- /// IO operation could not be completed and needs to be retried, an error
- /// with kind [`io::ErrorKind::WouldBlock`] is returned.
- ///
- /// On Unix platforms, calling this method corresponds to calling `fcntl`
- /// `FIONBIO`. On Windows calling this method corresponds to calling
- /// `ioctlsocket` `FIONBIO`.
- ///
- /// # Examples
- ///
- /// Bind a TCP listener to an address, listen for connections, and read
- /// bytes in nonblocking mode:
- ///
- /// ```no_run
- /// use std::io;
- /// use std::net::TcpListener;
- ///
- /// let listener = TcpListener::bind("127.0.0.1:7878").unwrap();
- /// listener.set_nonblocking(true).expect("Cannot set non-blocking");
- ///
- /// # fn wait_for_fd() { unimplemented!() }
- /// # fn handle_connection(stream: std::net::TcpStream) { unimplemented!() }
- /// for stream in listener.incoming() {
- /// match stream {
- /// Ok(s) => {
- /// // do something with the TcpStream
- /// handle_connection(s);
- /// }
- /// Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
- /// // wait until network socket is ready, typically implemented
- /// // via platform-specific APIs such as epoll or IOCP
- /// wait_for_fd();
- /// continue;
- /// }
- /// Err(e) => panic!("encountered IO error: {}", e),
- /// }
- /// }
- /// ```
- ///
- /// [`io::ErrorKind::WouldBlock`]: ../io/enum.ErrorKind.html#variant.WouldBlock
- #[stable(feature = "net2_mutators", since = "1.9.0")]
- pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
- self.0.set_nonblocking(nonblocking)
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a> Iterator for Incoming<'a> {
- type Item = io::Result<TcpStream>;
- fn next(&mut self) -> Option<io::Result<TcpStream>> {
- Some(self.listener.accept().map(|p| p.0))
- }
-}
-
-impl AsInner<net_imp::TcpListener> for TcpListener {
- fn as_inner(&self) -> &net_imp::TcpListener { &self.0 }
-}
-
-impl FromInner<net_imp::TcpListener> for TcpListener {
- fn from_inner(inner: net_imp::TcpListener) -> TcpListener {
- TcpListener(inner)
- }
-}
-
-impl IntoInner<net_imp::TcpListener> for TcpListener {
- fn into_inner(self) -> net_imp::TcpListener { self.0 }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl fmt::Debug for TcpListener {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- self.0.fmt(f)
- }
-}
-
-#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten"))))]
-mod tests {
- use io::ErrorKind;
- use io::prelude::*;
- use net::*;
- use net::test::{next_test_ip4, next_test_ip6};
- use sync::mpsc::channel;
- use sys_common::AsInner;
- use time::{Instant, Duration};
- use thread;
-
- fn each_ip(f: &mut dyn FnMut(SocketAddr)) {
- f(next_test_ip4());
- f(next_test_ip6());
- }
-
- macro_rules! t {
- ($e:expr) => {
- match $e {
- Ok(t) => t,
- Err(e) => panic!("received error for `{}`: {}", stringify!($e), e),
- }
- }
- }
-
- #[test]
- fn bind_error() {
- match TcpListener::bind("1.1.1.1:9999") {
- Ok(..) => panic!(),
- Err(e) =>
- assert_eq!(e.kind(), ErrorKind::AddrNotAvailable),
- }
- }
-
- #[test]
- fn connect_error() {
- match TcpStream::connect("0.0.0.0:1") {
- Ok(..) => panic!(),
- Err(e) => assert!(e.kind() == ErrorKind::ConnectionRefused ||
- e.kind() == ErrorKind::InvalidInput ||
- e.kind() == ErrorKind::AddrInUse ||
- e.kind() == ErrorKind::AddrNotAvailable,
- "bad error: {} {:?}", e, e.kind()),
- }
- }
-
- #[test]
- fn listen_localhost() {
- let socket_addr = next_test_ip4();
- let listener = t!(TcpListener::bind(&socket_addr));
-
- let _t = thread::spawn(move || {
- let mut stream = t!(TcpStream::connect(&("localhost",
- socket_addr.port())));
- t!(stream.write(&[144]));
- });
-
- let mut stream = t!(listener.accept()).0;
- let mut buf = [0];
- t!(stream.read(&mut buf));
- assert!(buf[0] == 144);
- }
-
- #[test]
- fn connect_loopback() {
- each_ip(&mut |addr| {
- let acceptor = t!(TcpListener::bind(&addr));
-
- let _t = thread::spawn(move|| {
- let host = match addr {
- SocketAddr::V4(..) => "127.0.0.1",
- SocketAddr::V6(..) => "::1",
- };
- let mut stream = t!(TcpStream::connect(&(host, addr.port())));
- t!(stream.write(&[66]));
- });
-
- let mut stream = t!(acceptor.accept()).0;
- let mut buf = [0];
- t!(stream.read(&mut buf));
- assert!(buf[0] == 66);
- })
- }
-
- #[test]
- fn smoke_test() {
- each_ip(&mut |addr| {
- let acceptor = t!(TcpListener::bind(&addr));
-
- let (tx, rx) = channel();
- let _t = thread::spawn(move|| {
- let mut stream = t!(TcpStream::connect(&addr));
- t!(stream.write(&[99]));
- tx.send(t!(stream.local_addr())).unwrap();
- });
-
- let (mut stream, addr) = t!(acceptor.accept());
- let mut buf = [0];
- t!(stream.read(&mut buf));
- assert!(buf[0] == 99);
- assert_eq!(addr, t!(rx.recv()));
- })
- }
-
- #[test]
- fn read_eof() {
- each_ip(&mut |addr| {
- let acceptor = t!(TcpListener::bind(&addr));
-
- let _t = thread::spawn(move|| {
- let _stream = t!(TcpStream::connect(&addr));
- // Close
- });
-
- let mut stream = t!(acceptor.accept()).0;
- let mut buf = [0];
- let nread = t!(stream.read(&mut buf));
- assert_eq!(nread, 0);
- let nread = t!(stream.read(&mut buf));
- assert_eq!(nread, 0);
- })
- }
-
- #[test]
- fn write_close() {
- each_ip(&mut |addr| {
- let acceptor = t!(TcpListener::bind(&addr));
-
- let (tx, rx) = channel();
- let _t = thread::spawn(move|| {
- drop(t!(TcpStream::connect(&addr)));
- tx.send(()).unwrap();
- });
-
- let mut stream = t!(acceptor.accept()).0;
- rx.recv().unwrap();
- let buf = [0];
- match stream.write(&buf) {
- Ok(..) => {}
- Err(e) => {
- assert!(e.kind() == ErrorKind::ConnectionReset ||
- e.kind() == ErrorKind::BrokenPipe ||
- e.kind() == ErrorKind::ConnectionAborted,
- "unknown error: {}", e);
- }
- }
- })
- }
-
- #[test]
- fn multiple_connect_serial() {
- each_ip(&mut |addr| {
- let max = 10;
- let acceptor = t!(TcpListener::bind(&addr));
-
- let _t = thread::spawn(move|| {
- for _ in 0..max {
- let mut stream = t!(TcpStream::connect(&addr));
- t!(stream.write(&[99]));
- }
- });
-
- for stream in acceptor.incoming().take(max) {
- let mut stream = t!(stream);
- let mut buf = [0];
- t!(stream.read(&mut buf));
- assert_eq!(buf[0], 99);
- }
- })
- }
-
- #[test]
- fn multiple_connect_interleaved_greedy_schedule() {
- const MAX: usize = 10;
- each_ip(&mut |addr| {
- let acceptor = t!(TcpListener::bind(&addr));
-
- let _t = thread::spawn(move|| {
- let acceptor = acceptor;
- for (i, stream) in acceptor.incoming().enumerate().take(MAX) {
- // Start another thread to handle the connection
- let _t = thread::spawn(move|| {
- let mut stream = t!(stream);
- let mut buf = [0];
- t!(stream.read(&mut buf));
- assert!(buf[0] == i as u8);
- });
- }
- });
-
- connect(0, addr);
- });
-
- fn connect(i: usize, addr: SocketAddr) {
- if i == MAX { return }
-
- let t = thread::spawn(move|| {
- let mut stream = t!(TcpStream::connect(&addr));
- // Connect again before writing
- connect(i + 1, addr);
- t!(stream.write(&[i as u8]));
- });
- t.join().ok().unwrap();
- }
- }
-
- #[test]
- fn multiple_connect_interleaved_lazy_schedule() {
- const MAX: usize = 10;
- each_ip(&mut |addr| {
- let acceptor = t!(TcpListener::bind(&addr));
-
- let _t = thread::spawn(move|| {
- for stream in acceptor.incoming().take(MAX) {
- // Start another thread to handle the connection
- let _t = thread::spawn(move|| {
- let mut stream = t!(stream);
- let mut buf = [0];
- t!(stream.read(&mut buf));
- assert!(buf[0] == 99);
- });
- }
- });
-
- connect(0, addr);
- });
-
- fn connect(i: usize, addr: SocketAddr) {
- if i == MAX { return }
-
- let t = thread::spawn(move|| {
- let mut stream = t!(TcpStream::connect(&addr));
- connect(i + 1, addr);
- t!(stream.write(&[99]));
- });
- t.join().ok().unwrap();
- }
- }
-
- #[test]
- fn socket_and_peer_name() {
- each_ip(&mut |addr| {
- let listener = t!(TcpListener::bind(&addr));
- let so_name = t!(listener.local_addr());
- assert_eq!(addr, so_name);
- let _t = thread::spawn(move|| {
- t!(listener.accept());
- });
-
- let stream = t!(TcpStream::connect(&addr));
- assert_eq!(addr, t!(stream.peer_addr()));
- })
- }
-
- #[test]
- fn partial_read() {
- each_ip(&mut |addr| {
- let (tx, rx) = channel();
- let srv = t!(TcpListener::bind(&addr));
- let _t = thread::spawn(move|| {
- let mut cl = t!(srv.accept()).0;
- cl.write(&[10]).unwrap();
- let mut b = [0];
- t!(cl.read(&mut b));
- tx.send(()).unwrap();
- });
-
- let mut c = t!(TcpStream::connect(&addr));
- let mut b = [0; 10];
- assert_eq!(c.read(&mut b).unwrap(), 1);
- t!(c.write(&[1]));
- rx.recv().unwrap();
- })
- }
-
- #[test]
- fn double_bind() {
- each_ip(&mut |addr| {
- let _listener = t!(TcpListener::bind(&addr));
- match TcpListener::bind(&addr) {
- Ok(..) => panic!(),
- Err(e) => {
- assert!(e.kind() == ErrorKind::ConnectionRefused ||
- e.kind() == ErrorKind::Other ||
- e.kind() == ErrorKind::AddrInUse,
- "unknown error: {} {:?}", e, e.kind());
- }
- }
- })
- }
-
- #[test]
- fn fast_rebind() {
- each_ip(&mut |addr| {
- let acceptor = t!(TcpListener::bind(&addr));
-
- let _t = thread::spawn(move|| {
- t!(TcpStream::connect(&addr));
- });
-
- t!(acceptor.accept());
- drop(acceptor);
- t!(TcpListener::bind(&addr));
- });
- }
-
- #[test]
- fn tcp_clone_smoke() {
- each_ip(&mut |addr| {
- let acceptor = t!(TcpListener::bind(&addr));
-
- let _t = thread::spawn(move|| {
- let mut s = t!(TcpStream::connect(&addr));
- let mut buf = [0, 0];
- assert_eq!(s.read(&mut buf).unwrap(), 1);
- assert_eq!(buf[0], 1);
- t!(s.write(&[2]));
- });
-
- let mut s1 = t!(acceptor.accept()).0;
- let s2 = t!(s1.try_clone());
-
- let (tx1, rx1) = channel();
- let (tx2, rx2) = channel();
- let _t = thread::spawn(move|| {
- let mut s2 = s2;
- rx1.recv().unwrap();
- t!(s2.write(&[1]));
- tx2.send(()).unwrap();
- });
- tx1.send(()).unwrap();
- let mut buf = [0, 0];
- assert_eq!(s1.read(&mut buf).unwrap(), 1);
- rx2.recv().unwrap();
- })
- }
-
- #[test]
- fn tcp_clone_two_read() {
- each_ip(&mut |addr| {
- let acceptor = t!(TcpListener::bind(&addr));
- let (tx1, rx) = channel();
- let tx2 = tx1.clone();
-
- let _t = thread::spawn(move|| {
- let mut s = t!(TcpStream::connect(&addr));
- t!(s.write(&[1]));
- rx.recv().unwrap();
- t!(s.write(&[2]));
- rx.recv().unwrap();
- });
-
- let mut s1 = t!(acceptor.accept()).0;
- let s2 = t!(s1.try_clone());
-
- let (done, rx) = channel();
- let _t = thread::spawn(move|| {
- let mut s2 = s2;
- let mut buf = [0, 0];
- t!(s2.read(&mut buf));
- tx2.send(()).unwrap();
- done.send(()).unwrap();
- });
- let mut buf = [0, 0];
- t!(s1.read(&mut buf));
- tx1.send(()).unwrap();
-
- rx.recv().unwrap();
- })
- }
-
- #[test]
- fn tcp_clone_two_write() {
- each_ip(&mut |addr| {
- let acceptor = t!(TcpListener::bind(&addr));
-
- let _t = thread::spawn(move|| {
- let mut s = t!(TcpStream::connect(&addr));
- let mut buf = [0, 1];
- t!(s.read(&mut buf));
- t!(s.read(&mut buf));
- });
-
- let mut s1 = t!(acceptor.accept()).0;
- let s2 = t!(s1.try_clone());
-
- let (done, rx) = channel();
- let _t = thread::spawn(move|| {
- let mut s2 = s2;
- t!(s2.write(&[1]));
- done.send(()).unwrap();
- });
- t!(s1.write(&[2]));
-
- rx.recv().unwrap();
- })
- }
-
- #[test]
- fn shutdown_smoke() {
- each_ip(&mut |addr| {
- let a = t!(TcpListener::bind(&addr));
- let _t = thread::spawn(move|| {
- let mut c = t!(a.accept()).0;
- let mut b = [0];
- assert_eq!(c.read(&mut b).unwrap(), 0);
- t!(c.write(&[1]));
- });
-
- let mut s = t!(TcpStream::connect(&addr));
- t!(s.shutdown(Shutdown::Write));
- assert!(s.write(&[1]).is_err());
- let mut b = [0, 0];
- assert_eq!(t!(s.read(&mut b)), 1);
- assert_eq!(b[0], 1);
- })
- }
-
- #[test]
- fn close_readwrite_smoke() {
- each_ip(&mut |addr| {
- let a = t!(TcpListener::bind(&addr));
- let (tx, rx) = channel::<()>();
- let _t = thread::spawn(move|| {
- let _s = t!(a.accept());
- let _ = rx.recv();
- });
-
- let mut b = [0];
- let mut s = t!(TcpStream::connect(&addr));
- let mut s2 = t!(s.try_clone());
-
- // closing should prevent reads/writes
- t!(s.shutdown(Shutdown::Write));
- assert!(s.write(&[0]).is_err());
- t!(s.shutdown(Shutdown::Read));
- assert_eq!(s.read(&mut b).unwrap(), 0);
-
- // closing should affect previous handles
- assert!(s2.write(&[0]).is_err());
- assert_eq!(s2.read(&mut b).unwrap(), 0);
-
- // closing should affect new handles
- let mut s3 = t!(s.try_clone());
- assert!(s3.write(&[0]).is_err());
- assert_eq!(s3.read(&mut b).unwrap(), 0);
-
- // make sure these don't die
- let _ = s2.shutdown(Shutdown::Read);
- let _ = s2.shutdown(Shutdown::Write);
- let _ = s3.shutdown(Shutdown::Read);
- let _ = s3.shutdown(Shutdown::Write);
- drop(tx);
- })
- }
-
- #[test]
- #[cfg(unix)] // test doesn't work on Windows, see #31657
- fn close_read_wakes_up() {
- each_ip(&mut |addr| {
- let a = t!(TcpListener::bind(&addr));
- let (tx1, rx) = channel::<()>();
- let _t = thread::spawn(move|| {
- let _s = t!(a.accept());
- let _ = rx.recv();
- });
-
- let s = t!(TcpStream::connect(&addr));
- let s2 = t!(s.try_clone());
- let (tx, rx) = channel();
- let _t = thread::spawn(move|| {
- let mut s2 = s2;
- assert_eq!(t!(s2.read(&mut [0])), 0);
- tx.send(()).unwrap();
- });
- // this should wake up the child thread
- t!(s.shutdown(Shutdown::Read));
-
- // this test will never finish if the child doesn't wake up
- rx.recv().unwrap();
- drop(tx1);
- })
- }
-
- #[test]
- fn clone_while_reading() {
- each_ip(&mut |addr| {
- let accept = t!(TcpListener::bind(&addr));
-
- // Enqueue a thread to write to a socket
- let (tx, rx) = channel();
- let (txdone, rxdone) = channel();
- let txdone2 = txdone.clone();
- let _t = thread::spawn(move|| {
- let mut tcp = t!(TcpStream::connect(&addr));
- rx.recv().unwrap();
- t!(tcp.write(&[0]));
- txdone2.send(()).unwrap();
- });
-
- // Spawn off a reading clone
- let tcp = t!(accept.accept()).0;
- let tcp2 = t!(tcp.try_clone());
- let txdone3 = txdone.clone();
- let _t = thread::spawn(move|| {
- let mut tcp2 = tcp2;
- t!(tcp2.read(&mut [0]));
- txdone3.send(()).unwrap();
- });
-
- // Try to ensure that the reading clone is indeed reading
- for _ in 0..50 {
- thread::yield_now();
- }
-
- // clone the handle again while it's reading, then let it finish the
- // read.
- let _ = t!(tcp.try_clone());
- tx.send(()).unwrap();
- rxdone.recv().unwrap();
- rxdone.recv().unwrap();
- })
- }
-
- #[test]
- fn clone_accept_smoke() {
- each_ip(&mut |addr| {
- let a = t!(TcpListener::bind(&addr));
- let a2 = t!(a.try_clone());
-
- let _t = thread::spawn(move|| {
- let _ = TcpStream::connect(&addr);
- });
- let _t = thread::spawn(move|| {
- let _ = TcpStream::connect(&addr);
- });
-
- t!(a.accept());
- t!(a2.accept());
- })
- }
-
- #[test]
- fn clone_accept_concurrent() {
- each_ip(&mut |addr| {
- let a = t!(TcpListener::bind(&addr));
- let a2 = t!(a.try_clone());
-
- let (tx, rx) = channel();
- let tx2 = tx.clone();
-
- let _t = thread::spawn(move|| {
- tx.send(t!(a.accept())).unwrap();
- });
- let _t = thread::spawn(move|| {
- tx2.send(t!(a2.accept())).unwrap();
- });
-
- let _t = thread::spawn(move|| {
- let _ = TcpStream::connect(&addr);
- });
- let _t = thread::spawn(move|| {
- let _ = TcpStream::connect(&addr);
- });
-
- rx.recv().unwrap();
- rx.recv().unwrap();
- })
- }
-
- #[test]
- fn debug() {
- let name = if cfg!(windows) {"socket"} else {"fd"};
- let socket_addr = next_test_ip4();
-
- let listener = t!(TcpListener::bind(&socket_addr));
- let listener_inner = listener.0.socket().as_inner();
- let compare = format!("TcpListener {{ addr: {:?}, {}: {:?} }}",
- socket_addr, name, listener_inner);
- assert_eq!(format!("{:?}", listener), compare);
-
- let stream = t!(TcpStream::connect(&("localhost",
- socket_addr.port())));
- let stream_inner = stream.0.socket().as_inner();
- let compare = format!("TcpStream {{ addr: {:?}, \
- peer: {:?}, {}: {:?} }}",
- stream.local_addr().unwrap(),
- stream.peer_addr().unwrap(),
- name,
- stream_inner);
- assert_eq!(format!("{:?}", stream), compare);
- }
-
- // FIXME: re-enabled bitrig/openbsd tests once their socket timeout code
- // no longer has rounding errors.
- #[cfg_attr(any(target_os = "bitrig", target_os = "netbsd", target_os = "openbsd"), ignore)]
- #[test]
- fn timeouts() {
- let addr = next_test_ip4();
- let listener = t!(TcpListener::bind(&addr));
-
- let stream = t!(TcpStream::connect(&("localhost", addr.port())));
- let dur = Duration::new(15410, 0);
-
- assert_eq!(None, t!(stream.read_timeout()));
-
- t!(stream.set_read_timeout(Some(dur)));
- assert_eq!(Some(dur), t!(stream.read_timeout()));
-
- assert_eq!(None, t!(stream.write_timeout()));
-
- t!(stream.set_write_timeout(Some(dur)));
- assert_eq!(Some(dur), t!(stream.write_timeout()));
-
- t!(stream.set_read_timeout(None));
- assert_eq!(None, t!(stream.read_timeout()));
-
- t!(stream.set_write_timeout(None));
- assert_eq!(None, t!(stream.write_timeout()));
- drop(listener);
- }
-
- #[test]
- fn test_read_timeout() {
- let addr = next_test_ip4();
- let listener = t!(TcpListener::bind(&addr));
-
- let mut stream = t!(TcpStream::connect(&("localhost", addr.port())));
- t!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
-
- let mut buf = [0; 10];
- let start = Instant::now();
- let kind = stream.read(&mut buf).err().expect("expected error").kind();
- assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut);
- assert!(start.elapsed() > Duration::from_millis(400));
- drop(listener);
- }
-
- #[test]
- fn test_read_with_timeout() {
- let addr = next_test_ip4();
- let listener = t!(TcpListener::bind(&addr));
-
- let mut stream = t!(TcpStream::connect(&("localhost", addr.port())));
- t!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
-
- let mut other_end = t!(listener.accept()).0;
- t!(other_end.write_all(b"hello world"));
-
- let mut buf = [0; 11];
- t!(stream.read(&mut buf));
- assert_eq!(b"hello world", &buf[..]);
-
- let start = Instant::now();
- let kind = stream.read(&mut buf).err().expect("expected error").kind();
- assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut);
- assert!(start.elapsed() > Duration::from_millis(400));
- 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();
- let _listener = t!(TcpListener::bind(&addr));
-
- let stream = t!(TcpStream::connect(&("localhost", addr.port())));
-
- assert_eq!(false, t!(stream.nodelay()));
- t!(stream.set_nodelay(true));
- assert_eq!(true, t!(stream.nodelay()));
- t!(stream.set_nodelay(false));
- assert_eq!(false, t!(stream.nodelay()));
- }
-
- #[test]
- fn ttl() {
- let ttl = 100;
-
- let addr = next_test_ip4();
- let listener = t!(TcpListener::bind(&addr));
-
- t!(listener.set_ttl(ttl));
- assert_eq!(ttl, t!(listener.ttl()));
-
- let stream = t!(TcpStream::connect(&("localhost", addr.port())));
-
- t!(stream.set_ttl(ttl));
- assert_eq!(ttl, t!(stream.ttl()));
- }
-
- #[test]
- fn set_nonblocking() {
- let addr = next_test_ip4();
- let listener = t!(TcpListener::bind(&addr));
-
- t!(listener.set_nonblocking(true));
- t!(listener.set_nonblocking(false));
-
- let mut stream = t!(TcpStream::connect(&("localhost", addr.port())));
-
- t!(stream.set_nonblocking(false));
- t!(stream.set_nonblocking(true));
-
- let mut buf = [0];
- match stream.read(&mut buf) {
- Ok(_) => panic!("expected error"),
- Err(ref e) if e.kind() == ErrorKind::WouldBlock => {}
- Err(e) => panic!("unexpected error {}", e),
- }
- }
-
- #[test]
- fn peek() {
- each_ip(&mut |addr| {
- let (txdone, rxdone) = channel();
-
- let srv = t!(TcpListener::bind(&addr));
- let _t = thread::spawn(move|| {
- let mut cl = t!(srv.accept()).0;
- cl.write(&[1,3,3,7]).unwrap();
- t!(rxdone.recv());
- });
-
- let mut c = t!(TcpStream::connect(&addr));
- let mut b = [0; 10];
- for _ in 1..3 {
- let len = c.peek(&mut b).unwrap();
- assert_eq!(len, 4);
- }
- let len = c.read(&mut b).unwrap();
- assert_eq!(len, 4);
-
- t!(c.set_nonblocking(true));
- match c.peek(&mut b) {
- Ok(_) => panic!("expected error"),
- Err(ref e) if e.kind() == ErrorKind::WouldBlock => {}
- Err(e) => panic!("unexpected error {}", e),
- }
- t!(txdone.send(()));
- })
- }
-
- #[test]
- fn connect_timeout_unroutable() {
- // this IP is unroutable, so connections should always time out,
- // provided the network is reachable to begin with.
- let addr = "10.255.255.1:80".parse().unwrap();
- let e = TcpStream::connect_timeout(&addr, Duration::from_millis(250)).unwrap_err();
- assert!(e.kind() == io::ErrorKind::TimedOut ||
- e.kind() == io::ErrorKind::Other,
- "bad error: {} {:?}", e, e.kind());
- }
-
- #[test]
- fn connect_timeout_unbound() {
- // bind and drop a socket to track down a "probably unassigned" port
- let socket = TcpListener::bind("127.0.0.1:0").unwrap();
- let addr = socket.local_addr().unwrap();
- drop(socket);
-
- let timeout = Duration::from_secs(1);
- let e = TcpStream::connect_timeout(&addr, timeout).unwrap_err();
- assert!(e.kind() == io::ErrorKind::ConnectionRefused ||
- e.kind() == io::ErrorKind::TimedOut ||
- e.kind() == io::ErrorKind::Other,
- "bad error: {} {:?}", e, e.kind());
- }
-
- #[test]
- fn connect_timeout_valid() {
- let listener = TcpListener::bind("127.0.0.1:0").unwrap();
- let addr = listener.local_addr().unwrap();
- TcpStream::connect_timeout(&addr, Duration::from_secs(2)).unwrap();
- }
-}
diff --git a/ctr-std/src/net/test.rs b/ctr-std/src/net/test.rs
deleted file mode 100644
index aec3d90..0000000
--- a/ctr-std/src/net/test.rs
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![allow(warnings)] // not used on emscripten
-
-use env;
-use net::{SocketAddr, SocketAddrV4, SocketAddrV6, Ipv4Addr, Ipv6Addr, ToSocketAddrs};
-use sync::atomic::{AtomicUsize, Ordering};
-
-static PORT: AtomicUsize = AtomicUsize::new(0);
-
-pub fn next_test_ip4() -> SocketAddr {
- let port = PORT.fetch_add(1, Ordering::SeqCst) as u16 + base_port();
- SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), port))
-}
-
-pub fn next_test_ip6() -> SocketAddr {
- let port = PORT.fetch_add(1, Ordering::SeqCst) as u16 + base_port();
- SocketAddr::V6(SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1),
- port, 0, 0))
-}
-
-pub fn sa4(a: Ipv4Addr, p: u16) -> SocketAddr {
- SocketAddr::V4(SocketAddrV4::new(a, p))
-}
-
-pub fn sa6(a: Ipv6Addr, p: u16) -> SocketAddr {
- SocketAddr::V6(SocketAddrV6::new(a, p, 0, 0))
-}
-
-pub fn tsa<A: ToSocketAddrs>(a: A) -> Result<Vec<SocketAddr>, String> {
- match a.to_socket_addrs() {
- Ok(a) => Ok(a.collect()),
- Err(e) => Err(e.to_string()),
- }
-}
-
-// The bots run multiple builds at the same time, and these builds
-// all want to use ports. This function figures out which workspace
-// it is running in and assigns a port range based on it.
-fn base_port() -> u16 {
- let cwd = env::current_dir().unwrap();
- let dirs = ["32-opt", "32-nopt",
- "musl-64-opt", "cross-opt",
- "64-opt", "64-nopt", "64-opt-vg", "64-debug-opt",
- "all-opt", "snap3", "dist"];
- dirs.iter().enumerate().find(|&(_, dir)| {
- cwd.to_str().unwrap().contains(dir)
- }).map(|p| p.0).unwrap_or(0) as u16 * 1000 + 19600
-}
diff --git a/ctr-std/src/net/udp.rs b/ctr-std/src/net/udp.rs
deleted file mode 100644
index 0ebe328..0000000
--- a/ctr-std/src/net/udp.rs
+++ /dev/null
@@ -1,1163 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use fmt;
-use io::{self, Error, ErrorKind};
-use net::{ToSocketAddrs, SocketAddr, Ipv4Addr, Ipv6Addr};
-use sys_common::net as net_imp;
-use sys_common::{AsInner, FromInner, IntoInner};
-use time::Duration;
-
-/// A UDP socket.
-///
-/// After creating a `UdpSocket` by [`bind`]ing it to a socket address, data can be
-/// [sent to] and [received from] any other socket address.
-///
-/// Although UDP is a connectionless protocol, this implementation provides an interface
-/// to set an address where data should be sent and received from. After setting a remote
-/// address with [`connect`], data can be sent to and received from that address with
-/// [`send`] and [`recv`].
-///
-/// As stated in the User Datagram Protocol's specification in [IETF RFC 768], UDP is
-/// an unordered, unreliable protocol; refer to [`TcpListener`] and [`TcpStream`] for TCP
-/// primitives.
-///
-/// [`bind`]: #method.bind
-/// [`connect`]: #method.connect
-/// [IETF RFC 768]: https://tools.ietf.org/html/rfc768
-/// [`recv`]: #method.recv
-/// [received from]: #method.recv_from
-/// [`send`]: #method.send
-/// [sent to]: #method.send_to
-/// [`TcpListener`]: ../../std/net/struct.TcpListener.html
-/// [`TcpStream`]: ../../std/net/struct.TcpStream.html
-///
-/// # Examples
-///
-/// ```no_run
-/// use std::net::UdpSocket;
-///
-/// 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)?;
-///
-/// // 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);
-
-impl UdpSocket {
- /// Creates a UDP socket from the given address.
- ///
- /// The address type can be any implementor of [`ToSocketAddrs`] trait. See
- /// its documentation for concrete examples.
- ///
- /// If `addr` yields multiple addresses, `bind` will be attempted with
- /// each of the addresses until one succeeds and returns the socket. If none
- /// of the addresses succeed in creating a socket, the error returned from
- /// the last attempt (the last address) is returned.
- ///
- /// [`ToSocketAddrs`]: ../../std/net/trait.ToSocketAddrs.html
- ///
- /// # Examples
- ///
- /// Create a UDP socket bound to `127.0.0.1:3400`:
- ///
- /// ```no_run
- /// use std::net::UdpSocket;
- ///
- /// let socket = UdpSocket::bind("127.0.0.1:3400").expect("couldn't bind to address");
- /// ```
- ///
- /// Create a UDP socket bound to `127.0.0.1:3400`. If the socket cannot be
- /// bound to that address, create a UDP socket bound to `127.0.0.1:3401`:
- ///
- /// ```no_run
- /// use std::net::{SocketAddr, UdpSocket};
- ///
- /// let addrs = [
- /// SocketAddr::from(([127, 0, 0, 1], 3400)),
- /// SocketAddr::from(([127, 0, 0, 1], 3401)),
- /// ];
- /// let socket = UdpSocket::bind(&addrs[..]).expect("couldn't bind to address");
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<UdpSocket> {
- super::each_addr(addr, net_imp::UdpSocket::bind).map(UdpSocket)
- }
-
- /// Receives a single datagram message on the socket. On success, returns the number
- /// of bytes read and the origin.
- ///
- /// The function must be called with valid byte array `buf` of sufficient size to
- /// hold the message bytes. If a message is too long to fit in the supplied buffer,
- /// excess bytes may be discarded.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::UdpSocket;
- ///
- /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
- /// let mut buf = [0; 10];
- /// let (number_of_bytes, src_addr) = socket.recv_from(&mut buf)
- /// .expect("Didn't receive data");
- /// let filled_buf = &mut buf[..number_of_bytes];
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
- self.0.recv_from(buf)
- }
-
- /// Receives a single datagram message on the socket, without removing it from the
- /// queue. On success, returns the number of bytes read and the origin.
- ///
- /// The function must be called with valid byte array `buf` of sufficient size to
- /// hold the message bytes. If a message is too long to fit in the supplied buffer,
- /// excess bytes may be discarded.
- ///
- /// Successive calls return the same data. This is accomplished by passing
- /// `MSG_PEEK` as a flag to the underlying `recvfrom` system call.
- ///
- /// Do not use this function to implement busy waiting, instead use `libc::poll` to
- /// synchronize IO events on one or more sockets.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::UdpSocket;
- ///
- /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
- /// let mut buf = [0; 10];
- /// let (number_of_bytes, src_addr) = socket.peek_from(&mut buf)
- /// .expect("Didn't receive data");
- /// let filled_buf = &mut buf[..number_of_bytes];
- /// ```
- #[stable(feature = "peek", since = "1.18.0")]
- pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
- self.0.peek_from(buf)
- }
-
- /// Sends data on the socket to the given address. On success, returns the
- /// number of bytes written.
- ///
- /// Address type can be any implementor of [`ToSocketAddrs`] trait. See its
- /// documentation for concrete examples.
- ///
- /// It is possible for `addr` to yield multiple addresses, but `send_to`
- /// will only send data to the first address yielded by `addr`.
- ///
- /// This will return an error when the IP version of the local socket
- /// does not match that returned from [`ToSocketAddrs`].
- ///
- /// See <https://github.com/rust-lang/rust/issues/34202> for more details.
- ///
- /// [`ToSocketAddrs`]: ../../std/net/trait.ToSocketAddrs.html
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::UdpSocket;
- ///
- /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
- /// socket.send_to(&[0; 10], "127.0.0.1:4242").expect("couldn't send data");
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn send_to<A: ToSocketAddrs>(&self, buf: &[u8], addr: A)
- -> io::Result<usize> {
- match addr.to_socket_addrs()?.next() {
- Some(addr) => self.0.send_to(buf, &addr),
- None => Err(Error::new(ErrorKind::InvalidInput,
- "no addresses to send data to")),
- }
- }
-
- /// Returns the socket address that this socket was created from.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, UdpSocket};
- ///
- /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
- /// assert_eq!(socket.local_addr().unwrap(),
- /// SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 34254)));
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn local_addr(&self) -> io::Result<SocketAddr> {
- self.0.socket_addr()
- }
-
- /// Creates a new independently owned handle to the underlying socket.
- ///
- /// The returned `UdpSocket` is a reference to the same socket that this
- /// object references. Both handles will read and write the same port, and
- /// options set on one socket will be propagated to the other.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::UdpSocket;
- ///
- /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
- /// let socket_clone = socket.try_clone().expect("couldn't clone the socket");
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn try_clone(&self) -> io::Result<UdpSocket> {
- self.0.duplicate().map(UdpSocket)
- }
-
- /// Sets the read timeout to the timeout specified.
- ///
- /// If the value specified is [`None`], then [`read`] calls will block
- /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is
- /// passed to this method.
- ///
- /// # 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
- /// [`TimedOut`]: ../../std/io/enum.ErrorKind.html#variant.TimedOut
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::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)
- }
-
- /// Sets the write timeout to the timeout specified.
- ///
- /// If the value specified is [`None`], then [`write`] calls will block
- /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is
- /// passed to this method.
- ///
- /// # 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
- /// [`TimedOut`]: ../../std/io/enum.ErrorKind.html#variant.TimedOut
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::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)
- }
-
- /// Returns the read timeout of this socket.
- ///
- /// If the timeout is [`None`], then [`read`] calls will block indefinitely.
- ///
- /// [`None`]: ../../std/option/enum.Option.html#variant.None
- /// [`read`]: ../../std/io/trait.Read.html#tymethod.read
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::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");
- /// assert_eq!(socket.read_timeout().unwrap(), None);
- /// ```
- #[stable(feature = "socket_timeout", since = "1.4.0")]
- pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
- self.0.read_timeout()
- }
-
- /// Returns the write timeout of this socket.
- ///
- /// If the timeout is [`None`], then [`write`] calls will block indefinitely.
- ///
- /// [`None`]: ../../std/option/enum.Option.html#variant.None
- /// [`write`]: ../../std/io/trait.Write.html#tymethod.write
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::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");
- /// assert_eq!(socket.write_timeout().unwrap(), None);
- /// ```
- #[stable(feature = "socket_timeout", since = "1.4.0")]
- pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
- self.0.write_timeout()
- }
-
- /// Sets the value of the `SO_BROADCAST` option for this socket.
- ///
- /// When enabled, this socket is allowed to send packets to a broadcast
- /// address.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::UdpSocket;
- ///
- /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
- /// socket.set_broadcast(false).expect("set_broadcast call failed");
- /// ```
- #[stable(feature = "net2_mutators", since = "1.9.0")]
- pub fn set_broadcast(&self, broadcast: bool) -> io::Result<()> {
- self.0.set_broadcast(broadcast)
- }
-
- /// Gets the value of the `SO_BROADCAST` option for this socket.
- ///
- /// For more information about this option, see
- /// [`set_broadcast`][link].
- ///
- /// [link]: #method.set_broadcast
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::UdpSocket;
- ///
- /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
- /// socket.set_broadcast(false).expect("set_broadcast call failed");
- /// assert_eq!(socket.broadcast().unwrap(), false);
- /// ```
- #[stable(feature = "net2_mutators", since = "1.9.0")]
- pub fn broadcast(&self) -> io::Result<bool> {
- self.0.broadcast()
- }
-
- /// Sets the value of the `IP_MULTICAST_LOOP` option for this socket.
- ///
- /// If enabled, multicast packets will be looped back to the local socket.
- /// Note that this may not have any affect on IPv6 sockets.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::UdpSocket;
- ///
- /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
- /// socket.set_multicast_loop_v4(false).expect("set_multicast_loop_v4 call failed");
- /// ```
- #[stable(feature = "net2_mutators", since = "1.9.0")]
- pub fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()> {
- self.0.set_multicast_loop_v4(multicast_loop_v4)
- }
-
- /// Gets the value of the `IP_MULTICAST_LOOP` option for this socket.
- ///
- /// For more information about this option, see
- /// [`set_multicast_loop_v4`][link].
- ///
- /// [link]: #method.set_multicast_loop_v4
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::UdpSocket;
- ///
- /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
- /// socket.set_multicast_loop_v4(false).expect("set_multicast_loop_v4 call failed");
- /// assert_eq!(socket.multicast_loop_v4().unwrap(), false);
- /// ```
- #[stable(feature = "net2_mutators", since = "1.9.0")]
- pub fn multicast_loop_v4(&self) -> io::Result<bool> {
- self.0.multicast_loop_v4()
- }
-
- /// Sets the value of the `IP_MULTICAST_TTL` option for this socket.
- ///
- /// Indicates the time-to-live value of outgoing multicast packets for
- /// this socket. The default value is 1 which means that multicast packets
- /// don't leave the local network unless explicitly requested.
- ///
- /// Note that this may not have any affect on IPv6 sockets.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::UdpSocket;
- ///
- /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
- /// socket.set_multicast_ttl_v4(42).expect("set_multicast_ttl_v4 call failed");
- /// ```
- #[stable(feature = "net2_mutators", since = "1.9.0")]
- pub fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()> {
- self.0.set_multicast_ttl_v4(multicast_ttl_v4)
- }
-
- /// Gets the value of the `IP_MULTICAST_TTL` option for this socket.
- ///
- /// For more information about this option, see
- /// [`set_multicast_ttl_v4`][link].
- ///
- /// [link]: #method.set_multicast_ttl_v4
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::UdpSocket;
- ///
- /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
- /// socket.set_multicast_ttl_v4(42).expect("set_multicast_ttl_v4 call failed");
- /// assert_eq!(socket.multicast_ttl_v4().unwrap(), 42);
- /// ```
- #[stable(feature = "net2_mutators", since = "1.9.0")]
- pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
- self.0.multicast_ttl_v4()
- }
-
- /// Sets the value of the `IPV6_MULTICAST_LOOP` option for this socket.
- ///
- /// Controls whether this socket sees the multicast packets it sends itself.
- /// Note that this may not have any affect on IPv4 sockets.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::UdpSocket;
- ///
- /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
- /// socket.set_multicast_loop_v6(false).expect("set_multicast_loop_v6 call failed");
- /// ```
- #[stable(feature = "net2_mutators", since = "1.9.0")]
- pub fn set_multicast_loop_v6(&self, multicast_loop_v6: bool) -> io::Result<()> {
- self.0.set_multicast_loop_v6(multicast_loop_v6)
- }
-
- /// Gets the value of the `IPV6_MULTICAST_LOOP` option for this socket.
- ///
- /// For more information about this option, see
- /// [`set_multicast_loop_v6`][link].
- ///
- /// [link]: #method.set_multicast_loop_v6
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::UdpSocket;
- ///
- /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
- /// socket.set_multicast_loop_v6(false).expect("set_multicast_loop_v6 call failed");
- /// assert_eq!(socket.multicast_loop_v6().unwrap(), false);
- /// ```
- #[stable(feature = "net2_mutators", since = "1.9.0")]
- pub fn multicast_loop_v6(&self) -> io::Result<bool> {
- self.0.multicast_loop_v6()
- }
-
- /// Sets the value for the `IP_TTL` option on this socket.
- ///
- /// This value sets the time-to-live field that is used in every packet sent
- /// from this socket.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::UdpSocket;
- ///
- /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
- /// socket.set_ttl(42).expect("set_ttl call failed");
- /// ```
- #[stable(feature = "net2_mutators", since = "1.9.0")]
- pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
- self.0.set_ttl(ttl)
- }
-
- /// Gets the value of the `IP_TTL` option for this socket.
- ///
- /// For more information about this option, see [`set_ttl`][link].
- ///
- /// [link]: #method.set_ttl
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::UdpSocket;
- ///
- /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
- /// socket.set_ttl(42).expect("set_ttl call failed");
- /// assert_eq!(socket.ttl().unwrap(), 42);
- /// ```
- #[stable(feature = "net2_mutators", since = "1.9.0")]
- pub fn ttl(&self) -> io::Result<u32> {
- self.0.ttl()
- }
-
- /// Executes an operation of the `IP_ADD_MEMBERSHIP` type.
- ///
- /// This function specifies a new multicast group for this socket to join.
- /// The address must be a valid multicast address, and `interface` is the
- /// address of the local interface with which the system should join the
- /// multicast group. If it's equal to `INADDR_ANY` then an appropriate
- /// interface is chosen by the system.
- #[stable(feature = "net2_mutators", since = "1.9.0")]
- pub fn join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> {
- self.0.join_multicast_v4(multiaddr, interface)
- }
-
- /// Executes an operation of the `IPV6_ADD_MEMBERSHIP` type.
- ///
- /// This function specifies a new multicast group for this socket to join.
- /// The address must be a valid multicast address, and `interface` is the
- /// index of the interface to join/leave (or 0 to indicate any interface).
- #[stable(feature = "net2_mutators", since = "1.9.0")]
- pub fn join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
- self.0.join_multicast_v6(multiaddr, interface)
- }
-
- /// Executes an operation of the `IP_DROP_MEMBERSHIP` type.
- ///
- /// For more information about this option, see
- /// [`join_multicast_v4`][link].
- ///
- /// [link]: #method.join_multicast_v4
- #[stable(feature = "net2_mutators", since = "1.9.0")]
- pub fn leave_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> {
- self.0.leave_multicast_v4(multiaddr, interface)
- }
-
- /// Executes an operation of the `IPV6_DROP_MEMBERSHIP` type.
- ///
- /// For more information about this option, see
- /// [`join_multicast_v6`][link].
- ///
- /// [link]: #method.join_multicast_v6
- #[stable(feature = "net2_mutators", since = "1.9.0")]
- pub fn leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
- self.0.leave_multicast_v6(multiaddr, interface)
- }
-
- /// Get the value of the `SO_ERROR` option on this socket.
- ///
- /// This will retrieve the stored error in the underlying socket, clearing
- /// the field in the process. This can be useful for checking errors between
- /// calls.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::UdpSocket;
- ///
- /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
- /// match socket.take_error() {
- /// Ok(Some(error)) => println!("UdpSocket error: {:?}", error),
- /// Ok(None) => println!("No error"),
- /// Err(error) => println!("UdpSocket.take_error failed: {:?}", error),
- /// }
- /// ```
- #[stable(feature = "net2_mutators", since = "1.9.0")]
- pub fn take_error(&self) -> io::Result<Option<io::Error>> {
- self.0.take_error()
- }
-
- /// Connects this UDP socket to a remote address, allowing the `send` and
- /// `recv` syscalls to be used to send data and also applies filters to only
- /// receive data from the specified address.
- ///
- /// If `addr` yields multiple addresses, `connect` will be attempted with
- /// each of the addresses until the underlying OS function returns no
- /// error. Note that usually, a successful `connect` call does not specify
- /// that there is a remote server listening on the port, rather, such an
- /// error would only be detected after the first send. If the OS returns an
- /// error for each of the specified addresses, the error returned from the
- /// last connection attempt (the last address) is returned.
- ///
- /// # Examples
- ///
- /// Create a UDP socket bound to `127.0.0.1:3400` and connect the socket to
- /// `127.0.0.1:8080`:
- ///
- /// ```no_run
- /// use std::net::UdpSocket;
- ///
- /// let socket = UdpSocket::bind("127.0.0.1:3400").expect("couldn't bind to address");
- /// socket.connect("127.0.0.1:8080").expect("connect function failed");
- /// ```
- ///
- /// Unlike in the TCP case, passing an array of addresses to the `connect`
- /// function of a UDP socket is not a useful thing to do: The OS will be
- /// unable to determine whether something is listening on the remote
- /// address without the application sending data.
- #[stable(feature = "net2_mutators", since = "1.9.0")]
- pub fn connect<A: ToSocketAddrs>(&self, addr: A) -> io::Result<()> {
- super::each_addr(addr, |addr| self.0.connect(addr))
- }
-
- /// Sends data on the socket to the remote address to which it is connected.
- ///
- /// The [`connect`] method will connect this socket to a remote address. This
- /// method will fail if the socket is not connected.
- ///
- /// [`connect`]: #method.connect
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::UdpSocket;
- ///
- /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
- /// socket.connect("127.0.0.1:8080").expect("connect function failed");
- /// socket.send(&[0, 1, 2]).expect("couldn't send message");
- /// ```
- #[stable(feature = "net2_mutators", since = "1.9.0")]
- pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
- self.0.send(buf)
- }
-
- /// Receives a single datagram message on the socket from the remote address to
- /// which it is connected. On success, returns the number of bytes read.
- ///
- /// The function must be called with valid byte array `buf` of sufficient size to
- /// hold the message bytes. If a message is too long to fit in the supplied buffer,
- /// excess bytes may be discarded.
- ///
- /// The [`connect`] method will connect this socket to a remote address. This
- /// method will fail if the socket is not connected.
- ///
- /// [`connect`]: #method.connect
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::UdpSocket;
- ///
- /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
- /// socket.connect("127.0.0.1:8080").expect("connect function failed");
- /// let mut buf = [0; 10];
- /// match socket.recv(&mut buf) {
- /// Ok(received) => println!("received {} bytes {:?}", received, &buf[..received]),
- /// Err(e) => println!("recv function failed: {:?}", e),
- /// }
- /// ```
- #[stable(feature = "net2_mutators", since = "1.9.0")]
- pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
- self.0.recv(buf)
- }
-
- /// Receives single datagram on the socket from the remote address to which it is
- /// connected, without removing the message from input queue. On success, returns
- /// the number of bytes peeked.
- ///
- /// The function must be called with valid byte array `buf` of sufficient size to
- /// hold the message bytes. If a message is too long to fit in the supplied buffer,
- /// excess bytes may be discarded.
- ///
- /// Successive calls return the same data. This is accomplished by passing
- /// `MSG_PEEK` as a flag to the underlying `recv` system call.
- ///
- /// Do not use this function to implement busy waiting, instead use `libc::poll` to
- /// synchronize IO events on one or more sockets.
- ///
- /// The [`connect`] method will connect this socket to a remote address. This
- /// method will fail if the socket is not connected.
- ///
- /// [`connect`]: #method.connect
- ///
- /// # Errors
- ///
- /// This method will fail if the socket is not connected. The `connect` method
- /// will connect this socket to a remote address.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::net::UdpSocket;
- ///
- /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
- /// socket.connect("127.0.0.1:8080").expect("connect function failed");
- /// let mut buf = [0; 10];
- /// match socket.peek(&mut buf) {
- /// Ok(received) => println!("received {} bytes", received),
- /// Err(e) => println!("peek function failed: {:?}", e),
- /// }
- /// ```
- #[stable(feature = "peek", since = "1.18.0")]
- pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
- self.0.peek(buf)
- }
-
- /// Moves this UDP socket into or out of nonblocking mode.
- ///
- /// This will result in `recv`, `recv_from`, `send`, and `send_to`
- /// operations becoming nonblocking, i.e. immediately returning from their
- /// calls. If the IO operation is successful, `Ok` is returned and no
- /// further action is required. If the IO operation could not be completed
- /// and needs to be retried, an error with kind
- /// [`io::ErrorKind::WouldBlock`] is returned.
- ///
- /// On Unix platforms, calling this method corresponds to calling `fcntl`
- /// `FIONBIO`. On Windows calling this method corresponds to calling
- /// `ioctlsocket` `FIONBIO`.
- ///
- /// [`io::ErrorKind::WouldBlock`]: ../io/enum.ErrorKind.html#variant.WouldBlock
- ///
- /// # Examples
- ///
- /// Create a UDP socket bound to `127.0.0.1:7878` and read bytes in
- /// nonblocking mode:
- ///
- /// ```no_run
- /// use std::io;
- /// use std::net::UdpSocket;
- ///
- /// let socket = UdpSocket::bind("127.0.0.1:7878").unwrap();
- /// socket.set_nonblocking(true).unwrap();
- ///
- /// # fn wait_for_fd() { unimplemented!() }
- /// let mut buf = [0; 10];
- /// let (num_bytes_read, _) = loop {
- /// match socket.recv_from(&mut buf) {
- /// Ok(n) => break n,
- /// Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
- /// // wait until network socket is ready, typically implemented
- /// // via platform-specific APIs such as epoll or IOCP
- /// wait_for_fd();
- /// }
- /// Err(e) => panic!("encountered IO error: {}", e),
- /// }
- /// };
- /// println!("bytes: {:?}", &buf[..num_bytes_read]);
- /// ```
- #[stable(feature = "net2_mutators", since = "1.9.0")]
- pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
- self.0.set_nonblocking(nonblocking)
- }
-}
-
-impl AsInner<net_imp::UdpSocket> for UdpSocket {
- fn as_inner(&self) -> &net_imp::UdpSocket { &self.0 }
-}
-
-impl FromInner<net_imp::UdpSocket> for UdpSocket {
- fn from_inner(inner: net_imp::UdpSocket) -> UdpSocket { UdpSocket(inner) }
-}
-
-impl IntoInner<net_imp::UdpSocket> for UdpSocket {
- fn into_inner(self) -> net_imp::UdpSocket { self.0 }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl fmt::Debug for UdpSocket {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- self.0.fmt(f)
- }
-}
-
-#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten"))))]
-mod tests {
- use io::ErrorKind;
- use net::*;
- use net::test::{next_test_ip4, next_test_ip6};
- use sync::mpsc::channel;
- use sys_common::AsInner;
- use time::{Instant, Duration};
- use thread;
-
- fn each_ip(f: &mut dyn FnMut(SocketAddr, SocketAddr)) {
- f(next_test_ip4(), next_test_ip4());
- f(next_test_ip6(), next_test_ip6());
- }
-
- macro_rules! t {
- ($e:expr) => {
- match $e {
- Ok(t) => t,
- Err(e) => panic!("received error for `{}`: {}", stringify!($e), e),
- }
- }
- }
-
- #[test]
- fn bind_error() {
- match UdpSocket::bind("1.1.1.1:9999") {
- Ok(..) => panic!(),
- Err(e) => {
- assert_eq!(e.kind(), ErrorKind::AddrNotAvailable)
- }
- }
- }
-
- #[test]
- fn socket_smoke_test_ip4() {
- each_ip(&mut |server_ip, client_ip| {
- let (tx1, rx1) = channel();
- let (tx2, rx2) = channel();
-
- let _t = thread::spawn(move|| {
- let client = t!(UdpSocket::bind(&client_ip));
- rx1.recv().unwrap();
- t!(client.send_to(&[99], &server_ip));
- tx2.send(()).unwrap();
- });
-
- let server = t!(UdpSocket::bind(&server_ip));
- tx1.send(()).unwrap();
- let mut buf = [0];
- let (nread, src) = t!(server.recv_from(&mut buf));
- assert_eq!(nread, 1);
- assert_eq!(buf[0], 99);
- assert_eq!(src, client_ip);
- rx2.recv().unwrap();
- })
- }
-
- #[test]
- fn socket_name_ip4() {
- each_ip(&mut |addr, _| {
- let server = t!(UdpSocket::bind(&addr));
- assert_eq!(addr, t!(server.local_addr()));
- })
- }
-
- #[test]
- fn udp_clone_smoke() {
- each_ip(&mut |addr1, addr2| {
- let sock1 = t!(UdpSocket::bind(&addr1));
- let sock2 = t!(UdpSocket::bind(&addr2));
-
- let _t = thread::spawn(move|| {
- let mut buf = [0, 0];
- assert_eq!(sock2.recv_from(&mut buf).unwrap(), (1, addr1));
- assert_eq!(buf[0], 1);
- t!(sock2.send_to(&[2], &addr1));
- });
-
- let sock3 = t!(sock1.try_clone());
-
- let (tx1, rx1) = channel();
- let (tx2, rx2) = channel();
- let _t = thread::spawn(move|| {
- rx1.recv().unwrap();
- t!(sock3.send_to(&[1], &addr2));
- tx2.send(()).unwrap();
- });
- tx1.send(()).unwrap();
- let mut buf = [0, 0];
- assert_eq!(sock1.recv_from(&mut buf).unwrap(), (1, addr2));
- rx2.recv().unwrap();
- })
- }
-
- #[test]
- fn udp_clone_two_read() {
- each_ip(&mut |addr1, addr2| {
- let sock1 = t!(UdpSocket::bind(&addr1));
- let sock2 = t!(UdpSocket::bind(&addr2));
- let (tx1, rx) = channel();
- let tx2 = tx1.clone();
-
- let _t = thread::spawn(move|| {
- t!(sock2.send_to(&[1], &addr1));
- rx.recv().unwrap();
- t!(sock2.send_to(&[2], &addr1));
- rx.recv().unwrap();
- });
-
- let sock3 = t!(sock1.try_clone());
-
- let (done, rx) = channel();
- let _t = thread::spawn(move|| {
- let mut buf = [0, 0];
- t!(sock3.recv_from(&mut buf));
- tx2.send(()).unwrap();
- done.send(()).unwrap();
- });
- let mut buf = [0, 0];
- t!(sock1.recv_from(&mut buf));
- tx1.send(()).unwrap();
-
- rx.recv().unwrap();
- })
- }
-
- #[test]
- fn udp_clone_two_write() {
- each_ip(&mut |addr1, addr2| {
- let sock1 = t!(UdpSocket::bind(&addr1));
- let sock2 = t!(UdpSocket::bind(&addr2));
-
- let (tx, rx) = channel();
- let (serv_tx, serv_rx) = channel();
-
- let _t = thread::spawn(move|| {
- let mut buf = [0, 1];
- rx.recv().unwrap();
- t!(sock2.recv_from(&mut buf));
- serv_tx.send(()).unwrap();
- });
-
- let sock3 = t!(sock1.try_clone());
-
- let (done, rx) = channel();
- let tx2 = tx.clone();
- let _t = thread::spawn(move|| {
- match sock3.send_to(&[1], &addr2) {
- Ok(..) => { let _ = tx2.send(()); }
- Err(..) => {}
- }
- done.send(()).unwrap();
- });
- match sock1.send_to(&[2], &addr2) {
- Ok(..) => { let _ = tx.send(()); }
- Err(..) => {}
- }
- drop(tx);
-
- rx.recv().unwrap();
- serv_rx.recv().unwrap();
- })
- }
-
- #[test]
- fn debug() {
- let name = if cfg!(windows) {"socket"} else {"fd"};
- let socket_addr = next_test_ip4();
-
- let udpsock = t!(UdpSocket::bind(&socket_addr));
- let udpsock_inner = udpsock.0.socket().as_inner();
- let compare = format!("UdpSocket {{ addr: {:?}, {}: {:?} }}",
- socket_addr, name, udpsock_inner);
- assert_eq!(format!("{:?}", udpsock), compare);
- }
-
- // FIXME: re-enabled bitrig/openbsd/netbsd tests once their socket timeout code
- // no longer has rounding errors.
- #[cfg_attr(any(target_os = "bitrig", target_os = "netbsd", target_os = "openbsd"), ignore)]
- #[test]
- fn timeouts() {
- let addr = next_test_ip4();
-
- let stream = t!(UdpSocket::bind(&addr));
- let dur = Duration::new(15410, 0);
-
- assert_eq!(None, t!(stream.read_timeout()));
-
- t!(stream.set_read_timeout(Some(dur)));
- assert_eq!(Some(dur), t!(stream.read_timeout()));
-
- assert_eq!(None, t!(stream.write_timeout()));
-
- t!(stream.set_write_timeout(Some(dur)));
- assert_eq!(Some(dur), t!(stream.write_timeout()));
-
- t!(stream.set_read_timeout(None));
- assert_eq!(None, t!(stream.read_timeout()));
-
- t!(stream.set_write_timeout(None));
- assert_eq!(None, t!(stream.write_timeout()));
- }
-
- #[test]
- fn test_read_timeout() {
- let addr = next_test_ip4();
-
- let stream = t!(UdpSocket::bind(&addr));
- t!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
-
- let mut buf = [0; 10];
-
- let start = Instant::now();
- let kind = stream.recv_from(&mut buf).err().expect("expected error").kind();
- assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut);
- assert!(start.elapsed() > Duration::from_millis(400));
- }
-
- #[test]
- fn test_read_with_timeout() {
- let addr = next_test_ip4();
-
- let stream = t!(UdpSocket::bind(&addr));
- t!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
-
- t!(stream.send_to(b"hello world", &addr));
-
- let mut buf = [0; 11];
- t!(stream.recv_from(&mut buf));
- assert_eq!(b"hello world", &buf[..]);
-
- let start = Instant::now();
- let kind = stream.recv_from(&mut buf).err().expect("expected error").kind();
- assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut);
- 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();
-
- let socket = t!(UdpSocket::bind(&addr));
- t!(socket.connect(addr));
-
- t!(socket.send(b"hello world"));
-
- let mut buf = [0; 11];
- t!(socket.recv(&mut buf));
- assert_eq!(b"hello world", &buf[..]);
- }
-
- #[test]
- fn connect_send_peek_recv() {
- each_ip(&mut |addr, _| {
- let socket = t!(UdpSocket::bind(&addr));
- t!(socket.connect(addr));
-
- t!(socket.send(b"hello world"));
-
- for _ in 1..3 {
- let mut buf = [0; 11];
- let size = t!(socket.peek(&mut buf));
- assert_eq!(b"hello world", &buf[..]);
- assert_eq!(size, 11);
- }
-
- let mut buf = [0; 11];
- let size = t!(socket.recv(&mut buf));
- assert_eq!(b"hello world", &buf[..]);
- assert_eq!(size, 11);
- })
- }
-
- #[test]
- fn peek_from() {
- each_ip(&mut |addr, _| {
- let socket = t!(UdpSocket::bind(&addr));
- t!(socket.send_to(b"hello world", &addr));
-
- for _ in 1..3 {
- let mut buf = [0; 11];
- let (size, _) = t!(socket.peek_from(&mut buf));
- assert_eq!(b"hello world", &buf[..]);
- assert_eq!(size, 11);
- }
-
- let mut buf = [0; 11];
- let (size, _) = t!(socket.recv_from(&mut buf));
- assert_eq!(b"hello world", &buf[..]);
- assert_eq!(size, 11);
- })
- }
-
- #[test]
- fn ttl() {
- let ttl = 100;
-
- let addr = next_test_ip4();
-
- let stream = t!(UdpSocket::bind(&addr));
-
- t!(stream.set_ttl(ttl));
- assert_eq!(ttl, t!(stream.ttl()));
- }
-
- #[test]
- fn set_nonblocking() {
- each_ip(&mut |addr, _| {
- let socket = t!(UdpSocket::bind(&addr));
-
- t!(socket.set_nonblocking(true));
- t!(socket.set_nonblocking(false));
-
- t!(socket.connect(addr));
-
- t!(socket.set_nonblocking(false));
- t!(socket.set_nonblocking(true));
-
- let mut buf = [0];
- match socket.recv(&mut buf) {
- Ok(_) => panic!("expected error"),
- Err(ref e) if e.kind() == ErrorKind::WouldBlock => {}
- Err(e) => panic!("unexpected error {}", e),
- }
- })
- }
-}