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