diff --git a/src/main/assets/arm/shadowsocks b/src/main/assets/arm/shadowsocks index 6cb0d5de..d8ae6178 100755 Binary files a/src/main/assets/arm/shadowsocks and b/src/main/assets/arm/shadowsocks differ diff --git a/src/main/assets/arm/tun2socks b/src/main/assets/arm/tun2socks index 1e371a2e..3f4e0967 100755 Binary files a/src/main/assets/arm/tun2socks and b/src/main/assets/arm/tun2socks differ diff --git a/src/main/assets/pdnsd.conf b/src/main/assets/pdnsd.conf index 54cb208a..79ca809d 100644 --- a/src/main/assets/pdnsd.conf +++ b/src/main/assets/pdnsd.conf @@ -1,8 +1,8 @@ global { perm_cache = 2048; cache_dir = "/data/data/com.github.shadowsocks"; - server_ip = 127.0.0.1; - server_port = 8153; + server_ip = 0.0.0.0; + server_port = 8153; query_method = tcp_only; run_ipv4 = on; min_ttl = 15m; diff --git a/src/main/assets/x86/shadowsocks b/src/main/assets/x86/shadowsocks index b1833a2e..f738a395 100755 Binary files a/src/main/assets/x86/shadowsocks and b/src/main/assets/x86/shadowsocks differ diff --git a/src/main/assets/x86/tun2socks b/src/main/assets/x86/tun2socks index 1fab6e3e..f8423e66 100755 Binary files a/src/main/assets/x86/tun2socks and b/src/main/assets/x86/tun2socks differ diff --git a/src/main/jni/badvpn/tun2socks/tun2socks.c b/src/main/jni/badvpn/tun2socks/tun2socks.c index d4b41466..c6d0de5b 100644 --- a/src/main/jni/badvpn/tun2socks/tun2socks.c +++ b/src/main/jni/badvpn/tun2socks/tun2socks.c @@ -209,8 +209,8 @@ LinkedList1 tcp_clients; int num_clients; #ifdef ANDROID -// IP address of dnsgw -BIPAddr dnsgw; +// Address of dnsgw +BAddr dnsgw; #endif static void terminate (void); @@ -897,20 +897,6 @@ int process_arguments (void) { ASSERT(!password_file_contents) -#ifdef ANDROID - // resolve dnsgw ipaddr - if (options.dnsgw) { - if (!BIPAddr_Resolve(&dnsgw, options.dnsgw, 0)) { - BLog(BLOG_ERROR, "dnsgw ipaddr: BIPAddr_Resolve failed"); - return 0; - } - if (dnsgw.type != BADDR_TYPE_IPV4) { - BLog(BLOG_ERROR, "dnsgw ipaddr: must be an IPv4 address"); - return 0; - } - } -#endif - // resolve netif ipaddr if (!BIPAddr_Resolve(&netif_ipaddr, options.netif_ipaddr, 0)) { BLog(BLOG_ERROR, "netif ipaddr: BIPAddr_Resolve failed"); @@ -977,6 +963,20 @@ int process_arguments (void) return 0; } } + +#ifdef ANDROID + // resolve dnsgw ipaddr + if (options.dnsgw) { + if (!BAddr_Parse2(&dnsgw, options.dnsgw, NULL, 0, 0)) { + BLog(BLOG_ERROR, "dnsgw addr: BAddr_Parse2 failed"); + return 0; + } + if (dnsgw.type != BADDR_TYPE_IPV4) { + BLog(BLOG_ERROR, "dnsgw addr: must be an IPv4 address"); + return 0; + } + } +#endif return 1; } @@ -1227,11 +1227,12 @@ int process_device_dns_packet (uint8_t *data, int data_len) } // build IP header - ipv4_header.destination_address = dnsgw.ipv4; + ipv4_header.destination_address = dnsgw.ipv4.ip; ipv4_header.checksum = hton16(0); ipv4_header.checksum = ipv4_checksum(&ipv4_header, NULL, 0); // build UDP header + udp_header.dest_port = hton16(dnsgw.ipv4.port); udp_header.checksum = hton16(0); udp_header.checksum = udp_checksum(&udp_header, data, data_len, ipv4_header.source_address, ipv4_header.destination_address); diff --git a/src/main/scala/com/github/shadowsocks/ShadowVpnService.scala b/src/main/scala/com/github/shadowsocks/ShadowVpnService.scala index f8fd30b5..f5818381 100644 --- a/src/main/scala/com/github/shadowsocks/ShadowVpnService.scala +++ b/src/main/scala/com/github/shadowsocks/ShadowVpnService.scala @@ -50,6 +50,7 @@ import android.net.VpnService import org.apache.http.conn.util.InetAddressUtils import android.os.Message import scala.Some +import scala.concurrent.ops._ object ShadowVpnService { def isServiceStarted(context: Context): Boolean = { @@ -136,18 +137,20 @@ class ShadowVpnService extends VpnService { } def startShadowsocksDaemon() { - new Thread { - override def run() { - val cmd: String = (BASE + - "shadowsocks -s \"%s\" -p \"%d\" -l \"%d\" -k \"%s\" -m \"%s\" -f " + - BASE + - "shadowsocks.pid") - .format(config.proxy, config.remotePort, config.localPort, config.sitekey, - config.encMethod) - Log.d(TAG, cmd) - System.exec(cmd) - } - }.start() + spawn { + val cmd: String = (BASE + + "shadowsocks -s \"%s\" -p \"%d\" -l \"%d\" -k \"%s\" -m \"%s\" -f " + + BASE + + "shadowsocks.pid") + .format(config.proxy, config.remotePort, config.localPort, config.sitekey, config.encMethod) + Log.d(TAG, cmd) + System.exec(cmd) + } + } + + def startDnsDaemon() { + val cmd: String = BASE + "pdnsd -c " + BASE + "pdnsd.conf" + Utils.runCommand(cmd) } def getVersionName: String = { @@ -182,43 +185,41 @@ class ShadowVpnService extends VpnService { config = Extra.get(intent) - new Thread(new Runnable { - def run() { - killProcesses() + spawn { + killProcesses() - // Resolve server address - var resolved: Boolean = false - if (!InetAddressUtils.isIPv4Address(config.proxy) && - !InetAddressUtils.isIPv6Address(config.proxy)) { - Utils.resolve(config.proxy, enableIPv6 = true) match { - case Some(addr) => - config.proxy = addr - resolved = true - case None => resolved = false - } - } else { - resolved = true + // Resolve server address + var resolved: Boolean = false + if (!InetAddressUtils.isIPv4Address(config.proxy) && + !InetAddressUtils.isIPv6Address(config.proxy)) { + Utils.resolve(config.proxy, enableIPv6 = true) match { + case Some(addr) => + config.proxy = addr + resolved = true + case None => resolved = false } - - // Resolve UDP gateway - if (resolved) { - Utils.resolve("u.maxcdn.info", enableIPv6 = false) match { - case Some(host) => udpgw = host - case None => resolved = false - } - } - - if (resolved && handleConnection) { - handler.sendEmptyMessageDelayed(MSG_CONNECT_SUCCESS, 300) - } else { - notifyAlert(getString(R.string.forward_fail), getString(R.string.service_failed)) - handler.sendEmptyMessageDelayed(MSG_CONNECT_FAIL, 300) - handler.sendEmptyMessageDelayed(MSG_STOP_SELF, 500) - } - handler.sendEmptyMessageDelayed(MSG_CONNECT_FINISH, 300) + } else { + resolved = true } - }).start() + + // Resolve UDP gateway + if (resolved) { + Utils.resolve("u.maxcdn.info", enableIPv6 = false) match { + case Some(host) => udpgw = host + case None => resolved = false + } + } + + if (resolved && handleConnection) { + handler.sendEmptyMessageDelayed(MSG_CONNECT_SUCCESS, 300) + } else { + notifyAlert(getString(R.string.forward_fail), getString(R.string.service_failed)) + handler.sendEmptyMessageDelayed(MSG_CONNECT_FAIL, 300) + handler.sendEmptyMessageDelayed(MSG_STOP_SELF, 500) + } + handler.sendEmptyMessageDelayed(MSG_CONNECT_FINISH, 300) + } } def waitForProcess(name: String): Boolean = { @@ -310,19 +311,21 @@ class ShadowVpnService extends VpnService { val cmd = (BASE + "tun2socks --netif-ipaddr %s " - + "--udpgw-remote-server-addr %s:7300 " + // + "--udpgw-remote-server-addr %s:7300 " + + "--dnsgw 127.0.0.1:8153 " + "--netif-netmask 255.255.255.0 " + "--socks-server-addr 127.0.0.1:%d " + "--tunfd %d " + "--tunmtu %d " + "--pid %stun2socks.pid") - .format(localAddress.format(2), udpgw, config.localPort, fd, VPN_MTU, BASE) + .format(localAddress.format(2), config.localPort, fd, VPN_MTU, BASE) Log.d(TAG, cmd) System.exec(cmd) } /** Called when the activity is first created. */ def handleConnection: Boolean = { + startDnsDaemon() startShadowsocksDaemon() startVpn() true @@ -384,11 +387,9 @@ class ShadowVpnService extends VpnService { unregisterReceiver(receiver) receiver = null } - new Thread { - override def run() { - killProcesses() - } - }.start() + spawn { + killProcesses() + } if (conn != null) { conn.close() conn = null