From b7aaae7513a29e4082fc5e607ea514387a066408 Mon Sep 17 00:00:00 2001 From: Roopesh Chander Date: Mon, 29 Oct 2018 06:00:31 +0530 Subject: [PATCH] VPN: If we don't have to make a DNS request, we shouldn't enter that status Signed-off-by: Roopesh Chander --- WireGuard/WireGuard/VPN/DNSResolver.swift | 14 +++++++ WireGuard/WireGuard/VPN/TunnelsManager.swift | 42 ++++++++++++++------ 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/WireGuard/WireGuard/VPN/DNSResolver.swift b/WireGuard/WireGuard/VPN/DNSResolver.swift index c047966..c7cf6c5 100644 --- a/WireGuard/WireGuard/VPN/DNSResolver.swift +++ b/WireGuard/WireGuard/VPN/DNSResolver.swift @@ -16,6 +16,20 @@ class DNSResolver { self.dispatchGroup = DispatchGroup() } + func resolveWithoutNetworkRequests() -> [Endpoint?]? { + var resolvedEndpoints: [Endpoint?] = Array(repeating: nil, count: endpoints.count) + for (i, endpoint) in self.endpoints.enumerated() { + guard let endpoint = endpoint else { continue } + if let resolvedEndpointStringInCache = DNSResolver.cache.object(forKey: endpoint.stringRepresentation() as NSString), + let resolvedEndpointInCache = Endpoint(from: resolvedEndpointStringInCache as String) { + resolvedEndpoints[i] = resolvedEndpointInCache + } else { + return nil + } + } + return resolvedEndpoints + } + func resolve(completionHandler: @escaping ([Endpoint?]?) -> Void) { let endpoints = self.endpoints let dispatchGroup = self.dispatchGroup diff --git a/WireGuard/WireGuard/VPN/TunnelsManager.swift b/WireGuard/WireGuard/VPN/TunnelsManager.swift index 76d5c05..1210d7e 100644 --- a/WireGuard/WireGuard/VPN/TunnelsManager.swift +++ b/WireGuard/WireGuard/VPN/TunnelsManager.swift @@ -261,19 +261,9 @@ class TunnelContainer: NSObject { let endpoints = tunnelConfiguration.peers.map { $0.endpoint } let dnsResolver = DNSResolver(endpoints: endpoints) assert(self.dnsResolver == nil) - self.dnsResolver = dnsResolver - status = .resolvingEndpointDomains - dnsResolver.resolve { [weak self] endpoints in - guard let s = self else { return } - assert(s.status == .resolvingEndpointDomains) - s.dnsResolver = nil - guard let endpoints = endpoints else { - completionHandler(TunnelsManagerError.dnsResolutionFailed) - s.status = .inactive - return - } - s.tunnelProvider.loadFromPreferences { [weak s] (error) in - guard let s = s else { return } + if let endpoints = dnsResolver.resolveWithoutNetworkRequests() { + self.tunnelProvider.loadFromPreferences { [weak self] (error) in + guard let s = self else { return } s.startObservingTunnelStatus() let session = (s.tunnelProvider.connection as! NETunnelProviderSession) do { @@ -285,6 +275,32 @@ class TunnelContainer: NSObject { completionHandler(error) } } + } else { + self.dnsResolver = dnsResolver + status = .resolvingEndpointDomains + dnsResolver.resolve { [weak self] endpoints in + guard let s = self else { return } + assert(s.status == .resolvingEndpointDomains) + s.dnsResolver = nil + guard let endpoints = endpoints else { + completionHandler(TunnelsManagerError.dnsResolutionFailed) + s.status = .inactive + return + } + s.tunnelProvider.loadFromPreferences { [weak s] (error) in + guard let s = s else { return } + s.startObservingTunnelStatus() + let session = (s.tunnelProvider.connection as! NETunnelProviderSession) + do { + let tunnelOptions = PacketTunnelOptionsGenerator.generateOptions( + from: tunnelConfiguration, withResolvedEndpoints: endpoints) + try session.startTunnel(options: tunnelOptions) + } catch (let error) { + os_log("Failed to activate tunnel: %{public}@", log: OSLog.default, type: .debug, "\(error)") + completionHandler(error) + } + } + } } }