リバースルックアップ0.0.0.0タイムアウト

リバースルックアップ0.0.0.0タイムアウト

組み込みLinuxデバイスでは、0.0.0.0起動時にIPアドレスのリバースルックアップを要求するアプリケーションを実行しています。これは最終的に呼ばれますgethostbyaddr

時にはgethostbyaddr通話がすぐに完了(失敗)することもありますが、時には5〜10秒ほど遅延(DNSタイムアウト?)されることもあります。どのような状況で遅延が発生しているかを確認できませんでした。

いくつかのヒント:

  • 初期初期化スクリプトのいずれかで次のコマンドを実行して、起動時にIP6サポートを無効にします。

    echo 1 >/proc/sys/net/ipv6/conf/all/disable_ipv6
    echo 1 >/proc/sys/net/ipv6/conf/default/disable_ipv6
    echo 1 >/proc/sys/net/ipv6/conf/lo/disable_ipv6
    

    (私の考えでは)これはあきらめなければなりません:https://www.netroby.com/view/3695

  • 私はAvahi/MDNSを使用していません。これにより、以下が削除されます。https://bugs.launchpad.net/ubuntu/+source/nss-mdns/+bug/94940

  • デバイスがローカルDNSサービスを実行していません。

  • この問題は DHCP または固定 IP 構成で発生します。 DHCPを使用すると、私のDSLルーターは自分自身をDNSサーバーとして宣伝します。ただし、静的IP構成を使用する場合は、8.8.8.8をDNSサーバーとして使用します(したがって、DSLルーター側で問題のあるDNSサーバーを削除する必要があります)。

ここで何が起こっているのかというアイデアはありますか?


修正する:

現在の関連行は次/etc/nsswitch.confのとおりです。

hosts: files dns

単純化されたテストアプリケーションを使用して問題を再現しました。以下は、タイムアウトが発生したときのstrace出力の一部です。

291   23:34:30 connect(6, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("8.8.8.8")}, 16) = 0 <0.000077>
291   23:34:30 gettimeofday({tv_sec=1514849670, tv_usec=139862}, NULL) = 0 <0.000032>
291   23:34:30 poll([{fd=6, events=POLLOUT}], 1, 0) = 1 ([{fd=6, revents=POLLOUT}]) <0.000049>
291   23:34:30 send(6, "\r\231\1\0\0\1\0\0\0\0\0\0\0010\0010\0010\0010\7in-addr\4arp"..., 38, MSG_NOSIGNAL) = 38 <0.000128>
291   23:34:30 poll([{fd=6, events=POLLIN}], 1, 5000) = 0 (Timeout) <5.005152>
291   23:34:35 gettimeofday({tv_sec=1514849675, tv_usec=147536}, NULL) = 0 <0.000088>
291   23:34:35 poll([{fd=6, events=POLLOUT}], 1, 0) = 1 ([{fd=6, revents=POLLOUT}]) <0.000086>
291   23:34:35 send(6, "\r\231\1\0\0\1\0\0\0\0\0\0\0010\0010\0010\0010\7in-addr\4arp"..., 38, MSG_NOSIGNAL) = 38 <0.000206>
291   23:34:35 poll([{fd=6, events=POLLIN}], 1, 5000) = 1 ([{fd=6, revents=POLLIN}]) <0.045356>
291   23:34:35 ioctl(6, FIONREAD, [106]) = 0 <0.000087>
291   23:34:35 recvfrom(6, "\r\231\201\203\0\1\0\0\0\1\0\0\0010\0010\0010\0010\7in-addr\4arp"..., 1024, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("8.8.8.8")}, [28->16]) = 106 <0.000096>

最初のDNS要求は応答を受け取りませんでしたが、5秒のタイムアウト後に再試行し、ほぼすぐに応答を受信しました。

ベストアンサー1

ネットワークが完全に稼働していないか(DNS要求が失われる)、ランダムなパケット損失が発生する可能性があります(特にWiFiで発生します)。前者はアプリケーションの実行をしばらく待って処理することができ、後者はほとんど不可避です。

しかし、役に立つかもしれないいくつかの点は次のとおりです。

  • アプリケーションを修復します。私はこれがオプションではないと思います。それ以外の場合は、すでにこれを行っています。

  • 0.0.0.0の項目をに入れます/etc/hosts。その後、基本的に即時の「ファイル」を介して解決する必要があります。もちろん、これには0.0.0.0に名前を付ける必要があり、アプリケーションの動作が変更または変更されない可能性があります。これがうまくいけば、これは最も簡単なオプションです。

  • ボックスにDNSが必要ない場合は、ボックスからDNSを削除して完全に無効にします/etc/nsswitch.conf

  • 0.0.0.in-addr.arpaに対する権限を付与するように構成できるローカルDNSキャッシュを実行します。その後、NXDOMAINを0.0.0.0にすばやく返すことができます。これを実行できるローカルキャッシュを提供するように設計された複数のプログラムがあります。たとえば、dnsmasqはかなり有名です。必要な機能に応じて、Unboundなどの他の機能もあります。

  • 少なくともglibcを使用すると、次のように入力してタイムアウトと再試行のoptions timeout:2 attempts:4動作を変更できます/etc/resolv.conf。タイムアウトを減らすと、DNSサーバーが問題を解決するのに時間がかかる可能性があるため、試行回数を増やす必要があります(ただし、解決が完了したらキャッシュからすばやく応答する必要があります)。

  • 独自のNSSモジュールを作成して、hosts0.0.0.0エラーをすばやく見つけることができます。少なくともglibcの場合は、次のことを行うことができます。glibc マニュアルセクション 29

おすすめ記事