为什么在Unix TCP/IP服务器上不使用SO_REUSEADDR?

x4shl7ld  于 12个月前  发布在  Unix
关注(0)|答案(3)|浏览(167)

我没有看到任何重要的TCP/IP服务器不使用SO_REUSEADDR:

  • Apache HTTP服务器SO_REUSEADDR用法
  • Nginx SO_REUSEADDR用法
  • 非常安全的FTPD SO_REUSEADDR使用
  • exim SO_REUSEADDR用法
  • 后缀SO_REUSEADDR用法
  • OpenSSH SO_REUSEADDR usage

在TCP/IP服务器上是否有不使用SO_REUSEADDR的用例?
我的意思是,让操作系统总是使用SO_REUSEADDR会破坏任何不使用它的服务器吗?
你知道一个TCP/IP服务器不使用SO_REUSEADDR是有原因的吗?
(of当然,你可能不想在MSWindows上使用它,因为它允许在同一个端口上运行两个服务器)

rsl1atfo

rsl1atfo1#

UNP(Stevens 2004)说:
SO_REUSEADDR允许侦听服务器启动并绑定其已知端口,即使先前建立的连接将此端口用作其本地端口。

所有TCP服务器都应指定此套接字选项以允许服务器重新启动

zqry0prt

zqry0prt2#

我认为最有可能的原因与TIME_WAIT状态存在的原因相同。
参见https://stackoverflow.com/a/3233022/5267751
设置SO_REUSEADDR的风险在于它会产生歧义:TCP数据包报头中的元数据不够唯一,堆栈无法可靠地判断数据包是否过时,因此应该丢弃而不是传递到新侦听器的套接字,因为它显然是为一个现已死亡的侦听器设计的。
https://stackoverflow.com/a/337137/5267751
在会话关闭后会出现TIME_WAIT状态的原因是因为网络中可能仍有活动的数据包正在发送给您(或者来自您的数据包可能会请求某种响应)。如果您要重新创建相同的元组,其中一个数据包出现了,它将被视为您的连接的有效数据包(并且可能会由于排序而导致错误)。
所以TIME_WAIT时间通常被设置为包最大年龄的两倍。这个值是你的包在网络丢弃它们之前被允许到达的最大年龄。

gzjq41n4

gzjq41n43#

当然,在默认情况下不使用SO_REUSEADDR是有充分理由的。
它将允许任何进程绑定到同一个监听套接字作为一个敏感的互联网服务,并接受代表它的连接!这允许无限的窃听和中间人。

相关问题