There has to be a name apart from “procrastination” for the phenomena that makes you delaying writing up a post. Time multiplies exponentially under the thrust of accomplishing more so that can also be included in the write up.
Anyways, in the last post we left our project at an interesting point where we got to know that File Descriptors of the VPN may not let us capture the entire traffic on device and we did not want to do it the proxy server way. So, what next?
Good news is that we were able to capture the device traffic using VPN.
What we did is essentially fitting the VPN to capture the device traffic rather than adding a proxy manually or programmatically using root.
My first attempt was to connect VPN to a nanohttpd server, but then I found that was not needed.
Make a tunnel to connect to any random port and configure the VPN to get the ParcelFileDescriptor.
Builder builder = new Builder(); builder = new Builder(); builder.setMtu(1500); builder.addAddress("10.0.0.2", 24); builder.addRoute("0.0.0.0", 0); mInterface = builder.establish();
This helps us capturing the traffic and we got packets like this one:
Now what? We needed to make sense of this packet, so we extracted crucial details from it and got something like this:
Cool! So we have the requested traffic but now how to fulfill the requests? Where should we direct them to and how should we connect to the internet to get them addressed?
We employed simple JAVA sockets to accomplish this task. If you rightly remember, we had a proxy server which was responsible for listening to incoming requests and fulfilling them using ProxyConnectionHandler and then writing back to output.
But what is the nature of these incoming requests? Here comes an interesting fact that has to do with the OSI layers.
The request we got at the proxy server end were like these:
This is a typical HTTP request with following structure:
While the one we receive from VPN interface file descriptor are purely the IP packets.
Now comes the interesting part, and the mistakes made.
Here is what I was trying to do: What VPN essentially done is it creates a tunnel, that directs all network traffic of the device to that tunnel. The VPN interface is essentially a parcel file descriptor and one can use FileInputStream and FileOutputStream to write in /out the file descriptor.
The intention was to direct the packets received from the fd(file descriptor) straight away to the proxy server(we used before) by using JAVA sockets. And from that proxy server the rest of the logic will follow. But the things we now observe were rather interesting.
- The requests entered into a loop. Here’s how: You trace the requests by setting up VPN on the device, now you want to fulfill these requests so you pass them to proxy server that in turn tries to make connection to the URL host, but now since the entire device is under VPN enabled network, these requests also get passed to the VPN interface and the loop continues, in short there was no way to reach to the internet out there in that scenario.
Solution: Protect the socket from VPN! Yes, we can do that using VpnService.protect(socket). So now only this socket gets out of the VPN control and can connect to the underlying network.
2. We saw certain packets coming across this socket now(that is protected) but still no rendering, why?
Reason might be the OSI layers we are operating into here. We captured the IP packets , however for transmission over sockets, we need TCP/UDP so we need to form the packet properly, may be add the required headers.
Until that is done, the packet will remain malformed and could not be responded well by the hosts. How that is to be done is still my quest though.
The third thing that might turn up is writing these requests back to the File Descriptor. So, essentially, these things were done internally by the device when we added a proxy server manually, making the packets ready for transmission over sockets, but presently we are one layer deeper and need to add the requisite to come to the layer sockets operate at.
Another interesting aspect I am pondering on presently is how to track from which app the traffic is coming. Let’s see how it turns out to be.
Too much for a post? May be 😛 Lemme add some music. This time we have FIFA 2016 tracks.
So, see you in the next post, will make it sooner, till then keep exploring 🙂