Java Linux 上的套接字和多个传出接口

Java Sockets and multiple outgoing interfaces on Linux

有很多相关的问题(例如 Java Socket specify a certain network interface for outgoing connections )但是我找不到一个令人满意的即实用的解决方案来解决我的问题:

在我的目标 (Linux) 平台上有多个网络接口 (eth0...ethN) 可以从中访问服务器 S。默认路由通常是通过 eth0,但是我正在尝试通过例如连接 S eth4 使用

new java.net.Socket(IP_of_S, targetport, IP_of_eth4, srcport)

sock.bind( eth4_SocketAddress );
sock.connect( S_SocketAddress );

在此示例中,eth4 的 IP 已正确分配,但流量仍通过默认路由的接口传出。我了解到这是由于 "weak end system model" RFC 1122。但是我想知道是否还有基于 Java 的解决方案来实现我最初的目标,或者我是否必须触发外部 iptables 或路由来自我的程序的调用。

(顺便说一句:需要在运行时动态选择传出接口,即我的程序关闭连接并经常尝试使用不同的出站接口重新连接。)

据我所知,如果没有一些路由 table 设置,您将无法选择传出接口。

在我看来,最好的解决方案是设置一堆特定于源的路由,匹配数据包源地址的路由,并绑定到给定的源地址以便 select 路由(就像你已经做的那样)。有两种方法可以实现:

  • 使用 ip rule 和多个路由 tables — 这在 http://lartc.org/howto/lartc.rpdb.html ;
  • 中有描述
  • 使用ip route add ... from ...。据我所知,这仅适用于 IPv6,但避免了多重路由的复杂性 tables.

您会在 https://arxiv.org/pdf/1403.0445v4.pdf 中找到有关源特定路由的一些背景知识(免责声明,我是合著者)。