1// Tests for this module
2#[cfg(all(test, not(target_os = "emscripten")))]
3mod tests;
4
5use crate::io;
6use crate::iter;
7use crate::mem;
8use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr};
9use crate::option;
10use crate::slice;
11use crate::sys::net::netc as c;
12use crate::sys_common::net::LookupHost;
13use crate::sys_common::{FromInner, IntoInner};
14use crate::vec;
15
16#[stable(feature = "rust1", since = "1.0.0")]
17pub use core::net::{SocketAddr, SocketAddrV4, SocketAddrV6};
18
19impl FromInner<c::sockaddr_in> for SocketAddrV4 {
20 fn from_inner(addr: c::sockaddr_in) -> SocketAddrV4 {
21 SocketAddrV4::new(ip:Ipv4Addr::from_inner(addr.sin_addr), port:u16::from_be(addr.sin_port))
22 }
23}
24
25impl FromInner<c::sockaddr_in6> for SocketAddrV6 {
26 fn from_inner(addr: c::sockaddr_in6) -> SocketAddrV6 {
27 SocketAddrV6::new(
28 ip:Ipv6Addr::from_inner(addr.sin6_addr),
29 port:u16::from_be(addr.sin6_port),
30 addr.sin6_flowinfo,
31 addr.sin6_scope_id,
32 )
33 }
34}
35
36impl IntoInner<c::sockaddr_in> for SocketAddrV4 {
37 fn into_inner(self) -> c::sockaddr_in {
38 c::sockaddr_in {
39 sin_family: c::AF_INET as c::sa_family_t,
40 sin_port: self.port().to_be(),
41 sin_addr: self.ip().into_inner(),
42 ..unsafe { mem::zeroed() }
43 }
44 }
45}
46
47impl IntoInner<c::sockaddr_in6> for SocketAddrV6 {
48 fn into_inner(self) -> c::sockaddr_in6 {
49 c::sockaddr_in6 {
50 sin6_family: c::AF_INET6 as c::sa_family_t,
51 sin6_port: self.port().to_be(),
52 sin6_addr: self.ip().into_inner(),
53 sin6_flowinfo: self.flowinfo(),
54 sin6_scope_id: self.scope_id(),
55 ..unsafe { mem::zeroed() }
56 }
57 }
58}
59
60/// A trait for objects which can be converted or resolved to one or more
61/// [`SocketAddr`] values.
62///
63/// This trait is used for generic address resolution when constructing network
64/// objects. By default it is implemented for the following types:
65///
66/// * [`SocketAddr`]: [`to_socket_addrs`] is the identity function.
67///
68/// * [`SocketAddrV4`], [`SocketAddrV6`], <code>([IpAddr], [u16])</code>,
69/// <code>([Ipv4Addr], [u16])</code>, <code>([Ipv6Addr], [u16])</code>:
70/// [`to_socket_addrs`] constructs a [`SocketAddr`] trivially.
71///
72/// * <code>(&[str], [u16])</code>: <code>&[str]</code> should be either a string representation
73/// of an [`IpAddr`] address as expected by [`FromStr`] implementation or a host
74/// name. [`u16`] is the port number.
75///
76/// * <code>&[str]</code>: the string should be either a string representation of a
77/// [`SocketAddr`] as expected by its [`FromStr`] implementation or a string like
78/// `<host_name>:<port>` pair where `<port>` is a [`u16`] value.
79///
80/// This trait allows constructing network objects like [`TcpStream`] or
81/// [`UdpSocket`] easily with values of various types for the bind/connection
82/// address. It is needed because sometimes one type is more appropriate than
83/// the other: for simple uses a string like `"localhost:12345"` is much nicer
84/// than manual construction of the corresponding [`SocketAddr`], but sometimes
85/// [`SocketAddr`] value is *the* main source of the address, and converting it to
86/// some other type (e.g., a string) just for it to be converted back to
87/// [`SocketAddr`] in constructor methods is pointless.
88///
89/// Addresses returned by the operating system that are not IP addresses are
90/// silently ignored.
91///
92/// [`FromStr`]: crate::str::FromStr "std::str::FromStr"
93/// [`TcpStream`]: crate::net::TcpStream "net::TcpStream"
94/// [`to_socket_addrs`]: ToSocketAddrs::to_socket_addrs
95/// [`UdpSocket`]: crate::net::UdpSocket "net::UdpSocket"
96///
97/// # Examples
98///
99/// Creating a [`SocketAddr`] iterator that yields one item:
100///
101/// ```
102/// use std::net::{ToSocketAddrs, SocketAddr};
103///
104/// let addr = SocketAddr::from(([127, 0, 0, 1], 443));
105/// let mut addrs_iter = addr.to_socket_addrs().unwrap();
106///
107/// assert_eq!(Some(addr), addrs_iter.next());
108/// assert!(addrs_iter.next().is_none());
109/// ```
110///
111/// Creating a [`SocketAddr`] iterator from a hostname:
112///
113/// ```no_run
114/// use std::net::{SocketAddr, ToSocketAddrs};
115///
116/// // assuming 'localhost' resolves to 127.0.0.1
117/// let mut addrs_iter = "localhost:443".to_socket_addrs().unwrap();
118/// assert_eq!(addrs_iter.next(), Some(SocketAddr::from(([127, 0, 0, 1], 443))));
119/// assert!(addrs_iter.next().is_none());
120///
121/// // assuming 'foo' does not resolve
122/// assert!("foo:443".to_socket_addrs().is_err());
123/// ```
124///
125/// Creating a [`SocketAddr`] iterator that yields multiple items:
126///
127/// ```
128/// use std::net::{SocketAddr, ToSocketAddrs};
129///
130/// let addr1 = SocketAddr::from(([0, 0, 0, 0], 80));
131/// let addr2 = SocketAddr::from(([127, 0, 0, 1], 443));
132/// let addrs = vec![addr1, addr2];
133///
134/// let mut addrs_iter = (&addrs[..]).to_socket_addrs().unwrap();
135///
136/// assert_eq!(Some(addr1), addrs_iter.next());
137/// assert_eq!(Some(addr2), addrs_iter.next());
138/// assert!(addrs_iter.next().is_none());
139/// ```
140///
141/// Attempting to create a [`SocketAddr`] iterator from an improperly formatted
142/// socket address `&str` (missing the port):
143///
144/// ```
145/// use std::io;
146/// use std::net::ToSocketAddrs;
147///
148/// let err = "127.0.0.1".to_socket_addrs().unwrap_err();
149/// assert_eq!(err.kind(), io::ErrorKind::InvalidInput);
150/// ```
151///
152/// [`TcpStream::connect`] is an example of an function that utilizes
153/// `ToSocketAddrs` as a trait bound on its parameter in order to accept
154/// different types:
155///
156/// ```no_run
157/// use std::net::{TcpStream, Ipv4Addr};
158///
159/// let stream = TcpStream::connect(("127.0.0.1", 443));
160/// // or
161/// let stream = TcpStream::connect("127.0.0.1:443");
162/// // or
163/// let stream = TcpStream::connect((Ipv4Addr::new(127, 0, 0, 1), 443));
164/// ```
165///
166/// [`TcpStream::connect`]: crate::net::TcpStream::connect
167#[stable(feature = "rust1", since = "1.0.0")]
168pub trait ToSocketAddrs {
169 /// Returned iterator over socket addresses which this type may correspond
170 /// to.
171 #[stable(feature = "rust1", since = "1.0.0")]
172 type Iter: Iterator<Item = SocketAddr>;
173
174 /// Converts this object to an iterator of resolved [`SocketAddr`]s.
175 ///
176 /// The returned iterator might not actually yield any values depending on the
177 /// outcome of any resolution performed.
178 ///
179 /// Note that this function may block the current thread while resolution is
180 /// performed.
181 #[stable(feature = "rust1", since = "1.0.0")]
182 fn to_socket_addrs(&self) -> io::Result<Self::Iter>;
183}
184
185#[stable(feature = "rust1", since = "1.0.0")]
186impl ToSocketAddrs for SocketAddr {
187 type Iter = option::IntoIter<SocketAddr>;
188 fn to_socket_addrs(&self) -> io::Result<option::IntoIter<SocketAddr>> {
189 Ok(Some(*self).into_iter())
190 }
191}
192
193#[stable(feature = "rust1", since = "1.0.0")]
194impl ToSocketAddrs for SocketAddrV4 {
195 type Iter = option::IntoIter<SocketAddr>;
196 fn to_socket_addrs(&self) -> io::Result<option::IntoIter<SocketAddr>> {
197 SocketAddr::V4(*self).to_socket_addrs()
198 }
199}
200
201#[stable(feature = "rust1", since = "1.0.0")]
202impl ToSocketAddrs for SocketAddrV6 {
203 type Iter = option::IntoIter<SocketAddr>;
204 fn to_socket_addrs(&self) -> io::Result<option::IntoIter<SocketAddr>> {
205 SocketAddr::V6(*self).to_socket_addrs()
206 }
207}
208
209#[stable(feature = "rust1", since = "1.0.0")]
210impl ToSocketAddrs for (IpAddr, u16) {
211 type Iter = option::IntoIter<SocketAddr>;
212 fn to_socket_addrs(&self) -> io::Result<option::IntoIter<SocketAddr>> {
213 let (ip: IpAddr, port: u16) = *self;
214 match ip {
215 IpAddr::V4(ref a: &Ipv4Addr) => (*a, port).to_socket_addrs(),
216 IpAddr::V6(ref a: &Ipv6Addr) => (*a, port).to_socket_addrs(),
217 }
218 }
219}
220
221#[stable(feature = "rust1", since = "1.0.0")]
222impl ToSocketAddrs for (Ipv4Addr, u16) {
223 type Iter = option::IntoIter<SocketAddr>;
224 fn to_socket_addrs(&self) -> io::Result<option::IntoIter<SocketAddr>> {
225 let (ip: Ipv4Addr, port: u16) = *self;
226 SocketAddrV4::new(ip, port).to_socket_addrs()
227 }
228}
229
230#[stable(feature = "rust1", since = "1.0.0")]
231impl ToSocketAddrs for (Ipv6Addr, u16) {
232 type Iter = option::IntoIter<SocketAddr>;
233 fn to_socket_addrs(&self) -> io::Result<option::IntoIter<SocketAddr>> {
234 let (ip: Ipv6Addr, port: u16) = *self;
235 SocketAddrV6::new(ip, port, flowinfo:0, scope_id:0).to_socket_addrs()
236 }
237}
238
239fn resolve_socket_addr(lh: LookupHost) -> io::Result<vec::IntoIter<SocketAddr>> {
240 let p: u16 = lh.port();
241 let v: Vec<_> = lhimpl Iterator
242 .map(|mut a: SocketAddr| {
243 a.set_port(new_port:p);
244 a
245 })
246 .collect();
247 Ok(v.into_iter())
248}
249
250#[stable(feature = "rust1", since = "1.0.0")]
251impl ToSocketAddrs for (&str, u16) {
252 type Iter = vec::IntoIter<SocketAddr>;
253 fn to_socket_addrs(&self) -> io::Result<vec::IntoIter<SocketAddr>> {
254 let (host: &str, port: u16) = *self;
255
256 // try to parse the host as a regular IP address first
257 if let Ok(addr: Ipv4Addr) = host.parse::<Ipv4Addr>() {
258 let addr: SocketAddrV4 = SocketAddrV4::new(ip:addr, port);
259 return Ok(vec![SocketAddr::V4(addr)].into_iter());
260 }
261 if let Ok(addr: Ipv6Addr) = host.parse::<Ipv6Addr>() {
262 let addr: SocketAddrV6 = SocketAddrV6::new(ip:addr, port, flowinfo:0, scope_id:0);
263 return Ok(vec![SocketAddr::V6(addr)].into_iter());
264 }
265
266 resolve_socket_addr((host, port).try_into()?)
267 }
268}
269
270#[stable(feature = "string_u16_to_socket_addrs", since = "1.46.0")]
271impl ToSocketAddrs for (String, u16) {
272 type Iter = vec::IntoIter<SocketAddr>;
273 fn to_socket_addrs(&self) -> io::Result<vec::IntoIter<SocketAddr>> {
274 (&*self.0, self.1).to_socket_addrs()
275 }
276}
277
278// accepts strings like 'localhost:12345'
279#[stable(feature = "rust1", since = "1.0.0")]
280impl ToSocketAddrs for str {
281 type Iter = vec::IntoIter<SocketAddr>;
282 fn to_socket_addrs(&self) -> io::Result<vec::IntoIter<SocketAddr>> {
283 // try to parse as a regular SocketAddr first
284 if let Ok(addr: SocketAddr) = self.parse() {
285 return Ok(vec![addr].into_iter());
286 }
287
288 resolve_socket_addr(self.try_into()?)
289 }
290}
291
292#[stable(feature = "slice_to_socket_addrs", since = "1.8.0")]
293impl<'a> ToSocketAddrs for &'a [SocketAddr] {
294 type Iter = iter::Cloned<slice::Iter<'a, SocketAddr>>;
295
296 fn to_socket_addrs(&self) -> io::Result<Self::Iter> {
297 Ok(self.iter().cloned())
298 }
299}
300
301#[stable(feature = "rust1", since = "1.0.0")]
302impl<T: ToSocketAddrs + ?Sized> ToSocketAddrs for &T {
303 type Iter = T::Iter;
304 fn to_socket_addrs(&self) -> io::Result<T::Iter> {
305 (**self).to_socket_addrs()
306 }
307}
308
309#[stable(feature = "string_to_socket_addrs", since = "1.16.0")]
310impl ToSocketAddrs for String {
311 type Iter = vec::IntoIter<SocketAddr>;
312 fn to_socket_addrs(&self) -> io::Result<vec::IntoIter<SocketAddr>> {
313 (&**self).to_socket_addrs()
314 }
315}
316