73 lines
2.1 KiB
Python
73 lines
2.1 KiB
Python
#!/usr/bin/env python2
|
|
|
|
""" DNS Resolver
|
|
|
|
This module contains a class for resolving hostnames. You will have to implement
|
|
things in this module. This resolver will be both used by the DNS client and the
|
|
DNS server, but with a different list of servers.
|
|
"""
|
|
|
|
import socket
|
|
|
|
from dns.classes import Class
|
|
from dns.types import Type
|
|
|
|
import dns.cache
|
|
import dns.message
|
|
import dns.rcodes
|
|
|
|
class Resolver(object):
|
|
""" DNS resolver """
|
|
|
|
def __init__(self, caching, ttl):
|
|
""" Initialize the resolver
|
|
|
|
Args:
|
|
caching (bool): caching is enabled if True
|
|
ttl (int): ttl of cache entries (if > 0)
|
|
"""
|
|
self.caching = caching
|
|
self.ttl = ttl
|
|
|
|
def gethostbyname(self, hostname):
|
|
""" Translate a host name to IPv4 address.
|
|
|
|
Currently this method contains an example. You will have to replace
|
|
this example with example with the algorithm described in section
|
|
5.3.3 in RFC 1034.
|
|
|
|
Args:
|
|
hostname (str): the hostname to resolve
|
|
|
|
Returns:
|
|
(str, [str], [str]): (hostname, aliaslist, ipaddrlist)
|
|
"""
|
|
timeout = 2
|
|
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
sock.settimeout(timeout)
|
|
|
|
# Create and send query
|
|
question = dns.message.Question(hostname, Type.A, Class.IN)
|
|
header = dns.message.Header(9001, 0, 1, 0, 0, 0)
|
|
header.qr = 0
|
|
header.opcode = 0
|
|
header.rd = 1
|
|
query = dns.message.Message(header, [question])
|
|
sock.sendto(query.to_bytes(), ("8.8.8.8", 53))
|
|
|
|
# Receive response
|
|
data = sock.recv(512)
|
|
response = dns.message.Message.from_bytes(data)
|
|
|
|
# Get data
|
|
aliases = []
|
|
for additional in response.additionals:
|
|
if additional.type_ == Type.CNAME:
|
|
aliases.append(additional.rdata.data)
|
|
addresses = []
|
|
for answer in response.answers:
|
|
if answer.type_ == Type.A:
|
|
addresses.append(answer.rdata.data)
|
|
|
|
return hostname, aliases, addresses
|