gpt4 book ai didi

c - getaddrinfo 在不同的操作系统上表现不同

转载 作者:行者123 更新时间:2023-12-05 06:50:01 25 4
gpt4 key购买 nike

我正在测试一条错误路径,该路径要求我删除来自 getaddrinfo 的请求。我设置了 2 个虚拟机:

  • RHEL 7.9
  • Ubuntu 20

代码在两台机器上是相同的,只是为 test.com 调用 getaddrinfo。我阻止了所有传入数据包以模拟 getaddrinfo 请求被丢弃,但是在完全相同的情况下,2 个操作系统的表现不同。

  • RHEL 在 12 秒后超时并出现错误 EAI_NONAME(没有这样的文件或目录)
  • Ubuntu 在 20 秒后超时并出现错误 EAI_AGAIN(资源暂时不可用)

所以我的两个问题是:

  • 为什么会出现 2 个不同的错误?
  • 为什么超时不同,它们是在哪里定义的?我试图查看 linux 源代码,但无法弄明白

代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

int main (void)
{
struct addrinfo hints, *res, *result;
int errcode;
char addrstr[100];
void *ptr;

memset (&hints, 0, sizeof (hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags |= AI_CANONNAME;

errcode = getaddrinfo ("test.com", NULL, &hints, &result);
if (errcode != 0)
{
perror ("getaddrinfo");
return -1;
}

res = result;

while (res)
{
inet_ntop (res->ai_family, res->ai_addr->sa_data, addrstr, 100);

switch (res->ai_family)
{
case AF_INET:
ptr = &((struct sockaddr_in *) res->ai_addr)->sin_addr;
break;
case AF_INET6:
ptr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
break;
}
inet_ntop (res->ai_family, ptr, addrstr, 100);
printf ("IPv%d address: %s (%s)\n", res->ai_family == PF_INET6 ? 6 : 4,
addrstr, res->ai_canonname);
res = res->ai_next;
}

freeaddrinfo(result);
return 0;
}

编译:

gcc test.c

RHEL 解析配置文件:

search ht.home
nameserver 192.168.0.1
nameserver [IPV6 address 1]
nameserver [IPV6 address 2]

Ubuntu:

nameserver 127.0.0.53
options edns0 trust-ad
search ht.home

最佳答案

此处 Ubuntu 的行为是正确的,而 RHEL 的行为是错误的 - 结果是不确定,因为它既无法获得名称的地址,也无法获得证明不存在的响应名字。

该机制可能混合了 glibc 错误(更确切地说,是故意的不一致行为)以及具有您已阻止的远程名称服务器的 RHEL 配置与通过 systemd-resolved 代理的 Ubuntu 配置之间的区别>(也许你没有阻止,而只是阻止它向真实网络发出传出查询?)。您可以通过在 strace 下运行您的测试程序并在环回和真实网络接口(interface)上观察 tcpdump 来确认此处的差异。

基本上,在某些情况下,glibc 将错误视为名称不存在,而在其他情况下,它将错误视为可报告的故障。如果您能够查询本地 systemd-resolved,它将返回一个 ServFail 错误代码,因为它无法获得结果 或不存在的加密证明 来自上游名称服务器,glibc 可能会报告这一点,但不会报告它自己无法联系名称服务器。

关于c - getaddrinfo 在不同的操作系统上表现不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66484235/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com