mirror of
https://github.com/yggdrasil-network/crispa-android.git
synced 2025-01-22 16:06:30 +00:00
1. added peers update in Mesh mode
This commit is contained in:
parent
e597fff59b
commit
bca4b88d3d
@ -2,10 +2,7 @@ package io.github.chronosx88.yggdrasil
|
|||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.app.ActivityManager
|
import android.app.ActivityManager
|
||||||
import android.content.ClipData
|
import android.content.*
|
||||||
import android.content.ClipboardManager
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
|
||||||
import android.net.VpnService
|
import android.net.VpnService
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
@ -18,17 +15,26 @@ import io.github.chronosx88.yggdrasil.models.DNSInfo
|
|||||||
import io.github.chronosx88.yggdrasil.models.PeerInfo
|
import io.github.chronosx88.yggdrasil.models.PeerInfo
|
||||||
import io.github.chronosx88.yggdrasil.models.config.DNSInfoListAdapter
|
import io.github.chronosx88.yggdrasil.models.config.DNSInfoListAdapter
|
||||||
import io.github.chronosx88.yggdrasil.models.config.PeerInfoListAdapter
|
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
|
import io.github.chronosx88.yggdrasil.models.config.Utils.Companion.deserializeStringList2DNSInfoSet
|
||||||
import io.github.chronosx88.yggdrasil.models.config.Utils.Companion.deserializeStringList2PeerInfoSet
|
import io.github.chronosx88.yggdrasil.models.config.Utils.Companion.deserializeStringList2PeerInfoSet
|
||||||
import io.github.chronosx88.yggdrasil.models.config.Utils.Companion.deserializeStringSet2DNSInfoSet
|
import io.github.chronosx88.yggdrasil.models.config.Utils.Companion.deserializeStringSet2DNSInfoSet
|
||||||
import io.github.chronosx88.yggdrasil.models.config.Utils.Companion.deserializeStringSet2PeerInfoSet
|
import io.github.chronosx88.yggdrasil.models.config.Utils.Companion.deserializeStringSet2PeerInfoSet
|
||||||
import io.github.chronosx88.yggdrasil.models.config.Utils.Companion.serializeDNSInfoSet2StringList
|
import io.github.chronosx88.yggdrasil.models.config.Utils.Companion.serializeDNSInfoSet2StringList
|
||||||
import io.github.chronosx88.yggdrasil.models.config.Utils.Companion.serializePeerInfoSet2StringList
|
import io.github.chronosx88.yggdrasil.models.config.Utils.Companion.serializePeerInfoSet2StringList
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.GlobalScope
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import java.net.InetAddress
|
||||||
|
import kotlin.concurrent.thread
|
||||||
|
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity() {
|
class MainActivity : AppCompatActivity() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
const val STATUS_PEERS_UPDATE = 12
|
||||||
|
const val MESH_PEERS = "MESH_PEERS"
|
||||||
const val STATIC_IP = "STATIC_IP_FLAG"
|
const val STATIC_IP = "STATIC_IP_FLAG"
|
||||||
const val signingPrivateKey = "signingPrivateKey"
|
const val signingPrivateKey = "signingPrivateKey"
|
||||||
const val signingPublicKey = "signingPublicKey"
|
const val signingPublicKey = "signingPublicKey"
|
||||||
@ -38,6 +44,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
const val STOP = "STOP"
|
const val STOP = "STOP"
|
||||||
const val START = "START"
|
const val START = "START"
|
||||||
const val UPDATE_DNS = "UPDATE_DNS"
|
const val UPDATE_DNS = "UPDATE_DNS"
|
||||||
|
const val UPDATE_PEERS = "UPDATE_PEERS"
|
||||||
const val PARAM_PINTENT = "pendingIntent"
|
const val PARAM_PINTENT = "pendingIntent"
|
||||||
const val STATUS_START = 7
|
const val STATUS_START = 7
|
||||||
const val STATUS_FINISH = 8
|
const val STATUS_FINISH = 8
|
||||||
@ -49,7 +56,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
const val DNS_LIST_CODE = 2000
|
const val DNS_LIST_CODE = 2000
|
||||||
const val PEER_LIST = "PEERS_LIST"
|
const val PEER_LIST = "PEERS_LIST"
|
||||||
const val DNS_LIST = "DNS_LIST"
|
const val DNS_LIST = "DNS_LIST"
|
||||||
const val CURRENT_PEERS = "CURRENT_PEERS_v1.2"
|
const val CURRENT_PEERS = "CURRENT_PEERS_v1.2.1"
|
||||||
const val CURRENT_DNS = "CURRENT_DNS_v1.2"
|
const val CURRENT_DNS = "CURRENT_DNS_v1.2"
|
||||||
const val START_VPN = "START_VPN"
|
const val START_VPN = "START_VPN"
|
||||||
private const val TAG="Yggdrasil"
|
private const val TAG="Yggdrasil"
|
||||||
@ -62,6 +69,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
private var currentPeers = setOf<PeerInfo>()
|
private var currentPeers = setOf<PeerInfo>()
|
||||||
private var currentDNS = setOf<DNSInfo>()
|
private var currentDNS = setOf<DNSInfo>()
|
||||||
|
private var meshPeersReceiver: BroadcastReceiver? = null
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@ -169,6 +177,16 @@ class MainActivity : AppCompatActivity() {
|
|||||||
startService(intent)
|
startService(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun updatePeers(){
|
||||||
|
Log.d(TAG,"Update Peers")
|
||||||
|
val intent = Intent(this, YggdrasilTunService::class.java)
|
||||||
|
val TASK_CODE = 100
|
||||||
|
val pi = createPendingResult(TASK_CODE, intent, 0)
|
||||||
|
intent.putExtra(PARAM_PINTENT, pi)
|
||||||
|
intent.putExtra(COMMAND, UPDATE_PEERS)
|
||||||
|
startService(intent)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
super.onActivityResult(requestCode, resultCode, data)
|
super.onActivityResult(requestCode, resultCode, data)
|
||||||
|
|
||||||
@ -244,7 +262,20 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
when (resultCode) {
|
when (resultCode) {
|
||||||
STATUS_START -> print("service started")
|
STATUS_START -> {
|
||||||
|
print("service started")
|
||||||
|
if(this.currentPeers.isEmpty()){
|
||||||
|
//this is Mesh mode, send Peers update every 5 sec
|
||||||
|
thread(start = true) {
|
||||||
|
while(true) {
|
||||||
|
Thread.sleep(5000)
|
||||||
|
if(isStarted) {
|
||||||
|
updatePeers()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
STATUS_FINISH -> {
|
STATUS_FINISH -> {
|
||||||
isStarted = true
|
isStarted = true
|
||||||
val ipLayout = findViewById<LinearLayout>(R.id.ipLayout)
|
val ipLayout = findViewById<LinearLayout>(R.id.ipLayout)
|
||||||
@ -257,6 +288,23 @@ class MainActivity : AppCompatActivity() {
|
|||||||
val ipLayout = findViewById<LinearLayout>(R.id.ipLayout)
|
val ipLayout = findViewById<LinearLayout>(R.id.ipLayout)
|
||||||
ipLayout.visibility = View.GONE
|
ipLayout.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
STATUS_PEERS_UPDATE ->{
|
||||||
|
if(data!!.extras!=null) {
|
||||||
|
thread(start = true) {
|
||||||
|
val meshPeers = deserializePeerStringList2PeerInfoSet(
|
||||||
|
data.extras!!.getStringArrayList(MESH_PEERS)
|
||||||
|
)
|
||||||
|
val listView = findViewById<ListView>(R.id.peers)
|
||||||
|
val adapter = PeerInfoListAdapter(
|
||||||
|
this@MainActivity,
|
||||||
|
meshPeers.sortedWith(compareBy { it.ping })
|
||||||
|
)
|
||||||
|
runOnUiThread {
|
||||||
|
listView.adapter = adapter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else -> { // Note the block
|
else -> { // Note the block
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -290,4 +338,11 @@ class MainActivity : AppCompatActivity() {
|
|||||||
preferences.getString(STATIC_IP, null) != null
|
preferences.getString(STATIC_IP, null) != null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
super.onDestroy()
|
||||||
|
if (meshPeersReceiver != null){
|
||||||
|
unregisterReceiver(meshPeersReceiver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,12 @@ import androidx.annotation.RequiresApi
|
|||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
|
import com.google.gson.reflect.TypeToken
|
||||||
import dummy.ConduitEndpoint
|
import dummy.ConduitEndpoint
|
||||||
import io.github.chronosx88.yggdrasil.models.DNSInfo
|
import io.github.chronosx88.yggdrasil.models.DNSInfo
|
||||||
import io.github.chronosx88.yggdrasil.models.PeerInfo
|
import io.github.chronosx88.yggdrasil.models.PeerInfo
|
||||||
|
import io.github.chronosx88.yggdrasil.models.config.Peer
|
||||||
|
import io.github.chronosx88.yggdrasil.models.config.Utils.Companion.convertPeer2PeerStringList
|
||||||
import io.github.chronosx88.yggdrasil.models.config.Utils.Companion.convertPeerInfoSet2PeerIdSet
|
import io.github.chronosx88.yggdrasil.models.config.Utils.Companion.convertPeerInfoSet2PeerIdSet
|
||||||
import io.github.chronosx88.yggdrasil.models.config.Utils.Companion.deserializeStringList2DNSInfoSet
|
import io.github.chronosx88.yggdrasil.models.config.Utils.Companion.deserializeStringList2DNSInfoSet
|
||||||
import io.github.chronosx88.yggdrasil.models.config.Utils.Companion.deserializeStringList2PeerInfoSet
|
import io.github.chronosx88.yggdrasil.models.config.Utils.Companion.deserializeStringList2PeerInfoSet
|
||||||
@ -27,6 +30,7 @@ import mobile.Mobile
|
|||||||
import mobile.Yggdrasil
|
import mobile.Yggdrasil
|
||||||
import java.io.*
|
import java.io.*
|
||||||
import java.net.Inet6Address
|
import java.net.Inet6Address
|
||||||
|
import kotlin.concurrent.thread
|
||||||
|
|
||||||
|
|
||||||
class YggdrasilTunService : VpnService() {
|
class YggdrasilTunService : VpnService() {
|
||||||
@ -56,10 +60,9 @@ class YggdrasilTunService : VpnService() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||||
|
val pi: PendingIntent? = intent?.getParcelableExtra(MainActivity.PARAM_PINTENT)
|
||||||
when(intent?.getStringExtra(MainActivity.COMMAND)){
|
when(intent?.getStringExtra(MainActivity.COMMAND)){
|
||||||
MainActivity.STOP ->{
|
MainActivity.STOP ->{
|
||||||
val pi: PendingIntent? = intent.getParcelableExtra(MainActivity.PARAM_PINTENT)
|
|
||||||
stopVpn(pi)
|
stopVpn(pi)
|
||||||
startForeground(FOREGROUND_ID, foregroundNotification("Yggdrasil service stopped"))
|
startForeground(FOREGROUND_ID, foregroundNotification("Yggdrasil service stopped"))
|
||||||
}
|
}
|
||||||
@ -67,7 +70,6 @@ class YggdrasilTunService : VpnService() {
|
|||||||
val peers = deserializeStringList2PeerInfoSet(intent.getStringArrayListExtra(MainActivity.PEERS))
|
val peers = deserializeStringList2PeerInfoSet(intent.getStringArrayListExtra(MainActivity.PEERS))
|
||||||
val dns = deserializeStringList2DNSInfoSet(intent.getStringArrayListExtra(MainActivity.DNS))
|
val dns = deserializeStringList2DNSInfoSet(intent.getStringArrayListExtra(MainActivity.DNS))
|
||||||
val staticIP: Boolean = intent.getBooleanExtra(MainActivity.STATIC_IP, false)
|
val staticIP: Boolean = intent.getBooleanExtra(MainActivity.STATIC_IP, false)
|
||||||
val pi: PendingIntent = intent.getParcelableExtra(MainActivity.PARAM_PINTENT)
|
|
||||||
ygg = Yggdrasil()
|
ygg = Yggdrasil()
|
||||||
setupTunInterface(pi, peers, dns, staticIP)
|
setupTunInterface(pi, peers, dns, staticIP)
|
||||||
startForeground(FOREGROUND_ID, foregroundNotification("Yggdrasil service started"))
|
startForeground(FOREGROUND_ID, foregroundNotification("Yggdrasil service started"))
|
||||||
@ -76,6 +78,9 @@ class YggdrasilTunService : VpnService() {
|
|||||||
val dns = deserializeStringList2DNSInfoSet(intent.getStringArrayListExtra(MainActivity.DNS))
|
val dns = deserializeStringList2DNSInfoSet(intent.getStringArrayListExtra(MainActivity.DNS))
|
||||||
setupIOStreams(dns)
|
setupIOStreams(dns)
|
||||||
}
|
}
|
||||||
|
MainActivity.UPDATE_PEERS ->{
|
||||||
|
sendMeshPeerStatus(pi)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return START_NOT_STICKY
|
return START_NOT_STICKY
|
||||||
@ -141,11 +146,22 @@ class YggdrasilTunService : VpnService() {
|
|||||||
writePacketsToTun(yggConduitEndpoint)
|
writePacketsToTun(yggConduitEndpoint)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val intent: Intent = Intent().putExtra(MainActivity.IPv6, address)
|
val intent: Intent = Intent().putExtra(MainActivity.IPv6, address)
|
||||||
pi.send(this, MainActivity.STATUS_FINISH, intent)
|
pi.send(this, MainActivity.STATUS_FINISH, intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun sendMeshPeerStatus(pi: PendingIntent?){
|
||||||
|
class Token : TypeToken<List<Peer>>()
|
||||||
|
var add = ygg.addressString
|
||||||
|
var meshPeers: List<Peer> = gson.fromJson(ygg.peersJSON, Token().type)
|
||||||
|
val intent: Intent = Intent().putStringArrayListExtra(
|
||||||
|
MainActivity.MESH_PEERS,
|
||||||
|
convertPeer2PeerStringList(meshPeers)
|
||||||
|
);
|
||||||
|
pi?.send(this, MainActivity.STATUS_PEERS_UPDATE, intent)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private fun fixConfig(
|
private fun fixConfig(
|
||||||
config: MutableMap<Any?, Any?>,
|
config: MutableMap<Any?, Any?>,
|
||||||
peers: Set<PeerInfo>,
|
peers: Set<PeerInfo>,
|
||||||
@ -231,7 +247,6 @@ class YggdrasilTunService : VpnService() {
|
|||||||
|
|
||||||
private fun stopVpn(pi: PendingIntent?) {
|
private fun stopVpn(pi: PendingIntent?) {
|
||||||
isClosed = true;
|
isClosed = true;
|
||||||
|
|
||||||
tunInputStream!!.close()
|
tunInputStream!!.close()
|
||||||
tunOutputStream!!.close()
|
tunOutputStream!!.close()
|
||||||
tunInterface!!.close()
|
tunInterface!!.close()
|
||||||
|
@ -19,12 +19,28 @@ class PeerInfo {
|
|||||||
this.port = port
|
this.port = port
|
||||||
this.countryCode = countryCode
|
this.countryCode = countryCode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constructor(schema: String, address: InetAddress, port: Int, countryCode: String?, isMeshPeer: Boolean){
|
||||||
|
this.schema = schema
|
||||||
|
this.address = address
|
||||||
|
var a = address.toString();
|
||||||
|
if(a.lastIndexOf('/')>0){
|
||||||
|
this.hostName = a.split("/")[0]
|
||||||
|
} else {
|
||||||
|
this.hostName = a.substring(1)
|
||||||
|
}
|
||||||
|
this.port = port
|
||||||
|
this.countryCode = countryCode
|
||||||
|
this.isMeshPeer = isMeshPeer
|
||||||
|
}
|
||||||
|
|
||||||
var schema: String
|
var schema: String
|
||||||
var address: InetAddress
|
var address: InetAddress
|
||||||
var hostName: String
|
var hostName: String
|
||||||
var port = 0
|
var port = 0
|
||||||
var countryCode: String
|
var countryCode: String?=null
|
||||||
var ping: Int = Int.MAX_VALUE
|
var ping: Int = Int.MAX_VALUE
|
||||||
|
var isMeshPeer = false
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
if(this.hostName.contains(":")) {
|
if(this.hostName.contains(":")) {
|
||||||
@ -39,7 +55,14 @@ class PeerInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getCountry(context: Context): CCPCountry? {
|
fun getCountry(context: Context): CCPCountry? {
|
||||||
return CCPCountry.getCountryForNameCodeFromLibraryMasterList(context, CountryCodePicker.Language.ENGLISH, countryCode)
|
if(countryCode==null){
|
||||||
|
return null
|
||||||
|
} else {
|
||||||
|
return CCPCountry.getCountryForNameCodeFromLibraryMasterList(
|
||||||
|
context,
|
||||||
|
CountryCodePicker.Language.ENGLISH,
|
||||||
|
countryCode
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package io.github.chronosx88.yggdrasil.models.config
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName
|
||||||
|
|
||||||
|
data class Peer (
|
||||||
|
//Example [{"PublicKey":[154,201,118,156,19,74,134,115,94,159,76,86,36,192,221,105,220,254,226,161,108,226,17,192,75,243,225,15,42,195,155,2],"Endpoint":"(self)","BytesSent":0,"BytesRecvd":0,"Protocol":"self","Port":0,"Uptime":209900460}]
|
||||||
|
@SerializedName("Endpoint") var endpoint : String,
|
||||||
|
@SerializedName("Port") var port : Int,
|
||||||
|
@SerializedName("Uptime") var uptime : Long,
|
||||||
|
@SerializedName("Protocol") var protocol : String,
|
||||||
|
@SerializedName("BytesSent") var bytesSent : Long,
|
||||||
|
@SerializedName("BytesRecvd") var bytesReceived : Long
|
||||||
|
)
|
@ -31,7 +31,11 @@ class PeerInfoListAdapter(
|
|||||||
peerInfoHolder = listItem.tag as PeerInfoHolder
|
peerInfoHolder = listItem.tag as PeerInfoHolder
|
||||||
}
|
}
|
||||||
val currentPeer = allPeers[position]
|
val currentPeer = allPeers[position]
|
||||||
|
if(currentPeer.isMeshPeer){
|
||||||
|
//TODO set mesh icon
|
||||||
|
} else {
|
||||||
peerInfoHolder.countryFlag.setImageResource(currentPeer.getCountry(mContext)!!.flagID)
|
peerInfoHolder.countryFlag.setImageResource(currentPeer.getCountry(mContext)!!.flagID)
|
||||||
|
}
|
||||||
peerInfoHolder.peerInfoText.text = currentPeer.toString()
|
peerInfoHolder.peerInfoText.text = currentPeer.toString()
|
||||||
return listItem!!
|
return listItem!!
|
||||||
}
|
}
|
||||||
|
@ -99,5 +99,39 @@ class Utils {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun convertPeer2PeerStringList(list: List<Peer>): ArrayList<String> {
|
||||||
|
var out = ArrayList<String>()
|
||||||
|
var gson = Gson()
|
||||||
|
for(p in list) {
|
||||||
|
out.add(gson.toJson(p))
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun deserializePeerStringList2PeerInfoSet(list: List<String>?): MutableSet<PeerInfo> {
|
||||||
|
var gson = Gson()
|
||||||
|
var out = mutableSetOf<PeerInfo>()
|
||||||
|
if (list != null) {
|
||||||
|
for(s in list) {
|
||||||
|
var p = gson.fromJson(s, Peer::class.java)
|
||||||
|
if(p.endpoint == "(self)"){
|
||||||
|
out.add(PeerInfo(p.protocol, InetAddress.getByName("localhost"), p.port, null, true))
|
||||||
|
} else {
|
||||||
|
out.add(
|
||||||
|
PeerInfo(
|
||||||
|
p.protocol,
|
||||||
|
InetAddress.getByName(p.endpoint),
|
||||||
|
p.port,
|
||||||
|
null,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user