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")]
595impl From<SocketAddrV4> for SocketAddr {
596    /// Converts a [`SocketAddrV4`] into a [`SocketAddr::V4`].
597    #[inline]
598    fn from(sock4: SocketAddrV4) -> SocketAddr {
599        SocketAddr::V4(sock4)
600    }
601}
602
603#[stable(feature = "ip_from_ip", since = "1.16.0")]
604impl From<SocketAddrV6> for SocketAddr {
605    /// Converts a [`SocketAddrV6`] into a [`SocketAddr::V6`].
606    #[inline]
607    fn from(sock6: SocketAddrV6) -> SocketAddr {
608        SocketAddr::V6(sock6)
609    }
610}
611
612#[stable(feature = "addr_from_into_ip", since = "1.17.0")]
613impl<I: Into<IpAddr>> From<(I, u16)> for SocketAddr {
614    /// Converts a tuple struct (Into<[`IpAddr`]>, `u16`) into a [`SocketAddr`].
615    ///
616    /// This conversion creates a [`SocketAddr::V4`] for an [`IpAddr::V4`]
617    /// and creates a [`SocketAddr::V6`] for an [`IpAddr::V6`].
618    ///
619    /// `u16` is treated as port of the newly created [`SocketAddr`].
620    fn from(pieces: (I, u16)) -> SocketAddr {
621        SocketAddr::new(pieces.0.into(), pieces.1)
622    }
623}
624
625#[stable(feature = "rust1", since = "1.0.0")]
626impl fmt::Display for SocketAddr {
627    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
628        match *self {
629            SocketAddr::V4(ref a) => a.fmt(f),
630            SocketAddr::V6(ref a) => a.fmt(f),
631        }
632    }
633}
634
635#[stable(feature = "rust1", since = "1.0.0")]
636impl fmt::Debug for SocketAddr {
637    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
638        fmt::Display::fmt(self, fmt)
639    }
640}
641
642#[stable(feature = "rust1", since = "1.0.0")]
643impl fmt::Display for SocketAddrV4 {
644    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
645        // If there are no alignment requirements, write the socket address directly to `f`.
646        // Otherwise, write it to a local buffer and then use `f.pad`.
647        if f.precision().is_none() && f.width().is_none() {
648            write!(f, "{}:{}", self.ip(), self.port())
649        } else {
650            const LONGEST_IPV4_SOCKET_ADDR: &str = "255.255.255.255:65535";
651
652            let mut buf = DisplayBuffer::<{ LONGEST_IPV4_SOCKET_ADDR.len() }>::new();
653            // Buffer is long enough for the longest possible IPv4 socket address, so this should never fail.
654            write!(buf, "{}:{}", self.ip(), self.port()).unwrap();
655
656            f.pad(buf.as_str())
657        }
658    }
659}
660
661#[stable(feature = "rust1", since = "1.0.0")]
662impl fmt::Debug for SocketAddrV4 {
663    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
664        fmt::Display::fmt(self, fmt)
665    }
666}
667
668#[stable(feature = "rust1", since = "1.0.0")]
669impl fmt::Display for SocketAddrV6 {
670    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
671        // If there are no alignment requirements, write the socket address directly to `f`.
672        // Otherwise, write it to a local buffer and then use `f.pad`.
673        if f.precision().is_none() && f.width().is_none() {
674            match self.scope_id() {
675                0 => write!(f, "[{}]:{}", self.ip(), self.port()),
676                scope_id => write!(f, "[{}%{}]:{}", self.ip(), scope_id, self.port()),
677            }
678        } else {
679            const LONGEST_IPV6_SOCKET_ADDR: &str =
680                "[ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff%4294967295]:65535";
681
682            let mut buf = DisplayBuffer::<{ LONGEST_IPV6_SOCKET_ADDR.len() }>::new();
683            match self.scope_id() {
684                0 => write!(buf, "[{}]:{}", self.ip(), self.port()),
685                scope_id => write!(buf, "[{}%{}]:{}", self.ip(), scope_id, self.port()),
686            }
687            // Buffer is long enough for the longest possible IPv6 socket address, so this should never fail.
688            .unwrap();
689
690            f.pad(buf.as_str())
691        }
692    }
693}
694
695#[stable(feature = "rust1", since = "1.0.0")]
696impl fmt::Debug for SocketAddrV6 {
697    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
698        fmt::Display::fmt(self, fmt)
699    }
700}
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