【问题标题】:macOS SO_REUSEPORT of setsockopt()setsockopt() 的 macOS SO_REUSEPORT
【发布时间】: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()的源码在哪里?

【问题讨论】:

    标签: macos sockets clang


    【解决方案1】:

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

    1. SO_REUSEPORT 和 SO_REUSEADDR 在许多情况下实际上可以互换工作(例如多播)。
    2. 在您提到的两个 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),
         ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-01-30
      • 2023-03-03
      • 2016-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-13
      相关资源
      最近更新 更多