authorgravatar for johnnymarler@gmail.comJonathan Marler <johnnymarler@gmail.com> 2020-07-25 23:29:02-06:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-07-27 07:11:07+00:00
log6cc72af03df86796251f2bca49fa45a006e67be5
treeb0133e7438b7c8af4b79db94925ebe065aba6565
parentc95091e5a50f0bfa120a83292ee546b8c3e11910

Provide Ip4Address and Ip6Address in addition to Address


1 files changed, 279 insertions(+), 196 deletions(-)

lib/std/net.zig+279-196
...@@ -14,8 +14,8 @@ const has_unix_sockets = @hasDecl(os, "sockaddr_un");...@@ -14,8 +14,8 @@ const has_unix_sockets = @hasDecl(os, "sockaddr_un");
1414
15pub const Address = extern union {15pub const Address = extern union {
16 any: os.sockaddr,16 any: os.sockaddr,
17 in: os.sockaddr_in,17 in: Ip4Address,
18 in6: os.sockaddr_in6,18 in6: Ip6Address,
19 un: if (has_unix_sockets) os.sockaddr_un else void,19 un: if (has_unix_sockets) os.sockaddr_un else void,
2020
21 // TODO this crashed the compiler. https://github.com/ziglang/zig/issues/351221 // TODO this crashed the compiler. https://github.com/ziglang/zig/issues/3512
...@@ -76,19 +76,227 @@ pub const Address = extern union {...@@ -76,19 +76,227 @@ pub const Address = extern union {
76 }76 }
77 }77 }
7878
79 pub fn parseIp6(buf: []const u8, port: u16) !Address {
80 return Address{.in6 = try Ip6Address.parse(buf, port) };
81 }
82
83 pub fn resolveIp6(buf: []const u8, port: u16) !Address {
84 return Address{.in6 = try Ip6Address.resolve(buf, port) };
85 }
86
87 pub fn parseIp4(buf: []const u8, port: u16) !Address {
88 return Address {.in = try Ip4Address.parse(buf, port) };
89 }
90
91 pub fn initIp4(addr: [4]u8, port: u16) Address {
92 return Address{.in = Ip4Address.init(addr, port) };
93 }
94
95 pub fn initIp6(addr: [16]u8, port: u16, flowinfo: u32, scope_id: u32) Address {
96 return Address{.in6 = Ip6Address.init(addr, port, flowinfo, scope_id) };
97 }
98
99 pub fn initUnix(path: []const u8) !Address {
100 var sock_addr = os.sockaddr_un{
101 .family = os.AF_UNIX,
102 .path = undefined,
103 };
104
105 // this enables us to have the proper length of the socket in getOsSockLen
106 mem.set(u8, &sock_addr.path, 0);
107
108 if (path.len > sock_addr.path.len) return error.NameTooLong;
109 mem.copy(u8, &sock_addr.path, path);
110
111 return Address{ .un = sock_addr };
112 }
113
114 /// Returns the port in native endian.
115 /// Asserts that the address is ip4 or ip6.
116 pub fn getPort(self: Address) u16 {
117 return switch (self.any.family) {
118 os.AF_INET => self.in.getPort(),
119 os.AF_INET6 => self.in6.getPort(),
120 else => unreachable,
121 };
122 }
123
124 /// `port` is native-endian.
125 /// Asserts that the address is ip4 or ip6.
126 pub fn setPort(self: *Address, port: u16) void {
127 switch (self.any.family) {
128 os.AF_INET => self.in.setPort(port),
129 os.AF_INET6 => self.in6.setPort(port),
130 else => unreachable,
131 }
132 }
133
134 /// Asserts that `addr` is an IP address.
135 /// This function will read past the end of the pointer, with a size depending
136 /// on the address family.
137 pub fn initPosix(addr: *align(4) const os.sockaddr) Address {
138 switch (addr.family) {
139 os.AF_INET => return Address{ .in = Ip4Address{ .sa = @ptrCast(*const os.sockaddr_in, addr).*} },
140 os.AF_INET6 => return Address{ .in6 = Ip6Address{ .sa = @ptrCast(*const os.sockaddr_in6, addr).*} },
141 else => unreachable,
142 }
143 }
144
145 pub fn format(
146 self: Address,
147 comptime fmt: []const u8,
148 options: std.fmt.FormatOptions,
149 out_stream: anytype,
150 ) !void {
151 switch (self.any.family) {
152 os.AF_INET => try self.in.format(fmt, options, out_stream),
153 os.AF_INET6 => try self.in6.format(fmt, options, out_stream),
154 os.AF_UNIX => {
155 if (!has_unix_sockets) {
156 unreachable;
157 }
158
159 try std.fmt.format(out_stream, "{}", .{&self.un.path});
160 },
161 else => unreachable,
162 }
163 }
164
165 pub fn eql(a: Address, b: Address) bool {
166 const a_bytes = @ptrCast([*]const u8, &a.any)[0..a.getOsSockLen()];
167 const b_bytes = @ptrCast([*]const u8, &b.any)[0..b.getOsSockLen()];
168 return mem.eql(u8, a_bytes, b_bytes);
169 }
170
171 pub fn getOsSockLen(self: Address) os.socklen_t {
172 switch (self.any.family) {
173 os.AF_INET => return self.in.getOsSockLen(),
174 os.AF_INET6 => return self.in6.getOsSockLen(),
175 os.AF_UNIX => {
176 if (!has_unix_sockets) {
177 unreachable;
178 }
179
180 const path_len = std.mem.len(@ptrCast([*:0]const u8, &self.un.path));
181 return @intCast(os.socklen_t, @sizeOf(os.sockaddr_un) - self.un.path.len + path_len);
182 },
183 else => unreachable,
184 }
185 }
186};
187
188pub const Ip4Address = extern struct {
189 sa: os.sockaddr_in,
190
191 pub fn parse(buf: []const u8, port: u16) !Ip4Address {
192 var result = Ip4Address{
193 .sa = .{
194 .port = mem.nativeToBig(u16, port),
195 .addr = undefined,
196 }
197 };
198 const out_ptr = mem.sliceAsBytes(@as(*[1]u32, &result.sa.addr)[0..]);
199
200 var x: u8 = 0;
201 var index: u8 = 0;
202 var saw_any_digits = false;
203 for (buf) |c| {
204 if (c == '.') {
205 if (!saw_any_digits) {
206 return error.InvalidCharacter;
207 }
208 if (index == 3) {
209 return error.InvalidEnd;
210 }
211 out_ptr[index] = x;
212 index += 1;
213 x = 0;
214 saw_any_digits = false;
215 } else if (c >= '0' and c <= '9') {
216 saw_any_digits = true;
217 x = try std.math.mul(u8, x, 10);
218 x = try std.math.add(u8, x, c - '0');
219 } else {
220 return error.InvalidCharacter;
221 }
222 }
223 if (index == 3 and saw_any_digits) {
224 out_ptr[index] = x;
225 return result;
226 }
227
228 return error.Incomplete;
229 }
230
231 pub fn resolveIp(name: []const u8, port: u16) !Ip4Address {
232 if (parse(name, port)) |ip4| return ip4 else |err| switch (err) {
233 error.Overflow,
234 error.InvalidEnd,
235 error.InvalidCharacter,
236 error.Incomplete,
237 => {},
238 }
239 return error.InvalidIPAddressFormat;
240 }
241
242 pub fn init(addr: [4]u8, port: u16) Ip4Address {
243 return Ip4Address {
244 .sa = os.sockaddr_in{
245 .port = mem.nativeToBig(u16, port),
246 .addr = @ptrCast(*align(1) const u32, &addr).*,
247 },
248 };
249 }
250
251 /// Returns the port in native endian.
252 /// Asserts that the address is ip4 or ip6.
253 pub fn getPort(self: Ip4Address) u16 {
254 return mem.bigToNative(u16, self.sa.port);
255 }
256
257 /// `port` is native-endian.
258 /// Asserts that the address is ip4 or ip6.
259 pub fn setPort(self: *Ip4Address, port: u16) void {
260 self.sa.port = mem.nativeToBig(u16, port);
261 }
262
263 pub fn format(
264 self: Ip4Address,
265 comptime fmt: []const u8,
266 options: std.fmt.FormatOptions,
267 out_stream: anytype,
268 ) !void {
269 const bytes = @ptrCast(*const [4]u8, &self.sa.addr);
270 try std.fmt.format(out_stream, "{}.{}.{}.{}:{}", .{
271 bytes[0],
272 bytes[1],
273 bytes[2],
274 bytes[3],
275 self.getPort(),
276 });
277 }
278
279 pub fn getOsSockLen(self: Ip4Address) os.socklen_t {
280 return @sizeOf(os.sockaddr_in);
281 }
282};
283
284pub const Ip6Address = extern struct {
285 sa: os.sockaddr_in6,
286
79 /// Parse a given IPv6 address string into an Address.287 /// Parse a given IPv6 address string into an Address.
80 /// Assumes the Scope ID of the address is fully numeric.288 /// Assumes the Scope ID of the address is fully numeric.
81 /// For non-numeric addresses, see `resolveIp6`.289 /// For non-numeric addresses, see `resolveIp6`.
82 pub fn parseIp6(buf: []const u8, port: u16) !Address {290 pub fn parse(buf: []const u8, port: u16) !Ip6Address {
83 var result = Address{291 var result = Ip6Address{
84 .in6 = os.sockaddr_in6{292 .sa = os.sockaddr_in6{
85 .scope_id = 0,293 .scope_id = 0,
86 .port = mem.nativeToBig(u16, port),294 .port = mem.nativeToBig(u16, port),
87 .flowinfo = 0,295 .flowinfo = 0,
88 .addr = undefined,296 .addr = undefined,
89 },297 },
90 };298 };
91 var ip_slice = result.in6.addr[0..];299 var ip_slice = result.sa.addr[0..];
92300
93 var tail: [16]u8 = undefined;301 var tail: [16]u8 = undefined;
94302
...@@ -101,10 +309,10 @@ pub const Address = extern union {...@@ -101,10 +309,10 @@ pub const Address = extern union {
101 if (scope_id) {309 if (scope_id) {
102 if (c >= '0' and c <= '9') {310 if (c >= '0' and c <= '9') {
103 const digit = c - '0';311 const digit = c - '0';
104 if (@mulWithOverflow(u32, result.in6.scope_id, 10, &result.in6.scope_id)) {312 if (@mulWithOverflow(u32, result.sa.scope_id, 10, &result.sa.scope_id)) {
105 return error.Overflow;313 return error.Overflow;
106 }314 }
107 if (@addWithOverflow(u32, result.in6.scope_id, digit, &result.in6.scope_id)) {315 if (@addWithOverflow(u32, result.sa.scope_id, digit, &result.sa.scope_id)) {
108 return error.Overflow;316 return error.Overflow;
109 }317 }
110 } else {318 } else {
...@@ -141,10 +349,10 @@ pub const Address = extern union {...@@ -141,10 +349,10 @@ pub const Address = extern union {
141 return error.InvalidIpv4Mapping;349 return error.InvalidIpv4Mapping;
142 }350 }
143 const start_index = mem.lastIndexOfScalar(u8, buf[0..i], ':').? + 1;351 const start_index = mem.lastIndexOfScalar(u8, buf[0..i], ':').? + 1;
144 const addr = (parseIp4(buf[start_index..], 0) catch {352 const addr = (Ip4Address.parse(buf[start_index..], 0) catch {
145 return error.InvalidIpv4Mapping;353 return error.InvalidIpv4Mapping;
146 }).in.addr;354 }).sa.addr;
147 ip_slice = result.in6.addr[0..];355 ip_slice = result.sa.addr[0..];
148 ip_slice[10] = 0xff;356 ip_slice[10] = 0xff;
149 ip_slice[11] = 0xff;357 ip_slice[11] = 0xff;
150358
...@@ -180,22 +388,22 @@ pub const Address = extern union {...@@ -180,22 +388,22 @@ pub const Address = extern union {
180 index += 1;388 index += 1;
181 ip_slice[index] = @truncate(u8, x);389 ip_slice[index] = @truncate(u8, x);
182 index += 1;390 index += 1;
183 mem.copy(u8, result.in6.addr[16 - index ..], ip_slice[0..index]);391 mem.copy(u8, result.sa.addr[16 - index ..], ip_slice[0..index]);
184 return result;392 return result;
185 }393 }
186 }394 }
187395
188 pub fn resolveIp6(buf: []const u8, port: u16) !Address {396 pub fn resolve(buf: []const u8, port: u16) !Ip6Address {
189 // TODO: Unify the implementations of resolveIp6 and parseIp6.397 // TODO: Unify the implementations of resolveIp6 and parseIp6.
190 var result = Address{398 var result = Ip6Address{
191 .in6 = os.sockaddr_in6{399 .sa = os.sockaddr_in6{
192 .scope_id = 0,400 .scope_id = 0,
193 .port = mem.nativeToBig(u16, port),401 .port = mem.nativeToBig(u16, port),
194 .flowinfo = 0,402 .flowinfo = 0,
195 .addr = undefined,403 .addr = undefined,
196 },404 },
197 };405 };
198 var ip_slice = result.in6.addr[0..];406 var ip_slice = result.sa.addr[0..];
199407
200 var tail: [16]u8 = undefined;408 var tail: [16]u8 = undefined;
201409
...@@ -256,10 +464,10 @@ pub const Address = extern union {...@@ -256,10 +464,10 @@ pub const Address = extern union {
256 return error.InvalidIpv4Mapping;464 return error.InvalidIpv4Mapping;
257 }465 }
258 const start_index = mem.lastIndexOfScalar(u8, buf[0..i], ':').? + 1;466 const start_index = mem.lastIndexOfScalar(u8, buf[0..i], ':').? + 1;
259 const addr = (parseIp4(buf[start_index..], 0) catch {467 const addr = (Ip4Address.parse(buf[start_index..], 0) catch {
260 return error.InvalidIpv4Mapping;468 return error.InvalidIpv4Mapping;
261 }).in.addr;469 }).sa.addr;
262 ip_slice = result.in6.addr[0..];470 ip_slice = result.sa.addr[0..];
263 ip_slice[10] = 0xff;471 ip_slice[10] = 0xff;
264 ip_slice[11] = 0xff;472 ip_slice[11] = 0xff;
265473
...@@ -299,7 +507,7 @@ pub const Address = extern union {...@@ -299,7 +507,7 @@ pub const Address = extern union {
299 };507 };
300 }508 }
301509
302 result.in6.scope_id = resolved_scope_id;510 result.sa.scope_id = resolved_scope_id;
303511
304 if (index == 14) {512 if (index == 14) {
305 ip_slice[14] = @truncate(u8, x >> 8);513 ip_slice[14] = @truncate(u8, x >> 8);
...@@ -310,63 +518,14 @@ pub const Address = extern union {...@@ -310,63 +518,14 @@ pub const Address = extern union {
310 index += 1;518 index += 1;
311 ip_slice[index] = @truncate(u8, x);519 ip_slice[index] = @truncate(u8, x);
312 index += 1;520 index += 1;
313 mem.copy(u8, result.in6.addr[16 - index ..], ip_slice[0..index]);521 mem.copy(u8, result.sa.addr[16 - index ..], ip_slice[0..index]);
314 return result;
315 }
316 }
317
318 pub fn parseIp4(buf: []const u8, port: u16) !Address {
319 var result = Address{
320 .in = os.sockaddr_in{
321 .port = mem.nativeToBig(u16, port),
322 .addr = undefined,
323 },
324 };
325 const out_ptr = mem.sliceAsBytes(@as(*[1]u32, &result.in.addr)[0..]);
326
327 var x: u8 = 0;
328 var index: u8 = 0;
329 var saw_any_digits = false;
330 for (buf) |c| {
331 if (c == '.') {
332 if (!saw_any_digits) {
333 return error.InvalidCharacter;
334 }
335 if (index == 3) {
336 return error.InvalidEnd;
337 }
338 out_ptr[index] = x;
339 index += 1;
340 x = 0;
341 saw_any_digits = false;
342 } else if (c >= '0' and c <= '9') {
343 saw_any_digits = true;
344 x = try std.math.mul(u8, x, 10);
345 x = try std.math.add(u8, x, c - '0');
346 } else {
347 return error.InvalidCharacter;
348 }
349 }
350 if (index == 3 and saw_any_digits) {
351 out_ptr[index] = x;
352 return result;522 return result;
353 }523 }
354
355 return error.Incomplete;
356 }524 }
357525
358 pub fn initIp4(addr: [4]u8, port: u16) Address {526 pub fn init(addr: [16]u8, port: u16, flowinfo: u32, scope_id: u32) Ip6Address {
359 return Address{527 return Ip6Address{
360 .in = os.sockaddr_in{528 .sa = os.sockaddr_in6{
361 .port = mem.nativeToBig(u16, port),
362 .addr = @ptrCast(*align(1) const u32, &addr).*,
363 },
364 };
365 }
366
367 pub fn initIp6(addr: [16]u8, port: u16, flowinfo: u32, scope_id: u32) Address {
368 return Address{
369 .in6 = os.sockaddr_in6{
370 .addr = addr,529 .addr = addr,
371 .port = mem.nativeToBig(u16, port),530 .port = mem.nativeToBig(u16, port),
372 .flowinfo = flowinfo,531 .flowinfo = flowinfo,
...@@ -375,147 +534,71 @@ pub const Address = extern union {...@@ -375,147 +534,71 @@ pub const Address = extern union {
375 };534 };
376 }535 }
377536
378 pub fn initUnix(path: []const u8) !Address {
379 var sock_addr = os.sockaddr_un{
380 .family = os.AF_UNIX,
381 .path = undefined,
382 };
383
384 // this enables us to have the proper length of the socket in getOsSockLen
385 mem.set(u8, &sock_addr.path, 0);
386
387 if (path.len > sock_addr.path.len) return error.NameTooLong;
388 mem.copy(u8, &sock_addr.path, path);
389
390 return Address{ .un = sock_addr };
391 }
392
393 /// Returns the port in native endian.537 /// Returns the port in native endian.
394 /// Asserts that the address is ip4 or ip6.538 /// Asserts that the address is ip4 or ip6.
395 pub fn getPort(self: Address) u16 {539 pub fn getPort(self: Ip6Address) u16 {
396 const big_endian_port = switch (self.any.family) {540 return mem.bigToNative(u16, self.sa.port);
397 os.AF_INET => self.in.port,
398 os.AF_INET6 => self.in6.port,
399 else => unreachable,
400 };
401 return mem.bigToNative(u16, big_endian_port);
402 }541 }
403542
404 /// `port` is native-endian.543 /// `port` is native-endian.
405 /// Asserts that the address is ip4 or ip6.544 /// Asserts that the address is ip4 or ip6.
406 pub fn setPort(self: *Address, port: u16) void {545 pub fn setPort(self: *Ip6Address, port: u16) void {
407 const ptr = switch (self.any.family) {546 self.sa.port = mem.nativeToBig(u16, port);
408 os.AF_INET => &self.in.port,
409 os.AF_INET6 => &self.in6.port,
410 else => unreachable,
411 };
412 ptr.* = mem.nativeToBig(u16, port);
413 }
414
415 /// Asserts that `addr` is an IP address.
416 /// This function will read past the end of the pointer, with a size depending
417 /// on the address family.
418 pub fn initPosix(addr: *align(4) const os.sockaddr) Address {
419 switch (addr.family) {
420 os.AF_INET => return Address{ .in = @ptrCast(*const os.sockaddr_in, addr).* },
421 os.AF_INET6 => return Address{ .in6 = @ptrCast(*const os.sockaddr_in6, addr).* },
422 else => unreachable,
423 }
424 }547 }
425548
426 pub fn format(549 pub fn format(
427 self: Address,550 self: Ip6Address,
428 comptime fmt: []const u8,551 comptime fmt: []const u8,
429 options: std.fmt.FormatOptions,552 options: std.fmt.FormatOptions,
430 out_stream: anytype,553 out_stream: anytype,
431 ) !void {554 ) !void {
432 switch (self.any.family) {555 const port = mem.bigToNative(u16, self.sa.port);
433 os.AF_INET => {556 if (mem.eql(u8, self.sa.addr[0..12], &[_]u8{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff })) {
434 const port = mem.bigToNative(u16, self.in.port);557 try std.fmt.format(out_stream, "[::ffff:{}.{}.{}.{}]:{}", .{
435 const bytes = @ptrCast(*const [4]u8, &self.in.addr);558 self.sa.addr[12],
436 try std.fmt.format(out_stream, "{}.{}.{}.{}:{}", .{559 self.sa.addr[13],
437 bytes[0],560 self.sa.addr[14],
438 bytes[1],561 self.sa.addr[15],
439 bytes[2],562 port,
440 bytes[3],563 });
441 port,564 return;
442 });565 }
443 },566 const big_endian_parts = @ptrCast(*align(1) const [8]u16, &self.sa.addr);
444 os.AF_INET6 => {567 const native_endian_parts = switch (builtin.endian) {
445 const port = mem.bigToNative(u16, self.in6.port);568 .Big => big_endian_parts.*,
446 if (mem.eql(u8, self.in6.addr[0..12], &[_]u8{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff })) {569 .Little => blk: {
447 try std.fmt.format(out_stream, "[::ffff:{}.{}.{}.{}]:{}", .{570 var buf: [8]u16 = undefined;
448 self.in6.addr[12],571 for (big_endian_parts) |part, i| {
449 self.in6.addr[13],572 buf[i] = mem.bigToNative(u16, part);
450 self.in6.addr[14],
451 self.in6.addr[15],
452 port,
453 });
454 return;
455 }
456 const big_endian_parts = @ptrCast(*align(1) const [8]u16, &self.in6.addr);
457 const native_endian_parts = switch (builtin.endian) {
458 .Big => big_endian_parts.*,
459 .Little => blk: {
460 var buf: [8]u16 = undefined;
461 for (big_endian_parts) |part, i| {
462 buf[i] = mem.bigToNative(u16, part);
463 }
464 break :blk buf;
465 },
466 };
467 try out_stream.writeAll("[");
468 var i: usize = 0;
469 var abbrv = false;
470 while (i < native_endian_parts.len) : (i += 1) {
471 if (native_endian_parts[i] == 0) {
472 if (!abbrv) {
473 try out_stream.writeAll(if (i == 0) "::" else ":");
474 abbrv = true;
475 }
476 continue;
477 }
478 try std.fmt.format(out_stream, "{x}", .{native_endian_parts[i]});
479 if (i != native_endian_parts.len - 1) {
480 try out_stream.writeAll(":");
481 }
482 }573 }
483 try std.fmt.format(out_stream, "]:{}", .{port});574 break :blk buf;
484 },575 },
485 os.AF_UNIX => {576 };
486 if (!has_unix_sockets) {577 try out_stream.writeAll("[");
487 unreachable;578 var i: usize = 0;
579 var abbrv = false;
580 while (i < native_endian_parts.len) : (i += 1) {
581 if (native_endian_parts[i] == 0) {
582 if (!abbrv) {
583 try out_stream.writeAll(if (i == 0) "::" else ":");
584 abbrv = true;
488 }585 }
489586 continue;
490 try std.fmt.format(out_stream, "{}", .{&self.un.path});587 }
491 },588 try std.fmt.format(out_stream, "{x}", .{native_endian_parts[i]});
492 else => unreachable,589 if (i != native_endian_parts.len - 1) {
590 try out_stream.writeAll(":");
591 }
493 }592 }
593 try std.fmt.format(out_stream, "]:{}", .{port});
494 }594 }
495595
496 pub fn eql(a: Address, b: Address) bool {596 pub fn getOsSockLen(self: Ip6Address) os.socklen_t {
497 const a_bytes = @ptrCast([*]const u8, &a.any)[0..a.getOsSockLen()];597 return @sizeOf(os.sockaddr_in6);
498 const b_bytes = @ptrCast([*]const u8, &b.any)[0..b.getOsSockLen()];
499 return mem.eql(u8, a_bytes, b_bytes);
500 }
501
502 pub fn getOsSockLen(self: Address) os.socklen_t {
503 switch (self.any.family) {
504 os.AF_INET => return @sizeOf(os.sockaddr_in),
505 os.AF_INET6 => return @sizeOf(os.sockaddr_in6),
506 os.AF_UNIX => {
507 if (!has_unix_sockets) {
508 unreachable;
509 }
510
511 const path_len = std.mem.len(@ptrCast([*:0]const u8, &self.un.path));
512 return @intCast(os.socklen_t, @sizeOf(os.sockaddr_un) - self.un.path.len + path_len);
513 },
514 else => unreachable,
515 }
516 }598 }
517};599};
518600
601
519pub fn connectUnixSocket(path: []const u8) !fs.File {602pub fn connectUnixSocket(path: []const u8) !fs.File {
520 const opt_non_block = if (std.io.is_async) os.SOCK_NONBLOCK else 0;603 const opt_non_block = if (std.io.is_async) os.SOCK_NONBLOCK else 0;
521 const sockfd = try os.socket(604 const sockfd = try os.socket(
...@@ -777,7 +860,7 @@ fn linuxLookupName(...@@ -777,7 +860,7 @@ fn linuxLookupName(
777 @memset(@ptrCast([*]u8, &sa6), 0, @sizeOf(os.sockaddr_in6));860 @memset(@ptrCast([*]u8, &sa6), 0, @sizeOf(os.sockaddr_in6));
778 var da6 = os.sockaddr_in6{861 var da6 = os.sockaddr_in6{
779 .family = os.AF_INET6,862 .family = os.AF_INET6,
780 .scope_id = addr.addr.in6.scope_id,863 .scope_id = addr.addr.in6.sa.scope_id,
781 .port = 65535,864 .port = 65535,
782 .flowinfo = 0,865 .flowinfo = 0,
783 .addr = [1]u8{0} ** 16,866 .addr = [1]u8{0} ** 16,
...@@ -795,7 +878,7 @@ fn linuxLookupName(...@@ -795,7 +878,7 @@ fn linuxLookupName(
795 var salen: os.socklen_t = undefined;878 var salen: os.socklen_t = undefined;
796 var dalen: os.socklen_t = undefined;879 var dalen: os.socklen_t = undefined;
797 if (addr.addr.any.family == os.AF_INET6) {880 if (addr.addr.any.family == os.AF_INET6) {
798 mem.copy(u8, &da6.addr, &addr.addr.in6.addr);881 mem.copy(u8, &da6.addr, &addr.addr.in6.sa.addr);
799 da = @ptrCast(*os.sockaddr, &da6);882 da = @ptrCast(*os.sockaddr, &da6);
800 dalen = @sizeOf(os.sockaddr_in6);883 dalen = @sizeOf(os.sockaddr_in6);
801 sa = @ptrCast(*os.sockaddr, &sa6);884 sa = @ptrCast(*os.sockaddr, &sa6);
...@@ -803,8 +886,8 @@ fn linuxLookupName(...@@ -803,8 +886,8 @@ fn linuxLookupName(
803 } else {886 } else {
804 mem.copy(u8, &sa6.addr, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff");887 mem.copy(u8, &sa6.addr, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff");
805 mem.copy(u8, &da6.addr, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff");888 mem.copy(u8, &da6.addr, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff");
806 mem.writeIntNative(u32, da6.addr[12..], addr.addr.in.addr);889 mem.writeIntNative(u32, da6.addr[12..], addr.addr.in.sa.addr);
807 da4.addr = addr.addr.in.addr;890 da4.addr = addr.addr.in.sa.addr;
808 da = @ptrCast(*os.sockaddr, &da4);891 da = @ptrCast(*os.sockaddr, &da4);
809 dalen = @sizeOf(os.sockaddr_in);892 dalen = @sizeOf(os.sockaddr_in);
810 sa = @ptrCast(*os.sockaddr, &sa4);893 sa = @ptrCast(*os.sockaddr, &sa4);