def test_authority_domain(self):
     question = Question(Name("server1.gumpe"), Type.A, Class.IN)
     header = Header(1337, 0, 1, 0, 0, 0)
     query = Message(header, questions=[question])
     s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
     s.sendto(query.to_bytes(), (SERVER, PORT))
     data = s.recv(512)
     s.close()
     message = Message.from_bytes(data)
     self.assertCountEqual(message.answers, [
         ResourceRecord(
             name=Name("server1.gumpe."),
             type_=Type.A,
             class_=Class.IN,
             ttl=0,
             rdata=ARecordData("10.0.1.5"),
         ),
         ResourceRecord(
             name=Name("server1.gumpe."),
             type_=Type.A,
             class_=Class.IN,
             ttl=0,
             rdata=ARecordData("10.0.1.4"),
         ),
     ])
예제 #2
0
 def test_resource_from_bytes(self, MockName, MockRData):
     MockName.from_bytes.return_value = (Name("example.com"), 13)
     MockRData.create_from_bytes.return_value = ARecordData("1.1.1.1")
     packet = (b"\x07example\x03com\x00\x00\x01\x00\x02\x00\x00\x00\x03\x00"
               b"\x04\x01\x01\x01\x01")
     record1, offset = ResourceRecord.from_bytes(packet, 0)
     record2 = ResourceRecord(Name("example.com"), Type.A, Class.CS, 3,
                              ARecordData("1.1.1.1"))
     self.assertEqual(record1, record2)
     MockName.from_bytes.assert_called_with(packet, 0)
     MockRData.create_from_bytes.assert_called_with(Type.A, packet, 23, 4)
 def test_concurrent_requests(self):
     queries = []
     answers = []
     question = Question(Name("gaia.cs.umass.edu"), Type.A, Class.IN)
     header = Header(1337, 0, 1, 0, 0, 0)
     header.rd = 1
     queries.append(Message(header, questions=[question]))
     answers.append([
         ResourceRecord(name=Name("gaia.cs.umass.edu"),
                        type_=Type.A,
                        class_=Class.IN,
                        ttl=0,
                        rdata=ARecordData("128.119.245.12")),
     ])
     question = Question(Name("server2.gumpe"), Type.A, Class.IN)
     header = Header(420, 0, 1, 0, 0, 0)
     queries.append(Message(header, questions=[question]))
     answers.append([
         ResourceRecord(name=Name("server2.gumpe"),
                        type_=Type.A,
                        class_=Class.IN,
                        ttl=0,
                        rdata=ARecordData("10.0.1.7")),
     ])
     header = Header(69, 0, 1, 0, 0, 0)
     question = Question(Name("www.gumpe"), Type.A, Class.IN)
     queries.append(Message(header, questions=[question]))
     answers.append([
         ResourceRecord(name=Name("www.gumpe"),
                        type_=Type.A,
                        class_=Class.IN,
                        ttl=0,
                        rdata=ARecordData("10.0.1.7")),
         ResourceRecord(name=Name("www.gumpe"),
                        type_=Type.CNAME,
                        class_=Class.IN,
                        ttl=0,
                        rdata=CNAMERecordData(Name("server2.gumpe"))),
     ])
     sockets = [
         socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
         for _ in range(len(queries))
     ]
     for i in range(len(sockets)):
         sockets[i].sendto(queries[i].to_bytes(), (SERVER, PORT))
     responses = []
     for i in range(len(sockets)):
         responses.append(Message.from_bytes(sockets[i].recv(1024)))
     for i in range(len(sockets)):
         sockets[i].close()
     for i in range(len(queries)):
         self.assertCountEqual(responses[i].answers, answers[i])
예제 #4
0
 def testCache(self):
     cac = RecordCache(0)
     self.assertEqual(cac.lookup("abcdefghqqqq.com", Type.A, Class.IN), [])
     test = ResourceRecord("blabla.com", Type.A, Class.IN, 0,
                           ARecordData("111.111.111.111"))
     cac.add_record(test)
     self.assertEqual(cac.lookup("blabla.com", Type.A, Class.IN), test)
