zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 2faf8debf18f6be1f8627a69aca0bfe0d5a736fb (tree)
parent 3f1dead2fc5922b588fbfb108f421ca957d6934a
Author: Andrew Kelley <andrew@ziglang.org>
Date:   Thu, 28 May 2026 20:03:04 +0200

Merge pull request 'DNS fixes' (#35501) from dns-fixes into master

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/35501

Diffstat:
Mlib/std/Io/Kqueue.zig | 4++--
Mlib/std/Io/Threaded.zig | 13++++++++-----
Mlib/std/Io/Uring.zig | 4++--
Mlib/std/Io/net.zig | 4+++-
Mlib/std/Io/net/test.zig | 9+++++----
Msrc/Package/Fetch.zig | 2+-
6 files changed, 21 insertions(+), 15 deletions(-)

diff --git a/lib/std/Io/Kqueue.zig b/lib/std/Io/Kqueue.zig @@ -1401,9 +1401,9 @@ fn openSocketPosix( }; errdefer closeFd(socket_fd); - if (options.ip6_only) { + if (options.ip6_only) |ip6_only| { if (posix.IPV6 == void) return error.OptionUnsupported; - try setSocketOption(k, socket_fd, posix.IPPROTO.IPV6, posix.IPV6.V6ONLY, 1); + try setSocketOption(k, socket_fd, posix.IPPROTO.IPV6, posix.IPV6.V6ONLY, @intFromBool(ip6_only)); } return socket_fd; diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig @@ -12407,9 +12407,9 @@ fn openSocketPosix( }; errdefer closeFd(socket_fd); - if (options.ip6_only) { + if (options.ip6_only) |ip6_only| { if (posix.IPV6 == void) return error.OptionUnsupported; - try setSocketOptionPosix(socket_fd, posix.IPPROTO.IPV6, posix.IPV6.V6ONLY, 1); + try setSocketOptionPosix(socket_fd, posix.IPPROTO.IPV6, posix.IPV6.V6ONLY, @intFromBool(ip6_only)); } return socket_fd; @@ -13627,12 +13627,15 @@ fn netLookupFallible( // On Linux, glibc provides getaddrinfo_a which is capable of supporting our semantics. // However, musl's POSIX-compliant getaddrinfo is not, so we bypass it. + const is_glibc = builtin.link_libc and builtin.target.isGnuLibC(); - if (builtin.target.isGnuLibC()) { + if (is_glibc) { // TODO use getaddrinfo_a / gai_cancel } - if (native_os == .linux or is_windows) { + // On Linux, we have to go through glibc because of the Name Service Switch feature. + const non_glibc_linux = native_os == .linux and !is_glibc; + if (non_glibc_linux or is_windows) { if (IpAddress.parseIp6(name, options.port)) |addr| { if (options.family == .ip4) return error.UnknownHostName; if (copyCanon(options.canonical_name_buffer, name)) |canon| { @@ -14493,7 +14496,7 @@ fn lookupDns( var socket = s: { if (any_ip6) ip6: { const ip6_addr: IpAddress = .{ .ip6 = .unspecified(0) }; - const socket = ip6_addr.bind(t_io, .{ .ip6_only = true, .mode = .dgram }) catch |err| switch (err) { + const socket = ip6_addr.bind(t_io, .{ .ip6_only = false, .mode = .dgram }) catch |err| switch (err) { error.AddressFamilyUnsupported => break :ip6, else => |e| return e, }; diff --git a/lib/std/Io/Uring.zig b/lib/std/Io/Uring.zig @@ -5984,9 +5984,9 @@ fn socket( }; errdefer ev.closeAsync(socket_fd); - if (options.ip6_only) { + if (options.ip6_only) |ip6_only| { if (linux.IPV6 == void) return error.OptionUnsupported; - try ev.setsockopt(cancel_region, socket_fd, linux.IPPROTO.IPV6, linux.IPV6.V6ONLY, 1); + try ev.setsockopt(cancel_region, socket_fd, linux.IPPROTO.IPV6, linux.IPV6.V6ONLY, @intFromBool(ip6_only)); } return socket_fd; diff --git a/lib/std/Io/net.zig b/lib/std/Io/net.zig @@ -281,7 +281,9 @@ pub const IpAddress = union(enum) { /// The socket is restricted to sending and receiving IPv6 packets only. /// In this case, an IPv4 and an IPv6 application can bind to a single port /// at the same time. - ip6_only: bool = false, + /// + /// The default is determined by system configuration. + ip6_only: ?bool = null, /// Allow the socket to send datagrams to broadcast addresses. /// When not enabled any attempt to send datagrams to a broadcast address /// will fail with `error.AccessDenied` diff --git a/lib/std/Io/net/test.zig b/lib/std/Io/net/test.zig @@ -136,21 +136,22 @@ test "resolve DNS" { }; var addresses_found: usize = 0; + var found_canonical_name = false; while (results.getOne(io)) |result| switch (result) { .address => |address| { if (address.eql(&localhost_v4) or address.eql(&localhost_v6)) addresses_found += 1; }, - .canonical_name => |canonical_name| try testing.expectEqualStrings( - if (canonical_name.bytes[canonical_name.bytes.len - 1] == '.') "localhost." else "localhost", - canonical_name.bytes, - ), + // We can't test the actual string here because it might be "localhost.localdomain" + // or even the computer host name (as on Windows). + .canonical_name => found_canonical_name = true, } else |err| switch (err) { error.Closed => {}, error.Canceled => |e| return e, } + try testing.expect(found_canonical_name); try testing.expect(addresses_found != 0); } diff --git a/src/Package/Fetch.zig b/src/Package/Fetch.zig @@ -1212,7 +1212,7 @@ fn initResource(f: *Fetch, uri: std.Uri, resource: *Resource, reader_buffer: []u { resource.* = .{ .http_request = .{ .request = http_client.request(.GET, uri, .{}) catch |err| - return f.fail(f.location_tok, try eb.printString("unable to connect to server: {t}", .{err})), + return f.fail(f.location_tok, try eb.printString("server connection failed: {t}", .{err})), .response = undefined, .transfer_buffer = reader_buffer, .decompress_buffer = &.{},