private void onAccept() throws IOException {
        SocketChannel clientChannel = mServerSocketChannel.accept();
        Socket clientSocket = clientChannel.socket();

        // The client ip is the remote server ip
        // The client port is the local port(it is the vpn port not the proxy server port)
        String ip = clientSocket.getInetAddress().getHostAddress();
        int port = clientSocket.getPort();

        // The session should have be saved before the tcp packets be forwarded to proxy server. So
        // we can query it by client port.
        Session session = mSessionProvider.query((short) port);
        if (session == null) {
            throw new IOException("No session saved with key: " + port);
        }

        int remotePort = NetBareUtils.convertPort(session.remotePort);

        // Connect remote server and dispatch data.
        TcpTunnel proxyTunnel = null;
        TcpTunnel remoteTunnel = null;
        try {
            proxyTunnel = new TcpProxyTunnel(clientChannel, mSelector, remotePort);
            remoteTunnel = new TcpRemoteTunnel(mVpnService, SocketChannel.open(),
                    mSelector, ip, remotePort);
            TcpVATunnel gatewayTunnel = new TcpVATunnel(session, proxyTunnel,
                    remoteTunnel, mMtu);
            gatewayTunnel.connect(new InetSocketAddress(ip, remotePort));
        } catch (IOException e){
            NetBareUtils.closeQuietly(proxyTunnel);
            NetBareUtils.closeQuietly(remoteTunnel);
            throw e;
        }
    }
The TCP proxy server is a nio {@link ServerSocketChannel}, it listens the connections from
{@link VpnService} and forwards request packets to real remote server. This server uses
{@link TcpVATunnel} to bind {@link VirtualGateway} and {@link NioTunnel} together. Every TCP
connection has two channels: {@link TcpProxyTunnel} and {@link TcpRemoteTunnel}.
The {@link TcpProxyTunnel} is responsible for sending remote server response packets to VPN
service, and the {@link TcpRemoteTunnel} is responsible for communicating with remote server.

@author Megatron King
@since 2018-10-11 17:35
netbare-core/src/main/java/com/github/megatronking/netbare/proxy/TcpProxyServer.java