add query proxies
This commit is contained in:
15 files changed
+310
-72
No files matched your search
@@ -18,6 +18,9 @@ func main() {
|
||||
return
|
||||
}
|
||||
|
||||
// Redirect stderr to stdout
|
||||
os.Stderr = os.Stdout
|
||||
|
||||
if cwd, err := os.Getwd(); err == nil {
|
||||
constant.SetHomeDir(cwd)
|
||||
} else {
|
||||
|
||||
@@ -13,8 +13,6 @@ func handleProfileDefault(client *net.UnixConn) {
|
||||
profile.LoadDefault()
|
||||
|
||||
log.Infoln("Profile default loaded")
|
||||
|
||||
client.Close()
|
||||
}
|
||||
|
||||
func handleProfileReload(client *net.UnixConn) {
|
||||
@@ -49,6 +47,4 @@ func handleProfileReload(client *net.UnixConn) {
|
||||
}
|
||||
|
||||
log.Infoln("Profile " + payload.Path + " loaded")
|
||||
|
||||
client.Close()
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net"
|
||||
|
||||
"github.com/Dreamacro/clash/log"
|
||||
"github.com/Dreamacro/clash/tunnel"
|
||||
)
|
||||
|
||||
func handleQueryProxies(client *net.UnixConn) {
|
||||
proxies := tunnel.Instance().Proxies()
|
||||
|
||||
var root struct {
|
||||
proxies []map[string]interface{} `json:"proxies"`
|
||||
}
|
||||
|
||||
root.proxies = make([]map[string]interface{}, len(proxies))
|
||||
|
||||
for _, p := range proxies {
|
||||
inner, err := p.MarshalJSON()
|
||||
|
||||
if err != nil {
|
||||
log.Warnln("MarshalJSON failure %s", err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
mapping := map[string]interface{}{}
|
||||
json.Unmarshal(inner, &mapping)
|
||||
|
||||
root.proxies = append(root.proxies, mapping)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,6 +13,7 @@ const (
|
||||
commandTunStop = 2
|
||||
commandProfileDefault = 3
|
||||
commandProfileReload = 4
|
||||
commandQueryProxies = 5
|
||||
)
|
||||
|
||||
var handlers map[int]func(*net.UnixConn) = make(map[int]func(*net.UnixConn))
|
||||
@@ -23,6 +24,7 @@ func init() {
|
||||
handlers[commandTunStop] = handleTunStop // tun.go
|
||||
handlers[commandProfileDefault] = handleProfileDefault // profile.go
|
||||
handlers[commandProfileReload] = handleProfileReload // profile.go
|
||||
handlers[commandQueryProxies] = handleQueryProxies
|
||||
}
|
||||
|
||||
// Start local control server
|
||||
@@ -64,4 +66,6 @@ func handleConnection(client *net.UnixConn) {
|
||||
}
|
||||
|
||||
handler(client)
|
||||
|
||||
client.Close()
|
||||
}
|
||||
@@ -49,11 +49,5 @@ func handleTunStart(client *net.UnixConn) {
|
||||
}
|
||||
|
||||
func handleTunStop(client *net.UnixConn) {
|
||||
buf, _ := readCommandPacket(client)
|
||||
|
||||
if tunCommandEnd != binary.BigEndian.Uint32(buf) {
|
||||
log.Warnln("Invalid tun command end")
|
||||
}
|
||||
|
||||
tun.StopTunProxy()
|
||||
}
|
||||
@@ -52,6 +52,8 @@ func StartTunProxy(fd, mtu int) error {
|
||||
|
||||
// StopTunProxy - stop
|
||||
func StopTunProxy() {
|
||||
log.Infoln("Tun Device Stopped")
|
||||
|
||||
instance.close()
|
||||
instance = nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.github.kr328.clash.core
|
||||
|
||||
import android.net.LocalSocket
|
||||
import android.net.LocalSocketAddress
|
||||
import java.io.DataInputStream
|
||||
import java.io.DataOutputStream
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
|
||||
abstract class BaseClash(private val controllerPath: File) {
|
||||
protected fun <R> runControl(
|
||||
command: Int,
|
||||
block: (LocalSocket, DataInputStream, DataOutputStream) -> R
|
||||
): R {
|
||||
val socket = LocalSocket()
|
||||
|
||||
socket.connect(
|
||||
LocalSocketAddress(
|
||||
controllerPath.absolutePath,
|
||||
LocalSocketAddress.Namespace.FILESYSTEM
|
||||
)
|
||||
)
|
||||
|
||||
val input = DataInputStream(socket.inputStream)
|
||||
val output = DataOutputStream(socket.outputStream)
|
||||
|
||||
output.writeInt(command)
|
||||
|
||||
val result = block(socket, input, output)
|
||||
|
||||
runCatching {
|
||||
socket.close()
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
protected fun runControl(command: Int) {
|
||||
return runControl(command) { _, _, _ -> }
|
||||
}
|
||||
|
||||
|
||||
protected fun DataOutputStream.writeString(string: String) {
|
||||
this.writeInt(string.length)
|
||||
this.writeBytes(string)
|
||||
}
|
||||
|
||||
protected fun DataInputStream.readString(): String {
|
||||
val len = this.readInt()
|
||||
val buffer = ByteArray(len)
|
||||
|
||||
this.read(buffer)
|
||||
|
||||
return String(buffer)
|
||||
}
|
||||
}
|
||||
@@ -1,28 +1,29 @@
|
||||
package com.github.kr328.clash.core
|
||||
|
||||
import android.content.Context
|
||||
import android.net.LocalSocket
|
||||
import android.net.LocalSocketAddress
|
||||
import android.util.Log
|
||||
import com.github.kr328.clash.core.Constants.TAG
|
||||
import org.json.JSONObject
|
||||
import java.io.*
|
||||
|
||||
class Clash(
|
||||
context: Context,
|
||||
clashDir: File,
|
||||
private val controllerPath: File,
|
||||
controllerPath: File,
|
||||
listener: (ClashProcessStatus) -> Unit
|
||||
) : ClashProcess(context, clashDir, controllerPath, listener) {
|
||||
) : BaseClash(controllerPath) {
|
||||
companion object {
|
||||
const val COMMAND_PING = 0
|
||||
const val COMMAND_TUN_START = 1
|
||||
const val COMMAND_TUN_STOP = 2
|
||||
const val COMMAND_PROFILE_DEFAULT = 3
|
||||
const val COMMAND_PROFILE_RELOAD = 4
|
||||
const val COMMAND_QUERY_PROXIES = 5
|
||||
|
||||
const val PING_REPLY = 233
|
||||
}
|
||||
|
||||
val process = ClashProcess(context, clashDir, controllerPath, listener)
|
||||
|
||||
fun ping(): Boolean {
|
||||
try {
|
||||
return runControl(COMMAND_PING) { _, input, _ ->
|
||||
@@ -34,8 +35,6 @@ class Clash(
|
||||
return false
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
@Synchronized
|
||||
fun loadProfile(file: File) {
|
||||
runControl(COMMAND_PROFILE_RELOAD) { _, input, output ->
|
||||
output.writeString(JSONObject().apply {
|
||||
@@ -49,7 +48,6 @@ class Clash(
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
fun startTunDevice(fd: FileDescriptor, mtu: Int) {
|
||||
runControl(COMMAND_TUN_START) { socket, _, output ->
|
||||
socket.setFileDescriptorsForSend(arrayOf(fd))
|
||||
@@ -60,49 +58,7 @@ class Clash(
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R> runControl(
|
||||
command: Int,
|
||||
block: (LocalSocket, DataInputStream, DataOutputStream) -> R
|
||||
): R {
|
||||
val socket = LocalSocket()
|
||||
|
||||
socket.connect(
|
||||
LocalSocketAddress(
|
||||
controllerPath.absolutePath,
|
||||
LocalSocketAddress.Namespace.FILESYSTEM
|
||||
)
|
||||
)
|
||||
|
||||
val input = DataInputStream(socket.inputStream)
|
||||
val output = DataOutputStream(socket.outputStream)
|
||||
|
||||
output.writeInt(command)
|
||||
|
||||
val result = block(socket, input, output)
|
||||
|
||||
try {
|
||||
input.close()
|
||||
output.close()
|
||||
|
||||
socket.close()
|
||||
} catch (ignore: IOException) {
|
||||
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private fun DataOutputStream.writeString(string: String) {
|
||||
this.writeInt(string.length)
|
||||
this.writeBytes(string)
|
||||
}
|
||||
|
||||
private fun DataInputStream.readString(): String {
|
||||
val len = this.readInt()
|
||||
val buffer = ByteArray(len)
|
||||
|
||||
this.read(buffer)
|
||||
|
||||
return String(buffer)
|
||||
fun stopTunDevice() {
|
||||
runControl(COMMAND_TUN_STOP)
|
||||
}
|
||||
}
|
||||
@@ -2,19 +2,18 @@ package com.github.kr328.clash.core
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import com.github.kr328.clash.core.Constants.TAG
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.IOException
|
||||
import java.lang.Exception
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
abstract class ClashProcess(private val context: Context,
|
||||
class ClashProcess(private val context: Context,
|
||||
private val clashDir: File,
|
||||
private val controllerPath: File,
|
||||
private val listener: (ClashProcessStatus) -> Unit) {
|
||||
companion object {
|
||||
const val TAG = "ClashForAndroid"
|
||||
|
||||
private const val CONTROLLER_STATUS_PREFIX = "[CONTROLLER]"
|
||||
|
||||
private val PID_PATTERN = Regex("\\[PID]\\s*(\\d+)")
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.github.kr328.clash.core
|
||||
|
||||
object Constants {
|
||||
const val TAG = "ClashForAndroid"
|
||||
}
|
||||
@@ -22,7 +22,7 @@ import java.util.concurrent.Executors
|
||||
|
||||
class ClashService : Service() {
|
||||
companion object {
|
||||
private val TAG = "ClashForAndroid"
|
||||
private const val TAG = "ClashForAndroid"
|
||||
|
||||
private const val CLASH_STATUS_NOTIFICATION_CHANNEL = "clash_status_channel"
|
||||
private const val CLASH_STATUS_NOTIFICATION_ID = 413
|
||||
@@ -100,7 +100,7 @@ class ClashService : Service() {
|
||||
}
|
||||
|
||||
override fun stopTunDevice() {
|
||||
clash.stop()
|
||||
clash.stopTunDevice()
|
||||
|
||||
handler.post(this@ClashService::updateNotification)
|
||||
}
|
||||
|
||||
@@ -82,8 +82,8 @@ class TunService : VpnService() {
|
||||
.addAddress(PRIVATE_VLAN6_CLIENT, 126)
|
||||
.addDefaultDns()
|
||||
.addDisallowedApplication(packageName)
|
||||
.addRoute("0.0.0.0", 0)
|
||||
.addRoute("::", 0)
|
||||
.addDns()
|
||||
.addBypassPrivateRoute()
|
||||
.setMtu(VPN_MTU)
|
||||
.setBlocking(false)
|
||||
.setMeteredCompat(false)
|
||||
@@ -129,4 +129,25 @@ class TunService : VpnService() {
|
||||
setMetered(isMetered)
|
||||
return this
|
||||
}
|
||||
|
||||
private fun Builder.addBypassPrivateRoute(): Builder {
|
||||
// IPv4
|
||||
resources.getStringArray(R.array.bypass_private_route).forEach {
|
||||
val address = it.split("/")
|
||||
Log.d(TAG, "$address")
|
||||
addRoute(address[0], address[1].toInt())
|
||||
}
|
||||
|
||||
// IPv6
|
||||
addRoute("::", 0)
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
private fun Builder.addDns(): Builder {
|
||||
resources.getStringArray(R.array.default_dns).forEach {
|
||||
addDnsServer(it)
|
||||
}
|
||||
return this
|
||||
}
|
||||
}
|
||||
@@ -48,11 +48,10 @@ class DefaultNetworkObserver(val context: Context, val listener: (Network?) -> U
|
||||
fun register() {
|
||||
connectivity.registerNetworkCallback(NetworkRequest.Builder().build(), callback)
|
||||
|
||||
listener(connectivity.activeNetwork)
|
||||
|
||||
handler.postDelayed({
|
||||
blocking = false
|
||||
}, 1000)
|
||||
listener(connectivity.activeNetwork)
|
||||
}, 3000)
|
||||
}
|
||||
|
||||
fun unregister() {
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.9 KiB |
@@ -0,0 +1,169 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- from https://github.com/shadowsocks/shadowsocks-android/blob/master/core/src/main/res/values/arrays.xml -->
|
||||
<string-array name="bypass_private_route" translatable="false">
|
||||
<item>1.0.0.0/8</item>
|
||||
<item>2.0.0.0/7</item>
|
||||
<item>4.0.0.0/6</item>
|
||||
<item>8.0.0.0/7</item>
|
||||
<item>11.0.0.0/8</item>
|
||||
<item>12.0.0.0/6</item>
|
||||
<item>16.0.0.0/4</item>
|
||||
<item>32.0.0.0/3</item>
|
||||
<item>64.0.0.0/3</item>
|
||||
<item>96.0.0.0/6</item>
|
||||
<item>100.0.0.0/10</item>
|
||||
<item>100.128.0.0/9</item>
|
||||
<item>101.0.0.0/8</item>
|
||||
<item>102.0.0.0/7</item>
|
||||
<item>104.0.0.0/5</item>
|
||||
<item>112.0.0.0/10</item>
|
||||
<item>112.64.0.0/11</item>
|
||||
<item>112.96.0.0/12</item>
|
||||
<item>112.112.0.0/13</item>
|
||||
<item>112.120.0.0/14</item>
|
||||
<item>112.124.0.0/19</item>
|
||||
<item>112.124.32.0/21</item>
|
||||
<item>112.124.40.0/22</item>
|
||||
<item>112.124.44.0/23</item>
|
||||
<item>112.124.46.0/24</item>
|
||||
<item>112.124.48.0/20</item>
|
||||
<item>112.124.64.0/18</item>
|
||||
<item>112.124.128.0/17</item>
|
||||
<item>112.125.0.0/16</item>
|
||||
<item>112.126.0.0/15</item>
|
||||
<item>112.128.0.0/9</item>
|
||||
<item>113.0.0.0/8</item>
|
||||
<item>114.0.0.0/10</item>
|
||||
<item>114.64.0.0/11</item>
|
||||
<item>114.96.0.0/12</item>
|
||||
<item>114.112.0.0/15</item>
|
||||
<item>114.114.0.0/18</item>
|
||||
<item>114.114.64.0/19</item>
|
||||
<item>114.114.96.0/20</item>
|
||||
<item>114.114.112.0/23</item>
|
||||
<item>114.114.115.0/24</item>
|
||||
<item>114.114.116.0/22</item>
|
||||
<item>114.114.120.0/21</item>
|
||||
<item>114.114.128.0/17</item>
|
||||
<item>114.115.0.0/16</item>
|
||||
<item>114.116.0.0/14</item>
|
||||
<item>114.120.0.0/13</item>
|
||||
<item>114.128.0.0/9</item>
|
||||
<item>115.0.0.0/8</item>
|
||||
<item>116.0.0.0/6</item>
|
||||
<item>120.0.0.0/6</item>
|
||||
<item>124.0.0.0/7</item>
|
||||
<item>126.0.0.0/8</item>
|
||||
<item>128.0.0.0/3</item>
|
||||
<item>160.0.0.0/5</item>
|
||||
<item>168.0.0.0/8</item>
|
||||
<item>169.0.0.0/9</item>
|
||||
<item>169.128.0.0/10</item>
|
||||
<item>169.192.0.0/11</item>
|
||||
<item>169.224.0.0/12</item>
|
||||
<item>169.240.0.0/13</item>
|
||||
<item>169.248.0.0/14</item>
|
||||
<item>169.252.0.0/15</item>
|
||||
<item>169.255.0.0/16</item>
|
||||
<item>170.0.0.0/7</item>
|
||||
<item>172.0.0.0/12</item>
|
||||
<item>172.32.0.0/11</item>
|
||||
<item>172.64.0.0/10</item>
|
||||
<item>172.128.0.0/9</item>
|
||||
<item>173.0.0.0/8</item>
|
||||
<item>174.0.0.0/7</item>
|
||||
<item>176.0.0.0/4</item>
|
||||
<item>192.0.0.8/29</item>
|
||||
<item>192.0.0.16/28</item>
|
||||
<item>192.0.0.32/27</item>
|
||||
<item>192.0.0.64/26</item>
|
||||
<item>192.0.0.128/25</item>
|
||||
<item>192.0.1.0/24</item>
|
||||
<item>192.0.3.0/24</item>
|
||||
<item>192.0.4.0/22</item>
|
||||
<item>192.0.8.0/21</item>
|
||||
<item>192.0.16.0/20</item>
|
||||
<item>192.0.32.0/19</item>
|
||||
<item>192.0.64.0/18</item>
|
||||
<item>192.0.128.0/17</item>
|
||||
<item>192.1.0.0/16</item>
|
||||
<item>192.2.0.0/15</item>
|
||||
<item>192.4.0.0/14</item>
|
||||
<item>192.8.0.0/13</item>
|
||||
<item>192.16.0.0/12</item>
|
||||
<item>192.32.0.0/11</item>
|
||||
<item>192.64.0.0/12</item>
|
||||
<item>192.80.0.0/13</item>
|
||||
<item>192.88.0.0/18</item>
|
||||
<item>192.88.64.0/19</item>
|
||||
<item>192.88.96.0/23</item>
|
||||
<item>192.88.98.0/24</item>
|
||||
<item>192.88.100.0/22</item>
|
||||
<item>192.88.104.0/21</item>
|
||||
<item>192.88.112.0/20</item>
|
||||
<item>192.88.128.0/17</item>
|
||||
<item>192.89.0.0/16</item>
|
||||
<item>192.90.0.0/15</item>
|
||||
<item>192.92.0.0/14</item>
|
||||
<item>192.96.0.0/11</item>
|
||||
<item>192.128.0.0/11</item>
|
||||
<item>192.160.0.0/13</item>
|
||||
<item>192.169.0.0/16</item>
|
||||
<item>192.170.0.0/15</item>
|
||||
<item>192.172.0.0/14</item>
|
||||
<item>192.176.0.0/12</item>
|
||||
<item>192.192.0.0/10</item>
|
||||
<item>193.0.0.0/8</item>
|
||||
<item>194.0.0.0/7</item>
|
||||
<item>196.0.0.0/7</item>
|
||||
<item>198.0.0.0/12</item>
|
||||
<item>198.16.0.0/15</item>
|
||||
<item>198.18.0.0/16</item>
|
||||
<item>198.20.0.0/14</item>
|
||||
<item>198.24.0.0/13</item>
|
||||
<item>198.32.0.0/12</item>
|
||||
<item>198.48.0.0/15</item>
|
||||
<item>198.50.0.0/16</item>
|
||||
<item>198.51.0.0/18</item>
|
||||
<item>198.51.64.0/19</item>
|
||||
<item>198.51.96.0/22</item>
|
||||
<item>198.51.101.0/24</item>
|
||||
<item>198.51.102.0/23</item>
|
||||
<item>198.51.104.0/21</item>
|
||||
<item>198.51.112.0/20</item>
|
||||
<item>198.51.128.0/17</item>
|
||||
<item>198.52.0.0/14</item>
|
||||
<item>198.56.0.0/13</item>
|
||||
<item>198.64.0.0/10</item>
|
||||
<item>198.128.0.0/9</item>
|
||||
<item>199.0.0.0/8</item>
|
||||
<item>200.0.0.0/7</item>
|
||||
<item>202.0.0.0/8</item>
|
||||
<item>203.0.0.0/18</item>
|
||||
<item>203.0.64.0/19</item>
|
||||
<item>203.0.96.0/20</item>
|
||||
<item>203.0.112.0/24</item>
|
||||
<item>203.0.114.0/23</item>
|
||||
<item>203.0.116.0/22</item>
|
||||
<item>203.0.120.0/21</item>
|
||||
<item>203.0.128.0/17</item>
|
||||
<item>203.1.0.0/16</item>
|
||||
<item>203.2.0.0/15</item>
|
||||
<item>203.4.0.0/14</item>
|
||||
<item>203.8.0.0/13</item>
|
||||
<item>203.16.0.0/12</item>
|
||||
<item>203.32.0.0/11</item>
|
||||
<item>203.64.0.0/10</item>
|
||||
<item>203.128.0.0/9</item>
|
||||
<item>204.0.0.0/6</item>
|
||||
<item>208.0.0.0/4</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="default_dns" translatable="false">
|
||||
<item>119.29.29.29</item>
|
||||
<item>223.5.5.5</item>
|
||||
<item>1.1.1.1</item>
|
||||
<item>8.8.8.8</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
Reference in new issue
Block a user