]> git.lizzy.rs Git - rust.git/blob - src/libstd/io/net/ip.rs
Delete the outdated source layout README
[rust.git] / src / libstd / io / net / ip.rs
1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! Internet Protocol (IP) addresses.
12 //!
13 //! This module contains functions useful for parsing, formatting, and
14 //! manipulating IP addresses.
15
16 #![allow(missing_docs)]
17
18 pub use self::IpAddr::*;
19
20 use fmt;
21 use io::{mod, IoResult, IoError};
22 use io::net;
23 use iter::{Iterator, IteratorExt};
24 use option::Option;
25 use option::Option::{None, Some};
26 use result::Result::{Ok, Err};
27 use str::{FromStr, StrPrelude};
28 use slice::{CloneSlicePrelude, SlicePrelude};
29 use vec::Vec;
30
31 pub type Port = u16;
32
33 #[deriving(PartialEq, Eq, Clone, Hash)]
34 pub enum IpAddr {
35     Ipv4Addr(u8, u8, u8, u8),
36     Ipv6Addr(u16, u16, u16, u16, u16, u16, u16, u16)
37 }
38
39 impl fmt::Show for IpAddr {
40     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
41         match *self {
42             Ipv4Addr(a, b, c, d) =>
43                 write!(fmt, "{}.{}.{}.{}", a, b, c, d),
44
45             // Ipv4 Compatible address
46             Ipv6Addr(0, 0, 0, 0, 0, 0, g, h) => {
47                 write!(fmt, "::{}.{}.{}.{}", (g >> 8) as u8, g as u8,
48                        (h >> 8) as u8, h as u8)
49             }
50
51             // Ipv4-Mapped address
52             Ipv6Addr(0, 0, 0, 0, 0, 0xFFFF, g, h) => {
53                 write!(fmt, "::FFFF:{}.{}.{}.{}", (g >> 8) as u8, g as u8,
54                        (h >> 8) as u8, h as u8)
55             }
56
57             Ipv6Addr(a, b, c, d, e, f, g, h) =>
58                 write!(fmt, "{:x}:{:x}:{:x}:{:x}:{:x}:{:x}:{:x}:{:x}",
59                        a, b, c, d, e, f, g, h)
60         }
61     }
62 }
63
64 #[deriving(PartialEq, Eq, Clone, Hash)]
65 pub struct SocketAddr {
66     pub ip: IpAddr,
67     pub port: Port,
68 }
69
70 impl fmt::Show for SocketAddr {
71     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
72         match self.ip {
73             Ipv4Addr(..) => write!(f, "{}:{}", self.ip, self.port),
74             Ipv6Addr(..) => write!(f, "[{}]:{}", self.ip, self.port),
75         }
76     }
77 }
78
79 struct Parser<'a> {
80     // parsing as ASCII, so can use byte array
81     s: &'a [u8],
82     pos: uint,
83 }
84
85 impl<'a> Parser<'a> {
86     fn new(s: &'a str) -> Parser<'a> {
87         Parser {
88             s: s.as_bytes(),
89             pos: 0,
90         }
91     }
92
93     fn is_eof(&self) -> bool {
94         self.pos == self.s.len()
95     }
96
97     // Commit only if parser returns Some
98     fn read_atomically<T>(&mut self, cb: |&mut Parser| -> Option<T>)
99                        -> Option<T> {
100         let pos = self.pos;
101         let r = cb(self);
102         if r.is_none() {
103             self.pos = pos;
104         }
105         r
106     }
107
108     // Commit only if parser read till EOF
109     fn read_till_eof<T>(&mut self, cb: |&mut Parser| -> Option<T>)
110                      -> Option<T> {
111         self.read_atomically(|p| {
112             match cb(p) {
113                 Some(x) => if p.is_eof() {Some(x)} else {None},
114                 None => None,
115             }
116         })
117     }
118
119     // Return result of first successful parser
120     fn read_or<T>(&mut self, parsers: &mut [|&mut Parser| -> Option<T>])
121                -> Option<T> {
122         for pf in parsers.iter_mut() {
123             match self.read_atomically(|p: &mut Parser| (*pf)(p)) {
124                 Some(r) => return Some(r),
125                 None => {}
126             }
127         }
128         None
129     }
130
131     // Apply 3 parsers sequentially
132     fn read_seq_3<A,
133                   B,
134                   C>(
135                   &mut self,
136                   pa: |&mut Parser| -> Option<A>,
137                   pb: |&mut Parser| -> Option<B>,
138                   pc: |&mut Parser| -> Option<C>)
139                   -> Option<(A, B, C)> {
140         self.read_atomically(|p| {
141             let a = pa(p);
142             let b = if a.is_some() { pb(p) } else { None };
143             let c = if b.is_some() { pc(p) } else { None };
144             match (a, b, c) {
145                 (Some(a), Some(b), Some(c)) => Some((a, b, c)),
146                 _ => None
147             }
148         })
149     }
150
151     // Read next char
152     fn read_char(&mut self) -> Option<char> {
153         if self.is_eof() {
154             None
155         } else {
156             let r = self.s[self.pos] as char;
157             self.pos += 1;
158             Some(r)
159         }
160     }
161
162     // Return char and advance iff next char is equal to requested
163     fn read_given_char(&mut self, c: char) -> Option<char> {
164         self.read_atomically(|p| {
165             match p.read_char() {
166                 Some(next) if next == c => Some(next),
167                 _ => None,
168             }
169         })
170     }
171
172     // Read digit
173     fn read_digit(&mut self, radix: u8) -> Option<u8> {
174         fn parse_digit(c: char, radix: u8) -> Option<u8> {
175             let c = c as u8;
176             // assuming radix is either 10 or 16
177             if c >= b'0' && c <= b'9' {
178                 Some(c - b'0')
179             } else if radix > 10 && c >= b'a' && c < b'a' + (radix - 10) {
180                 Some(c - b'a' + 10)
181             } else if radix > 10 && c >= b'A' && c < b'A' + (radix - 10) {
182                 Some(c - b'A' + 10)
183             } else {
184                 None
185             }
186         }
187
188         self.read_atomically(|p| {
189             p.read_char().and_then(|c| parse_digit(c, radix))
190         })
191     }
192
193     fn read_number_impl(&mut self, radix: u8, max_digits: u32, upto: u32) -> Option<u32> {
194         let mut r = 0u32;
195         let mut digit_count = 0;
196         loop {
197             match self.read_digit(radix) {
198                 Some(d) => {
199                     r = r * (radix as u32) + (d as u32);
200                     digit_count += 1;
201                     if digit_count > max_digits || r >= upto {
202                         return None
203                     }
204                 }
205                 None => {
206                     if digit_count == 0 {
207                         return None
208                     } else {
209                         return Some(r)
210                     }
211                 }
212             };
213         }
214     }
215
216     // Read number, failing if max_digits of number value exceeded
217     fn read_number(&mut self, radix: u8, max_digits: u32, upto: u32) -> Option<u32> {
218         self.read_atomically(|p| p.read_number_impl(radix, max_digits, upto))
219     }
220
221     fn read_ipv4_addr_impl(&mut self) -> Option<IpAddr> {
222         let mut bs = [0u8, ..4];
223         let mut i = 0;
224         while i < 4 {
225             if i != 0 && self.read_given_char('.').is_none() {
226                 return None;
227             }
228
229             let octet = self.read_number(10, 3, 0x100).map(|n| n as u8);
230             match octet {
231                 Some(d) => bs[i] = d,
232                 None => return None,
233             };
234             i += 1;
235         }
236         Some(Ipv4Addr(bs[0], bs[1], bs[2], bs[3]))
237     }
238
239     // Read IPv4 address
240     fn read_ipv4_addr(&mut self) -> Option<IpAddr> {
241         self.read_atomically(|p| p.read_ipv4_addr_impl())
242     }
243
244     fn read_ipv6_addr_impl(&mut self) -> Option<IpAddr> {
245         fn ipv6_addr_from_head_tail(head: &[u16], tail: &[u16]) -> IpAddr {
246             assert!(head.len() + tail.len() <= 8);
247             let mut gs = [0u16, ..8];
248             gs.clone_from_slice(head);
249             gs[mut 8 - tail.len() .. 8].clone_from_slice(tail);
250             Ipv6Addr(gs[0], gs[1], gs[2], gs[3], gs[4], gs[5], gs[6], gs[7])
251         }
252
253         fn read_groups(p: &mut Parser, groups: &mut [u16, ..8], limit: uint) -> (uint, bool) {
254             let mut i = 0;
255             while i < limit {
256                 if i < limit - 1 {
257                     let ipv4 = p.read_atomically(|p| {
258                         if i == 0 || p.read_given_char(':').is_some() {
259                             p.read_ipv4_addr()
260                         } else {
261                             None
262                         }
263                     });
264                     match ipv4 {
265                         Some(Ipv4Addr(a, b, c, d)) => {
266                             groups[i + 0] = (a as u16 << 8) | (b as u16);
267                             groups[i + 1] = (c as u16 << 8) | (d as u16);
268                             return (i + 2, true);
269                         }
270                         _ => {}
271                     }
272                 }
273
274                 let group = p.read_atomically(|p| {
275                     if i == 0 || p.read_given_char(':').is_some() {
276                         p.read_number(16, 4, 0x10000).map(|n| n as u16)
277                     } else {
278                         None
279                     }
280                 });
281                 match group {
282                     Some(g) => groups[i] = g,
283                     None => return (i, false)
284                 }
285                 i += 1;
286             }
287             (i, false)
288         }
289
290         let mut head = [0u16, ..8];
291         let (head_size, head_ipv4) = read_groups(self, &mut head, 8);
292
293         if head_size == 8 {
294             return Some(Ipv6Addr(
295                 head[0], head[1], head[2], head[3],
296                 head[4], head[5], head[6], head[7]))
297         }
298
299         // IPv4 part is not allowed before `::`
300         if head_ipv4 {
301             return None
302         }
303
304         // read `::` if previous code parsed less than 8 groups
305         if !self.read_given_char(':').is_some() || !self.read_given_char(':').is_some() {
306             return None;
307         }
308
309         let mut tail = [0u16, ..8];
310         let (tail_size, _) = read_groups(self, &mut tail, 8 - head_size);
311         Some(ipv6_addr_from_head_tail(head[..head_size], tail[..tail_size]))
312     }
313
314     fn read_ipv6_addr(&mut self) -> Option<IpAddr> {
315         self.read_atomically(|p| p.read_ipv6_addr_impl())
316     }
317
318     fn read_ip_addr(&mut self) -> Option<IpAddr> {
319         let ipv4_addr = |p: &mut Parser| p.read_ipv4_addr();
320         let ipv6_addr = |p: &mut Parser| p.read_ipv6_addr();
321         self.read_or(&mut [ipv4_addr, ipv6_addr])
322     }
323
324     fn read_socket_addr(&mut self) -> Option<SocketAddr> {
325         let ip_addr = |p: &mut Parser| {
326             let ipv4_p = |p: &mut Parser| p.read_ip_addr();
327             let ipv6_p = |p: &mut Parser| {
328                 let open_br = |p: &mut Parser| p.read_given_char('[');
329                 let ip_addr = |p: &mut Parser| p.read_ipv6_addr();
330                 let clos_br = |p: &mut Parser| p.read_given_char(']');
331                 p.read_seq_3::<char, IpAddr, char>(open_br, ip_addr, clos_br)
332                         .map(|t| match t { (_, ip, _) => ip })
333             };
334             p.read_or(&mut [ipv4_p, ipv6_p])
335         };
336         let colon = |p: &mut Parser| p.read_given_char(':');
337         let port  = |p: &mut Parser| p.read_number(10, 5, 0x10000).map(|n| n as u16);
338
339         // host, colon, port
340         self.read_seq_3::<IpAddr, char, u16>(ip_addr, colon, port)
341                 .map(|t| match t { (ip, _, port) => SocketAddr { ip: ip, port: port } })
342     }
343 }
344
345 impl FromStr for IpAddr {
346     fn from_str(s: &str) -> Option<IpAddr> {
347         Parser::new(s).read_till_eof(|p| p.read_ip_addr())
348     }
349 }
350
351 impl FromStr for SocketAddr {
352     fn from_str(s: &str) -> Option<SocketAddr> {
353         Parser::new(s).read_till_eof(|p| p.read_socket_addr())
354     }
355 }
356
357 /// A trait for objects which can be converted or resolved to one or more `SocketAddr` values.
358 ///
359 /// Implementing types minimally have to implement either `to_socket_addr` or `to_socket_addr_all`
360 /// method, and its trivial counterpart will be available automatically.
361 ///
362 /// This trait is used for generic address resolution when constructing network objects.
363 /// By default it is implemented for the following types:
364 ///
365 ///  * `SocketAddr` - `to_socket_addr` is identity function.
366 ///
367 ///  * `(IpAddr, u16)` - `to_socket_addr` constructs `SocketAddr` trivially.
368 ///
369 ///  * `(&str, u16)` - the string should be either a string representation of an IP address
370 ///    expected by `FromStr` implementation for `IpAddr` or a host name.
371 ///
372 ///    For the former, `to_socket_addr_all` returns a vector with a single element corresponding
373 ///    to that IP address joined with the given port.
374 ///
375 ///    For the latter, it tries to resolve the host name and returns a vector of all IP addresses
376 ///    for the host name, each joined with the given port.
377 ///
378 ///  * `&str` - the string should be either a string representation of a `SocketAddr` as
379 ///    expected by its `FromStr` implementation or a string like `<host_name>:<port>` pair
380 ///    where `<port>` is a `u16` value.
381 ///
382 ///    For the former, `to_socker_addr_all` returns a vector with a single element corresponding
383 ///    to that socker address.
384 ///
385 ///    For the latter, it tries to resolve the host name and returns a vector of all IP addresses
386 ///    for the host name, each joined with the port.
387 ///
388 ///
389 /// This trait allows constructing network objects like `TcpStream` or `UdpSocket` easily with
390 /// values of various types for the bind/connection address. It is needed because sometimes
391 /// one type is more appropriate than the other: for simple uses a string like `"localhost:12345"`
392 /// is much nicer than manual construction of the corresponding `SocketAddr`, but sometimes
393 /// `SocketAddr` value is *the* main source of the address, and converting it to some other type
394 /// (e.g. a string) just for it to be converted back to `SocketAddr` in constructor methods
395 /// is pointless.
396 ///
397 /// Some examples:
398 ///
399 /// ```rust,no_run
400 /// # #![allow(unused_must_use)]
401 ///
402 /// use std::io::{TcpStream, TcpListener};
403 /// use std::io::net::udp::UdpSocket;
404 /// use std::io::net::ip::{Ipv4Addr, SocketAddr};
405 ///
406 /// fn main() {
407 ///     // The following lines are equivalent modulo possible "localhost" name resolution
408 ///     // differences
409 ///     let tcp_s = TcpStream::connect(SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 12345 });
410 ///     let tcp_s = TcpStream::connect((Ipv4Addr(127, 0, 0, 1), 12345u16));
411 ///     let tcp_s = TcpStream::connect(("127.0.0.1", 12345u16));
412 ///     let tcp_s = TcpStream::connect(("localhost", 12345u16));
413 ///     let tcp_s = TcpStream::connect("127.0.0.1:12345");
414 ///     let tcp_s = TcpStream::connect("localhost:12345");
415 ///
416 ///     // TcpListener::bind(), UdpSocket::bind() and UdpSocket::send_to() behave similarly
417 ///     let tcp_l = TcpListener::bind("localhost:12345");
418 ///
419 ///     let mut udp_s = UdpSocket::bind(("127.0.0.1", 23451u16)).unwrap();
420 ///     udp_s.send_to([7u8, 7u8, 7u8].as_slice(), (Ipv4Addr(127, 0, 0, 1), 23451u16));
421 /// }
422 /// ```
423 pub trait ToSocketAddr {
424     /// Converts this object to single socket address value.
425     ///
426     /// If more than one value is available, this method returns the first one. If no
427     /// values are available, this method returns an `IoError`.
428     ///
429     /// By default this method delegates to `to_socket_addr_all` method, taking the first
430     /// item from its result.
431     fn to_socket_addr(&self) -> IoResult<SocketAddr> {
432         self.to_socket_addr_all()
433             .and_then(|v| v.into_iter().next().ok_or_else(|| IoError {
434                 kind: io::InvalidInput,
435                 desc: "no address available",
436                 detail: None
437             }))
438     }
439
440     /// Converts this object to all available socket address values.
441     ///
442     /// Some values like host name string naturally corrrespond to multiple IP addresses.
443     /// This method tries to return all available addresses corresponding to this object.
444     ///
445     /// By default this method delegates to `to_socket_addr` method, creating a singleton
446     /// vector from its result.
447     #[inline]
448     fn to_socket_addr_all(&self) -> IoResult<Vec<SocketAddr>> {
449         self.to_socket_addr().map(|a| vec![a])
450     }
451 }
452
453 impl ToSocketAddr for SocketAddr {
454     #[inline]
455     fn to_socket_addr(&self) -> IoResult<SocketAddr> { Ok(*self) }
456 }
457
458 impl ToSocketAddr for (IpAddr, u16) {
459     #[inline]
460     fn to_socket_addr(&self) -> IoResult<SocketAddr> {
461         let (ip, port) = *self;
462         Ok(SocketAddr { ip: ip, port: port })
463     }
464 }
465
466 fn resolve_socket_addr(s: &str, p: u16) -> IoResult<Vec<SocketAddr>> {
467     net::get_host_addresses(s)
468         .map(|v| v.into_iter().map(|a| SocketAddr { ip: a, port: p }).collect())
469 }
470
471 fn parse_and_resolve_socket_addr(s: &str) -> IoResult<Vec<SocketAddr>> {
472     macro_rules! try_opt(
473         ($e:expr, $msg:expr) => (
474             match $e {
475                 Some(r) => r,
476                 None => return Err(IoError {
477                     kind: io::InvalidInput,
478                     desc: $msg,
479                     detail: None
480                 })
481             }
482         )
483     )
484
485     // split the string by ':' and convert the second part to u16
486     let mut parts_iter = s.rsplitn(2, ':');
487     let port_str = try_opt!(parts_iter.next(), "invalid socket address");
488     let host = try_opt!(parts_iter.next(), "invalid socket address");
489     let port: u16 = try_opt!(FromStr::from_str(port_str), "invalid port value");
490     resolve_socket_addr(host, port)
491 }
492
493 impl<'a> ToSocketAddr for (&'a str, u16) {
494     fn to_socket_addr_all(&self) -> IoResult<Vec<SocketAddr>> {
495         let (host, port) = *self;
496
497         // try to parse the host as a regular IpAddr first
498         match FromStr::from_str(host) {
499             Some(addr) => return Ok(vec![SocketAddr {
500                 ip: addr,
501                 port: port
502             }]),
503             None => {}
504         }
505
506         resolve_socket_addr(host, port)
507     }
508 }
509
510 // accepts strings like 'localhost:12345'
511 impl<'a> ToSocketAddr for &'a str {
512     fn to_socket_addr(&self) -> IoResult<SocketAddr> {
513         // try to parse as a regular SocketAddr first
514         match FromStr::from_str(*self) {
515             Some(addr) => return Ok(addr),
516             None => {}
517         }
518
519         parse_and_resolve_socket_addr(*self)
520             .and_then(|v| v.into_iter().next()
521                 .ok_or_else(|| IoError {
522                     kind: io::InvalidInput,
523                     desc: "no address available",
524                     detail: None
525                 })
526             )
527     }
528
529     fn to_socket_addr_all(&self) -> IoResult<Vec<SocketAddr>> {
530         // try to parse as a regular SocketAddr first
531         match FromStr::from_str(*self) {
532             Some(addr) => return Ok(vec![addr]),
533             None => {}
534         }
535
536         parse_and_resolve_socket_addr(*self)
537     }
538 }
539
540
541 #[cfg(test)]
542 mod test {
543     use prelude::*;
544     use super::*;
545     use str::FromStr;
546
547     #[test]
548     fn test_from_str_ipv4() {
549         assert_eq!(Some(Ipv4Addr(127, 0, 0, 1)), FromStr::from_str("127.0.0.1"));
550         assert_eq!(Some(Ipv4Addr(255, 255, 255, 255)), FromStr::from_str("255.255.255.255"));
551         assert_eq!(Some(Ipv4Addr(0, 0, 0, 0)), FromStr::from_str("0.0.0.0"));
552
553         // out of range
554         let none: Option<IpAddr> = FromStr::from_str("256.0.0.1");
555         assert_eq!(None, none);
556         // too short
557         let none: Option<IpAddr> = FromStr::from_str("255.0.0");
558         assert_eq!(None, none);
559         // too long
560         let none: Option<IpAddr> = FromStr::from_str("255.0.0.1.2");
561         assert_eq!(None, none);
562         // no number between dots
563         let none: Option<IpAddr> = FromStr::from_str("255.0..1");
564         assert_eq!(None, none);
565     }
566
567     #[test]
568     fn test_from_str_ipv6() {
569         assert_eq!(Some(Ipv6Addr(0, 0, 0, 0, 0, 0, 0, 0)), FromStr::from_str("0:0:0:0:0:0:0:0"));
570         assert_eq!(Some(Ipv6Addr(0, 0, 0, 0, 0, 0, 0, 1)), FromStr::from_str("0:0:0:0:0:0:0:1"));
571
572         assert_eq!(Some(Ipv6Addr(0, 0, 0, 0, 0, 0, 0, 1)), FromStr::from_str("::1"));
573         assert_eq!(Some(Ipv6Addr(0, 0, 0, 0, 0, 0, 0, 0)), FromStr::from_str("::"));
574
575         assert_eq!(Some(Ipv6Addr(0x2a02, 0x6b8, 0, 0, 0, 0, 0x11, 0x11)),
576                 FromStr::from_str("2a02:6b8::11:11"));
577
578         // too long group
579         let none: Option<IpAddr> = FromStr::from_str("::00000");
580         assert_eq!(None, none);
581         // too short
582         let none: Option<IpAddr> = FromStr::from_str("1:2:3:4:5:6:7");
583         assert_eq!(None, none);
584         // too long
585         let none: Option<IpAddr> = FromStr::from_str("1:2:3:4:5:6:7:8:9");
586         assert_eq!(None, none);
587         // triple colon
588         let none: Option<IpAddr> = FromStr::from_str("1:2:::6:7:8");
589         assert_eq!(None, none);
590         // two double colons
591         let none: Option<IpAddr> = FromStr::from_str("1:2::6::8");
592         assert_eq!(None, none);
593     }
594
595     #[test]
596     fn test_from_str_ipv4_in_ipv6() {
597         assert_eq!(Some(Ipv6Addr(0, 0, 0, 0, 0, 0, 49152, 545)),
598                 FromStr::from_str("::192.0.2.33"));
599         assert_eq!(Some(Ipv6Addr(0, 0, 0, 0, 0, 0xFFFF, 49152, 545)),
600                 FromStr::from_str("::FFFF:192.0.2.33"));
601         assert_eq!(Some(Ipv6Addr(0x64, 0xff9b, 0, 0, 0, 0, 49152, 545)),
602                 FromStr::from_str("64:ff9b::192.0.2.33"));
603         assert_eq!(Some(Ipv6Addr(0x2001, 0xdb8, 0x122, 0xc000, 0x2, 0x2100, 49152, 545)),
604                 FromStr::from_str("2001:db8:122:c000:2:2100:192.0.2.33"));
605
606         // colon after v4
607         let none: Option<IpAddr> = FromStr::from_str("::127.0.0.1:");
608         assert_eq!(None, none);
609         // not enough groups
610         let none: Option<IpAddr> = FromStr::from_str("1.2.3.4.5:127.0.0.1");
611         assert_eq!(None, none);
612         // too many groups
613         let none: Option<IpAddr> =
614             FromStr::from_str("1.2.3.4.5:6:7:127.0.0.1");
615         assert_eq!(None, none);
616     }
617
618     #[test]
619     fn test_from_str_socket_addr() {
620         assert_eq!(Some(SocketAddr { ip: Ipv4Addr(77, 88, 21, 11), port: 80 }),
621                 FromStr::from_str("77.88.21.11:80"));
622         assert_eq!(Some(SocketAddr { ip: Ipv6Addr(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), port: 53 }),
623                 FromStr::from_str("[2a02:6b8:0:1::1]:53"));
624         assert_eq!(Some(SocketAddr { ip: Ipv6Addr(0, 0, 0, 0, 0, 0, 0x7F00, 1), port: 22 }),
625                 FromStr::from_str("[::127.0.0.1]:22"));
626
627         // without port
628         let none: Option<SocketAddr> = FromStr::from_str("127.0.0.1");
629         assert_eq!(None, none);
630         // without port
631         let none: Option<SocketAddr> = FromStr::from_str("127.0.0.1:");
632         assert_eq!(None, none);
633         // wrong brackets around v4
634         let none: Option<SocketAddr> = FromStr::from_str("[127.0.0.1]:22");
635         assert_eq!(None, none);
636         // port out of range
637         let none: Option<SocketAddr> = FromStr::from_str("127.0.0.1:123456");
638         assert_eq!(None, none);
639     }
640
641     #[test]
642     fn ipv6_addr_to_string() {
643         let a1 = Ipv6Addr(0, 0, 0, 0, 0, 0xffff, 0xc000, 0x280);
644         assert!(a1.to_string() == "::ffff:192.0.2.128" ||
645                 a1.to_string() == "::FFFF:192.0.2.128");
646         assert_eq!(Ipv6Addr(8, 9, 10, 11, 12, 13, 14, 15).to_string(),
647                    "8:9:a:b:c:d:e:f");
648     }
649
650     #[test]
651     fn to_socket_addr_socketaddr() {
652         let a = SocketAddr { ip: Ipv4Addr(77, 88, 21, 11), port: 12345 };
653         assert_eq!(Ok(a), a.to_socket_addr());
654         assert_eq!(Ok(vec![a]), a.to_socket_addr_all());
655     }
656
657     #[test]
658     fn to_socket_addr_ipaddr_u16() {
659         let a = Ipv4Addr(77, 88, 21, 11);
660         let p = 12345u16;
661         let e = SocketAddr { ip: a, port: p };
662         assert_eq!(Ok(e), (a, p).to_socket_addr());
663         assert_eq!(Ok(vec![e]), (a, p).to_socket_addr_all());
664     }
665
666     #[test]
667     fn to_socket_addr_str_u16() {
668         let a = SocketAddr { ip: Ipv4Addr(77, 88, 21, 11), port: 24352 };
669         assert_eq!(Ok(a), ("77.88.21.11", 24352u16).to_socket_addr());
670         assert_eq!(Ok(vec![a]), ("77.88.21.11", 24352u16).to_socket_addr_all());
671
672         let a = SocketAddr { ip: Ipv6Addr(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), port: 53 };
673         assert_eq!(Ok(a), ("2a02:6b8:0:1::1", 53).to_socket_addr());
674         assert_eq!(Ok(vec![a]), ("2a02:6b8:0:1::1", 53).to_socket_addr_all());
675
676         let a = SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 23924 };
677         assert!(("localhost", 23924u16).to_socket_addr_all().unwrap().contains(&a));
678     }
679
680     #[test]
681     fn to_socket_addr_str() {
682         let a = SocketAddr { ip: Ipv4Addr(77, 88, 21, 11), port: 24352 };
683         assert_eq!(Ok(a), "77.88.21.11:24352".to_socket_addr());
684         assert_eq!(Ok(vec![a]), "77.88.21.11:24352".to_socket_addr_all());
685
686         let a = SocketAddr { ip: Ipv6Addr(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), port: 53 };
687         assert_eq!(Ok(a), "[2a02:6b8:0:1::1]:53".to_socket_addr());
688         assert_eq!(Ok(vec![a]), "[2a02:6b8:0:1::1]:53".to_socket_addr_all());
689
690         let a = SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 23924 };
691         assert!("localhost:23924".to_socket_addr_all().unwrap().contains(&a));
692     }
693 }