| ... | @@ -746,7 +746,79 @@ pub fn getAddressList(allocator: mem.Allocator, name: []const u8, port: u16) !*A | ... | @@ -746,7 +746,79 @@ pub fn getAddressList(allocator: mem.Allocator, name: []const u8, port: u16) !*A |
| 746 | const arena = result.arena.allocator(); | 746 | const arena = result.arena.allocator(); |
| 747 | errdefer result.deinit(); | 747 | errdefer result.deinit(); |
| 748 | | 748 | |
| 749 | if (builtin.target.os.tag == .windows or builtin.link_libc) { | 749 | if (builtin.target.os.tag == .windows) { |
| | 750 | const name_c = try std.cstr.addNullByte(allocator, name); |
| | 751 | defer allocator.free(name_c); |
| | 752 | |
| | 753 | const port_c = try std.fmt.allocPrintZ(allocator, "{}", .{port}); |
| | 754 | defer allocator.free(port_c); |
| | 755 | |
| | 756 | const ws2_32 = os.windows.ws2_32; |
| | 757 | const hints = os.addrinfo{ |
| | 758 | .flags = ws2_32.AI.NUMERICSERV, |
| | 759 | .family = os.AF.UNSPEC, |
| | 760 | .socktype = os.SOCK.STREAM, |
| | 761 | .protocol = os.IPPROTO.TCP, |
| | 762 | .canonname = null, |
| | 763 | .addr = null, |
| | 764 | .addrlen = 0, |
| | 765 | .next = null, |
| | 766 | }; |
| | 767 | var res: *os.addrinfo = undefined; |
| | 768 | var first = true; |
| | 769 | while (true) { |
| | 770 | const rc = ws2_32.getaddrinfo(name_c.ptr, port_c.ptr, &hints, &res); |
| | 771 | switch (@intToEnum(os.windows.ws2_32.WinsockError, @intCast(u16, rc))) { |
| | 772 | @intToEnum(os.windows.ws2_32.WinsockError, 0) => break, |
| | 773 | .WSATRY_AGAIN => return error.TemporaryNameServerFailure, |
| | 774 | .WSANO_RECOVERY => return error.NameServerFailure, |
| | 775 | .WSAEAFNOSUPPORT => return error.AddressFamilyNotSupported, |
| | 776 | .WSA_NOT_ENOUGH_MEMORY => return error.OutOfMemory, |
| | 777 | .WSAHOST_NOT_FOUND => return error.UnknownHostName, |
| | 778 | .WSATYPE_NOT_FOUND => return error.ServiceUnavailable, |
| | 779 | .WSAEINVAL => unreachable, |
| | 780 | .WSAESOCKTNOSUPPORT => unreachable, |
| | 781 | .WSANOTINITIALISED => { |
| | 782 | if (!first) return error.Unexpected; |
| | 783 | first = false; |
| | 784 | try os.windows.callWSAStartup(); |
| | 785 | continue; |
| | 786 | }, |
| | 787 | else => |err| return os.windows.unexpectedWSAError(err), |
| | 788 | } |
| | 789 | } |
| | 790 | defer ws2_32.freeaddrinfo(res); |
| | 791 | |
| | 792 | const addr_count = blk: { |
| | 793 | var count: usize = 0; |
| | 794 | var it: ?*os.addrinfo = res; |
| | 795 | while (it) |info| : (it = info.next) { |
| | 796 | if (info.addr != null) { |
| | 797 | count += 1; |
| | 798 | } |
| | 799 | } |
| | 800 | break :blk count; |
| | 801 | }; |
| | 802 | result.addrs = try arena.alloc(Address, addr_count); |
| | 803 | |
| | 804 | var it: ?*os.addrinfo = res; |
| | 805 | var i: usize = 0; |
| | 806 | while (it) |info| : (it = info.next) { |
| | 807 | const addr = info.addr orelse continue; |
| | 808 | result.addrs[i] = Address.initPosix(@alignCast(4, addr)); |
| | 809 | |
| | 810 | if (info.canonname) |n| { |
| | 811 | if (result.canon_name == null) { |
| | 812 | result.canon_name = try arena.dupe(u8, mem.sliceTo(n, 0)); |
| | 813 | } |
| | 814 | } |
| | 815 | i += 1; |
| | 816 | } |
| | 817 | |
| | 818 | return result; |
| | 819 | } |
| | 820 | |
| | 821 | if (builtin.link_libc) { |
| 750 | const name_c = try std.cstr.addNullByte(allocator, name); | 822 | const name_c = try std.cstr.addNullByte(allocator, name); |
| 751 | defer allocator.free(name_c); | 823 | defer allocator.free(name_c); |
| 752 | | 824 | |
| ... | @@ -765,19 +837,7 @@ pub fn getAddressList(allocator: mem.Allocator, name: []const u8, port: u16) !*A | ... | @@ -765,19 +837,7 @@ pub fn getAddressList(allocator: mem.Allocator, name: []const u8, port: u16) !*A |
| 765 | .next = null, | 837 | .next = null, |
| 766 | }; | 838 | }; |
| 767 | var res: *os.addrinfo = undefined; | 839 | var res: *os.addrinfo = undefined; |
| 768 | const rc = sys.getaddrinfo(name_c.ptr, port_c.ptr, &hints, &res); | 840 | switch (sys.getaddrinfo(name_c.ptr, port_c.ptr, &hints, &res)) { |
| 769 | if (builtin.target.os.tag == .windows) switch (@intToEnum(os.windows.ws2_32.WinsockError, @intCast(u16, rc))) { | | |
| 770 | @intToEnum(os.windows.ws2_32.WinsockError, 0) => {}, | | |
| 771 | .WSATRY_AGAIN => return error.TemporaryNameServerFailure, | | |
| 772 | .WSANO_RECOVERY => return error.NameServerFailure, | | |
| 773 | .WSAEAFNOSUPPORT => return error.AddressFamilyNotSupported, | | |
| 774 | .WSA_NOT_ENOUGH_MEMORY => return error.OutOfMemory, | | |
| 775 | .WSAHOST_NOT_FOUND => return error.UnknownHostName, | | |
| 776 | .WSATYPE_NOT_FOUND => return error.ServiceUnavailable, | | |
| 777 | .WSAEINVAL => unreachable, | | |
| 778 | .WSAESOCKTNOSUPPORT => unreachable, | | |
| 779 | else => |err| return os.windows.unexpectedWSAError(err), | | |
| 780 | } else switch (rc) { | | |
| 781 | @intToEnum(sys.EAI, 0) => {}, | 841 | @intToEnum(sys.EAI, 0) => {}, |
| 782 | .ADDRFAMILY => return error.HostLacksNetworkAddresses, | 842 | .ADDRFAMILY => return error.HostLacksNetworkAddresses, |
| 783 | .AGAIN => return error.TemporaryNameServerFailure, | 843 | .AGAIN => return error.TemporaryNameServerFailure, |
| ... | @@ -824,6 +884,7 @@ pub fn getAddressList(allocator: mem.Allocator, name: []const u8, port: u16) !*A | ... | @@ -824,6 +884,7 @@ pub fn getAddressList(allocator: mem.Allocator, name: []const u8, port: u16) !*A |
| 824 | | 884 | |
| 825 | return result; | 885 | return result; |
| 826 | } | 886 | } |
| | 887 | |
| 827 | if (builtin.target.os.tag == .linux) { | 888 | if (builtin.target.os.tag == .linux) { |
| 828 | const flags = std.c.AI.NUMERICSERV; | 889 | const flags = std.c.AI.NUMERICSERV; |
| 829 | const family = os.AF.UNSPEC; | 890 | const family = os.AF.UNSPEC; |