5

我正在尝试在 linux 的不同网络接口上的 ruby​​ 应用程序中打开多个套接字。例如,假设我有 IP 为 192.168.1.2 的接口 eth0 和 IP 地址为 10.0.0.2 的接口 wlan0。我想同时连接到每个接口上都有一个套接字的服务器。我认为绑定到这些接口的 IP 地址会起作用,但似乎并非如此。在wireshark中,当我绑定到wlan0的IP时,我成功地看到SYN数据包使用正确的源IP发送,但是wireshark在eth0上看到它们并且套接字永远不会打开。

Ruby 版本:ruby 1.9.3p194(2012-04-20 修订版 35410)[x86_64-linux]

这是我当前的代码。我还尝试了 ruby​​-doc 页面上记录的 Socket 的 Addrinfo 方法,结果相同。

require 'socket'

ip = "192.168.1.2" # IP of internal interface
port = 8000
server = "" # IP of the server I'm trying to connect to goes here

lhost = Socket.pack_sockaddr_in(0, ip)
rhost = Socket.pack_sockaddr_in(port, server)
socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
socket.bind(lhost)
socket.connect(rhost)

感谢您的任何帮助!

4

1 回答 1

7

解决方案是基于源的路由

我能够弄清楚,并认为我应该留下我的答案,以防其他人在路上遇到这个问题。

我需要做的是基于源的路由。总体思路是创建两个路由表,一个在一个接口上强制流量,另一个在另一个接口上强制流量,并具有一个 ip 规则,该规则使用基于源 IP 地址的适当路由表。我是这样设置的:

创建表

首先,我必须编辑/etc/iproute2/rt_tables以添加以下行:

128    multiplex0
129    multiplex1

这创建了两个带有 ID 的路由表,128129调用了multiplex0multiplex1

向表中添加路由

接下来,我为这些表创建了如下规则:

ip route add default via 10.0.2.2 table multiplex0 
ip route add default via 192.168.1.1 table multiplex1

这些命令指定要在路由表中使用的默认网关。我的 10.0/16 网络的默认网关是 10.0.2.2,我的 192.168.1/24 网络的默认网关是 192.168.1.1。

如果两个网络有相同的默认网关怎么办?

如果您的网络具有相同的默认网关,我相信您可以dev eth0在上述命令中添加(或任何您的接口)以指定接口,尽管我尚未对此进行测试。当我了解更多信息时,我会进行编辑。

编辑:我已经对此进行了测试,它确实有效。如果您在路由中指定接口,则两条路由可以具有相同的默认网关。

基于源的规则

接下来我需要创建规则来使用这些表:

ip rule add from 10.0.0.0/16 table multiplex0
ip rule add from 192.168.1.1/24 table multiplex1

这些规则说,任何源 IP 在 10.0/16 范围内的数据包都应该根据 multiplex0 中的规则进行路由,而任何源 IP 在 192.168.1/24 范围内的数据包都应该使用 multiplex1。当数据包使用这些表时,它们被定向到适当的网关和相应的接口。中提琴!

编辑:在此步骤中仅指定网络接口的 IP 会更准确!例如,如果两个接口都在 192.168.1/24 网络上,则它是必要的。

刷新缓存

最后,我发出ip route flush cache使一切生效并使用上面的 ruby​​ 代码,我能够在正确的接口上打开我的两个套接字到同一个可公开路由的主机。

于 2013-06-14T19:06:12.337 回答