authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-05-28 20:03:04+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-05-28 20:03:04+02:00
log2faf8debf18f6be1f8627a69aca0bfe0d5a736fb
treea9e9e20868d8ebc12dc4242f466e7e55d2dcc4b6
parent3f1dead2fc5922b588fbfb108f421ca957d6934a
parent109e4d85c09339b35e25b5aba2dbd9b83074cfb7

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

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

6 files changed, 21 insertions(+), 15 deletions(-)

lib/std/Io/Kqueue.zig+2-2
......@@ -1401,9 +1401,9 @@ fn openSocketPosix(
14011401 };
14021402 errdefer closeFd(socket_fd);
14031403
1404 if (options.ip6_only) {
1404 if (options.ip6_only) |ip6_only| {
14051405 if (posix.IPV6 == void) return error.OptionUnsupported;
1406 try setSocketOption(k, socket_fd, posix.IPPROTO.IPV6, posix.IPV6.V6ONLY, 1);
1406 try setSocketOption(k, socket_fd, posix.IPPROTO.IPV6, posix.IPV6.V6ONLY, @intFromBool(ip6_only));
14071407 }
14081408
14091409 return socket_fd;
lib/std/Io/Threaded.zig+8-5
......@@ -12407,9 +12407,9 @@ fn openSocketPosix(
1240712407 };
1240812408 errdefer closeFd(socket_fd);
1240912409
12410 if (options.ip6_only) {
12410 if (options.ip6_only) |ip6_only| {
1241112411 if (posix.IPV6 == void) return error.OptionUnsupported;
12412 try setSocketOptionPosix(socket_fd, posix.IPPROTO.IPV6, posix.IPV6.V6ONLY, 1);
12412 try setSocketOptionPosix(socket_fd, posix.IPPROTO.IPV6, posix.IPV6.V6ONLY, @intFromBool(ip6_only));
1241312413 }
1241412414
1241512415 return socket_fd;
......@@ -13627,12 +13627,15 @@ fn netLookupFallible(
1362713627
1362813628 // On Linux, glibc provides getaddrinfo_a which is capable of supporting our semantics.
1362913629 // However, musl's POSIX-compliant getaddrinfo is not, so we bypass it.
13630 const is_glibc = builtin.link_libc and builtin.target.isGnuLibC();
1363013631
13631 if (builtin.target.isGnuLibC()) {
13632 if (is_glibc) {
1363213633 // TODO use getaddrinfo_a / gai_cancel
1363313634 }
1363413635
13635 if (native_os == .linux or is_windows) {
13636 // On Linux, we have to go through glibc because of the Name Service Switch feature.
13637 const non_glibc_linux = native_os == .linux and !is_glibc;
13638 if (non_glibc_linux or is_windows) {
1363613639 if (IpAddress.parseIp6(name, options.port)) |addr| {
1363713640 if (options.family == .ip4) return error.UnknownHostName;
1363813641 if (copyCanon(options.canonical_name_buffer, name)) |canon| {
......@@ -14493,7 +14496,7 @@ fn lookupDns(
1449314496 var socket = s: {
1449414497 if (any_ip6) ip6: {
1449514498 const ip6_addr: IpAddress = .{ .ip6 = .unspecified(0) };
14496 const socket = ip6_addr.bind(t_io, .{ .ip6_only = true, .mode = .dgram }) catch |err| switch (err) {
14499 const socket = ip6_addr.bind(t_io, .{ .ip6_only = false, .mode = .dgram }) catch |err| switch (err) {
1449714500 error.AddressFamilyUnsupported => break :ip6,
1449814501 else => |e| return e,
1449914502 };
lib/std/Io/Uring.zig+2-2
......@@ -5984,9 +5984,9 @@ fn socket(
59845984 };
59855985 errdefer ev.closeAsync(socket_fd);
59865986
5987 if (options.ip6_only) {
5987 if (options.ip6_only) |ip6_only| {
59885988 if (linux.IPV6 == void) return error.OptionUnsupported;
5989 try ev.setsockopt(cancel_region, socket_fd, linux.IPPROTO.IPV6, linux.IPV6.V6ONLY, 1);
5989 try ev.setsockopt(cancel_region, socket_fd, linux.IPPROTO.IPV6, linux.IPV6.V6ONLY, @intFromBool(ip6_only));
59905990 }
59915991
59925992 return socket_fd;
lib/std/Io/net.zig+3-1
......@@ -281,7 +281,9 @@ pub const IpAddress = union(enum) {
281281 /// The socket is restricted to sending and receiving IPv6 packets only.
282282 /// In this case, an IPv4 and an IPv6 application can bind to a single port
283283 /// at the same time.
284 ip6_only: bool = false,
284 ///
285 /// The default is determined by system configuration.
286 ip6_only: ?bool = null,
285287 /// Allow the socket to send datagrams to broadcast addresses.
286288 /// When not enabled any attempt to send datagrams to a broadcast address
287289 /// will fail with `error.AccessDenied`
lib/std/Io/net/test.zig+5-4
......@@ -136,21 +136,22 @@ test "resolve DNS" {
136136 };
137137
138138 var addresses_found: usize = 0;
139 var found_canonical_name = false;
139140
140141 while (results.getOne(io)) |result| switch (result) {
141142 .address => |address| {
142143 if (address.eql(&localhost_v4) or address.eql(&localhost_v6))
143144 addresses_found += 1;
144145 },
145 .canonical_name => |canonical_name| try testing.expectEqualStrings(
146 if (canonical_name.bytes[canonical_name.bytes.len - 1] == '.') "localhost." else "localhost",
147 canonical_name.bytes,
148 ),
146 // We can't test the actual string here because it might be "localhost.localdomain"
147 // or even the computer host name (as on Windows).
148 .canonical_name => found_canonical_name = true,
149149 } else |err| switch (err) {
150150 error.Closed => {},
151151 error.Canceled => |e| return e,
152152 }
153153
154 try testing.expect(found_canonical_name);
154155 try testing.expect(addresses_found != 0);
155156 }
156157
src/Package/Fetch.zig+1-1
......@@ -1212,7 +1212,7 @@ fn initResource(f: *Fetch, uri: std.Uri, resource: *Resource, reader_buffer: []u
12121212 {
12131213 resource.* = .{ .http_request = .{
12141214 .request = http_client.request(.GET, uri, .{}) catch |err|
1215 return f.fail(f.location_tok, try eb.printString("unable to connect to server: {t}", .{err})),
1215 return f.fail(f.location_tok, try eb.printString("server connection failed: {t}", .{err})),
12161216 .response = undefined,
12171217 .transfer_buffer = reader_buffer,
12181218 .decompress_buffer = &.{},