Compare commits

...
16 Commits
Author SHA1 Message Date
Max Lv c21bd74302 Merge branch 'beta' 2017-03-11 18:48:12 +08:00
Max Lv a8822330a3 Bump version 2017-03-11 18:43:03 +08:00
Max Lv 1cf6e4802c Update strings 2017-03-11 18:15:34 +08:00
Max Lv f64014eb7b Always forwording UDP traffic #1156 2017-03-11 15:49:06 +08:00
Mygod 2f6f991e6e Fix literal IPv6 address handling in URIs 2017-03-11 12:33:27 +08:00
Mygod 90e00a3857 Refine README.md 2017-03-11 12:11:52 +08:00
Mygod 9c97dc9bf6 Update README.md to reflect changes in sbt-android 2017-03-09 23:54:48 +08:00
Mygod 7d2e0a515f Remove redundant group in legacyPattern 2017-03-09 20:46:34 +08:00
Max Lv c920c0daa4 Bump version 2017-02-24 19:37:23 +08:00
Mygod 8e3854b496 Update dependencies 2017-02-24 19:37:23 +08:00
Max Lv ad42167b2e Update shadowsocks-libev 2017-02-24 19:37:23 +08:00
Max Lv 3bf0963c5a Trim remoteDns 2017-02-24 19:37:23 +08:00
Max Lv c3315d35ed Fix #1130 2017-02-24 19:37:23 +08:00
Max Lv 103dc10a0a Update shadowsocks-libev 2017-02-24 19:37:23 +08:00
Max Lv 36c94b8d83 Fix a memory leak 2017-02-24 19:37:22 +08:00
Mygod df72b29302 Fix malformed URL in about.html 2017-02-23 15:17:57 +08:00
11 changed files with 33 additions and 27 deletions
+1 -1
View File
@@ -16,7 +16,7 @@ A [shadowsocks](http://shadowsocks.org) client for Android, written in Scala.
* Android SDK * Android SDK
- Build Tools 25+ - Build Tools 25+
- Android Support Repository and Google Repository (see `build.sbt` for version) - Android Support Repository and Google Repository (see `build.sbt` for version)
* Android NDK r14+ - Android NDK r14+
### BUILD ### BUILD
+2 -2
View File
@@ -2,8 +2,8 @@ enablePlugins(AndroidApp)
android.useSupportVectors android.useSupportVectors
name := "shadowsocks" name := "shadowsocks"
version := "4.1.2" version := "4.1.3"
versionCode := Some(182) versionCode := Some(183)
proguardOptions ++= proguardOptions ++=
"-keep class com.github.shadowsocks.JniHelper { *; }" :: "-keep class com.github.shadowsocks.JniHelper { *; }" ::
+1 -1
View File
@@ -275,7 +275,7 @@ img {
<body> <body>
<p>A <a href="http://shadowsocks.org">Shadowsocks</a> client for Android, written in Scala.</p> <p>A <a href="http://shadowsocks.org">Shadowsocks</a> client for Android, written in Scala.</p>
<p>Copyright (C) 2017 by Max Lv <a href="&#x6d;&#97;&#x69;&#108;&#116;&#111;&#x3a;&#x6d;&#97;x&#46;&#99;.&#108;&#118;&#x40;&#103;&#109;&#97;&#x69;&#108;&#46;&#x63;&#x6f;&#109;">&#x6d;&#97;&#x78;.&#x63;&#x2e;&#108;v&#64;&#x67;&#109;&#x61;&#x69;&#108;&#x2e;&#99;&#111;&#109;</a></p> <p>Copyright (C) 2017 by Max Lv <a href="&#x6d;&#97;&#x69;&#108;&#116;&#111;&#x3a;&#x6d;&#97;x&#46;&#99;.&#108;&#118;&#x40;&#103;&#109;&#97;&#x69;&#108;&#46;&#x63;&#x6f;&#109;">&#x6d;&#97;&#x78;.&#x63;&#x2e;&#108;v&#64;&#x67;&#109;&#x61;&#x69;&#108;&#x2e;&#99;&#111;&#109;</a></p>
<p>Copyright (C) 2017 by Mygod Studio <a href="contact-shadowsocks-android@mygod.be">contact-shadowsocks-android@mygod.be</a></p> <p>Copyright (C) 2017 by Mygod Studio <a href="mailto:contact-shadowsocks-android@mygod.be">contact-shadowsocks-android@mygod.be</a></p>
<p>This program is free software: you can redistribute it and/or modify <p>This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
+3 -3
View File
@@ -44,8 +44,8 @@
<string name="auto_connect_summary">"システム起動時にバックグラウンドで本サービスを開始"</string> <string name="auto_connect_summary">"システム起動時にバックグラウンドで本サービスを開始"</string>
<string name="tcp_fastopen_summary">"使用するにはROOT権限が必要"</string> <string name="tcp_fastopen_summary">"使用するにはROOT権限が必要"</string>
<string name="tcp_fastopen_summary_unsupported">"ご利用のカーネルバージョンはサポートしておりません:%s &lt; 3.7.1"</string> <string name="tcp_fastopen_summary_unsupported">"ご利用のカーネルバージョンはサポートしておりません:%s &lt; 3.7.1"</string>
<string name="udp_dns">"UDP転送"</string> <string name="udp_dns">"DNS転送"</string>
<string name="udp_dns_summary">"UDPプロトコルでリモードサーバーにパケットを転送"</string> <string name="udp_dns_summary">"DNSプロトコルでリモードサーバーにパケットを転送"</string>
<!-- notification category --> <!-- notification category -->
<string name="forward_success">"バックグラウンドでサービスを開始しました"</string> <string name="forward_success">"バックグラウンドでサービスを開始しました"</string>
@@ -138,4 +138,4 @@
<string name="proxied_apps_summary_v21">"選択したアプリにプロキシを設定する"</string> <string name="proxied_apps_summary_v21">"選択したアプリにプロキシを設定する"</string>
<string name="acl_rule_templates_generic">"サブネット/ホストネームPCREパターン"</string> <string name="acl_rule_templates_generic">"サブネット/ホストネームPCREパターン"</string>
<string name="acl_rule_templates_domain">"ドメイン及びサブドメイン"</string> <string name="acl_rule_templates_domain">"ドメイン及びサブドメイン"</string>
</resources> </resources>
+3 -3
View File
@@ -52,8 +52,8 @@
<string name="auto_connect_summary">"Запускать Shadowsocks при включении"</string> <string name="auto_connect_summary">"Запускать Shadowsocks при включении"</string>
<string name="tcp_fastopen_summary">"Переключение требует наличия ROOT прав"</string> <string name="tcp_fastopen_summary">"Переключение требует наличия ROOT прав"</string>
<string name="tcp_fastopen_summary_unsupported">"Неподдерживаемая версия ядра: %s &lt; 3.7.1"</string> <string name="tcp_fastopen_summary_unsupported">"Неподдерживаемая версия ядра: %s &lt; 3.7.1"</string>
<string name="udp_dns">"Проброс UDP"</string> <string name="udp_dns">"Проброс DNS"</string>
<string name="udp_dns_summary">"Пробрасывать UDP пакеты на удалённый сервер"</string> <string name="udp_dns_summary">"Пробрасывать DNS пакеты на удалённый сервер"</string>
<!-- notification category --> <!-- notification category -->
<string name="forward_success">"Shadowsocks запущен."</string> <string name="forward_success">"Shadowsocks запущен."</string>
@@ -121,4 +121,4 @@
<string name="route_entry_bypass_lan_chn">"Обход LAN и Китай"</string> <string name="route_entry_bypass_lan_chn">"Обход LAN и Китай"</string>
<string name="route_entry_chinalist">"Список Китай"</string> <string name="route_entry_chinalist">"Список Китай"</string>
<string name="proxied_apps_summary_v21">"Установить прокси для выбранных приложений"</string> <string name="proxied_apps_summary_v21">"Установить прокси для выбранных приложений"</string>
</resources> </resources>
@@ -45,8 +45,8 @@
<string name="auto_connect_summary">"随系统启动后台服务"</string> <string name="auto_connect_summary">"随系统启动后台服务"</string>
<string name="tcp_fastopen_summary">"切换需要 ROOT 权限"</string> <string name="tcp_fastopen_summary">"切换需要 ROOT 权限"</string>
<string name="tcp_fastopen_summary_unsupported">"不支持的内核版本:%s &lt; 3.7.1"</string> <string name="tcp_fastopen_summary_unsupported">"不支持的内核版本:%s &lt; 3.7.1"</string>
<string name="udp_dns">"UDP 转发"</string> <string name="udp_dns">"DNS 转发"</string>
<string name="udp_dns_summary">"由远程服务器转发 UDP 协议的数据包"</string> <string name="udp_dns_summary">"由远程服务器转发 DNS 协议的数据包"</string>
<!-- notification category --> <!-- notification category -->
<string name="forward_success">"后台服务已开始运行。"</string> <string name="forward_success">"后台服务已开始运行。"</string>
@@ -140,4 +140,4 @@
<string name="proxied_apps_summary_v21">"为应用程序分别设置代理"</string> <string name="proxied_apps_summary_v21">"为应用程序分别设置代理"</string>
<string name="acl_rule_templates_generic">"子网/域名 PCRE 正则表达式"</string> <string name="acl_rule_templates_generic">"子网/域名 PCRE 正则表达式"</string>
<string name="acl_rule_templates_domain">"域名及其子域名"</string> <string name="acl_rule_templates_domain">"域名及其子域名"</string>
</resources> </resources>
@@ -44,8 +44,8 @@
<string name="auto_connect_summary">"在裝置啟動時啟用 Shadowsocks"</string> <string name="auto_connect_summary">"在裝置啟動時啟用 Shadowsocks"</string>
<string name="tcp_fastopen_summary">"切換需要 ROOT 權限"</string> <string name="tcp_fastopen_summary">"切換需要 ROOT 權限"</string>
<string name="tcp_fastopen_summary_unsupported">"不支援的核心版本:%s &lt; 3.7.1"</string> <string name="tcp_fastopen_summary_unsupported">"不支援的核心版本:%s &lt; 3.7.1"</string>
<string name="udp_dns">"UDP 轉送"</string> <string name="udp_dns">"DNS 轉送"</string>
<string name="udp_dns_summary">"向遠端轉送 UDP 封包"</string> <string name="udp_dns_summary">"向遠端轉送 DNS 封包"</string>
<!-- notification category --> <!-- notification category -->
<string name="forward_success">"Shadowsocks 已啟動。"</string> <string name="forward_success">"Shadowsocks 已啟動。"</string>
@@ -139,4 +139,4 @@
<string name="proxied_apps_summary_v21">"為已選擇的應用程式設定 Proxy"</string> <string name="proxied_apps_summary_v21">"為已選擇的應用程式設定 Proxy"</string>
<string name="acl_rule_templates_generic">"子網路/主機名稱 PCRE 模式"</string> <string name="acl_rule_templates_generic">"子網路/主機名稱 PCRE 模式"</string>
<string name="acl_rule_templates_domain">"網域及其所有子網域"</string> <string name="acl_rule_templates_domain">"網域及其所有子網域"</string>
</resources> </resources>
+2 -2
View File
@@ -53,8 +53,8 @@
<string name="auto_connect_summary">Enable Shadowsocks on startup</string> <string name="auto_connect_summary">Enable Shadowsocks on startup</string>
<string name="tcp_fastopen_summary">Toggling requires ROOT permission</string> <string name="tcp_fastopen_summary">Toggling requires ROOT permission</string>
<string name="tcp_fastopen_summary_unsupported">Unsupported kernel version: %s &lt; 3.7.1</string> <string name="tcp_fastopen_summary_unsupported">Unsupported kernel version: %s &lt; 3.7.1</string>
<string name="udp_dns">UDP Forwarding</string> <string name="udp_dns">DNS Forwarding</string>
<string name="udp_dns_summary">Forward UDP packets to remote</string> <string name="udp_dns_summary">Force to forward DNS packets to remote</string>
<!-- notification category --> <!-- notification category -->
<string name="forward_success">Shadowsocks started.</string> <string name="forward_success">Shadowsocks started.</string>
@@ -159,13 +159,12 @@ class ShadowsocksVpnService extends VpnService with BaseService {
def startShadowsocksDaemon() { def startShadowsocksDaemon() {
val cmd = ArrayBuffer[String](getApplicationInfo.nativeLibraryDir + "/libss-local.so", val cmd = ArrayBuffer[String](getApplicationInfo.nativeLibraryDir + "/libss-local.so",
"-V", "-V",
"-u",
"-b", "127.0.0.1", "-b", "127.0.0.1",
"-l", profile.localPort.toString, "-l", profile.localPort.toString,
"-t", "600", "-t", "600",
"-c", buildShadowsocksConfig("ss-local-vpn.conf")) "-c", buildShadowsocksConfig("ss-local-vpn.conf"))
if (profile.udpdns) cmd += "-u"
if (profile.route != Acl.ALL) { if (profile.route != Acl.ALL) {
cmd += "--acl" cmd += "--acl"
cmd += Acl.getFile(profile.route).getAbsolutePath cmd += Acl.getFile(profile.route).getAbsolutePath
@@ -242,9 +241,9 @@ class ShadowsocksVpnService extends VpnService with BaseService {
if (profile.ipv6) if (profile.ipv6)
cmd += ("--netif-ip6addr", PRIVATE_VLAN6.formatLocal(Locale.ENGLISH, "2")) cmd += ("--netif-ip6addr", PRIVATE_VLAN6.formatLocal(Locale.ENGLISH, "2"))
if (profile.udpdns) cmd += "--enable-udprelay"
cmd += "--enable-udprelay"
else if (!profile.udpdns)
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))
@@ -98,7 +98,8 @@ class Profile {
.scheme("ss") .scheme("ss")
.encodedAuthority("%s@%s:%d".formatLocal(Locale.ENGLISH, .encodedAuthority("%s@%s:%d".formatLocal(Locale.ENGLISH,
Base64.encodeToString("%s:%s".formatLocal(Locale.ENGLISH, method, password).getBytes, Base64.encodeToString("%s:%s".formatLocal(Locale.ENGLISH, method, password).getBytes,
Base64.NO_PADDING | Base64.NO_WRAP | Base64.URL_SAFE), host, remotePort)) Base64.NO_PADDING | Base64.NO_WRAP | Base64.URL_SAFE),
if (host.contains(':')) '[' + host + ']' else host, remotePort))
val configuration = new PluginConfiguration(plugin) val configuration = new PluginConfiguration(plugin)
if (configuration.selected.nonEmpty) if (configuration.selected.nonEmpty)
builder.appendQueryParameter(Key.plugin, configuration.selectedOptions.toString(false)) builder.appendQueryParameter(Key.plugin, configuration.selectedOptions.toString(false))
@@ -20,13 +20,15 @@
package com.github.shadowsocks.utils package com.github.shadowsocks.utils
import java.net.URI
import android.net.Uri import android.net.Uri
import android.util.{Base64, Log} import android.util.{Base64, Log}
import com.github.shadowsocks.database.Profile import com.github.shadowsocks.database.Profile
object Parser { object Parser {
val TAG = "ShadowParser" val TAG = "ShadowParser"
private val pattern = "(?i)ss://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]".r private val pattern = "(?i)ss://[-a-zA-Z0-9+&@#/%?=~_|!:,.;\\[\\]]*[-a-zA-Z0-9+&@#/%=~_|\\[\\]]".r
private val userInfoPattern = "^(.+?):(.*)$".r private val userInfoPattern = "^(.+?):(.*)$".r
private val legacyPattern = "^(.+?):(.*)@(.+?):(\\d+?)$".r private val legacyPattern = "^(.+?):(.*)@(.+?):(\\d+?)$".r
@@ -54,8 +56,12 @@ object Parser {
val profile = new Profile val profile = new Profile
profile.method = method profile.method = method
profile.password = password profile.password = password
profile.host = uri.getHost // bug in Android: https://code.google.com/p/android/issues/detail?id=192855
profile.remotePort = uri.getPort val javaURI = new URI(m.matched)
profile.host = javaURI.getHost
if (profile.host.headOption.contains('[') && profile.host.lastOption.contains(']'))
profile.host = profile.host.substring(1, profile.host.length - 1)
profile.remotePort = javaURI.getPort
profile.plugin = uri.getQueryParameter(Key.plugin) profile.plugin = uri.getQueryParameter(Key.plugin)
profile.name = uri.getFragment profile.name = uri.getFragment
profile profile