OS X相当于SO_BINDTODEVICE

时间:2013-12-16 16:40:41

标签: linux macos sockets vpn

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

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

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

OS X是否相当于这样做?任

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

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

顺便说一句。我发现了类似的问题,但我不明白答案: Writing an OS X kernel extension to implement Linux's SO_BINDTODEVICE socket option

更新1

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

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

4 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

使用RFC 3542接口选择传出接口(IPV6_PKTINFO)。 http://tools.ietf.org/html/rfc3542#section-6

答案 2 :(得分:0)

这对我有用:

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

答案 3 :(得分:0)

是的,请使用IP_BOUND_IF

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

但是,您只需将bind()与接口的IP地址配合使用,通常会更容易。