about summary refs log tree commit diff
path: root/src/libstd/rt
diff options
context:
space:
mode:
authorLuqman Aden <me@luqman.ca>2013-07-25 05:47:49 -0400
committerLuqman Aden <me@luqman.ca>2013-07-25 05:57:52 -0400
commite2bb32bea19f8bfd2165361b5ad2d025c2ffeba0 (patch)
tree355fdbb16fdb7436855214315a8ee27dbb91a072 /src/libstd/rt
parentac40d5323da30211c8dd516681c6e518777135e9 (diff)
downloadrust-e2bb32bea19f8bfd2165361b5ad2d025c2ffeba0.tar.gz
rust-e2bb32bea19f8bfd2165361b5ad2d025c2ffeba0.zip
libstd: Handle IPv4-Mapped/Compatible IPv6 addresses.
Diffstat (limited to 'src/libstd/rt')
-rw-r--r--src/libstd/rt/uv/net.rs31
1 files changed, 30 insertions, 1 deletions
diff --git a/src/libstd/rt/uv/net.rs b/src/libstd/rt/uv/net.rs
index dbfe36acbeb..a039f3ab7ed 100644
--- a/src/libstd/rt/uv/net.rs
+++ b/src/libstd/rt/uv/net.rs
@@ -113,7 +113,36 @@ fn uv_ip_as_ip<T>(addr: UvIpAddr, f: &fn(IpAddr) -> T) -> T {
                         };
                         match s {
                             "" => ~[],
-                            s => s.split_iter(':').transform(read_hex_segment).collect(),
+                            // IPv4-Mapped/Compatible IPv6 Address?
+                            s if s.find('.').is_some() => {
+                                let i = s.rfind(':').get_or_default(-1);
+
+                                let b = s.slice(i + 1, s.len()); // the ipv4 part
+
+                                let h = b.split_iter('.')
+                                   .transform(|s: &str| -> u8 { FromStr::from_str(s).unwrap() })
+                                   .transform(|s: u8| -> ~str { fmt!("%02x", s as uint) })
+                                   .collect::<~[~str]>();
+
+                                if i == -1 {
+                                    // Ipv4 Compatible Address (::x.x.x.x)
+                                    // first 96 bits are zero leaving 32 bits
+                                    // for the ipv4 part
+                                    // (i.e ::127.0.0.1 == ::7F00:1)
+                                    ~[num::FromStrRadix::from_str_radix(h[0] + h[1], 16).unwrap(),
+                                      num::FromStrRadix::from_str_radix(h[2] + h[3], 16).unwrap()]
+                                } else {
+                                    // Ipv4-Mapped Address (::FFFF:x.x.x.x)
+                                    // first 80 bits are zero, followed by all ones
+                                    // for the next 16 bits, leaving 32 bits for
+                                    // the ipv4 part
+                                    // (i.e ::FFFF:127.0.0.1 == ::FFFF:7F00:1)
+                                    ~[1,
+                                      num::FromStrRadix::from_str_radix(h[0] + h[1], 16).unwrap(),
+                                      num::FromStrRadix::from_str_radix(h[2] + h[3], 16).unwrap()]
+                                }
+                            },
+                            s => s.split_iter(':').transform(read_hex_segment).collect()
                         }
                     };
                     s.split_str_iter("::").transform(convert_each_segment).collect()