From 772dfdef8c01388966a2a6c8fd80c045cfc98ece Mon Sep 17 00:00:00 2001
From: Revertron <105154+Revertron@users.noreply.github.com>
Date: Sun, 30 Oct 2022 22:14:30 +0100
Subject: [PATCH 1/3] Added DNS configuration functionality. (#24)
* Changed app icon from default to Yggdrasil leaf.
* Added workaround for DNS-reslver and fix for unmetered networks.
* Added DNS configuration functionality.
* Changed DNS configuration UI. Disabled DNS config by default. Added DNS fix for Chrome-based browsers.
---
app/build.gradle | 1 +
app/src/main/AndroidManifest.xml | 6 +-
.../eu/neilalexander/yggdrasil/DnsActivity.kt | 166 ++++++++++++
.../neilalexander/yggdrasil/MainActivity.kt | 24 +-
.../yggdrasil/PacketTunnelProvider.kt | 31 ++-
.../neilalexander/yggdrasil/PeersActivity.kt | 10 +-
app/src/main/res/layout/activity_dns.xml | 245 ++++++++++++++++++
app/src/main/res/layout/activity_main.xml | 50 +++-
app/src/main/res/layout/activity_peers.xml | 4 +-
.../main/res/layout/dialog_add_dns_server.xml | 34 +++
app/src/main/res/layout/dialog_addpeer.xml | 1 +
app/src/main/res/layout/dns_server_usable.xml | 47 ++++
app/src/main/res/layout/peers_configured.xml | 3 +-
app/src/main/res/values/strings.xml | 17 ++
build.gradle | 5 +-
readme.md | 2 +-
16 files changed, 620 insertions(+), 26 deletions(-)
create mode 100644 app/src/main/java/eu/neilalexander/yggdrasil/DnsActivity.kt
create mode 100644 app/src/main/res/layout/activity_dns.xml
create mode 100644 app/src/main/res/layout/dialog_add_dns_server.xml
create mode 100644 app/src/main/res/layout/dns_server_usable.xml
diff --git a/app/build.gradle b/app/build.gradle
index 213ae2b..52a4d45 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -55,6 +55,7 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
+ implementation 'androidx.preference:preference-ktx:1.1.0'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 776bbad..9a1557c 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -16,17 +16,19 @@
android:parentActivityName=".MainActivity" />
-
+
+
+ android:permission="android.permission.BIND_VPN_SERVICE"
+ android:exported="true">
diff --git a/app/src/main/java/eu/neilalexander/yggdrasil/DnsActivity.kt b/app/src/main/java/eu/neilalexander/yggdrasil/DnsActivity.kt
new file mode 100644
index 0000000..fc1c3ef
--- /dev/null
+++ b/app/src/main/java/eu/neilalexander/yggdrasil/DnsActivity.kt
@@ -0,0 +1,166 @@
+package eu.neilalexander.yggdrasil
+
+import android.annotation.SuppressLint
+import android.app.AlertDialog
+import android.content.SharedPreferences
+import androidx.appcompat.app.AppCompatActivity
+import android.os.Bundle
+import android.view.ContextThemeWrapper
+import android.view.LayoutInflater
+import android.view.View
+import android.widget.*
+import com.google.android.material.textfield.TextInputEditText
+
+const val KEY_DNS_SERVERS = "dns_servers"
+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
+ private lateinit var inflater: LayoutInflater
+
+ 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
+
+ @SuppressLint("ApplySharedPref")
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_dns)
+
+ config = ConfigurationProxy(applicationContext)
+ inflater = LayoutInflater.from(this)
+
+ 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(getString(R.string.dns_add_server_dialog_title))
+ builder.setView(view)
+ builder.setPositiveButton(getString(R.string.add)) { dialog, _ ->
+ servers.add(input.text.toString())
+ preferences.edit().apply {
+ putString(KEY_DNS_SERVERS, servers.joinToString(","))
+ commit()
+ }
+ dialog.dismiss()
+ updateConfiguredServers()
+ }
+ builder.setNegativeButton(getString(R.string.cancel)) { dialog, _ ->
+ dialog.cancel()
+ }
+ builder.show()
+ }
+
+ 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")
+ private fun updateConfiguredServers() {
+ when (servers.size) {
+ 0 -> {
+ serversTableLayout.visibility = View.GONE
+ 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 = getString(R.string.dns_configured_servers)
+ serversTableHint.text = getText(R.string.dns_configured_servers_hint)
+
+ serversTableLayout.removeAllViewsInLayout()
+ for (i in servers.indices) {
+ val server = servers[i]
+ val view = inflater.inflate(R.layout.peers_configured, null)
+ 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 ${server}?")
+ builder.setPositiveButton(getString(R.string.remove)) { dialog, _ ->
+ servers.removeAt(button.tag as Int)
+ preferences.edit().apply {
+ this.putString(KEY_DNS_SERVERS, servers.joinToString(","))
+ this.commit()
+ }
+ dialog.dismiss()
+ updateConfiguredServers()
+ }
+ builder.setNegativeButton(getString(R.string.cancel)) { dialog, _ ->
+ dialog.cancel()
+ }
+ builder.show()
+ }
+ serversTableLayout.addView(view)
+ }
+ }
+ }
+ }
+
+ @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 769b803..ea56090 100644
--- a/app/src/main/java/eu/neilalexander/yggdrasil/MainActivity.kt
+++ b/app/src/main/java/eu/neilalexander/yggdrasil/MainActivity.kt
@@ -27,6 +27,8 @@ class MainActivity : AppCompatActivity() {
private lateinit var coordinatesLabel: TextView
private lateinit var peersLabel: TextView
private lateinit var peersRow: TableRow
+ private lateinit var dnsLabel: TextView
+ private lateinit var dnsRow: TableRow
private lateinit var settingsRow: TableRow
private fun start() {
@@ -47,13 +49,15 @@ class MainActivity : AppCompatActivity() {
findViewById(R.id.versionValue).text = Mobile.getVersion()
- enabledSwitch = findViewById(R.id.enableMulticastBeacon)
+ enabledSwitch = findViewById(R.id.enableYggdrasil)
enabledLabel = findViewById(R.id.yggdrasilStatusLabel)
ipAddressLabel = findViewById(R.id.ipAddressValue)
subnetLabel = findViewById(R.id.subnetValue)
coordinatesLabel = findViewById(R.id.coordinatesValue)
peersLabel = findViewById(R.id.peersValue)
peersRow = findViewById(R.id.peersTableRow)
+ dnsLabel = findViewById(R.id.dnsValue)
+ dnsRow = findViewById(R.id.dnsTableRow)
settingsRow = findViewById(R.id.settingsTableRow)
enabledLabel.setTextColor(Color.GRAY)
@@ -82,6 +86,12 @@ class MainActivity : AppCompatActivity() {
startActivity(intent)
}
+ dnsRow.isClickable = true
+ dnsRow.setOnClickListener {
+ val intent = Intent(this, DnsActivity::class.java)
+ startActivity(intent)
+ }
+
settingsRow.isClickable = true
settingsRow.setOnClickListener {
val intent = Intent(this, SettingsActivity::class.java)
@@ -94,6 +104,18 @@ class MainActivity : AppCompatActivity() {
LocalBroadcastManager.getInstance(this).registerReceiver(
receiver, IntentFilter(PacketTunnelState.RECEIVER_INTENT)
)
+ val preferences = androidx.preference.PreferenceManager.getDefaultSharedPreferences(this.baseContext)
+ val serverString = preferences.getString(KEY_DNS_SERVERS, "")
+ if (serverString!!.isNotEmpty()) {
+ val servers = serverString.split(",")
+ dnsLabel.text = when (servers.size) {
+ 0 -> "No servers"
+ 1 -> "1 server"
+ else -> "${servers.size} servers"
+ }
+ } else {
+ dnsLabel.text = "No servers"
+ }
}
private val receiver: BroadcastReceiver = object : BroadcastReceiver() {
diff --git a/app/src/main/java/eu/neilalexander/yggdrasil/PacketTunnelProvider.kt b/app/src/main/java/eu/neilalexander/yggdrasil/PacketTunnelProvider.kt
index d92ce8f..dd8afc3 100644
--- a/app/src/main/java/eu/neilalexander/yggdrasil/PacketTunnelProvider.kt
+++ b/app/src/main/java/eu/neilalexander/yggdrasil/PacketTunnelProvider.kt
@@ -17,6 +17,8 @@ import java.util.concurrent.atomic.AtomicBoolean
import kotlin.concurrent.thread
+private const val TAG = "PacketTunnelProvider"
+
class PacketTunnelProvider: VpnService() {
companion object {
const val RECEIVER_INTENT = "eu.neilalexander.yggdrasil.PacketTunnelProvider.MESSAGE"
@@ -50,16 +52,16 @@ class PacketTunnelProvider: VpnService() {
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
if (intent == null) {
- Log.d("PacketTunnelProvider", "Intent is null")
+ Log.d(TAG, "Intent is null")
return START_NOT_STICKY
}
return when (intent.action ?: ACTION_STOP) {
ACTION_STOP -> {
- Log.d("PacketTunnelProvider", "Stopping...")
+ Log.d(TAG, "Stopping...")
stop(); START_NOT_STICKY
}
else -> {
- Log.d("PacketTunnelProvider", "Starting...")
+ Log.d(TAG, "Starting...")
start(); START_STICKY
}
}
@@ -70,11 +72,11 @@ class PacketTunnelProvider: VpnService() {
return
}
- Log.d("PacketTunnelProvider", config.getJSON().toString())
+ Log.d(TAG, config.getJSON().toString())
yggdrasil.startJSON(config.getJSONByteArray())
val address = yggdrasil.addressString
- var builder = Builder()
+ val builder = Builder()
.addAddress(address, 7)
.addRoute("200::", 7)
// We do this to trick the DNS-resolver into thinking that we have "regular" IPv6,
@@ -97,6 +99,21 @@ class PacketTunnelProvider: VpnService() {
builder.setMetered(false)
}
+ val preferences = androidx.preference.PreferenceManager.getDefaultSharedPreferences(this.baseContext)
+ val serverString = preferences.getString(KEY_DNS_SERVERS, "")
+ if (serverString!!.isNotEmpty()) {
+ val servers = serverString.split(",")
+ if (servers.isNotEmpty()) {
+ servers.forEach {
+ Log.i(TAG, "Using DNS server $it")
+ builder.addDnsServer(it)
+ }
+ }
+ }
+ if (preferences.getBoolean(KEY_ENABLE_CHROME_FIX, false)) {
+ builder.addRoute("2001:4860:4860::8888", 128)
+ }
+
parcel = builder.establish()
val parcel = parcel
if (parcel == null || !parcel.fileDescriptor.valid()) {
@@ -123,7 +140,7 @@ class PacketTunnelProvider: VpnService() {
intent.putExtra("ip", yggdrasil.addressString)
intent.putExtra("subnet", yggdrasil.subnetString)
intent.putExtra("coords", yggdrasil.coordsString)
- intent.putExtra("peers", JSONArray(yggdrasil.peersJSON).length())
+ intent.putExtra("peers", yggdrasil.peersJSON)
LocalBroadcastManager.getInstance(this).sendBroadcast(intent)
}
@@ -214,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/java/eu/neilalexander/yggdrasil/PeersActivity.kt b/app/src/main/java/eu/neilalexander/yggdrasil/PeersActivity.kt
index af76c8b..b9ec651 100644
--- a/app/src/main/java/eu/neilalexander/yggdrasil/PeersActivity.kt
+++ b/app/src/main/java/eu/neilalexander/yggdrasil/PeersActivity.kt
@@ -49,14 +49,14 @@ class PeersActivity : AppCompatActivity() {
addPeerButton = findViewById(R.id.addPeerButton)
addPeerButton.setOnClickListener {
- var view = inflater.inflate(R.layout.dialog_addpeer, null)
- var input = view.findViewById(R.id.addPeerInput)
+ val view = inflater.inflate(R.layout.dialog_addpeer, null)
+ val input = view.findViewById(R.id.addPeerInput)
val builder: AlertDialog.Builder = AlertDialog.Builder(ContextThemeWrapper(this, R.style.Theme_MaterialComponents_DayNight_Dialog))
builder.setTitle("Add Configured Peer")
builder.setView(view)
builder.setPositiveButton("Add") { dialog, _ ->
config.updateJSON { json ->
- json.getJSONArray("Peers").put(input.text)
+ json.getJSONArray("Peers").put(input.text.toString().trim())
}
dialog.dismiss()
updateConfiguredPeers()
@@ -90,7 +90,7 @@ class PeersActivity : AppCompatActivity() {
configuredTableLayout.removeAllViewsInLayout()
for (i in 0 until peers.length()) {
val peer = peers[i].toString()
- var view = inflater.inflate(R.layout.peers_configured, null)
+ val view = inflater.inflate(R.layout.peers_configured, null)
view.findViewById(R.id.addressValue).text = peer
view.findViewById(R.id.deletePeerButton).tag = i
@@ -130,7 +130,7 @@ class PeersActivity : AppCompatActivity() {
connectedTableLayout.removeAllViewsInLayout()
for (i in 0 until peers.length()) {
val peer = peers.getJSONObject(i)
- var view = inflater.inflate(R.layout.peers_connected, null)
+ val view = inflater.inflate(R.layout.peers_connected, null)
val ip = peer.getString("IP")
view.findViewById(R.id.addressLabel).text = ip
view.findViewById(R.id.detailsLabel).text = peer.getString("Remote")
diff --git a/app/src/main/res/layout/activity_dns.xml b/app/src/main/res/layout/activity_dns.xml
new file mode 100644
index 0000000..132f2a0
--- /dev/null
+++ b/app/src/main/res/layout/activity_dns.xml
@@ -0,0 +1,245 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 9b2fcd8..2064b49 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -94,7 +94,7 @@
android:layout_weight="2" />
@@ -347,6 +347,50 @@
app:srcCompat="@drawable/ic_baseline_chevron_right_24" />
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_peers.xml b/app/src/main/res/layout/activity_peers.xml
index 3001949..a9d74b0 100644
--- a/app/src/main/res/layout/activity_peers.xml
+++ b/app/src/main/res/layout/activity_peers.xml
@@ -128,7 +128,7 @@
android:layout_height="wrap_content"
android:layout_marginStart="16pt"
android:layout_marginLeft="16pt"
- android:layout_marginTop="2pt"
+ android:layout_marginTop="4pt"
android:layout_marginEnd="8pt"
android:layout_marginRight="8pt"
android:layout_marginBottom="4pt"
@@ -237,7 +237,7 @@
android:layout_height="wrap_content"
android:layout_marginStart="16pt"
android:layout_marginLeft="16pt"
- android:layout_marginTop="2pt"
+ android:layout_marginTop="4pt"
android:layout_marginEnd="8pt"
android:layout_marginRight="8pt"
android:alpha="0.7"
diff --git a/app/src/main/res/layout/dialog_add_dns_server.xml b/app/src/main/res/layout/dialog_add_dns_server.xml
new file mode 100644
index 0000000..341c502
--- /dev/null
+++ b/app/src/main/res/layout/dialog_add_dns_server.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_addpeer.xml b/app/src/main/res/layout/dialog_addpeer.xml
index c627c5c..0e334d2 100644
--- a/app/src/main/res/layout/dialog_addpeer.xml
+++ b/app/src/main/res/layout/dialog_addpeer.xml
@@ -27,6 +27,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4pt"
+ android:lines="1"
android:hint="tcp://address:port" />
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/layout/peers_configured.xml b/app/src/main/res/layout/peers_configured.xml
index 82615d5..19ede91 100644
--- a/app/src/main/res/layout/peers_configured.xml
+++ b/app/src/main/res/layout/peers_configured.xml
@@ -1,7 +1,6 @@
@@ -16,7 +15,7 @@
android:layout_marginBottom="12dp"
android:ellipsize="end"
android:singleLine="true"
- android:text="TextView"
+ android:text=""
android:textColor="?attr/textDefault"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/deletePeerButton"
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
diff --git a/build.gradle b/build.gradle
index b090095..0cf859d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,12 +1,12 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
- ext.kotlin_version = "1.5.0"
+ ext.kotlin_version = '1.7.20'
repositories {
google()
mavenCentral()
}
dependencies {
- classpath "com.android.tools.build:gradle:4.2.1"
+ classpath "com.android.tools.build:gradle:4.2.2"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
@@ -18,7 +18,6 @@ allprojects {
repositories {
google()
mavenCentral()
- jcenter() // Warning: this repository is going to shut down soon
}
}
diff --git a/readme.md b/readme.md
index a4f2ec1..69fe52e 100644
--- a/readme.md
+++ b/readme.md
@@ -26,7 +26,7 @@ cp /tmp/yggdrasil-go/yggdrasil.aar /tmp/yggdrasil-android/app/libs/
```
cd /tmp/yggdrasil-android
-./gradew assembleRelease
+./gradlew assembleRelease
```
note: you will need to use jdk-11 as jdk-16 `"doesn't work" ™`
From 6771177ca9cd1458726c10cb4fa4797c0e95688e Mon Sep 17 00:00:00 2001
From: Neil Alexander
Date: Sun, 30 Oct 2022 21:23:34 +0000
Subject: [PATCH 2/3] Update DNS server strings
---
app/src/main/res/layout/dialog_add_dns_server.xml | 2 +-
app/src/main/res/values/strings.xml | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/app/src/main/res/layout/dialog_add_dns_server.xml b/app/src/main/res/layout/dialog_add_dns_server.xml
index 341c502..f779d30 100644
--- a/app/src/main/res/layout/dialog_add_dns_server.xml
+++ b/app/src/main/res/layout/dialog_add_dns_server.xml
@@ -16,7 +16,7 @@
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:text="Enter the IP address of DNS server to add. It will be used by OS and all apps when Yggdrasil starts." />
+ android:text="Enter the IP address of the DNS server to add. Note that all DNS requests, including for non-Yggdrasil internet hostnames, will be sent to these servers." />
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.
+ Use these DNS servers while Yggdrasil is running. Note that all DNS requests, including for non-Yggdrasil internet hostnames, will be sent to these servers.
+ Yggdrasil will not configure any DNS servers when the service starts. All DNS requests will be resolved by the default resolver.
+ These DNS servers are provided by community members. Click the + button to add them to the 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.
@@ -15,6 +15,6 @@
DNS
Usable servers
Fix Chrome-based browsers
- Chrome-based browsers need an additional fix to understand that you have IPv6 connectivity.
+ If you do not have IPv6 internet connectivity, this option should help Chrome-based browsers to resolve Yggdrasil domain names correctly.
DNS fixes
\ No newline at end of file
From 24bcee79341634533124a758a5eeef6ba1652c2c Mon Sep 17 00:00:00 2001
From: Neil Alexander
Date: Sun, 30 Oct 2022 21:35:00 +0000
Subject: [PATCH 3/3] Update CI
---
.github/workflows/android.yml | 10 ++++-
.github/workflows/nightlylink.yml | 62 -------------------------------
2 files changed, 9 insertions(+), 63 deletions(-)
delete mode 100644 .github/workflows/nightlylink.yml
diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml
index 0a39c9c..dc1eec4 100644
--- a/.github/workflows/android.yml
+++ b/.github/workflows/android.yml
@@ -55,7 +55,14 @@ jobs:
env:
ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
- - name: Gradle build
+ - name: Gradle build
+ if: github.ref_name != 'main'
+ run: |
+ chmod +x gradlew
+ ./gradlew buildRelease
+
+ - name: Gradle signed build
+ if: github.ref_name == 'main'
run: |
echo "${{ secrets.RELEASE_KEYSTORE }}" > app/gha.keystore.asc
gpg -d --passphrase "${{ secrets.RELEASE_KEYSTORE_PASSWORD }}" --batch app/gha.keystore.asc > app/gha.jks
@@ -63,6 +70,7 @@ jobs:
./gradlew assembleYggdrasil
- name: Upload artifact
+ if: github.ref_name == 'main'
uses: actions/upload-artifact@v3
with:
name: yggdrasil-android
diff --git a/.github/workflows/nightlylink.yml b/.github/workflows/nightlylink.yml
deleted file mode 100644
index a90b517..0000000
--- a/.github/workflows/nightlylink.yml
+++ /dev/null
@@ -1,62 +0,0 @@
-name: Comment
-on:
- workflow_run:
- workflows: ['Build']
- types: [completed]
-jobs:
- pr_comment:
- if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success'
- runs-on: ubuntu-latest
- steps:
- - uses: actions/github-script@v6
- with:
- # This snippet is public-domain, taken from
- # https://github.com/oprypin/nightly.link/blob/master/.github/workflows/pr-comment.yml
- script: |
- async function upsertComment(owner, repo, issue_number, purpose, body) {
- const {data: comments} = await github.rest.issues.listComments(
- {owner, repo, issue_number});
-
- const marker = ``;
- body = marker + "\n" + body;
-
- const existing = comments.filter((c) => c.body.includes(marker));
- if (existing.length > 0) {
- const last = existing[existing.length - 1];
- core.info(`Updating comment ${last.id}`);
- await github.rest.issues.updateComment({
- owner, repo,
- body,
- comment_id: last.id,
- });
- } else {
- core.info(`Creating a comment in issue / PR #${issue_number}`);
- await github.rest.issues.createComment({issue_number, body, owner, repo});
- }
- }
-
- const {owner, repo} = context.repo;
- const run_id = ${{github.event.workflow_run.id}};
-
- const pull_requests = ${{ toJSON(github.event.workflow_run.pull_requests) }};
- if (!pull_requests.length) {
- return core.error("This workflow doesn't match any pull requests!");
- }
-
- const artifacts = await github.paginate(
- github.rest.actions.listWorkflowRunArtifacts, {owner, repo, run_id});
- if (!artifacts.length) {
- return core.error(`No artifacts found`);
- }
- let body = `Download the artifacts for this pull request:\n`;
- for (const art of artifacts) {
- body += `\n* [${art.name}.zip](https://nightly.link/${owner}/${repo}/actions/artifacts/${art.id}.zip)`;
- }
-
- core.info("Review thread message body:", body);
-
- for (const pr of pull_requests) {
- await upsertComment(owner, repo, pr.number,
- "nightly-link", body);
- }
-