| author | |
| committer | |
| log | ab003cd0545e54e66410b8e67136d4ef079b3198 |
| tree | c97ce15f2daccb5e5a807bd99a400bea218a24ed |
| parent | dab8dd5e0306af4ef9b2388cfa8012ea596920ae |
2 files changed, 108 insertions(+), 31 deletions(-)
lib/std/Io/Threaded.zig+75-2| ... | @@ -4058,8 +4058,81 @@ fn netLookupFallible( | ... | @@ -4058,8 +4058,81 @@ fn netLookupFallible( |
| 4058 | assert(name.len <= HostName.max_len); | 4058 | assert(name.len <= HostName.max_len); |
| 4059 | 4059 | ||
| 4060 | if (is_windows) { | 4060 | if (is_windows) { |
| 4061 | // TODO use GetAddrInfoExW / GetAddrInfoExCancel | 4061 | var name_buffer: [HostName.max_len + 1]u16 = undefined; |
| 4062 | @compileError("TODO"); | 4062 | const name_len = std.unicode.wtf8ToWtf16Le(&name_buffer, host_name.bytes) catch |
| 4063 | unreachable; // HostName is prevalidated. | ||
| 4064 | name_buffer[name_len] = 0; | ||
| 4065 | const name_w = name_buffer[0..name_len :0]; | ||
| 4066 | |||
| 4067 | var port_buffer: [8]u8 = undefined; | ||
| 4068 | var port_buffer_wide: [8]u16 = undefined; | ||
| 4069 | const port = std.fmt.bufPrint(&port_buffer, "{d}", .{options.port}) catch | ||
| 4070 | unreachable; // `port_buffer` is big enough for decimal u16. | ||
| 4071 | for (port, port_buffer[0..port.len]) |byte, *wide| wide.* = byte; | ||
| 4072 | port_buffer_wide[port.len] = 0; | ||
| 4073 | const port_w = port_buffer_wide[0..port.len :0]; | ||
| 4074 | |||
| 4075 | const hints: ws2_32.ADDRINFOEXW = .{ | ||
| 4076 | .flags = .{ .NUMERICSERV = true }, | ||
| 4077 | .family = posix.AF.UNSPEC, | ||
| 4078 | .socktype = posix.SOCK.STREAM, | ||
| 4079 | .protocol = posix.IPPROTO.TCP, | ||
| 4080 | .canonname = null, | ||
| 4081 | .addr = null, | ||
| 4082 | .addrlen = 0, | ||
| 4083 | .blob = null, | ||
| 4084 | .bloblen = 0, | ||
| 4085 | .provider = null, | ||
| 4086 | .next = null, | ||
| 4087 | }; | ||
| 4088 | var res: *ws2_32.ADDRINFOEXW = undefined; | ||
| 4089 | const timeout: ?*ws2_32.timeval = null; | ||
| 4090 | while (true) { | ||
| 4091 | try t.checkCancel(); // TODO make requestCancel call GetAddrInfoExCancel | ||
| 4092 | // TODO make this append to the queue eagerly rather than blocking until | ||
| 4093 | // the whole thing finishes | ||
| 4094 | const rc: ws2_32.WinsockError = @enumFromInt(ws2_32.GetAddrInfoExW(name_w, port_w, .DNS, null, &hints, &res, timeout, null, null)); | ||
| 4095 | switch (rc) { | ||
| 4096 | @as(ws2_32.WinsockError, @enumFromInt(0)) => break, | ||
| 4097 | .EINTR => continue, | ||
| 4098 | .ECANCELLED, .E_CANCELLED => return error.Canceled, | ||
| 4099 | .NOTINITIALISED => { | ||
| 4100 | try initializeWsa(t); | ||
| 4101 | continue; | ||
| 4102 | }, | ||
| 4103 | .TRY_AGAIN => return error.NameServerFailure, | ||
| 4104 | .EINVAL => |err| return wsaErrorBug(err), | ||
| 4105 | .NO_RECOVERY => return error.NameServerFailure, | ||
| 4106 | .EAFNOSUPPORT => return error.AddressFamilyUnsupported, | ||
| 4107 | .NOT_ENOUGH_MEMORY => return error.SystemResources, | ||
| 4108 | .HOST_NOT_FOUND => return error.UnknownHostName, | ||
| 4109 | .TYPE_NOT_FOUND => return error.ProtocolUnsupportedByAddressFamily, | ||
| 4110 | .ESOCKTNOSUPPORT => return error.ProtocolUnsupportedBySystem, | ||
| 4111 | else => |err| return windows.unexpectedWSAError(err), | ||
| 4112 | } | ||
| 4113 | } | ||
| 4114 | defer ws2_32.FreeAddrInfoExW(res); | ||
| 4115 | |||
| 4116 | var it: ?*ws2_32.ADDRINFOEXW = res; | ||
| 4117 | var canon_name: ?[*:0]const u16 = null; | ||
| 4118 | while (it) |info| : (it = info.next) { | ||
| 4119 | const addr = info.addr orelse continue; | ||
| 4120 | const storage: WsaAddress = .{ .any = addr.* }; | ||
| 4121 | try resolved.putOne(t_io, .{ .address = addressFromWsa(&storage) }); | ||
| 4122 | |||
| 4123 | if (info.canonname) |n| { | ||
| 4124 | if (canon_name == null) { | ||
| 4125 | canon_name = n; | ||
| 4126 | } | ||
| 4127 | } | ||
| 4128 | } | ||
| 4129 | if (canon_name) |n| { | ||
| 4130 | const len = std.unicode.wtf16LeToWtf8(options.canonical_name_buffer, std.mem.sliceTo(n, 0)); | ||
| 4131 | try resolved.putOne(t_io, .{ .canonical_name = .{ | ||
| 4132 | .bytes = options.canonical_name_buffer[0..len], | ||
| 4133 | } }); | ||
| 4134 | } | ||
| 4135 | return; | ||
| 4063 | } | 4136 | } |
| 4064 | 4137 | ||
| 4065 | // On Linux, glibc provides getaddrinfo_a which is capable of supporting our semantics. | 4138 | // On Linux, glibc provides getaddrinfo_a which is capable of supporting our semantics. |
lib/std/os/windows/ws2_32.zig+33-29| ... | @@ -702,28 +702,32 @@ pub const FIONBIO = -2147195266; | ... | @@ -702,28 +702,32 @@ pub const FIONBIO = -2147195266; |
| 702 | pub const ADDRINFOEX_VERSION_2 = 2; | 702 | pub const ADDRINFOEX_VERSION_2 = 2; |
| 703 | pub const ADDRINFOEX_VERSION_3 = 3; | 703 | pub const ADDRINFOEX_VERSION_3 = 3; |
| 704 | pub const ADDRINFOEX_VERSION_4 = 4; | 704 | pub const ADDRINFOEX_VERSION_4 = 4; |
| 705 | pub const NS_ALL = 0; | 705 | |
| 706 | pub const NS_SAP = 1; | 706 | pub const NS = enum(u32) { |
| 707 | pub const NS_NDS = 2; | 707 | ALL = 0, |
| 708 | pub const NS_PEER_BROWSE = 3; | 708 | SAP = 1, |
| 709 | pub const NS_SLP = 5; | 709 | NDS = 2, |
| 710 | pub const NS_DHCP = 6; | 710 | PEER_BROWSE = 3, |
| 711 | pub const NS_TCPIP_LOCAL = 10; | 711 | SLP = 5, |
| 712 | pub const NS_TCPIP_HOSTS = 11; | 712 | DHCP = 6, |
| 713 | pub const NS_DNS = 12; | 713 | TCPIP_LOCAL = 10, |
| 714 | pub const NS_NETBT = 13; | 714 | TCPIP_HOSTS = 11, |
| 715 | pub const NS_WINS = 14; | 715 | DNS = 12, |
| 716 | pub const NS_NLA = 15; | 716 | NETBT = 13, |
| 717 | pub const NS_NBP = 20; | 717 | WINS = 14, |
| 718 | pub const NS_MS = 30; | 718 | NLA = 15, |
| 719 | pub const NS_STDA = 31; | 719 | NBP = 20, |
| 720 | pub const NS_NTDS = 32; | 720 | MS = 30, |
| 721 | pub const NS_EMAIL = 37; | 721 | STDA = 31, |
| 722 | pub const NS_X500 = 40; | 722 | NTDS = 32, |
| 723 | pub const NS_NIS = 41; | 723 | EMAIL = 37, |
| 724 | pub const NS_NISPLUS = 42; | 724 | X500 = 40, |
| 725 | pub const NS_WRQ = 50; | 725 | NIS = 41, |
| 726 | pub const NS_NETDES = 60; | 726 | NISPLUS = 42, |
| 727 | WRQ = 50, | ||
| 728 | NETDES = 60, | ||
| 729 | }; | ||
| 730 | |||
| 727 | pub const NI_NOFQDN = 1; | 731 | pub const NI_NOFQDN = 1; |
| 728 | pub const NI_NUMERICHOST = 2; | 732 | pub const NI_NUMERICHOST = 2; |
| 729 | pub const NI_NAMEREQD = 4; | 733 | pub const NI_NAMEREQD = 4; |
| ... | @@ -1086,12 +1090,12 @@ pub const ADDRINFOEXW = extern struct { | ... | @@ -1086,12 +1090,12 @@ pub const ADDRINFOEXW = extern struct { |
| 1086 | socktype: i32, | 1090 | socktype: i32, |
| 1087 | protocol: i32, | 1091 | protocol: i32, |
| 1088 | addrlen: usize, | 1092 | addrlen: usize, |
| 1089 | canonname: [*:0]u16, | 1093 | canonname: ?[*:0]u16, |
| 1090 | addr: *sockaddr, | 1094 | addr: ?*sockaddr, |
| 1091 | blob: *anyopaque, | 1095 | blob: ?*anyopaque, |
| 1092 | bloblen: usize, | 1096 | bloblen: usize, |
| 1093 | provider: *GUID, | 1097 | provider: ?*GUID, |
| 1094 | next: *ADDRINFOEXW, | 1098 | next: ?*ADDRINFOEXW, |
| 1095 | }; | 1099 | }; |
| 1096 | 1100 | ||
| 1097 | pub const sockaddr = extern struct { | 1101 | pub const sockaddr = extern struct { |
| ... | @@ -2101,7 +2105,7 @@ pub extern "mswsock" fn EnumProtocolsW( | ... | @@ -2101,7 +2105,7 @@ pub extern "mswsock" fn EnumProtocolsW( |
| 2101 | ) callconv(.winapi) i32; | 2105 | ) callconv(.winapi) i32; |
| 2102 | 2106 | ||
| 2103 | pub extern "mswsock" fn GetAddressByNameW( | 2107 | pub extern "mswsock" fn GetAddressByNameW( |
| 2104 | dwNameSpace: u32, | 2108 | dwNameSpace: NS, |
| 2105 | lpServiceType: *GUID, | 2109 | lpServiceType: *GUID, |
| 2106 | lpServiceName: ?[*:0]u16, | 2110 | lpServiceName: ?[*:0]u16, |
| 2107 | lpiProtocols: ?*i32, | 2111 | lpiProtocols: ?*i32, |
| ... | @@ -2127,7 +2131,7 @@ pub extern "mswsock" fn GetNameByTypeW( | ... | @@ -2127,7 +2131,7 @@ pub extern "mswsock" fn GetNameByTypeW( |
| 2127 | pub extern "ws2_32" fn GetAddrInfoExW( | 2131 | pub extern "ws2_32" fn GetAddrInfoExW( |
| 2128 | pName: ?[*:0]const u16, | 2132 | pName: ?[*:0]const u16, |
| 2129 | pServiceName: ?[*:0]const u16, | 2133 | pServiceName: ?[*:0]const u16, |
| 2130 | dwNameSpace: DWORD, | 2134 | dwNameSpace: NS, |
| 2131 | lpNspId: ?*GUID, | 2135 | lpNspId: ?*GUID, |
| 2132 | hints: ?*const ADDRINFOEXW, | 2136 | hints: ?*const ADDRINFOEXW, |
| 2133 | ppResult: **ADDRINFOEXW, | 2137 | ppResult: **ADDRINFOEXW, |