I'm trying to implement simple Android firewall app through VPN service.
Basic scheme looks like this:
I'm trying to simply forward packets through my VPN service. So I've started with implementing ToyVpn Google example (time to time taking a glance at this example) for my purposes, but it's not working: when my VPN is running I see that packets are sent, but I've got no response.
App is written on Kotlin, but it's not complicated for Java lovers.
My Builder is configured with IP and route as shown below:
val builder = Builder()
builder.addAddress("10.0.0.2", 32).addRoute("0.0.0.0", 0)
mInterface = builder.establish()
After that I'm setting a tunnel a way it's shown in ToyVpn, but my VPN server destination IP address is local:
val tunnel = DatagramChannel.open()
if (!protect(tunnel.socket())) {
throw IllegalStateException("Cannot protect the tunnel");
}
tunnel.connect(InetSocketAddress("127.0.0.1", 55555))
tunnel.configureBlocking(false)
protect(tunnel.socket())
After that I'm trying to forward packets from in
and out
FileInputStream's (also taken from ToyVpn):
val `in` = FileInputStream(mInterface!!.fileDescriptor)
val out = FileOutputStream(mInterface!!.fileDescriptor)
var timer = 0
while (true) {
var idle = true
var length = `in`.read(packet.array())
if (length > 0) {
packet.limit(length)
tunnel.write(packet);
packet.clear()
idle = false
if (timer < 1) {
timer = 1
}
}
length = tunnel.read(packet)
if (length > 0) {
if (packet.get(0).toInt() !== 0) {
out.write(packet.array(), 0, length)
}
packet.clear()
idle = false
if (timer > 0) {
timer = 0
}
}
if (idle) {
Thread.sleep(100)
timer += if (timer > 0) 100 else -100
if (timer < -15000) {
packet.put(0.toByte()).limit(1)
for (i in 0..2) {
packet.position(0)
tunnel.write(packet)
}
packet.clear()
timer = 1
}
if (timer > 20000) {
throw IllegalStateException("Timed out")
}
}
Thread.sleep(50)
}
My first question: What am I doing wrong? The code is clear and should work properly, but it does not!
Basicly I want my service to fitler packets by IP address. I know that huge apps like tPacketCapture parse packets from the scratch and than reconstruct them.
My second question: Is there a way to make packet filtering simplier if I want to fetch only the IP address?
P.S.: Actualy I've already asked a similar question about it here a few days ago, but error had another nature related to Kotlin language, which app is developed on. Also I've seen this and this questions, but the answers there didn't help me.