如何使TCP套接字与SO_BINDTODEVICE(针对路由表)一起工作
How to make a TCP socket work with SO_BINDTODEVICE (against routing table)
问题背景:
在我们的机器上,我们有多个网络接口,这些接口通向不同的网络。可能存在重叠的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字段)。所以我只能传递接口的名称。)
- 如果强制接口与路由表中的接口相同,则一切正常
- 如果强制接口不同,则(使用Wireshark测试):
- SYN从强制接口发送到所需的对等端
- 在强制接口上接收到来自期望对等端的SYN、ACK
- ACK未从强制接口发送,并且未建立连接。(然后转到步骤2。)
如何检查系统拒绝SYN、ACK或ACK的位置?如何正确地强制TCP套接字使用特定的接口进行连接(对照路由表)?
也许还有其他更方便的方法可以在所需的接口上创建TCP连接?
谢谢!
我知道这不是你的答案,但你可以禁用其他接口,只启用你想要的网络,在你的情况下,你似乎需要所有的接口,但我认为这种方法可以帮助其他人。你可以用这样的东西来启用/禁用网络接口:
启用
ifr.ifr_flags = true;
strcpy(ifr.ifr_name, "eth0"); //you could put any interface name beside "eth0"
res = ioctl(sockfd, SIOCSIFFLAGS, &ifr);
对于disable,您只需要将flag设置为false,其余代码相同:
ifr.ifr_flags=true;
不要使用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之外,你也可以做同样的事情。
这是内核配置的一个问题-在许多发行版上,默认情况下,它被配置为在这种特定情况下拒绝传入的数据包。
我在对另一个类似问题的回答中找到了这个问题的解决方案:
要允许这样的流量,你必须在你的机器上设置一些变量(作为根):
sysctl -w net.ipv4.conf.all.accept_local=1 sysctl -w net.ipv4.conf.all.rp_filter=0 sysctl -w net.ipv4.conf.your_nic.rp_filter=0
其中CCD_ 1是接收分组的网络接口。注意同时更改
net.ipv4.conf.all.rp_filter
和net.ipv4.conf.your_nic.rp_filter
,否则将无法工作(内核默认为最严格的设置)。
- QSqlquery prepare()和bindvalue()不工作
- 导入库可以跨dll版本工作吗
- 以螺旋方式打印矩阵的程序.(工作不好)
- 对象指针在c++中是如何工作的
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- VSOMEIP-2个设备之间的通信(TCP/UDP)不工作
- 为字符串中每 N 个字符插入空格的函数没有按照我认为的方式工作?
- C++为线程工作动态地分割例程
- 为什么我的 std::ref 无法按预期工作?
- 布尔比较运算符是如何在C++中工作的
- SampleConsensusPrerejective(ext.RANSAC)是如何真正工作的
- 不确定要在我的main中放入什么才能使我的代码正常工作
- 为什么std::condition_variable notify_all的工作速度比notify_one快(对于随机请
- <<操作员在下面的行中工作
- 有人能解释一下为什么下界是这样工作的吗C++的
- ExtractIconEx:可以工作,但偶尔会崩溃
- C++中的memset函数工作不正常
- 当我在第一个循环中使用"auto"时,它工作正常,但是使用"int"它会给出错误,为什么?
- 链表c++插入,所有情况都已检查,但没有任何工作
- 如何使TCP套接字与SO_BINDTODEVICE(针对路由表)一起工作