@@ -73,12 +73,11 @@ pub enum SocketAddr {
7373/// assert_eq!(socket.ip(), &Ipv4Addr::new(127, 0, 0, 1)); 
7474/// assert_eq!(socket.port(), 8080); 
7575/// ``` 
76- #[ derive( Copy ) ]  
76+ #[ derive( Copy ,   Clone ,   Eq ,   PartialEq ) ]  
7777#[ stable( feature = "rust1" ,  since = "1.0.0" ) ]  
7878pub  struct  SocketAddrV4  { 
79-     // Do not assume that this struct is implemented as the underlying system representation. 
80-     // The memory layout is not part of the stable interface that std exposes. 
81-     inner :  c:: sockaddr_in , 
79+     ip :  Ipv4Addr , 
80+     port :  u16 , 
8281} 
8382
8483/// An IPv6 socket address. 
@@ -107,12 +106,13 @@ pub struct SocketAddrV4 {
107106/// assert_eq!(socket.ip(), &Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1)); 
108107/// assert_eq!(socket.port(), 8080); 
109108/// ``` 
110- #[ derive( Copy ) ]  
109+ #[ derive( Copy ,   Clone ,   Eq ,   PartialEq ) ]  
111110#[ stable( feature = "rust1" ,  since = "1.0.0" ) ]  
112111pub  struct  SocketAddrV6  { 
113-     // Do not assume that this struct is implemented as the underlying system representation. 
114-     // The memory layout is not part of the stable interface that std exposes. 
115-     inner :  c:: sockaddr_in6 , 
112+     ip :  Ipv6Addr , 
113+     port :  u16 , 
114+     flowinfo :  u32 , 
115+     scope_id :  u32 , 
116116} 
117117
118118impl  SocketAddr  { 
@@ -131,7 +131,8 @@ impl SocketAddr {
131131     /// ``` 
132132     #[ stable( feature = "ip_addr" ,  since = "1.7.0" ) ]  
133133    #[ must_use]  
134-     pub  fn  new ( ip :  IpAddr ,  port :  u16 )  -> SocketAddr  { 
134+     #[ rustc_const_unstable( feature = "const_socketaddr" ,  issue = "none" ) ]  
135+     pub  const  fn  new ( ip :  IpAddr ,  port :  u16 )  -> SocketAddr  { 
135136        match  ip { 
136137            IpAddr :: V4 ( a)  => SocketAddr :: V4 ( SocketAddrV4 :: new ( a,  port) ) , 
137138            IpAddr :: V6 ( a)  => SocketAddr :: V6 ( SocketAddrV6 :: new ( a,  port,  0 ,  0 ) ) , 
@@ -277,15 +278,9 @@ impl SocketAddrV4 {
277278     /// ``` 
278279     #[ stable( feature = "rust1" ,  since = "1.0.0" ) ]  
279280    #[ must_use]  
280-     pub  fn  new ( ip :  Ipv4Addr ,  port :  u16 )  -> SocketAddrV4  { 
281-         SocketAddrV4  { 
282-             inner :  c:: sockaddr_in  { 
283-                 sin_family :  c:: AF_INET  as  c:: sa_family_t , 
284-                 sin_port :  htons ( port) , 
285-                 sin_addr :  ip. into_inner ( ) , 
286-                 ..unsafe  {  mem:: zeroed ( )  } 
287-             } , 
288-         } 
281+     #[ rustc_const_unstable( feature = "const_socketaddr" ,  issue = "none" ) ]  
282+     pub  const  fn  new ( ip :  Ipv4Addr ,  port :  u16 )  -> SocketAddrV4  { 
283+         SocketAddrV4  {  ip,  port } 
289284    } 
290285
291286    /// Returns the IP address associated with this socket address. 
@@ -302,9 +297,7 @@ impl SocketAddrV4 {
302297    #[ stable( feature = "rust1" ,  since = "1.0.0" ) ]  
303298    #[ rustc_const_unstable( feature = "const_socketaddr" ,  issue = "82485" ) ]  
304299    pub  const  fn  ip ( & self )  -> & Ipv4Addr  { 
305-         // SAFETY: `Ipv4Addr` is `#[repr(C)] struct { _: in_addr; }`. 
306-         // It is safe to cast from `&in_addr` to `&Ipv4Addr`. 
307-         unsafe  {  & * ( & self . inner . sin_addr  as  * const  c:: in_addr  as  * const  Ipv4Addr )  } 
300+         & self . ip 
308301    } 
309302
310303    /// Changes the IP address associated with this socket address. 
@@ -320,7 +313,7 @@ impl SocketAddrV4 {
320313     /// ``` 
321314     #[ stable( feature = "sockaddr_setters" ,  since = "1.9.0" ) ]  
322315    pub  fn  set_ip ( & mut  self ,  new_ip :  Ipv4Addr )  { 
323-         self . inner . sin_addr  = new_ip. into_inner ( ) 
316+         self . ip  = new_ip; 
324317    } 
325318
326319    /// Returns the port number associated with this socket address. 
@@ -337,7 +330,7 @@ impl SocketAddrV4 {
337330    #[ stable( feature = "rust1" ,  since = "1.0.0" ) ]  
338331    #[ rustc_const_unstable( feature = "const_socketaddr" ,  issue = "82485" ) ]  
339332    pub  const  fn  port ( & self )  -> u16  { 
340-         ntohs ( self . inner . sin_port ) 
333+         self . port 
341334    } 
342335
343336    /// Changes the port number associated with this socket address. 
@@ -353,7 +346,7 @@ impl SocketAddrV4 {
353346     /// ``` 
354347     #[ stable( feature = "sockaddr_setters" ,  since = "1.9.0" ) ]  
355348    pub  fn  set_port ( & mut  self ,  new_port :  u16 )  { 
356-         self . inner . sin_port  = htons ( new_port) ; 
349+         self . port  = new_port; 
357350    } 
358351} 
359352
@@ -376,17 +369,9 @@ impl SocketAddrV6 {
376369     /// ``` 
377370     #[ stable( feature = "rust1" ,  since = "1.0.0" ) ]  
378371    #[ must_use]  
379-     pub  fn  new ( ip :  Ipv6Addr ,  port :  u16 ,  flowinfo :  u32 ,  scope_id :  u32 )  -> SocketAddrV6  { 
380-         SocketAddrV6  { 
381-             inner :  c:: sockaddr_in6  { 
382-                 sin6_family :  c:: AF_INET6  as  c:: sa_family_t , 
383-                 sin6_port :  htons ( port) , 
384-                 sin6_addr :  * ip. as_inner ( ) , 
385-                 sin6_flowinfo :  flowinfo, 
386-                 sin6_scope_id :  scope_id, 
387-                 ..unsafe  {  mem:: zeroed ( )  } 
388-             } , 
389-         } 
372+     #[ rustc_const_unstable( feature = "const_socketaddr" ,  issue = "none" ) ]  
373+     pub  const  fn  new ( ip :  Ipv6Addr ,  port :  u16 ,  flowinfo :  u32 ,  scope_id :  u32 )  -> SocketAddrV6  { 
374+         SocketAddrV6  {  ip,  port,  flowinfo,  scope_id } 
390375    } 
391376
392377    /// Returns the IP address associated with this socket address. 
@@ -403,7 +388,7 @@ impl SocketAddrV6 {
403388    #[ stable( feature = "rust1" ,  since = "1.0.0" ) ]  
404389    #[ rustc_const_unstable( feature = "const_socketaddr" ,  issue = "82485" ) ]  
405390    pub  const  fn  ip ( & self )  -> & Ipv6Addr  { 
406-         unsafe   {   & * ( & self . inner . sin6_addr   as   * const  c :: in6_addr   as   * const   Ipv6Addr )   } 
391+         & self . ip 
407392    } 
408393
409394    /// Changes the IP address associated with this socket address. 
@@ -419,7 +404,7 @@ impl SocketAddrV6 {
419404     /// ``` 
420405     #[ stable( feature = "sockaddr_setters" ,  since = "1.9.0" ) ]  
421406    pub  fn  set_ip ( & mut  self ,  new_ip :  Ipv6Addr )  { 
422-         self . inner . sin6_addr  = * new_ip. as_inner ( ) 
407+         self . ip  = new_ip; 
423408    } 
424409
425410    /// Returns the port number associated with this socket address. 
@@ -436,7 +421,7 @@ impl SocketAddrV6 {
436421    #[ stable( feature = "rust1" ,  since = "1.0.0" ) ]  
437422    #[ rustc_const_unstable( feature = "const_socketaddr" ,  issue = "82485" ) ]  
438423    pub  const  fn  port ( & self )  -> u16  { 
439-         ntohs ( self . inner . sin6_port ) 
424+         self . port 
440425    } 
441426
442427    /// Changes the port number associated with this socket address. 
@@ -452,7 +437,7 @@ impl SocketAddrV6 {
452437     /// ``` 
453438     #[ stable( feature = "sockaddr_setters" ,  since = "1.9.0" ) ]  
454439    pub  fn  set_port ( & mut  self ,  new_port :  u16 )  { 
455-         self . inner . sin6_port  = htons ( new_port) ; 
440+         self . port  = new_port; 
456441    } 
457442
458443    /// Returns the flow information associated with this address. 
@@ -479,7 +464,7 @@ impl SocketAddrV6 {
479464    #[ stable( feature = "rust1" ,  since = "1.0.0" ) ]  
480465    #[ rustc_const_unstable( feature = "const_socketaddr" ,  issue = "82485" ) ]  
481466    pub  const  fn  flowinfo ( & self )  -> u32  { 
482-         self . inner . sin6_flowinfo 
467+         self . flowinfo 
483468    } 
484469
485470    /// Changes the flow information associated with this socket address. 
@@ -497,7 +482,7 @@ impl SocketAddrV6 {
497482     /// ``` 
498483     #[ stable( feature = "sockaddr_setters" ,  since = "1.9.0" ) ]  
499484    pub  fn  set_flowinfo ( & mut  self ,  new_flowinfo :  u32 )  { 
500-         self . inner . sin6_flowinfo  = new_flowinfo; 
485+         self . flowinfo  = new_flowinfo; 
501486    } 
502487
503488    /// Returns the scope ID associated with this address. 
@@ -519,7 +504,7 @@ impl SocketAddrV6 {
519504    #[ stable( feature = "rust1" ,  since = "1.0.0" ) ]  
520505    #[ rustc_const_unstable( feature = "const_socketaddr" ,  issue = "82485" ) ]  
521506    pub  const  fn  scope_id ( & self )  -> u32  { 
522-         self . inner . sin6_scope_id 
507+         self . scope_id 
523508    } 
524509
525510    /// Changes the scope ID associated with this socket address. 
@@ -537,19 +522,51 @@ impl SocketAddrV6 {
537522     /// ``` 
538523     #[ stable( feature = "sockaddr_setters" ,  since = "1.9.0" ) ]  
539524    pub  fn  set_scope_id ( & mut  self ,  new_scope_id :  u32 )  { 
540-         self . inner . sin6_scope_id  = new_scope_id; 
525+         self . scope_id  = new_scope_id; 
541526    } 
542527} 
543528
544529impl  FromInner < c:: sockaddr_in >  for  SocketAddrV4  { 
545530    fn  from_inner ( addr :  c:: sockaddr_in )  -> SocketAddrV4  { 
546-         SocketAddrV4  {  inner :  addr } 
531+         SocketAddrV4  { 
532+             ip :  unsafe  {  * ( & addr. sin_addr  as  * const  c:: in_addr  as  * const  Ipv4Addr )  } , 
533+             port :  ntohs ( addr. sin_port ) , 
534+         } 
547535    } 
548536} 
549537
550538impl  FromInner < c:: sockaddr_in6 >  for  SocketAddrV6  { 
551539    fn  from_inner ( addr :  c:: sockaddr_in6 )  -> SocketAddrV6  { 
552-         SocketAddrV6  {  inner :  addr } 
540+         SocketAddrV6  { 
541+             ip :  unsafe  {  * ( & addr. sin6_addr  as  * const  c:: in6_addr  as  * const  Ipv6Addr )  } , 
542+             port :  ntohs ( addr. sin6_port ) , 
543+             flowinfo :  addr. sin6_flowinfo , 
544+             scope_id :  addr. sin6_scope_id , 
545+         } 
546+     } 
547+ } 
548+ 
549+ impl  IntoInner < c:: sockaddr_in >  for  SocketAddrV4  { 
550+     fn  into_inner ( self )  -> c:: sockaddr_in  { 
551+         c:: sockaddr_in  { 
552+             sin_family :  c:: AF_INET  as  c:: sa_family_t , 
553+             sin_port :  htons ( self . port ) , 
554+             sin_addr :  self . ip . into_inner ( ) , 
555+             ..unsafe  {  mem:: zeroed ( )  } 
556+         } 
557+     } 
558+ } 
559+ 
560+ impl  IntoInner < c:: sockaddr_in6 >  for  SocketAddrV6  { 
561+     fn  into_inner ( self )  -> c:: sockaddr_in6  { 
562+         c:: sockaddr_in6  { 
563+             sin6_family :  c:: AF_INET6  as  c:: sa_family_t , 
564+             sin6_port :  htons ( self . port ) , 
565+             sin6_addr :  * self . ip . as_inner ( ) , 
566+             sin6_flowinfo :  self . flowinfo , 
567+             sin6_scope_id :  self . scope_id , 
568+             ..unsafe  {  mem:: zeroed ( )  } 
569+         } 
553570    } 
554571} 
555572
@@ -582,14 +599,32 @@ impl<I: Into<IpAddr>> From<(I, u16)> for SocketAddr {
582599    } 
583600} 
584601
585- impl < ' a >  IntoInner < ( * const  c:: sockaddr ,  c:: socklen_t ) >  for  & ' a  SocketAddr  { 
586-     fn  into_inner ( self )  -> ( * const  c:: sockaddr ,  c:: socklen_t )  { 
602+ /// A type with the same memory layout as `c::sockaddr`. Used in converting Rust level 
603+ /// SocketAddr* types into their system representation. The benefit of this specific 
604+ /// type over using `c::sockaddr_storage` is that this type is exactly as large as it 
605+ /// needs to be and not a lot larger. And it can be initialized more cleanly from Rust. 
606+ #[ repr( C ) ]  
607+ pub ( crate )  union  SocketAddrCRepr  { 
608+     v4 :  c:: sockaddr_in , 
609+     v6 :  c:: sockaddr_in6 , 
610+ } 
611+ 
612+ impl  SocketAddrCRepr  { 
613+     pub  fn  as_ptr ( & self )  -> * const  c:: sockaddr  { 
614+         self  as  * const  _  as  * const  c:: sockaddr 
615+     } 
616+ } 
617+ 
618+ impl < ' a >  IntoInner < ( SocketAddrCRepr ,  c:: socklen_t ) >  for  & ' a  SocketAddr  { 
619+     fn  into_inner ( self )  -> ( SocketAddrCRepr ,  c:: socklen_t )  { 
587620        match  * self  { 
588621            SocketAddr :: V4 ( ref  a)  => { 
589-                 ( a as  * const  _  as  * const  _ ,  mem:: size_of_val ( a)  as  c:: socklen_t ) 
622+                 let  sockaddr = SocketAddrCRepr  {  v4 :  a. into_inner ( )  } ; 
623+                 ( sockaddr,  mem:: size_of :: < c:: sockaddr_in > ( )  as  c:: socklen_t ) 
590624            } 
591625            SocketAddr :: V6 ( ref  a)  => { 
592-                 ( a as  * const  _  as  * const  _ ,  mem:: size_of_val ( a)  as  c:: socklen_t ) 
626+                 let  sockaddr = SocketAddrCRepr  {  v6 :  a. into_inner ( )  } ; 
627+                 ( sockaddr,  mem:: size_of :: < c:: sockaddr_in6 > ( )  as  c:: socklen_t ) 
593628            } 
594629        } 
595630    } 
@@ -688,40 +723,6 @@ impl fmt::Debug for SocketAddrV6 {
688723    } 
689724} 
690725
691- #[ stable( feature = "rust1" ,  since = "1.0.0" ) ]  
692- impl  Clone  for  SocketAddrV4  { 
693-     fn  clone ( & self )  -> SocketAddrV4  { 
694-         * self 
695-     } 
696- } 
697- #[ stable( feature = "rust1" ,  since = "1.0.0" ) ]  
698- impl  Clone  for  SocketAddrV6  { 
699-     fn  clone ( & self )  -> SocketAddrV6  { 
700-         * self 
701-     } 
702- } 
703- 
704- #[ stable( feature = "rust1" ,  since = "1.0.0" ) ]  
705- impl  PartialEq  for  SocketAddrV4  { 
706-     fn  eq ( & self ,  other :  & SocketAddrV4 )  -> bool  { 
707-         self . inner . sin_port  == other. inner . sin_port 
708-             && self . inner . sin_addr . s_addr  == other. inner . sin_addr . s_addr 
709-     } 
710- } 
711- #[ stable( feature = "rust1" ,  since = "1.0.0" ) ]  
712- impl  PartialEq  for  SocketAddrV6  { 
713-     fn  eq ( & self ,  other :  & SocketAddrV6 )  -> bool  { 
714-         self . inner . sin6_port  == other. inner . sin6_port 
715-             && self . inner . sin6_addr . s6_addr  == other. inner . sin6_addr . s6_addr 
716-             && self . inner . sin6_flowinfo  == other. inner . sin6_flowinfo 
717-             && self . inner . sin6_scope_id  == other. inner . sin6_scope_id 
718-     } 
719- } 
720- #[ stable( feature = "rust1" ,  since = "1.0.0" ) ]  
721- impl  Eq  for  SocketAddrV4  { } 
722- #[ stable( feature = "rust1" ,  since = "1.0.0" ) ]  
723- impl  Eq  for  SocketAddrV6  { } 
724- 
725726#[ stable( feature = "socketaddr_ordering" ,  since = "1.45.0" ) ]  
726727impl  PartialOrd  for  SocketAddrV4  { 
727728    fn  partial_cmp ( & self ,  other :  & SocketAddrV4 )  -> Option < Ordering >  { 
@@ -753,19 +754,13 @@ impl Ord for SocketAddrV6 {
753754#[ stable( feature = "rust1" ,  since = "1.0.0" ) ]  
754755impl  hash:: Hash  for  SocketAddrV4  { 
755756    fn  hash < H :  hash:: Hasher > ( & self ,  s :  & mut  H )  { 
756-         ( self . inner . sin_port ,  self . inner . sin_addr . s_addr ) . hash ( s) 
757+         ( self . port ,  self . ip ) . hash ( s) 
757758    } 
758759} 
759760#[ stable( feature = "rust1" ,  since = "1.0.0" ) ]  
760761impl  hash:: Hash  for  SocketAddrV6  { 
761762    fn  hash < H :  hash:: Hasher > ( & self ,  s :  & mut  H )  { 
762-         ( 
763-             self . inner . sin6_port , 
764-             & self . inner . sin6_addr . s6_addr , 
765-             self . inner . sin6_flowinfo , 
766-             self . inner . sin6_scope_id , 
767-         ) 
768-             . hash ( s) 
763+         ( self . port ,  & self . ip ,  self . flowinfo ,  self . scope_id ) . hash ( s) 
769764    } 
770765} 
771766
0 commit comments