如何检查套接字绑定的IP地址是否仍然是有效机器的地址之一?

Phi*_*ipp 7 c sockets linux networking

一旦我打电话socket()bind()(具有特定的IP地址,而不是INADDR_ANY);listen(),似乎无法确定 IP 地址是否仍然是系统接口之一的有效地址。

我研究过使用什么:

  • getsockopt(SO_ERROR)使用;检查错误
  • epoll()对某些EPOLLERR,EPOLL{,RD}HUP事件使用-ing;
  • 希望accept()当进程在此系统调用上被阻止时,如果 IP 地址被删除,会返回错误;

上述这些似乎都没有检测到 IP 地址消失和/或接口状态的变化。

  • 调用bind()一些定时器回调来定期检查IP地址是否可以绑定,但这需要创建另一个套接字,这是不可行的。

我没有测试这些:

  • 设置SO_BINDTODEVICE的目的是希望在接口出现故障/IP 地址被删除的情况下,这将改变第一个三元组中设施的行为。

  • 调用ioctl()类似SIOCSPGRP或 的FIOASYNC函数,因为它们承诺向进程发出有关异步事件的信号,希望这些事件包括 IP 地址的消失。

  • 用于netlink获取路由表事件,但这是 Linux 特定的。

我希望有一种更便携的方式。

我需要的是一些类似于 的事件RDMA_CM_EVENT_DEVICE_REMOVAL,但是AF_INET当没有与该 IP 地址绑定的接口时,套接字会通知我。即使这样也可能无法实现,因为bind()如果接口关闭,即使完成也不会出现错误。

Jam*_*ner 1

当 BSD 套接字的链路断开时,您不需要关闭套接字。

其他问题显示了如何侦听Remy 提到的网络路由更改。

更简单的方法可能是在使用套接字之前检查 IP 当前是否已绑定。127.0.0.1这是验证是否仍然有效的方法:

% cat checksocket.c && cc -o checksocket checksocket.c ; ./checksocket
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <ifaddrs.h>
#include <netdb.h>
#include <net/if.h>

int main (void)
{
    struct ifaddrs *ifa, *i;
    char host[NI_MAXHOST];

    int ret = getifaddrs(&ifa);
    if (ret) {
        perror("getifaddrs:");
        exit(EXIT_FAILURE);
    }

    for (i = ifa; i != NULL; i = i->ifa_next) {
        ret = getnameinfo(i->ifa_addr, sizeof(*(i->ifa_addr)),
            host, sizeof(host), NULL, 0, NI_NUMERICHOST);
        char find[] = "127.0.0.1";
        int len = strlen(host);
        if (!ret && len && !strncmp(host, find, len)) {
            printf("Still valid: %s %s\n", i->ifa_name, ret ? "" : host);
        }
    }

    freeifaddrs(ifa);

    return 0;
}
Still valid: lo0 127.0.0.1
Run Code Online (Sandbox Code Playgroud)