Skip to content

Commit

Permalink
nat mode ok
Browse files Browse the repository at this point in the history
  • Loading branch information
KagayamaKaede committed Nov 17, 2015
1 parent 96c9ffb commit 7147aaa
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 49 deletions.
53 changes: 37 additions & 16 deletions app/src/main/java/com/proxy/shadowsocksr/SSRNatService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import android.util.Log
import android.util.SparseArray
import com.proxy.shadowsocksr.impl.SSRLocal
import com.proxy.shadowsocksr.impl.SSRTunnel
import com.proxy.shadowsocksr.impl.UDPRelayServer
import com.proxy.shadowsocksr.items.ConnectProfile
import com.proxy.shadowsocksr.util.*
import java.io.File
Expand All @@ -35,6 +36,7 @@ class SSRNatService : Service()

private var local: SSRLocal? = null
private var tunnel: SSRTunnel? = null
private var udprs: UDPRelayServer? = null

private var connProfile: ConnectProfile? = null
@Volatile private var isNATConnected = false
Expand Down Expand Up @@ -136,20 +138,19 @@ class SSRNatService : Service()
return true;
}

@Throws(Exception::class)
private fun copyDaemonBin(file: String, out: File): Boolean
{
val am: AssetManager = assets;
val abi: String = Jni.getABI();
val buf: ByteArray = ByteArray(
1024 * 32);//most tf card have 16k or 32k logic unit size, may be 32k buffer is better
try
{
var create = out.createNewFile();
if (!create)
if (!out.createNewFile())
{
throw IOException("Create File Failed!");
}
val fis = am.open(abi + File.separator + file);
val fis = assets.open(abi + File.separator + file);
val fos = FileOutputStream(out);
var length: Int = fis.read(buf);
while (length > 0)
Expand Down Expand Up @@ -271,11 +272,20 @@ class SSRNatService : Service()

private fun startTunnel()
{
tunnel = SSRTunnel(connProfile!!.server, "127.0.0.1", "8.8.8.8",
connProfile!!.remotePort, 8163, 53, connProfile!!.cryptMethod,
connProfile!!.tcpProtocol, connProfile!!.obfsMethod,
connProfile!!.obfsParam, connProfile!!.passwd, false)
tunnel!!.start()
if (connProfile!!.dnsForward)
{
udprs = UDPRelayServer(connProfile!!.server, "127.0.0.1", connProfile!!.remotePort,
8153, true, false, connProfile!!.cryptMethod, connProfile!!.passwd, "8.8.8.8",
53)
}
else
{
tunnel = SSRTunnel(connProfile!!.server, "127.0.0.1", "8.8.8.8",
connProfile!!.remotePort, 8163, 53, connProfile!!.cryptMethod,
connProfile!!.tcpProtocol, connProfile!!.obfsMethod,
connProfile!!.obfsParam, connProfile!!.passwd, false)
}
if (udprs == null) tunnel!!.start() else udprs!!.start()
}

private fun startDnsDaemon()
Expand Down Expand Up @@ -321,6 +331,11 @@ class SSRNatService : Service()
tunnel!!.stopTunnel()
tunnel = null
}
if (udprs != null)
{
udprs!!.stopUDPRelayServer()
udprs = null
}
try
{
android.os.Process.killProcess(pdnsdPID)
Expand Down Expand Up @@ -371,11 +386,10 @@ class SSRNatService : Service()
try
{
val ai = pm.getApplicationInfo(app, PackageManager.GET_ACTIVITIES)
Log.e("EXC","${ai.uid}")
Log.e("EXC", "${ai.uid}")
uidSet.add(ai.uid)
http_sb.add(
(CommonUtils.iptables + CMD_IPTABLES_DNAT_ADD_SOCKS).replace("-t nat",
"-t nat -m owner --uid-owner ${ai.uid}"))
http_sb.add((CommonUtils.iptables + CMD_IPTABLES_DNAT_ADD_SOCKS)
.replace("-t nat", "-t nat -m owner --uid-owner ${ai.uid}"))
}
catch(ignored: Exception)
{
Expand Down Expand Up @@ -426,8 +440,8 @@ class SSRNatService : Service()
//
flushDns()
//
val open = PendingIntent.getActivity(this@SSRNatService, -1, Intent(
this@SSRNatService, MainActivity::class.java), 0)
val open = PendingIntent.getActivity(this@SSRNatService, -1,
Intent(this@SSRNatService, MainActivity::class.java), 0)
val notificationBuilder = NotificationCompat.Builder(this@SSRNatService)
notificationBuilder
.setWhen(0)
Expand Down Expand Up @@ -463,7 +477,14 @@ class SSRNatService : Service()
{
stopSelf()
}

ShellUtil().runCmd(arrayOf("rm -f ${Consts.baseDir}pdnsd-nat.conf",
"rm -f ${Consts.baseDir}redsocks-nat.conf"));
stopForeground(true)
}

override fun onDestroy()
{
stopRunner()
super.onDestroy()
}
}
8 changes: 5 additions & 3 deletions app/src/main/java/com/proxy/shadowsocksr/SSRVPNService.java
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ private void startSSRDaemon()
connProfile.getLocalPort(), connProfile.getPasswd(),
connProfile.getCryptMethod(), connProfile.getTcpProtocol(),
connProfile.getObfsMethod(), connProfile.getObfsParam(),
true,aclList);
true, aclList);

