11

最初の「名前またはサービスが不明」(EAI_NONAME) を取得した場合、getaddrinfo() への次の呼び出しは、最初にキャッシュをチェックするのではなく、dns に直接行くようです (nscd ログはルックアップ試行を示さず、tcpdump は DNS サーバーへのトラフィックを示します) )。最初の呼び出しがアドレスの取得に成功した場合、それ以降、予想どおり、すべての getaddrinfo() 呼び出しは最初に nscd に進みます。

arm Linux の glibc-2.13 に対してコンパイルしています。私の rc.d では、デーモンの前に nscd が開始されます。nscd は、共有キャッシュを禁止し、ホスト キャッシュを維持するように設定されています。busybox (0.47) の nscd を使用しています。nsswitch.conf は、ホストが cache/files/dns をチェックするように設定されています。hosts.conf はファイル/バインドをチェックするように設定されています。

私のデーモンは getaddrinfo() を呼び出しています。

実行中の nscd のデバッグ ログがあり、クライアントが DNS 応答の読み取りを開始し、"Broken Pipe" エラーで終了したことを示しています。

その後、キャッシュを使用しようとする他のデーモンからの GAI の試みが表示されます (したがって、nscd がロックされているなどではないことがわかります)。

デーモンを再起動すると、最初の DNS クエリが再びタイムアウトになると、同じ動作になります。

私のデーモンのキャッシュへのリンクを無効にしている glibc に何かありますか? デーモンを再起動せずにキャッシュに再接続する方法はありますか (resolv.conf を res_init() で強制的に再ロードするのと同様)

4

1 に答える 1

5

alk がコメントで言及している ようにgetaddrinfo()、100 回以上再試行すると、nscd クエリが強制的に実行されます。


その理由を理解するために、 getaddrinfo() の実行の流れを簡単に見てみましょう。

  1. getaddrinfo()gaih_inet を呼び出します

  2. gaih_inet() に対して次の操作を実行します__nss_not_use_nscd_hosts

    • 正の整数かどうかをチェックしますか?
    • インクリメントします。
    • リトライ回数を超えていないかチェックNSS_NSCD_RETRY

      • 上記の両方の条件が満たされている場合にのみ、nscd を照会しようとします。

      • また、nscd へのクエリを試行すると、カウントはすぐにゼロにリセットされる
        ため、次回呼び出される nscd は無視されNSS_NSCD_RETRYますgetaddrinfo()

  3. また__nss_not_use_nscd_hosts、次の場所で nscd によって内部的に変更されます

上記に基づいて、 は
getaddrinfo()毎回 nscd をクエリしないと結論付けることができます。

nscd の内部状態 ( によって決定される__nss_not_use_nscd_hosts)によって、最終的に nscdを呼び出す
かどうかが決まります。getaddrinfo()

100回の再試行制限を実際に回避するに NSS_NSCD_RETRYは、標準の動作から逸脱するようにlibcを変更および再構築できます。しかし、これが他の意図しない回帰を引き起こさないかどうかはよくわかりません。

参考:にロジックを導入したパッチ__nss_not_use_nscd_hostsgetaddrinfo()

于 2013-07-30T04:38:35.180 に答える