Skip to content

Commit e2bb32b

Browse files
committed
libstd: Handle IPv4-Mapped/Compatible IPv6 addresses.
1 parent ac40d53 commit e2bb32b

File tree

1 file changed

+30
-1
lines changed

1 file changed

+30
-1
lines changed

src/libstd/rt/uv/net.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,36 @@ fn uv_ip_as_ip<T>(addr: UvIpAddr, f: &fn(IpAddr) -> T) -> T {
113113
};
114114
match s {
115115
"" => ~[],
116-
s => s.split_iter(':').transform(read_hex_segment).collect(),
116+
// IPv4-Mapped/Compatible IPv6 Address?
117+
s if s.find('.').is_some() => {
118+
let i = s.rfind(':').get_or_default(-1);
119+
120+
let b = s.slice(i + 1, s.len()); // the ipv4 part
121+
122+
let h = b.split_iter('.')
123+
.transform(|s: &str| -> u8 { FromStr::from_str(s).unwrap() })
124+
.transform(|s: u8| -> ~str { fmt!("%02x", s as uint) })
125+
.collect::<~[~str]>();
126+
127+
if i == -1 {
128+
// Ipv4 Compatible Address (::x.x.x.x)
129+
// first 96 bits are zero leaving 32 bits
130+
// for the ipv4 part
131+
// (i.e ::127.0.0.1 == ::7F00:1)
132+
~[num::FromStrRadix::from_str_radix(h[0] + h[1], 16).unwrap(),
133+
num::FromStrRadix::from_str_radix(h[2] + h[3], 16).unwrap()]
134+
} else {
135+
// Ipv4-Mapped Address (::FFFF:x.x.x.x)
136+
// first 80 bits are zero, followed by all ones
137+
// for the next 16 bits, leaving 32 bits for
138+
// the ipv4 part
139+
// (i.e ::FFFF:127.0.0.1 == ::FFFF:7F00:1)
140+
~[1,
141+
num::FromStrRadix::from_str_radix(h[0] + h[1], 16).unwrap(),
142+
num::FromStrRadix::from_str_radix(h[2] + h[3], 16).unwrap()]
143+
}
144+
},
145+
s => s.split_iter(':').transform(read_hex_segment).collect()
117146
}
118147
};
119148
s.split_str_iter("::").transform(convert_each_segment).collect()

0 commit comments

Comments
 (0)