authorgravatar for hawkbee@gmail.comhequn <hawkbee@gmail.com> 2023-03-18 03:58:02+08:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-03-17 15:58:02-04:00
logf56f3c5824af17516bcf3a0559b98cdad20bd416
tree7172d305d5d2c43b64f03351ea3c3918f783f182
parent71e873703ffc49138d95cb66636856062341c420
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

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>

1 files changed, 24 insertions(+), 21 deletions(-)

lib/std/net.zig+24-21
......@@ -741,7 +741,7 @@ pub fn tcpConnectToAddress(address: Address) TcpConnectToAddressError!Stream {
741741 return Stream{ .handle = sockfd };
742742}
743743
744const GetAddressListError = std.mem.Allocator.Error || std.fs.File.OpenError || std.fs.File.ReadError || std.os.SocketError || std.os.BindError || error{
744const GetAddressListError = std.mem.Allocator.Error || std.fs.File.OpenError || std.fs.File.ReadError || std.os.SocketError || std.os.BindError || std.os.SetSockOptError || error{
745745 // TODO: break this up into error sets from the various underlying functions
746746
747747 TemporaryNameServerFailure,
......@@ -1534,15 +1534,10 @@ fn resMSendRc(
15341534 ns[i] = iplit.addr;
15351535 assert(ns[i].getPort() == 53);
15361536 if (iplit.addr.any.family != os.AF.INET) {
1537 sl = @sizeOf(os.sockaddr.in6);
15381537 family = os.AF.INET6;
15391538 }
15401539 }
15411540
1542 // Get local address and open/bind a socket
1543 var sa: Address = undefined;
1544 @memset(@ptrCast([*]u8, &sa), 0, @sizeOf(Address));
1545 sa.any.family = family;
15461541 const flags = os.SOCK.DGRAM | os.SOCK.CLOEXEC | os.SOCK.NONBLOCK;
15471542 const fd = os.socket(family, flags, 0) catch |err| switch (err) {
15481543 error.AddressFamilyNotSupported => blk: {
......@@ -1556,27 +1551,35 @@ fn resMSendRc(
15561551 else => |e| return e,
15571552 };
15581553 defer os.closeSocket(fd);
1559 try os.bind(fd, &sa.any, sl);
15601554
15611555 // Past this point, there are no errors. Each individual query will
15621556 // yield either no reply (indicated by zero length) or an answer
15631557 // packet which is up to the caller to interpret.
15641558
15651559 // Convert any IPv4 addresses in a mixed environment to v4-mapped
1566 // TODO
1567 //if (family == AF.INET6) {
1568 // setsockopt(fd, IPPROTO.IPV6, IPV6_V6ONLY, &(int){0}, sizeof 0);
1569 // for (i=0; i<nns; i++) {
1570 // if (ns[i].sin.sin_family != AF.INET) continue;
1571 // memcpy(ns[i].sin6.sin6_addr.s6_addr+12,
1572 // &ns[i].sin.sin_addr, 4);
1573 // memcpy(ns[i].sin6.sin6_addr.s6_addr,
1574 // "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12);
1575 // ns[i].sin6.sin6_family = AF.INET6;
1576 // ns[i].sin6.sin6_flowinfo = 0;
1577 // ns[i].sin6.sin6_scope_id = 0;
1578 // }
1579 //}
1560 if (family == os.AF.INET6) {
1561 try os.setsockopt(
1562 fd,
1563 os.SOL.IPV6,
1564 os.linux.IPV6.V6ONLY,
1565 &mem.toBytes(@as(c_int, 0)),
1566 );
1567 for (0..ns.len) |i| {
1568 if (ns[i].any.family != os.AF.INET) continue;
1569 mem.writeIntNative(u32, ns[i].in6.sa.addr[12..], ns[i].in.sa.addr);
1570 mem.copy(u8, ns[i].in6.sa.addr[0..12], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff");
1571 ns[i].any.family = os.AF.INET6;
1572 ns[i].in6.sa.flowinfo = 0;
1573 ns[i].in6.sa.scope_id = 0;
1574 }
1575 sl = @sizeOf(os.sockaddr.in6);
1576 }
1577
1578 // Get local address and open/bind a socket
1579 var sa: Address = undefined;
1580 @memset(@ptrCast([*]u8, &sa), 0, @sizeOf(Address));
1581 sa.any.family = family;
1582 try os.bind(fd, &sa.any, sl);
15801583
15811584 var pfd = [1]os.pollfd{os.pollfd{
15821585 .fd = fd,