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