diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2023-01-17 07:35:25 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-01-17 07:35:25 -0500 |
| commit | f4b4e570d87c53d31cb4bee27b0468bdc8b826ae (patch) | |
| tree | 2b8af517d767df8cddc6476e1adc30f88f3e99e0 /lib/std/net.zig | |
| parent | d56a65a8c4609a740eee43fd7073c2485c87c2c6 (diff) | |
| parent | d35d086ae6206b706c9116d0376cabbdf6a25650 (diff) | |
| download | zig-f4b4e570d87c53d31cb4bee27b0468bdc8b826ae.tar.gz zig-f4b4e570d87c53d31cb4bee27b0468bdc8b826ae.zip | |
Merge pull request #14229 from star-tek-mb/wincerts
windows root certificate scanning
Diffstat (limited to 'lib/std/net.zig')
| -rw-r--r-- | lib/std/net.zig | 89 |
1 files changed, 75 insertions, 14 deletions
diff --git a/lib/std/net.zig b/lib/std/net.zig index da4cf30046..c4cee40a1d 100644 --- a/lib/std/net.zig +++ b/lib/std/net.zig @@ -746,7 +746,79 @@ pub fn getAddressList(allocator: mem.Allocator, name: []const u8, port: u16) !*A const arena = result.arena.allocator(); errdefer result.deinit(); - if (builtin.target.os.tag == .windows or builtin.link_libc) { + if (builtin.target.os.tag == .windows) { + const name_c = try std.cstr.addNullByte(allocator, name); + defer allocator.free(name_c); + + const port_c = try std.fmt.allocPrintZ(allocator, "{}", .{port}); + defer allocator.free(port_c); + + const ws2_32 = os.windows.ws2_32; + const hints = os.addrinfo{ + .flags = ws2_32.AI.NUMERICSERV, + .family = os.AF.UNSPEC, + .socktype = os.SOCK.STREAM, + .protocol = os.IPPROTO.TCP, + .canonname = null, + .addr = null, + .addrlen = 0, + .next = null, + }; + var res: *os.addrinfo = undefined; + var first = true; + while (true) { + const rc = ws2_32.getaddrinfo(name_c.ptr, port_c.ptr, &hints, &res); + switch (@intToEnum(os.windows.ws2_32.WinsockError, @intCast(u16, rc))) { + @intToEnum(os.windows.ws2_32.WinsockError, 0) => break, + .WSATRY_AGAIN => return error.TemporaryNameServerFailure, + .WSANO_RECOVERY => return error.NameServerFailure, + .WSAEAFNOSUPPORT => return error.AddressFamilyNotSupported, + .WSA_NOT_ENOUGH_MEMORY => return error.OutOfMemory, + .WSAHOST_NOT_FOUND => return error.UnknownHostName, + .WSATYPE_NOT_FOUND => return error.ServiceUnavailable, + .WSAEINVAL => unreachable, + .WSAESOCKTNOSUPPORT => unreachable, + .WSANOTINITIALISED => { + if (!first) return error.Unexpected; + first = false; + try os.windows.callWSAStartup(); + continue; + }, + else => |err| return os.windows.unexpectedWSAError(err), + } + } + defer ws2_32.freeaddrinfo(res); + + const addr_count = blk: { + var count: usize = 0; + var it: ?*os.addrinfo = res; + while (it) |info| : (it = info.next) { + if (info.addr != null) { + count += 1; + } + } + break :blk count; + }; + result.addrs = try arena.alloc(Address, addr_count); + + var it: ?*os.addrinfo = res; + var i: usize = 0; + while (it) |info| : (it = info.next) { + const addr = info.addr orelse continue; + result.addrs[i] = Address.initPosix(@alignCast(4, addr)); + + if (info.canonname) |n| { + if (result.canon_name == null) { + result.canon_name = try arena.dupe(u8, mem.sliceTo(n, 0)); + } + } + i += 1; + } + + return result; + } + + if (builtin.link_libc) { const name_c = try std.cstr.addNullByte(allocator, name); defer allocator.free(name_c); @@ -765,19 +837,7 @@ pub fn getAddressList(allocator: mem.Allocator, name: []const u8, port: u16) !*A .next = null, }; var res: *os.addrinfo = undefined; - const rc = sys.getaddrinfo(name_c.ptr, port_c.ptr, &hints, &res); - if (builtin.target.os.tag == .windows) switch (@intToEnum(os.windows.ws2_32.WinsockError, @intCast(u16, rc))) { - @intToEnum(os.windows.ws2_32.WinsockError, 0) => {}, - .WSATRY_AGAIN => return error.TemporaryNameServerFailure, - .WSANO_RECOVERY => return error.NameServerFailure, - .WSAEAFNOSUPPORT => return error.AddressFamilyNotSupported, - .WSA_NOT_ENOUGH_MEMORY => return error.OutOfMemory, - .WSAHOST_NOT_FOUND => return error.UnknownHostName, - .WSATYPE_NOT_FOUND => return error.ServiceUnavailable, - .WSAEINVAL => unreachable, - .WSAESOCKTNOSUPPORT => unreachable, - else => |err| return os.windows.unexpectedWSAError(err), - } else switch (rc) { + switch (sys.getaddrinfo(name_c.ptr, port_c.ptr, &hints, &res)) { @intToEnum(sys.EAI, 0) => {}, .ADDRFAMILY => return error.HostLacksNetworkAddresses, .AGAIN => return error.TemporaryNameServerFailure, @@ -824,6 +884,7 @@ pub fn getAddressList(allocator: mem.Allocator, name: []const u8, port: u16) !*A return result; } + if (builtin.target.os.tag == .linux) { const flags = std.c.AI.NUMERICSERV; const family = os.AF.UNSPEC; |
