aboutsummaryrefslogtreecommitdiffstats
path: root/WireGuard/WireGuardNetworkExtension/DNSResolver.swift
diff options
context:
space:
mode:
Diffstat (limited to 'WireGuard/WireGuardNetworkExtension/DNSResolver.swift')
-rw-r--r--WireGuard/WireGuardNetworkExtension/DNSResolver.swift160
1 files changed, 0 insertions, 160 deletions
diff --git a/WireGuard/WireGuardNetworkExtension/DNSResolver.swift b/WireGuard/WireGuardNetworkExtension/DNSResolver.swift
deleted file mode 100644
index cdb9665..0000000
--- a/WireGuard/WireGuardNetworkExtension/DNSResolver.swift
+++ /dev/null
@@ -1,160 +0,0 @@
-// SPDX-License-Identifier: MIT
-// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved.
-
-import Network
-import Foundation
-
-class DNSResolver {
-
- static func isAllEndpointsAlreadyResolved(endpoints: [Endpoint?]) -> Bool {
- for endpoint in endpoints {
- guard let endpoint = endpoint else { continue }
- if !endpoint.hasHostAsIPAddress() {
- return false
- }
- }
- return true
- }
-
- static func resolveSync(endpoints: [Endpoint?]) -> [Endpoint?]? {
- let dispatchGroup = DispatchGroup()
-
- if isAllEndpointsAlreadyResolved(endpoints: endpoints) {
- return endpoints
- }
-
- var resolvedEndpoints: [Endpoint?] = Array(repeating: nil, count: endpoints.count)
- for (index, endpoint) in endpoints.enumerated() {
- guard let endpoint = endpoint else { continue }
- if endpoint.hasHostAsIPAddress() {
- resolvedEndpoints[index] = endpoint
- } else {
- let workItem = DispatchWorkItem {
- resolvedEndpoints[index] = DNSResolver.resolveSync(endpoint: endpoint)
- }
- DispatchQueue.global(qos: .userInitiated).async(group: dispatchGroup, execute: workItem)
- }
- }
-
- dispatchGroup.wait() // TODO: Timeout?
-
- var hostnamesWithDnsResolutionFailure = [String]()
- assert(endpoints.count == resolvedEndpoints.count)
- for tuple in zip(endpoints, resolvedEndpoints) {
- let endpoint = tuple.0
- let resolvedEndpoint = tuple.1
- if let endpoint = endpoint {
- if resolvedEndpoint == nil {
- guard let hostname = endpoint.hostname() else { fatalError() }
- hostnamesWithDnsResolutionFailure.append(hostname)
- }
- }
- }
- if !hostnamesWithDnsResolutionFailure.isEmpty {
- wg_log(.error, message: "DNS resolution failed for the following hostnames: \(hostnamesWithDnsResolutionFailure.joined(separator: ", "))")
- return nil
- }
- return resolvedEndpoints
- }
-
- private static func resolveSync(endpoint: Endpoint) -> Endpoint? {
- switch endpoint.host {
- case .name(let name, _):
- var resultPointer = UnsafeMutablePointer<addrinfo>(OpaquePointer(bitPattern: 0))
- var hints = addrinfo(
- ai_flags: AI_ALL, // We set this to ALL so that we get v4 addresses even on DNS64 networks
- ai_family: AF_UNSPEC,
- ai_socktype: SOCK_DGRAM,
- ai_protocol: IPPROTO_UDP,
- ai_addrlen: 0,
- ai_canonname: nil,
- ai_addr: nil,
- ai_next: nil)
- if getaddrinfo(name, "\(endpoint.port)", &hints, &resultPointer) != 0 {
- return nil
- }
- var next = resultPointer
- var ipv4Address: IPv4Address?
- var ipv6Address: IPv6Address?
- while next != nil {
- let result = next!.pointee
- next = result.ai_next
- if result.ai_family == AF_INET && result.ai_addrlen == MemoryLayout<sockaddr_in>.size {
- var sa4 = UnsafeRawPointer(result.ai_addr)!.assumingMemoryBound(to: sockaddr_in.self).pointee
- ipv4Address = IPv4Address(Data(bytes: &sa4.sin_addr, count: MemoryLayout<in_addr>.size))
- break // If we found an IPv4 address, we can stop
- } else if result.ai_family == AF_INET6 && result.ai_addrlen == MemoryLayout<sockaddr_in6>.size {
- var sa6 = UnsafeRawPointer(result.ai_addr)!.assumingMemoryBound(to: sockaddr_in6.self).pointee
- ipv6Address = IPv6Address(Data(bytes: &sa6.sin6_addr, count: MemoryLayout<in6_addr>.size))
- continue // If we already have an IPv6 address, we can skip this one
- }
- }
- freeaddrinfo(resultPointer)
-
- // We prefer an IPv4 address over an IPv6 address
- if let ipv4Address = ipv4Address {
- return Endpoint(host: .ipv4(ipv4Address), port: endpoint.port)
- } else if let ipv6Address = ipv6Address {
- return Endpoint(host: .ipv6(ipv6Address), port: endpoint.port)
- } else {
- return nil
- }
- default:
- return endpoint
- }
- }
-}
-
-extension Endpoint {
- func withReresolvedIP() -> Endpoint {
- #if os(iOS)
- var ret = self
- let hostname: String
- switch host {
- case .name(let name, _):
- hostname = name
- case .ipv4(let address):
- hostname = "\(address)"
- case .ipv6(let address):
- hostname = "\(address)"
- @unknown default:
- fatalError()
- }
-
- var resultPointer = UnsafeMutablePointer<addrinfo>(OpaquePointer(bitPattern: 0))
- var hints = addrinfo(
- ai_flags: 0, // We set this to zero so that we actually resolve this using DNS64
- ai_family: AF_UNSPEC,
- ai_socktype: SOCK_DGRAM,
- ai_protocol: IPPROTO_UDP,
- ai_addrlen: 0,
- ai_canonname: nil,
- ai_addr: nil,
- ai_next: nil)
- if getaddrinfo(hostname, "\(port)", &hints, &resultPointer) != 0 || resultPointer == nil {
- return ret
- }
- let result = resultPointer!.pointee
- if result.ai_family == AF_INET && result.ai_addrlen == MemoryLayout<sockaddr_in>.size {
- var sa4 = UnsafeRawPointer(result.ai_addr)!.assumingMemoryBound(to: sockaddr_in.self).pointee
- let addr = IPv4Address(Data(bytes: &sa4.sin_addr, count: MemoryLayout<in_addr>.size))
- ret = Endpoint(host: .ipv4(addr!), port: port)
- } else if result.ai_family == AF_INET6 && result.ai_addrlen == MemoryLayout<sockaddr_in6>.size {
- var sa6 = UnsafeRawPointer(result.ai_addr)!.assumingMemoryBound(to: sockaddr_in6.self).pointee
- let addr = IPv6Address(Data(bytes: &sa6.sin6_addr, count: MemoryLayout<in6_addr>.size))
- ret = Endpoint(host: .ipv6(addr!), port: port)
- }
- freeaddrinfo(resultPointer)
- if ret.host != host {
- wg_log(.debug, message: "DNS64: mapped \(host) to \(ret.host)")
- } else {
- wg_log(.debug, message: "DNS64: mapped \(host) to itself.")
- }
- return ret
- #elseif os(macOS)
- return self
- #else
- #error("Unimplemented")
- #endif
- }
-}