我正在探索Android的VpnService的功能。目前,我通过在用户空间中重建IP堆栈来构建了一个非常基本的请求转发器:我从VpnService的输入流中读取IP数据包,对其进行解析,对于我不希望转发的连接,我尝试重新创建这些数据包。 VPN连接之外的套接字连接。
我知道VpnService.protect()
可以帮助实现这一点,并尝试按以下方式实现它:
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
不幸的是,这种方法导致环回VPN接口(interface)。
上面的代码只会阻塞并最终超时,我通过从一个单独的线程调用
Socket.connect(InetSocketAddress)
来观察回送;连接直接返回到我的VpnService的输入流中,然后重复该过程。不用说,这会导致循环。我感到这样做的原因是,在创建套接字(以及随后的对
VpnService.protect(Socket)
的调用)时,我尚未设置目标IP和端口。似乎确实是这种情况,因为通过在我的VpnService实现中重写
VpnService.protect(Socket)
和VpnService.protect(int)
并在两种情况下调用super都返回false。如何正确保护套接字连接?
最佳答案
以下代码有效。
Socket socket = SocketChannel.open().socket();
if ((null != socket) && (null != vpnService)) {
vpnService.protect(socket);
}
socket.connect(...);
new Socket()没有有效的文件描述符,因此无法受到保护。