在我们的机器上,我们有多个网络接口,可以连接不同的网络。存在可能重叠的IP地址(例如,具有相同IP地址的两个不同网络中的两个不同机器)。因此,当我们想要与特定的对等体连接时,我们不仅需要指定它的IP地址,还需要指定通向适当网络的网络接口。 我们希望用C / C ++编写能够通过TCP与特定对等体连接的应用程序。
我正在尝试使用设置了SO_BINDTODEVICE的套接字建立TCP连接。这是一个简化的片段:
sockfd = socket(AF_INET, SOCK_STREAM, 0);
setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, interface_name,
strlen(interface_name));
connect(sockfd, (sockaddr *) &serv_addr, sizeof(serv_addr));
(我知道struct ifreq,但似乎只有第一个字段(ifr_name字段正在使用中)。所以我只能传递接口的名称。)
如何检查我们的系统拒绝SYN,ACK或ACK的位置?如何正确强制TCP套接字使用特定接口(针对路由表)进行连接?
也许还有一些其他更方便的方法可以在所需的界面上创建TCP连接?
谢谢!
答案 0 :(得分:1)
我知道这不是你的答案,但是你可以禁用其他接口并启用你想要的网络,在你的情况下你似乎需要所有接口,但我认为这种方法可以帮助其他人。您可以使用以下内容启用/禁用网络接口:
启用
ifr.ifr_flags = true;
strcpy(ifr.ifr_name, "eth0"); //you could put any interface name beside "eth0"
res = ioctl(sockfd, SIOCSIFFLAGS, &ifr);
对于禁用,您只需要将flag设置为false,其余代码都是相同的:
ifr.ifr_flags = true;
答案 1 :(得分:0)
不要使用SO_BINDTODEVICE。它并不是所有平台都支持,并且有一种更简单的方法。
而是将套接字绑定到要用于连接到远程端的正确网络上的本地IP地址。
即,
sockfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = 0; //Auto-determine port.
sin.sin_addr.s_addr = inet_addr("192.168.1.123"); //Your IP address on same network as peer you want to connect to
bind(sockfd, (sockaddr*)&sin, sizeof(sin));
然后调用connect。
对于服务器端,你会做同样的事情,除了指定一个端口而不是0,然后调用listen而不是connect。
答案 2 :(得分:0)
这是内核配置的问题 - 在许多发行版上,它默认配置为在这种特定情况下拒绝传入的数据包。
我在this answer to another similar question中找到了解决此问题的方法:
要允许此类流量,您必须在您的计算机上设置一些变量(以root身份):
your_nic
其中
net.ipv4.conf.all.rp_filter
是接收数据包的网络接口。请注意同时更改net.ipv4.conf.your_nic.rp_filter
和plot(c(1:3))
,否则它将无效(内核默认为限制性最强的设置)。