user1424739
user1424739

Reputation: 13675

macOS SO_REUSEPORT of setsockopt()

SO_REUSEPORT is deleted to make the example work on macOS.

Socket programming - setsockopt: Protocol not available?

But man setsockopt on macOS clearly document the option SO_REUSEPORT.

SO_REUSEPORT    enables duplicate address and port bindings

Why SO_REUSEPORT has to be removed to make the example? Is there a bug in setsockopt() on macOS? Where is the source code of setsockopt() on macOS?

Upvotes: 2

Views: 711

Answers (1)

Technologeeks
Technologeeks

Reputation: 7897

SO_REUSEPORT is an option for secsockopt, so the source for it is in the kernel proper. That'd be xnu's sources, specifically the sys call handler checks validity (bsd/kern/uipc_socket.c) and the IPv4/v6 stacks (bsd/netinet/in_pcb.c and bsd/netinet6/in6_pcb.c, respectively) implement it. From it, you can see two things:

  1. that SO_REUSEPORT and SO_REUSEADDR actually work interchangeably in many cases (e.g. multicast).
  2. it would work in the sample you referred to when put in two setsockopt(2) calls, as well: The mistake was that the options are not bitmasks, so | and + won't work with them - even though
#define SO_REUSEADDR    0x0004          /* allow local address reuse */
#define SO_REUSEPORT    0x0200          /* allow local address & port reuse */

are used in the kernel as bit masks later on (|'ed) , the code in kernel to handle getsockopt and check for validity uses a switch statement, so it ends up that neither option is honored, because it doesn't fall in those cases. Specifically, it's 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),
     ...

Upvotes: 2

Related Questions