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

OS X 相当于 SO_BINDTODEVICE

是否有相当于 FreeBSD 的 make_dev() 函数的 OS X?

subprocess

Mac OS X 下的 _wfopen 等效项

VMware上面安装了mac OS X10.11分辨率这么调

Linux (Fedora 13) 与 OS X 中的 sigwait