gpt4 book ai didi

c - 使用 getaddrinfo() 仅在 DNS 超时时第一次检查 nscd 缓存

转载 作者:IT王子 更新时间:2023-10-29 00:01:28 26 4
gpt4 key购买 nike

如果我得到一个初始的“名称或服务未知”(EAI_NONAME),对 getaddrinfo() 的下一次调用似乎直接进入 dns 而不是首先检查缓存(nscd 日志显示没有查找尝试,tcpdump 显示流量到 DNS 服务器)。如果第一次调用成功获取地址,从那时起,所有 getaddrinfo() 调用都会像预期的那样首先转到 nscd。

我正在针对 arm linux 的 glibc-2.13 进行编译。在我的 rc.d 中,nscd 在我的守护进程之前启动。 nscd 设置为禁止共享缓存,并维护主机缓存。我正在使用来自 busybox (0.47) 的 nscd。 nsswitch.conf 已设置,因此主机会检查缓存/文件/dns。 hosts.conf 设置为检查文件/绑定(bind)。

我的守护进程正在调用 getaddrinfo()。

我有 nscd 运行的调试日志,它们显示客户端开始读取 DNS 响应并以“Broken Pipe”错误关闭。

之后它将显示来自其他试图使用缓存的守护进程的 GAI 尝试(所以我知道它不是 nscd 锁定或任何东西),但是获得 EAI_NONAME 的守护进程再也不会联系 nscd 进行缓存查找。

如果我重新启动守护程序,我会得到相同的行为,如果第一个 DNS 查询再次超时。

glibc 中是否有某些东西使我的守护程序与缓存的链接失效?有没有办法在不重新启动我的守护程序的情况下将我的守护程序重新连接到缓存(类似于通过 res_init() 强制重新加载 resolv.conf)?

最佳答案

<子>作为alk mentions in his comment ,重试 getaddrinfo() 超过 100 次应该会强制执行 nscd 查询。


要了解原因,让我们快速浏览一下内部 getaddrinfo() 的执行流程。

  1. getaddrinfo() calls gaih_inet .

  2. gaih_inet()__nss_not_use_nscd_hosts 上执行以下操作:

    • 检查它是否为正整数?
    • 增加它。
    • 检查是否超过重试次数NSS_NSCD_RETRY

      • 仅当上述两个条件都满足时,它才会尝试查询 nscd。

      • 同样在尝试查询 nscd 时,计数会立即重置为零
        从而忽略下一个 NSS_NSCD_RETRY 的 nscd次 getaddrinfo() 被调用。

  3. 还有 __nss_not_use_nscd_hosts由 nscd 在以下地方内部修改

Based on the above, it can be concluded that
getaddrinfo() does NOT query nscd every single time.

nscd的内部状态(由__nss_not_use_nscd_hosts决定)
决定 getaddrinfo() 是否最终调用 nscd。

To really force one's way around the 100 retry limitation, one could modify NSS_NSCD_RETRY and rebuild libc to deviate from the standard behaviour. But i am not really sure if this will NOT result in any other unintended regressions.

引用:Patchgetaddrinfo() 中引入了 __nss_not_use_nscd_hosts 逻辑。

关于c - 使用 getaddrinfo() 仅在 DNS 超时时第一次检查 nscd 缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16741732/

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