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的主要内容,如果未能解决你的问题,请参考以下文章