web-dev-qa-db-ja.com

インターネット接続が最初に成功する前にプログラムが開始された場合、プログラムはホスト名を解決できません

これは 私が投稿したstackoverflowの投稿 に関連しています。

基本的に、組み込みシステム(Buildrootベース)で実行しているPythonスクリプトがあります。 pythonスクリプトは起動時に実行されますが、ユニットが携帯電話の信号のあるエリアにない可能性があるため、それまでにインターネット接続がアップすることを保証できません(pppdに基づく)。

私が見つけたのは、マシンでインターネット接続が確立される前にpythonコードが開始された場合、接続が確立された後でも、pythonコードは解決できないということです。名前。ソケットが接続しようとすると、[Errno -3] Temporary failure in name resolutionエラーが発生します。それを機能させる唯一の方法は、pythonコードを開始する前に少なくとも1回はインターネット接続を確立することです。

Pythonコードが検索できるインターネット接続が少なくとも1回確立された後、システムにどのような変更が加えられていますか?これが起こらないように起動時に設定できるものはありますか?

1
Amr Bekhit

ほとんどのプログラムは、システムDNS構成を読み取ります(/etc/resolv.conf)起動時または最初のネットワークアクセス時に1回だけ。構成が変更されても、構成を再読み取りしません。

システムでは、ネットワークが起動するとDNS構成が変更されるようです(おそらく、未構成からDNSサーバーが構成されている状態に変更されます)。これは非常に一般的であり、システムが常に同じネットワークに接続されているとは限らない場合は避けられません。

プログラムが影響を受けないようにする方法は、ローカルDNSキャッシングサーバーを実行することです。このようにして、アプリケーションのDNS構成を静的にすることができます(常にnameserver 127.0.0.1 in /etc/resolv.conf)、ネットワーク接続によって提供されるサーバーについて通知する必要があるのはDNSキャッシングサーバーのみです。 Dnsmasq は、特に組み込みシステムでは一般的な選択です(Linuxルーターを使用している場合は、おそらくdnsmasqを実行します)。 Buildrootを使用して独自のイメージを構築している場合は、dnsmasqパッケージを含めます。 dnsmasqを使用せずにビルド済みのイメージがある場合でも、Builtrootを介してdnsmasqをインストールするのが最善の策かもしれませんが、Buildrootに慣れていないため、その方法を説明できません。

Pppdが提供するスクリプトフックを使用して、IPが起動した後にスクリプトを呼び出すことができます。たとえば(pppdのマンページから)

/etc/ppp/ip-up
A program or script which is executed when the link is available for 
sending and receiving IP packets (that is, IPCP has come up). It is 
executed with the parameters 

interface-name tty-device speed local-IP-address remote-IP-address ipparam

そこからpythonスクリプトを開始すると、問題ないはずです。

3
gerhard d.

解決テーブルの更新を強制するには、これを実行できます(Linuxの場合)。

import ctypes
libc = ctypes.cdll.LoadLibrary('libc.so.6')
res_init = libc.__res_init
res_init()
2
caleb