diff options
Diffstat (limited to 'src/libstd/rt')
| -rw-r--r-- | src/libstd/rt/uv/net.rs | 31 |
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() |
