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