Commit ab003cd054
Changed files (2)
lib
std
os
windows
lib/std/Io/Threaded.zig
@@ -4058,8 +4058,81 @@ fn netLookupFallible(
assert(name.len <= HostName.max_len);
if (is_windows) {
- // TODO use GetAddrInfoExW / GetAddrInfoExCancel
- @compileError("TODO");
+ var name_buffer: [HostName.max_len + 1]u16 = undefined;
+ const name_len = std.unicode.wtf8ToWtf16Le(&name_buffer, host_name.bytes) catch
+ unreachable; // HostName is prevalidated.
+ name_buffer[name_len] = 0;
+ const name_w = name_buffer[0..name_len :0];
+
+ var port_buffer: [8]u8 = undefined;
+ var port_buffer_wide: [8]u16 = undefined;
+ const port = std.fmt.bufPrint(&port_buffer, "{d}", .{options.port}) catch
+ unreachable; // `port_buffer` is big enough for decimal u16.
+ for (port, port_buffer[0..port.len]) |byte, *wide| wide.* = byte;
+ port_buffer_wide[port.len] = 0;
+ const port_w = port_buffer_wide[0..port.len :0];
+
+ const hints: ws2_32.ADDRINFOEXW = .{
+ .flags = .{ .NUMERICSERV = true },
+ .family = posix.AF.UNSPEC,
+ .socktype = posix.SOCK.STREAM,
+ .protocol = posix.IPPROTO.TCP,
+ .canonname = null,
+ .addr = null,
+ .addrlen = 0,
+ .blob = null,
+ .bloblen = 0,
+ .provider = null,
+ .next = null,
+ };
+ var res: *ws2_32.ADDRINFOEXW = undefined;
+ const timeout: ?*ws2_32.timeval = null;
+ while (true) {
+ try t.checkCancel(); // TODO make requestCancel call GetAddrInfoExCancel
+ // TODO make this append to the queue eagerly rather than blocking until
+ // the whole thing finishes
+ const rc: ws2_32.WinsockError = @enumFromInt(ws2_32.GetAddrInfoExW(name_w, port_w, .DNS, null, &hints, &res, timeout, null, null));
+ switch (rc) {
+ @as(ws2_32.WinsockError, @enumFromInt(0)) => break,
+ .EINTR => continue,
+ .ECANCELLED, .E_CANCELLED => return error.Canceled,
+ .NOTINITIALISED => {
+ try initializeWsa(t);
+ continue;
+ },
+ .TRY_AGAIN => return error.NameServerFailure,
+ .EINVAL => |err| return wsaErrorBug(err),
+ .NO_RECOVERY => return error.NameServerFailure,
+ .EAFNOSUPPORT => return error.AddressFamilyUnsupported,
+ .NOT_ENOUGH_MEMORY => return error.SystemResources,
+ .HOST_NOT_FOUND => return error.UnknownHostName,
+ .TYPE_NOT_FOUND => return error.ProtocolUnsupportedByAddressFamily,
+ .ESOCKTNOSUPPORT => return error.ProtocolUnsupportedBySystem,
+ else => |err| return windows.unexpectedWSAError(err),
+ }
+ }
+ defer ws2_32.FreeAddrInfoExW(res);
+
+ var it: ?*ws2_32.ADDRINFOEXW = res;
+ var canon_name: ?[*:0]const u16 = null;
+ while (it) |info| : (it = info.next) {
+ const addr = info.addr orelse continue;
+ const storage: WsaAddress = .{ .any = addr.* };
+ try resolved.putOne(t_io, .{ .address = addressFromWsa(&storage) });
+
+ if (info.canonname) |n| {
+ if (canon_name == null) {
+ canon_name = n;
+ }
+ }
+ }
+ if (canon_name) |n| {
+ const len = std.unicode.wtf16LeToWtf8(options.canonical_name_buffer, std.mem.sliceTo(n, 0));
+ try resolved.putOne(t_io, .{ .canonical_name = .{
+ .bytes = options.canonical_name_buffer[0..len],
+ } });
+ }
+ return;
}
// On Linux, glibc provides getaddrinfo_a which is capable of supporting our semantics.
lib/std/os/windows/ws2_32.zig
@@ -702,28 +702,32 @@ pub const FIONBIO = -2147195266;
pub const ADDRINFOEX_VERSION_2 = 2;
pub const ADDRINFOEX_VERSION_3 = 3;
pub const ADDRINFOEX_VERSION_4 = 4;
-pub const NS_ALL = 0;
-pub const NS_SAP = 1;
-pub const NS_NDS = 2;
-pub const NS_PEER_BROWSE = 3;
-pub const NS_SLP = 5;
-pub const NS_DHCP = 6;
-pub const NS_TCPIP_LOCAL = 10;
-pub const NS_TCPIP_HOSTS = 11;
-pub const NS_DNS = 12;
-pub const NS_NETBT = 13;
-pub const NS_WINS = 14;
-pub const NS_NLA = 15;
-pub const NS_NBP = 20;
-pub const NS_MS = 30;
-pub const NS_STDA = 31;
-pub const NS_NTDS = 32;
-pub const NS_EMAIL = 37;
-pub const NS_X500 = 40;
-pub const NS_NIS = 41;
-pub const NS_NISPLUS = 42;
-pub const NS_WRQ = 50;
-pub const NS_NETDES = 60;
+
+pub const NS = enum(u32) {
+ ALL = 0,
+ SAP = 1,
+ NDS = 2,
+ PEER_BROWSE = 3,
+ SLP = 5,
+ DHCP = 6,
+ TCPIP_LOCAL = 10,
+ TCPIP_HOSTS = 11,
+ DNS = 12,
+ NETBT = 13,
+ WINS = 14,
+ NLA = 15,
+ NBP = 20,
+ MS = 30,
+ STDA = 31,
+ NTDS = 32,
+ EMAIL = 37,
+ X500 = 40,
+ NIS = 41,
+ NISPLUS = 42,
+ WRQ = 50,
+ NETDES = 60,
+};
+
pub const NI_NOFQDN = 1;
pub const NI_NUMERICHOST = 2;
pub const NI_NAMEREQD = 4;
@@ -1086,12 +1090,12 @@ pub const ADDRINFOEXW = extern struct {
socktype: i32,
protocol: i32,
addrlen: usize,
- canonname: [*:0]u16,
- addr: *sockaddr,
- blob: *anyopaque,
+ canonname: ?[*:0]u16,
+ addr: ?*sockaddr,
+ blob: ?*anyopaque,
bloblen: usize,
- provider: *GUID,
- next: *ADDRINFOEXW,
+ provider: ?*GUID,
+ next: ?*ADDRINFOEXW,
};
pub const sockaddr = extern struct {
@@ -2101,7 +2105,7 @@ pub extern "mswsock" fn EnumProtocolsW(
) callconv(.winapi) i32;
pub extern "mswsock" fn GetAddressByNameW(
- dwNameSpace: u32,
+ dwNameSpace: NS,
lpServiceType: *GUID,
lpServiceName: ?[*:0]u16,
lpiProtocols: ?*i32,
@@ -2127,7 +2131,7 @@ pub extern "mswsock" fn GetNameByTypeW(
pub extern "ws2_32" fn GetAddrInfoExW(
pName: ?[*:0]const u16,
pServiceName: ?[*:0]const u16,
- dwNameSpace: DWORD,
+ dwNameSpace: NS,
lpNspId: ?*GUID,
hints: ?*const ADDRINFOEXW,
ppResult: **ADDRINFOEXW,