1 | use super::display_buffer::DisplayBuffer; |
2 | use crate::fmt::{self, Write}; |
3 | use 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" )] |
33 | pub 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" )] |
81 | pub 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" )] |
147 | pub struct SocketAddrV6 { |
148 | ip: Ipv6Addr, |
149 | port: u16, |
150 | flowinfo: u32, |
151 | scope_id: u32, |
152 | } |
153 | |
154 | impl 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 | |
312 | impl 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 | |
405 | impl 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 | impl 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" )] |
604 | impl 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" )] |
613 | impl<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(ip:pieces.0.into(), port:pieces.1) |
622 | } |
623 | } |
624 | |
625 | #[stable (feature = "rust1" , since = "1.0.0" )] |
626 | impl fmt::Display for SocketAddr { |
627 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
628 | match *self { |
629 | SocketAddr::V4(ref a: &SocketAddrV4) => a.fmt(f), |
630 | SocketAddr::V6(ref a: &SocketAddrV6) => a.fmt(f), |
631 | } |
632 | } |
633 | } |
634 | |
635 | #[stable (feature = "rust1" , since = "1.0.0" )] |
636 | impl fmt::Debug for SocketAddr { |
637 | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
638 | fmt::Display::fmt(self, f:fmt) |
639 | } |
640 | } |
641 | |
642 | #[stable (feature = "rust1" , since = "1.0.0" )] |
643 | impl 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<_> = 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" )] |
662 | impl fmt::Debug for SocketAddrV4 { |
663 | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
664 | fmt::Display::fmt(self, f:fmt) |
665 | } |
666 | } |
667 | |
668 | #[stable (feature = "rust1" , since = "1.0.0" )] |
669 | impl 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" )] |
696 | impl fmt::Debug for SocketAddrV6 { |
697 | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
698 | fmt::Display::fmt(self, f:fmt) |
699 | } |
700 | } |
701 | |