Skip to content

Instantly share code, notes, and snippets.

@2xyo
Created July 23, 2013 09:17
Show Gist options
  • Select an option

  • Save 2xyo/6061091 to your computer and use it in GitHub Desktop.

Select an option

Save 2xyo/6061091 to your computer and use it in GitHub Desktop.
This is NOT a serious Python DNS benchmark ( adns / dnspython pool / dnspython thread )
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import adns
from Queue import Queue
from threading import Thread
from multiprocessing import Pool
from datetime import datetime
import dns.resolver
q = Queue()
ans = {}
myresolver = dns.resolver.Resolver()
myresolver.use_edns(0, 0, 3824)
myresolver.retry_servfail = True
myresolver.timeout = 10
# version async
def resolve_dns_async(hosts, rr="A", intensity=100):
_adns = adns.init()
resolved_hosts = {}
active_queries = {}
host_queue = hosts[:]
if rr == "A":
rr = adns.rr.A
elif rr == "TXT":
rr = adns.rr.TXT
else:
raise NotImplementedError("RR not not implemented")
def collect_results():
for query in _adns.completed():
answer = query.check()
host = active_queries[query]
del active_queries[query]
if answer[0] == 0:
ip = answer[3]
resolved_hosts[host] = ip
else:
resolved_hosts[host] = None
def finished_resolving():
return len(resolved_hosts) == len(hosts)
while not finished_resolving():
while host_queue and len(active_queries) < intensity:
host = host_queue.pop()
query = _adns.submit(host, rr)
active_queries[query] = host
collect_results()
# Python 2.6
#resolved_hosts = dict((i, j) for (i, j) in resolved_hosts.items() if j)
# Python > 2.7
return {i:j for i, j in resolved_hosts.items() if j}
# version thread
def worker():
while True:
item = q.get()
try:
ans[item[0]] = tuple(str(n) for n in myresolver.query(item[0], item[1]))
except:
pass
q.task_done()
def resolve_dns_thread(hosts, rr="A", intensity=100):
for i in range(intensity):
t = Thread(target=worker)
t.daemon = True
t.start()
for host in hosts:
q.put((host, rr))
q.join()
return ans
# version pool
def worker_pool(host):
rr = host[1]
host = host[0]
try:
return {host: tuple(str(n) for n in myresolver.query(host, rr))}
except:
return None
def resolve_dns_pool(hosts, rr="A", intensity=10):
pool = Pool(processes=intensity)
hosts = [(host, rr) for host in hosts]
return {i.iterkeys().next():i.itervalues().next() for i in pool.map(worker_pool, hosts) if i}
if __name__ == '__main__':
f = open('top-1m.csv')
hosts = [line.split(',')[1].strip() for line in f.readlines()]
f.close()
print "{} domains loaded".format(len(hosts))
try:
for thr in range(50, 1000, 25):
t = datetime.now()
resolve_dns_async(hosts, rr='A', intensity=thr)
print "resolve_dns_async {} // : {}".format(thr, datetime.now() - t)
except Exception as e:
print e
try:
for thr in range(50, 1000, 25):
t = datetime.now()
resolve_dns_thread(hosts, rr='A', intensity=thr)
print "resolve_dns_thread {} threads: {}".format(thr, datetime.now() - t)
except Exception as e:
print e
try:
for thr in range(50, 1000, 250):
t = datetime.now()
resolve_dns_pool(hosts, rr='A', intensity=thr)
print "resolve_dns_pool {} processes: {}".format(thr, datetime.now() - t)
except Exception as e:
print e
options {
# cache
directory "/var/cache/bind";
# No DNSSEC
dnssec-validation no;
dnssec-enable no;
# conform to RFC1035
auth-nxdomain no;
# only add records to the authority and additional
# data sections when they are required
minimal-responses yes;
# provide recursive query behaviour
recursion yes;
# number of simultaneous recursive lookups
recursive-clients 5000;
# maximum number of TCP connections to be supported.
tcp-clients 5000;
# IP address which is allowed to issue recursive queries to the server.
allow-recursion { 127.0.0.1; };
# IP address on which BIND will listen for incoming queries.
listen-on { 127.0.0.1; };
# not listen for any IPv6 traffic
listen-on-v6 { none; };
# maximum time (in seconds) for which the server will
# cache negative (NXDOMAIN) answers
#max-ncache-ttl 30;
# maximum time (in seconds) for which the server will
# cache positive answers
#max-cache-ttl 60;
# file-name to which data will be written when
# the command rndc stats is issued.
statistics-file "bind.stats";
# number of seconds to cache lame delegations or lame servers
lame-ttl 1800;
# Don't log queries
querylog no;
# dig +bufsize=1024 rs.dns-oarc.net TXT +short
edns-udp-size 3843;
};
adns-python==1.2.1
dnspython==1.11.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment