authorgravatar for git@l4.pmLuna <git@l4.pm> 2019-11-08 19:35:04-03:00
committergravatar for git@l4.pmLuna <git@l4.pm> 2019-11-08 19:35:04-03:00
log5d05cfcfe6144a7f49f57cb376863edd0059d9ca
treeac74983cbb2bb1de382b99107e85d67e5521bb0f
parent6d28b28ccc689e6bf8849b1d39e969e8da760999

rename IpAddress to Address, add Address.unix


2 files changed, 58 insertions(+), 57 deletions(-)

lib/std/net.zig+43-42
......@@ -10,15 +10,16 @@ test "" {
1010 _ = @import("net/test.zig");
1111}
1212
13pub const IpAddress = extern union {
13pub const Address = extern union {
1414 any: os.sockaddr,
1515 in: os.sockaddr_in,
1616 in6: os.sockaddr_in6,
17 unix: os.sockaddr_un,
1718
1819 // TODO this crashed the compiler
1920 //pub const localhost = initIp4(parseIp4("127.0.0.1") catch unreachable, 0);
2021
21 pub fn parse(name: []const u8, port: u16) !IpAddress {
22 pub fn parseIp(name: []const u8, port: u16) !Address {
2223 if (parseIp4(name, port)) |ip4| return ip4 else |err| switch (err) {
2324 error.Overflow,
2425 error.InvalidEnd,
......@@ -39,7 +40,7 @@ pub const IpAddress = extern union {
3940 return error.InvalidIPAddressFormat;
4041 }
4142
42 pub fn parseExpectingFamily(name: []const u8, family: os.sa_family_t, port: u16) !IpAddress {
43 pub fn parseExpectingFamily(name: []const u8, family: os.sa_family_t, port: u16) !Address {
4344 switch (family) {
4445 os.AF_INET => return parseIp4(name, port),
4546 os.AF_INET6 => return parseIp6(name, port),
......@@ -48,8 +49,8 @@ pub const IpAddress = extern union {
4849 }
4950 }
5051
51 pub fn parseIp6(buf: []const u8, port: u16) !IpAddress {
52 var result = IpAddress{
52 pub fn parseIp6(buf: []const u8, port: u16) !Address {
53 var result = Address{
5354 .in6 = os.sockaddr_in6{
5455 .scope_id = 0,
5556 .port = mem.nativeToBig(u16, port),
......@@ -154,8 +155,8 @@ pub const IpAddress = extern union {
154155 }
155156 }
156157
157 pub fn parseIp4(buf: []const u8, port: u16) !IpAddress {
158 var result = IpAddress{
158 pub fn parseIp4(buf: []const u8, port: u16) !Address {
159 var result = Address{
159160 .in = os.sockaddr_in{
160161 .port = mem.nativeToBig(u16, port),
161162 .addr = undefined,
......@@ -194,8 +195,8 @@ pub const IpAddress = extern union {
194195 return error.Incomplete;
195196 }
196197
197 pub fn initIp4(addr: [4]u8, port: u16) IpAddress {
198 return IpAddress{
198 pub fn initIp4(addr: [4]u8, port: u16) Address {
199 return Address{
199200 .in = os.sockaddr_in{
200201 .port = mem.nativeToBig(u16, port),
201202 .addr = @ptrCast(*align(1) const u32, &addr).*,
......@@ -203,8 +204,8 @@ pub const IpAddress = extern union {
203204 };
204205 }
205206
206 pub fn initIp6(addr: [16]u8, port: u16, flowinfo: u32, scope_id: u32) IpAddress {
207 return IpAddress{
207 pub fn initIp6(addr: [16]u8, port: u16, flowinfo: u32, scope_id: u32) Address {
208 return Address{
208209 .in6 = os.sockaddr_in6{
209210 .addr = addr,
210211 .port = mem.nativeToBig(u16, port),
......@@ -215,7 +216,7 @@ pub const IpAddress = extern union {
215216 }
216217
217218 /// Returns the port in native endian.
218 pub fn getPort(self: IpAddress) u16 {
219 pub fn getPort(self: Address) u16 {
219220 const big_endian_port = switch (self.any.family) {
220221 os.AF_INET => self.in.port,
221222 os.AF_INET6 => self.in6.port,
......@@ -225,7 +226,7 @@ pub const IpAddress = extern union {
225226 }
226227
227228 /// `port` is native-endian.
228 pub fn setPort(self: *IpAddress, port: u16) void {
229 pub fn setPort(self: *Address, port: u16) void {
229230 const ptr = switch (self.any.family) {
230231 os.AF_INET => &self.in.port,
231232 os.AF_INET6 => &self.in6.port,
......@@ -237,16 +238,16 @@ pub const IpAddress = extern union {
237238 /// Asserts that `addr` is an IP address.
238239 /// This function will read past the end of the pointer, with a size depending
239240 /// on the address family.
240 pub fn initPosix(addr: *align(4) const os.sockaddr) IpAddress {
241 pub fn initPosix(addr: *align(4) const os.sockaddr) Address {
241242 switch (addr.family) {
242 os.AF_INET => return IpAddress{ .in = @ptrCast(*const os.sockaddr_in, addr).* },
243 os.AF_INET6 => return IpAddress{ .in6 = @ptrCast(*const os.sockaddr_in6, addr).* },
243 os.AF_INET => return Address{ .in = @ptrCast(*const os.sockaddr_in, addr).* },
244 os.AF_INET6 => return Address{ .in6 = @ptrCast(*const os.sockaddr_in6, addr).* },
244245 else => unreachable,
245246 }
246247 }
247248
248249 pub fn format(
249 self: IpAddress,
250 self: Address,
250251 comptime fmt: []const u8,
251252 options: std.fmt.FormatOptions,
252253 context: var,
......@@ -271,7 +272,7 @@ pub const IpAddress = extern union {
271272 },
272273 os.AF_INET6 => {
273274 const port = mem.bigToNative(u16, self.in6.port);
274 if (mem.eql(u8, self.in6.addr[0..12], [_]u8{0,0,0,0,0,0,0,0,0,0,0xff,0xff})) {
275 if (mem.eql(u8, self.in6.addr[0..12], [_]u8{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff })) {
275276 try std.fmt.format(
276277 context,
277278 Errors,
......@@ -318,13 +319,13 @@ pub const IpAddress = extern union {
318319 }
319320 }
320321
321 pub fn eql(a: IpAddress, b: IpAddress) bool {
322 pub fn eql(a: Address, b: Address) bool {
322323 const a_bytes = @ptrCast([*]const u8, &a.any)[0..a.getOsSockLen()];
323324 const b_bytes = @ptrCast([*]const u8, &b.any)[0..b.getOsSockLen()];
324325 return mem.eql(u8, a_bytes, b_bytes);
325326 }
326327
327 fn getOsSockLen(self: IpAddress) os.socklen_t {
328 fn getOsSockLen(self: Address) os.socklen_t {
328329 switch (self.any.family) {
329330 os.AF_INET => return @sizeOf(os.sockaddr_in),
330331 os.AF_INET6 => return @sizeOf(os.sockaddr_in6),
......@@ -358,7 +359,7 @@ pub fn connectUnixSocket(path: []const u8) !fs.File {
358359
359360pub const AddressList = struct {
360361 arena: std.heap.ArenaAllocator,
361 addrs: []IpAddress,
362 addrs: []Address,
362363 canon_name: ?[]u8,
363364
364365 fn deinit(self: *AddressList) void {
......@@ -381,7 +382,7 @@ pub fn tcpConnectToHost(allocator: *mem.Allocator, name: []const u8, port: u16)
381382 return tcpConnectToAddress(addrs[0], port);
382383}
383384
384pub fn tcpConnectToAddress(address: IpAddress) !fs.File {
385pub fn tcpConnectToAddress(address: Address) !fs.File {
385386 const nonblock = if (std.io.is_async) os.SOCK_NONBLOCK else 0;
386387 const sock_flags = os.SOCK_STREAM | os.SOCK_CLOEXEC | nonblock;
387388 const sockfd = try os.socket(address.any.family, sock_flags, os.IPPROTO_TCP);
......@@ -456,13 +457,13 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !*
456457 }
457458 break :blk count;
458459 };
459 result.addrs = try arena.alloc(IpAddress, addr_count);
460 result.addrs = try arena.alloc(Address, addr_count);
460461
461462 var it: ?*os.addrinfo = res;
462463 var i: usize = 0;
463464 while (it) |info| : (it = info.next) {
464465 const addr = info.addr orelse continue;
465 result.addrs[i] = IpAddress.initPosix(@alignCast(4, addr));
466 result.addrs[i] = Address.initPosix(@alignCast(4, addr));
466467
467468 if (info.canonname) |n| {
468469 if (result.canon_name == null) {
......@@ -485,7 +486,7 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !*
485486
486487 try linuxLookupName(&lookup_addrs, &canon, name, family, flags, port);
487488
488 result.addrs = try arena.alloc(IpAddress, lookup_addrs.len);
489 result.addrs = try arena.alloc(Address, lookup_addrs.len);
489490 if (!canon.isNull()) {
490491 result.canon_name = canon.toOwnedSlice();
491492 }
......@@ -501,7 +502,7 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !*
501502}
502503
503504const LookupAddr = struct {
504 addr: IpAddress,
505 addr: Address,
505506 sortkey: i32 = 0,
506507};
507508
......@@ -524,7 +525,7 @@ fn linuxLookupName(
524525 if (opt_name) |name| {
525526 // reject empty name and check len so it fits into temp bufs
526527 try canon.replaceContents(name);
527 if (IpAddress.parseExpectingFamily(name, family, port)) |addr| {
528 if (Address.parseExpectingFamily(name, family, port)) |addr| {
528529 try addrs.append(LookupAddr{ .addr = addr });
529530 } else |name_err| if ((flags & std.c.AI_NUMERICHOST) != 0) {
530531 return name_err;
......@@ -751,23 +752,23 @@ fn linuxLookupNameFromNull(
751752 if ((flags & std.c.AI_PASSIVE) != 0) {
752753 if (family != os.AF_INET6) {
753754 (try addrs.addOne()).* = LookupAddr{
754 .addr = IpAddress.initIp4([1]u8{0} ** 4, port),
755 .addr = Address.initIp4([1]u8{0} ** 4, port),
755756 };
756757 }
757758 if (family != os.AF_INET) {
758759 (try addrs.addOne()).* = LookupAddr{
759 .addr = IpAddress.initIp6([1]u8{0} ** 16, port, 0, 0),
760 .addr = Address.initIp6([1]u8{0} ** 16, port, 0, 0),
760761 };
761762 }
762763 } else {
763764 if (family != os.AF_INET6) {
764765 (try addrs.addOne()).* = LookupAddr{
765 .addr = IpAddress.initIp4([4]u8{ 127, 0, 0, 1 }, port),
766 .addr = Address.initIp4([4]u8{ 127, 0, 0, 1 }, port),
766767 };
767768 }
768769 if (family != os.AF_INET) {
769770 (try addrs.addOne()).* = LookupAddr{
770 .addr = IpAddress.initIp6(([1]u8{0} ** 15) ++ [1]u8{1}, port, 0, 0),
771 .addr = Address.initIp6(([1]u8{0} ** 15) ++ [1]u8{1}, port, 0, 0),
771772 };
772773 }
773774 }
......@@ -812,7 +813,7 @@ fn linuxLookupNameFromHosts(
812813 }
813814 } else continue;
814815
815 const addr = IpAddress.parseExpectingFamily(ip_text, family, port) catch |err| switch (err) {
816 const addr = Address.parseExpectingFamily(ip_text, family, port) catch |err| switch (err) {
816817 error.Overflow,
817818 error.InvalidEnd,
818819 error.InvalidCharacter,
......@@ -1033,7 +1034,7 @@ fn linuxLookupNameFromNumericUnspec(
10331034 name: []const u8,
10341035 port: u16,
10351036) !void {
1036 const addr = try IpAddress.parse(name, port);
1037 const addr = try Address.parse(name, port);
10371038 (try addrs.addOne()).* = LookupAddr{ .addr = addr };
10381039}
10391040
......@@ -1049,7 +1050,7 @@ fn resMSendRc(
10491050 var sl: os.socklen_t = @sizeOf(os.sockaddr_in);
10501051 var family: os.sa_family_t = os.AF_INET;
10511052
1052 var ns_list = std.ArrayList(IpAddress).init(rc.ns.allocator);
1053 var ns_list = std.ArrayList(Address).init(rc.ns.allocator);
10531054 defer ns_list.deinit();
10541055
10551056 try ns_list.resize(rc.ns.len);
......@@ -1065,8 +1066,8 @@ fn resMSendRc(
10651066 }
10661067
10671068 // Get local address and open/bind a socket
1068 var sa: IpAddress = undefined;
1069 @memset(@ptrCast([*]u8, &sa), 0, @sizeOf(IpAddress));
1069 var sa: Address = undefined;
1070 @memset(@ptrCast([*]u8, &sa), 0, @sizeOf(Address));
10701071 sa.any.family = family;
10711072 const flags = os.SOCK_DGRAM | os.SOCK_CLOEXEC | os.SOCK_NONBLOCK;
10721073 const fd = os.socket(family, flags, 0) catch |err| switch (err) {
......@@ -1224,7 +1225,7 @@ fn dnsParseCallback(ctx: dpc_ctx, rr: u8, data: []const u8, packet: []const u8)
12241225 const new_addr = try ctx.addrs.addOne();
12251226 new_addr.* = LookupAddr{
12261227 // TODO slice [0..4] to make this *[4]u8 without @ptrCast
1227 .addr = IpAddress.initIp4(@ptrCast(*const [4]u8, data.ptr).*, ctx.port),
1228 .addr = Address.initIp4(@ptrCast(*const [4]u8, data.ptr).*, ctx.port),
12281229 };
12291230 },
12301231 os.RR_AAAA => {
......@@ -1232,7 +1233,7 @@ fn dnsParseCallback(ctx: dpc_ctx, rr: u8, data: []const u8, packet: []const u8)
12321233 const new_addr = try ctx.addrs.addOne();
12331234 new_addr.* = LookupAddr{
12341235 // TODO slice [0..16] to make this *[16]u8 without @ptrCast
1235 .addr = IpAddress.initIp6(@ptrCast(*const [16]u8, data.ptr).*, ctx.port, 0, 0),
1236 .addr = Address.initIp6(@ptrCast(*const [16]u8, data.ptr).*, ctx.port, 0, 0),
12361237 };
12371238 },
12381239 os.RR_CNAME => {
......@@ -1253,7 +1254,7 @@ pub const TcpServer = struct {
12531254 kernel_backlog: u32,
12541255
12551256 /// `undefined` until `listen` returns successfully.
1256 listen_address: IpAddress,
1257 listen_address: Address,
12571258
12581259 sockfd: ?os.fd_t,
12591260
......@@ -1280,7 +1281,7 @@ pub const TcpServer = struct {
12801281 self.* = undefined;
12811282 }
12821283
1283 pub fn listen(self: *TcpServer, address: IpAddress) !void {
1284 pub fn listen(self: *TcpServer, address: Address) !void {
12841285 const nonblock = if (std.io.is_async) os.SOCK_NONBLOCK else 0;
12851286 const sock_flags = os.SOCK_STREAM | os.SOCK_CLOEXEC | nonblock;
12861287 const sockfd = try os.socket(os.AF_INET, sock_flags, os.IPPROTO_TCP);
......@@ -1330,8 +1331,8 @@ pub const TcpServer = struct {
13301331 pub fn accept(self: *TcpServer) AcceptError!fs.File {
13311332 const nonblock = if (std.io.is_async) os.SOCK_NONBLOCK else 0;
13321333 const accept_flags = nonblock | os.SOCK_CLOEXEC;
1333 var accepted_addr: IpAddress = undefined;
1334 var adr_len: os.socklen_t = @sizeOf(IpAddress);
1334 var accepted_addr: Address = undefined;
1335 var adr_len: os.socklen_t = @sizeOf(Address);
13351336 if (os.accept4(self.sockfd.?, &accepted_addr.any, &adr_len, accept_flags)) |fd| {
13361337 return fs.File.openHandle(fd);
13371338 } else |err| switch (err) {
lib/std/net/test.zig+15-15
......@@ -28,17 +28,17 @@ test "parse and render IPv6 addresses" {
2828 "::ffff:123.5.123.5",
2929 };
3030 for (ips) |ip, i| {
31 var addr = net.IpAddress.parseIp6(ip, 0) catch unreachable;
31 var addr = net.Address.parseIp6(ip, 0) catch unreachable;
3232 var newIp = std.fmt.bufPrint(buffer[0..], "{}", addr) catch unreachable;
3333 std.testing.expect(std.mem.eql(u8, printed[i], newIp[1 .. newIp.len - 3]));
3434 }
3535
36 testing.expectError(error.InvalidCharacter, net.IpAddress.parseIp6(":::", 0));
37 testing.expectError(error.Overflow, net.IpAddress.parseIp6("FF001::FB", 0));
38 testing.expectError(error.InvalidCharacter, net.IpAddress.parseIp6("FF01::Fb:zig", 0));
39 testing.expectError(error.InvalidEnd, net.IpAddress.parseIp6("FF01:0:0:0:0:0:0:FB:", 0));
40 testing.expectError(error.Incomplete, net.IpAddress.parseIp6("FF01:", 0));
41 testing.expectError(error.InvalidIpv4Mapping, net.IpAddress.parseIp6("::123.123.123.123", 0));
36 testing.expectError(error.InvalidCharacter, net.Address.parseIp6(":::", 0));
37 testing.expectError(error.Overflow, net.Address.parseIp6("FF001::FB", 0));
38 testing.expectError(error.InvalidCharacter, net.Address.parseIp6("FF01::Fb:zig", 0));
39 testing.expectError(error.InvalidEnd, net.Address.parseIp6("FF01:0:0:0:0:0:0:FB:", 0));
40 testing.expectError(error.Incomplete, net.Address.parseIp6("FF01:", 0));
41 testing.expectError(error.InvalidIpv4Mapping, net.Address.parseIp6("::123.123.123.123", 0));
4242}
4343
4444test "parse and render IPv4 addresses" {
......@@ -50,16 +50,16 @@ test "parse and render IPv4 addresses" {
5050 "123.255.0.91",
5151 "127.0.0.1",
5252 }) |ip| {
53 var addr = net.IpAddress.parseIp4(ip, 0) catch unreachable;
53 var addr = net.Address.parseIp4(ip, 0) catch unreachable;
5454 var newIp = std.fmt.bufPrint(buffer[0..], "{}", addr) catch unreachable;
5555 std.testing.expect(std.mem.eql(u8, ip, newIp[0 .. newIp.len - 2]));
5656 }
5757
58 testing.expectError(error.Overflow, net.IpAddress.parseIp4("256.0.0.1", 0));
59 testing.expectError(error.InvalidCharacter, net.IpAddress.parseIp4("x.0.0.1", 0));
60 testing.expectError(error.InvalidEnd, net.IpAddress.parseIp4("127.0.0.1.1", 0));
61 testing.expectError(error.Incomplete, net.IpAddress.parseIp4("127.0.0.", 0));
62 testing.expectError(error.InvalidCharacter, net.IpAddress.parseIp4("100..0.1", 0));
58 testing.expectError(error.Overflow, net.Address.parseIp4("256.0.0.1", 0));
59 testing.expectError(error.InvalidCharacter, net.Address.parseIp4("x.0.0.1", 0));
60 testing.expectError(error.InvalidEnd, net.Address.parseIp4("127.0.0.1.1", 0));
61 testing.expectError(error.Incomplete, net.Address.parseIp4("127.0.0.", 0));
62 testing.expectError(error.InvalidCharacter, net.Address.parseIp4("100..0.1", 0));
6363}
6464
6565test "resolve DNS" {
......@@ -91,7 +91,7 @@ test "listen on a port, send bytes, receive bytes" {
9191 }
9292
9393 // TODO doing this at comptime crashed the compiler
94 const localhost = net.IpAddress.parse("127.0.0.1", 0);
94 const localhost = net.Address.parse("127.0.0.1", 0);
9595
9696 var server = net.TcpServer.init(net.TcpServer.Options{});
9797 defer server.deinit();
......@@ -104,7 +104,7 @@ test "listen on a port, send bytes, receive bytes" {
104104 try await client_frame;
105105}
106106
107fn testClient(addr: net.IpAddress) anyerror!void {
107fn testClient(addr: net.Address) anyerror!void {
108108 const socket_file = try net.tcpConnectToAddress(addr);
109109 defer socket_file.close();
110110