authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-11-04 19:54:36+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-11-04 19:54:36+02:00
log6e786b60d4fb3a39b717e077d034131be613d6aa
treeaa0d68a8c7a537ba8380571e386105b945d279c5
parent32ac1b5927ba9314b9fa0ec2bb21dba4b2e66c66
signaturelock-open Commit is signed but in an unrecognized format.

support ipv4-mapped ipv6 addresses


2 files changed, 24 insertions(+), 1 deletions(-)

lib/std/net.zig+20
...@@ -32,6 +32,7 @@ pub const IpAddress = extern union {...@@ -32,6 +32,7 @@ pub const IpAddress = extern union {
32 error.InvalidEnd,32 error.InvalidEnd,
33 error.InvalidCharacter,33 error.InvalidCharacter,
34 error.Incomplete,34 error.Incomplete,
35 error.InvalidIpv4Mapping,
35 => {},36 => {},
36 }37 }
3738
...@@ -103,6 +104,24 @@ pub const IpAddress = extern union {...@@ -103,6 +104,24 @@ pub const IpAddress = extern union {
103 }104 }
104 scope_id = true;105 scope_id = true;
105 saw_any_digits = false;106 saw_any_digits = false;
107 } else if (c == '.') {
108 if (!abbrv or ip_slice[0] != 0xff or ip_slice[1] != 0xff) {
109 // must start with '::ffff:'
110 return error.InvalidIpv4Mapping;
111 }
112 const start_index = mem.lastIndexOfScalar(u8, buf[0..i], ':').? + 1;
113 const addr = (parseIp4(buf[start_index..], 0) catch {
114 return error.InvalidIpv4Mapping;
115 }).in.addr;
116 ip_slice = result.in6.addr[0..];
117 ip_slice[10] = 0xff;
118 ip_slice[11] = 0xff;
119
120 ip_slice[12] = @truncate(u8, addr >> 24 & 0xff);
121 ip_slice[13] = @truncate(u8, addr >> 16 & 0xff);
122 ip_slice[14] = @truncate(u8, addr >> 8 & 0xff);
123 ip_slice[15] = @truncate(u8, addr & 0xff);
124 return result;
106 } else {125 } else {
107 const digit = try std.fmt.charToDigit(c, 16);126 const digit = try std.fmt.charToDigit(c, 16);
108 if (@mulWithOverflow(u16, x, 16, &x)) {127 if (@mulWithOverflow(u16, x, 16, &x)) {
...@@ -783,6 +802,7 @@ fn linuxLookupNameFromHosts(...@@ -783,6 +802,7 @@ fn linuxLookupNameFromHosts(
783 error.InvalidCharacter,802 error.InvalidCharacter,
784 error.Incomplete,803 error.Incomplete,
785 error.InvalidIPAddressFormat,804 error.InvalidIPAddressFormat,
805 error.InvalidIpv4Mapping,
786 => continue,806 => continue,
787 };807 };
788 try addrs.append(LookupAddr{ .addr = addr });808 try addrs.append(LookupAddr{ .addr = addr });
lib/std/net/test.zig+4-1
...@@ -14,6 +14,7 @@ test "parse and render IPv6 addresses" {...@@ -14,6 +14,7 @@ test "parse and render IPv6 addresses" {
14 "::1234:5678",14 "::1234:5678",
15 "2001:db8::1234:5678",15 "2001:db8::1234:5678",
16 "FF01::FB%1234",16 "FF01::FB%1234",
17 "::ffff:123.123.123.123",
17 };18 };
18 const printed = [_][]const u8{19 const printed = [_][]const u8{
19 "ff01::fb",20 "ff01::fb",
...@@ -23,7 +24,8 @@ test "parse and render IPv6 addresses" {...@@ -23,7 +24,8 @@ test "parse and render IPv6 addresses" {
23 "2001:db8::",24 "2001:db8::",
24 "::1234:5678",25 "::1234:5678",
25 "2001:db8::1234:5678",26 "2001:db8::1234:5678",
26 "ff01::fb"27 "ff01::fb",
28 "::ffff:7b7b:7b7b",
27 };29 };
28 for (ips) |ip, i| {30 for (ips) |ip, i| {
29 var addr = net.IpAddress.parseIp6(ip, 0) catch unreachable;31 var addr = net.IpAddress.parseIp6(ip, 0) catch unreachable;
...@@ -36,6 +38,7 @@ test "parse and render IPv6 addresses" {...@@ -36,6 +38,7 @@ test "parse and render IPv6 addresses" {
36 testing.expectError(error.InvalidCharacter, net.IpAddress.parseIp6("FF01::Fb:zig", 0));38 testing.expectError(error.InvalidCharacter, net.IpAddress.parseIp6("FF01::Fb:zig", 0));
37 testing.expectError(error.InvalidEnd, net.IpAddress.parseIp6("FF01:0:0:0:0:0:0:FB:", 0));39 testing.expectError(error.InvalidEnd, net.IpAddress.parseIp6("FF01:0:0:0:0:0:0:FB:", 0));
38 testing.expectError(error.Incomplete, net.IpAddress.parseIp6("FF01:", 0));40 testing.expectError(error.Incomplete, net.IpAddress.parseIp6("FF01:", 0));
41 testing.expectError(error.InvalidIpv4Mapping, net.IpAddress.parseIp6("::123.123.123.123", 0));
39}42}
4043
41test "parse and render IPv4 addresses" {44test "parse and render IPv4 addresses" {