std: Add net::IpAddr, destabilize lookup_host
This commits adds back an `IpAddr` enum matching the `SocketAddr` enum, but without a port. The enumeration is `#[unstable]`. The `lookup_host` function and iterator are also destabilized behind a new feature gate due to questions around the semantics of returning `SocketAddr` values.
This commit is contained in:
@@ -15,7 +15,7 @@ use hash;
|
|||||||
use io;
|
use io;
|
||||||
use libc::{self, socklen_t, sa_family_t};
|
use libc::{self, socklen_t, sa_family_t};
|
||||||
use mem;
|
use mem;
|
||||||
use net::{lookup_host, ntoh, hton, Ipv4Addr, Ipv6Addr};
|
use net::{lookup_host, ntoh, hton, IpAddr, Ipv4Addr, Ipv6Addr};
|
||||||
use option;
|
use option;
|
||||||
use sys_common::{FromInner, AsInner, IntoInner};
|
use sys_common::{FromInner, AsInner, IntoInner};
|
||||||
use vec;
|
use vec;
|
||||||
@@ -47,6 +47,15 @@ pub struct SocketAddrV4 { inner: libc::sockaddr_in }
|
|||||||
pub struct SocketAddrV6 { inner: libc::sockaddr_in6 }
|
pub struct SocketAddrV6 { inner: libc::sockaddr_in6 }
|
||||||
|
|
||||||
impl SocketAddr {
|
impl SocketAddr {
|
||||||
|
/// Gets the IP address associated with this socket address.
|
||||||
|
#[unstable(feature = "ip_addr", reason = "recent addition")]
|
||||||
|
pub fn ip(&self) -> IpAddr {
|
||||||
|
match *self {
|
||||||
|
SocketAddr::V4(ref a) => IpAddr::V4(*a.ip()),
|
||||||
|
SocketAddr::V6(ref a) => IpAddr::V6(*a.ip()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Gets the port number associated with this socket address
|
/// Gets the port number associated with this socket address
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn port(&self) -> u16 {
|
pub fn port(&self) -> u16 {
|
||||||
@@ -333,6 +342,18 @@ impl ToSocketAddrs for SocketAddrV6 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[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")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl ToSocketAddrs for (Ipv4Addr, u16) {
|
impl ToSocketAddrs for (Ipv4Addr, u16) {
|
||||||
type Iter = option::IntoIter<SocketAddr>;
|
type Iter = option::IntoIter<SocketAddr>;
|
||||||
|
|||||||
@@ -21,6 +21,16 @@ use libc;
|
|||||||
use sys_common::{AsInner, FromInner};
|
use sys_common::{AsInner, FromInner};
|
||||||
use net::{hton, ntoh};
|
use net::{hton, ntoh};
|
||||||
|
|
||||||
|
/// An IP address, either a IPv4 or IPv6 address.
|
||||||
|
#[unstable(feature = "ip_addr", reason = "recent addition")]
|
||||||
|
#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, PartialOrd, Ord)]
|
||||||
|
pub enum IpAddr {
|
||||||
|
/// Representation of an IPv4 address.
|
||||||
|
V4(Ipv4Addr),
|
||||||
|
/// Representation of an IPv6 address.
|
||||||
|
V6(Ipv6Addr),
|
||||||
|
}
|
||||||
|
|
||||||
/// Representation of an IPv4 address.
|
/// Representation of an IPv4 address.
|
||||||
#[derive(Copy)]
|
#[derive(Copy)]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
@@ -139,6 +149,16 @@ impl Ipv4Addr {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
impl fmt::Display for IpAddr {
|
||||||
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match *self {
|
||||||
|
IpAddr::V4(ref a) => a.fmt(fmt),
|
||||||
|
IpAddr::V6(ref a) => a.fmt(fmt),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl fmt::Display for Ipv4Addr {
|
impl fmt::Display for Ipv4Addr {
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ use io::{self, Error, ErrorKind};
|
|||||||
use num::Int;
|
use num::Int;
|
||||||
use sys_common::net2 as net_imp;
|
use sys_common::net2 as net_imp;
|
||||||
|
|
||||||
pub use self::ip::{Ipv4Addr, Ipv6Addr, Ipv6MulticastScope};
|
pub use self::ip::{IpAddr, Ipv4Addr, Ipv6Addr, Ipv6MulticastScope};
|
||||||
pub use self::addr::{SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs};
|
pub use self::addr::{SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs};
|
||||||
pub use self::tcp::{TcpStream, TcpListener};
|
pub use self::tcp::{TcpStream, TcpListener};
|
||||||
pub use self::udp::UdpSocket;
|
pub use self::udp::UdpSocket;
|
||||||
@@ -74,10 +74,14 @@ fn each_addr<A: ToSocketAddrs, F, T>(addr: A, mut f: F) -> io::Result<T>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// An iterator over `SocketAddr` values returned from a host lookup operation.
|
/// An iterator over `SocketAddr` values returned from a host lookup operation.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[unstable(feature = "lookup_host", reason = "unsure about the returned \
|
||||||
|
iterator and returning socket \
|
||||||
|
addresses")]
|
||||||
pub struct LookupHost(net_imp::LookupHost);
|
pub struct LookupHost(net_imp::LookupHost);
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[unstable(feature = "lookup_host", reason = "unsure about the returned \
|
||||||
|
iterator and returning socket \
|
||||||
|
addresses")]
|
||||||
impl Iterator for LookupHost {
|
impl Iterator for LookupHost {
|
||||||
type Item = io::Result<SocketAddr>;
|
type Item = io::Result<SocketAddr>;
|
||||||
fn next(&mut self) -> Option<io::Result<SocketAddr>> { self.0.next() }
|
fn next(&mut self) -> Option<io::Result<SocketAddr>> { self.0.next() }
|
||||||
@@ -91,7 +95,7 @@ impl Iterator for LookupHost {
|
|||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// # #![feature(net)]
|
/// # #![feature(lookup_host)]
|
||||||
/// use std::net;
|
/// use std::net;
|
||||||
///
|
///
|
||||||
/// # fn foo() -> std::io::Result<()> {
|
/// # fn foo() -> std::io::Result<()> {
|
||||||
@@ -101,7 +105,9 @@ impl Iterator for LookupHost {
|
|||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[unstable(feature = "lookup_host", reason = "unsure about the returned \
|
||||||
|
iterator and returning socket \
|
||||||
|
addresses")]
|
||||||
pub fn lookup_host(host: &str) -> io::Result<LookupHost> {
|
pub fn lookup_host(host: &str) -> io::Result<LookupHost> {
|
||||||
net_imp::lookup_host(host).map(LookupHost)
|
net_imp::lookup_host(host).map(LookupHost)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
use prelude::v1::*;
|
use prelude::v1::*;
|
||||||
|
|
||||||
use io::{self, Error, ErrorKind};
|
use io::{self, Error, ErrorKind};
|
||||||
use net::{ToSocketAddrs, SocketAddr};
|
use net::{ToSocketAddrs, SocketAddr, IpAddr};
|
||||||
use sys_common::net2 as net_imp;
|
use sys_common::net2 as net_imp;
|
||||||
use sys_common::AsInner;
|
use sys_common::AsInner;
|
||||||
|
|
||||||
@@ -116,12 +116,12 @@ impl UdpSocket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Joins a multicast IP address (becomes a member of it)
|
/// Joins a multicast IP address (becomes a member of it)
|
||||||
pub fn join_multicast(&self, multi: &SocketAddr) -> io::Result<()> {
|
pub fn join_multicast(&self, multi: &IpAddr) -> io::Result<()> {
|
||||||
self.0.join_multicast(multi)
|
self.0.join_multicast(multi)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Leaves a multicast IP address (drops membership from it)
|
/// Leaves a multicast IP address (drops membership from it)
|
||||||
pub fn leave_multicast(&self, multi: &SocketAddr) -> io::Result<()> {
|
pub fn leave_multicast(&self, multi: &IpAddr) -> io::Result<()> {
|
||||||
self.0.leave_multicast(multi)
|
self.0.leave_multicast(multi)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ use ffi::CString;
|
|||||||
use io::{self, Error, ErrorKind};
|
use io::{self, Error, ErrorKind};
|
||||||
use libc::{self, c_int, c_char, c_void, socklen_t};
|
use libc::{self, c_int, c_char, c_void, socklen_t};
|
||||||
use mem;
|
use mem;
|
||||||
use net::{SocketAddr, Shutdown};
|
use net::{SocketAddr, Shutdown, IpAddr};
|
||||||
use sys::c;
|
use sys::c;
|
||||||
use sys::net::{cvt, cvt_r, cvt_gai, Socket, init, wrlen_t};
|
use sys::net::{cvt, cvt_r, cvt_gai, Socket, init, wrlen_t};
|
||||||
use sys_common::{AsInner, FromInner, IntoInner};
|
use sys_common::{AsInner, FromInner, IntoInner};
|
||||||
@@ -334,39 +334,39 @@ impl UdpSocket {
|
|||||||
libc::IP_MULTICAST_LOOP, on as c_int)
|
libc::IP_MULTICAST_LOOP, on as c_int)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn join_multicast(&self, multi: &SocketAddr) -> io::Result<()> {
|
pub fn join_multicast(&self, multi: &IpAddr) -> io::Result<()> {
|
||||||
match *multi {
|
match *multi {
|
||||||
SocketAddr::V4(..) => {
|
IpAddr::V4(..) => {
|
||||||
self.set_membership(multi, libc::IP_ADD_MEMBERSHIP)
|
self.set_membership(multi, libc::IP_ADD_MEMBERSHIP)
|
||||||
}
|
}
|
||||||
SocketAddr::V6(..) => {
|
IpAddr::V6(..) => {
|
||||||
self.set_membership(multi, libc::IPV6_ADD_MEMBERSHIP)
|
self.set_membership(multi, libc::IPV6_ADD_MEMBERSHIP)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn leave_multicast(&self, multi: &SocketAddr) -> io::Result<()> {
|
pub fn leave_multicast(&self, multi: &IpAddr) -> io::Result<()> {
|
||||||
match *multi {
|
match *multi {
|
||||||
SocketAddr::V4(..) => {
|
IpAddr::V4(..) => {
|
||||||
self.set_membership(multi, libc::IP_DROP_MEMBERSHIP)
|
self.set_membership(multi, libc::IP_DROP_MEMBERSHIP)
|
||||||
}
|
}
|
||||||
SocketAddr::V6(..) => {
|
IpAddr::V6(..) => {
|
||||||
self.set_membership(multi, libc::IPV6_DROP_MEMBERSHIP)
|
self.set_membership(multi, libc::IPV6_DROP_MEMBERSHIP)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn set_membership(&self, addr: &SocketAddr, opt: c_int) -> io::Result<()> {
|
fn set_membership(&self, addr: &IpAddr, opt: c_int) -> io::Result<()> {
|
||||||
match *addr {
|
match *addr {
|
||||||
SocketAddr::V4(ref addr) => {
|
IpAddr::V4(ref addr) => {
|
||||||
let mreq = libc::ip_mreq {
|
let mreq = libc::ip_mreq {
|
||||||
imr_multiaddr: *addr.ip().as_inner(),
|
imr_multiaddr: *addr.as_inner(),
|
||||||
// interface == INADDR_ANY
|
// interface == INADDR_ANY
|
||||||
imr_interface: libc::in_addr { s_addr: 0x0 },
|
imr_interface: libc::in_addr { s_addr: 0x0 },
|
||||||
};
|
};
|
||||||
setsockopt(&self.inner, libc::IPPROTO_IP, opt, mreq)
|
setsockopt(&self.inner, libc::IPPROTO_IP, opt, mreq)
|
||||||
}
|
}
|
||||||
SocketAddr::V6(ref addr) => {
|
IpAddr::V6(ref addr) => {
|
||||||
let mreq = libc::ip6_mreq {
|
let mreq = libc::ip6_mreq {
|
||||||
ipv6mr_multiaddr: *addr.ip().as_inner(),
|
ipv6mr_multiaddr: *addr.as_inner(),
|
||||||
ipv6mr_interface: 0,
|
ipv6mr_interface: 0,
|
||||||
};
|
};
|
||||||
setsockopt(&self.inner, libc::IPPROTO_IPV6, opt, mreq)
|
setsockopt(&self.inner, libc::IPPROTO_IPV6, opt, mreq)
|
||||||
|
|||||||
Reference in New Issue
Block a user