Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
com.ccwangluo.accelerator
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
sheteng
com.ccwangluo.accelerator
Commits
0ffae32a
Commit
0ffae32a
authored
Jan 16, 2017
by
Mygod
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement plugin interface in mobile app
parent
c54745e2
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
136 additions
and
103 deletions
+136
-103
mobile/src/main/java/com/github/shadowsocks/utils/Commandline.java
...c/main/java/com/github/shadowsocks/utils/Commandline.java
+18
-9
mobile/src/main/scala/com/github/shadowsocks/BaseService.scala
...e/src/main/scala/com/github/shadowsocks/BaseService.scala
+26
-1
mobile/src/main/scala/com/github/shadowsocks/GuardedProcess.scala
...rc/main/scala/com/github/shadowsocks/GuardedProcess.scala
+5
-4
mobile/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala
.../scala/com/github/shadowsocks/ShadowsocksNatService.scala
+14
-55
mobile/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala
.../scala/com/github/shadowsocks/ShadowsocksVpnService.scala
+9
-29
mobile/src/main/scala/com/github/shadowsocks/plugin/PluginManager.scala
...n/scala/com/github/shadowsocks/plugin/PluginManager.scala
+55
-1
mobile/src/main/scala/com/github/shadowsocks/utils/Constants.scala
...c/main/scala/com/github/shadowsocks/utils/Constants.scala
+0
-1
mobile/src/main/scala/com/github/shadowsocks/utils/IOUtils.scala
...src/main/scala/com/github/shadowsocks/utils/IOUtils.scala
+7
-1
plugin/src/main/scala/com/github/shadowsocks/plugin/NativePluginProvider.scala
.../com/github/shadowsocks/plugin/NativePluginProvider.scala
+2
-2
No files found.
mobile/src/main/java/com/github/shadowsocks/utils/Commandline.java
View file @
0ffae32a
package
com.github.shadowsocks.utils
;
package
com.github.shadowsocks.utils
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.StringTokenizer
;
import
java.util.StringTokenizer
;
/**
/**
...
@@ -32,23 +33,21 @@ public final class Commandline {
...
@@ -32,23 +33,21 @@ public final class Commandline {
/**
/**
* Quote the parts of the given array in way that makes them
* Quote the parts of the given array in way that makes them
* usable as command line arguments.
* usable as command line arguments.
* @param
line
the list of arguments to quote.
* @param
args
the list of arguments to quote.
* @return empty string for null or no command, else every argument split
* @return empty string for null or no command, else every argument split
* by spaces and quoted by quoting rules.
* by spaces and quoted by quoting rules.
*/
*/
public
static
String
toString
(
String
[]
line
)
{
public
static
String
toString
(
Iterable
<
String
>
args
)
{
// empty path return empty string
// empty path return empty string
if
(
line
==
null
||
line
.
length
==
0
)
{
if
(
args
==
null
)
{
return
""
;
return
""
;
}
}
// path containing one or more elements
// path containing one or more elements
final
StringBuilder
result
=
new
StringBuilder
();
final
StringBuilder
result
=
new
StringBuilder
();
for
(
int
i
=
0
;
i
<
line
.
length
;
i
++)
{
for
(
String
arg
:
args
)
{
if
(
i
>
0
)
{
if
(
result
.
length
()
>
0
)
result
.
append
(
' '
);
result
.
append
(
' '
);
for
(
int
j
=
0
;
j
<
arg
.
length
();
++
j
)
{
}
char
ch
=
arg
.
charAt
(
j
);
for
(
int
j
=
0
;
j
<
line
[
i
].
length
();
++
j
)
{
char
ch
=
line
[
i
].
charAt
(
j
);
switch
(
ch
)
{
switch
(
ch
)
{
case
' '
:
case
'\\'
:
case
'"'
:
case
'\''
:
result
.
append
(
'\\'
);
// intentionally no break
case
' '
:
case
'\\'
:
case
'"'
:
case
'\''
:
result
.
append
(
'\\'
);
// intentionally no break
default
:
result
.
append
(
ch
);
default
:
result
.
append
(
ch
);
...
@@ -57,6 +56,16 @@ public final class Commandline {
...
@@ -57,6 +56,16 @@ public final class Commandline {
}
}
return
result
.
toString
();
return
result
.
toString
();
}
}
/**
* Quote the parts of the given array in way that makes them
* usable as command line arguments.
* @param args the list of arguments to quote.
* @return empty string for null or no command, else every argument split
* by spaces and quoted by quoting rules.
*/
public
static
String
toString
(
String
[]
args
)
{
return
toString
(
Arrays
.
asList
(
args
));
// thanks to Java, arrays aren't iterable
}
/**
/**
* Crack a command line.
* Crack a command line.
...
...
mobile/src/main/scala/com/github/shadowsocks/BaseService.scala
View file @
0ffae32a
...
@@ -24,7 +24,7 @@ import java.io.IOException
...
@@ -24,7 +24,7 @@ import java.io.IOException
import
java.net.InetAddress
import
java.net.InetAddress
import
java.util
import
java.util
import
java.util.concurrent.TimeUnit
import
java.util.concurrent.TimeUnit
import
java.util.
{
Timer
,
TimerTask
}
import
java.util.
{
Locale
,
Timer
,
TimerTask
}
import
android.app.Service
import
android.app.Service
import
android.content.
{
BroadcastReceiver
,
Context
,
Intent
,
IntentFilter
}
import
android.content.
{
BroadcastReceiver
,
Context
,
Intent
,
IntentFilter
}
...
@@ -36,6 +36,7 @@ import com.github.shadowsocks.ShadowsocksApplication.app
...
@@ -36,6 +36,7 @@ import com.github.shadowsocks.ShadowsocksApplication.app
import
com.github.shadowsocks.acl.Acl
import
com.github.shadowsocks.acl.Acl
import
com.github.shadowsocks.aidl.
{
IShadowsocksService
,
IShadowsocksServiceCallback
}
import
com.github.shadowsocks.aidl.
{
IShadowsocksService
,
IShadowsocksServiceCallback
}
import
com.github.shadowsocks.database.Profile
import
com.github.shadowsocks.database.Profile
import
com.github.shadowsocks.plugin.
{
PluginConfiguration
,
PluginManager
,
PluginOptions
}
import
com.github.shadowsocks.utils._
import
com.github.shadowsocks.utils._
import
okhttp3.
{
Dns
,
FormBody
,
OkHttpClient
,
Request
}
import
okhttp3.
{
Dns
,
FormBody
,
OkHttpClient
,
Request
}
...
@@ -46,6 +47,8 @@ trait BaseService extends Service {
...
@@ -46,6 +47,8 @@ trait BaseService extends Service {
@volatile
private
var
state
=
State
.
STOPPED
@volatile
private
var
state
=
State
.
STOPPED
@volatile
protected
var
profile
:
Profile
=
_
@volatile
protected
var
profile
:
Profile
=
_
@volatile
private
var
plugin
:
PluginOptions
=
_
@volatile
private
var
pluginPath
:
String
=
_
case
class
NameNotResolvedException
()
extends
IOException
case
class
NameNotResolvedException
()
extends
IOException
case
class
NullConnectionException
()
extends
NullPointerException
case
class
NullConnectionException
()
extends
NullPointerException
...
@@ -149,8 +152,12 @@ trait BaseService extends Service {
...
@@ -149,8 +152,12 @@ trait BaseService extends Service {
profile
.
password
=
proxy
(
2
).
trim
profile
.
password
=
proxy
(
2
).
trim
profile
.
method
=
proxy
(
3
).
trim
profile
.
method
=
proxy
(
3
).
trim
}
}
if
(
profile
.
route
==
Acl
.
CUSTOM_RULES
)
// rationalize custom rules
if
(
profile
.
route
==
Acl
.
CUSTOM_RULES
)
// rationalize custom rules
Acl
.
save
(
Acl
.
CUSTOM_RULES
,
new
Acl
().
fromId
(
Acl
.
CUSTOM_RULES
))
Acl
.
save
(
Acl
.
CUSTOM_RULES
,
new
Acl
().
fromId
(
Acl
.
CUSTOM_RULES
))
plugin
=
new
PluginConfiguration
(
profile
.
plugin
).
selectedOptions
pluginPath
=
PluginManager
.
initPlugin
(
plugin
.
id
)
}
}
def
startRunner
(
profile
:
Profile
)
{
def
startRunner
(
profile
:
Profile
)
{
...
@@ -304,4 +311,22 @@ trait BaseService extends Service {
...
@@ -304,4 +311,22 @@ trait BaseService extends Service {
case
_:
Exception
=>
"exclude = "
+
default
+
";"
case
_:
Exception
=>
"exclude = "
+
default
+
";"
}
}
}
}
protected
def
buildShadowsocksConfig
(
file
:
String
,
localPortOffset
:
Int
=
0
)
:
String
=
{
val
builder
=
new
StringBuilder
(
"""{"server": "%s", "server_port": %d, "local_port": %d, "password": "%s", "method": "%s""""
.
formatLocal
(
Locale
.
ENGLISH
,
profile
.
host
,
profile
.
remotePort
,
profile
.
localPort
+
localPortOffset
,
profile
.
password
,
profile
.
method
))
if
(
profile
.
auth
)
builder
.
append
(
""", "auth": true"""
)
if
(
pluginPath
!=
null
)
{
builder
.
append
(
""", "plugin": """"
)
builder
.
append
(
pluginPath
)
builder
.
append
(
"""", "plugin_opts": """"
)
builder
.
append
(
plugin
.
toString
)
builder
.
append
(
'"'
)
}
builder
.
append
(
'}'
)
IOUtils
.
writeString
(
file
,
builder
.
toString
)
file
}
}
}
mobile/src/main/scala/com/github/shadowsocks/GuardedProcess.scala
View file @
0ffae32a
...
@@ -26,6 +26,7 @@ import java.util.concurrent.Semaphore
...
@@ -26,6 +26,7 @@ import java.util.concurrent.Semaphore
import
android.util.Log
import
android.util.Log
import
com.github.shadowsocks.utils.CloseUtils._
import
com.github.shadowsocks.utils.CloseUtils._
import
com.github.shadowsocks.utils.Commandline
import
scala.collection.JavaConversions._
import
scala.collection.JavaConversions._
import
scala.collection.immutable.Stream
import
scala.collection.immutable.Stream
...
@@ -57,7 +58,7 @@ class GuardedProcess(cmd: Seq[String]) {
...
@@ -57,7 +58,7 @@ class GuardedProcess(cmd: Seq[String]) {
try
{
try
{
var
callback
:
()
=>
Unit
=
null
var
callback
:
()
=>
Unit
=
null
while
(!
isDestroyed
)
{
while
(!
isDestroyed
)
{
Log
.
i
(
TAG
,
"start process: "
+
cmd
)
Log
.
i
(
TAG
,
"start process: "
+
Commandline
.
toString
(
cmd
)
)
val
startTime
=
currentTimeMillis
val
startTime
=
currentTimeMillis
process
=
new
ProcessBuilder
(
cmd
).
redirectErrorStream
(
true
).
start
process
=
new
ProcessBuilder
(
cmd
).
redirectErrorStream
(
true
).
start
...
@@ -75,7 +76,7 @@ class GuardedProcess(cmd: Seq[String]) {
...
@@ -75,7 +76,7 @@ class GuardedProcess(cmd: Seq[String]) {
isRestart
=
false
isRestart
=
false
}
else
{
}
else
{
if
(
currentTimeMillis
-
startTime
<
1000
)
{
if
(
currentTimeMillis
-
startTime
<
1000
)
{
Log
.
w
(
TAG
,
"process exit too fast, stop guard: "
+
cmd
)
Log
.
w
(
TAG
,
"process exit too fast, stop guard: "
+
Commandline
.
toString
(
cmd
)
)
isDestroyed
=
true
isDestroyed
=
true
}
}
}
}
...
@@ -83,11 +84,11 @@ class GuardedProcess(cmd: Seq[String]) {
...
@@ -83,11 +84,11 @@ class GuardedProcess(cmd: Seq[String]) {
}
}
}
catch
{
}
catch
{
case
_:
InterruptedException
=>
case
_:
InterruptedException
=>
Log
.
i
(
TAG
,
"thread interrupt, destroy process: "
+
cmd
)
Log
.
i
(
TAG
,
"thread interrupt, destroy process: "
+
Commandline
.
toString
(
cmd
)
)
process
.
destroy
()
process
.
destroy
()
case
e
:
IOException
=>
ioException
=
e
case
e
:
IOException
=>
ioException
=
e
}
finally
semaphore
.
release
()
}
finally
semaphore
.
release
()
},
"GuardThread-"
+
cmd
)
},
"GuardThread-"
+
cmd
.
head
)
guardThread
.
start
()
guardThread
.
start
()
semaphore
.
acquire
()
semaphore
.
acquire
()
...
...
mobile/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala
View file @
0ffae32a
...
@@ -53,21 +53,11 @@ class ShadowsocksNatService extends BaseService {
...
@@ -53,21 +53,11 @@ class ShadowsocksNatService extends BaseService {
var
su
:
Shell.Interactive
=
_
var
su
:
Shell.Interactive
=
_
def
startShadowsocksDaemon
()
{
def
startShadowsocksDaemon
()
{
val
conf
=
ConfigUtils
.
SHADOWSOCKS
.
formatLocal
(
Locale
.
ENGLISH
,
profile
.
host
,
profile
.
remotePort
,
profile
.
localPort
,
profile
.
password
,
profile
.
method
,
600
)
Utils
.
printToFile
(
new
File
(
getApplicationInfo
.
dataDir
+
"/ss-local-nat.conf"
))(
p
=>
{
p
.
println
(
conf
)
})
val
cmd
=
ArrayBuffer
[
String
](
getApplicationInfo
.
nativeLibraryDir
+
"/libss-local.so"
val
cmd
=
ArrayBuffer
[
String
](
getApplicationInfo
.
nativeLibraryDir
+
"/libss-local.so"
,
"-b"
,
"127.0.0.1"
,
"-b"
,
"127.0.0.1"
,
"-t"
,
"600"
,
"-t"
,
"600"
,
"-P"
,
getApplicationInfo
.
dataDir
,
"-P"
,
getApplicationInfo
.
dataDir
,
"-c"
,
getApplicationInfo
.
dataDir
+
"/ss-local-nat.conf"
)
,
"-c"
,
buildShadowsocksConfig
(
getApplicationInfo
.
dataDir
+
"/ss-local-nat.conf"
))
if
(
profile
.
auth
)
cmd
+=
"-A"
if
(
TcpFastOpen
.
sendEnabled
)
cmd
+=
"--fast-open"
if
(
TcpFastOpen
.
sendEnabled
)
cmd
+=
"--fast-open"
...
@@ -76,55 +66,24 @@ class ShadowsocksNatService extends BaseService {
...
@@ -76,55 +66,24 @@ class ShadowsocksNatService extends BaseService {
cmd
+=
Acl
.
getPath
(
profile
.
route
)
cmd
+=
Acl
.
getPath
(
profile
.
route
)
}
}
if
(
BuildConfig
.
DEBUG
)
Log
.
d
(
TAG
,
cmd
.
mkString
(
" "
))
if
(
BuildConfig
.
DEBUG
)
Log
.
d
(
TAG
,
Commandline
.
toString
(
cmd
))
sslocalProcess
=
new
GuardedProcess
(
cmd
).
start
()
sslocalProcess
=
new
GuardedProcess
(
cmd
).
start
()
}
}
def
startDNSTunnel
()
{
def
startDNSTunnel
()
{
if
(
profile
.
udpdns
)
{
val
conf
=
ConfigUtils
.
SHADOWSOCKS
.
formatLocal
(
Locale
.
ENGLISH
,
profile
.
host
,
profile
.
remotePort
,
profile
.
localPort
+
53
,
profile
.
password
,
profile
.
method
,
10
)
Utils
.
printToFile
(
new
File
(
getApplicationInfo
.
dataDir
+
"/ss-tunnel-nat.conf"
))(
p
=>
{
p
.
println
(
conf
)
})
val
cmd
=
ArrayBuffer
[
String
](
getApplicationInfo
.
nativeLibraryDir
+
"/libss-tunnel.so"
val
cmd
=
ArrayBuffer
[
String
](
getApplicationInfo
.
nativeLibraryDir
+
"/libss-tunnel.so"
,
"-u"
,
"-t"
,
"10"
,
"-t"
,
"10"
,
"-b"
,
"127.0.0.1"
,
"-b"
,
"127.0.0.1"
,
"-l"
,
(
profile
.
localPort
+
53
).
toString
,
"-l"
,
(
profile
.
localPort
+
53
).
toString
,
"-L"
,
if
(
profile
.
remoteDns
==
null
)
"8.8.8.8:53"
else
profile
.
remoteDns
+
":53"
,
"-L"
,
if
(
profile
.
remoteDns
==
null
)
"8.8.8.8:53"
else
profile
.
remoteDns
+
":53"
,
"-P"
,
getApplicationInfo
.
dataDir
,
"-c"
,
getApplicationInfo
.
dataDir
+
"/ss-tunnel-nat.conf"
)
if
(
profile
.
auth
)
cmd
+=
"-A"
if
(
BuildConfig
.
DEBUG
)
Log
.
d
(
TAG
,
cmd
.
mkString
(
" "
))
sstunnelProcess
=
new
GuardedProcess
(
cmd
).
start
()
}
else
{
val
conf
=
ConfigUtils
.
SHADOWSOCKS
.
formatLocal
(
Locale
.
ENGLISH
,
profile
.
host
,
profile
.
remotePort
,
profile
.
localPort
+
63
,
profile
.
password
,
profile
.
method
,
10
)
Utils
.
printToFile
(
new
File
(
getApplicationInfo
.
dataDir
+
"/ss-tunnel-nat.conf"
))(
p
=>
{
p
.
println
(
conf
)
})
val
cmdBuf
=
ArrayBuffer
[
String
](
getApplicationInfo
.
nativeLibraryDir
+
"/libss-tunnel.so"
,
"-t"
,
"10"
,
"-b"
,
"127.0.0.1"
,
"-l"
,
(
profile
.
localPort
+
63
).
toString
,
"-L"
,
if
(
profile
.
remoteDns
==
null
)
"8.8.8.8:53"
else
profile
.
remoteDns
+
":53"
,
"-P"
,
getApplicationInfo
.
dataDir
,
"-P"
,
getApplicationInfo
.
dataDir
,
"-c"
,
getApplicationInfo
.
dataDir
+
"/ss-tunnel-nat.conf"
)
,
"-c"
,
buildShadowsocksConfig
(
getApplicationInfo
.
dataDir
+
"/ss-tunnel-nat.conf"
,
53
)
)
if
(
profile
.
auth
)
cmdBuf
+=
"-A"
if
(
profile
.
udpdns
)
cmd
.
append
(
"-u"
)
if
(
BuildConfig
.
DEBUG
)
Log
.
d
(
TAG
,
cmdBuf
.
mkString
(
" "
))
if
(
BuildConfig
.
DEBUG
)
Log
.
d
(
TAG
,
Commandline
.
toString
(
cmd
))
sstunnelProcess
=
new
GuardedProcess
(
cmdBuf
).
start
()
sstunnelProcess
=
new
GuardedProcess
(
cmd
).
start
()
}
}
}
def
startDnsDaemon
()
{
def
startDnsDaemon
()
{
...
@@ -150,7 +109,7 @@ class ShadowsocksNatService extends BaseService {
...
@@ -150,7 +109,7 @@ class ShadowsocksNatService extends BaseService {
})
})
val
cmd
=
Array
(
getApplicationInfo
.
nativeLibraryDir
+
"/libpdnsd.so"
,
"-c"
,
getApplicationInfo
.
dataDir
+
"/pdnsd-nat.conf"
)
val
cmd
=
Array
(
getApplicationInfo
.
nativeLibraryDir
+
"/libpdnsd.so"
,
"-c"
,
getApplicationInfo
.
dataDir
+
"/pdnsd-nat.conf"
)
if
(
BuildConfig
.
DEBUG
)
Log
.
d
(
TAG
,
cmd
.
mkString
(
" "
))
if
(
BuildConfig
.
DEBUG
)
Log
.
d
(
TAG
,
Commandline
.
toString
(
cmd
))
pdnsdProcess
=
new
GuardedProcess
(
cmd
).
start
()
pdnsdProcess
=
new
GuardedProcess
(
cmd
).
start
()
}
}
...
@@ -162,7 +121,7 @@ class ShadowsocksNatService extends BaseService {
...
@@ -162,7 +121,7 @@ class ShadowsocksNatService extends BaseService {
p
.
println
(
conf
)
p
.
println
(
conf
)
})
})
if
(
BuildConfig
.
DEBUG
)
Log
.
d
(
TAG
,
cmd
.
mkString
(
" "
))
if
(
BuildConfig
.
DEBUG
)
Log
.
d
(
TAG
,
Commandline
.
toString
(
cmd
))
redsocksProcess
=
new
GuardedProcess
(
cmd
).
start
()
redsocksProcess
=
new
GuardedProcess
(
cmd
).
start
()
}
}
...
...
mobile/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala
View file @
0ffae32a
...
@@ -30,10 +30,11 @@ import android.net.VpnService
...
@@ -30,10 +30,11 @@ import android.net.VpnService
import
android.os._
import
android.os._
import
android.util.Log
import
android.util.Log
import
com.github.shadowsocks.ShadowsocksApplication.app
import
com.github.shadowsocks.ShadowsocksApplication.app
import
com.github.shadowsocks.acl.
{
Acl
SyncJob
,
Acl
}
import
com.github.shadowsocks.acl.
{
Acl
,
AclSyncJob
}
import
com.github.shadowsocks.database.Profile
import
com.github.shadowsocks.database.Profile
import
com.github.shadowsocks.utils._
import
com.github.shadowsocks.utils._
import
scala.collection.JavaConversions._
import
scala.collection.mutable.ArrayBuffer
import
scala.collection.mutable.ArrayBuffer
class
ShadowsocksVpnService
extends
VpnService
with
BaseService
{
class
ShadowsocksVpnService
extends
VpnService
with
BaseService
{
...
@@ -162,21 +163,11 @@ class ShadowsocksVpnService extends VpnService with BaseService {
...
@@ -162,21 +163,11 @@ class ShadowsocksVpnService extends VpnService with BaseService {
}
}
def
startShadowsocksDaemon
()
{
def
startShadowsocksDaemon
()
{
val
conf
=
ConfigUtils
.
SHADOWSOCKS
.
formatLocal
(
Locale
.
ENGLISH
,
profile
.
host
,
profile
.
remotePort
,
profile
.
localPort
,
profile
.
password
,
profile
.
method
,
600
)
Utils
.
printToFile
(
new
File
(
getApplicationInfo
.
dataDir
+
"/ss-local-vpn.conf"
))(
p
=>
{
p
.
println
(
conf
)
})
val
cmd
=
ArrayBuffer
[
String
](
getApplicationInfo
.
nativeLibraryDir
+
"/libss-local.so"
,
"-V"
val
cmd
=
ArrayBuffer
[
String
](
getApplicationInfo
.
nativeLibraryDir
+
"/libss-local.so"
,
"-V"
,
"-b"
,
"127.0.0.1"
,
"-b"
,
"127.0.0.1"
,
"-t"
,
"600"
,
"-t"
,
"600"
,
"-P"
,
getApplicationInfo
.
dataDir
,
"-P"
,
getApplicationInfo
.
dataDir
,
"-c"
,
getApplicationInfo
.
dataDir
+
"/ss-local-vpn.conf"
)
,
"-c"
,
buildShadowsocksConfig
(
getApplicationInfo
.
dataDir
+
"/ss-local-vpn.conf"
))
if
(
profile
.
auth
)
cmd
+=
"-A"
if
(
profile
.
udpdns
)
cmd
+=
"-u"
if
(
profile
.
udpdns
)
cmd
+=
"-u"
...
@@ -187,31 +178,20 @@ class ShadowsocksVpnService extends VpnService with BaseService {
...
@@ -187,31 +178,20 @@ class ShadowsocksVpnService extends VpnService with BaseService {
if
(
TcpFastOpen
.
sendEnabled
)
cmd
+=
"--fast-open"
if
(
TcpFastOpen
.
sendEnabled
)
cmd
+=
"--fast-open"
if
(
BuildConfig
.
DEBUG
)
Log
.
d
(
TAG
,
cmd
.
mkString
(
" "
))
if
(
BuildConfig
.
DEBUG
)
Log
.
d
(
TAG
,
Commandline
.
toString
(
cmd
))
sslocalProcess
=
new
GuardedProcess
(
cmd
).
start
()
sslocalProcess
=
new
GuardedProcess
(
cmd
).
start
()
}
}
def
startDnsTunnel
()
{
def
startDnsTunnel
()
{
val
conf
=
val
cmd
=
Array
[
String
](
getApplicationInfo
.
nativeLibraryDir
+
"/libss-tunnel.so"
ConfigUtils
.
SHADOWSOCKS
.
formatLocal
(
Locale
.
ENGLISH
,
profile
.
host
,
profile
.
remotePort
,
profile
.
localPort
+
63
,
profile
.
password
,
profile
.
method
,
10
)
Utils
.
printToFile
(
new
File
(
getApplicationInfo
.
dataDir
+
"/ss-tunnel-vpn.conf"
))(
p
=>
{
p
.
println
(
conf
)
})
val
cmd
=
ArrayBuffer
[
String
](
getApplicationInfo
.
nativeLibraryDir
+
"/libss-tunnel.so"
,
"-V"
,
"-V"
,
"-t"
,
"10"
,
"-t"
,
"10"
,
"-b"
,
"127.0.0.1"
,
"-b"
,
"127.0.0.1"
,
"-L"
,
if
(
profile
.
remoteDns
==
null
)
"8.8.8.8:53"
else
profile
.
remoteDns
+
":53"
,
"-L"
,
if
(
profile
.
remoteDns
==
null
)
"8.8.8.8:53"
else
profile
.
remoteDns
+
":53"
,
"-P"
,
getApplicationInfo
.
dataDir
,
"-P"
,
getApplicationInfo
.
dataDir
,
"-c"
,
getApplicationInfo
.
dataDir
+
"/ss-tunnel-vpn.conf"
)
,
"-c"
,
buildShadowsocksConfig
(
getApplicationInfo
.
dataDir
+
"/ss-tunnel-vpn.conf"
,
53
))
if
(
BuildConfig
.
DEBUG
)
Log
.
d
(
TAG
,
Commandline
.
toString
(
cmd
))
if
(
profile
.
auth
)
cmd
+=
"-A"
if
(
BuildConfig
.
DEBUG
)
Log
.
d
(
TAG
,
cmd
.
mkString
(
" "
))
sstunnelProcess
=
new
GuardedProcess
(
cmd
).
start
()
sstunnelProcess
=
new
GuardedProcess
(
cmd
).
start
()
}
}
...
@@ -236,7 +216,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
...
@@ -236,7 +216,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
})
})
val
cmd
=
Array
(
getApplicationInfo
.
nativeLibraryDir
+
"/libpdnsd.so"
,
"-c"
,
getApplicationInfo
.
dataDir
+
"/pdnsd-vpn.conf"
)
val
cmd
=
Array
(
getApplicationInfo
.
nativeLibraryDir
+
"/libpdnsd.so"
,
"-c"
,
getApplicationInfo
.
dataDir
+
"/pdnsd-vpn.conf"
)
if
(
BuildConfig
.
DEBUG
)
Log
.
d
(
TAG
,
cmd
.
mkString
(
" "
))
if
(
BuildConfig
.
DEBUG
)
Log
.
d
(
TAG
,
Commandline
.
toString
(
cmd
))
pdnsdProcess
=
new
GuardedProcess
(
cmd
).
start
()
pdnsdProcess
=
new
GuardedProcess
(
cmd
).
start
()
}
}
...
@@ -310,7 +290,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
...
@@ -310,7 +290,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
cmd
+=
(
"--dnsgw"
,
"%s:%d"
.
formatLocal
(
Locale
.
ENGLISH
,
PRIVATE_VLAN
.
formatLocal
(
Locale
.
ENGLISH
,
"1"
),
cmd
+=
(
"--dnsgw"
,
"%s:%d"
.
formatLocal
(
Locale
.
ENGLISH
,
PRIVATE_VLAN
.
formatLocal
(
Locale
.
ENGLISH
,
"1"
),
profile
.
localPort
+
53
))
profile
.
localPort
+
53
))
if
(
BuildConfig
.
DEBUG
)
Log
.
d
(
TAG
,
cmd
.
mkString
(
" "
))
if
(
BuildConfig
.
DEBUG
)
Log
.
d
(
TAG
,
Commandline
.
toString
(
cmd
))
tun2socksProcess
=
new
GuardedProcess
(
cmd
).
start
(()
=>
sendFd
(
fd
))
tun2socksProcess
=
new
GuardedProcess
(
cmd
).
start
(()
=>
sendFd
(
fd
))
...
...
mobile/src/main/scala/com/github/shadowsocks/plugin/PluginManager.scala
View file @
0ffae32a
package
com.github.shadowsocks.plugin
package
com.github.shadowsocks.plugin
import
java.io.
{
File
,
FileNotFoundException
,
FileOutputStream
,
IOException
}
import
android.content.pm.PackageManager
import
android.content.pm.PackageManager
import
android.content.
{
BroadcastReceiver
,
Intent
}
import
android.content.
{
BroadcastReceiver
,
ContentResolver
,
Intent
}
import
android.net.Uri
import
com.github.shadowsocks.ShadowsocksApplication.app
import
com.github.shadowsocks.ShadowsocksApplication.app
import
com.github.shadowsocks.utils.CloseUtils.autoClose
import
com.github.shadowsocks.utils.IOUtils
import
scala.collection.JavaConverters._
import
scala.collection.JavaConverters._
...
@@ -22,4 +27,53 @@ object PluginManager {
...
@@ -22,4 +27,53 @@ object PluginManager {
})
})
cachedPlugins
cachedPlugins
}
}
// the following parts are meant to be used by :bg
@throws
[
Throwable
]
def
initPlugin
(
id
:
String
)
:
String
=
{
if
(
id
.
isEmpty
)
return
null
var
throwable
:
Throwable
=
null
try
initNativePlugin
(
id
)
match
{
case
null
=>
case
path
=>
return
path
}
catch
{
case
t
:
Throwable
=>
if
(
throwable
==
null
)
throwable
=
t
}
// add other plugin types here
throw
if
(
throwable
==
null
)
new
FileNotFoundException
(
app
.
getString
(
com
.
github
.
shadowsocks
.
R
.
string
.
plugin_unknown
,
id
))
else
throwable
}
@throws
[
IOException
]
@throws
[
IndexOutOfBoundsException
]
@throws
[
AssertionError
]
private
def
initNativePlugin
(
id
:
String
)
:
String
=
{
val
builder
=
new
Uri
.
Builder
()
.
scheme
(
ContentResolver
.
SCHEME_CONTENT
)
.
authority
(
PluginInterface
.
getAuthority
(
id
))
val
cr
=
app
.
getContentResolver
val
cursor
=
cr
.
query
(
builder
.
build
(),
Array
(
PluginInterface
.
COLUMN_PATH
),
null
,
null
,
null
)
if
(
cursor
!=
null
)
{
var
initialized
=
false
val
pluginDir
=
new
File
(
app
.
getFilesDir
,
"plugin"
)
if
(
cursor
.
moveToFirst
())
{
IOUtils
.
deleteRecursively
(
pluginDir
)
if
(!
pluginDir
.
mkdirs
())
throw
new
FileNotFoundException
(
"Unable to create plugin directory"
)
val
pluginDirPath
=
pluginDir
.
getAbsolutePath
+
'/'
do
{
val
path
=
cursor
.
getString
(
0
)
val
file
=
new
File
(
pluginDir
,
path
)
assert
(
file
.
getAbsolutePath
.
startsWith
(
pluginDirPath
))
autoClose
(
cr
.
openInputStream
(
builder
.
path
(
path
).
build
()))(
in
=>
autoClose
(
new
FileOutputStream
(
file
))(
out
=>
IOUtils
.
copy
(
in
,
out
)))
if
(
path
==
id
)
initialized
=
true
}
while
(
cursor
.
moveToNext
())
}
if
(!
initialized
)
throw
new
IndexOutOfBoundsException
(
"Plugin entry binary not found"
)
new
File
(
pluginDir
,
id
).
getAbsolutePath
}
else
null
}
}
}
mobile/src/main/scala/com/github/shadowsocks/utils/Constants.scala
View file @
0ffae32a
...
@@ -31,7 +31,6 @@ object Executable {
...
@@ -31,7 +31,6 @@ object Executable {
}
}
object
ConfigUtils
{
object
ConfigUtils
{
val
SHADOWSOCKS
=
"{\"server\": \"%s\", \"server_port\": %d, \"local_port\": %d, \"password\": \"%s\", \"method\":\"%s\", \"timeout\": %d}"
val
REDSOCKS
=
"base {\n"
+
val
REDSOCKS
=
"base {\n"
+
" log_debug = off;\n"
+
" log_debug = off;\n"
+
" log_info = off;\n"
+
" log_info = off;\n"
+
...
...
mobile/src/main/scala/com/github/shadowsocks/utils/IOUtils.scala
View file @
0ffae32a
...
@@ -21,7 +21,7 @@
...
@@ -21,7 +21,7 @@
package
com.github.shadowsocks.utils
package
com.github.shadowsocks.utils
import
com.github.shadowsocks.utils.CloseUtils._
import
com.github.shadowsocks.utils.CloseUtils._
import
java.io.
{
FileWriter
,
InputStream
,
OutputStream
}
import
java.io.
_
/**
/**
* @author Mygod
* @author Mygod
...
@@ -39,4 +39,10 @@ object IOUtils {
...
@@ -39,4 +39,10 @@ object IOUtils {
def
writeString
(
file
:
String
,
content
:
String
)
:
Unit
=
def
writeString
(
file
:
String
,
content
:
String
)
:
Unit
=
autoClose
(
new
FileWriter
(
file
))(
writer
=>
writer
.
write
(
content
))
autoClose
(
new
FileWriter
(
file
))(
writer
=>
writer
.
write
(
content
))
@throws
[
FileNotFoundException
]
def
deleteRecursively
(
file
:
File
)
{
if
(
file
.
isDirectory
)
file
.
listFiles
().
foreach
(
deleteRecursively
)
if
(!
file
.
delete
())
throw
new
FileNotFoundException
(
"Failed to delete: "
+
file
.
getAbsolutePath
)
}
}
}
plugin/src/main/scala/com/github/shadowsocks/plugin/NativePluginProvider.scala
View file @
0ffae32a
...
@@ -46,7 +46,7 @@ abstract class NativePluginProvider extends ContentProvider {
...
@@ -46,7 +46,7 @@ abstract class NativePluginProvider extends ContentProvider {
override
def
query
(
uri
:
Uri
,
projection
:
Array
[
String
],
selection
:
String
,
selectionArgs
:
Array
[
String
],
override
def
query
(
uri
:
Uri
,
projection
:
Array
[
String
],
selection
:
String
,
selectionArgs
:
Array
[
String
],
sortOrder
:
String
)
:
Cursor
=
{
sortOrder
:
String
)
:
Cursor
=
{
if
(
selection
!=
null
||
selectionArgs
!=
null
||
sortOrder
!=
null
)
???
assert
(
selection
==
null
&&
selectionArgs
==
null
&&
sortOrder
==
null
)
val
result
=
new
MatrixCursor
(
projection
.
filter
(
_
==
PluginInterface
.
COLUMN_PATH
))
val
result
=
new
MatrixCursor
(
projection
.
filter
(
_
==
PluginInterface
.
COLUMN_PATH
))
populateFiles
(
new
PathProvider
(
uri
,
result
))
populateFiles
(
new
PathProvider
(
uri
,
result
))
result
result
...
@@ -54,7 +54,7 @@ abstract class NativePluginProvider extends ContentProvider {
...
@@ -54,7 +54,7 @@ abstract class NativePluginProvider extends ContentProvider {
def
openFile
(
uri
:
Uri
)
:
ParcelFileDescriptor
def
openFile
(
uri
:
Uri
)
:
ParcelFileDescriptor
override
def
openFile
(
uri
:
Uri
,
mode
:
String
)
:
ParcelFileDescriptor
=
{
override
def
openFile
(
uri
:
Uri
,
mode
:
String
)
:
ParcelFileDescriptor
=
{
if
(
mode
!=
"r"
)
???
assert
(
mode
==
"r"
)
openFile
(
uri
)
openFile
(
uri
)
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment