【问题标题】:What happens if you bind to a specific interface and then the IP changes?如果绑定到特定接口然后 IP 更改会发生什么?
【发布时间】:2018-07-06 11:13:39
【问题描述】:

通过以下 sn-p 我绑定到特定接口

iface, err := net.InterfaceByName(ifaceName)

if err != nil {
    return nil, fmt.Errorf("ERR: Error using interface %q: %q", ifaceName, err.Error())
}

addrs, err := iface.Addrs()

if err != nil {
    return nil, fmt.Errorf("ERR: Error using interface %q: %q", ifaceName, err.Error())
}

if len(addrs) < 1 {
    return nil, fmt.Errorf("ERR: Interface %q has no addresses?", ifaceName)
}

ipAddr := addrs[0].(*net.IPNet).IP
udpAddr := &net.UDPAddr { IP: ipAddr }

然后将其用作 Listen 的本地地址。有谁知道如果接口的IP地址发生变化会发生什么?

【问题讨论】:

  • 你绑定的不是接口,而是IP地址。

标签: linux go network-programming


【解决方案1】:

我相信这个问题最好在 linux 网络方面得到最好的回答,而不是 go 语言,因为 go 服务器必须执行以下操作才能在套接字上侦听:

我描述了 TCP 服务器的情况,但 UDP 服务器将是类似的(在一定程度上!)。您可以通过设置一个简单的服务器并使用 strace 运行它来自己进行调查,例如:

strace -e trace=network nc -l -s 192.168.0.1 7777strace 部分将显示系统调用,nc -l 部分将侦听给定地址)

输出(我鼓励你用一个简单的 go 服务器尝试类似的事情!):

bind(3, {sa_family=AF_INET, sin_port=htons(7777), sin_addr=inet_addr("192.168.0.1")}, 16) = 0
listen(3, 1)                            = 0
accept4(3, 

我们可以看到服务器在接受呼叫时阻塞并等待传入​​连接。在 Linux 手册页中更准确地说明了此处发生的情况:

如果队列中没有挂起的连接,并且套接字是 未标记为非阻塞,accept() 阻塞调用者,直到 存在连接。如果套接字被标记为非阻塞并且没有 队列中存在挂起的连接,accept() 失败并显示 EAGAIN 或 EWOULDBLOCK 错误。

现在的问题是主机上的接口接收到的数据包如何到达该套接字。它需要经过TCP/IP stack 最终到达我们的应用程序。这不是一个简单的过程,您可以在许多linux networking guides 中找到有关它的详细信息)。本质上,会发生什么(这是非常高级的描述/概括):

  1. 数据包到达网络接口卡,被分类并 到达正确的上层(例如 IP 数据包的 IP)
  2. 数据包到达 IP 层,在此处检查 IP 标头 其他的东西,然后IP头被剥离,数据包被 由这个 IP 数据包携带的数据包被传递到上层(例如,如果 TCP - 到 TCP 层)
  3. 从 IP 层调用tcp_v4_rcv 函数(在 TCPv4 的情况下), 并且数据包到达TCP层。在这里,标题被检查并且 然后正在寻找这个传入数据包的打开套接字 (致电__tcp_v4_lookup)。

在这个阶段,如果没有找到这个包的 TCP 套接字,则丢弃这个包。 否则,打包它传递给进程。

直接回答您的问题:如果 IP 地址发生变化,并且旧 TCP 套接字绑定到旧 IP 地址,则为该套接字接收的数据包(如果服务器正在运行且未刷新,它将仍然打开)将在通过 linux 内核的网络部分的过程中被丢弃。

这是一个 如果您真的想深入了解,可以在一篇很棒的文章 Inside the Linux Packet Filter(以及 part 2 关于 IP 层以上发生的事情)中找到对所发生事情的良好描述

【讨论】:

    猜你喜欢
    • 2017-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-17
    • 2011-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多