| ... | ... | @@ -741,7 +741,7 @@ pub fn tcpConnectToAddress(address: Address) TcpConnectToAddressError!Stream { |
| 741 | 741 | return Stream{ .handle = sockfd }; |
| 742 | 742 | } |
| 743 | 743 | |
| 744 | | const GetAddressListError = std.mem.Allocator.Error || std.fs.File.OpenError || std.fs.File.ReadError || std.os.SocketError || std.os.BindError || error{ |
| 744 | const GetAddressListError = std.mem.Allocator.Error || std.fs.File.OpenError || std.fs.File.ReadError || std.os.SocketError || std.os.BindError || std.os.SetSockOptError || error{ |
| 745 | 745 | // TODO: break this up into error sets from the various underlying functions |
| 746 | 746 | |
| 747 | 747 | TemporaryNameServerFailure, |
| ... | ... | @@ -1534,15 +1534,10 @@ fn resMSendRc( |
| 1534 | 1534 | ns[i] = iplit.addr; |
| 1535 | 1535 | assert(ns[i].getPort() == 53); |
| 1536 | 1536 | if (iplit.addr.any.family != os.AF.INET) { |
| 1537 | | sl = @sizeOf(os.sockaddr.in6); |
| 1538 | 1537 | family = os.AF.INET6; |
| 1539 | 1538 | } |
| 1540 | 1539 | } |
| 1541 | 1540 | |
| 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; |
| 1546 | 1541 | const flags = os.SOCK.DGRAM | os.SOCK.CLOEXEC | os.SOCK.NONBLOCK; |
| 1547 | 1542 | const fd = os.socket(family, flags, 0) catch |err| switch (err) { |
| 1548 | 1543 | error.AddressFamilyNotSupported => blk: { |
| ... | ... | @@ -1556,27 +1551,35 @@ fn resMSendRc( |
| 1556 | 1551 | else => |e| return e, |
| 1557 | 1552 | }; |
| 1558 | 1553 | defer os.closeSocket(fd); |
| 1559 | | try os.bind(fd, &sa.any, sl); |
| 1560 | 1554 | |
| 1561 | 1555 | // Past this point, there are no errors. Each individual query will |
| 1562 | 1556 | // yield either no reply (indicated by zero length) or an answer |
| 1563 | 1557 | // packet which is up to the caller to interpret. |
| 1564 | 1558 | |
| 1565 | 1559 | // 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); |
| 1580 | 1583 | |
| 1581 | 1584 | var pfd = [1]os.pollfd{os.pollfd{ |
| 1582 | 1585 | .fd = fd, |