Friday, March 8, 2013

python-dnspython を使う場合のタイムアウトについて

python から DNS を触りに行ったりしていて気が付いたことがあったのでメモ。

python には dnspython というライブラリがあって、DNS Update 機能等も含めて便利に使えるようになっている。Ubuntu/Debian では、python-dnspython という名前のパッケージを apt-get install すればよい。

さて、DNSサーバも落ちたりするわけで、そういう場合に備えて、特に自前で運用しているDNSサーバなら、単純には

/etc/resolv.conf

にこんな感じで、

nameserver  192.168.0.1
nameserver  192.168.0.2
search  example.com
options  timeout:5  attempt:1

複数DNSサーバを並べて、options で timeout やリトライ回数を書いておくとか、そういう感じかと思う。

さて、このへんから本題。
素人の私は、上記のように書いておけば、dnspython が nslookup なり dig なりのように中から参照してくれるのかと思い込んでいたのだが、そうではないのだった。

(現行stable版の 1.10.0の)ドキュメント


を読んでみてもよくわからないので、最初は「もしかしたら、timeoutを指定できないのか?」と思ったら、とんだ濡れ衣で、ちゃんとできた。:o

以下のような感じで、名前解決なら Resolver オブジェクトを作ったあと、timeout とか lifetime といった attribute に秒単位で設定すればよい。

    def lookup(hostname):
        import dns.resolver
           :
        resolver = dns.resolver.Resolver()
        resolver.timeout = 5.0
        resolver.lifetime = 5.0
           :

実は、このへんは以下で参照可能なソースの


以下のあたりのResolver クラスの定義をつらつら眺めていて判明したのだった。:o

 394 -class Resolver(object): 
 395      """DNS stub resolver 
    (snip)
 408      @ivar timeout: The number of seconds to wait for a response from a 
 409      server, before timing out. 
 410      @type timeout: float 
 411      @ivar lifetime: The total number of seconds to spend trying to get an 
 412      answer to the question.  If the lifetime expires, a Timeout exception 
 413      will occur. 
 414      @type lifetime: float 

ところで、ここでもう一つ注意がある。

timeout や lifetime の型は float であって int ではないことに注意。実際、上記のサンプルの 5.0 のところは、最初 5 と書いていたのだが、私が動かしてみた限りは思った通りに timeout してくれず、(たぶん)デフォルト値の 30 秒のままだった :(

文字列と判断されて無視されたのかなぁ...とか、つらつら思いつつ、初心者の日々は流れていくのであった。

No comments:

Post a Comment