summaryrefslogtreecommitdiff
path: root/project2/proj2_s4498062/dns/resolver.py
diff options
context:
space:
mode:
Diffstat (limited to 'project2/proj2_s4498062/dns/resolver.py')
-rw-r--r--project2/proj2_s4498062/dns/resolver.py48
1 files changed, 29 insertions, 19 deletions
diff --git a/project2/proj2_s4498062/dns/resolver.py b/project2/proj2_s4498062/dns/resolver.py
index ffb7c16..fe46492 100644
--- a/project2/proj2_s4498062/dns/resolver.py
+++ b/project2/proj2_s4498062/dns/resolver.py
@@ -13,7 +13,7 @@ import socket
from dns.classes import Class
from dns.types import Type
-import dns.cache
+from dns.cache import RecordCache
from dns.message import Message, Question, Header
import dns.rcodes
@@ -48,8 +48,16 @@ class Resolver(object):
self.ttl = ttl
self.timeout = timeout
- def do_query(self, hint, hostname, type_, class_=Class.IN):
+ if self.caching:
+ self.cache = RecordCache()
+
+ def do_query(self, hint, hostname, type_, class_=Class.IN, caching=True):
"""Do a query to a hint"""
+ if self.caching and caching:
+ records = self.cache.lookup(hostname, type_, class_)
+ if records != []:
+ return records
+
ident = randint(0, 65535)
header = Header(ident, 0, 1, 0, 0, 0)
header.qr = 0
@@ -65,19 +73,22 @@ class Resolver(object):
data = sock.recv(512)
resp = Message.from_bytes(data)
if resp.header.ident == ident:
- return resp
+ if self.caching and caching:
+ self.cache.add_records_from(resp)
+ return resp.answers + resp.authorities + resp.additionals
except socket.timeout:
pass
- return None
+ return []
- def do_query_to_multiple(self, hints, hostname, type_, class_=Class.IN):
+ def do_query_to_multiple(
+ self, hints, hostname, type_, class_=Class.IN, caching=True):
"""Do a query to multiple hints, return the remaining hints"""
while hints != []:
hint = hints.pop()
- response = self.do_query(hint, hostname, type_, class_)
+ response = self.do_query(hint, hostname, type_, class_, caching)
if response is not None:
return hints, response
- return [], None
+ return [], []
def gethostbyname(self, hostname):
""" Translate a host name to IPv4 address.
@@ -101,11 +112,7 @@ class Resolver(object):
domain = domains.pop(-1)
aliases = []
while hints != []:
- hints, resp = self.do_query_to_multiple(hints, domain, Type.A)
- if resp == None:
- continue
-
- info = resp.answers + resp.authorities + resp.additionals
+ hints, info = self.do_query_to_multiple(hints, domain, Type.A)
aliases += [
r.rdata.data for r in info
@@ -117,7 +124,8 @@ class Resolver(object):
if r.match(type_=Type.A, class_=Class.IN, name=domain)]
if ips != []:
return hostname, aliases, ips
- # Case 2: name servers
+
+ # Case 2: name servers for this domain
auths = [
r.rdata.data for r in info
if r.match(type_=Type.NS, class_=Class.IN, name=domain)]
@@ -135,21 +143,23 @@ class Resolver(object):
if domain != hostname:
domain = domains.pop(-1) + '.' + domain
continue
- # Case 3: delegation to other name servers
+
+ # Case 3: name servers for the same domain
parent = '.'.join(domain.split('.')[1:])
- refs = [
+ auths = [
r.rdata.data for r in info
if r.match(type_=Type.NS, class_=Class.IN, name=parent)]
ips = [
- add.rdata.data for ns in refs for add in info
+ add.rdata.data for ns in auths for add in info
if add.match(name=ns, type_=Type.A)]
if ips != []:
hints += ips
continue
- if refs != []:
- refs = [h for r in refs for h in self.gethostbyname(r)[2]]
- hints += refs
+ if auths != []:
+ auths = [h for r in auths for h in self.gethostbyname(r)[2]]
+ hints += auths
continue
+
# Case 4: aliases
for alias in aliases:
_, extra_aliases, alias_addresses = self.gethostbyname(alias)