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