NIO: implement address resolution on Windows (#1684)
Windows has a slightly different API for address resolution. Implement the Windows path for addrinfo resolution.
This commit is contained in:
parent
245ce96490
commit
255f29d3f3
|
@ -23,6 +23,21 @@
|
|||
/// This resolver is a single-use object: it can only be used to perform a single host resolution.
|
||||
import CNIOLinux
|
||||
|
||||
#if os(Windows)
|
||||
import let WinSDK.AF_INET
|
||||
import let WinSDK.AF_INET6
|
||||
|
||||
import func WinSDK.FreeAddrInfoW
|
||||
import func WinSDK.GetAddrInfoW
|
||||
import func WinSDK.gai_strerrorA
|
||||
|
||||
import struct WinSDK.ADDRESS_FAMILY
|
||||
import struct WinSDK.ADDRINFOW
|
||||
import struct WinSDK.SOCKADDR_IN
|
||||
import struct WinSDK.SOCKADDR_IN6
|
||||
#endif
|
||||
|
||||
|
||||
internal class GetaddrinfoResolver: Resolver {
|
||||
private let v4Future: EventLoopPromise<[SocketAddress]>
|
||||
private let v6Future: EventLoopPromise<[SocketAddress]>
|
||||
|
@ -85,6 +100,30 @@ internal class GetaddrinfoResolver: Resolver {
|
|||
/// - host: The hostname to do the DNS queries on.
|
||||
/// - port: The port we'll be connecting to.
|
||||
private func resolve(host: String, port: Int) {
|
||||
#if os(Windows)
|
||||
host.withCString(encodedAs: UTF16.self) { wszHost in
|
||||
String(port).withCString(encodedAs: UTF16.self) { wszPort in
|
||||
var pResult: UnsafeMutablePointer<ADDRINFOW>?
|
||||
|
||||
var aiHints: ADDRINFOW = ADDRINFOW()
|
||||
aiHints.ai_socktype = self.aiSocktype.rawValue
|
||||
aiHints.ai_protocol = self.aiProtocol
|
||||
|
||||
let iResult = GetAddrInfoW(wszHost, wszPort, &aiHints, &pResult)
|
||||
guard iResult == 0 else {
|
||||
self.fail(SocketAddressError.unknown(host: host, port: port))
|
||||
return
|
||||
}
|
||||
|
||||
if let pResult = pResult {
|
||||
parseResults(pResult, host: host)
|
||||
FreeAddrInfoW(pResult)
|
||||
} else {
|
||||
self.fail(SocketAddressError.unsupported)
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
var info: UnsafeMutablePointer<addrinfo>?
|
||||
|
||||
var hint = addrinfo()
|
||||
|
@ -102,6 +141,7 @@ internal class GetaddrinfoResolver: Resolver {
|
|||
/* this is odd, getaddrinfo returned NULL */
|
||||
self.fail(SocketAddressError.unsupported)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Parses the DNS results from the `addrinfo` linked list.
|
||||
|
@ -109,11 +149,17 @@ internal class GetaddrinfoResolver: Resolver {
|
|||
/// - parameters:
|
||||
/// - info: The pointer to the first of the `addrinfo` structures in the list.
|
||||
/// - host: The hostname we resolved.
|
||||
private func parseResults(_ info: UnsafeMutablePointer<addrinfo>, host: String) {
|
||||
var info = info
|
||||
var v4Results = [SocketAddress]()
|
||||
var v6Results = [SocketAddress]()
|
||||
#if os(Windows)
|
||||
internal typealias CAddrInfo = ADDRINFOW
|
||||
#else
|
||||
internal typealias CAddrInfo = addrinfo
|
||||
#endif
|
||||
|
||||
private func parseResults(_ info: UnsafeMutablePointer<CAddrInfo>, host: String) {
|
||||
var v4Results: [SocketAddress] = []
|
||||
var v6Results: [SocketAddress] = []
|
||||
|
||||
var info: UnsafeMutablePointer<CAddrInfo> = info
|
||||
while true {
|
||||
switch NIOBSDSocket.AddressFamily(rawValue: info.pointee.ai_family) {
|
||||
case .inet:
|
||||
|
|
|
@ -339,7 +339,7 @@ public enum SocketAddress: CustomStringConvertible {
|
|||
return try String(port).withCString(encodedAs: UTF16.self) { wszPort in
|
||||
var pResult: UnsafeMutablePointer<ADDRINFOW>?
|
||||
|
||||
guard GetAddrInfoW(wsHost, wszPort, nil, &pResult) == 0 else {
|
||||
guard GetAddrInfoW(wszHost, wszPort, nil, &pResult) == 0 else {
|
||||
throw SocketAddressError.unknown(host: host, port: port)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue