Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
bannedbook committed May 30, 2020
1 parent 0499c9a commit 59688cf
Show file tree
Hide file tree
Showing 14 changed files with 301 additions and 47 deletions.
6 changes: 3 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ buildscript {
junitVersion = '4.13'
androidTestVersion = '1.2.0'
androidEspressoVersion = '3.2.0'
versionCode = 5000788
versionName = '5.1.3-nightly'
versionCode = 5000808
versionName = '5.1.4-nightly'
resConfigs = ['ar', 'es', 'fa', 'fr', 'ja', 'ko', 'ru', 'tr', 'zh-rCN', 'zh-rTW']
}

Expand All @@ -25,7 +25,7 @@ buildscript {
}

dependencies {
classpath 'com.android.tools.build:gradle:4.0.0-rc01'
classpath 'com.android.tools.build:gradle:4.0.0'
classpath 'com.github.ben-manes:gradle-versions-plugin:0.27.0'
classpath 'com.google.android.gms:oss-licenses-plugin:0.9.5'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.0.0-beta04'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ object BaseService {
}

data.notification = createNotification(profile.formattedName)
Core.analytics.logEvent("start", bundleOf(Pair(FirebaseAnalytics.Param.METHOD, tag)))
//Core.analytics.logEvent("start", bundleOf(Pair(FirebaseAnalytics.Param.METHOD, tag)))

