Zig Version
0.16.0-dev.1859+212968c57
Steps to Reproduce and Observed Behavior
I am running macOS on Apple Silicon (arm64).
Reproduce by calling into std.Io.Threaded.netLookupFallible, e.g. via std.Io.net.HostName.lookup using Threaded I/O implementation:
conststd=@import("std");constIo=std.Io;constHostName=Io.net.HostName;constQueue=Io.Queue;pubfnmain()!void{varthreaded:Io.Threaded=.init_single_threaded;constio=threaded.io();consthost_name="localhost";constport=8080;varresults:[32]HostName.LookupResult=undefined;varqueue:Queue(HostName.LookupResult)=.init(&results);varcanonical_name_buf:[255]u8=undefined;tryHostName.lookup(HostName{.bytes=host_name},io,&queue,HostName.LookupOptions{.port=port,.canonical_name_buffer=&canonical_name_buf});while(queue.getOne(io))|res|{switch(res){.address=>|address|{switch(address){.ip6=>|ipv6|{std.debug.print("{any}\n",.{ipv6.bytes});},else=>{}}},else=>{}}}else|err|{switch(err){error.Canceled=>unreachable,error.Closed=>{}}}}
Output:
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
Expected Behavior
The full IPv6 address should be returned, i.e. for loopback:
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }
std/Io/Threaded.zig:10759 copies bytes of any, a *sockaddr, into PosixAddress which may need to be interpreted as sockaddr.in6:
const storage: PosixAddress = .{ .any = any.* };
If any is indeed a sockaddr.in6, the last 12 bytes aren't copied. I believe the issue would also manifest in the Windows implementation on line 10603 of the same file.
If the *sockaddr is cast to the correct pointer type (based on any.family) before copying the bytes into a PosixAddress it solves the issue. Happy to take this fix on myself and discuss alternate approaches if necessary - it would be my first contribution to Zig :)
### Zig Version
0.16.0-dev.1859+212968c57
### Steps to Reproduce and Observed Behavior
I am running macOS on Apple Silicon (arm64).
Reproduce by calling into `std.Io.Threaded.netLookupFallible`, e.g. via `std.Io.net.HostName.lookup` using `Threaded` I/O implementation:
```zig
const std = @import("std");
const Io = std.Io;
const HostName = Io.net.HostName;
const Queue = Io.Queue;
pub fn main() !void {
var threaded: Io.Threaded = .init_single_threaded;
const io = threaded.io();
const host_name = "localhost";
const port = 8080;
var results: [32]HostName.LookupResult = undefined;
var queue: Queue(HostName.LookupResult) = .init(&results);
var canonical_name_buf: [255]u8 = undefined;
try HostName.lookup(
HostName{ .bytes = host_name },
io,
&queue,
HostName.LookupOptions{ .port = port, .canonical_name_buffer = &canonical_name_buf }
);
while (queue.getOne(io)) |res| {
switch (res) {
.address => |address| {
switch (address) {
.ip6 => |ipv6| {
std.debug.print("{any}\n", .{ ipv6.bytes });
},
else => {}
}
},
else => {}
}
} else |err| {
switch (err) {
error.Canceled => unreachable,
error.Closed => {}
}
}
}
```
Output:
```
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
```
### Expected Behavior
The full IPv6 address should be returned, i.e. for loopback:
```
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }
```
`std/Io/Threaded.zig:10759` copies bytes of `any`, a `*sockaddr`, into `PosixAddress` which may need to be interpreted as `sockaddr.in6`:
```
const storage: PosixAddress = .{ .any = any.* };
```
If `any` is indeed a `sockaddr.in6`, the last 12 bytes aren't copied. I believe the issue would also manifest in the Windows implementation on line `10603` of the same file.
If the `*sockaddr` is cast to the correct pointer type (based on `any.family`) before copying the bytes into a `PosixAddress` it solves the issue. Happy to take this fix on myself and discuss alternate approaches if necessary - it would be my first contribution to Zig :)