OS X equivalent of SO_BINDTODEVICE



Linux允许执行以下代码,将套接字绑定到某个特定的网络接口。因此,通过这个套接字发送的数据将始终通过原始接口进行传输。

setsockopt(socket, SOL_SOCKET, SO_BINDTODEVICE, name, strlen(name))

据我所知,此功能用于VPN客户端。套接字连接到远程服务器并绑定到网络接口。这样,来自VPN客户端本身的流量就不会循环回VPN客户端。

有没有相当于操作系统X的功能?任一

  • 将套接字绑定到某个特定接口

  • 将VPN客户端中的套接字标记为不回环。

顺便说一句。我发现了类似的问题,但我不明白答案:编写一个OSX内核扩展来实现Linux';s SO_BINDTODEVICE套接字选项

更新1

我发现一些VPN客户端使用TUN/TAP设备来防止环回问题。http://backreference.org/2010/03/26/tuntap-interface-tutorial/

然而,我并不是说所有的OS X VPN都使用它。

是的,使用IP_BOUND_IF

int idx = if_nametoindex("en0");
setsockopt(sockfd, IPPROTO_IP, IP_BOUND_IF, &idx, sizeof(idx))

然而,您可以将bind()与接口的IP地址一起使用,这通常更容易。

使用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;
}

这对我有效:

char ethInterface[4] = "en0";
setsockopt(sock, SOL_SOCKET, IP_RECVIF, ethInterface, strlen(ethInterface));

使用RFC 3542接口来选择传出接口(IPV6_PKTINFO)。https://www.rfc-editor.org/rfc/rfc3542#section-6

相关内容

最新更新