sou REUSEADDR(setsockopt选项)-Linux的含义是什么?

sou REUSEADDR(setsockopt选项)-Linux的含义是什么?,linux,sockets,port,ip-address,setsockopt,Linux,Sockets,Port,Ip Address,Setsockopt,从手册页: 因此(u REUSEADDR)指定规则 用于验证提供的地址 to bind()应允许重用本地 地址,如果 协议此选项接受整数 价值这是一个布尔选项 我应该什么时候用?为什么“本地地址的重用”会带来什么好处 因此,REUSEADDR允许您的服务器 绑定到a中的地址 等待状态的时间 这个套接字选项告诉内核,即使这个端口很忙(处于TIME_WAIT状态),仍然要继续使用它。如果它是忙碌的,但有另一种状态,你仍然会得到一个地址已经在使用错误。如果您的服务器已关闭,然后在其端口上的套接字仍处于

从手册页:

因此(u REUSEADDR)指定规则 用于验证提供的地址 to bind()应允许重用本地 地址,如果 协议此选项接受整数 价值这是一个布尔选项

我应该什么时候用?为什么“本地地址的重用”会带来什么好处

因此,REUSEADDR允许您的服务器 绑定到a中的地址
等待状态的时间

这个套接字选项告诉内核,即使这个端口很忙(处于TIME_WAIT状态),仍然要继续使用它。如果它是忙碌的,但有另一种状态,你仍然会得到一个地址已经在使用错误。如果您的服务器已关闭,然后在其端口上的套接字仍处于活动状态时立即重新启动,则此选项非常有用


来看,TCP的主要设计目标是在面临数据包丢失、数据包重新排序以及关键的数据包重复的情况下实现可靠的数据通信

很明显,TCP/IP网络堆栈在连接打开时是如何处理所有这些问题的,但是在连接关闭后会出现一种边缘情况。如果在对话结束时发送的数据包被复制和延迟,使得数据包在延迟的数据包之前到达接收方,会发生什么情况?堆栈尽职尽责地关闭其连接。然后,延迟的重复数据包出现。堆栈应该做什么

更重要的是,如果一个在给定IP地址+TCP端口组合上打开套接字的程序关闭了它的套接字,然后一段时间后,一个程序出现并想要在相同的IP地址和TCP端口号上侦听,它应该怎么做?(典型情况:程序被终止并快速重新启动。)

有两种选择:

  • 不允许在数据包传输的最长时间的至少2倍内重复使用该IP/端口组合。在TCP中,这通常称为2×延迟。有时还可以看到2×,大致相当

    这是所有常见TCP/IP堆栈的默认行为。2×MSL通常在30到120秒之间,它作为周期显示在
    netstat
    输出中。在这段时间之后,堆栈假设任何恶意数据包由于过期而在路由中被丢弃,因此套接字离开
    time\u WAIT
    状态,允许重用该IP/端口组合

  • 允许新程序重新绑定到该IP/端口组合。在具有接口的堆栈中(基本上是所有Unix和类Unix系统,加上Windows via),在调用之前,必须通过设置
    SO\u REUSEADDR
    选项via来请求此行为

  • 因此_REUSEADDR
    最常在网络服务器程序中设置,因为常见的使用模式是进行配置更改,然后需要重新启动该程序以使更改生效。如果没有
    SO\u REUSEADDR
    ,则重新启动的程序的新实例中的
    bind()
    调用将失败,前提是在您终止前一个实例时打开了与它的连接。这些连接将使TCP端口保持在
    TIME\u WAIT
    状态30-120秒,因此属于上述情况1

    设置
    SO_REUSEADDR
    的风险在于,它会产生歧义:TCP数据包头中的元数据不够唯一,堆栈无法可靠地判断数据包是否过时,因此应该丢弃而不是交付给新侦听器的套接字,因为它显然是为现已死亡的侦听器准备的

    如果您看不出这是真的,那么以下是侦听计算机的TCP/IP堆栈必须与每个连接一起工作才能做出该决定的所有内容:

  • 本地IP:不是唯一的per-conn。事实上,我们这里的问题定义是,我们有意重用本地IP

  • 本地TCP端口:同上

  • 远程IP:造成歧义的机器可能会重新连接,因此这无助于消除数据包正确目的地的歧义

  • 远程端口:在性能良好的网络堆栈中,传出连接的远程端口不会很快被重用,但它只有16位,因此您有30-120秒的时间强制堆栈通过数万个选择并重用端口。早在20世纪60年代,计算机就可以以如此快的速度工作

    如果您的答案是远程堆栈应该执行类似于
    TIME\u WAIT
    的操作来禁止重用,那么该解决方案假定远程主机是良性的。恶意参与者可以自由重用该远程端口

    我假设侦听器的堆栈可以选择严格禁止仅来自TCP 4元组的连接,以便在
    TIME\u WAIT
    状态期间,阻止给定远程主机与同一远程临时端口重新连接,但我不知道有任何TCP堆栈具有这种特殊的改进

  • 本地和远程TCP序列号:这些序列号也不够唯一,以至于新的远程程序无法产生相同的值

  • 如果我们今天重新设计TCP,我想我们会将其作为非可选功能集成或类似功能,其效果之一是使这种无意的恶意连接劫持不可能发生,但这需要添加大字段(128位及以上),这在1981年根本不实用,发布TCP()当前版本的文档时

    如果没有这样的强化,允许在
    时间_WAIT
    期间重新绑定所产生的歧义意味着你可以a)将用于旧侦听器的陈旧数据错误地传递到属于新侦听器的套接字,从而破坏侦听器的协议或将陈旧数据错误地注入连接;或者b)新侦听器套接字的新数据被错误地分配给旧侦听器的套接字,因此无效