]> git.ipfire.org Git - thirdparty/wireguard-apple.git/commitdiff
DNSResolver: DNS resolution can now happen synchronously
authorRoopesh Chander <roop@roopc.net>
Thu, 8 Nov 2018 10:55:05 +0000 (16:25 +0530)
committerRoopesh Chander <roop@roopc.net>
Thu, 8 Nov 2018 12:22:11 +0000 (17:52 +0530)
Signed-off-by: Roopesh Chander <roop@roopc.net>
WireGuard/WireGuardNetworkExtension/DNSResolver.swift

index 6b7b73b7ec4116d13bbaff977a83df7574d07ccc..4181f75729d59271f5edf5845cbbdc6273fed96e 100644 (file)
@@ -4,6 +4,10 @@
 import Network
 import Foundation
 
+enum DNSResolverError: Error {
+    case dnsResolutionFailed(hostnames: [String])
+}
+
 class DNSResolver {
     let endpoints: [Endpoint?]
     let dispatchGroup: DispatchGroup
@@ -32,10 +36,11 @@ class DNSResolver {
         return resolvedEndpoints
     }
 
-    func resolve(completionHandler: @escaping ([Endpoint?]?) -> Void) {
+    func resolveSync() throws -> [Endpoint?] {
         let endpoints = self.endpoints
         let dispatchGroup = self.dispatchGroup
         dispatchWorkItems = []
+
         var resolvedEndpoints: [Endpoint?] = Array<Endpoint?>(repeating: nil, count: endpoints.count)
         var isResolvedByDNSRequest: [Bool] = Array<Bool>(repeating: false, count: endpoints.count)
         for (i, endpoint) in self.endpoints.enumerated() {
@@ -54,26 +59,26 @@ class DNSResolver {
                 DispatchQueue.global(qos: .userInitiated).async(group: dispatchGroup, execute: workItem)
             }
         }
-        dispatchGroup.notify(queue: .main) {
-            assert(endpoints.count == resolvedEndpoints.count)
-            for (i, endpoint) in endpoints.enumerated() {
-                guard let endpoint = endpoint, let resolvedEndpoint = resolvedEndpoints[i] else {
-                    completionHandler(nil)
-                    return
-                }
-                if (isResolvedByDNSRequest[i]) {
-                    DNSResolver.cache.setObject(resolvedEndpoint.stringRepresentation() as NSString,
-                                                forKey: endpoint.stringRepresentation() as NSString)
+
+        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) {
+                    // DNS resolution failed
+                    guard let hostname = endpoint.hostname() else { fatalError() }
+                    hostnamesWithDnsResolutionFailure.append(hostname)
                 }
             }
-            let numberOfEndpointsToResolve = endpoints.compactMap { $0 }.count
-            let numberOfResolvedEndpoints = resolvedEndpoints.compactMap { $0 }.count
-            if (numberOfResolvedEndpoints < numberOfEndpointsToResolve) {
-                completionHandler(nil)
-            } else {
-                completionHandler(resolvedEndpoints)
-            }
         }
+        if (!hostnamesWithDnsResolutionFailure.isEmpty) {
+            throw DNSResolverError.dnsResolutionFailed(hostnames: hostnamesWithDnsResolutionFailure)
+        }
+        return resolvedEndpoints
     }
 
     func cancel() {