예제 #5
0
    def read_master_file(self, filename):
        """Read the zone from a master file

        See section 5 of RFC 1035.

        Args:
            filename (str): the filename of the master file
        """
        temp = []
        """Read the cache file from disk"""
        with open("roothints.md") as file_:
            lines = file_.readlines()
        for l in lines:
            #remove comments
            b = re.sub(r';[^\n]*', "", l)
            te = l.split()
            if (te[0] != ';'):
                temp.append(te)
            if ("." in te[0]):
                type_ = self.getType(te[2])
                if (type_ == Type.A):
                    rdata = ARecordData(te[3])
                elif (type_ == Type.NS):
                    rdata = NSRecordData(te[3])
                elif (type_ == Type.CNAME):
                    rdata = CNAMERecordData(te[3])
                rr = ResourceRecord(te[0], type_, Class.IN, te[1], rdata)
                self.records.update({te[0]: rr})
 def test_expired_cache_entry(self):
     cache = RecordCache(0)
     record = ResourceRecord(
         name=Name("bonobo.putin"),
         type_=Type.A,
         class_=Class.IN,
         ttl=0,
         rdata=ARecordData("1.0.0.1"),
     )
     cache.add_record(record)
     self.assertEqual(cache.lookup(Name("bonobo.putin"), Type.A, Class.IN),
                      None)
 def test_invalid_domain_from_cache(self):
     cache = RecordCache(0)
     record = ResourceRecord(
         name=Name("bonobo.putin"),
         type_=Type.A,
         class_=Class.IN,
         ttl=60,
         rdata=ARecordData("1.0.0.1"),
     )
     cache.add_record(record)
     self.assertEqual(cache.lookup(Name("bonobo.putin"), Type.A, Class.IN),
                      record)
 def test_ttl_overwrite(self):
     cache = RecordCache(60)
     record = ResourceRecord(
         name=Name("bonobo.putin"),
         type_=Type.A,
         class_=Class.IN,
         ttl=0,
         rdata=ARecordData("1.0.0.1"),
     )
     cache.add_record(record)
     cache_entry = cache.lookup(Name("bonobo.putin"), Type.A, Class.IN)
     self.assertEqual(cache_entry, record)
     self.assertEqual(cache_entry.ttl, 60)
 def test_outside_zone(self):
     question = Question(Name("gaia.cs.umass.edu"), Type.A, Class.IN)
     header = Header(1337, 0, 1, 0, 0, 0)
     header.rd = 1
     query = Message(header, questions=[question])
     s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
     s.sendto(query.to_bytes(), (SERVER, PORT))
     data = s.recv(512)
     s.close()
     message = Message.from_bytes(data)
     self.assertEqual(message.answers, [
         ResourceRecord(name=Name("gaia.cs.umass.edu"),
                        type_=Type.A,
                        class_=Class.IN,
                        ttl=0,
                        rdata=ARecordData("128.119.245.12")),
     ])
 def test_expired_cache_entry(self):
     cache = RecordCache(0)
     resolver = Resolver(5, cache)
     cache.add_record(
         ResourceRecord(
             name=Name("hw.gumpe"),
             type_=Type.A,
             class_=Class.IN,
             ttl=0,
             rdata=ARecordData("1.0.0.2"),
         ))
     cache.add_record(
         ResourceRecord(
             name=Name("hw.gumpe"),
             type_=Type.CNAME,
             class_=Class.IN,
             ttl=0,
             rdata=CNAMERecordData(Name("gumpe.hw")),
         ))
     self.assertEqual(resolver.gethostbyname("hw.gumpe"),
                      ("hw.gumpe", [], []))
 def test_invalid_domain_from_cache(self):
     cache = RecordCache(0)
     resolver = Resolver(5, cache)
     cache.add_record(
         ResourceRecord(
             name=Name("bonobo.putin"),
             type_=Type.A,
             class_=Class.IN,
             ttl=60,
             rdata=ARecordData("1.0.0.1"),
         ))
     cache.add_record(
         ResourceRecord(
             name=Name("bonobo.putin"),
             type_=Type.CNAME,
             class_=Class.IN,
             ttl=60,
             rdata=CNAMERecordData(Name("putin.bonobo")),
         ))
     self.assertEqual(resolver.gethostbyname("bonobo.putin"),
                      ("bonobo.putin", ["putin.bonobo."], ["1.0.0.1"]))
