From fdd0b7955b4b6909440631704770d72237233907 Mon Sep 17 00:00:00 2001 From: Revertron Date: Sun, 30 Oct 2022 17:09:38 +0100 Subject: [PATCH] Changed DNS configuration UI. Disabled DNS config by default. Added DNS fix for Chrome-based browsers. --- .../eu/neilalexander/yggdrasil/DnsActivity.kt | 90 +++++++++--- .../neilalexander/yggdrasil/MainActivity.kt | 2 +- .../yggdrasil/PacketTunnelProvider.kt | 7 +- app/src/main/res/layout/activity_dns.xml | 137 +++++++++++++++++- app/src/main/res/layout/dns_server_usable.xml | 47 ++++++ app/src/main/res/values/strings.xml | 17 +++ 6 files changed, 275 insertions(+), 25 deletions(-) create mode 100644 app/src/main/res/layout/dns_server_usable.xml diff --git a/app/src/main/java/eu/neilalexander/yggdrasil/DnsActivity.kt b/app/src/main/java/eu/neilalexander/yggdrasil/DnsActivity.kt index ff45391..fc1c3ef 100644 --- a/app/src/main/java/eu/neilalexander/yggdrasil/DnsActivity.kt +++ b/app/src/main/java/eu/neilalexander/yggdrasil/DnsActivity.kt @@ -12,7 +12,8 @@ import android.widget.* import com.google.android.material.textfield.TextInputEditText const val KEY_DNS_SERVERS = "dns_servers" -const val DEFAULT_DNS_SERVERS = "302:7991::53,302:db60::53,300:6223::53" +const val KEY_ENABLE_CHROME_FIX = "enable_chrome_fix" +const val DEFAULT_DNS_SERVERS = "302:7991::53,302:db60::53,300:6223::53,301:1088::53" class DnsActivity : AppCompatActivity() { private lateinit var config: ConfigurationProxy @@ -20,7 +21,10 @@ class DnsActivity : AppCompatActivity() { private lateinit var serversTableLayout: TableLayout private lateinit var serversTableLabel: TextView + private lateinit var serversTableHint: TextView private lateinit var addServerButton: ImageButton + private lateinit var enableChromeFix: Switch + private lateinit var servers: MutableList private lateinit var preferences: SharedPreferences @@ -34,41 +38,52 @@ class DnsActivity : AppCompatActivity() { serversTableLayout = findViewById(R.id.configuredDnsTableLayout) serversTableLabel = findViewById(R.id.configuredDnsLabel) + serversTableHint = findViewById(R.id.configuredDnsHint) + enableChromeFix = findViewById(R.id.enableChromeFix) addServerButton = findViewById(R.id.addServerButton) addServerButton.setOnClickListener { val view = inflater.inflate(R.layout.dialog_add_dns_server, null) val input = view.findViewById(R.id.addDnsInput) val builder: AlertDialog.Builder = AlertDialog.Builder(ContextThemeWrapper(this, R.style.Theme_MaterialComponents_DayNight_Dialog)) - builder.setTitle("Add DNS server") + builder.setTitle(getString(R.string.dns_add_server_dialog_title)) builder.setView(view) - builder.setPositiveButton("Add") { dialog, _ -> + builder.setPositiveButton(getString(R.string.add)) { dialog, _ -> servers.add(input.text.toString()) preferences.edit().apply { - this.putString(KEY_DNS_SERVERS, servers.joinToString(",")) - this.commit() + putString(KEY_DNS_SERVERS, servers.joinToString(",")) + commit() } dialog.dismiss() updateConfiguredServers() } - builder.setNegativeButton("Cancel") { dialog, _ -> + builder.setNegativeButton(getString(R.string.cancel)) { dialog, _ -> dialog.cancel() } builder.show() } - preferences = androidx.preference.PreferenceManager.getDefaultSharedPreferences(this.baseContext) - val serverString = preferences.getString(KEY_DNS_SERVERS, DEFAULT_DNS_SERVERS) - if (serverString!!.isNotEmpty()) { - servers = serverString.split(",").toMutableList() - } else { - servers = mutableListOf() + enableChromeFix.setOnCheckedChangeListener { _, isChecked -> + preferences.edit().apply { + putBoolean(KEY_ENABLE_CHROME_FIX, isChecked) + commit() + } } + + preferences = androidx.preference.PreferenceManager.getDefaultSharedPreferences(this.baseContext) + val serverString = preferences.getString(KEY_DNS_SERVERS, "") + servers = if (serverString!!.isNotEmpty()) { + serverString.split(",").toMutableList() + } else { + mutableListOf() + } + updateUsableServers() } override fun onResume() { super.onResume() updateConfiguredServers() + enableChromeFix.isChecked = preferences.getBoolean(KEY_ENABLE_CHROME_FIX, false) } @SuppressLint("ApplySharedPref") @@ -76,23 +91,25 @@ class DnsActivity : AppCompatActivity() { when (servers.size) { 0 -> { serversTableLayout.visibility = View.GONE - serversTableLabel.text = "No servers configured" + serversTableLabel.text = getString(R.string.dns_no_configured_servers) + serversTableHint.text = getText(R.string.dns_configured_servers_hint_empty) } else -> { serversTableLayout.visibility = View.VISIBLE - serversTableLabel.text = "Configured servers" + serversTableLabel.text = getString(R.string.dns_configured_servers) + serversTableHint.text = getText(R.string.dns_configured_servers_hint) serversTableLayout.removeAllViewsInLayout() for (i in servers.indices) { - val peer = servers[i] + val server = servers[i] val view = inflater.inflate(R.layout.peers_configured, null) - view.findViewById(R.id.addressValue).text = peer + view.findViewById(R.id.addressValue).text = server view.findViewById(R.id.deletePeerButton).tag = i view.findViewById(R.id.deletePeerButton).setOnClickListener { button -> val builder: AlertDialog.Builder = AlertDialog.Builder(this) - builder.setTitle("Remove ${peer}?") - builder.setPositiveButton("Remove") { dialog, _ -> + builder.setTitle("Remove ${server}?") + builder.setPositiveButton(getString(R.string.remove)) { dialog, _ -> servers.removeAt(button.tag as Int) preferences.edit().apply { this.putString(KEY_DNS_SERVERS, servers.joinToString(",")) @@ -101,7 +118,7 @@ class DnsActivity : AppCompatActivity() { dialog.dismiss() updateConfiguredServers() } - builder.setNegativeButton("Cancel") { dialog, _ -> + builder.setNegativeButton(getString(R.string.cancel)) { dialog, _ -> dialog.cancel() } builder.show() @@ -111,4 +128,39 @@ class DnsActivity : AppCompatActivity() { } } } + + @SuppressLint("ApplySharedPref") + private fun updateUsableServers() { + val usableTableLayout: TableLayout = findViewById(R.id.usableDnsTableLayout) + val defaultServers = DEFAULT_DNS_SERVERS.split(",") + + defaultServers.forEach { + val server = it + val view = inflater.inflate(R.layout.dns_server_usable, null) + view.findViewById(R.id.serverValue).text = server + val addButton = view.findViewById(R.id.addButton) + addButton.tag = server + + addButton.setOnClickListener { button -> + servers.add(button.tag as String) + preferences.edit().apply { + this.putString(KEY_DNS_SERVERS, servers.joinToString(",")) + this.commit() + } + updateConfiguredServers() + } + view.setOnLongClickListener { + val builder: AlertDialog.Builder = AlertDialog.Builder(this) + builder.setTitle(getString(R.string.dns_server_info_dialog_title)) + builder.setMessage(getText(R.string.dns_server_info_revertron)) + builder.setPositiveButton(getString(R.string.ok)) { dialog, _ -> + dialog.dismiss() + } + builder.show() + true + } + + usableTableLayout.addView(view) + } + } } \ No newline at end of file diff --git a/app/src/main/java/eu/neilalexander/yggdrasil/MainActivity.kt b/app/src/main/java/eu/neilalexander/yggdrasil/MainActivity.kt index 4d449cd..ea56090 100644 --- a/app/src/main/java/eu/neilalexander/yggdrasil/MainActivity.kt +++ b/app/src/main/java/eu/neilalexander/yggdrasil/MainActivity.kt @@ -105,7 +105,7 @@ class MainActivity : AppCompatActivity() { receiver, IntentFilter(PacketTunnelState.RECEIVER_INTENT) ) val preferences = androidx.preference.PreferenceManager.getDefaultSharedPreferences(this.baseContext) - val serverString = preferences.getString(KEY_DNS_SERVERS, DEFAULT_DNS_SERVERS) + val serverString = preferences.getString(KEY_DNS_SERVERS, "") if (serverString!!.isNotEmpty()) { val servers = serverString.split(",") dnsLabel.text = when (servers.size) { diff --git a/app/src/main/java/eu/neilalexander/yggdrasil/PacketTunnelProvider.kt b/app/src/main/java/eu/neilalexander/yggdrasil/PacketTunnelProvider.kt index 769780f..dd8afc3 100644 --- a/app/src/main/java/eu/neilalexander/yggdrasil/PacketTunnelProvider.kt +++ b/app/src/main/java/eu/neilalexander/yggdrasil/PacketTunnelProvider.kt @@ -100,7 +100,7 @@ class PacketTunnelProvider: VpnService() { } val preferences = androidx.preference.PreferenceManager.getDefaultSharedPreferences(this.baseContext) - val serverString = preferences.getString(KEY_DNS_SERVERS, DEFAULT_DNS_SERVERS) + val serverString = preferences.getString(KEY_DNS_SERVERS, "") if (serverString!!.isNotEmpty()) { val servers = serverString.split(",") if (servers.isNotEmpty()) { @@ -110,6 +110,9 @@ class PacketTunnelProvider: VpnService() { } } } + if (preferences.getBoolean(KEY_ENABLE_CHROME_FIX, false)) { + builder.addRoute("2001:4860:4860::8888", 128) + } parcel = builder.establish() val parcel = parcel @@ -228,7 +231,7 @@ class PacketTunnelProvider: VpnService() { } private fun reader() { - var b = ByteArray(65535) + val b = ByteArray(65535) reads@ while (started.get()) { val readerStream = readerStream val readerThread = readerThread diff --git a/app/src/main/res/layout/activity_dns.xml b/app/src/main/res/layout/activity_dns.xml index abb434e..132f2a0 100644 --- a/app/src/main/res/layout/activity_dns.xml +++ b/app/src/main/res/layout/activity_dns.xml @@ -27,7 +27,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="8pt" - android:text="DNS" + android:text="@string/dns_activity_title" android:textColor="?attr/textDefault" android:textSize="24sp" android:textStyle="bold" /> @@ -68,7 +68,7 @@ android:layout_marginBottom="2pt" android:alpha="0.7" android:paddingRight="8pt" - android:text="DNS servers" + android:text="" android:textAllCaps="true" android:textAppearance="@style/TextAppearance.AppCompat.Small" android:textSize="12sp" /> @@ -90,6 +90,57 @@ android:paddingBottom="2pt" android:showDividers="middle" /> + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/dns_server_usable.xml b/app/src/main/res/layout/dns_server_usable.xml new file mode 100644 index 0000000..d26e788 --- /dev/null +++ b/app/src/main/res/layout/dns_server_usable.xml @@ -0,0 +1,47 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c2e6bce..a8469d5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,3 +1,20 @@ Yggdrasil + Yggdrasil will use these DNS servers in VPN config when service starts. All your DNS requests will be resolved by them. + Yggdrasil will not configure any DNS servers when service starts. All your DNS requests will be resolved by system resolver. + These are DNS servers run by community members. Click plus button to add them to a list above. Long-tap to see more info. + No servers configured + Configured servers + The server supports resolving regular ICANN domains, ALFIS domains, OpenNIC domains.\n\nAlso, it blocks ads, analytics and malware websites.\n\nThe server is run by Revertron. + Server info + OK + Cancel + Remove + Add + Add DNS server + DNS + Usable servers + Fix Chrome-based browsers + Chrome-based browsers need an additional fix to understand that you have IPv6 connectivity. + DNS fixes \ No newline at end of file