mirror of
https://github.com/yggdrasil-network/crispa-android.git
synced 2025-01-22 07:56: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.ActivityManager
|
||||
import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.*
|
||||
import android.net.VpnService
|
||||
import android.os.Bundle
|
||||
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.config.DNSInfoListAdapter
|
||||
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.deserializeStringList2PeerInfoSet
|
||||
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.serializeDNSInfoSet2StringList
|
||||
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() {
|
||||
|
||||
companion object {
|
||||
const val STATUS_PEERS_UPDATE = 12
|
||||
const val MESH_PEERS = "MESH_PEERS"
|
||||
const val STATIC_IP = "STATIC_IP_FLAG"
|
||||
const val signingPrivateKey = "signingPrivateKey"
|
||||
const val signingPublicKey = "signingPublicKey"
|
||||
@ -38,6 +44,7 @@ class MainActivity : AppCompatActivity() {
|
||||
const val STOP = "STOP"
|
||||
const val START = "START"
|
||||
const val UPDATE_DNS = "UPDATE_DNS"
|
||||
const val UPDATE_PEERS = "UPDATE_PEERS"
|
||||
const val PARAM_PINTENT = "pendingIntent"
|
||||
const val STATUS_START = 7
|
||||
const val STATUS_FINISH = 8
|
||||
@ -49,7 +56,7 @@ class MainActivity : AppCompatActivity() {
|
||||
const val DNS_LIST_CODE = 2000
|
||||
const val PEER_LIST = "PEERS_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 START_VPN = "START_VPN"
|
||||
private const val TAG="Yggdrasil"
|
||||
@ -62,6 +69,7 @@ class MainActivity : AppCompatActivity() {
|
||||
|
||||
private var currentPeers = setOf<PeerInfo>()
|
||||
private var currentDNS = setOf<DNSInfo>()
|
||||
private var meshPeersReceiver: BroadcastReceiver? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
@ -169,6 +177,16 @@ class MainActivity : AppCompatActivity() {
|
||||
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?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
|
||||
@ -244,7 +262,20 @@ class MainActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
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 -> {
|
||||
isStarted = true
|
||||
val ipLayout = findViewById<LinearLayout>(R.id.ipLayout)
|
||||
@ -257,6 +288,23 @@ class MainActivity : AppCompatActivity() {
|
||||
val ipLayout = findViewById<LinearLayout>(R.id.ipLayout)
|
||||
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
|
||||
|
||||
}
|
||||
@ -290,4 +338,11 @@ class MainActivity : AppCompatActivity() {
|
||||
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.preference.PreferenceManager
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import dummy.ConduitEndpoint
|
||||
import io.github.chronosx88.yggdrasil.models.DNSInfo
|
||||
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.deserializeStringList2DNSInfoSet
|
||||
import io.github.chronosx88.yggdrasil.models.config.Utils.Companion.deserializeStringList2PeerInfoSet
|
||||
@ -27,6 +30,7 @@ import mobile.Mobile
|
||||
import mobile.Yggdrasil
|
||||
import java.io.*
|
||||
import java.net.Inet6Address
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
|
||||
class YggdrasilTunService : VpnService() {
|
||||
@ -56,10 +60,9 @@ class YggdrasilTunService : VpnService() {
|
||||
}
|
||||
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
|
||||
val pi: PendingIntent? = intent?.getParcelableExtra(MainActivity.PARAM_PINTENT)
|
||||
when(intent?.getStringExtra(MainActivity.COMMAND)){
|
||||
MainActivity.STOP ->{
|
||||
val pi: PendingIntent? = intent.getParcelableExtra(MainActivity.PARAM_PINTENT)
|
||||
stopVpn(pi)
|
||||
startForeground(FOREGROUND_ID, foregroundNotification("Yggdrasil service stopped"))
|
||||
}
|
||||
@ -67,7 +70,6 @@ class YggdrasilTunService : VpnService() {
|
||||
val peers = deserializeStringList2PeerInfoSet(intent.getStringArrayListExtra(MainActivity.PEERS))
|
||||
val dns = deserializeStringList2DNSInfoSet(intent.getStringArrayListExtra(MainActivity.DNS))
|
||||
val staticIP: Boolean = intent.getBooleanExtra(MainActivity.STATIC_IP, false)
|
||||
val pi: PendingIntent = intent.getParcelableExtra(MainActivity.PARAM_PINTENT)
|
||||
ygg = Yggdrasil()
|
||||
setupTunInterface(pi, peers, dns, staticIP)
|
||||
startForeground(FOREGROUND_ID, foregroundNotification("Yggdrasil service started"))
|
||||
@ -76,6 +78,9 @@ class YggdrasilTunService : VpnService() {
|
||||
val dns = deserializeStringList2DNSInfoSet(intent.getStringArrayListExtra(MainActivity.DNS))
|
||||
setupIOStreams(dns)
|
||||
}
|
||||
MainActivity.UPDATE_PEERS ->{
|
||||
sendMeshPeerStatus(pi)
|
||||
}
|
||||
}
|
||||
|
||||
return START_NOT_STICKY
|
||||
@ -141,11 +146,22 @@ class YggdrasilTunService : VpnService() {
|
||||
writePacketsToTun(yggConduitEndpoint)
|
||||
}
|
||||
}
|
||||
|
||||
val intent: Intent = Intent().putExtra(MainActivity.IPv6, address)
|
||||
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(
|
||||
config: MutableMap<Any?, Any?>,
|
||||
peers: Set<PeerInfo>,
|
||||
@ -231,7 +247,6 @@ class YggdrasilTunService : VpnService() {
|
||||
|
||||
private fun stopVpn(pi: PendingIntent?) {
|
||||
isClosed = true;
|
||||
|
||||
tunInputStream!!.close()
|
||||
tunOutputStream!!.close()
|
||||
tunInterface!!.close()
|
||||
|
@ -19,12 +19,28 @@ class PeerInfo {
|
||||
this.port = port
|
||||
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 address: InetAddress
|
||||
var hostName: String
|
||||
var port = 0
|
||||
var countryCode: String
|
||||
var countryCode: String?=null
|
||||
var ping: Int = Int.MAX_VALUE
|
||||
var isMeshPeer = false
|
||||
|
||||
override fun toString(): String {
|
||||
if(this.hostName.contains(":")) {
|
||||
@ -39,7 +55,14 @@ class PeerInfo {
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
val currentPeer = allPeers[position]
|
||||
peerInfoHolder.countryFlag.setImageResource(currentPeer.getCountry(mContext)!!.flagID)
|
||||
if(currentPeer.isMeshPeer){
|
||||
//TODO set mesh icon
|
||||
} else {
|
||||
peerInfoHolder.countryFlag.setImageResource(currentPeer.getCountry(mContext)!!.flagID)
|
||||
}
|
||||
peerInfoHolder.peerInfoText.text = currentPeer.toString()
|
||||
return listItem!!
|
||||
}
|
||||
|
@ -99,5 +99,39 @@ class Utils {
|
||||
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