예제 #12
0
def getType(t):
    if(t == 'A'):
        return Type.A
    if(t == 'NS'):
        return Type.NS
    if(t == 'CNAME'):
        return Type.CNAME

temp = []
"""Read the cache file from disk"""
with open("roothints.md") as file_:
    lines = file_.readlines()
for l in lines:
    #remove comments
    b = re.sub(r';[^\n]*', "", l)
    te = l.split()
    if(te[0] != ';'):
        temp.append(te)
    if("." in te[0]):
        type_ = getType(te[2])
        if(type_ == Type.A):
            rdata = ARecordData(te[3])
        elif(type_ == Type.NS):
            rdata = NSRecordData(te[3])
        elif(type_ == Type.CNAME):
            rdata = CNAMERecordData(te[3])
        rr = ResourceRecord(te[0], type_, Class.IN, te[1], rdata)
        print(rr.to_dict())

    
예제 #13
0
    def serve(self):
        """Start serving requests"""
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.bind(("", self.port))

        while not self.done:
            data, address = sock.recvfrom(65565)
            message = Message.from_bytes(data)

            rd = message.header.rd
            rcode = 0
            aa = 1

            self.log("REQUEST RECIEVED:", address)
            answers, authorities, additionals = self.zone_resolution(message.questions)

            if answers == []:
                if authorities == [] and additionals == []:
                    self.log("\tZONE RESOLUTION FAILED")
                    answers = self.consult_cache(message.questions)

                    if answers == []:
                        self.log("\tCACHE LOOKUP FAILED")
                        rcode = 3
                    else:
                        aa = 0

                if rcode == 3 and rd == 1:
                    rcode = 0
                    self.log("\tCALLING RESOLVER")
                    resolver = Resolver(5, True, 0)
                    resolver.rd = 0
                    resolver.rootip = "198.41.0.4"
                    for q in message.questions:
                        self.log("\t\tRESOLVING:", q.qname)

                        hostname, namelist, iplist = resolver.gethostbyname(str(q.qname))
                        if hostname == str(q.qname):
                            for ip in iplist:
                                answers.append(ResourceRecord(q.qname, Type.A, Class.IN, self.ttl, ARecordData(ip)))
                            for n in namelist:
                                answers.append(ResourceRecord(q.qname, Type.CNAME, Class.IN, self.ttl, CNAMERecordData(n)))

            self.log("SENDING RESPONSE:", rcode, "\n")
            mess = self.build_message(message.header.ident, rd, aa, rcode, message.questions, answers, authorities, additionals)
            sock.sendto(mess.to_bytes(), address)
예제 #14
0
 def consult_cache(self, questions):
     answers = []
     for q in questions:
         res, iplist, namelist = self.check_cache(q.qname)
         if res:
             for ip in iplist:
                 answers.append(ResourceRecord(q.qname, Type.A, Class.IN, self.ttl, ARecordData(ip)))
             for n in namelist:
                 answers.append(ResourceRecord(q.qname, Type.CNAME, Class.IN, self.ttl, CNAMERecordData(n)))
     return answers
예제 #15
0
 def test_testOne(self):
     RR = ResourceRecord(Name("invalid_address.asdas"), Type.A, Class.IN, 2, ARecordData("1.4.1"))
     self.resolver.cache.add_record(RR)
     hostname, aliaslist, ipaddrlist = self.resolver.gethostbyname("invalid_address.asdas")
     self.assertEqual(ipaddrlist[0], "1.4.1")