Protect a socket in VpnService
android, android-4.0-ice-cream-sandwich, packet-capture, sockets, vpn
Solution
The following code works.
Socket socket = SocketChannel.open().socket();
if ((null != socket) && (null != vpnService)) {
vpnService.protect(socket);
}
socket.connect(...);
new Socket() doesn't have a valid file descriptor, so it cannot be protected.
Problem
I'm exploring the capabilities of Android's VpnService. Presently, I've built a very rudimentary request forwarder by essentially rebuilding the IP stack in user space: I read IP packets from the VpnService's input stream, parse them, and for connections I don't want to forward, I attempt to recreate those socket connections outside the VPN connection. I've understood that this last bit is facilitated by `VpnService.protect()` and have tried implementing it as follows: ``` Socket socket = new Socket(); vpnService.protect(socket); socket.connect(new InetSocketAddress( header.getDestinationAddress(), // From my IP datagram header body.getDestinationPort())); // From the TCP datagram header ``` Unfortunately, this approach is causing a loopback into the VPN interface. Whereas the above code will simply block and eventually time out, I observe the loopback by calling `Socket.connect(InetSocketAddress)` from a separate thread; the connection comes straight back into my VpnService's input stream and the process repeats. Needless to say, this causes a loop. I get the feeling that the reason for this is that at the time of socket creation (and subsequently, the call to `VpnService.protect(Socket)`), I haven't set the destination IP & port yet. This seems to indeed be the case, as the by overriding `VpnService.protect(Socket)` and `VpnService.protect(int)` in my VpnService implementation and calling the supers in both cases returns false. How can I properly protect a socket connection?