summaryrefslogtreecommitdiff
path: root/project2/proj2_s4498062/dns
diff options
context:
space:
mode:
Diffstat (limited to 'project2/proj2_s4498062/dns')
-rw-r--r--project2/proj2_s4498062/dns/cache.py7
-rw-r--r--project2/proj2_s4498062/dns/resolver.py42
-rw-r--r--project2/proj2_s4498062/dns/resource.py4
-rw-r--r--project2/proj2_s4498062/dns/server.py18
4 files changed, 29 insertions, 42 deletions
diff --git a/project2/proj2_s4498062/dns/cache.py b/project2/proj2_s4498062/dns/cache.py
index 9cde66f..a8b62be 100644
--- a/project2/proj2_s4498062/dns/cache.py
+++ b/project2/proj2_s4498062/dns/cache.py
@@ -53,7 +53,7 @@ class RecordCache(object):
FILE = '.dns.cache'
- def __init__(self):
+ def __init__(self, ttl):
""" Initialize the RecordCache
Args:
@@ -61,15 +61,16 @@ class RecordCache(object):
"""
self.records = []
self.read_cache_file()
+ self.ttl = ttl
def __del__(self):
self.write_cache_file()
def remove_old(self):
"""Remove entries for which the TTL has expired"""
- now = int(time.clock())
+ now = int(time.time())
for record in reversed(self.records):
- if record.ttl + record.timestamp < now:
+ if min(self.ttl, record.ttl) + record.timestamp < now:
self.records.remove(record)
def lookup(self, dname, type_, class_):
diff --git a/project2/proj2_s4498062/dns/resolver.py b/project2/proj2_s4498062/dns/resolver.py
index 2c22adb..4c09681 100644
--- a/project2/proj2_s4498062/dns/resolver.py
+++ b/project2/proj2_s4498062/dns/resolver.py
@@ -48,7 +48,7 @@ class Resolver(object):
self.timeout = timeout
if self.caching:
- self.cache = RecordCache()
+ self.cache = RecordCache(ttl)
def do_query(self, hint, hostname, type_, class_=Class.IN, caching=True):
"""Do a query to a hint"""
@@ -98,9 +98,6 @@ class Resolver(object):
Returns:
(str, [str], [str]): (hostname, aliaslist, ipaddrlist)
"""
- domains = hostname.split('.')
- hints = self.ROOT_SERVERS
-
if self.caching:
addrs = self.cache.lookup(hostname, Type.A, Class.IN)
cnames = self.cache.lookup(hostname, Type.CNAME, Class.IN)
@@ -109,66 +106,45 @@ class Resolver(object):
[r.rdata.data for r in cnames], \
[r.rdata.data for r in addrs]
for cname in cnames:
- print 'trying', cname.rdata.data
cname, aliases, addrs = self.gethostbyname(cname.rdata.data)
if addrs != []:
return str(cname), aliases, addrs
- if domains == []:
+ if hostname == '':
return hostname, [], []
- domain = domains.pop(-1)
+ hints = self.ROOT_SERVERS[:]
aliases = []
while hints != []:
- hints, info = self.do_query_to_multiple(hints, domain, Type.A)
+ hints, info = self.do_query_to_multiple(hints, hostname, Type.A)
aliases += [
r.rdata.data for r in info
- if r.match(type_=Type.CNAME, class_=Class.IN, name=domain)]
+ if r.match(type_=Type.CNAME, class_=Class.IN, name=hostname)]
# Case 1: answer
ips = [
r.rdata.data for r in info
- if r.match(type_=Type.A, class_=Class.IN, name=domain)]
+ if r.match(type_=Type.A, class_=Class.IN, name=hostname)]
if ips != []:
return hostname, aliases, ips
- # Case 2: name servers for this domain
+ # Case 2: name servers
auths = [
r.rdata.data for r in info
- if r.match(type_=Type.NS, class_=Class.IN, name=domain)]
+ if r.match(type_=Type.NS, class_=Class.IN)]
ips = [
add.rdata.data for ns in auths for add in info
if add.match(name=ns, type_=Type.A)]
if ips != []:
hints += ips
- if domain != hostname:
- domain = domains.pop(-1) + '.' + domain
continue
if auths != []:
auths = [h for a in auths for h in self.gethostbyname(a)[2]]
hints += auths
- if domain != hostname:
- domain = domains.pop(-1) + '.' + domain
- continue
-
- # Case 3: name servers for the same domain
- parent = '.'.join(domain.split('.')[1:])
- 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 auths for add in info
- if add.match(name=ns, type_=Type.A)]
- if ips != []:
- hints += ips
- continue
- if auths != []:
- auths = [h for r in auths for h in self.gethostbyname(r)[2]]
- hints += auths
continue
- # Case 4: aliases
+ # Case 3: aliases
for alias in aliases:
_, extra_aliases, alias_addresses = self.gethostbyname(alias)
if alias_addresses != []:
diff --git a/project2/proj2_s4498062/dns/resource.py b/project2/proj2_s4498062/dns/resource.py
index b1c8ae4..e552c22 100644
--- a/project2/proj2_s4498062/dns/resource.py
+++ b/project2/proj2_s4498062/dns/resource.py
@@ -14,7 +14,7 @@ from dns.types import Type
class ResourceRecord(object):
""" DNS resource record """
- def __init__(self, name, type_, class_, ttl, rdata, timestamp=time.time()):
+ def __init__(self, name, type_, class_, ttl, rdata, timestamp=None):
""" Create a new resource record
Args:
@@ -28,7 +28,7 @@ class ResourceRecord(object):
self.class_ = class_
self.ttl = ttl
self.rdata = rdata
- self.timestamp = timestamp
+ self.timestamp = int(timestamp or time.time())
def match(self, name=None, type_=None, class_=None, ttl=None):
"""Check if the record matches properties"""
diff --git a/project2/proj2_s4498062/dns/server.py b/project2/proj2_s4498062/dns/server.py
index f830651..10cad8b 100644
--- a/project2/proj2_s4498062/dns/server.py
+++ b/project2/proj2_s4498062/dns/server.py
@@ -12,7 +12,8 @@ from dns.classes import Class
from dns.types import Type
from dns.message import Header, Message
from dns.resolver import Resolver
-from dns.resource import ResourceRecord, ARecordData, CNAMERecordData
+from dns.resource import \
+ ResourceRecord, ARecordData, NSRecordData, CNAMERecordData
class RequestHandler(Thread):
@@ -112,12 +113,21 @@ class Server(object):
ttl, class_ = 3600000, Class.IN
for match in re.finditer(rgx.ZONE_LINE_DOMAIN, zone, re.MULTILINE):
match = match.groups()
- name = match[0]
- ttl = int(match[1] or match[4] or ttl)
+ name = match[0][:-1]
+ ttl = int(match[1] or match[4] or ttl * 1000) / 1000
class_ = Class.from_string(
match[2] or match[3] or Class.to_string(class_))
type_ = Type.from_string(match[5])
data = match[6]
- record = ResourceRecord(name, type_, class_, ttl, data)
+ if type_ == Type.A:
+ cls = ARecordData
+ elif type_ == Type.NS:
+ cls = NSRecordData
+ elif type_ == Type.CNAME:
+ cls = CNAMERecordData
+ else:
+ continue
+
+ record = ResourceRecord(name, type_, class_, ttl, cls(data))
self.zone.append(record)