socket指定SRCIP和SO_BINDTODEVICE的区别

在网络编程中,尤其是多WAN(不论这个多WAN是物理的还是虚拟的,最终Linux都是以映射的NETDEVICE设备为准)的网络编程中,经常会用到上述实现,但常常会导致网络不通或走错接口的情况

单播报文内核实现上的区别

1)指定SRCIP - 这种情况下Linux内核并不会通过SRCIP直接定死出接口后,在没有特殊路由规则的情况下还是会按照DESTIP查找出接口

注意:此时抓包会发现即使指定了SRCIP,但实际上出接口并不是我们要的那个接口,即会出现走错接口的情况

处理方法:

添加静态路由 - 通过目的地址指定正确的出接口和下一跳

添加策略路由 - 通过SRCIP匹配策略路由指定正确的出接口和下一跳。策略路由可以适应所有的目的地址。

2)SO_BINDTODEVICE - 绑定出接口(注意是 出接口 ),在没有同时指定SRCIP的情况下Linux内核会通过出接口反查SRCIP使用,但这里通用会存在一个问题,查路由时出接口成为一个条件

注意:如果路由没有特殊规则,此时抓包会发现 当承载在非点对点(点对点不需要特别指定下一跳,接口属性已经决定只能发给PeerToPeer对端设备)的网络交互时,非同网段的DESTIP(同网段不需要下一跳)交互报文在某些情况下发不出来,多数原因是:非点对点的 非同网段的DESTIP交互需要网关(下一跳),在单默认网关的情况下,当该出接口不是默认网关指定的出接口时,一般没有路由规则指定下一跳 -

处理方法:

添加静态路由 - 通过目的地址指定下一跳

添加策略路由 - 通过出接口匹配策略路由下一跳。策略路由可以适应所有的目的地址。(此条未实际验证)

多播报文内核实现的区别

1)指定SRCIP - 未同时通过SO_BINDTODEVICE绑定出接口时,通过SRCIP直接查出接口;通过SO_BINDTODEVICE绑定出接口时,以SO_BINDTODEVICE处理为准,即SO_BINDTODEVICE的处理优先级别更高

2)SO_BINDTODEVICE - 通过出接口直接反查SRCIP使用

上述内核实现主要集中在ip_route_output_slow函数中,SRCIP传入参数为fl4->saddr;SO_BINDTODEVICE传入参数为fl4->flowi4_oif

上一篇:linux 动态库(.so)、静态库编译命令与调用(.a);


下一篇:JAVA网络编程-客户端Socket