@@ -67,6 +67,17 @@ impl SocketAddr {
6767 }
6868 }
6969
70+ /// Change the IP address associated with this socket address.
71+ #[ unstable( feature = "sockaddr_setters" , reason = "recent addition" , issue = "31572" ) ]
72+ pub fn set_ip ( & mut self , new_ip : IpAddr ) {
73+ // `match (*self, new_ip)` would have us mutate a copy of self only to throw it away.
74+ match ( self , new_ip) {
75+ ( & mut SocketAddr :: V4 ( ref mut a) , IpAddr :: V4 ( new_ip) ) => a. set_ip ( new_ip) ,
76+ ( & mut SocketAddr :: V6 ( ref mut a) , IpAddr :: V6 ( new_ip) ) => a. set_ip ( new_ip) ,
77+ ( self_, new_ip) => * self_ = Self :: new ( new_ip, self_. port ( ) ) ,
78+ }
79+ }
80+
7081 /// Returns the port number associated with this socket address.
7182 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
7283 pub fn port ( & self ) -> u16 {
@@ -75,6 +86,15 @@ impl SocketAddr {
7586 SocketAddr :: V6 ( ref a) => a. port ( ) ,
7687 }
7788 }
89+
90+ /// Change the port number associated with this socket address.
91+ #[ unstable( feature = "sockaddr_setters" , reason = "recent addition" , issue = "31572" ) ]
92+ pub fn set_port ( & mut self , new_port : u16 ) {
93+ match * self {
94+ SocketAddr :: V4 ( ref mut a) => a. set_port ( new_port) ,
95+ SocketAddr :: V6 ( ref mut a) => a. set_port ( new_port) ,
96+ }
97+ }
7898}
7999
80100impl SocketAddrV4 {
@@ -99,9 +119,17 @@ impl SocketAddrV4 {
99119 }
100120 }
101121
122+ /// Change the IP address associated with this socket address.
123+ #[ unstable( feature = "sockaddr_setters" , reason = "recent addition" , issue = "31572" ) ]
124+ pub fn set_ip ( & mut self , new_ip : Ipv4Addr ) { self . inner . sin_addr = * new_ip. as_inner ( ) }
125+
102126 /// Returns the port number associated with this socket address.
103127 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
104128 pub fn port ( & self ) -> u16 { ntoh ( self . inner . sin_port ) }
129+
130+ /// Change the port number associated with this socket address.
131+ #[ unstable( feature = "sockaddr_setters" , reason = "recent addition" , issue = "31572" ) ]
132+ pub fn set_port ( & mut self , new_port : u16 ) { self . inner . sin_port = hton ( new_port) }
105133}
106134
107135impl SocketAddrV6 {
@@ -130,19 +158,39 @@ impl SocketAddrV6 {
130158 }
131159 }
132160
161+ /// Change the IP address associated with this socket address.
162+ #[ unstable( feature = "sockaddr_setters" , reason = "recent addition" , issue = "31572" ) ]
163+ pub fn set_ip ( & mut self , new_ip : Ipv6Addr ) { self . inner . sin6_addr = * new_ip. as_inner ( ) }
164+
133165 /// Returns the port number associated with this socket address.
134166 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
135167 pub fn port ( & self ) -> u16 { ntoh ( self . inner . sin6_port ) }
136168
169+ /// Change the port number associated with this socket address.
170+ #[ unstable( feature = "sockaddr_setters" , reason = "recent addition" , issue = "31572" ) ]
171+ pub fn set_port ( & mut self , new_port : u16 ) { self . inner . sin6_port = hton ( new_port) }
172+
137173 /// Returns the flow information associated with this address,
138174 /// corresponding to the `sin6_flowinfo` field in C.
139175 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
140176 pub fn flowinfo ( & self ) -> u32 { ntoh ( self . inner . sin6_flowinfo ) }
141177
178+ /// Change the flow information associated with this socket address.
179+ #[ unstable( feature = "sockaddr_setters" , reason = "recent addition" , issue = "31572" ) ]
180+ pub fn set_flowinfo ( & mut self , new_flowinfo : u32 ) {
181+ self . inner . sin6_flowinfo = hton ( new_flowinfo)
182+ }
183+
142184 /// Returns the scope ID associated with this address,
143185 /// corresponding to the `sin6_scope_id` field in C.
144186 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
145187 pub fn scope_id ( & self ) -> u32 { ntoh ( self . inner . sin6_scope_id ) }
188+
189+ /// Change the scope ID associated with this socket address.
190+ #[ unstable( feature = "sockaddr_setters" , reason = "recent addition" , issue = "31572" ) ]
191+ pub fn set_scope_id ( & mut self , new_scope_id : u32 ) {
192+ self . inner . sin6_scope_id = hton ( new_scope_id)
193+ }
146194}
147195
148196impl FromInner < c:: sockaddr_in > for SocketAddrV4 {
@@ -385,16 +433,9 @@ impl ToSocketAddrs for (Ipv6Addr, u16) {
385433fn resolve_socket_addr ( s : & str , p : u16 ) -> io:: Result < vec:: IntoIter < SocketAddr > > {
386434 let ips = try!( lookup_host ( s) ) ;
387435 let v: Vec < _ > = try!( ips. map ( |a| {
388- a. map ( |a| {
389- match a {
390- SocketAddr :: V4 ( ref a) => {
391- SocketAddr :: V4 ( SocketAddrV4 :: new ( * a. ip ( ) , p) )
392- }
393- SocketAddr :: V6 ( ref a) => {
394- SocketAddr :: V6 ( SocketAddrV6 :: new ( * a. ip ( ) , p, a. flowinfo ( ) ,
395- a. scope_id ( ) ) )
396- }
397- }
436+ a. map ( |mut a| {
437+ a. set_port ( p) ;
438+ a
398439 } )
399440 } ) . collect ( ) ) ;
400441 Ok ( v. into_iter ( ) )
@@ -511,4 +552,73 @@ mod tests {
511552 fn to_socket_addr_str_bad ( ) {
512553 assert ! ( tsa( "1200::AB00:1234::2552:7777:1313:34300" ) . is_err( ) ) ;
513554 }
555+
556+ #[ test]
557+ fn set_ip ( ) {
558+ fn ip4 ( low : u8 ) -> Ipv4Addr { Ipv4Addr :: new ( 77 , 88 , 21 , low) }
559+ fn ip6 ( low : u16 ) -> Ipv6Addr { Ipv6Addr :: new ( 0x2a02 , 0x6b8 , 0 , 1 , 0 , 0 , 0 , low) }
560+
561+ let mut v4 = SocketAddrV4 :: new ( ip4 ( 11 ) , 80 ) ;
562+ assert_eq ! ( v4. ip( ) , & ip4( 11 ) ) ;
563+ v4. set_ip ( ip4 ( 12 ) ) ;
564+ assert_eq ! ( v4. ip( ) , & ip4( 12 ) ) ;
565+
566+ let mut addr = SocketAddr :: V4 ( v4) ;
567+ assert_eq ! ( addr. ip( ) , IpAddr :: V4 ( ip4( 12 ) ) ) ;
568+ addr. set_ip ( IpAddr :: V4 ( ip4 ( 13 ) ) ) ;
569+ assert_eq ! ( addr. ip( ) , IpAddr :: V4 ( ip4( 13 ) ) ) ;
570+ addr. set_ip ( IpAddr :: V6 ( ip6 ( 14 ) ) ) ;
571+ assert_eq ! ( addr. ip( ) , IpAddr :: V6 ( ip6( 14 ) ) ) ;
572+
573+ let mut v6 = SocketAddrV6 :: new ( ip6 ( 1 ) , 80 , 0 , 0 ) ;
574+ assert_eq ! ( v6. ip( ) , & ip6( 1 ) ) ;
575+ v6. set_ip ( ip6 ( 2 ) ) ;
576+ assert_eq ! ( v6. ip( ) , & ip6( 2 ) ) ;
577+
578+ let mut addr = SocketAddr :: V6 ( v6) ;
579+ assert_eq ! ( addr. ip( ) , IpAddr :: V6 ( ip6( 2 ) ) ) ;
580+ addr. set_ip ( IpAddr :: V6 ( ip6 ( 3 ) ) ) ;
581+ assert_eq ! ( addr. ip( ) , IpAddr :: V6 ( ip6( 3 ) ) ) ;
582+ addr. set_ip ( IpAddr :: V4 ( ip4 ( 4 ) ) ) ;
583+ assert_eq ! ( addr. ip( ) , IpAddr :: V4 ( ip4( 4 ) ) ) ;
584+ }
585+
586+ #[ test]
587+ fn set_port ( ) {
588+ let mut v4 = SocketAddrV4 :: new ( Ipv4Addr :: new ( 77 , 88 , 21 , 11 ) , 80 ) ;
589+ assert_eq ! ( v4. port( ) , 80 ) ;
590+ v4. set_port ( 443 ) ;
591+ assert_eq ! ( v4. port( ) , 443 ) ;
592+
593+ let mut addr = SocketAddr :: V4 ( v4) ;
594+ assert_eq ! ( addr. port( ) , 443 ) ;
595+ addr. set_port ( 8080 ) ;
596+ assert_eq ! ( addr. port( ) , 8080 ) ;
597+
598+ let mut v6 = SocketAddrV6 :: new ( Ipv6Addr :: new ( 0x2a02 , 0x6b8 , 0 , 1 , 0 , 0 , 0 , 1 ) , 80 , 0 , 0 ) ;
599+ assert_eq ! ( v6. port( ) , 80 ) ;
600+ v6. set_port ( 443 ) ;
601+ assert_eq ! ( v6. port( ) , 443 ) ;
602+
603+ let mut addr = SocketAddr :: V6 ( v6) ;
604+ assert_eq ! ( addr. port( ) , 443 ) ;
605+ addr. set_port ( 8080 ) ;
606+ assert_eq ! ( addr. port( ) , 8080 ) ;
607+ }
608+
609+ #[ test]
610+ fn set_flowinfo ( ) {
611+ let mut v6 = SocketAddrV6 :: new ( Ipv6Addr :: new ( 0x2a02 , 0x6b8 , 0 , 1 , 0 , 0 , 0 , 1 ) , 80 , 10 , 0 ) ;
612+ assert_eq ! ( v6. flowinfo( ) , 10 ) ;
613+ v6. set_flowinfo ( 20 ) ;
614+ assert_eq ! ( v6. flowinfo( ) , 20 ) ;
615+ }
616+
617+ #[ test]
618+ fn set_scope_id ( ) {
619+ let mut v6 = SocketAddrV6 :: new ( Ipv6Addr :: new ( 0x2a02 , 0x6b8 , 0 , 1 , 0 , 0 , 0 , 1 ) , 80 , 0 , 10 ) ;
620+ assert_eq ! ( v6. scope_id( ) , 10 ) ;
621+ v6. set_scope_id ( 20 ) ;
622+ assert_eq ! ( v6. scope_id( ) , 20 ) ;
623+ }
514624}
0 commit comments