core/net/
socket_addr.rs

1use super::display_buffer::DisplayBuffer;
2use crate::fmt::{self, Write};
3use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr};
4
5/// An internet socket address, either IPv4 or IPv6.
6///
7/// Internet socket addresses consist of an [IP address], a 16-bit port number, as well
8/// as possibly some version-dependent additional information. See [`SocketAddrV4`]'s and
9/// [`SocketAddrV6`]'s respective documentation for more details.
10///
11/// [IP address]: IpAddr
12///
13/// # Portability
14///
15/// `SocketAddr` is intended to be a portable representation of socket addresses and is likely not
16/// the same as the internal socket address type used by the target operating system's API. Like all
17/// `repr(Rust)` structs, however, its exact layout remains undefined and should not be relied upon
18/// between builds.
19///
20/// # Examples
21///
22/// ```
23/// use std::net::{IpAddr, Ipv4Addr, SocketAddr};
24///
25/// let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
26///
27/// assert_eq!("127.0.0.1:8080".parse(), Ok(socket));
28/// assert_eq!(socket.port(), 8080);
29/// assert_eq!(socket.is_ipv4(), true);
30/// ```
31#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
32#[stable(feature = "rust1", since = "1.0.0")]
33pub enum SocketAddr {
34    /// An IPv4 socket address.
35    #[stable(feature = "rust1", since = "1.0.0")]
36    V4(#[stable(feature = "rust1", since = "1.0.0")] SocketAddrV4),
37    /// An IPv6 socket address.
38    #[stable(feature = "rust1", since = "1.0.0")]
39    V6(#[stable(feature = "rust1", since = "1.0.0")] SocketAddrV6),
40}
41
42/// An IPv4 socket address.
43///
44/// IPv4 socket addresses consist of an [`IPv4` address] and a 16-bit port number, as
45/// stated in [IETF RFC 793].
46///
47/// See [`SocketAddr`] for a type encompassing both IPv4 and IPv6 socket addresses.
48///
49/// [IETF RFC 793]: https://tools.ietf.org/html/rfc793
50/// [`IPv4` address]: Ipv4Addr
51///
52/// # Portability
53///
54/// `SocketAddrV4` is intended to be a portable representation of socket addresses and is likely not
55/// the same as the internal socket address type used by the target operating system's API. Like all
56/// `repr(Rust)` structs, however, its exact layout remains undefined and should not be relied upon
57/// between builds.
58///
59/// # Textual representation
60///
61/// `SocketAddrV4` provides a [`FromStr`](crate::str::FromStr) implementation.
62/// It accepts an IPv4 address in its [textual representation], followed by a
63/// single `:`, followed by the port encoded as a decimal integer.  Other
64/// formats are not accepted.
65///
66/// [textual representation]: Ipv4Addr#textual-representation
67///
68/// # Examples
69///
70/// ```
71/// use std::net::{Ipv4Addr, SocketAddrV4};
72///
73/// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
74///
75/// assert_eq!("127.0.0.1:8080".parse(), Ok(socket));
76/// assert_eq!(socket.ip(), &Ipv4Addr::new(127, 0, 0, 1));
77/// assert_eq!(socket.port(), 8080);
78/// ```
79#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
80#[stable(feature = "rust1", since = "1.0.0")]
81pub struct SocketAddrV4 {
82    ip: Ipv4Addr,
83    port: u16,
84}
85
86/// An IPv6 socket address.
87///
88/// IPv6 socket addresses consist of an [`IPv6` address], a 16-bit port number, as well
89/// as fields containing the traffic class, the flow label, and a scope identifier
90/// (see [IETF RFC 2553, Section 3.3] for more details).
91///
92/// See [`SocketAddr`] for a type encompassing both IPv4 and IPv6 socket addresses.
93///
94/// [IETF RFC 2553, Section 3.3]: https://tools.ietf.org/html/rfc2553#section-3.3
95/// [`IPv6` address]: Ipv6Addr
96///
97/// # Portability
98///
99/// `SocketAddrV6` is intended to be a portable representation of socket addresses and is likely not
100/// the same as the internal socket address type used by the target operating system's API. Like all
101/// `repr(Rust)` structs, however, its exact layout remains undefined and should not be relied upon
102/// between builds.
103///
104/// # Textual representation
105///
106/// `SocketAddrV6` provides a [`FromStr`](crate::str::FromStr) implementation,
107/// based on the bracketed format recommended by [IETF RFC 5952],
108/// with scope identifiers based on those specified in [IETF RFC 4007].
109///
110/// It accepts addresses consisting of the following elements, in order:
111///   - A left square bracket (`[`)
112///   - The [textual representation] of an IPv6 address
113///   - _Optionally_, a percent sign (`%`) followed by the scope identifier
114///     encoded as a decimal integer
115///   - A right square bracket (`]`)
116///   - A colon (`:`)
117///   - The port, encoded as a decimal integer.
118///
119/// For example, the string `[2001:db8::413]:443` represents a `SocketAddrV6`
120/// with the address `2001:db8::413` and port `443`.  The string
121/// `[2001:db8::413%612]:443` represents the same address and port, with a
122/// scope identifier of `612`.
123///
124/// Other formats are not accepted.
125///
126/// [IETF RFC 5952]: https://tools.ietf.org/html/rfc5952#section-6
127/// [IETF RFC 4007]: https://tools.ietf.org/html/rfc4007#section-11
128/// [textual representation]: Ipv6Addr#textual-representation
129///
130/// # Examples
131///
132/// ```
133/// use std::net::{Ipv6Addr, SocketAddrV6};
134///
135/// let socket = SocketAddrV6::new(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), 8080, 0, 0);
136///
137/// assert_eq!("[2001:db8::1]:8080".parse(), Ok(socket));
138/// assert_eq!(socket.ip(), &Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1));
139/// assert_eq!(socket.port(), 8080);
140///
141/// let mut with_scope = socket.clone();
142/// with_scope.set_scope_id(3);
143/// assert_eq!("[2001:db8::1%3]:8080".parse(), Ok(with_scope));
144/// ```
145#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
146#[stable(feature = "rust1", since = "1.0.0")]
147pub struct SocketAddrV6 {
148    ip: Ipv6Addr,
149    port: u16,
150    flowinfo: u32,
151    scope_id: u32,
152}
153
154impl SocketAddr {
155    /// Creates a new socket address from an [IP address] and a port number.
156    ///
157    /// [IP address]: IpAddr
158    ///
159    /// # Examples
160    ///
161    /// ```
162    /// use std::net::{IpAddr, Ipv4Addr, SocketAddr};
163    ///
164    /// let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
165    /// assert_eq!(socket.ip(), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)));
166    /// assert_eq!(socket.port(), 8080);
167    /// ```
168    #[stable(feature = "ip_addr", since = "1.7.0")]
169    #[must_use]
170    #[rustc_const_stable(feature = "const_socketaddr", since = "1.69.0")]
171    #[inline]
172    pub const fn new(ip: IpAddr, port: u16) -> SocketAddr {
173        match ip {
174            IpAddr::V4(a) => SocketAddr::V4(SocketAddrV4::new(a, port)),
175            IpAddr::V6(a) => SocketAddr::V6(SocketAddrV6::new(a, port, 0, 0)),
176        }
177    }
178
179    /// Returns the IP address associated with this socket address.
180    ///
181    /// # Examples
182    ///
183    /// ```
184    /// use std::net::{IpAddr, Ipv4Addr, SocketAddr};
185    ///
186    /// let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
187    /// assert_eq!(socket.ip(), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)));
188    /// ```
189    #[must_use]
190    #[stable(feature = "ip_addr", since = "1.7.0")]
191    #[rustc_const_stable(feature = "const_socketaddr", since = "1.69.0")]
192    #[inline]
193    pub const fn ip(&self) -> IpAddr {
194        match *self {
195            SocketAddr::V4(ref a) => IpAddr::V4(*a.ip()),
196            SocketAddr::V6(ref a) => IpAddr::V6(*a.ip()),
197        }
198    }
199
200    /// Changes the IP address associated with this socket address.
201    ///
202    /// # Examples
203    ///
204    /// ```
205    /// use std::net::{IpAddr, Ipv4Addr, SocketAddr};
206    ///
207    /// let mut socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
208    /// socket.set_ip(IpAddr::V4(Ipv4Addr::new(10, 10, 0, 1)));
209    /// assert_eq!(socket.ip(), IpAddr::V4(Ipv4Addr::new(10, 10, 0, 1)));
210    /// ```
211    #[inline]
212    #[stable(feature = "sockaddr_setters", since = "1.9.0")]
213    #[rustc_const_stable(feature = "const_sockaddr_setters", since = "1.87.0")]
214    pub const fn set_ip(&mut self, new_ip: IpAddr) {
215        // `match (*self, new_ip)` would have us mutate a copy of self only to throw it away.
216        match (self, new_ip) {
217            (&mut SocketAddr::V4(ref mut a), IpAddr::V4(new_ip)) => a.set_ip(new_ip),
218            (&mut SocketAddr::V6(ref mut a), IpAddr::V6(new_ip)) => a.set_ip(new_ip),
219            (self_, new_ip) => *self_ = Self::new(new_ip, self_.port()),
220        }
221    }
222
223    /// Returns the port number associated with this socket address.
224    ///
225    /// # Examples
226    ///
227    /// ```
228    /// use std::net::{IpAddr, Ipv4Addr, SocketAddr};
229    ///
230    /// let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
231    /// assert_eq!(socket.port(), 8080);
232    /// ```
233    #[must_use]
234    #[stable(feature = "rust1", since = "1.0.0")]
235    #[rustc_const_stable(feature = "const_socketaddr", since = "1.69.0")]
236    #[inline]
237    pub const fn port(&self) -> u16 {
238        match *self {
239            SocketAddr::V4(ref a) => a.port(),
240            SocketAddr::V6(ref a) => a.port(),
241        }
242    }
243
244    /// Changes the port number associated with this socket address.
245    ///
246    /// # Examples
247    ///
248    /// ```
249    /// use std::net::{IpAddr, Ipv4Addr, SocketAddr};
250    ///
251    /// let mut socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
252    /// socket.set_port(1025);
253    /// assert_eq!(socket.port(), 1025);
254    /// ```
255    #[inline]
256    #[stable(feature = "sockaddr_setters", since = "1.9.0")]
257    #[rustc_const_stable(feature = "const_sockaddr_setters", since = "1.87.0")]
258    pub const fn set_port(&mut self, new_port: u16) {
259        match *self {
260            SocketAddr::V4(ref mut a) => a.set_port(new_port),
261            SocketAddr::V6(ref mut a) => a.set_port(new_port),
262        }
263    }
264
265    /// Returns [`true`] if the [IP address] in this `SocketAddr` is an
266    /// [`IPv4` address], and [`false`] otherwise.
267    ///
268    /// [IP address]: IpAddr
269    /// [`IPv4` address]: IpAddr::V4
270    ///
271    /// # Examples
272    ///
273    /// ```
274    /// use std::net::{IpAddr, Ipv4Addr, SocketAddr};
275    ///
276    /// let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
277    /// assert_eq!(socket.is_ipv4(), true);
278    /// assert_eq!(socket.is_ipv6(), false);
279    /// ```
280    #[must_use]
281    #[stable(feature = "sockaddr_checker", since = "1.16.0")]
282    #[rustc_const_stable(feature = "const_socketaddr", since = "1.69.0")]
283    #[inline]
284    pub const fn is_ipv4(&self) -> bool {
285        matches!(*self, SocketAddr::V4(_))
286    }
287
288    /// Returns [`true`] if the [IP address] in this `SocketAddr` is an
289    /// [`IPv6` address], and [`false`] otherwise.
290    ///
291    /// [IP address]: IpAddr
292    /// [`IPv6` address]: IpAddr::V6
293    ///
294    /// # Examples
295    ///
296    /// ```
297    /// use std::net::{IpAddr, Ipv6Addr, SocketAddr};
298    ///
299    /// let socket = SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 65535, 0, 1)), 8080);
300    /// assert_eq!(socket.is_ipv4(), false);
301    /// assert_eq!(socket.is_ipv6(), true);
302    /// ```
303    #[must_use]
304    #[stable(feature = "sockaddr_checker", since = "1.16.0")]
305    #[rustc_const_stable(feature = "const_socketaddr", since = "1.69.0")]
306    #[inline]
307    pub const fn is_ipv6(&self) -> bool {
308        matches!(*self, SocketAddr::V6(_))
309    }
310}
311
312impl SocketAddrV4 {
313    /// Creates a new socket address from an [`IPv4` address] and a port number.
314    ///
315    /// [`IPv4` address]: Ipv4Addr
316    ///
317    /// # Examples
318    ///
319    /// ```
320    /// use std::net::{SocketAddrV4, Ipv4Addr};
321    ///
322    /// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
323    /// ```
324    #[stable(feature = "rust1", since = "1.0.0")]
325    #[must_use]
326    #[rustc_const_stable(feature = "const_socketaddr", since = "1.69.0")]
327    #[inline]
328    pub const fn new(ip: Ipv4Addr, port: u16) -> SocketAddrV4 {
329        SocketAddrV4 { ip, port }
330    }
331
332    /// Returns the IP address associated with this socket address.
333    ///
334    /// # Examples
335    ///
336    /// ```
337    /// use std::net::{SocketAddrV4, Ipv4Addr};
338    ///
339    /// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
340    /// assert_eq!(socket.ip(), &Ipv4Addr::new(127, 0, 0, 1));
341    /// ```
342    #[must_use]
343    #[stable(feature = "rust1", since = "1.0.0")]
344    #[rustc_const_stable(feature = "const_socketaddr", since = "1.69.0")]
345    #[inline]
346    pub const fn ip(&self) -> &Ipv4Addr {
347        &self.ip
348    }
349
350    /// Changes the IP address associated with this socket address.
351    ///
352    /// # Examples
353    ///
354    /// ```
355    /// use std::net::{SocketAddrV4, Ipv4Addr};
356    ///
357    /// let mut socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
358    /// socket.set_ip(Ipv4Addr::new(192, 168, 0, 1));
359    /// assert_eq!(socket.ip(), &Ipv4Addr::new(192, 168, 0, 1));
360    /// ```
361    #[inline]
362    #[stable(feature = "sockaddr_setters", since = "1.9.0")]
363    #[rustc_const_stable(feature = "const_sockaddr_setters", since = "1.87.0")]
364    pub const fn set_ip(&mut self, new_ip: Ipv4Addr) {
365        self.ip = new_ip;
366    }
367
368    /// Returns the port number associated with this socket address.
369    ///
370    /// # Examples
371    ///
372    /// ```
373    /// use std::net::{SocketAddrV4, Ipv4Addr};
374    ///
375    /// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
376    /// assert_eq!(socket.port(), 8080);
377    /// ```
378    #[must_use]
379    #[stable(feature = "rust1", since = "1.0.0")]
380    #[rustc_const_stable(feature = "const_socketaddr", since = "1.69.0")]
381    #[inline]
382    pub const fn port(&self) -> u16 {
383        self.port
384    }
385
386    /// Changes the port number associated with this socket address.
387    ///
388    /// # Examples
389    ///
390    /// ```
391    /// use std::net::{SocketAddrV4, Ipv4Addr};
392    ///
393    /// let mut socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
394    /// socket.set_port(4242);
395    /// assert_eq!(socket.port(), 4242);
396    /// ```
397    #[inline]
398    #[stable(feature = "sockaddr_setters", since = "1.9.0")]
399    #[rustc_const_stable(feature = "const_sockaddr_setters", since = "1.87.0")]
400    pub const fn set_port(&mut self, new_port: u16) {
401        self.port = new_port;
402    }
403}
404
405impl SocketAddrV6 {
406    /// Creates a new socket address from an [`IPv6` address], a 16-bit port number,
407    /// and the `flowinfo` and `scope_id` fields.
408    ///
409    /// For more information on the meaning and layout of the `flowinfo` and `scope_id`
410    /// parameters, see [IETF RFC 2553, Section 3.3].
411    ///
412    /// [IETF RFC 2553, Section 3.3]: https://tools.ietf.org/html/rfc2553#section-3.3
413    /// [`IPv6` address]: Ipv6Addr
414    ///
415    /// # Examples
416    ///
417    /// ```
418    /// use std::net::{SocketAddrV6, Ipv6Addr};
419    ///
420    /// let socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 0, 0);
421    /// ```
422    #[stable(feature = "rust1", since = "1.0.0")]
423    #[must_use]
424    #[rustc_const_stable(feature = "const_socketaddr", since = "1.69.0")]
425    #[inline]
426    pub const fn new(ip: Ipv6Addr, port: u16, flowinfo: u32, scope_id: u32) -> SocketAddrV6 {
427        SocketAddrV6 { ip, port, flowinfo, scope_id }
428    }
429
430    /// Returns the IP address associated with this socket address.
431    ///
432    /// # Examples
433    ///
434    /// ```
435    /// use std::net::{SocketAddrV6, Ipv6Addr};
436    ///
437    /// let socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 0, 0);
438    /// assert_eq!(socket.ip(), &Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
439    /// ```
440    #[must_use]
441    #[stable(feature = "rust1", since = "1.0.0")]
442    #[rustc_const_stable(feature = "const_socketaddr", since = "1.69.0")]
443    #[inline]
444    pub const fn ip(&self) -> &Ipv6Addr {
445        &self.ip
446    }
447
448    /// Changes the IP address associated with this socket address.
449    ///
450    /// # Examples
451    ///
452    /// ```
453    /// use std::net::{SocketAddrV6, Ipv6Addr};
454    ///
455    /// let mut socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 0, 0);
456    /// socket.set_ip(Ipv6Addr::new(76, 45, 0, 0, 0, 0, 0, 0));
457    /// assert_eq!(socket.ip(), &Ipv6Addr::new(76, 45, 0, 0, 0, 0, 0, 0));
458    /// ```
459    #[inline]
460    #[stable(feature = "sockaddr_setters", since = "1.9.0")]
461    #[rustc_const_stable(feature = "const_sockaddr_setters", since = "1.87.0")]
462    pub const fn set_ip(&mut self, new_ip: Ipv6Addr) {
463        self.ip = new_ip;
464    }
465
466    /// Returns the port number associated with this socket address.
467    ///
468    /// # Examples
469    ///
470    /// ```
471    /// use std::net::{SocketAddrV6, Ipv6Addr};
472    ///
473    /// let socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 0, 0);
474    /// assert_eq!(socket.port(), 8080);
475    /// ```
476    #[must_use]
477    #[stable(feature = "rust1", since = "1.0.0")]
478    #[rustc_const_stable(feature = "const_socketaddr", since = "1.69.0")]
479    #[inline]
480    pub const fn port(&self) -> u16 {
481        self.port
482    }
483
484    /// Changes the port number associated with this socket address.
485    ///
486    /// # Examples
487    ///
488    /// ```
489    /// use std::net::{SocketAddrV6, Ipv6Addr};
490    ///
491    /// let mut socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 0, 0);
492    /// socket.set_port(4242);
493    /// assert_eq!(socket.port(), 4242);
494    /// ```
495    #[inline]
496    #[stable(feature = "sockaddr_setters", since = "1.9.0")]
497    #[rustc_const_stable(feature = "const_sockaddr_setters", since = "1.87.0")]
498    pub const fn set_port(&mut self, new_port: u16) {
499        self.port = new_port;
500    }
501
502    /// Returns the flow information associated with this address.
503    ///
504    /// This information corresponds to the `sin6_flowinfo` field in C's `netinet/in.h`,
505    /// as specified in [IETF RFC 2553, Section 3.3].
506    /// It combines information about the flow label and the traffic class as specified
507    /// in [IETF RFC 2460], respectively [Section 6] and [Section 7].
508    ///
509    /// [IETF RFC 2553, Section 3.3]: https://tools.ietf.org/html/rfc2553#section-3.3
510    /// [IETF RFC 2460]: https://tools.ietf.org/html/rfc2460
511    /// [Section 6]: https://tools.ietf.org/html/rfc2460#section-6
512    /// [Section 7]: https://tools.ietf.org/html/rfc2460#section-7
513    ///
514    /// # Examples
515    ///
516    /// ```
517    /// use std::net::{SocketAddrV6, Ipv6Addr};
518    ///
519    /// let socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 10, 0);
520    /// assert_eq!(socket.flowinfo(), 10);
521    /// ```
522    #[must_use]
523    #[stable(feature = "rust1", since = "1.0.0")]
524    #[rustc_const_stable(feature = "const_socketaddr", since = "1.69.0")]
525    #[inline]
526    pub const fn flowinfo(&self) -> u32 {
527        self.flowinfo
528    }
529
530    /// Changes the flow information associated with this socket address.
531    ///
532    /// See [`SocketAddrV6::flowinfo`]'s documentation for more details.
533    ///
534    /// # Examples
535    ///
536    /// ```
537    /// use std::net::{SocketAddrV6, Ipv6Addr};
538    ///
539    /// let mut socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 10, 0);
540    /// socket.set_flowinfo(56);
541    /// assert_eq!(socket.flowinfo(), 56);
542    /// ```
543    #[inline]
544    #[stable(feature = "sockaddr_setters", since = "1.9.0")]
545    #[rustc_const_stable(feature = "const_sockaddr_setters", since = "1.87.0")]
546    pub const fn set_flowinfo(&mut self, new_flowinfo: u32) {
547        self.flowinfo = new_flowinfo;
548    }
549
550    /// Returns the scope ID associated with this address.
551    ///
552    /// This information corresponds to the `sin6_scope_id` field in C's `netinet/in.h`,
553    /// as specified in [IETF RFC 2553, Section 3.3].
554    ///
555    /// [IETF RFC 2553, Section 3.3]: https://tools.ietf.org/html/rfc2553#section-3.3
556    ///
557    /// # Examples
558    ///
559    /// ```
560    /// use std::net::{SocketAddrV6, Ipv6Addr};
561    ///
562    /// let socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 0, 78);
563    /// assert_eq!(socket.scope_id(), 78);
564    /// ```
565    #[must_use]
566    #[stable(feature = "rust1", since = "1.0.0")]
567    #[rustc_const_stable(feature = "const_socketaddr", since = "1.69.0")]
568    #[inline]
569    pub const fn scope_id(&self) -> u32 {
570        self.scope_id
571    }
572
573    /// Changes the scope ID associated with this socket address.
574    ///
575    /// See [`SocketAddrV6::scope_id`]'s documentation for more details.
576    ///
577    /// # Examples
578    ///
579    /// ```
580    /// use std::net::{SocketAddrV6, Ipv6Addr};
581    ///
582    /// let mut socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 0, 78);
583    /// socket.set_scope_id(42);
584    /// assert_eq!(socket.scope_id(), 42);
585    /// ```
586    #[inline]
587    #[stable(feature = "sockaddr_setters", since = "1.9.0")]
588    #[rustc_const_stable(feature = "const_sockaddr_setters", since = "1.87.0")]
589    pub const fn set_scope_id(&mut self, new_scope_id: u32) {
590        self.scope_id = new_scope_id;
591    }
592}
593
594#[stable(feature = "ip_from_ip", since = "1.16.0")]
595#[rustc_const_unstable(feature = "const_try", issue = "74935")]
596impl const From<SocketAddrV4> for SocketAddr {
597    /// Converts a [`SocketAddrV4`] into a [`SocketAddr::V4`].
598    #[inline]
599    fn from(sock4: SocketAddrV4) -> SocketAddr {
600        SocketAddr::V4(sock4)
601    }
602}
603
604#[stable(feature = "ip_from_ip", since = "1.16.0")]
605#[rustc_const_unstable(feature = "const_try", issue = "74935")]
606impl const From<SocketAddrV6> for SocketAddr {
607    /// Converts a [`SocketAddrV6`] into a [`SocketAddr::V6`].
608    #[inline]
609    fn from(sock6: SocketAddrV6) -> SocketAddr {
610        SocketAddr::V6(sock6)
611    }
612}
613
614#[stable(feature = "addr_from_into_ip", since = "1.17.0")]
615#[rustc_const_unstable(feature = "const_try", issue = "74935")]
616impl<I: ~const Into<IpAddr>> const From<(I, u16)> for SocketAddr {
617    /// Converts a tuple struct (Into<[`IpAddr`]>, `u16`) into a [`SocketAddr`].
618    ///
619    /// This conversion creates a [`SocketAddr::V4`] for an [`IpAddr::V4`]
620    /// and creates a [`SocketAddr::V6`] for an [`IpAddr::V6`].
621    ///
622    /// `u16` is treated as port of the newly created [`SocketAddr`].
623    fn from(pieces: (I, u16)) -> SocketAddr {
624        SocketAddr::new(pieces.0.into(), pieces.1)
625    }
626}
627
628#[stable(feature = "rust1", since = "1.0.0")]
629impl fmt::Display for SocketAddr {
630    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
631        match *self {
632            SocketAddr::V4(ref a) => a.fmt(f),
633            SocketAddr::V6(ref a) => a.fmt(f),
634        }
635    }
636}
637
638#[stable(feature = "rust1", since = "1.0.0")]
639impl fmt::Debug for SocketAddr {
640    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
641        fmt::Display::fmt(self, fmt)
642    }
643}
644
645#[stable(feature = "rust1", since = "1.0.0")]
646impl fmt::Display for SocketAddrV4 {
647    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
648        // If there are no alignment requirements, write the socket address directly to `f`.
649        // Otherwise, write it to a local buffer and then use `f.pad`.
650        if f.precision().is_none() && f.width().is_none() {
651            write!(f, "{}:{}", self.ip(), self.port())
652        } else {
653            const LONGEST_IPV4_SOCKET_ADDR: &str = "255.255.255.255:65535";
654
655            let mut buf = DisplayBuffer::<{ LONGEST_IPV4_SOCKET_ADDR.len() }>::new();
656            // Buffer is long enough for the longest possible IPv4 socket address, so this should never fail.
657            write!(buf, "{}:{}", self.ip(), self.port()).unwrap();
658
659            f.pad(buf.as_str())
660        }
661    }
662}
663
664#[stable(feature = "rust1", since = "1.0.0")]
665impl fmt::Debug for SocketAddrV4 {
666    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
667        fmt::Display::fmt(self, fmt)
668    }
669}
670
671#[stable(feature = "rust1", since = "1.0.0")]
672impl fmt::Display for SocketAddrV6 {
673    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
674        // If there are no alignment requirements, write the socket address directly to `f`.
675        // Otherwise, write it to a local buffer and then use `f.pad`.
676        if f.precision().is_none() && f.width().is_none() {
677            match self.scope_id() {
678                0 => write!(f, "[{}]:{}", self.ip(), self.port()),
679                scope_id => write!(f, "[{}%{}]:{}", self.ip(), scope_id, self.port()),
680            }
681        } else {
682            const LONGEST_IPV6_SOCKET_ADDR: &str =
683                "[ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff%4294967295]:65535";
684
685            let mut buf = DisplayBuffer::<{ LONGEST_IPV6_SOCKET_ADDR.len() }>::new();
686            match self.scope_id() {
687                0 => write!(buf, "[{}]:{}", self.ip(), self.port()),
688                scope_id => write!(buf, "[{}%{}]:{}", self.ip(), scope_id, self.port()),
689            }
690            // Buffer is long enough for the longest possible IPv6 socket address, so this should never fail.
691            .unwrap();
692
693            f.pad(buf.as_str())
694        }
695    }
696}
697
698#[stable(feature = "rust1", since = "1.0.0")]
699impl fmt::Debug for SocketAddrV6 {
700    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
701        fmt::Display::fmt(self, fmt)
702    }
703}
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy