setsockopt() 的 macOS SO_REUSEPORT

Posted

技术标签:

【中文标题】setsockopt() 的 macOS SO_REUSEPORT【英文标题】:macOS SO_REUSEPORT of setsockopt() 【发布时间】:2021-03-04 15:34:23 【问题描述】:

删除了 SO_REUSEPORT 以使示例在 macOS 上运行。

Socket programming - setsockopt: Protocol not available?

但是 macOS 上的 man setsockopt 清楚地记录了选项 SO_REUSEPORT。

SO_REUSEPORT    enables duplicate address and port bindings

为什么必须删除 SO_REUSEPORT 才能创建示例? macOS 上的setsockopt() 中是否存在错误? macOS上setsockopt()的源码在哪里?

【问题讨论】:

【参考方案1】:

SO_REUSEPORT 是 secsockopt 的一个选项,因此它的源代码在内核中。那将是 xnu 的来源,特别是 sys 调用处理程序检查有效性(bsd/kern/uipc_socket.c)和 IPv4/v6 堆栈 (分别为 bsd/netinet/in_pcb.c 和 bsd/netinet6/in6_pcb.c)实现它。从中可以看出两点:

    SO_REUSEPORT 和 SO_REUSEADDR 在许多情况下实际上可以互换工作(例如多播)。 在您提到的两个 setsockopt(2) 调用中也可以使用它:错误是选项是 not 位掩码,所以 |和 + 不会与他们一起工作 - 即使
#define SO_REUSEADDR    0x0004          /* allow local address reuse */
#define SO_REUSEPORT    0x0200          /* allow local address & port reuse */

稍后在内核中用作位掩码 (|'ed) ,内核中处理 getsockopt 和检查有效性的代码使用 switch 语句,因此最终这两个选项都没有被兑现,因为它没有落在那些情况下。具体来说就是bsd/kern/uipc_socket.c:

int  sosetoptlock(struct socket *so, struct sockopt *sopt, int dolock)
    
    . ...
       switch (sopt->sopt_name) 
      . ..
       case SO_REUSEADDR:
                    case SO_REUSEPORT:
                    case SO_OOBINLINE:
                    case SO_TIMESTAMP:
                    case SO_TIMESTAMP_MONOTONIC:
                    case SO_TIMESTAMP_CONTINUOUS:
                    case SO_DONTTRUNC:
                    case SO_WANTMORE:
                    case SO_WANTOOBFLAG:
                    case SO_NOWAKEFROMSLEEP:
                    case SO_NOAPNFALLBK:
                            error = sooptcopyin(sopt, &optval, sizeof(optval),
     ...

【讨论】:

以上是关于setsockopt() 的 macOS SO_REUSEPORT的主要内容,如果未能解决你的问题,请参考以下文章

setsockopt用法详解

setsockopt用法详解

setsockopt用法详解

setsockopt 的目的到底是啥?

setsockopt设置socket状态

setsockopt