客户端在虚拟网络接口环境中收到服务器的SYN / ACK后无法回复ACK

时间:2019-06-11 10:47:22

标签: c++ linux tcp vpn tun

我正在设置本地vpn环境,我想通过虚拟网络接口在本地捕获流量,然后通过物理网络接口绑定套接字将其转发到真实目的地。但是,设置tun虚拟网络接口后,我什至无法连接真实目的地。

我的测试机: Linux测试-VirtualBox 3.19.0-15-通用#15-Ubuntu SMP星期四四月16 23:32:37 UTC 2015 x86_64 x86_64 x86_64 GNU / Linux

首先,我成功创建了一个名为tun0的虚拟网络接口,如下所示:

      tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
      inet addr:192.168.2.1  P-t-P:192.168.2.1  Mask:255.0.0.0
      UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
      RX packets:0 errors:0 dropped:0 overruns:0 frame:0
      TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
      collisions:0 txqueuelen:500 
      RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

为简便起见,我仅将目标服务器的IP地址添加到路由表中: 路由添加-host 45.113.192.102 dev tun0 路由表如下: 内核IP路由表

     Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
     0.0.0.0         xxx.xx.xxx.xxx   0.0.0.0         UG        0 0          0 eth0
     45.113.192.102  0.0.0.0         255.255.255.255 UH        0 0          0 tun0
     xxx.xx.xxx.xxx   0.0.0.0         255.255.255.128 U         0 0          0 eth0
     192.0.0.0       0.0.0.0         255.0.0.0       U         0 0          0 tun0

xxx.xx.xxx.xxx是我的内部主机/网关ip地址。

最后,我创建一个套接字并将该套接字绑定到物理网络接口。我在这里使用libuv,而与该问题无关。

struct sockaddr_in remote_addr;
memset(&remote_addr, 0, sizeof(remote_addr));
remote_addr.sin_family = AF_INET;
remote_addr.sin_port = ntohs(443);
inet_pton(AF_INET, "45.113.192.102", &remote_addr.sin_addr);
uv_os_sock_t sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock < 0) {
    std::cout << "ERROR--- create socket failed\n";
    return -1;
}
int32_t r;
r = setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, "eth0", strlen("eth0"));
if (r != 0) {
    std::cout << "setsockopt failed: " << errno;
    return -1;
}

uv_tcp_init(g_uv_loop, &socket_handle);
r = uv_tcp_open(&socket_handle, sock);
uv_connect_t connect_req;
r = uv_tcp_connect(&connect_req, &socket_handle,
        (struct sockaddr *) &remote_addr, _tcp_connect_cb);

我运行我的代码,发现我无法连接到“ 45.113.192.102”。 我通过Wireshark捕获了流量,发现我的程序已将SYN发送到“ 45.113.192.102”,“ 45.113.192.102”也答复了SYN,ACK。但是,在那之后,我的程序似乎没有发送ACK,这导致连接失败。 在下面,客户端不断发送[TCP虚假重传] SYN,服务器回复[TCP重传] SYN,ACK。

0 个答案:

没有答案