data.changeState(State.Connecting)
data.connectingJob = GlobalScope.launch(Dispatchers.Main) {
Expand Down
22 changes: 9 additions & 13 deletions core/src/main/java/com/github/shadowsocks/bg/ProxyInstance.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@
package com.github.shadowsocks.bg

import android.content.Context
import android.util.Base64
import com.github.shadowsocks.Core
import android.util.Log
import com.github.shadowsocks.acl.Acl
import com.github.shadowsocks.acl.AclSyncer
import com.github.shadowsocks.database.Profile
Expand All @@ -31,26 +30,23 @@ import com.github.shadowsocks.plugin.PluginConfiguration
import com.github.shadowsocks.plugin.PluginManager
import com.github.shadowsocks.preference.DataStore
import com.github.shadowsocks.utils.parseNumericAddress
import com.github.shadowsocks.utils.signaturesCompat
import com.github.shadowsocks.utils.useCancellable
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.File
import java.io.IOException
import java.net.*
import java.security.MessageDigest
import java.net.Inet4Address
import java.net.Inet6Address
import java.net.UnknownHostException

/**
* This class sets up environment for ss-local.
*/
class ProxyInstance(val profile: Profile, private val route: String = profile.route) {
open class ProxyInstance(open val profile: Profile, private val route: String = profile.route) {
private var configFile: File? = null
var trafficMonitor: TrafficMonitor? = null
val plugin by lazy { PluginManager.init(PluginConfiguration(profile.plugin ?: "")) }
private var scheduleConfigUpdate = false

suspend fun init(service: BaseService.Interface, hosts: HostsFile) {
open suspend fun init(service: BaseService.Interface, hosts: HostsFile) {

// it's hard to resolve DNS on a specific interface so we'll do it here
if (profile.host.parseNumericAddress() == null) {
Expand Down Expand Up @@ -79,7 +75,7 @@ class ProxyInstance(val profile: Profile, private val route: String = profile.ro
* Sensitive shadowsocks configuration file requires extra protection. It may be stored in encrypted storage or
* device storage, depending on which is currently available.
*/
fun start(service: BaseService.Interface, stat: File, configFile: File, extraFlag: String? = null) {
open fun start(service: BaseService.Interface, stat: File, configFile: File, extraFlag: String? = null) {
trafficMonitor = TrafficMonitor(stat)

this.configFile = configFile
Expand Down Expand Up @@ -109,12 +105,12 @@ class ProxyInstance(val profile: Profile, private val route: String = profile.ro
service.data.processes!!.start(cmd)
}

fun scheduleUpdate() {
open fun scheduleUpdate() {
if (route !in arrayOf(Acl.ALL, Acl.CUSTOM_RULES)) AclSyncer.schedule(route)
if (scheduleConfigUpdate) RemoteConfig.fetchAsync()
}

fun shutdown(scope: CoroutineScope) {
open fun shutdown(scope: CoroutineScope) {
trafficMonitor?.apply {
thread.shutdown(scope)
persistStats(profile.id) // Make sure update total traffic when stopping the runner
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import java.io.IOException
import java.nio.ByteBuffer
import java.nio.ByteOrder

class TrafficMonitor(statFile: File) {
open class TrafficMonitor(statFile: File) {
val thread = object : LocalSocketListener("TrafficMonitor-" + statFile.name, statFile) {
private val buffer = ByteArray(16)
private val stat = ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN)
Expand All @@ -57,7 +57,7 @@ class TrafficMonitor(statFile: File) {
private var dirty = false
private var persisted: TrafficStats? = null

fun requestUpdate(): Pair<TrafficStats, Boolean> {
open fun requestUpdate(): Pair<TrafficStats, Boolean> {
val now = SystemClock.elapsedRealtime()
val delta = now - timestampLast
timestampLast = now
Expand Down
30 changes: 30 additions & 0 deletions core/src/main/java/com/github/shadowsocks/bg/V2ProxyInstance.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.github.shadowsocks.bg

import com.github.shadowsocks.Core
import com.github.shadowsocks.database.Profile
import com.github.shadowsocks.net.HostsFile
import kotlinx.coroutines.CoroutineScope
import libv2ray.V2RayPoint
import java.io.File

class V2ProxyInstance(override val profile: Profile, private val route: String = profile.route) : ProxyInstance(profile,route) {
private var v2rayPoint: V2RayPoint? =null
constructor(v2Point: V2RayPoint,profile: Profile, route: String) : this(profile,route) {
this.v2rayPoint=v2Point
trafficMonitor = V2TrafficMonitor(File(Core.deviceStorage.noBackupFilesDir, "stat_main"),v2rayPoint!!)
}

override suspend fun init(service: BaseService.Interface, hosts: HostsFile) {
}
override fun start(service: BaseService.Interface, stat: File, configFile: File, extraFlag: String?) {
}
override fun scheduleUpdate() {
}
override fun shutdown(scope: CoroutineScope) {
trafficMonitor?.apply {
thread.shutdown(scope)
persistStats(profile.id) // Make sure update total traffic when stopping the runner
}
trafficMonitor = null
}
}
14 changes: 13 additions & 1 deletion core/src/main/java/com/github/shadowsocks/bg/V2RayVpnService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ class V2RayVpnService : VpnService() , BaseService.Interface{
data.connectingJob = GlobalScope.launch(Dispatchers.Main) {
try {
activeProfile = ProfileManager.getProfile(DataStore.profileId)!!
val proxy = V2ProxyInstance(v2rayPoint,activeProfile,activeProfile.route)
data.proxy = proxy
genStoreV2rayConfig()
startV2ray()
} catch (_: CancellationException) {
Expand Down Expand Up @@ -324,12 +326,15 @@ class V2RayVpnService : VpnService() , BaseService.Interface{
try {
v2rayPoint.runLoop()
} catch (e: Exception) {
Log.d(packageName, e.toString())
Log.e(packageName, e.toString())
e.printStackTrace()
}

if (v2rayPoint.isRunning) {
Log.e(packageName, "v2rayPoint isRunning")
data.changeState(BaseService.State.Connected)
} else {
Log.e(packageName, "v2rayPoint is not Running")
//MessageUtil.sendMsg2UI(this, AppConfig.MSG_STATE_START_FAILURE, "")
//cancelNotification()
}
Expand All @@ -351,6 +356,13 @@ class V2RayVpnService : VpnService() , BaseService.Interface{
}
data.notification?.destroy()
data.notification = null
val ids = listOfNotNull(data.proxy, data.udpFallback).map {
it.shutdown(this)
it.profile.id
}
data.binder.trafficPersisted(ids)
data.proxy = null
data.udpFallback = null
// change the state
data.changeState(BaseService.State.Stopped, msg)

Expand Down
35 changes: 35 additions & 0 deletions core/src/main/java/com/github/shadowsocks/bg/V2TrafficMonitor.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.github.shadowsocks.bg

import com.github.shadowsocks.aidl.TrafficStats
import libv2ray.V2RayPoint
import rx.Observable
import java.io.File

class V2TrafficMonitor(statFile: File): TrafficMonitor(statFile) {
private var v2rayPoint: V2RayPoint? =null

constructor(statFile: File,v2Point: V2RayPoint) : this(statFile) {
this.v2rayPoint=v2Point
}

override fun requestUpdate(): Pair<TrafficStats, Boolean> {
var updated = false
if (v2rayPoint!!.isRunning ) {
Observable.interval(3, java.util.concurrent.TimeUnit.SECONDS)
.subscribe {
val uplink = v2rayPoint!!.queryStats("socks", "uplink")
val downlink = v2rayPoint!!.queryStats("socks", "downlink")
val zero_speed = (uplink == 0L && downlink == 0L)
if (!zero_speed ) {
current.txTotal+=uplink
current.txRate = uplink / 3
current.rxTotal+=downlink
current.rxRate = downlink / 3
}
}
}
if (current.txRate>0 || current.rxRate>0) updated = true
return Pair(current, updated)
}

}
90 changes: 81 additions & 9 deletions core/src/main/java/com/github/shadowsocks/database/Profile.kt
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,80 @@ data class Profile(
private val decodedPattern_ssr_protocolparam = "(?i)(.*)[?&]protoparam=([A-Za-z0-9_=-]*)(.*)".toRegex()
private val decodedPattern_ssr_groupparam = "(?i)(.*)[?&]group=([A-Za-z0-9_=-]*)(.*)".toRegex()

private val pattern_vmess = "(?i)vmess://([A-Za-z0-9_=-]+)".toRegex()
private val pattern_vmess = "(?i)vmess://(.*)".toRegex()

private fun base64Decode(data: String) = String(Base64.decode(data.replace("=", ""), Base64.URL_SAFE), Charsets.UTF_8)
/**
* base64 decode
*/
fun decodeForVmess(text: String): String {
try {
return Base64.decode(text, Base64.NO_WRAP).toString(charset("UTF-8"))
} catch (e: Exception) {
e.printStackTrace()
return ""
}
}

fun profileFromVmessBean(vmess: VmessBean, profile:Profile): Profile {
profile.profileType = "vmess"
//profile.id=vmess.guid.toLong()
profile.remoteDns=vmess.remoteDns
profile.host=vmess.address
profile.alterId=vmess.alterId
profile.headerType=vmess.headerType
profile.password=vmess.id
profile.network=vmess.network
profile.path=vmess.path
profile.remotePort=vmess.port
profile.name=vmess.remarks
profile.requestHost=vmess.requestHost
profile.method=vmess.security
profile.streamSecurity=vmess.streamSecurity
profile.url_group=vmess.subid

if(vmess.route=="0")profile.route="all"
else if(vmess.route=="1")profile.route="bypass-lan"
else if(vmess.route=="2")profile.route="bypass-china"
else if(vmess.route=="3")profile.route="bypass-lan-china"
else profile.route="all"

return profile
}


private fun ResolveVmess4Kitsunebi(server: String): VmessBean {
val vmess = VmessBean()
var result = server.replace(VMESS_PROTOCOL, "")
val indexSplit = result.indexOf("?")
if (indexSplit > 0) {
result = result.substring(0, indexSplit)
}
result = decodeForVmess(result)

val arr1 = result.split('@')
if (arr1.count() != 2) {
return vmess
}
val arr21 = arr1[0].split(':')
val arr22 = arr1[1].split(':')
if (arr21.count() != 2 || arr21.count() != 2) {
return vmess
}

vmess.address = arr22[0]
vmess.port = parseInt(arr22[1])
vmess.security = arr21[0]
vmess.id = arr21[1]

vmess.security = "chacha20-poly1305"
vmess.network = "tcp"
vmess.headerType = "none"
vmess.remarks = "Alien"
vmess.alterId = 0

return vmess
}
fun findAllVmessUrls(data: CharSequence?, feature: Profile? = null) = pattern_vmess.findAll(data
?: "").map {
val server = it.groupValues[1]
Expand All @@ -140,11 +210,10 @@ data class Profile(
try {
val indexSplit = server.indexOf("?")
if (indexSplit > 0) {
null
//profile = ResolveVmess4Kitsunebi(server,subid)
profileFromVmessBean(ResolveVmess4Kitsunebi(server),profile)
} else {
var result = server.replace(VMESS_PROTOCOL, "")
result = base64Decode(result)
result = decodeForVmess(result)
if (TextUtils.isEmpty(result)) {
null
}
Expand Down Expand Up @@ -176,8 +245,9 @@ data class Profile(
profile.streamSecurity = vmessQRCode.tls
profile
}
} catch (e: IllegalArgumentException) {
Log.e(TAG, "Invalid SSR URI: ${it.value}")
} catch (e: Exception) {
printLog(e)
Log.e(TAG, "Invalid Vmess URI: ${it.value}")
null
}
}.filterNotNull().toMutableSet()
Expand Down Expand Up @@ -232,7 +302,7 @@ data class Profile(
profile.name = uri.fragment
profile
} else {
Log.e(TAG, "Unrecognized URI: ${it.value}")
Log.e(TAG, "Unrecognized URI")
null
}
} else {
Expand Down Expand Up @@ -363,6 +433,9 @@ data class Profile(
@Query("SELECT * FROM `Profile` WHERE `id` = :id")
operator fun get(id: Long): Profile?

@Query("SELECT * FROM `Profile` WHERE `host` = :host LIMIT 1")
fun getByHost(host: String): Profile?

@Query("SELECT * FROM `Profile` WHERE `Subscription` != 2 ORDER BY `userOrder`")
fun listActive(): List<Profile>

Expand Down Expand Up @@ -425,8 +498,7 @@ data class Profile(
return builder.build()
}

fun isSameAs(other: Profile): Boolean = other.host == host && other.remotePort == remotePort &&
other.password == password && other.method == method
fun isSameAs(other: Profile): Boolean = other.host == host

override fun toString() = toUri().toString()

Expand Down
Loading

0 comments on commit 59688cf

Please sign in to comment.