refactor DNS settings

This commit is contained in:
arm64v8a 2023-07-10 14:46:52 +09:00
parent 911a26edf5
commit 7a9463030c
11 changed files with 75 additions and 74 deletions

View File

@ -18,10 +18,8 @@ object Key {
const val REMOTE_DNS = "remoteDns" const val REMOTE_DNS = "remoteDns"
const val DIRECT_DNS = "directDns" const val DIRECT_DNS = "directDns"
const val DIRECT_DNS_USE_SYSTEM = "directDnsUseSystem"
const val ENABLE_DNS_ROUTING = "enableDnsRouting" const val ENABLE_DNS_ROUTING = "enableDnsRouting"
const val ENABLE_FAKEDNS = "enableFakeDns" const val ENABLE_FAKEDNS = "enableFakeDns"
const val DNS_NETWORK = "dnsNetwork"
const val IPV6_MODE = "ipv6Mode" const val IPV6_MODE = "ipv6Mode"
@ -32,7 +30,6 @@ object Key {
const val TRAFFIC_SNIFFING = "trafficSniffing" const val TRAFFIC_SNIFFING = "trafficSniffing"
const val RESOLVE_DESTINATION = "resolveDestination" const val RESOLVE_DESTINATION = "resolveDestination"
const val RESOLVE_SERVER = "resolveServer"
const val BYPASS_LAN = "bypassLan" const val BYPASS_LAN = "bypassLan"
const val BYPASS_LAN_IN_CORE = "bypassLanInCore" const val BYPASS_LAN_IN_CORE = "bypassLanInCore"

View File

@ -84,7 +84,6 @@ object DataStore : OnPreferenceDataStoreChangeListener {
var trafficSniffing by configurationStore.stringToInt(Key.TRAFFIC_SNIFFING) { 1 } var trafficSniffing by configurationStore.stringToInt(Key.TRAFFIC_SNIFFING) { 1 }
var resolveDestination by configurationStore.boolean(Key.RESOLVE_DESTINATION) var resolveDestination by configurationStore.boolean(Key.RESOLVE_DESTINATION)
var resolveServer by configurationStore.boolean(Key.RESOLVE_SERVER)
// var tcpKeepAliveInterval by configurationStore.stringToInt(Key.TCP_KEEP_ALIVE_INTERVAL) { 15 } // var tcpKeepAliveInterval by configurationStore.stringToInt(Key.TCP_KEEP_ALIVE_INTERVAL) { 15 }
var mtu by configurationStore.stringToInt(Key.MTU) { 9000 } var mtu by configurationStore.stringToInt(Key.MTU) { 9000 }
@ -98,10 +97,8 @@ object DataStore : OnPreferenceDataStoreChangeListener {
var remoteDns by configurationStore.string(Key.REMOTE_DNS) { "https://8.8.8.8/dns-query" } var remoteDns by configurationStore.string(Key.REMOTE_DNS) { "https://8.8.8.8/dns-query" }
var directDns by configurationStore.string(Key.DIRECT_DNS) { "https://223.5.5.5/dns-query" } var directDns by configurationStore.string(Key.DIRECT_DNS) { "https://223.5.5.5/dns-query" }
var directDnsUseSystem by configurationStore.boolean(Key.DIRECT_DNS_USE_SYSTEM)
var enableDnsRouting by configurationStore.boolean(Key.ENABLE_DNS_ROUTING) { true } var enableDnsRouting by configurationStore.boolean(Key.ENABLE_DNS_ROUTING) { true }
var enableFakeDns by configurationStore.boolean(Key.ENABLE_FAKEDNS) var enableFakeDns by configurationStore.boolean(Key.ENABLE_FAKEDNS)
var dnsNetwork by configurationStore.stringSet(Key.DNS_NETWORK)
var rulesProvider by configurationStore.stringToInt(Key.RULES_PROVIDER) var rulesProvider by configurationStore.stringToInt(Key.RULES_PROVIDER)
var logLevel by configurationStore.stringToInt(Key.LOG_LEVEL) var logLevel by configurationStore.stringToInt(Key.LOG_LEVEL)

View File

@ -32,7 +32,7 @@ import io.nekohasekai.sagernet.ktx.mkPort
import io.nekohasekai.sagernet.utils.PackageCache import io.nekohasekai.sagernet.utils.PackageCache
import moe.matsuri.nb4a.Protocols import moe.matsuri.nb4a.Protocols
import moe.matsuri.nb4a.SingBoxOptions.* import moe.matsuri.nb4a.SingBoxOptions.*
import moe.matsuri.nb4a.applyDNSNetworkSettings import moe.matsuri.nb4a.SingBoxOptionsUtil
import moe.matsuri.nb4a.checkEmpty import moe.matsuri.nb4a.checkEmpty
import moe.matsuri.nb4a.makeSingBoxRule import moe.matsuri.nb4a.makeSingBoxRule
import moe.matsuri.nb4a.plugin.Plugins import moe.matsuri.nb4a.plugin.Plugins
@ -146,7 +146,7 @@ fun buildConfig(
val bind = if (!forTest && DataStore.allowAccess) "0.0.0.0" else LOCALHOST val bind = if (!forTest && DataStore.allowAccess) "0.0.0.0" else LOCALHOST
val remoteDns = DataStore.remoteDns.split("\n") val remoteDns = DataStore.remoteDns.split("\n")
.mapNotNull { dns -> dns.trim().takeIf { it.isNotBlank() && !it.startsWith("#") } } .mapNotNull { dns -> dns.trim().takeIf { it.isNotBlank() && !it.startsWith("#") } }
var directDNS = DataStore.directDns.split("\n") val directDNS = DataStore.directDns.split("\n")
.mapNotNull { dns -> dns.trim().takeIf { it.isNotBlank() && !it.startsWith("#") } } .mapNotNull { dns -> dns.trim().takeIf { it.isNotBlank() && !it.startsWith("#") } }
val enableDnsRouting = DataStore.enableDnsRouting val enableDnsRouting = DataStore.enableDnsRouting
val useFakeDns = DataStore.enableFakeDns && !forTest && DataStore.ipv6Mode != IPv6Mode.ONLY val useFakeDns = DataStore.enableFakeDns && !forTest && DataStore.ipv6Mode != IPv6Mode.ONLY
@ -196,15 +196,18 @@ fun buildConfig(
servers = mutableListOf() servers = mutableListOf()
rules = mutableListOf() rules = mutableListOf()
independent_cache = true independent_cache = true
}
when (ipv6Mode) { fun autoDnsDomainStrategy(s: String): String? {
IPv6Mode.DISABLE -> { if (s.isNotEmpty()) {
strategy = "ipv4_only" return s
} }
return when (ipv6Mode) {
IPv6Mode.ONLY -> { IPv6Mode.DISABLE -> "ipv4_only"
strategy = "ipv6_only" IPv6Mode.ENABLE -> "prefer_ipv4"
} IPv6Mode.PREFER -> "prefer_ipv6"
IPv6Mode.ONLY -> "ipv6_only"
else -> null
} }
} }
@ -298,7 +301,7 @@ fun buildConfig(
val chainTag = "c-$chainId" val chainTag = "c-$chainId"
var muxApplied = false var muxApplied = false
var currentDomainStrategy = genDomainStrategy(DataStore.resolveServer) val defaultServerDomainStrategy = SingBoxOptionsUtil.domainStrategy("server")
profileList.forEachIndexed { index, proxyEntity -> profileList.forEachIndexed { index, proxyEntity ->
val bean = proxyEntity.requireBean() val bean = proxyEntity.requireBean()
@ -427,11 +430,12 @@ fun buildConfig(
// domain_strategy // domain_strategy
pastEntity?.requireBean()?.apply { pastEntity?.requireBean()?.apply {
// don't loopback // don't loopback
if (currentDomainStrategy != "" && !serverAddress.isIpAddress()) { if (defaultServerDomainStrategy != "" && !serverAddress.isIpAddress()) {
domainListDNSDirectForce.add("full:$serverAddress") domainListDNSDirectForce.add("full:$serverAddress")
} }
} }
currentOutbound["domain_strategy"] = if (forTest) "" else currentDomainStrategy currentOutbound["domain_strategy"] =
if (forTest) "" else defaultServerDomainStrategy
// custom JSON merge // custom JSON merge
if (bean.customOutboundJson.isNotBlank()) { if (bean.customOutboundJson.isNotBlank()) {
@ -597,12 +601,14 @@ fun buildConfig(
} }
userDNSRuleList += makeDnsRuleObj().apply { userDNSRuleList += makeDnsRuleObj().apply {
server = "dns-remote" server = "dns-remote"
inbound = null
} }
} }
-2L -> { -2L -> {
userDNSRuleList += makeDnsRuleObj().apply { server = "dns-block" } userDNSRuleList += makeDnsRuleObj().apply {
server = "dns-block"
disable_cache = true
}
} }
} }
@ -653,11 +659,6 @@ fun buildConfig(
}.asMap()) }.asMap())
} }
if (DataStore.directDnsUseSystem) {
// finally able to use "localDns" now...
directDNS = listOf(LOCAL_DNS_SERVER)
}
// Bypass Lookup for the first profile // Bypass Lookup for the first profile
bypassDNSBeans.forEach { bypassDNSBeans.forEach {
var serverAddr = it.serverAddress var serverAddr = it.serverAddress
@ -695,7 +696,7 @@ fun buildConfig(
address = it ?: throw Exception("No remote DNS, check your settings!") address = it ?: throw Exception("No remote DNS, check your settings!")
tag = "dns-remote" tag = "dns-remote"
address_resolver = "dns-direct" address_resolver = "dns-direct"
applyDNSNetworkSettings(false) strategy = autoDnsDomainStrategy(SingBoxOptionsUtil.domainStrategy(tag))
}) })
} }
@ -706,7 +707,7 @@ fun buildConfig(
tag = "dns-direct" tag = "dns-direct"
detour = TAG_DIRECT detour = TAG_DIRECT
address_resolver = "dns-local" address_resolver = "dns-local"
applyDNSNetworkSettings(true) strategy = autoDnsDomainStrategy(SingBoxOptionsUtil.domainStrategy(tag))
}) })
} }
dns.servers.add(DNSServerOptions().apply { dns.servers.add(DNSServerOptions().apply {

View File

@ -90,22 +90,9 @@ class SettingsPreferenceFragment : PreferenceFragmentCompat() {
val remoteDns = findPreference<EditTextPreference>(Key.REMOTE_DNS)!! val remoteDns = findPreference<EditTextPreference>(Key.REMOTE_DNS)!!
val directDns = findPreference<EditTextPreference>(Key.DIRECT_DNS)!! val directDns = findPreference<EditTextPreference>(Key.DIRECT_DNS)!!
val directDnsUseSystem = findPreference<SwitchPreference>(Key.DIRECT_DNS_USE_SYSTEM)!!
val enableDnsRouting = findPreference<SwitchPreference>(Key.ENABLE_DNS_ROUTING)!! val enableDnsRouting = findPreference<SwitchPreference>(Key.ENABLE_DNS_ROUTING)!!
val enableFakeDns = findPreference<SwitchPreference>(Key.ENABLE_FAKEDNS)!! val enableFakeDns = findPreference<SwitchPreference>(Key.ENABLE_FAKEDNS)!!
// if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
// DataStore.directDnsUseSystem = false
// directDnsUseSystem.remove()
// } else {
directDns.isEnabled = !directDnsUseSystem.isChecked
directDnsUseSystem.setOnPreferenceChangeListener { _, newValue ->
directDns.isEnabled = !(newValue as Boolean)
needReload()
true
}
// }
val requireTransproxy = findPreference<SwitchPreference>(Key.REQUIRE_TRANSPROXY)!! val requireTransproxy = findPreference<SwitchPreference>(Key.REQUIRE_TRANSPROXY)!!
val transproxyPort = findPreference<EditTextPreference>(Key.TRANSPROXY_PORT)!! val transproxyPort = findPreference<EditTextPreference>(Key.TRANSPROXY_PORT)!!
val transproxyMode = findPreference<SimpleMenuPreference>(Key.TRANSPROXY_MODE)!! val transproxyMode = findPreference<SimpleMenuPreference>(Key.TRANSPROXY_MODE)!!
@ -157,8 +144,6 @@ class SettingsPreferenceFragment : PreferenceFragmentCompat() {
entryValues = e entryValues = e
} }
val dnsNetwork = findPreference<MultiSelectListPreference>(Key.DNS_NETWORK)!!
portLocalDns.setOnBindEditTextListener(EditTextPreferenceModifiers.Port) portLocalDns.setOnBindEditTextListener(EditTextPreferenceModifiers.Port)
muxConcurrency.setOnBindEditTextListener(EditTextPreferenceModifiers.Port) muxConcurrency.setOnBindEditTextListener(EditTextPreferenceModifiers.Port)
mixedPort.setOnBindEditTextListener(EditTextPreferenceModifiers.Port) mixedPort.setOnBindEditTextListener(EditTextPreferenceModifiers.Port)
@ -191,7 +176,6 @@ class SettingsPreferenceFragment : PreferenceFragmentCompat() {
val tunImplementation = findPreference<SimpleMenuPreference>(Key.TUN_IMPLEMENTATION)!! val tunImplementation = findPreference<SimpleMenuPreference>(Key.TUN_IMPLEMENTATION)!!
val resolveDestination = findPreference<SwitchPreference>(Key.RESOLVE_DESTINATION)!! val resolveDestination = findPreference<SwitchPreference>(Key.RESOLVE_DESTINATION)!!
val resolveServer = findPreference<SwitchPreference>(Key.RESOLVE_SERVER)!!
val acquireWakeLock = findPreference<SwitchPreference>(Key.ACQUIRE_WAKE_LOCK)!! val acquireWakeLock = findPreference<SwitchPreference>(Key.ACQUIRE_WAKE_LOCK)!!
val enableClashAPI = findPreference<SwitchPreference>(Key.ENABLE_CLASH_API)!! val enableClashAPI = findPreference<SwitchPreference>(Key.ENABLE_CLASH_API)!!
enableClashAPI.setOnPreferenceChangeListener { _, newValue -> enableClashAPI.setOnPreferenceChangeListener { _, newValue ->
@ -214,7 +198,6 @@ class SettingsPreferenceFragment : PreferenceFragmentCompat() {
remoteDns.onPreferenceChangeListener = reloadListener remoteDns.onPreferenceChangeListener = reloadListener
directDns.onPreferenceChangeListener = reloadListener directDns.onPreferenceChangeListener = reloadListener
enableDnsRouting.onPreferenceChangeListener = reloadListener enableDnsRouting.onPreferenceChangeListener = reloadListener
dnsNetwork.onPreferenceChangeListener = reloadListener
portLocalDns.onPreferenceChangeListener = reloadListener portLocalDns.onPreferenceChangeListener = reloadListener
ipv6Mode.onPreferenceChangeListener = reloadListener ipv6Mode.onPreferenceChangeListener = reloadListener
@ -224,7 +207,6 @@ class SettingsPreferenceFragment : PreferenceFragmentCompat() {
transproxyMode.onPreferenceChangeListener = reloadListener transproxyMode.onPreferenceChangeListener = reloadListener
resolveDestination.onPreferenceChangeListener = reloadListener resolveDestination.onPreferenceChangeListener = reloadListener
resolveServer.onPreferenceChangeListener = reloadListener
tunImplementation.onPreferenceChangeListener = reloadListener tunImplementation.onPreferenceChangeListener = reloadListener
acquireWakeLock.onPreferenceChangeListener = reloadListener acquireWakeLock.onPreferenceChangeListener = reloadListener

View File

@ -2,14 +2,28 @@ package moe.matsuri.nb4a
import io.nekohasekai.sagernet.database.DataStore import io.nekohasekai.sagernet.database.DataStore
fun SingBoxOptions.DNSServerOptions.applyDNSNetworkSettings(isDirect: Boolean) { object SingBoxOptionsUtil {
if (isDirect) {
if (DataStore.dnsNetwork.contains("NoDirectIPv4")) this.strategy = "ipv6_only" fun domainStrategy(tag: String): String {
if (DataStore.dnsNetwork.contains("NoDirectIPv6")) this.strategy = "ipv4_only" fun auto2AsIs(key: String): String {
} else { return (DataStore.configurationStore.getString(key) ?: "").replace("auto", "")
if (DataStore.dnsNetwork.contains("NoRemoteIPv4")) this.strategy = "ipv6_only" }
if (DataStore.dnsNetwork.contains("NoRemoteIPv6")) this.strategy = "ipv4_only" return when (tag) {
"dns-remote" -> {
auto2AsIs("domain_strategy_for_remote")
}
"dns-direct" -> {
auto2AsIs("domain_strategy_for_direct")
}
// server
else -> {
auto2AsIs("domain_strategy_for_server")
}
}
} }
} }
fun SingBoxOptions.DNSRule_DefaultOptions.makeSingBoxRule(list: List<String>) { fun SingBoxOptions.DNSRule_DefaultOptions.makeSingBoxRule(list: List<String>) {

View File

@ -80,7 +80,6 @@
<string name="cag_dns">Ajustes de DNS</string> <string name="cag_dns">Ajustes de DNS</string>
<string name="remote_dns">DNS remoto</string> <string name="remote_dns">DNS remoto</string>
<string name="direct_dns">DNS directo</string> <string name="direct_dns">DNS directo</string>
<string name="direct_dns_use_system">Utilizar DNS del sistema como DNS directo</string>
<string name="enable_dns_routing">Activar enrutamiento DNS</string> <string name="enable_dns_routing">Activar enrutamiento DNS</string>
<string name="dns_routing_message">Resuelve dominios en rutas de omisión con el DNS directo. Tenga en cuenta las posibles fugas de DNS</string> <string name="dns_routing_message">Resuelve dominios en rutas de omisión con el DNS directo. Tenga en cuenta las posibles fugas de DNS</string>
<string name="enable_fakedns">Activar DNS falso</string> <string name="enable_fakedns">Activar DNS falso</string>

View File

@ -78,7 +78,6 @@
<string name="cag_dns">تنظیمات DNS</string> <string name="cag_dns">تنظیمات DNS</string>
<string name="remote_dns">DNS از راه دور</string> <string name="remote_dns">DNS از راه دور</string>
<string name="direct_dns">DNS مستقیم</string> <string name="direct_dns">DNS مستقیم</string>
<string name="direct_dns_use_system">از DNS سیستم به عنوان Direct DNS استفاده کنید</string>
<string name="enable_dns_routing">مسیریابی DNS را فعال کنید</string> <string name="enable_dns_routing">مسیریابی DNS را فعال کنید</string>
<string name="dns_routing_message">حل دامنه ها در مسیرهای بای پس با Direct DNS. از نشت های احتمالی DNS آگاه باشید</string> <string name="dns_routing_message">حل دامنه ها در مسیرهای بای پس با Direct DNS. از نشت های احتمالی DNS آگاه باشید</string>
<string name="enable_fakedns">FakeDNS را فعال کنید</string> <string name="enable_fakedns">FakeDNS را فعال کنید</string>

View File

@ -334,7 +334,6 @@
<string name="clear_profiles_message">您确定要清空该分组吗\?</string> <string name="clear_profiles_message">您确定要清空该分组吗\?</string>
<string name="remote_dns">远程 DNS</string> <string name="remote_dns">远程 DNS</string>
<string name="direct_dns">直连 DNS</string> <string name="direct_dns">直连 DNS</string>
<string name="direct_dns_use_system">使用系统 DNS 作为直连 DNS</string>
<string name="enable_dns_routing">启用 DNS 路由</string> <string name="enable_dns_routing">启用 DNS 路由</string>
<string name="dns_routing_message">使用直连 DNS 解析绕过路由中的 domains. 注意潜在的 DNS 泄漏</string> <string name="dns_routing_message">使用直连 DNS 解析绕过路由中的 domains. 注意潜在的 DNS 泄漏</string>
<string name="enable_fakedns">启用 FakeDNS</string> <string name="enable_fakedns">启用 FakeDNS</string>
@ -442,7 +441,9 @@
<string name="create_shortcut">创建快捷方式</string> <string name="create_shortcut">创建快捷方式</string>
<string name="app_tls_version">订阅最低 TLS 版本</string> <string name="app_tls_version">订阅最低 TLS 版本</string>
<string name="hop_interval">端口跳跃间隔(秒)</string> <string name="hop_interval">端口跳跃间隔(秒)</string>
<string name="dns_network">DNS 查询类型</string> <string name="domain_strategy_for_remote">域名策略(远程)</string>
<string name="domain_strategy_for_direct">域名策略(直连)</string>
<string name="domain_strategy_for_server">域名策略(服务器地址)</string>
<string name="tuic_disable_sni">禁用 SNI</string> <string name="tuic_disable_sni">禁用 SNI</string>
<string name="tuic_reduce_rtt">启用 0-RTT QUIC 握手</string> <string name="tuic_reduce_rtt">启用 0-RTT QUIC 握手</string>
<string name="tuic_fast_connect">TCP 快速打开</string> <string name="tuic_fast_connect">TCP 快速打开</string>

View File

@ -445,10 +445,11 @@
</string-array> </string-array>
<string-array name="dns_network_select"> <string-array name="dns_network_select">
<item>NoRemoteIPv4</item> <item>auto</item>
<item>NoRemoteIPv6</item> <item>prefer_ipv6</item>
<item>NoDirectIPv4</item> <item>prefer_ipv4</item>
<item>NoDirectIPv6</item> <item>ipv4_only</item>
<item>ipv6_only</item>
</string-array> </string-array>
<string-array name="exe_prefer_provider"> <string-array name="exe_prefer_provider">

View File

@ -84,7 +84,6 @@
<string name="cag_dns">DNS Settings</string> <string name="cag_dns">DNS Settings</string>
<string name="remote_dns">Remote DNS</string> <string name="remote_dns">Remote DNS</string>
<string name="direct_dns">Direct DNS</string> <string name="direct_dns">Direct DNS</string>
<string name="direct_dns_use_system">Use system DNS as Direct DNS</string>
<string name="enable_dns_routing">Enable DNS Routing</string> <string name="enable_dns_routing">Enable DNS Routing</string>
<string name="dns_routing_message">Resolve domains in bypass routes with Direct DNS. Be aware of potential DNS leaks</string> <string name="dns_routing_message">Resolve domains in bypass routes with Direct DNS. Be aware of potential DNS leaks</string>
<string name="enable_fakedns">Enable FakeDNS</string> <string name="enable_fakedns">Enable FakeDNS</string>
@ -487,7 +486,9 @@ Anyone can write advanced plugins, which can control NekoBox. please download an
<string name="create_shortcut">Create Shortcut</string> <string name="create_shortcut">Create Shortcut</string>
<string name="app_tls_version">Subscription Min TLS Version</string> <string name="app_tls_version">Subscription Min TLS Version</string>
<string name="hop_interval">Port Hopping Interval(second)</string> <string name="hop_interval">Port Hopping Interval(second)</string>
<string name="dns_network">DNS query type</string> <string name="domain_strategy_for_remote">Domain strategy for Remote</string>
<string name="domain_strategy_for_direct">Domain strategy for Direct</string>
<string name="domain_strategy_for_server">Domain strategy for Server address</string>
<string name="show_bottom_bar">Show bottom bar like SagerNet</string> <string name="show_bottom_bar">Show bottom bar like SagerNet</string>
<string name="utls_fingerprint">uTLS fingerprint</string> <string name="utls_fingerprint">uTLS fingerprint</string>
<string name="custom_outbound_json">Custom outbound JSON</string> <string name="custom_outbound_json">Custom outbound JSON</string>

View File

@ -116,9 +116,6 @@
app:key="resolveDestination" app:key="resolveDestination"
app:summary="@string/resolve_destination_summary" app:summary="@string/resolve_destination_summary"
app:title="@string/resolve_destination" /> app:title="@string/resolve_destination" />
<SwitchPreference
app:key="resolveServer"
app:title="@string/resolve_server" />
<moe.matsuri.nb4a.ui.SimpleMenuPreference <moe.matsuri.nb4a.ui.SimpleMenuPreference
app:defaultValue="0" app:defaultValue="0"
app:entries="@array/ipv6_mode" app:entries="@array/ipv6_mode"
@ -168,20 +165,32 @@
app:key="remoteDns" app:key="remoteDns"
app:title="@string/remote_dns" app:title="@string/remote_dns"
app:useSimpleSummaryProvider="true" /> app:useSimpleSummaryProvider="true" />
<moe.matsuri.nb4a.ui.SimpleMenuPreference
app:defaultValue="auto"
app:entries="@array/dns_network_select"
app:entryValues="@array/dns_network_select"
app:key="domain_strategy_for_remote"
app:title="@string/domain_strategy_for_remote"
app:useSimpleSummaryProvider="true" />
<EditTextPreference <EditTextPreference
app:defaultValue="https://223.5.5.5/dns-query" app:defaultValue="https://223.5.5.5/dns-query"
app:icon="@drawable/ic_action_dns"
app:key="directDns" app:key="directDns"
app:title="@string/direct_dns" app:title="@string/direct_dns"
app:useSimpleSummaryProvider="true" /> app:useSimpleSummaryProvider="true" />
<SwitchPreference <moe.matsuri.nb4a.ui.SimpleMenuPreference
app:key="directDnsUseSystem" app:defaultValue="auto"
app:title="@string/direct_dns_use_system" />
<MultiSelectListPreference
app:defaultValue="@array/mux_select_init"
app:entries="@array/dns_network_select" app:entries="@array/dns_network_select"
app:entryValues="@array/dns_network_select" app:entryValues="@array/dns_network_select"
app:key="dnsNetwork" app:key="domain_strategy_for_direct"
app:title="@string/dns_network" app:title="@string/domain_strategy_for_direct"
app:useSimpleSummaryProvider="true" />
<moe.matsuri.nb4a.ui.SimpleMenuPreference
app:defaultValue="auto"
app:entries="@array/dns_network_select"
app:entryValues="@array/dns_network_select"
app:key="domain_strategy_for_server"
app:title="@string/domain_strategy_for_server"
app:useSimpleSummaryProvider="true" /> app:useSimpleSummaryProvider="true" />
<SwitchPreference <SwitchPreference
app:defaultValue="true" app:defaultValue="true"