2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-30 21:45:37 +00:00

[trac813] preparation for further tests: introducing the RR class to centralize

the RR type independent rendering logic.  Also added the trivial A/NS classes.
This commit is contained in:
JINMEI Tatuya
2011-05-02 15:23:13 -07:00
parent 0e3b55edc7
commit 98d147ea68

View File

@@ -15,7 +15,7 @@
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
import configparser, re, time, sys import configparser, re, time, socket, sys
from datetime import datetime from datetime import datetime
from optparse import OptionParser from optparse import OptionParser
@@ -215,6 +215,74 @@ class EDNS:
f.write('# RDLEN=%d\n' % self.rdlen) f.write('# RDLEN=%d\n' % self.rdlen)
f.write('%04x\n' % self.rdlen) f.write('%04x\n' % self.rdlen)
class RR:
'''This is a base class for various types of RR test data.
For each RR type (A, AAAA, NS, etc), we define a derived class of RR
to dump type specific RDATA parameters. This class defines parameters
common to all types of RDATA, namely the owner name, RR class and TTL.
The dump() method of derived classes are expected to call dump_header(),
whose default implementation is provided in this class. This method
decides whether to dump the test data as an RR (with name, type, class)
or only as RDATA (with its length), and dumps the corresponding data
via the specified file object.
By convention we assume derived classes are named after the common
standard mnemonic of the corresponding RR types. For example, the
derived class for the RR type SOA should be named "SOA".
Configurable parameters are as follows:
- as_rr (bool): Whether or not the data is to be dumped as an RR. False
by default.
- rr_class (string): The RR class of the data. Only meaningful when the
data is dumped as an RR. Default is 'IN'.
- rr_ttl (integer): The TTL value of the RR. Only meaningful when the
data is dumped as an RR. Default is 86400 (1 day).
'''
def __init__(self):
self.as_rr = False
# only when as_rr is True, same for class/TTL:
self.rr_name = 'example.com'
self.rr_class = 'IN'
self.rr_ttl = 86400
def dump_header(self, f, rdlen):
type_txt = self.__class__.__name__
type_code = parse_value(type_txt, dict_rrtype)
if self.as_rr:
rrclass = parse_value(self.rr_class, dict_rrclass)
f.write('\n# %s RR (QNAME=%s Class=%s TTL=%d RDLEN=%d)\n' %
(type_txt, self.rr_name,
code_totext(rrclass, rdict_rrclass), self.rr_ttl, rdlen))
f.write('%s %04x %04x %08x %04x\n' %
(encode_name(self.rr_name), type_code, rrclass,
self.rr_ttl, rdlen))
else:
f.write('\n# %s RDATA (RDLEN=%d)\n' % (type_txt, rdlen))
f.write('%04x\n' % rdlen)
class A(RR):
rdlen = 4 # fixed by default
address = '192.0.2.1'
def dump(self, f):
self.dump_header(f, self.rdlen)
f.write('# Address=%s\n' % (self.address))
bin_address = socket.inet_aton(self.address)
f.write('%02x%02x%02x%02x\n' % (bin_address[0], bin_address[1],
bin_address[2], bin_address[3]))
class NS(RR):
rdlen = None # auto calculate
nsname = 'ns.example.com'
def dump(self, f):
nsname_wire = encode_name(self.nsname)
if self.rdlen is None:
self.rdlen = len(nsname_wire) / 2
self.dump_header(f, self.rdlen)
f.write('# NS name=%s\n' % (self.nsname))
f.write('%s\n' % nsname_wire)
class SOA: class SOA:
# this currently doesn't support name compression within the RDATA. # this currently doesn't support name compression within the RDATA.
rdlen = -1 # auto-calculate rdlen = -1 # auto-calculate
@@ -432,12 +500,7 @@ class RRSIG:
f.write('# Tag=%d Signer=%s and Signature\n' % (self.tag, self.signer)) f.write('# Tag=%d Signer=%s and Signature\n' % (self.tag, self.signer))
f.write('%04x %s %s\n' % (self.tag, name_wire, sig_wire)) f.write('%04x %s %s\n' % (self.tag, name_wire, sig_wire))
class TSIG: class TSIG(RR):
as_rr = False
rr_name = 'example.com' # only when as_rr is True, same for class/TTL
rr_class = 'ANY'
rr_ttl = 0
rdlen = None # auto-calculate rdlen = None # auto-calculate
algorithm = 'hmac-sha256' algorithm = 'hmac-sha256'
time_signed = 1286978795 # arbitrarily chosen default time_signed = 1286978795 # arbitrarily chosen default
@@ -449,12 +512,17 @@ class TSIG:
other_len = None # 6 if error is BADTIME; otherwise 0 other_len = None # 6 if error is BADTIME; otherwise 0
other_data = None # use time_signed + fudge + 1 for BADTIME other_data = None # use time_signed + fudge + 1 for BADTIME
dict_macsize = { 'hmac-md5' : 16, 'hmac-sha1' : 20, 'hmac-sha256' : 32 } dict_macsize = { 'hmac-md5' : 16, 'hmac-sha1' : 20, 'hmac-sha256' : 32 }
# TSIG has some special defaults
def __init__(self):
self.rr_class = 'ANY'
self.rr_ttl = 0
def dump(self, f): def dump(self, f):
if str(self.algorithm) == 'hmac-md5': if str(self.algorithm) == 'hmac-md5':
name_wire = encode_name('hmac-md5.sig-alg.reg.int') name_wire = encode_name('hmac-md5.sig-alg.reg.int')
else: else:
name_wire = encode_name(self.algorithm) name_wire = encode_name(self.algorithm)
rdlen = self.rdlen
mac_size = self.mac_size mac_size = self.mac_size
if mac_size is None: if mac_size is None:
if self.algorithm in self.dict_macsize.keys(): if self.algorithm in self.dict_macsize.keys():
@@ -473,20 +541,10 @@ class TSIG:
if self.error == 18 else '' if self.error == 18 else ''
else: else:
other_data = encode_string(self.other_data, other_len) other_data = encode_string(self.other_data, other_len)
if rdlen is None: if self.rdlen is None:
rdlen = int(len(name_wire) / 2 + 16 + len(mac) / 2 + \ self.rdlen = int(len(name_wire) / 2 + 16 + len(mac) / 2 + \
len(other_data) / 2) len(other_data) / 2)
if self.as_rr: self.dump_header(f, self.rdlen)
rrclass = parse_value(self.rr_class, dict_rrclass)
f.write('\n# TSIG RR (QNAME=%s Class=%s TTL=%d RDLEN=%d)\n' %
(self.rr_name, code_totext(rrclass, rdict_rrclass),
self.rr_ttl, rdlen))
f.write('%s %04x %04x %08x %04x\n' %
(encode_name(self.rr_name), dict_rrtype['tsig'],
rrclass, self.rr_ttl, rdlen))
else:
f.write('\n# TSIG RDATA (RDLEN=%d)\n' % rdlen)
f.write('%04x\n' % rdlen);
f.write('# Algorithm=%s Time-Signed=%d Fudge=%d\n' % f.write('# Algorithm=%s Time-Signed=%d Fudge=%d\n' %
(self.algorithm, self.time_signed, self.fudge)) (self.algorithm, self.time_signed, self.fudge))
f.write('%s %012x %04x\n' % (name_wire, self.time_signed, self.fudge)) f.write('%s %012x %04x\n' % (name_wire, self.time_signed, self.fudge))
@@ -502,7 +560,8 @@ def get_config_param(section):
config_param = {'name' : (Name, {}), config_param = {'name' : (Name, {}),
'header' : (DNSHeader, header_xtables), 'header' : (DNSHeader, header_xtables),
'question' : (DNSQuestion, question_xtables), 'question' : (DNSQuestion, question_xtables),
'edns' : (EDNS, {}), 'soa' : (SOA, {}), 'txt' : (TXT, {}), 'edns' : (EDNS, {}), 'a' : (A, {}), 'ns' : (NS, {}),
'soa' : (SOA, {}), 'txt' : (TXT, {}),
'rp' : (RP, {}), 'rrsig' : (RRSIG, {}), 'rp' : (RP, {}), 'rrsig' : (RRSIG, {}),
'nsec' : (NSEC, {}), 'nsec3' : (NSEC3, {}), 'nsec' : (NSEC, {}), 'nsec3' : (NSEC3, {}),
'tsig' : (TSIG, {}) } 'tsig' : (TSIG, {}) }