我有一个带有多个接口的Linux服务器。每个接口都有一个IP和网络。路由表中还有一个默认路由和其他路由,以便与某些网络的连接通过一个或另一个接口。当然,任何程序在与服务器的某个接口相同的网络中发送到IP的连接都将通过该接口。
给定该服务器上的程序将要连接的目标IP:是否有API来检索将使用的本地接口的IP地址?
或者可选地:一旦刚刚启动某个IP连接,我怎样才能准确获得最合适的服务器本地IP地址? 可以吗?
我不想再次编写路由逻辑。
实施例: eth0:192.168.1.10/24 eth1:10.1.1.20/24 默认gw:192.168.1.1 额外的静态路线: 通过10.1.1.1到10.2.0.0/16
现在,如果一个程序启动到1.2.3.4的UDP连接,它将使用eth0,我想要查询的appropritate IP将是192.168.10。 现在,如果一个程序启动到10.2.55.66的UDP连接,它将使用eth1,我想查询的appropritate IP将是10.1.1.20。 现在,如果一个程序启动到10.1.1.9的UDP连接,它将使用eth1,我想查询的appropritate IP将是10.1.1.20。
这个问题的原因是我想修改snmp-trap发送程序以将正确的地址放在agentField中
答案 0 :(得分:2)
是否有API来检索将使用的本地接口的IP地址?
我不相信。无论如何,它本身就会很有趣 - 路由表可能会在您查询该API的时间与您实际建立连接的时间之间发生变化。
或者可选:刚刚启动某个IP连接后,如何才能获得最合适的服务器本地IP地址?可以吗?
您可以这样做 - 一旦您有一个连接套接字,getsockname()
将告诉您套接字的本地地址,其中包括IP地址和端口号。
答案 1 :(得分:2)
当未通过mount
参数指定本地IP地址时,NFSv4 clientaddr
执行非常类似的操作。它必须获取远程NFS服务器可以连接的本地IP地址,即使本地计算机上有多个接口也是如此。
它通过创建UDP数据报套接字,绑定到本地地址,connect()
到远程计算机,然后使用getsockname()
查询将用于传出数据包的本地IP地址来实现此目的。由于UDP是无连接协议,因此根本不会通过线路发送数据;这只使用本地路由表来确定绑定到套接字的本地IP地址。
请参阅utils/mount/network.c:nfs_callback_address()的Linux-NFS git repository了解具体实施情况。它使用utils/mount/network.c:nfs_ca_sockname()来获取地址,并使用utils/mount/network.c:nfs_ca_gai()来检查本地计算机是否支持地址系列(这样它就不会使用以下方式返回本地地址(NFS术语中的回调地址))地址族,比如说IPv6,本地机器不支持。)
是的,如果 machine-internal 路由在上述操作完成后发生更改,则会失败 - 也就是说,您手动修改路由表以使用该目标IP地址的另一个接口。这不是一个真正的问题,因为它通常会破坏(挂起直到超时)所有现有的连接,因为它们绑定到错误的本地IP地址,并且内核不能只是从进程下切换它。换句话说,如果你这样做,你必须要求连接断开。
本地计算机外部的路由更改不受影响。应该明白为什么:原始UDP连接测试没有到达机器外部,只到达本地路由表。机器本身外部的任何路由(包括下一跳,或机器外部的网关地址,在本地路由表中)都不会导致任何破坏,并且不会更改使用上述过程获得的结果。
我希望你觉得这很有用。