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