local.setOnNeedProtectTCPListener(this);
local.start();
Expand All @@ -375,18 +375,20 @@ private void startSSRDaemon()
{
udprs = new UDPRelayServer(connProfile.getServer(), "127.0.0.1",
connProfile.getRemotePort(), connProfile.getLocalPort(),
connProfile.getCryptMethod(), connProfile.getPasswd());
false, true, connProfile.getCryptMethod(),
connProfile.getPasswd(), null, null);
udprs.setOnNeedProtectUDPListener(this);
udprs.start();
}
}

private void startDnsTunnel()
{

tunnel = new SSRTunnel(connProfile.getServer(), "127.0.0.1", "8.8.8.8",
connProfile.getRemotePort(), 8163, 53, connProfile.getCryptMethod(),
connProfile.getTcpProtocol(), connProfile.getObfsMethod(),
connProfile.getObfsParam(), connProfile.getPasswd(),true);
connProfile.getObfsParam(), connProfile.getPasswd(), true);

tunnel.setOnNeedProtectTCPListener(this);
tunnel.start();
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/com/proxy/shadowsocksr/impl/SSRTunnel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class SSRTunnel(private val remoteIP: String, private val localIP: String, dnsIP
{
private var ssc: ServerSocketChannel? = null

private var dnsIp: ByteArray? = null
private var dnsIp: ByteArray?=null

private var localThreadPool: ExecutorService? = null
private var remoteThreadPool: ExecutorService? = null
Expand Down
102 changes: 73 additions & 29 deletions app/src/main/java/com/proxy/shadowsocksr/impl/UDPRelayServer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,18 @@ import android.util.LruCache
import com.proxy.shadowsocksr.impl.interfaces.OnNeedProtectUDPListener

import java.io.IOException
import java.net.InetAddress
import java.net.InetSocketAddress
import java.net.SocketAddress
import java.net.UnknownHostException
import java.nio.ByteBuffer
import java.nio.channels.DatagramChannel
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors

class UDPRelayServer(private val remoteIP: String, private val localIP: String, private val remotePort: Int, private val localPort: Int,
cryptMethod: String, pwd: String) : Thread()
private val isTunnelMode: Boolean, private val isVPNMode: Boolean,
cryptMethod: String, pwd: String, dnsIp: String?, dnsPort: Int?) : Thread()
{
private var udpServer: DatagramChannel? = null
private var isaLocal: InetSocketAddress? = null
Expand All @@ -28,13 +31,27 @@ class UDPRelayServer(private val remoteIP: String, private val localIP: String,

private val cache: LruCache<SocketAddress, UDPRemoteDataHandler>

private var dnsIp: ByteArray? = null
private var dnsPort: Int? = null

private var onNeedProtectUDPListener: OnNeedProtectUDPListener? = null

init
{
cache = LruCache<SocketAddress, UDPRemoteDataHandler>(64)
crypto = UDPEncryptor(pwd, cryptMethod)
ivLen = crypto.ivLen
if (isTunnelMode)
{
try
{
this.dnsIp = InetAddress.getByName(dnsIp).address
}
catch (ignored: UnknownHostException)
{
}
this.dnsPort = dnsPort
}
}

fun setOnNeedProtectUDPListener(onNeedProtectUDPListener: OnNeedProtectUDPListener)
Expand Down Expand Up @@ -93,26 +110,46 @@ class UDPRelayServer(private val remoteIP: String, private val localIP: String,
val localAddress = udpServer!!.receive(buf)
//
buf.flip()
//
val dataLocalIn: ByteArray
val rcnt = buf.limit()
if (rcnt < 8)
{
Log.e("EXC", "LOCAL RECV SMALL PKG")
buf.clear()//not response small package
continue
}
//
if (!(buf.get().toInt() == 0 && //RSV
buf.get().toInt() == 0 && //RSV
buf.get().toInt() == 0))
//FRAG
if (isTunnelMode)
{ //direct build target dns server socks5 request pkg
if (rcnt < 12)
{
Log.e("EXC", "LOCAL RECV SMALL PKG")
buf.clear()//not response small package
continue
}
dataLocalIn = ByteArray(7 + rcnt)
dataLocalIn[0] = 1
System.arraycopy(dnsIp, 0, dataLocalIn, 1, 4)
dataLocalIn[5] = ((dnsPort!!.shr(8)) and 0xFF).toByte()
dataLocalIn[6] = (dnsPort!!.and(0xFF)).toByte()
buf.get(dataLocalIn, 7, dataLocalIn.size)
}
else
{
Log.e("EXC", "LOCAL RECV NOT SOCKS5 UDP PKG")
buf.clear()
continue
if (rcnt < 8)
{
Log.e("EXC", "LOCAL RECV SMALL PKG")
buf.clear()//not response small package
continue
}
//
if (!(buf.get().toInt() == 0 && //RSV
buf.get().toInt() == 0 && //RSV
buf.get().toInt() == 0)) //FRAG
{
Log.e("EXC", "LOCAL RECV NOT SOCKS5 UDP PKG")
buf.clear()
continue
}
//
dataLocalIn = ByteArray(rcnt - 3)
buf.get(dataLocalIn)
}
//
val dataLocalIn = ByteArray(rcnt - 3)
buf.get(dataLocalIn)
val dataRemoteOut = crypto.encrypt(dataLocalIn)
//
var handler: UDPRemoteDataHandler? = cache.get(localAddress)
Expand All @@ -121,19 +158,28 @@ class UDPRelayServer(private val remoteIP: String, private val localIP: String,
val remoteChannel = DatagramChannel.open()
remoteChannel.configureBlocking(true)
remoteChannel.connect(isaRemote)
val isProtected = onNeedProtectUDPListener!!.onNeedProtectUDP(
remoteChannel.socket())
if (isProtected)
if (isVPNMode)
{
val isProtected = onNeedProtectUDPListener!!.onNeedProtectUDP(
remoteChannel.socket())
if (isProtected)
{
handler = UDPRemoteDataHandler(localAddress, remoteChannel)
cache.put(localAddress, handler)
exec!!.execute(handler)
}
else
{
buf.clear()
continue
}
}
else
{ //Nat mode need not protect
handler = UDPRemoteDataHandler(localAddress, remoteChannel)
cache.put(localAddress, handler)
exec!!.execute(handler)
}
else
{
buf.clear()
continue
}
}
handler.remoteChannel!!.write(ByteBuffer.wrap(dataRemoteOut))
//
Expand All @@ -152,8 +198,6 @@ class UDPRelayServer(private val remoteIP: String, private val localIP: String,
catch (ignored: Exception)
{
}

buf.clear()
}
}

Expand All @@ -170,7 +214,8 @@ class UDPRelayServer(private val remoteIP: String, private val localIP: String,
while (isRunning)
{
val rcnt = remoteChannel!!.read(remoteReadBuf)
if (rcnt < ivLen + 8)
//
if (rcnt < ivLen + 1)
{
remoteReadBuf.clear()//not response small package, just drop.
continue
Expand All @@ -197,7 +242,6 @@ class UDPRelayServer(private val remoteIP: String, private val localIP: String,
catch (ignored: IOException)
{
}

remoteChannel = null
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ redsocks {
port = %d;
type = socks5;
}
"""
@JvmStatic const val PdNSdLocal = """global {
perm_cache = 2048;
Expand Down

0 comments on commit 7147aaa

Please sign in to comment.