diff options
| author | hequn <hawkbee@gmail.com> | 2023-03-18 03:58:02 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-03-17 15:58:02 -0400 |
| commit | f56f3c5824af17516bcf3a0559b98cdad20bd416 (patch) | |
| tree | 7172d305d5d2c43b64f03351ea3c3918f783f182 /lib/std/net.zig | |
| parent | 71e873703ffc49138d95cb66636856062341c420 (diff) | |
| download | zig-f56f3c5824af17516bcf3a0559b98cdad20bd416.tar.gz zig-f56f3c5824af17516bcf3a0559b98cdad20bd416.zip | |
Enable IPv4 mapped address conversion in linux version getAddressList (#14916)
It seems like the original code of setsockopt is not effective because
i catch the EINVAL branch when uncomment this code, it should call
setsockopt before the bind call.
This should fix issue #14900.
Co-authored-by: Qun He <hawkbee@qq.com>
Diffstat (limited to 'lib/std/net.zig')
| -rw-r--r-- | lib/std/net.zig | 45 |
1 files changed, 24 insertions, 21 deletions
diff --git a/lib/std/net.zig b/lib/std/net.zig index 7222433fd5..8800bbe6be 100644 --- a/lib/std/net.zig +++ b/lib/std/net.zig @@ -741,7 +741,7 @@ pub fn tcpConnectToAddress(address: Address) TcpConnectToAddressError!Stream { return Stream{ .handle = sockfd }; } -const GetAddressListError = std.mem.Allocator.Error || std.fs.File.OpenError || std.fs.File.ReadError || std.os.SocketError || std.os.BindError || error{ +const GetAddressListError = std.mem.Allocator.Error || std.fs.File.OpenError || std.fs.File.ReadError || std.os.SocketError || std.os.BindError || std.os.SetSockOptError || error{ // TODO: break this up into error sets from the various underlying functions TemporaryNameServerFailure, @@ -1534,15 +1534,10 @@ fn resMSendRc( ns[i] = iplit.addr; assert(ns[i].getPort() == 53); if (iplit.addr.any.family != os.AF.INET) { - sl = @sizeOf(os.sockaddr.in6); family = os.AF.INET6; } } - // Get local address and open/bind a socket - var sa: Address = undefined; - @memset(@ptrCast([*]u8, &sa), 0, @sizeOf(Address)); - sa.any.family = family; const flags = os.SOCK.DGRAM | os.SOCK.CLOEXEC | os.SOCK.NONBLOCK; const fd = os.socket(family, flags, 0) catch |err| switch (err) { error.AddressFamilyNotSupported => blk: { @@ -1556,27 +1551,35 @@ fn resMSendRc( else => |e| return e, }; defer os.closeSocket(fd); - try os.bind(fd, &sa.any, sl); // Past this point, there are no errors. Each individual query will // yield either no reply (indicated by zero length) or an answer // packet which is up to the caller to interpret. // Convert any IPv4 addresses in a mixed environment to v4-mapped - // TODO - //if (family == AF.INET6) { - // setsockopt(fd, IPPROTO.IPV6, IPV6_V6ONLY, &(int){0}, sizeof 0); - // for (i=0; i<nns; i++) { - // if (ns[i].sin.sin_family != AF.INET) continue; - // memcpy(ns[i].sin6.sin6_addr.s6_addr+12, - // &ns[i].sin.sin_addr, 4); - // memcpy(ns[i].sin6.sin6_addr.s6_addr, - // "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12); - // ns[i].sin6.sin6_family = AF.INET6; - // ns[i].sin6.sin6_flowinfo = 0; - // ns[i].sin6.sin6_scope_id = 0; - // } - //} + if (family == os.AF.INET6) { + try os.setsockopt( + fd, + os.SOL.IPV6, + os.linux.IPV6.V6ONLY, + &mem.toBytes(@as(c_int, 0)), + ); + for (0..ns.len) |i| { + if (ns[i].any.family != os.AF.INET) continue; + mem.writeIntNative(u32, ns[i].in6.sa.addr[12..], ns[i].in.sa.addr); + mem.copy(u8, ns[i].in6.sa.addr[0..12], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff"); + ns[i].any.family = os.AF.INET6; + ns[i].in6.sa.flowinfo = 0; + ns[i].in6.sa.scope_id = 0; + } + sl = @sizeOf(os.sockaddr.in6); + } + + // Get local address and open/bind a socket + var sa: Address = undefined; + @memset(@ptrCast([*]u8, &sa), 0, @sizeOf(Address)); + sa.any.family = family; + try os.bind(fd, &sa.any, sl); var pfd = [1]os.pollfd{os.pollfd{ .fd = fd, |
