OS X 相当于 SO_BINDTODEVICE
Posted
技术标签:
【中文标题】OS X 相当于 SO_BINDTODEVICE【英文标题】:OS X equivalent of SO_BINDTODEVICE 【发布时间】:2014-01-04 03:29:16 【问题描述】:Linux 允许执行以下代码将套接字绑定到某个特定的网络接口。因此,通过此套接字发送的数据将始终通过原始接口进行引导。
setsockopt(socket, SOL_SOCKET, SO_BINDTODEVICE, name, strlen(name))
据我了解,此功能用于 *** 客户端。套接字连接到远程服务器并绑定到网络接口。这样,来自 *** 客户端的流量就不会被环回到 *** 客户端。
是否有 OS X 相当于这样做?要么
将套接字绑定到某个特定接口
将 *** 客户端中的套接字标记为不被环回。
顺便说一句。我发现了类似的问题,但我不明白答案: Writing an OS X kernel extension to implement Linux's SO_BINDTODEVICE socket option
更新 1
我发现一些 *** 客户端使用 TUN/TAP 设备来防止环回问题。 http://backreference.org/2010/03/26/tuntap-interface-tutorial/
但是,我并不是说所有 OS X *** 都使用它。
【问题讨论】:
【参考方案1】:是否使用 getifaddrs() 来识别设备的地址,然后直接绑定到该设备?或者 SO_BINDTODEVICE 除了传统的 bind() 调用还有其他行为吗?
int BindToDevice(int sock, int family, const char* devicename)
ifaddrs* pList = NULL;
ifaddrs* pAdapter = NULL;
ifaddrs* pAdapterFound = NULL;
int bindresult = -1;
int result = getifaddrs(&pList);
if (result < 0)
return -1;
pAdapter = pList;
while (pAdapter)
if ((pAdapter->ifa_addr != NULL) && (pAdapter->ifa_name != NULL) && (family == pAdapter->ifa_addr->sa_family))
if (strcmp(pAdapter->ifa_name, devicename) == 0)
pAdapterFound = pAdapter;
break;
pAdapter = pAdapter->ifa_next;
if (pAdapterFound != NULL)
int addrsize = (family == AF_INET6)?sizeof(sockaddr_in6):sizeof(sockaddr_in);
bindresult = bind(sock, pAdapterFound->ifa_addr, addrsize);
freeifaddrs(pList);
return bindresult;
【讨论】:
我的印象是 bind() 仅在我们想要执行 listen() 和 accept() 的情况下使用。但是,就我而言,我想做 connect(),因为这个套接字是给客户端的。 只要路由表允许,也可以与客户端(连接)套接字一起使用。【参考方案2】:使用 RFC 3542 接口选择传出接口 (IPV6_PKTINFO)。 https://www.rfc-editor.org/rfc/rfc3542#section-6
【讨论】:
【参考方案3】:这对我有用:
char ethInterface[4] = "en0";
setsockopt(sock, SOL_SOCKET, IP_RECVIF, ethInterface, strlen(ethInterface));
【讨论】:
-1 这听起来不对。根据 Stevens 的说法,这不用于指定接收/发送接口的名称,但为此:“此套接字选项导致接收 UDP 数据报的接口的索引作为辅助返回recvmsg 提供的数据。”【参考方案4】:是的,使用IP_BOUND_IF
int idx = if_nametoindex("en0");
setsockopt(sockfd, IPPROTO_IP, IP_BOUND_IF, &idx, sizeof(idx))
但是,您可以将bind()
与接口的 IP 地址一起使用,这通常更容易。
【讨论】:
以上是关于OS X 相当于 SO_BINDTODEVICE的主要内容,如果未能解决你的问题,请参考以下文章
是否有相当于 FreeBSD 的 make_dev() 函数的 OS X?