使用getaddrinfo()仅在DNS超时时首次检查nscd缓存

使用getaddrinfo()仅在DNS超时时首次检查nscd缓存,c,linux,getaddrinfo,nss,C,Linux,Getaddrinfo,Nss,如果我得到一个初始的“名称或服务未知”(EAI_NONAME),那么对getaddrinfo()的下一个调用似乎直接转到dns,而不是首先检查缓存(nscd日志显示没有查找尝试,tcpdump显示到dns服务器的流量)。如果第一个调用成功获取地址,那么从那时起,所有getaddrinfo()调用都会按照预期首先转到nscd 我是针对armlinux的glibc-2.13编译的。在我的rc.d中,nscd在我的守护进程之前启动。nscd设置为不允许共享缓存,并维护主机缓存。我正在使用busybox

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

我是针对armlinux的glibc-2.13编译的。在我的rc.d中,nscd在我的守护进程之前启动。nscd设置为不允许共享缓存,并维护主机缓存。我正在使用busybox(0.47)中的nscd。nsswitch.conf已设置,以便主机检查缓存/文件/dns。hosts.conf设置为检查文件/绑定

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

我有运行nscd的调试日志,它们显示客户端开始读取DNS响应,并以“管道断开”错误结束

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

如果我重新启动守护进程,如果第一个DNS查询再次超时,我将获得相同的行为

glibc中是否存在使我的守护进程到缓存的链接无效的内容?有没有办法在不重新启动的情况下将我的守护进程重新连接到缓存(类似于通过res_init()强制重新加载resolv.conf) 同样,重试
getaddrinfo()
超过100次应强制执行nscd查询


为了了解原因,让我们快速浏览一下getaddrinfo()中的执行流程

  • \u nss\u not\u use\u nscd\u主机上执行以下操作:

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

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

      • 此外,在尝试查询nscd时,计数会立即重置为零
        因此,在下次调用
        getaddrinfo()
        时忽略nscd

  • 也由nscd在以下地方进行内部修改

    • 第178、189行
      --重置为
      1

    • 第89、164行
      --重置为
      1


    • --设置为
      -1
      ,即禁用nscd

  • 基于以上,可以得出以下结论:
    getaddrinfo()
    不会每次都查询nscd

    nscd的内部状态(由
    确定\u nss\u不使用\u nscd\u主机

    决定
    getaddrinfo()
    是否最终调用nscd

    要真正迫使自己绕过100次重试限制,可以修改
    NSS\u NSCD\u重试
    并重建libc以偏离标准 行为。但我不确定这是否会导致任何后果 其他意外的倒退


    参考:在
    getaddrinfo()

    中引入了
    \uu nss\u not\u use\u nscd\u hosts
    逻辑“…是否有办法在不重新启动的情况下将我的守护程序重新连接到缓存…”您是否经常尝试让守护程序调用
    getaddrinfo()
    。比如说100+次?尝试并监视对
    nscd
    的访问。我不能在这里测试这个,但是您的守护进程可能会决定再次测试
    nscd
    连接,如果从那时起成功使用它。“如果我重新启动守护进程,我会得到相同的行为…”您在这里指的是您自己的守护进程,而不是
    nscd
    ,是吗?顺便说一句:我是从检查eglibc的资料中得到上述想法的。