VPN Service 运行在 IP 层。它创建了一个虚拟的网络接口，可以配置地址和路由规则，并返回一个 file descriptor。每次读这个 fp 返回一个数据包，每次写发送一个数据包。
establish()。前者接受用户响应并关闭其他应用的 VPN 链接，后者使用
VpnService.Builder 的参数创建 VPN 接口。
实现 VpnService 的类必须在 manifest 中声明：
<service android:name=".ExampleVpnService" android:permission="android.permission.BIND_VPN_SERVICE"> <intent-filter> <action android:name="android.net.VpnService"/> </intent-filter> </service>
Your VPN will need to create a new socket, protect the socket from being routed back into the VPN using
VpnService.protect(Socket), and connect the socket to 10.162.1.2. Having set up a tunnel connection to the VPN server, you should proceed to writing the input stream of the VpnService's interface into the tunnel's output stream, and in turn write the tunnel response back into the interface output stream.
Incoming and outgoing streams of the VpnService are in the network layer( layer); you are receiving (and should in turn be transmitting) raw IP packets, as you describe in your question.
also check out the OSI model and IP header format on WikiPedia
When forwarding the requests, you are in the application layer; you should be transmitting the contents of the UDP or TCP payload (i.e. only their data, not the headers themselves) using respectively a DatagramSocket or a Socket.
Bear in mind that this skips the transport layer as those implementations take care of constructing the UDP header (in case of DatagramSocket) and the TCP header and options (in case of Socket).
all I hava to do is to:
check if the IP packet is for http or https:
act as a route, forward as is, but ack requests and reconstruct the packet with new src, and
The whole process is like we are the router, and dispatch different packet to different nodes(servers).