Merge pull request #25 from vikulin/master

Fixed bug with checkmark clean up while adding new peers in list
This commit is contained in:
Vadym Vikulin 2020-10-17 20:20:22 +03:00 committed by GitHub
commit 7294166b50
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 362 additions and 67 deletions

View File

@ -1,6 +1,22 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<JetCodeStyleSettings>
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
<value>
<package name="java.util" alias="false" withSubpackages="false" />
<package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" />
<package name="io.ktor" alias="false" withSubpackages="true" />
</value>
</option>
<option name="PACKAGES_IMPORT_LAYOUT">
<value>
<package name="" alias="false" withSubpackages="true" />
<package name="java" alias="false" withSubpackages="true" />
<package name="javax" alias="false" withSubpackages="true" />
<package name="kotlin" alias="false" withSubpackages="true" />
<package name="" alias="true" withSubpackages="true" />
</value>
</option>
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings>
<codeStyleSettings language="XML">

1
.idea/gradle.xml generated
View File

@ -15,6 +15,7 @@
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
<option name="useQualifiedModuleNames" value="true" />
</GradleProjectSettings>
</option>
</component>

View File

@ -3,15 +3,15 @@ apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 29
compileSdkVersion 30
defaultConfig {
applicationId "io.github.chronosx88.yggdrasil"
minSdkVersion 15
targetSdkVersion 29
versionCode 4
versionName "1.4"
targetSdkVersion 30
versionCode 5
versionName "1.5"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
project.ext.set("archivesBaseName", project.getParent().name+"-"+versionName)
setProperty("archivesBaseName", project.getParent().name+"-"+versionName)
}
signingConfigs {
release {
@ -58,8 +58,8 @@ dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation project(path: ':yggdrasil')
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
implementation "androidx.preference:preference-ktx:1.1.1"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
@ -69,6 +69,6 @@ dependencies {
implementation 'com.hbb20:ccp:2.4.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
androidTestImplementation 'androidx.test:runner:1.3.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}

View File

@ -14,6 +14,12 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
tools:ignore="GoogleAppIndexingWarning">
<activity
android:name=".AboutActivity"
android:parentActivityName=".MainActivity"
android:label="@string/title_activity_about"
android:theme="@style/AppTheme.NoActionBar"
android:screenOrientation="portrait"/>
<activity
android:name=".PeerListActivity"
android:parentActivityName=".MainActivity"

View File

@ -0,0 +1,205 @@
package io.github.chronosx88.yggdrasil
import android.os.Bundle
import android.text.Html
import android.text.method.LinkMovementMethod
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.text.HtmlCompat
class AboutActivity:AppCompatActivity() {
companion object {
@JvmStatic var about = "<body style=\"background-color:#343334;\">\n" +
"<p class=\"western\" align=\"center\">\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\" color=\"#ffffff\">\n" +
"Github repo <a href=\"https://github.com/yggdrasil-network/yggdrasil-android\"><u>https://github.com/yggdrasil-network/yggdrasil-android</u></a>.\n" +
"</font>\n" +
"<p class=\"western\" ><font style=\"font-size: 14pt\" color=\"#ffffff\"><b>Introduction</b></font></p>\n" +
"<p>\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\">Yggdrasil is an early-stage implementation of a fully end-to-end encrypted IPv6 network. I\n" +
"t is lightweight, self-arranging, supported on multiple platforms and allows pretty much any IPv6-capable application to communicate securely with other Yggdrasil nodes.\n" +
"Yggdrasil does not require you to have IPv6 Internet connectivity - it also works over IPv4.</font></p>\n" +
"<p class=\"western\"><font style=\"font-size: 14pt\" color=\"#ffffff\"><b>Credit</b></font></p>\n" +
"<p>\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\" >Developers: vikulin <a href=\"mailto:vadym.vikulin@gmail.com\">vadym.vikulin@gmail.com</a>, ChronosX88 <a href=\"mailto:chronosx88@gmail.com\">chronosx88@gmail.com</a></font></p>\n" +
"\n" +
"<p>\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\">QA: jorektheglitch <a href=\"mailto:entressi@yandex.ru\">entressi@yandex.ru</a>\n" +
"</font></p>\n" +
"\n" +
"<font class=\"western\" style=\"font-size: 14pt\" color=\"#ffffff\"><b>Is Yggdrasil safe?</b></font>\n" +
"<p>\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\">All traffic sent across the Yggdrasil network is encrypted end-to-end. Assuming that our crypto is solid, it cannot be decrypted or read by any intermediate nodes, and can only be decrypted by the recipient for which it was intended. However, please note that Yggdrasil has not been officially externally audited.\n" +
"</font></p>\n" +
"\n" +
"<font class=\"western\" style=\"font-size: 14pt\" color=\"#ffffff\"><b>Is Yggdrasil stable?</b></font>\n" +
"<p>\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\">Our official stance is that it is still alpha software. Expect things to not be wholly smooth, and expect to have to upgrade often to the latest builds. That said, there is a small community of users who have not experienced any stability problems so far. Yggdrasil very rarely crashes.\n" +
"</font></p>\n" +
"\n" +
"<font class=\"western\" style=\"font-size: 14pt\" color=\"#ffffff\"><b>Is Yggdrasil anonymous?</b></font>\n" +
"<p>\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\">It is not a goal of the Yggdrasil project to provide anonymity. Your direct peers may be able to determine your location if, for example, you are peering over the Internet.\n" +
"</font></p>\n" +
"\n" +
"<font class=\"western\" style=\"font-size: 14pt\" color=\"#ffffff\"><b>Does Yggdrasil work on my platform?</b></font>\n" +
"<p>\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\">Quite likely! Take a look at the <a href=\"https://yggdrasil-network.github.io/platforms.html\"><u>Platforms</u></a> page - youll find platform-specific notes there.\n" +
"</font></p>\n" +
"\n" +
"<font class=\"western\" style=\"font-size: 14pt\" color=\"#ffffff\"><b>Does Yggdrasil require IPv6?</b></font>\n" +
"<p>\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\">Your system must be IPv6-capable, which just about all modern operating systems are.\n" +
"While Yggdrasil does transport only IPv6 traffic internally, you do not need an IPv6 internet connection to peer with other Yggdrasil users. You can peer with other Yggdrasil nodes over either IPv4 or IPv6.\n" +
"</font>\n" +
"<p>\n" +
"<font class=\"western\" style=\"font-size: 14pt\" color=\"#ffffff\"><b>Will Yggdrasil conflict with my network routing?</b></font>\n" +
"<p>\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\">Yggdrasil uses the 0200::/7 range, which is a range deprecated by the IETF. It has been deprecated since 2004, pending changes to an RFC which simply never materialised 14 years later. It was decided to use this range instead of fc00::/7 (which is more typically allocated to private networks) in order to prevent conflicts with existing ULA ranges.\n" +
"As long as you are not using this deprecated address range on your network, you will not experience any routing conflicts.\n" +
"</font>\n" +
"<p>\n" +
"<font class=\"western\" style=\"font-size: 14pt\" color=\"#ffffff\"><b>Can the network be crawled?</b></font>\n" +
"<p>\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\">Currently it is possible to crawl the network to reveal the spanning tree relationships by querying nodes in the DHT. This is how <a href=\"http://51.15.204.214/\"><u>the network map</u></a> and popularity contest are generated today. However, it is considered a design weakness that this is even possible currently and will hopefully be fixed in the future.\n" +
"</font></p>\n" +
"\n" +
"<font class=\"western\" style=\"font-size: 14pt\" color=\"#ffffff\"><b>Can I run a crawler?</b></font>\n" +
"<p>\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\">Please dont run your own network crawler. Crawlers generate a lot of network-wide protocol traffic and effect is amplified by each additional crawler. If you really really really want information about the network today, use an <a href=\"http://[301:4541:2f84:1188:216:3eff:feb6:65a3]:3001/nodeinfo.json\"><u>existing data source within the network</u></a> instead of crawling yourself.\n" +
"</font></p>\n" +
"\n" +
"<font class=\"western\" style=\"font-size: 14pt\" color=\"#ffffff\"><b>Ive just installed Yggdrasil and I cant ping anyone. What have I missed?</b></font>\n" +
"<p>\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\">Yggdrasil requires that you configure either a static peer to another Yggdrasil node, or that you discover another Yggdrasil node on the same subnet using multicast discovery (which is enabled by default). If you have not added or discovered any peers, you will not be able to reach beyond your own node.\n" +
"You can check if you have any peers by running yggdrasilctl getPeers - peer on port 0 is your own node, ports 1 and above are your active peers.\n" +
"Stuck for peers? Try adding a <a href=\"https://github.com/yggdrasil-network/public-peers\"><u>public peer</u></a>.\n" +
"</font></p>\n" +
"\n" +
"<font class=\"western\" style=\"font-size: 14pt\" color=\"#ffffff\"><b>Ive installed the Yggdrasil Debian package and now I cant find the logs.</b></font>\n" +
"<p>\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\">The Debian package installs the Yggdrasil service into systemd, therefore you can query systemd for the logs:\n" +
"<p>\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\">\n" +
" systemctl status yggdrasil\n" +
"</font>\n" +
"<p>\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\">\n" +
" journalctl -u yggdrasil\n" +
"</font<\n" +
"</font></p>\n" +
"\n" +
"<font class=\"western\" style=\"font-size: 14pt\" color=\"#ffffff\"><b>Ive modified the configuration file but nothing has changed.</b></font>\n" +
"<p>\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\">Yggdrasil only loads the configuration at startup. Restart the Yggdrasil process or service to load the new configuration.\n" +
"</font></p>\n" +
"\n" +
"<font class=\"western\" style=\"font-size: 14pt\" color=\"#ffffff\"><b>Im running Yggdrasil on a machine that is directly reachable from the Internet. Does this mean anyone can peer with me?</b></font>\n" +
"<p>\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\">Without any further configuration, yes.\n" +
"However, you can either limit incoming connections to your host using a firewall by limiting or denying connections to the port specified in your Listen configuration option. This is useful if you want to limit peerings from certain IP ranges or on certain interfaces.\n" +
"<p>\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\">\n" +
"Alternatively, you can limit who can peer with you by modifying the AllowedEncryptionPublicKeys option in your Yggdrasil configuration. When this list is empty, any remote node is allowed to peer with you.\n" +
"</font>\n" +
"<p>\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\">\n" +
"To restrict incoming peerings to certain nodes, you should first ask the operators of those nodes for their EncryptionPublicKey and then add those public keys into your own AllowedEncryptionPublicKeys list. From that point forward, only nodes with those public keys will be allowed to peer with you.\n" +
"</font>\n" +
"</font></p>\n" +
"\n" +
"<font class=\"western\" style=\"font-size: 14pt\" color=\"#ffffff\"><b>I am running Yggdrasil from behind a NAT. Will this affect my connectivity?</b></font>\n" +
"<p>\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\">To accept incoming peerings, you will probably need to configure port forwarding on your router/gateway. Yggdrasil listens on the port number specified in the Listen setting, so forward this port to the machine that runs Yggdrasil.\n" +
"<p>\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\">\n" +
"To use outbound peerings, that is, static peers that have been configured in your Peers setting, you will likely not need to change anything.\n" +
"</font>\n" +
"</font></p>\n" +
"\n" +
"<font class=\"western\" style=\"font-size: 14pt\" color=\"#ffffff\"><b>Why does my Yggdrasil adapter have an unusually high MTU?</b></font>\n" +
"<p>\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\">Yggdrasil peerings are typically stream-based and therefore dont suffer from fragmentation issues when pushing large amounts of data. By using the largest possible MTU supported by a platform, we can send much more data in each write, and the TCP connection will take care of the rest. This also helps somewhat in the reduction of TCP-over-TCP amplification, as there are less control messages to be amplified.\n" +
"<p>\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\">\n" +
"This also uses less CPU, as we can send more data for every system call on the TUN/TAP adapter or network socket. System calls often result in context switches by the operating system and are expensive operations, therefore by using an MTU of up to 65535, we can save as many as 42 context switches for each packet - a substantial performance improvement!\n" +
"</font>\n" +
"</font></p>\n" +
"\n" +
"<font class=\"western\" style=\"font-size: 14pt\" color=\"#ffffff\"><b>Ive changed my AdminListen port and now yggdrasilctl doesnt work.</b></font>\n" +
"<p>\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\">yggdrasilctl will assume that your admin port is on localhost:9001. If you have changed it, simply pass your configured endpoint through to yggdrasilctl, i.e.\n" +
"<p>\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\">\n" +
"yggdrasilctl -endpoint=127.0.0.1:12345\n" +
"</font>\n" +
"</font></p>\n" +
"\n" +
"<font class=\"western\" style=\"font-size: 14pt\" color=\"#ffffff\"><b>I want to run an Yggdrasil router to provide connectivity for other people, but I dont want them to be able to reach my own machine.</b></font>\n" +
"<p>\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\">You can set the IfName configuration setting to \"none\". This will load Yggdrasil, but will not create a TUN/TAP adapter, meaning that your host will not be exposed to the Yggdrasil network. This does of course mean that you wont be able to send any traffic from that node to Yggdrasil either\n" +
"</font></p>\n" +
"\n" +
"<font class=\"western\" style=\"font-size: 14pt\" color=\"#ffffff\"><b>Does Yggdrasil work alongside an existing VPN?</b></font>\n" +
"<p>\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\">Yes, Yggdrasil should not interfere with existing VPNs. VPN traffic can be sent while using Yggdrasil.\n" +
"</font></p>\n" +
"\n" +
"<font class=\"western\" style=\"font-size: 14pt\" color=\"#ffffff\"><b>Does Yggdrasil work with networks like Tor or I2P?</b></font>\n" +
"<p>\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\">Yggdrasil can peer over Tor or I2P. See <a href=\"https://github.com/yggdrasil-network/public-peers/tree/master/other\"><u>/public-peers/tree/master/other</u></a> for public peers.\n" +
"</font></p>\n" +
"\n" +
"<font class=\"western\" style=\"font-size: 14pt\" color=\"#ffffff\"><b>I want to allow outgoing connections from my machine but prevent unwanted incoming connections.</b></font>\n" +
"<p>\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\">Generally this requires you to use a firewall. The steps for this will vary from platform to platform.\n" +
"</font></p>\n" +
"<font class=\"western\" style=\"font-size: 13pt\" color=\"#ffffff\"><b>Linux (with ip6tables)</b></font>\n" +
"<p>\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\">Assuming your TUN/TAP adapter is tun0:\n" +
"<p>\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\">\n" +
"ip6tables -A INPUT -i tun0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT\n" +
"</font>\n" +
"<p>\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\">\n" +
"ip6tables -A INPUT -i tun0 -m conntrack --ctstate INVALID -j DROP\n" +
"</font>\n" +
"<p>\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\">\n" +
"ip6tables -A INPUT -i tun0 -j DROP\n" +
"</font>\n" +
"</font></p>\n" +
"\n" +
"<font class=\"western\" style=\"font-size: 13pt\" color=\"#ffffff\"><b>Windows (with Windows Firewall)</b></font>\n" +
"\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\">Windows, by default, will classify the TAP adapter as a “Public Network”. Configure Windows Firewall to prevent incoming connections on Public networks.\n" +
"</font></p>\n" +
"\n" +
"<font class=\"western\" style=\"font-size: 13pt\" color=\"#ffffff\"><b>macOS (with built-in firewall)</b></font>\n" +
"\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\">macOS has an application firewall, therefore any firewall policies applied on other interfaces will also apply to the Yggdrasil interface.\n" +
"</font></p>\n" +
"\n" +
"<font class=\"western\" style=\"font-size: 14pt\" color=\"#ffffff\"><b>Is there any benefit to being the “root node” of the network?</b></font>\n" +
"<p>\n" +
"<font style=\"font-size: 10pt\" color=\"#ffffff\">No. At worst, the root node may be used in worst-case-scenario paths between other nodes in the absence of being able to determine better routes, but this is not advantageous.\n" +
"</font></p>\n" +
"</body>"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_about)
setSupportActionBar(findViewById(R.id.toolbar))
var textArea = this.findViewById<TextView>(R.id.about)
textArea.movementMethod = LinkMovementMethod.getInstance();
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
textArea.text = Html.fromHtml(about, HtmlCompat.FROM_HTML_MODE_LEGACY)
} else {
textArea.text = Html.fromHtml(about)
}
}
}

View File

@ -3,8 +3,6 @@ package io.github.chronosx88.yggdrasil
import android.app.Activity
import android.app.ActivityManager
import android.content.*
import android.net.ConnectivityManager
import android.net.Network
import android.net.VpnService
import android.os.Build
import android.os.Bundle
@ -13,12 +11,12 @@ import android.view.Gravity
import android.view.View
import android.widget.*
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.SwitchCompat
import androidx.preference.PreferenceManager
import dalvik.system.DexFile
import io.github.chronosx88.yggdrasil.models.DNSInfo
import io.github.chronosx88.yggdrasil.models.PeerInfo
import io.github.chronosx88.yggdrasil.models.config.DNSInfoListAdapter
import io.github.chronosx88.yggdrasil.models.config.NetworkUtils
import io.github.chronosx88.yggdrasil.models.config.PeerInfoListAdapter
import io.github.chronosx88.yggdrasil.models.config.Utils.Companion.deserializePeerStringList2PeerInfoSet
import io.github.chronosx88.yggdrasil.models.config.Utils.Companion.deserializeStringList2DNSInfoSet
@ -57,12 +55,16 @@ class MainActivity : AppCompatActivity() {
const val CURRENT_PEERS = "CURRENT_PEERS_v1.2.1"
const val CURRENT_DNS = "CURRENT_DNS_v1.2"
const val START_VPN = "START_VPN"
private const val TAG="Yggdrasil"
private const val TAG = "Yggdrasil"
private const val VPN_REQUEST_CODE = 0x0F
@JvmStatic var isStarted = false
@JvmStatic var isCancelled = false
@JvmStatic var address:String? = ""
@JvmStatic
var isStarted = false
@JvmStatic
var isCancelled = false
@JvmStatic
var address: String? = ""
}
private var currentPeers = setOf<PeerInfo>()
@ -74,7 +76,7 @@ class MainActivity : AppCompatActivity() {
setContentView(R.layout.activity_main)
setSupportActionBar(findViewById(R.id.toolbar))
isStarted = isYggServiceRunning(this)
val switchOn = findViewById<Switch>(R.id.switchOn)
val switchOn = findViewById<SwitchCompat>(R.id.switchOn)
switchOn.isChecked = isStarted
switchOn.setOnCheckedChangeListener { _, isChecked ->
@ -92,12 +94,17 @@ class MainActivity : AppCompatActivity() {
//save to shared preferences
val preferences =
PreferenceManager.getDefaultSharedPreferences(this.baseContext)
val staticIP = findViewById<Switch>(R.id.staticIP)
val staticIP = findViewById<SwitchCompat>(R.id.staticIP)
staticIP.isChecked =
preferences.getString(STATIC_IP, null) != null
val peersListView = findViewById<ListView>(R.id.peers)
currentPeers = deserializeStringSet2PeerInfoSet(preferences.getStringSet(CURRENT_PEERS, HashSet())!!)
currentPeers = deserializeStringSet2PeerInfoSet(
preferences.getStringSet(
CURRENT_PEERS,
HashSet()
)!!
)
val adapter = PeerInfoListAdapter(this, currentPeers.sortedWith(compareBy { it.ping }))
peersListView.adapter = adapter
if(isStarted && this.currentPeers.isEmpty()) {
@ -125,7 +132,12 @@ class MainActivity : AppCompatActivity() {
}
val listViewDNS = findViewById<ListView>(R.id.dns)
currentDNS = deserializeStringSet2DNSInfoSet(preferences.getStringSet(CURRENT_DNS, HashSet())!!)
currentDNS = deserializeStringSet2DNSInfoSet(
preferences.getStringSet(
CURRENT_DNS,
HashSet()
)!!
)
val adapterDns = DNSInfoListAdapter(this, currentDNS.sortedWith(compareBy { it.ping }))
listViewDNS.adapter = adapterDns
val editDnsButton = findViewById<Button>(R.id.editDNS)
@ -193,10 +205,16 @@ class MainActivity : AppCompatActivity() {
val cl = classLoader
val c: Class<*> = dexFile.loadClass("dummy/Dummy", cl)
}
val versionName = findViewById<Button>(R.id.about)
versionName.text = """version:${BuildConfig.VERSION_NAME} build:${BuildConfig.VERSION_CODE}"""
versionName.setOnClickListener {
val intent = Intent(this@MainActivity, AboutActivity::class.java)
startActivity(intent)
}
}
private fun stopVpn(){
Log.i(TAG,"Stop")
Log.i(TAG, "Stop")
val intent = Intent(this, YggdrasilTunService::class.java)
val TASK_CODE = 100
val pi = createPendingResult(TASK_CODE, intent, 0)
@ -206,7 +224,7 @@ class MainActivity : AppCompatActivity() {
}
private fun startVpn(){
Log.i(TAG,"Start")
Log.i(TAG, "Start")
val intent= VpnService.prepare(this)
if (intent!=null){
startActivityForResult(intent, VPN_REQUEST_CODE)
@ -216,7 +234,7 @@ class MainActivity : AppCompatActivity() {
}
private fun updateDNS(){
Log.i(TAG,"Update DNS")
Log.i(TAG, "Update DNS")
val intent = Intent(this, YggdrasilTunService::class.java)
val TASK_CODE = 100
val pi = createPendingResult(TASK_CODE, intent, 0)
@ -227,7 +245,7 @@ class MainActivity : AppCompatActivity() {
}
private fun updatePeers(){
Log.d(TAG,"Update Peers")
Log.d(TAG, "Update Peers")
val intent = Intent(this, YggdrasilTunService::class.java)
val TASK_CODE = 100
val pi = createPendingResult(TASK_CODE, intent, 0)
@ -258,9 +276,13 @@ class MainActivity : AppCompatActivity() {
val pi = createPendingResult(TASK_CODE, intent, 0)
intent.putExtra(PARAM_PINTENT, pi)
intent.putExtra(COMMAND, START)
intent.putStringArrayListExtra(CURRENT_PEERS, serializePeerInfoSet2StringList(currentPeers))
intent.putStringArrayListExtra(
CURRENT_PEERS, serializePeerInfoSet2StringList(
currentPeers
)
)
intent.putStringArrayListExtra(CURRENT_DNS, serializeDNSInfoSet2StringList(currentDNS))
intent.putExtra(STATIC_IP, findViewById<Switch>(R.id.staticIP).isChecked)
intent.putExtra(STATIC_IP, findViewById<SwitchCompat>(R.id.staticIP).isChecked)
startService(intent)
}
@ -272,7 +294,10 @@ class MainActivity : AppCompatActivity() {
var currentPeers = data.extras!!.getStringArrayList(PEER_LIST)
/*WiFi Direct test. need peer empty list*/
this.currentPeers = deserializeStringList2PeerInfoSet(currentPeers)
val adapter = PeerInfoListAdapter(this, this.currentPeers.sortedWith(compareBy { it.ping }))
val adapter = PeerInfoListAdapter(
this,
this.currentPeers.sortedWith(compareBy { it.ping })
)
val listView = findViewById<ListView>(R.id.peers)
listView.adapter = adapter
@ -297,7 +322,10 @@ class MainActivity : AppCompatActivity() {
if(data!!.extras!=null){
var currentDNS = data.extras!!.getStringArrayList(DNS_LIST)
this.currentDNS = deserializeStringList2DNSInfoSet(currentDNS)
val adapter = DNSInfoListAdapter(this, this.currentDNS.sortedWith(compareBy { it.ping }))
val adapter = DNSInfoListAdapter(
this,
this.currentDNS.sortedWith(compareBy { it.ping })
)
val listView = findViewById<ListView>(R.id.dns)
listView.adapter = adapter
//save to shared preferences
@ -313,7 +341,7 @@ class MainActivity : AppCompatActivity() {
when (resultCode) {
STATUS_START -> {
print("service started")
if(this.currentPeers.isEmpty()){
if (this.currentPeers.isEmpty()) {
checkPeers()
}
}
@ -329,8 +357,8 @@ class MainActivity : AppCompatActivity() {
val ipLayout = findViewById<LinearLayout>(R.id.ipLayout)
ipLayout.visibility = View.GONE
}
STATUS_PEERS_UPDATE ->{
if(data!!.extras!=null) {
STATUS_PEERS_UPDATE -> {
if (data!!.extras != null) {
thread(start = true) {
val meshPeers = deserializePeerStringList2PeerInfoSet(
data.extras!!.getStringArrayList(MESH_PEERS)
@ -338,7 +366,8 @@ class MainActivity : AppCompatActivity() {
val listView = findViewById<ListView>(R.id.peers)
val adapter = PeerInfoListAdapter(
this@MainActivity,
meshPeers.filter { it.schema!="self" }.sortedWith(compareBy { it.ping })
meshPeers.filter { it.schema != "self" }
.sortedWith(compareBy { it.ping })
)
runOnUiThread {
listView.adapter = adapter

View File

@ -241,18 +241,6 @@ class PeerListActivity : AppCompatActivity() {
val result = Intent(this, MainActivity::class.java)
var adapter = findViewById<ListView>(R.id.peerList).adapter as SelectPeerInfoListAdapter
val selectedPeers = adapter.getSelectedPeers()
/* WiFi Direct test - no peers is needed
if(selectedPeers.size>0) {
result.putExtra(MainActivity.PEER_LIST, serializePeerInfoSet2StringList(selectedPeers))
setResult(Activity.RESULT_OK, result)
finish()
} else {
val text = "Select at least one peer"
val duration = Toast.LENGTH_SHORT
val toast = Toast.makeText(applicationContext, text, duration)
toast.setGravity(Gravity.CENTER, 0, 0)
toast.show()
}*/
result.putExtra(MainActivity.PEER_LIST, serializePeerInfoSet2StringList(selectedPeers))
setResult(Activity.RESULT_OK, result)
finish()

View File

@ -27,6 +27,7 @@ import mobile.Mobile
import mobile.Yggdrasil
import java.io.*
import java.net.Inet6Address
import kotlin.concurrent.thread
class YggdrasilTunService : VpnService() {
@ -44,8 +45,6 @@ class YggdrasilTunService : VpnService() {
private const val TAG = "Yggdrasil-service"
}
private var scope: CoroutineScope? = null
private val FOREGROUND_ID = 1338
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
@ -124,15 +123,13 @@ class YggdrasilTunService : VpnService() {
setupIOStreams(dns)
val job = SupervisorJob()
scope = CoroutineScope(Dispatchers.Default + job)
scope!!.launch {
thread(start = true) {
val buffer = ByteArray(MAX_PACKET_SIZE)
while (!isClosed) {
readPacketsFromTun(yggConduitEndpoint, buffer)
}
}
scope!!.launch {
thread(start = true) {
while (!isClosed) {
writePacketsToTun(yggConduitEndpoint)
}
@ -234,7 +231,6 @@ class YggdrasilTunService : VpnService() {
private fun stopVpn(pi: PendingIntent?) {
isClosed = true;
scope!!.coroutineContext.cancelChildren()
tunInputStream.close()
tunOutputStream.close()
tunInterface!!.close()

View File

@ -57,7 +57,6 @@ class SelectPeerInfoListAdapter(
peerInfoHolder.peerInfoText.setTextColor(Color.WHITE)
}
peerInfoHolder.checkbox.setOnCheckedChangeListener { _, isChecked ->
if(!isLoading) {
if (isChecked) {
if (!currentPeers.contains(currentPeer)) {
currentPeers.add(currentPeer)
@ -68,7 +67,6 @@ class SelectPeerInfoListAdapter(
}
}
}
}
peerInfoHolder.checkbox.isChecked = this.currentPeers.contains(currentPeer)
return listItem!!
}

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".AboutActivity"
android:background="@color/grey">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<include layout="@layout/content_about" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -30,7 +30,7 @@
app:popupTheme="@style/AppTheme.PopupOverlay"
android:layout_marginRight="240dp" />
<Switch
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/staticIP"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -42,7 +42,7 @@
android:text="Static IP"
android:textColor="@color/white"/>
<Switch
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/switchOn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@color/grey"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/about"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="20dp">
</TextView>
</LinearLayout>
</ScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -152,5 +152,12 @@
app:layout_constraintTop_toTopOf="parent"/>
</LinearLayout>
<Button
android:id="@+id/about"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
app:layout_constraintBottom_toBottomOf="parent"
android:text=""
android:textSize="10sp" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -2,6 +2,6 @@
<resources>
<style name="SwitchTheme" parent="Theme.AppCompat.Light">
<item name="android:colorControlActivated">@color/green</item>
<item name="colorControlActivated">@color/green</item>
</style>
</resources>

View File

@ -7,4 +7,5 @@
<string name="title_activity_dns_list">Edit DNS</string>
<string name="address_copied">Address copied</string>
<string name="schema">Schema</string>
<string name="title_activity_about">Yggdrasil</string>
</resources>

View File

@ -8,7 +8,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.0.1'
classpath 'com.android.tools.build:gradle:4.1.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files

View File

@ -1,6 +1,6 @@
#Tue Jun 09 01:07:00 PDT 2020
#Wed Oct 14 16:00:08 EEST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip