@@ -2,62 +2,69 @@ import Foundation
22import NetworkExtension
33
44final class SplitTunnelDNSProxyProvider : NEDNSProxyProvider {
5-
6- public var flowHandler : FlowHandlerProtocol !
7- public var vpnState : VpnState !
8-
5+
6+ // The engine
7+ public var engine : ProxyEngineProtocol !
8+
99 // The logger
1010 public var logger : LoggerProtocol !
11-
12- override func startProxy( options: [ String : Any ] ? = nil , completionHandler: @escaping ( Error ? ) -> Void ) {
11+
12+ override func startProxy( options: [ String : Any ] ? , completionHandler: @escaping ( Error ? ) -> Void ) {
1313 let logLevel : String = options ? [ " logLevel " ] as? String ?? " "
1414 let logFile : String = options ? [ " logFile " ] as? String ?? " "
1515
1616 self . logger = self . logger ?? Logger . instance
1717
18- // Ensure the logger is initialized first
18+ // Ensure the logger is initialized first.
19+ // May be redundant
1920 logger. updateLogger ( logLevel: logLevel, logFile: logFile)
20-
21- // init just once, set up swiftNIO event loop
22- self . flowHandler = FlowHandler ( )
23-
24- var options = [
25- " bypassApps " : [ " /usr/bin/curl " , " org.mozilla.firefox " ] ,
21+
22+ // assume the option array is passed when the DNS proxy is started
23+ // or it's shared with the transparent proxy
24+ let _options = [
25+ " bypassApps " : [ " com.apple.nslookup " , " com.apple.curl " , " com.apple.ping " ] ,
2626 " vpnOnlyApps " : [ ] ,
2727 " bindInterface " : " en0 " ,
2828 " serverAddress " : " 127.0.0.1 " ,
29+ // do we want to use the same log file or a different one?
2930 " logFile " : " /tmp/STProxy.log " ,
3031 " logLevel " : " debug " ,
3132 " routeVpn " : true ,
3233 " isConnected " : true ,
34+ " dnsFollowAppRules " : true ,
3335 " whitelistGroupName " : " piavpn "
3436 ] as [ String : Any ]
35- guard let vpnState2 = VpnStateFactory . create ( options: options ) else {
37+ guard let vpnState = VpnStateFactory . create ( options: _options ) else {
3638 log ( . error, " provided incorrect list of options. They might be missing or an incorrect type " )
3739 return
3840 }
39- vpnState = vpnState2
40-
41- completionHandler ( nil )
42- }
4341
44- override func stopProxy( with reason: NEProviderStopReason , completionHandler: @escaping ( ) -> Void ) {
45- completionHandler ( )
42+ // Right now we do not share the engine with the transparent proxy.
43+ // This means we will have 2 SwiftNIO event loops and that both proxies are indipendent of eachother.
44+ // This can be refactored later if the DNS proxy never runs when the transparent proxy is off
45+ self . engine = self . engine ?? ProxyEngine ( vpnState: vpnState, flowHandler: DnsFlowHandler ( ) )
46+
47+ // Whitelist this process in the firewall - error logging happens in function.
48+ // May be redundant
49+ guard FirewallWhitelister ( groupName: vpnState. whitelistGroupName) . whitelist ( ) else {
50+ return
51+ }
52+
53+ completionHandler ( nil )
54+ log ( . info, " DNS Proxy started! " )
4655 }
4756
4857 // Be aware that by returning false in NEDNSProxyProvider handleNewFlow(),
4958 // the flow is discarded and the connection is closed.
5059 // This is similar to how NEAppProxyProvider works, compared to what we use
5160 // for traffic Split Tunnel which is NETransparentProxyProvider.
52- // This means that we need to handle ALL DNS requests when DNS Split Tunnel
53- // is enabled, even for non-managed apps.
61+ // This means that we need to handle the DNS requests of ALL apps
62+ // when DNS Split Tunnel is enabled
5463 override func handleNewFlow( _ flow: NEAppProxyFlow ) -> Bool {
55- var appName = flow. sourceAppSigningIdentifier
56- if appName == " com.apple.nslookup " || appName == " com.apple.curl " {
57- flowHandler. startProxySession ( flow: flow, vpnState: vpnState)
58- return true
59- } else {
60- return false
61- }
64+ return engine. handleNewFlow ( flow)
65+ }
66+
67+ override func stopProxy( with reason: NEProviderStopReason , completionHandler: @escaping ( ) -> Void ) {
68+ log ( . info, " DNS Proxy stopped! " )
6269 }
6370}
0 commit comments