no_std_net/addr.rs
1// Effectively all the code in this repo is copied with permission from Rust's std library.
2// They hold the copyright (http://rust-lang.org/COPYRIGHT) and whatever other rights, but this
3// crate is MIT licensed also, so it's all good.
4
5#[cfg(all(test, not(target_os = "emscripten")))]
6mod tests;
7
8use core::cmp::Ordering;
9use core::fmt::{self, Write};
10use core::hash;
11use core::iter;
12use core::option;
13use core::slice;
14
15use super::helper::WriteHelper;
16use super::{IpAddr, Ipv4Addr, Ipv6Addr};
17
18/// An internet socket address, either IPv4 or IPv6.
19///
20/// Internet socket addresses consist of an [IP address], a 16-bit port number, as well
21/// as possibly some version-dependent additional information. See [`SocketAddrV4`]'s and
22/// [`SocketAddrV6`]'s respective documentation for more details.
23///
24/// [IP address]: IpAddr
25///
26/// # Examples
27///
28/// ```
29/// use no_std_net::{IpAddr, Ipv4Addr, SocketAddr};
30///
31/// let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
32///
33/// assert_eq!("127.0.0.1:8080".parse(), Ok(socket));
34/// assert_eq!(socket.port(), 8080);
35/// assert_eq!(socket.is_ipv4(), true);
36/// ```
37#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
38pub enum SocketAddr {
39 /// An IPv4 socket address.
40 V4(SocketAddrV4),
41 /// An IPv6 socket address.
42 V6(SocketAddrV6),
43}
44
45/// An IPv4 socket address.
46///
47/// IPv4 socket addresses consist of an [`IPv4` address] and a 16-bit port number, as
48/// stated in [IETF RFC 793].
49///
50/// See [`SocketAddr`] for a type encompassing both IPv4 and IPv6 socket addresses.
51///
52/// [IETF RFC 793]: https://tools.ietf.org/html/rfc793
53/// [`IPv4` address]: Ipv4Addr
54///
55/// # Examples
56///
57/// ```
58/// use no_std_net::{Ipv4Addr, SocketAddrV4};
59///
60/// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
61///
62/// assert_eq!("127.0.0.1:8080".parse(), Ok(socket));
63/// assert_eq!(socket.ip(), &Ipv4Addr::new(127, 0, 0, 1));
64/// assert_eq!(socket.port(), 8080);
65/// ```
66#[derive(Copy)]
67pub struct SocketAddrV4 {
68 addr: Ipv4Addr,
69 port: u16,
70}
71
72/// An IPv6 socket address.
73///
74/// IPv6 socket addresses consist of an [`IPv6` address], a 16-bit port number, as well
75/// as fields containing the traffic class, the flow label, and a scope identifier
76/// (see [IETF RFC 2553, Section 3.3] for more details).
77///
78/// See [`SocketAddr`] for a type encompassing both IPv4 and IPv6 socket addresses.
79///
80/// [IETF RFC 2553, Section 3.3]: https://tools.ietf.org/html/rfc2553#section-3.3
81/// [`IPv6` address]: Ipv6Addr
82///
83/// # Examples
84///
85/// ```
86/// use no_std_net::{Ipv6Addr, SocketAddrV6};
87///
88/// let socket = SocketAddrV6::new(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), 8080, 0, 0);
89///
90/// assert_eq!("[2001:db8::1]:8080".parse(), Ok(socket));
91/// assert_eq!(socket.ip(), &Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1));
92/// assert_eq!(socket.port(), 8080);
93/// ```
94#[derive(Copy)]
95pub struct SocketAddrV6 {
96 addr: Ipv6Addr,
97 port: u16,
98 flow_info: u32,
99 scope_id: u32,
100}
101
102impl SocketAddr {
103 /// Creates a new socket address from an [IP address] and a port number.
104 ///
105 /// [IP address]: IpAddr
106 ///
107 /// # Examples
108 ///
109 /// ```
110 /// use no_std_net::{IpAddr, Ipv4Addr, SocketAddr};
111 ///
112 /// let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
113 /// assert_eq!(socket.ip(), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)));
114 /// assert_eq!(socket.port(), 8080);
115 /// ```
116 pub const fn new(ip: IpAddr, port: u16) -> SocketAddr {
117 match ip {
118 IpAddr::V4(a) => SocketAddr::V4(SocketAddrV4::new(a, port)),
119 IpAddr::V6(a) => SocketAddr::V6(SocketAddrV6::new(a, port, 0, 0)),
120 }
121 }
122
123 /// Returns the IP address associated with this socket address.
124 ///
125 /// # Examples
126 ///
127 /// ```
128 /// use no_std_net::{IpAddr, Ipv4Addr, SocketAddr};
129 ///
130 /// let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
131 /// assert_eq!(socket.ip(), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)));
132 /// ```
133 pub const fn ip(&self) -> IpAddr {
134 match *self {
135 SocketAddr::V4(ref a) => IpAddr::V4(*a.ip()),
136 SocketAddr::V6(ref a) => IpAddr::V6(*a.ip()),
137 }
138 }
139
140 /// Changes the IP address associated with this socket address.
141 ///
142 /// # Examples
143 ///
144 /// ```
145 /// use no_std_net::{IpAddr, Ipv4Addr, SocketAddr};
146 ///
147 /// let mut socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
148 /// socket.set_ip(IpAddr::V4(Ipv4Addr::new(10, 10, 0, 1)));
149 /// assert_eq!(socket.ip(), IpAddr::V4(Ipv4Addr::new(10, 10, 0, 1)));
150 /// ```
151 pub fn set_ip(&mut self, new_ip: IpAddr) {
152 // `match (*self, new_ip)` would have us mutate a copy of self only to throw it away.
153 match (self, new_ip) {
154 (&mut SocketAddr::V4(ref mut a), IpAddr::V4(new_ip)) => a.set_ip(new_ip),
155 (&mut SocketAddr::V6(ref mut a), IpAddr::V6(new_ip)) => a.set_ip(new_ip),
156 (self_, new_ip) => *self_ = Self::new(new_ip, self_.port()),
157 }
158 }
159
160 /// Returns the port number associated with this socket address.
161 ///
162 /// # Examples
163 ///
164 /// ```
165 /// use no_std_net::{IpAddr, Ipv4Addr, SocketAddr};
166 ///
167 /// let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
168 /// assert_eq!(socket.port(), 8080);
169 /// ```
170 pub const fn port(&self) -> u16 {
171 match *self {
172 SocketAddr::V4(ref a) => a.port(),
173 SocketAddr::V6(ref a) => a.port(),
174 }
175 }
176
177 /// Changes the port number associated with this socket address.
178 ///
179 /// # Examples
180 ///
181 /// ```
182 /// use no_std_net::{IpAddr, Ipv4Addr, SocketAddr};
183 ///
184 /// let mut socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
185 /// socket.set_port(1025);
186 /// assert_eq!(socket.port(), 1025);
187 /// ```
188 pub fn set_port(&mut self, new_port: u16) {
189 match *self {
190 SocketAddr::V4(ref mut a) => a.set_port(new_port),
191 SocketAddr::V6(ref mut a) => a.set_port(new_port),
192 }
193 }
194
195 /// Returns [`true`] if the [IP address] in this `SocketAddr` is an
196 /// [`IPv4` address], and [`false`] otherwise.
197 ///
198 /// [IP address]: IpAddr
199 /// [`IPv4` address]: IpAddr::V4
200 ///
201 /// # Examples
202 ///
203 /// ```
204 /// use no_std_net::{IpAddr, Ipv4Addr, SocketAddr};
205 ///
206 /// let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
207 /// assert_eq!(socket.is_ipv4(), true);
208 /// assert_eq!(socket.is_ipv6(), false);
209 /// ```
210 pub const fn is_ipv4(&self) -> bool {
211 matches!(*self, SocketAddr::V4(_))
212 }
213
214 /// Returns [`true`] if the [IP address] in this `SocketAddr` is an
215 /// [`IPv6` address], and [`false`] otherwise.
216 ///
217 /// [IP address]: IpAddr
218 /// [`IPv6` address]: IpAddr::V6
219 ///
220 /// # Examples
221 ///
222 /// ```
223 /// use no_std_net::{IpAddr, Ipv6Addr, SocketAddr};
224 ///
225 /// let socket = SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 65535, 0, 1)), 8080);
226 /// assert_eq!(socket.is_ipv4(), false);
227 /// assert_eq!(socket.is_ipv6(), true);
228 /// ```
229 pub const fn is_ipv6(&self) -> bool {
230 matches!(*self, SocketAddr::V6(_))
231 }
232}
233
234impl SocketAddrV4 {
235 /// Creates a new socket address from an [`IPv4` address] and a port number.
236 ///
237 /// [`IPv4` address]: Ipv4Addr
238 ///
239 /// # Examples
240 ///
241 /// ```
242 /// use no_std_net::{SocketAddrV4, Ipv4Addr};
243 ///
244 /// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
245 /// ```
246 pub const fn new(ip: Ipv4Addr, port: u16) -> SocketAddrV4 {
247 SocketAddrV4 {
248 addr: ip,
249 port: port,
250 }
251 }
252
253 /// Returns the IP address associated with this socket address.
254 ///
255 /// # Examples
256 ///
257 /// ```
258 /// use no_std_net::{SocketAddrV4, Ipv4Addr};
259 ///
260 /// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
261 /// assert_eq!(socket.ip(), &Ipv4Addr::new(127, 0, 0, 1));
262 /// ```
263 pub const fn ip(&self) -> &Ipv4Addr {
264 &self.addr
265 }
266
267 /// Changes the IP address associated with this socket address.
268 ///
269 /// # Examples
270 ///
271 /// ```
272 /// use no_std_net::{SocketAddrV4, Ipv4Addr};
273 ///
274 /// let mut socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
275 /// socket.set_ip(Ipv4Addr::new(192, 168, 0, 1));
276 /// assert_eq!(socket.ip(), &Ipv4Addr::new(192, 168, 0, 1));
277 /// ```
278 pub fn set_ip(&mut self, new_ip: Ipv4Addr) {
279 self.addr = new_ip
280 }
281
282 /// Returns the port number associated with this socket address.
283 ///
284 /// # Examples
285 ///
286 /// ```
287 /// use no_std_net::{SocketAddrV4, Ipv4Addr};
288 ///
289 /// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
290 /// assert_eq!(socket.port(), 8080);
291 /// ```
292 pub const fn port(&self) -> u16 {
293 self.port
294 }
295
296 /// Changes the port number associated with this socket address.
297 ///
298 /// # Examples
299 ///
300 /// ```
301 /// use no_std_net::{SocketAddrV4, Ipv4Addr};
302 ///
303 /// let mut socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
304 /// socket.set_port(4242);
305 /// assert_eq!(socket.port(), 4242);
306 /// ```
307 pub fn set_port(&mut self, new_port: u16) {
308 self.port = new_port;
309 }
310}
311
312impl SocketAddrV6 {
313 /// Creates a new socket address from an [`IPv6` address], a 16-bit port number,
314 /// and the `flowinfo` and `scope_id` fields.
315 ///
316 /// For more information on the meaning and layout of the `flowinfo` and `scope_id`
317 /// parameters, see [IETF RFC 2553, Section 3.3].
318 ///
319 /// [IETF RFC 2553, Section 3.3]: https://tools.ietf.org/html/rfc2553#section-3.3
320 /// [`IPv6` address]: Ipv6Addr
321 ///
322 /// # Examples
323 ///
324 /// ```
325 /// use no_std_net::{SocketAddrV6, Ipv6Addr};
326 ///
327 /// let socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 0, 0);
328 /// ```
329 pub const fn new(ip: Ipv6Addr, port: u16, flowinfo: u32, scope_id: u32) -> SocketAddrV6 {
330 SocketAddrV6 {
331 addr: ip,
332 port: port,
333 flow_info: flowinfo,
334 scope_id: scope_id,
335 }
336 }
337
338 /// Returns the IP address associated with this socket address.
339 ///
340 /// # Examples
341 ///
342 /// ```
343 /// use no_std_net::{SocketAddrV6, Ipv6Addr};
344 ///
345 /// let socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 0, 0);
346 /// assert_eq!(socket.ip(), &Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
347 /// ```
348 pub const fn ip(&self) -> &Ipv6Addr {
349 &self.addr
350 }
351
352 /// Changes the IP address associated with this socket address.
353 ///
354 /// # Examples
355 ///
356 /// ```
357 /// use no_std_net::{SocketAddrV6, Ipv6Addr};
358 ///
359 /// let mut socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 0, 0);
360 /// socket.set_ip(Ipv6Addr::new(76, 45, 0, 0, 0, 0, 0, 0));
361 /// assert_eq!(socket.ip(), &Ipv6Addr::new(76, 45, 0, 0, 0, 0, 0, 0));
362 /// ```
363 pub fn set_ip(&mut self, new_ip: Ipv6Addr) {
364 self.addr = new_ip
365 }
366
367 /// Returns the port number associated with this socket address.
368 ///
369 /// # Examples
370 ///
371 /// ```
372 /// use no_std_net::{SocketAddrV6, Ipv6Addr};
373 ///
374 /// let socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 0, 0);
375 /// assert_eq!(socket.port(), 8080);
376 /// ```
377 pub const fn port(&self) -> u16 {
378 self.port
379 }
380
381 /// Changes the port number associated with this socket address.
382 ///
383 /// # Examples
384 ///
385 /// ```
386 /// use no_std_net::{SocketAddrV6, Ipv6Addr};
387 ///
388 /// let mut socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 0, 0);
389 /// socket.set_port(4242);
390 /// assert_eq!(socket.port(), 4242);
391 /// ```
392 pub fn set_port(&mut self, new_port: u16) {
393 self.port = new_port
394 }
395
396 /// Returns the flow information associated with this address.
397 ///
398 /// This information corresponds to the `sin6_flowinfo` field in C's `netinet/in.h`,
399 /// as specified in [IETF RFC 2553, Section 3.3].
400 /// It combines information about the flow label and the traffic class as specified
401 /// in [IETF RFC 2460], respectively [Section 6] and [Section 7].
402 ///
403 /// [IETF RFC 2553, Section 3.3]: https://tools.ietf.org/html/rfc2553#section-3.3
404 /// [IETF RFC 2460]: https://tools.ietf.org/html/rfc2460
405 /// [Section 6]: https://tools.ietf.org/html/rfc2460#section-6
406 /// [Section 7]: https://tools.ietf.org/html/rfc2460#section-7
407 ///
408 /// # Examples
409 ///
410 /// ```
411 /// use no_std_net::{SocketAddrV6, Ipv6Addr};
412 ///
413 /// let socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 10, 0);
414 /// assert_eq!(socket.flowinfo(), 10);
415 /// ```
416 pub const fn flowinfo(&self) -> u32 {
417 self.flow_info
418 }
419
420 /// Changes the flow information associated with this socket address.
421 ///
422 /// See [`SocketAddrV6::flowinfo`]'s documentation for more details.
423 ///
424 /// # Examples
425 ///
426 /// ```
427 /// use no_std_net::{SocketAddrV6, Ipv6Addr};
428 ///
429 /// let mut socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 10, 0);
430 /// socket.set_flowinfo(56);
431 /// assert_eq!(socket.flowinfo(), 56);
432 /// ```
433 pub fn set_flowinfo(&mut self, new_flowinfo: u32) {
434 self.flow_info = new_flowinfo;
435 }
436
437 /// Returns the scope ID associated with this address.
438 ///
439 /// This information corresponds to the `sin6_scope_id` field in C's `netinet/in.h`,
440 /// as specified in [IETF RFC 2553, Section 3.3].
441 ///
442 /// [IETF RFC 2553, Section 3.3]: https://tools.ietf.org/html/rfc2553#section-3.3
443 ///
444 /// # Examples
445 ///
446 /// ```
447 /// use no_std_net::{SocketAddrV6, Ipv6Addr};
448 ///
449 /// let socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 0, 78);
450 /// assert_eq!(socket.scope_id(), 78);
451 /// ```
452 pub const fn scope_id(&self) -> u32 {
453 self.scope_id
454 }
455
456 /// Changes the scope ID associated with this socket address.
457 ///
458 /// See [`SocketAddrV6::scope_id`]'s documentation for more details.
459 ///
460 /// # Examples
461 ///
462 /// ```
463 /// use no_std_net::{SocketAddrV6, Ipv6Addr};
464 ///
465 /// let mut socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 0, 78);
466 /// socket.set_scope_id(42);
467 /// assert_eq!(socket.scope_id(), 42);
468 /// ```
469 pub fn set_scope_id(&mut self, new_scope_id: u32) {
470 self.scope_id = new_scope_id;
471 }
472}
473
474impl From<SocketAddrV4> for SocketAddr {
475 /// Converts a [`SocketAddrV4`] into a [`SocketAddr::V4`].
476 fn from(sock4: SocketAddrV4) -> SocketAddr {
477 SocketAddr::V4(sock4)
478 }
479}
480
481impl From<SocketAddrV6> for SocketAddr {
482 /// Converts a [`SocketAddrV6`] into a [`SocketAddr::V6`].
483 fn from(sock6: SocketAddrV6) -> SocketAddr {
484 SocketAddr::V6(sock6)
485 }
486}
487
488impl<I: Into<IpAddr>> From<(I, u16)> for SocketAddr {
489 /// Converts a tuple struct (Into<[`IpAddr`]>, `u16`) into a [`SocketAddr`].
490 ///
491 /// This conversion creates a [`SocketAddr::V4`] for a [`IpAddr::V4`]
492 /// and creates a [`SocketAddr::V6`] for a [`IpAddr::V6`].
493 ///
494 /// `u16` is treated as port of the newly created [`SocketAddr`].
495 fn from(pieces: (I, u16)) -> SocketAddr {
496 SocketAddr::new(pieces.0.into(), pieces.1)
497 }
498}
499
500impl fmt::Display for SocketAddr {
501 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
502 match *self {
503 SocketAddr::V4(ref a) => a.fmt(f),
504 SocketAddr::V6(ref a) => a.fmt(f),
505 }
506 }
507}
508
509impl fmt::Debug for SocketAddr {
510 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
511 fmt::Display::fmt(self, fmt)
512 }
513}
514
515impl fmt::Display for SocketAddrV4 {
516 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
517 // Fast path: if there's no alignment stuff, write to the output buffer
518 // directly
519 if f.precision().is_none() && f.width().is_none() {
520 write!(f, "{}:{}", self.ip(), self.port())
521 } else {
522 const IPV4_SOCKET_BUF_LEN: usize = (3 * 4) // the segments
523 + 3 // the separators
524 + 1 + 5; // the port
525 let mut buf = [0; IPV4_SOCKET_BUF_LEN];
526 let mut buf_slice = WriteHelper::new(&mut buf[..]);
527
528 // Unwrap is fine because writing to a sufficiently-sized
529 // buffer is infallible
530 write!(buf_slice, "{}:{}", self.ip(), self.port()).unwrap();
531 let len = IPV4_SOCKET_BUF_LEN - buf_slice.into_raw().len();
532
533 // This unsafe is OK because we know what is being written to the buffer
534 let buf = unsafe { core::str::from_utf8_unchecked(&buf[..len]) };
535 f.pad(buf)
536 }
537 }
538}
539
540impl fmt::Debug for SocketAddrV4 {
541 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
542 fmt::Display::fmt(self, fmt)
543 }
544}
545
546impl fmt::Display for SocketAddrV6 {
547 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
548 // Fast path: if there's no alignment stuff, write to the output
549 // buffer directly
550 if f.precision().is_none() && f.width().is_none() {
551 match self.scope_id() {
552 0 => write!(f, "[{}]:{}", self.ip(), self.port()),
553 scope_id => write!(f, "[{}%{}]:{}", self.ip(), scope_id, self.port()),
554 }
555 } else {
556 const IPV6_SOCKET_BUF_LEN: usize = (4 * 8) // The address
557 + 7 // The colon separators
558 + 2 // The brackets
559 + 1 + 10 // The scope id
560 + 1 + 5; // The port
561
562 let mut buf = [0; IPV6_SOCKET_BUF_LEN];
563 let mut buf_slice = WriteHelper::new(&mut buf[..]);
564
565 match self.scope_id() {
566 0 => write!(buf_slice, "[{}]:{}", self.ip(), self.port()),
567 scope_id => write!(buf_slice, "[{}%{}]:{}", self.ip(), scope_id, self.port()),
568 }
569 // Unwrap is fine because writing to a sufficiently-sized
570 // buffer is infallible
571 .unwrap();
572 let len = IPV6_SOCKET_BUF_LEN - buf_slice.into_raw().len();
573
574 // This unsafe is OK because we know what is being written to the buffer
575 let buf = unsafe { core::str::from_utf8_unchecked(&buf[..len]) };
576 f.pad(buf)
577 }
578 }
579}
580
581impl fmt::Debug for SocketAddrV6 {
582 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
583 fmt::Display::fmt(self, fmt)
584 }
585}
586
587impl Clone for SocketAddrV4 {
588 fn clone(&self) -> SocketAddrV4 {
589 *self
590 }
591}
592impl Clone for SocketAddrV6 {
593 fn clone(&self) -> SocketAddrV6 {
594 *self
595 }
596}
597
598impl PartialEq for SocketAddrV4 {
599 fn eq(&self, other: &SocketAddrV4) -> bool {
600 self.port == other.port && self.addr == other.addr
601 }
602}
603impl PartialEq for SocketAddrV6 {
604 fn eq(&self, other: &SocketAddrV6) -> bool {
605 self.port == other.port
606 && self.addr == other.addr
607 && self.flow_info == other.flow_info
608 && self.scope_id == other.scope_id
609 }
610}
611impl Eq for SocketAddrV4 {}
612impl Eq for SocketAddrV6 {}
613
614impl PartialOrd for SocketAddrV4 {
615 fn partial_cmp(&self, other: &SocketAddrV4) -> Option<Ordering> {
616 Some(self.cmp(other))
617 }
618}
619
620impl PartialOrd for SocketAddrV6 {
621 fn partial_cmp(&self, other: &SocketAddrV6) -> Option<Ordering> {
622 Some(self.cmp(other))
623 }
624}
625
626impl Ord for SocketAddrV4 {
627 fn cmp(&self, other: &SocketAddrV4) -> Ordering {
628 self.ip()
629 .cmp(other.ip())
630 .then(self.port().cmp(&other.port()))
631 }
632}
633
634impl Ord for SocketAddrV6 {
635 fn cmp(&self, other: &SocketAddrV6) -> Ordering {
636 self.ip()
637 .cmp(other.ip())
638 .then(self.port().cmp(&other.port()))
639 }
640}
641
642impl hash::Hash for SocketAddrV4 {
643 fn hash<H: hash::Hasher>(&self, s: &mut H) {
644 (self.port, self.addr).hash(s)
645 }
646}
647impl hash::Hash for SocketAddrV6 {
648 fn hash<H: hash::Hasher>(&self, s: &mut H) {
649 (self.port, self.addr, self.flow_info, self.scope_id).hash(s)
650 }
651}
652
653/// A trait for objects which can be converted or resolved to one or more
654/// [`SocketAddr`] values.
655///
656/// This trait is used for generic address resolution when constructing network
657/// objects. By default it is implemented for the following types:
658///
659/// * [`SocketAddr`]: [`to_socket_addrs`] is the identity function.
660///
661/// * [`SocketAddrV4`], [`SocketAddrV6`], `(`[`IpAddr`]`, `[`u16`]`)`,
662/// `(`[`Ipv4Addr`]`, `[`u16`]`)`, `(`[`Ipv6Addr`]`, `[`u16`]`)`:
663/// [`to_socket_addrs`] constructs a [`SocketAddr`] trivially.
664///
665/// * `(`[`&str`]`, `[`u16`]`)`: [`&str`] should be either a string representation
666/// of an [`IpAddr`] address as expected by [`FromStr`] implementation or a host
667/// name. [`u16`] is the port number.
668///
669/// * [`&str`]: the string should be either a string representation of a
670/// [`SocketAddr`] as expected by its [`FromStr`] implementation or a string like
671/// `<host_name>:<port>` pair where `<port>` is a [`u16`] value.
672///
673/// This trait allows constructing network objects like [`TcpStream`] or
674/// [`UdpSocket`] easily with values of various types for the bind/connection
675/// address. It is needed because sometimes one type is more appropriate than
676/// the other: for simple uses a string like `"localhost:12345"` is much nicer
677/// than manual construction of the corresponding [`SocketAddr`], but sometimes
678/// [`SocketAddr`] value is *the* main source of the address, and converting it to
679/// some other type (e.g., a string) just for it to be converted back to
680/// [`SocketAddr`] in constructor methods is pointless.
681///
682/// Addresses returned by the operating system that are not IP addresses are
683/// silently ignored.
684///
685/// [`FromStr`]: core::str::FromStr
686/// [`&str`]: str
687#[cfg_attr(feature = "std", doc = "[`TcpStream`]: std::net::TcpStream")]
688#[cfg_attr(
689 not(feature = "std"),
690 doc = "[`TcpStream`]: https://doc.rust-lang.org/std/net/struct.TcpStream.html"
691)]
692/// [`to_socket_addrs`]: ToSocketAddrs::to_socket_addrs
693#[cfg_attr(feature = "std", doc = "[`UdpSocket`]: std::net::UdpSocket")]
694#[cfg_attr(
695 not(feature = "std"),
696 doc = "[`UdpSocket`]: https://doc.rust-lang.org/std/net/struct.UdpSocket.html"
697)]
698///
699/// # Examples
700///
701/// Creating a [`SocketAddr`] iterator that yields one item:
702///
703/// ```
704/// use no_std_net::{ToSocketAddrs, SocketAddr};
705///
706/// let addr = SocketAddr::from(([127, 0, 0, 1], 443));
707/// let mut addrs_iter = addr.to_socket_addrs().unwrap();
708///
709/// assert_eq!(Some(addr), addrs_iter.next());
710/// assert!(addrs_iter.next().is_none());
711/// ```
712///
713/// Creating a [`SocketAddr`] iterator that yields multiple items:
714///
715/// ```
716/// use no_std_net::{SocketAddr, ToSocketAddrs};
717///
718/// let addr1 = SocketAddr::from(([0, 0, 0, 0], 80));
719/// let addr2 = SocketAddr::from(([127, 0, 0, 1], 443));
720/// let addrs = vec![addr1, addr2];
721///
722/// let mut addrs_iter = (&addrs[..]).to_socket_addrs().unwrap();
723///
724/// assert_eq!(Some(addr1), addrs_iter.next());
725/// assert_eq!(Some(addr2), addrs_iter.next());
726/// assert!(addrs_iter.next().is_none());
727/// ```
728pub trait ToSocketAddrs {
729 /// Returned iterator over socket addresses which this type may correspond
730 /// to.
731 type Iter: Iterator<Item = SocketAddr>;
732
733 /// Converts this object to an iterator of resolved `SocketAddr`s.
734 ///
735 /// The returned iterator may not actually yield any values depending on the
736 /// outcome of any resolution performed.
737 ///
738 /// Note that this function may block the current thread while resolution is
739 /// performed.
740 fn to_socket_addrs(&self) -> Result<Self::Iter, ToSocketAddrError>;
741}
742
743/// This is a placeholder for the core::result::Result type parameter, it is unused.
744#[derive(Debug)]
745pub enum ToSocketAddrError {}
746
747impl ToSocketAddrs for SocketAddr {
748 type Iter = option::IntoIter<SocketAddr>;
749 fn to_socket_addrs(&self) -> Result<option::IntoIter<SocketAddr>, ToSocketAddrError> {
750 Ok(Some(*self).into_iter())
751 }
752}
753
754impl ToSocketAddrs for SocketAddrV4 {
755 type Iter = option::IntoIter<SocketAddr>;
756 fn to_socket_addrs(&self) -> Result<option::IntoIter<SocketAddr>, ToSocketAddrError> {
757 SocketAddr::V4(*self).to_socket_addrs()
758 }
759}
760
761impl ToSocketAddrs for SocketAddrV6 {
762 type Iter = option::IntoIter<SocketAddr>;
763 fn to_socket_addrs(&self) -> Result<option::IntoIter<SocketAddr>, ToSocketAddrError> {
764 SocketAddr::V6(*self).to_socket_addrs()
765 }
766}
767
768impl ToSocketAddrs for (IpAddr, u16) {
769 type Iter = option::IntoIter<SocketAddr>;
770 fn to_socket_addrs(&self) -> Result<option::IntoIter<SocketAddr>, ToSocketAddrError> {
771 let (ip, port) = *self;
772 match ip {
773 IpAddr::V4(ref a) => (*a, port).to_socket_addrs(),
774 IpAddr::V6(ref a) => (*a, port).to_socket_addrs(),
775 }
776 }
777}
778
779impl ToSocketAddrs for (Ipv4Addr, u16) {
780 type Iter = option::IntoIter<SocketAddr>;
781 fn to_socket_addrs(&self) -> Result<option::IntoIter<SocketAddr>, ToSocketAddrError> {
782 let (ip, port) = *self;
783 SocketAddrV4::new(ip, port).to_socket_addrs()
784 }
785}
786
787impl ToSocketAddrs for (Ipv6Addr, u16) {
788 type Iter = option::IntoIter<SocketAddr>;
789 fn to_socket_addrs(&self) -> Result<option::IntoIter<SocketAddr>, ToSocketAddrError> {
790 let (ip, port) = *self;
791 SocketAddrV6::new(ip, port, 0, 0).to_socket_addrs()
792 }
793}
794
795impl<'a> ToSocketAddrs for &'a [SocketAddr] {
796 type Iter = iter::Cloned<slice::Iter<'a, SocketAddr>>;
797
798 fn to_socket_addrs(&self) -> Result<Self::Iter, ToSocketAddrError> {
799 Ok(self.iter().cloned())
800 }
801}
802
803impl<'a, T: ToSocketAddrs + ?Sized> ToSocketAddrs for &'a T {
804 type Iter = T::Iter;
805 fn to_socket_addrs(&self) -> Result<T::Iter, ToSocketAddrError> {
806 (**self).to_socket_addrs()
807 }
808}