1 //! The following is derived from Rust's
2 //! library/std/src/net/socket_addr.rs at revision
3 //! f7e8ba28a4785e698a55fb95e4b3e803302de0ff.
4 //!
5 //! All code in this file is licensed MIT or Apache 2.0 at your option.
6 //!
7 //! This defines `SocketAddr`, `SocketAddrV4`, and `SocketAddrV6` in a
8 //! platform-independent way. It is not the native representation.
9 
10 #![allow(unsafe_code)]
11 
12 use crate::net::ip::{IpAddr, Ipv4Addr, Ipv6Addr};
13 use core::cmp::Ordering;
14 use core::hash;
15 
16 /// An internet socket address, either IPv4 or IPv6.
17 ///
18 /// Internet socket addresses consist of an [IP address], a 16-bit port number, as well
19 /// as possibly some version-dependent additional information. See [`SocketAddrV4`]'s and
20 /// [`SocketAddrV6`]'s respective documentation for more details.
21 ///
22 /// The size of a `SocketAddr` instance may vary depending on the target operating
23 /// system.
24 ///
25 /// [IP address]: IpAddr
26 ///
27 /// # Examples
28 ///
29 /// ```
30 /// use std::net::{IpAddr, Ipv4Addr, SocketAddr};
31 ///
32 /// let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
33 ///
34 /// assert_eq!("127.0.0.1:8080".parse(), Ok(socket));
35 /// assert_eq!(socket.port(), 8080);
36 /// assert_eq!(socket.is_ipv4(), true);
37 /// ```
38 #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
39 #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))]
40 pub enum SocketAddr {
41     /// An IPv4 socket address.
42     #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))]
43     V4(#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] SocketAddrV4),
44     /// An IPv6 socket address.
45     #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))]
46     V6(#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] SocketAddrV6),
47 }
48 
49 /// An IPv4 socket address.
50 ///
51 /// IPv4 socket addresses consist of an [`IPv4` address] and a 16-bit port number, as
52 /// stated in [IETF RFC 793].
53 ///
54 /// See [`SocketAddr`] for a type encompassing both IPv4 and IPv6 socket addresses.
55 ///
56 /// The size of a `SocketAddrV4` struct may vary depending on the target operating
57 /// system. Do not assume that this type has the same memory layout as the underlying
58 /// system representation.
59 ///
60 /// [IETF RFC 793]: https://tools.ietf.org/html/rfc793
61 /// [`IPv4` address]: Ipv4Addr
62 ///
63 /// # Examples
64 ///
65 /// ```
66 /// use std::net::{Ipv4Addr, SocketAddrV4};
67 ///
68 /// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
69 ///
70 /// assert_eq!("127.0.0.1:8080".parse(), Ok(socket));
71 /// assert_eq!(socket.ip(), &Ipv4Addr::new(127, 0, 0, 1));
72 /// assert_eq!(socket.port(), 8080);
73 /// ```
74 #[derive(Copy, Clone, Eq, PartialEq)]
75 #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))]
76 pub struct SocketAddrV4 {
77     ip: Ipv4Addr,
78     port: u16,
79 }
80 
81 /// An IPv6 socket address.
82 ///
83 /// IPv6 socket addresses consist of an [`IPv6` address], a 16-bit port number, as well
84 /// as fields containing the traffic class, the flow label, and a scope identifier
85 /// (see [IETF RFC 2553, Section 3.3] for more details).
86 ///
87 /// See [`SocketAddr`] for a type encompassing both IPv4 and IPv6 socket addresses.
88 ///
89 /// The size of a `SocketAddrV6` struct may vary depending on the target operating
90 /// system. Do not assume that this type has the same memory layout as the underlying
91 /// system representation.
92 ///
93 /// [IETF RFC 2553, Section 3.3]: https://tools.ietf.org/html/rfc2553#section-3.3
94 /// [`IPv6` address]: Ipv6Addr
95 ///
96 /// # Examples
97 ///
98 /// ```
99 /// use std::net::{Ipv6Addr, SocketAddrV6};
100 ///
101 /// let socket = SocketAddrV6::new(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), 8080, 0, 0);
102 ///
103 /// assert_eq!("[2001:db8::1]:8080".parse(), Ok(socket));
104 /// assert_eq!(socket.ip(), &Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1));
105 /// assert_eq!(socket.port(), 8080);
106 /// ```
107 #[derive(Copy, Clone, Eq, PartialEq)]
108 #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))]
109 pub struct SocketAddrV6 {
110     ip: Ipv6Addr,
111     port: u16,
112     flowinfo: u32,
113     scope_id: u32,
114 }
115 
116 impl SocketAddr {
117     /// Creates a new socket address from an [IP address] and a port number.
118     ///
119     /// [IP address]: IpAddr
120     ///
121     /// # Examples
122     ///
123     /// ```
124     /// use std::net::{IpAddr, Ipv4Addr, SocketAddr};
125     ///
126     /// let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
127     /// assert_eq!(socket.ip(), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)));
128     /// assert_eq!(socket.port(), 8080);
129     /// ```
130     #[cfg_attr(staged_api, stable(feature = "ip_addr", since = "1.7.0"))]
131     #[must_use]
132     #[cfg_attr(
133         staged_api,
134         rustc_const_unstable(feature = "const_socketaddr", issue = "82485")
135     )]
136     pub const fn new(ip: IpAddr, port: u16) -> SocketAddr {
137         match ip {
138             IpAddr::V4(a) => SocketAddr::V4(SocketAddrV4::new(a, port)),
139             IpAddr::V6(a) => SocketAddr::V6(SocketAddrV6::new(a, port, 0, 0)),
140         }
141     }
142 
143     /// Returns the IP address associated with this socket address.
144     ///
145     /// # Examples
146     ///
147     /// ```
148     /// use std::net::{IpAddr, Ipv4Addr, SocketAddr};
149     ///
150     /// let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
151     /// assert_eq!(socket.ip(), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)));
152     /// ```
153     #[must_use]
154     #[cfg_attr(staged_api, stable(feature = "ip_addr", since = "1.7.0"))]
155     #[cfg_attr(
156         staged_api,
157         rustc_const_unstable(feature = "const_socketaddr", issue = "82485")
158     )]
159     pub const fn ip(&self) -> IpAddr {
160         match *self {
161             SocketAddr::V4(ref a) => IpAddr::V4(*a.ip()),
162             SocketAddr::V6(ref a) => IpAddr::V6(*a.ip()),
163         }
164     }
165 
166     /// Changes the IP address associated with this socket address.
167     ///
168     /// # Examples
169     ///
170     /// ```
171     /// use std::net::{IpAddr, Ipv4Addr, SocketAddr};
172     ///
173     /// let mut socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
174     /// socket.set_ip(IpAddr::V4(Ipv4Addr::new(10, 10, 0, 1)));
175     /// assert_eq!(socket.ip(), IpAddr::V4(Ipv4Addr::new(10, 10, 0, 1)));
176     /// ```
177     #[cfg_attr(staged_api, stable(feature = "sockaddr_setters", since = "1.9.0"))]
set_ipnull178     pub fn set_ip(&mut self, new_ip: IpAddr) {
179         // `match (*self, new_ip)` would have us mutate a copy of self only to throw it away.
180         match (self, new_ip) {
181             (&mut SocketAddr::V4(ref mut a), IpAddr::V4(new_ip)) => a.set_ip(new_ip),
182             (&mut SocketAddr::V6(ref mut a), IpAddr::V6(new_ip)) => a.set_ip(new_ip),
183             (self_, new_ip) => *self_ = Self::new(new_ip, self_.port()),
184         }
185     }
186 
187     /// Returns the port number associated with this socket address.
188     ///
189     /// # Examples
190     ///
191     /// ```
192     /// use std::net::{IpAddr, Ipv4Addr, SocketAddr};
193     ///
194     /// let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
195     /// assert_eq!(socket.port(), 8080);
196     /// ```
197     #[must_use]
198     #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))]
199     #[cfg_attr(
200         staged_api,
201         rustc_const_unstable(feature = "const_socketaddr", issue = "82485")
202     )]
203     pub const fn port(&self) -> u16 {
204         match *self {
205             SocketAddr::V4(ref a) => a.port(),
206             SocketAddr::V6(ref a) => a.port(),
207         }
208     }
209 
210     /// Changes the port number associated with this socket address.
211     ///
212     /// # Examples
213     ///
214     /// ```
215     /// use std::net::{IpAddr, Ipv4Addr, SocketAddr};
216     ///
217     /// let mut socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
218     /// socket.set_port(1025);
219     /// assert_eq!(socket.port(), 1025);
220     /// ```
221     #[cfg_attr(staged_api, stable(feature = "sockaddr_setters", since = "1.9.0"))]
set_portnull222     pub fn set_port(&mut self, new_port: u16) {
223         match *self {
224             SocketAddr::V4(ref mut a) => a.set_port(new_port),
225             SocketAddr::V6(ref mut a) => a.set_port(new_port),
226         }
227     }
228 
229     /// Returns [`true`] if the [IP address] in this `SocketAddr` is an
230     /// [`IPv4` address], and [`false`] otherwise.
231     ///
232     /// [IP address]: IpAddr
233     /// [`IPv4` address]: IpAddr::V4
234     ///
235     /// # Examples
236     ///
237     /// ```
238     /// use std::net::{IpAddr, Ipv4Addr, SocketAddr};
239     ///
240     /// let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
241     /// assert_eq!(socket.is_ipv4(), true);
242     /// assert_eq!(socket.is_ipv6(), false);
243     /// ```
244     #[must_use]
245     #[cfg_attr(staged_api, stable(feature = "sockaddr_checker", since = "1.16.0"))]
246     #[cfg_attr(
247         staged_api,
248         rustc_const_unstable(feature = "const_socketaddr", issue = "82485")
249     )]
250     pub const fn is_ipv4(&self) -> bool {
251         matches!(*self, SocketAddr::V4(_))
252     }
253 
254     /// Returns [`true`] if the [IP address] in this `SocketAddr` is an
255     /// [`IPv6` address], and [`false`] otherwise.
256     ///
257     /// [IP address]: IpAddr
258     /// [`IPv6` address]: IpAddr::V6
259     ///
260     /// # Examples
261     ///
262     /// ```
263     /// use std::net::{IpAddr, Ipv6Addr, SocketAddr};
264     ///
265     /// let socket = SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 65535, 0, 1)), 8080);
266     /// assert_eq!(socket.is_ipv4(), false);
267     /// assert_eq!(socket.is_ipv6(), true);
268     /// ```
269     #[must_use]
270     #[cfg_attr(staged_api, stable(feature = "sockaddr_checker", since = "1.16.0"))]
271     #[cfg_attr(
272         staged_api,
273         rustc_const_unstable(feature = "const_socketaddr", issue = "82485")
274     )]
275     pub const fn is_ipv6(&self) -> bool {
276         matches!(*self, SocketAddr::V6(_))
277     }
278 }
279 
280 impl SocketAddrV4 {
281     /// Creates a new socket address from an [`IPv4` address] and a port number.
282     ///
283     /// [`IPv4` address]: Ipv4Addr
284     ///
285     /// # Examples
286     ///
287     /// ```
288     /// use std::net::{SocketAddrV4, Ipv4Addr};
289     ///
290     /// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
291     /// ```
292     #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))]
293     #[must_use]
294     #[cfg_attr(
295         staged_api,
296         rustc_const_unstable(feature = "const_socketaddr", issue = "82485")
297     )]
298     pub const fn new(ip: Ipv4Addr, port: u16) -> SocketAddrV4 {
299         SocketAddrV4 { ip, port }
300     }
301 
302     /// Returns the IP address associated with this socket address.
303     ///
304     /// # Examples
305     ///
306     /// ```
307     /// use std::net::{SocketAddrV4, Ipv4Addr};
308     ///
309     /// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
310     /// assert_eq!(socket.ip(), &Ipv4Addr::new(127, 0, 0, 1));
311     /// ```
312     #[must_use]
313     #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))]
314     #[cfg_attr(
315         staged_api,
316         rustc_const_unstable(feature = "const_socketaddr", issue = "82485")
317     )]
318     pub const fn ip(&self) -> &Ipv4Addr {
319         &self.ip
320     }
321 
322     /// Changes the IP address associated with this socket address.
323     ///
324     /// # Examples
325     ///
326     /// ```
327     /// use std::net::{SocketAddrV4, Ipv4Addr};
328     ///
329     /// let mut socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
330     /// socket.set_ip(Ipv4Addr::new(192, 168, 0, 1));
331     /// assert_eq!(socket.ip(), &Ipv4Addr::new(192, 168, 0, 1));
332     /// ```
333     #[cfg_attr(staged_api, stable(feature = "sockaddr_setters", since = "1.9.0"))]
set_ipnull334     pub fn set_ip(&mut self, new_ip: Ipv4Addr) {
335         self.ip = new_ip;
336     }
337 
338     /// Returns the port number associated with this socket address.
339     ///
340     /// # Examples
341     ///
342     /// ```
343     /// use std::net::{SocketAddrV4, Ipv4Addr};
344     ///
345     /// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
346     /// assert_eq!(socket.port(), 8080);
347     /// ```
348     #[must_use]
349     #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))]
350     #[cfg_attr(
351         staged_api,
352         rustc_const_unstable(feature = "const_socketaddr", issue = "82485")
353     )]
354     pub const fn port(&self) -> u16 {
355         self.port
356     }
357 
358     /// Changes the port number associated with this socket address.
359     ///
360     /// # Examples
361     ///
362     /// ```
363     /// use std::net::{SocketAddrV4, Ipv4Addr};
364     ///
365     /// let mut socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
366     /// socket.set_port(4242);
367     /// assert_eq!(socket.port(), 4242);
368     /// ```
369     #[cfg_attr(staged_api, stable(feature = "sockaddr_setters", since = "1.9.0"))]
set_portnull370     pub fn set_port(&mut self, new_port: u16) {
371         self.port = new_port;
372     }
373 }
374 
375 impl SocketAddrV6 {
376     /// Creates a new socket address from an [`IPv6` address], a 16-bit port number,
377     /// and the `flowinfo` and `scope_id` fields.
378     ///
379     /// For more information on the meaning and layout of the `flowinfo` and `scope_id`
380     /// parameters, see [IETF RFC 2553, Section 3.3].
381     ///
382     /// [IETF RFC 2553, Section 3.3]: https://tools.ietf.org/html/rfc2553#section-3.3
383     /// [`IPv6` address]: Ipv6Addr
384     ///
385     /// # Examples
386     ///
387     /// ```
388     /// use std::net::{SocketAddrV6, Ipv6Addr};
389     ///
390     /// let socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 0, 0);
391     /// ```
392     #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))]
393     #[must_use]
394     #[cfg_attr(
395         staged_api,
396         rustc_const_unstable(feature = "const_socketaddr", issue = "82485")
397     )]
398     pub const fn new(ip: Ipv6Addr, port: u16, flowinfo: u32, scope_id: u32) -> SocketAddrV6 {
399         SocketAddrV6 {
400             ip,
401             port,
402             flowinfo,
403             scope_id,
404         }
405     }
406 
407     /// Returns the IP address associated with this socket address.
408     ///
409     /// # Examples
410     ///
411     /// ```
412     /// use std::net::{SocketAddrV6, Ipv6Addr};
413     ///
414     /// let socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 0, 0);
415     /// assert_eq!(socket.ip(), &Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
416     /// ```
417     #[must_use]
418     #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))]
419     #[cfg_attr(
420         staged_api,
421         rustc_const_unstable(feature = "const_socketaddr", issue = "82485")
422     )]
423     pub const fn ip(&self) -> &Ipv6Addr {
424         &self.ip
425     }
426 
427     /// Changes the IP address associated with this socket address.
428     ///
429     /// # Examples
430     ///
431     /// ```
432     /// use std::net::{SocketAddrV6, Ipv6Addr};
433     ///
434     /// let mut socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 0, 0);
435     /// socket.set_ip(Ipv6Addr::new(76, 45, 0, 0, 0, 0, 0, 0));
436     /// assert_eq!(socket.ip(), &Ipv6Addr::new(76, 45, 0, 0, 0, 0, 0, 0));
437     /// ```
438     #[cfg_attr(staged_api, stable(feature = "sockaddr_setters", since = "1.9.0"))]
set_ipnull439     pub fn set_ip(&mut self, new_ip: Ipv6Addr) {
440         self.ip = new_ip;
441     }
442 
443     /// Returns the port number associated with this socket address.
444     ///
445     /// # Examples
446     ///
447     /// ```
448     /// use std::net::{SocketAddrV6, Ipv6Addr};
449     ///
450     /// let socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 0, 0);
451     /// assert_eq!(socket.port(), 8080);
452     /// ```
453     #[must_use]
454     #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))]
455     #[cfg_attr(
456         staged_api,
457         rustc_const_unstable(feature = "const_socketaddr", issue = "82485")
458     )]
459     pub const fn port(&self) -> u16 {
460         self.port
461     }
462 
463     /// Changes the port number associated with this socket address.
464     ///
465     /// # Examples
466     ///
467     /// ```
468     /// use std::net::{SocketAddrV6, Ipv6Addr};
469     ///
470     /// let mut socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 0, 0);
471     /// socket.set_port(4242);
472     /// assert_eq!(socket.port(), 4242);
473     /// ```
474     #[cfg_attr(staged_api, stable(feature = "sockaddr_setters", since = "1.9.0"))]
set_portnull475     pub fn set_port(&mut self, new_port: u16) {
476         self.port = new_port;
477     }
478 
479     /// Returns the flow information associated with this address.
480     ///
481     /// This information corresponds to the `sin6_flowinfo` field in C's `netinet/in.h`,
482     /// as specified in [IETF RFC 2553, Section 3.3].
483     /// It combines information about the flow label and the traffic class as specified
484     /// in [IETF RFC 2460], respectively [Section 6] and [Section 7].
485     ///
486     /// [IETF RFC 2553, Section 3.3]: https://tools.ietf.org/html/rfc2553#section-3.3
487     /// [IETF RFC 2460]: https://tools.ietf.org/html/rfc2460
488     /// [Section 6]: https://tools.ietf.org/html/rfc2460#section-6
489     /// [Section 7]: https://tools.ietf.org/html/rfc2460#section-7
490     ///
491     /// # Examples
492     ///
493     /// ```
494     /// use std::net::{SocketAddrV6, Ipv6Addr};
495     ///
496     /// let socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 10, 0);
497     /// assert_eq!(socket.flowinfo(), 10);
498     /// ```
499     #[must_use]
500     #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))]
501     #[cfg_attr(
502         staged_api,
503         rustc_const_unstable(feature = "const_socketaddr", issue = "82485")
504     )]
505     pub const fn flowinfo(&self) -> u32 {
506         self.flowinfo
507     }
508 
509     /// Changes the flow information associated with this socket address.
510     ///
511     /// See [`SocketAddrV6::flowinfo`]'s documentation for more details.
512     ///
513     /// # Examples
514     ///
515     /// ```
516     /// use std::net::{SocketAddrV6, Ipv6Addr};
517     ///
518     /// let mut socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 10, 0);
519     /// socket.set_flowinfo(56);
520     /// assert_eq!(socket.flowinfo(), 56);
521     /// ```
522     #[cfg_attr(staged_api, stable(feature = "sockaddr_setters", since = "1.9.0"))]
set_flowinfonull523     pub fn set_flowinfo(&mut self, new_flowinfo: u32) {
524         self.flowinfo = new_flowinfo;
525     }
526 
527     /// Returns the scope ID associated with this address.
528     ///
529     /// This information corresponds to the `sin6_scope_id` field in C's `netinet/in.h`,
530     /// as specified in [IETF RFC 2553, Section 3.3].
531     ///
532     /// [IETF RFC 2553, Section 3.3]: https://tools.ietf.org/html/rfc2553#section-3.3
533     ///
534     /// # Examples
535     ///
536     /// ```
537     /// use std::net::{SocketAddrV6, Ipv6Addr};
538     ///
539     /// let socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 0, 78);
540     /// assert_eq!(socket.scope_id(), 78);
541     /// ```
542     #[must_use]
543     #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))]
544     #[cfg_attr(
545         staged_api,
546         rustc_const_unstable(feature = "const_socketaddr", issue = "82485")
547     )]
548     pub const fn scope_id(&self) -> u32 {
549         self.scope_id
550     }
551 
552     /// Changes the scope ID associated with this socket address.
553     ///
554     /// See [`SocketAddrV6::scope_id`]'s documentation for more details.
555     ///
556     /// # Examples
557     ///
558     /// ```
559     /// use std::net::{SocketAddrV6, Ipv6Addr};
560     ///
561     /// let mut socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 0, 78);
562     /// socket.set_scope_id(42);
563     /// assert_eq!(socket.scope_id(), 42);
564     /// ```
565     #[cfg_attr(staged_api, stable(feature = "sockaddr_setters", since = "1.9.0"))]
set_scope_idnull566     pub fn set_scope_id(&mut self, new_scope_id: u32) {
567         self.scope_id = new_scope_id;
568     }
569 }
570 
571 #[cfg_attr(staged_api, stable(feature = "ip_from_ip", since = "1.16.0"))]
572 impl From<SocketAddrV4> for SocketAddr {
573     /// Converts a [`SocketAddrV4`] into a [`SocketAddr::V4`].
fromnull574     fn from(sock4: SocketAddrV4) -> SocketAddr {
575         SocketAddr::V4(sock4)
576     }
577 }
578 
579 #[cfg_attr(staged_api, stable(feature = "ip_from_ip", since = "1.16.0"))]
580 impl From<SocketAddrV6> for SocketAddr {
581     /// Converts a [`SocketAddrV6`] into a [`SocketAddr::V6`].
fromnull582     fn from(sock6: SocketAddrV6) -> SocketAddr {
583         SocketAddr::V6(sock6)
584     }
585 }
586 
587 #[cfg_attr(staged_api, stable(feature = "addr_from_into_ip", since = "1.17.0"))]
588 impl<I: Into<IpAddr>> From<(I, u16)> for SocketAddr {
589     /// Converts a tuple struct (Into<[`IpAddr`]>, `u16`) into a [`SocketAddr`].
590     ///
591     /// This conversion creates a [`SocketAddr::V4`] for an [`IpAddr::V4`]
592     /// and creates a [`SocketAddr::V6`] for an [`IpAddr::V6`].
593     ///
594     /// `u16` is treated as port of the newly created [`SocketAddr`].
fromnull595     fn from(pieces: (I, u16)) -> SocketAddr {
596         SocketAddr::new(pieces.0.into(), pieces.1)
597     }
598 }
599 
600 #[cfg_attr(staged_api, stable(feature = "socketaddr_ordering", since = "1.45.0"))]
601 impl PartialOrd for SocketAddrV4 {
partial_cmpnull602     fn partial_cmp(&self, other: &SocketAddrV4) -> Option<Ordering> {
603         Some(self.cmp(other))
604     }
605 }
606 
607 #[cfg_attr(staged_api, stable(feature = "socketaddr_ordering", since = "1.45.0"))]
608 impl PartialOrd for SocketAddrV6 {
partial_cmpnull609     fn partial_cmp(&self, other: &SocketAddrV6) -> Option<Ordering> {
610         Some(self.cmp(other))
611     }
612 }
613 
614 #[cfg_attr(staged_api, stable(feature = "socketaddr_ordering", since = "1.45.0"))]
615 impl Ord for SocketAddrV4 {
cmpnull616     fn cmp(&self, other: &SocketAddrV4) -> Ordering {
617         self.ip()
618             .cmp(other.ip())
619             .then(self.port().cmp(&other.port()))
620     }
621 }
622 
623 #[cfg_attr(staged_api, stable(feature = "socketaddr_ordering", since = "1.45.0"))]
624 impl Ord for SocketAddrV6 {
cmpnull625     fn cmp(&self, other: &SocketAddrV6) -> Ordering {
626         self.ip()
627             .cmp(other.ip())
628             .then(self.port().cmp(&other.port()))
629     }
630 }
631 
632 #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))]
633 impl hash::Hash for SocketAddrV4 {
hashnull634     fn hash<H: hash::Hasher>(&self, s: &mut H) {
635         (self.port, self.ip).hash(s)
636     }
637 }
638 #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))]
639 impl hash::Hash for SocketAddrV6 {
hashnull640     fn hash<H: hash::Hasher>(&self, s: &mut H) {
641         (self.port, &self.ip, self.flowinfo, self.scope_id).hash(s)
642     }
643 }
644