@@ -6,52 +6,82 @@ import NetworkExtension
66
77extension DNSModule : NESettingsApplying {
88 public func apply( _ ctx: PartoutLoggerContext , to settings: inout NEPacketTunnelNetworkSettings ) {
9- var dnsSettings : NEDNSSettings ?
9+ let dnsSettings : NEDNSSettings
1010 let rawServers = servers. map ( \. rawValue)
1111
12+ // Former DNS settings are always overridden, even with empty servers
1213 switch protocolType {
1314 case . cleartext:
14- if !rawServers. isEmpty {
15- dnsSettings = NEDNSSettings ( servers: rawServers)
16- pp_log ( ctx, . os, . info, " \t \t Servers: \( servers. map { $0. asSensitiveAddress ( ctx) } ) " )
17- } else {
18- pp_log ( ctx, . os, . info, " \t \t Servers: empty " )
15+ guard !rawServers. isEmpty else {
16+ pp_log ( ctx, . os, . info, " \t \t Skip DNS settings, cleartext requires non-empty servers " )
17+ return
1918 }
20-
19+ dnsSettings = NEDNSSettings ( servers: rawServers)
20+ pp_log ( ctx, . os, . info, " \t \t Servers: \( servers. map { $0. asSensitiveAddress ( ctx) } ) " )
2121 case . https( let url) :
2222 let specificSettings = NEDNSOverHTTPSSettings ( servers: rawServers)
2323 specificSettings. serverURL = url
2424 dnsSettings = specificSettings
2525 pp_log ( ctx, . os, . info, " \t \t Servers: \( servers. map { $0. asSensitiveAddress ( ctx) } ) " )
2626 pp_log ( ctx, . os, . info, " \t \t DoH URL: \( url. absoluteString. asSensitiveAddress ( ctx) ) " )
27-
2827 case . tls( let hostname) :
2928 let specificSettings = NEDNSOverTLSSettings ( servers: rawServers)
3029 specificSettings. serverName = hostname
3130 dnsSettings = specificSettings
3231 pp_log ( ctx, . os, . info, " \t \t Servers: \( servers. map { $0. asSensitiveAddress ( ctx) } ) " )
3332 pp_log ( ctx, . os, . info, " \t \t DoT hostname: \( hostname. asSensitiveAddress ( ctx) ) " )
34-
3533 @unknown default :
3634 break
3735 }
3836
39- if dnsSettings != nil {
40- domainName. map {
41- dnsSettings? . domainName = $0. rawValue
42- pp_log ( ctx, . os, . info, " \t \t Domain: \( $0. asSensitiveAddress ( ctx) ) " )
43- }
44- searchDomains. map {
45- guard !$0. isEmpty else {
46- return
47- }
48- dnsSettings? . searchDomains = $0. map ( \. rawValue)
49- pp_log ( ctx, . os, . info, " \t \t Search domains: \( $0. map { $0. asSensitiveAddress ( ctx) } ) " )
50- }
51- } else {
52- pp_log ( ctx, . os, . info, " \t \t Skip DNS settings " )
37+ // Main domain (if set)
38+ domainName. map {
39+ dnsSettings. domainName = $0. rawValue
40+ pp_log ( ctx, . os, . info, " \t \t Domain: \( $0. asSensitiveAddress ( ctx) ) " )
41+ }
42+
43+ // Apply domains with the given policy
44+ let domains = searchDomains ?? [ ]
45+ let domainsDescription = domains. map { $0. asSensitiveAddress ( ctx) }
46+ let searchDomains = domains. map ( \. rawValue)
47+ //
48+ // Credit for .matchDomains:
49+ // https://github.com/WireGuard/wireguard-apple/pull/11
50+ //
51+ switch domainPolicy {
52+ case . search:
53+ dnsSettings. searchDomains = searchDomains
54+ // XXX: This works around a Network Extension bug. We add the
55+ // search domains here because .searchDomains is ineffective when
56+ // the VPN is not the default gateway
57+ dnsSettings. matchDomains = [ " " ] + searchDomains
58+ dnsSettings. matchDomainsNoSearch = false
59+ pp_log ( ctx, . os, . info, " \t \t Search-only domains: \( domainsDescription) " )
60+ case . match:
61+ let matchDomains = !searchDomains. isEmpty ? searchDomains : [ " " ]
62+ dnsSettings. searchDomains = nil
63+ dnsSettings. matchDomains = matchDomains
64+ dnsSettings. matchDomainsNoSearch = true
65+ pp_log ( ctx, . os, . info, " \t \t Match-only domains: \( domainsDescription) " )
66+ default :
67+ let matchDomains = !searchDomains. isEmpty ? searchDomains : [ " " ]
68+ dnsSettings. searchDomains = searchDomains
69+ dnsSettings. matchDomains = matchDomains
70+ dnsSettings. matchDomainsNoSearch = false
71+ pp_log ( ctx, . os, . info, " \t \t Match/Search domains: \( domainsDescription) " )
72+ }
73+
74+ //
75+ // This is why we guard before committing .matchDomains:
76+ // https://git.zx2c4.com/wireguard-apple/commit/?id=20bdf46792905de8862ae7641e50e0f9f99ec946
77+ //
78+ assert ( dnsSettings. matchDomains != nil )
79+ if dnsSettings. servers. isEmpty {
80+ pp_log ( ctx, . os, . error, " \t \t Ignoring match domains without bootstrap DNS servers " )
81+ dnsSettings. matchDomains = nil
5382 }
5483
84+ // Commit to tunnel settings
5585 settings. dnsSettings = dnsSettings
5686 }
5787}
0 commit comments