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