Browse Source

[904] documented RR class configurations

JINMEI Tatuya 13 years ago
parent
commit
1feeca7c22
1 changed files with 205 additions and 20 deletions
  1. 205 20
      src/lib/dns/tests/testdata/gen_wiredata.py.in

+ 205 - 20
src/lib/dns/tests/testdata/gen_wiredata.py.in

@@ -312,11 +312,11 @@ What you are expected to do is as follows:
   dump() method would look like this:
 
     def dump(self, f):
-      if self.rdlen is None:
-          self.rdlen = 2
-      self.dump_header(f, self.rdlen)
-      f.write('# Value=%d\\n' % (self.value))
-      f.write('%04x\\n' % (self.value))
+        if self.rdlen is None:
+            self.rdlen = 2
+        self.dump_header(f, self.rdlen)
+        f.write('# Value=%d\\n' % (self.value))
+        f.write('%04x\\n' % (self.value))
 
   The first f.write() call is not mandatory, but is encouraged to
   be provided so that the generated files will be more human readable.
@@ -375,7 +375,6 @@ rdict_nsec3_algorithm = dict([(dict_nsec3_algorithm[k], k.upper()) for k in \
 header_xtables = { 'qr' : dict_qr, 'opcode' : dict_opcode,
                    'rcode' : dict_rcode }
 question_xtables = { 'rrtype' : dict_rrtype, 'rrclass' : dict_rrclass }
-rrsig_xtables = { 'algorithm' : dict_algorithm }
 
 def parse_value(value, xtable = {}):
     if re.search(re_hex, value):
@@ -593,6 +592,13 @@ class RR:
             f.write('%s\n' % rdlen_data)
 
 class A(RR):
+    '''Implements rendering A RDATA (of class IN) in the test data format.
+
+    Configurable parameter is as follows (see the description of the
+    same name of attribute for the default value):
+    - address (string): The address field.  This must be a valid textual
+      IPv4 address.
+    '''
     RDLEN_DEFAULT = 4           # fixed by default
     address = '192.0.2.1'
 
@@ -606,6 +612,14 @@ class A(RR):
                                         bin_address[2], bin_address[3]))
 
 class AAAA(RR):
+    '''Implements rendering AAAA RDATA (of class IN) in the test data
+    format.
+
+    Configurable parameter is as follows (see the description of the
+    same name of attribute for the default value):
+    - address (string): The address field.  This must be a valid textual
+      IPv6 address.
+    '''
     RDLEN_DEFAULT = 16          # fixed by default
     address = '2001:db8::1'
 
@@ -619,6 +633,14 @@ class AAAA(RR):
         f.write('\n')
 
 class NS(RR):
+    '''Implements rendering NS RDATA in the test data format.
+
+    Configurable parameter is as follows (see the description of the
+    same name of attribute for the default value):
+    - nsname (string): The NSDNAME field.  The string must be
+      interpreted as a valid domain name.
+    '''
+
     nsname = 'ns.example.com'
 
     def dump(self, f):
@@ -630,6 +652,19 @@ class NS(RR):
         f.write('%s\n' % nsname_wire)
 
 class SOA(RR):
+    '''Implements rendering SOA RDATA in the test data format.
+
+    Configurable parameters are as follows (see the description of the
+    same name of attribute for the default value):
+    - mname/rname (string): The MNAME/RNAME fields, respectively.  The
+      string must be interpreted as a valid domain name.
+    - serial (32-bit int): The SERIAL field
+    - refresh (32-bit int): The REFRESH field
+    - retry (32-bit int): The RETRY field
+    - expire (32-bit int): The EXPIRE field
+    - minimum (32-bit int): The MINIMUM field
+    '''
+
     mname = 'ns.example.com'
     rname = 'root.example.com'
     serial = 2010012601
@@ -653,9 +688,30 @@ class SOA(RR):
                                                 self.minimum))
 
 class TXT(RR):
-    nstring = 1                 # number of character-strings
-    stringlen = -1              # default string length, auto-calculate
-    string = 'Test String'      # default string
+    '''Implements rendering TXT RDATA in the test data format.
+
+    Configurable parameters are as follows (see the description of the
+    same name of attribute for the default value):
+    - nstring (int): number of character-strings
+    - stringlenN (int) (int, N = 0, ..., nstring-1): the length of the
+      N-th character-string.
+    - stringN (string, N = 0, ..., nstring-1): the N-th
+      character-string.
+    - stringlen (int): the default string.  If nstring >= 1 and the
+      corresponding stringlenN isn't specified in the spec file, this
+      value will be used.  If this parameter isn't specified either,
+      the length of the string will be used.  Note that it means
+      this parameter (or any stringlenN) doesn't have to be specified
+      unless you want to intentially build a broken character string.
+    - string (string): the default string.  If nstring >= 1 and the
+      corresponding stringN isn't specified in the spec file, this
+      string will be used.
+    '''
+
+    nstring = 1
+    stringlen = None
+    string = 'Test String'
+
     def dump(self, f):
         stringlen_list = []
         string_list = []
@@ -672,7 +728,7 @@ class TXT(RR):
                 stringlen_list.append(self.__dict__[key_stringlen])
             else:
                 stringlen_list.append(self.stringlen)
-            if stringlen_list[-1] < 0:
+            if stringlen_list[-1] is None:
                 stringlen_list[-1] = int(len(wirestring_list[-1]) / 2)
         if self.rdlen is None:
             self.rdlen = int(len(''.join(wirestring_list)) / 2) + self.nstring
@@ -685,10 +741,13 @@ class TXT(RR):
                                     wirestring_list[i]))
 
 class RP(RR):
-    '''Implements rendering RP RDATA in the wire format.
-    Configurable parameters are as follows:
-    - mailbox: The mailbox field.  Default is 'root.example.com'
-    - text: The text field.  Default is 'rp-text.example.com'
+    '''Implements rendering RP RDATA in the test data format.
+
+    Configurable parameters are as follows (see the description of the
+    same name of attribute for the default value):
+    - mailbox (string): The mailbox field.
+    - text (string): The text field.
+    These strings must be interpreted as a valid domain name.
     '''
     mailbox = 'root.example.com'
     text = 'rp-text.example.com'
@@ -706,7 +765,26 @@ class RP(RR):
 class NSECBASE(RR):
     '''Implements rendering NSEC/NSEC3 type bitmaps commonly used for
     these RRs.  The NSEC and NSEC3 classes will be inherited from this
-    class.'''
+    class.
+
+    Configurable parameters are as follows (see the description of the
+    same name of attribute for the default value):
+    - nbitmap (int): The number of type bitmaps.
+    The following three define the bitmaps.  If suffixed with "N"
+    (0 <= N < nbitmaps), it means the definition for the N-th bitmap.
+    If there is no suffix (e.g., just "block", it means the default
+    for any unspecified values)
+    - block[N] (8-bit int): The Window Block.
+    - maplen[N] (8-bit int): The Bitmap Length.  The default "maplen"
+      can also be unspecified (with being set to None), in which case
+      the corresponding length will be calculated from the bitmap.
+    - bitmap[N] (string): The Bitmap.  This must be the hexadecimal
+      representation of the bitmap field.  For example, for a bitmap
+      where the 7th and 15th bits (and only these bits) are set, it
+      must be '0101'.  Note also that the value must be quated with
+      single quatations because it could also be interpreted as an
+      integer.
+    '''
     nbitmap = 1                 # number of bitmaps
     block = 0
     maplen = None              # default bitmap length, auto-calculate
@@ -747,6 +825,15 @@ class NSECBASE(RR):
                     (block_list[i], maplen_list[i], bitmap_list[i]))
 
 class NSEC(NSECBASE):
+    '''Implements rendering NSEC RDATA in the test data format.
+
+    Configurable parameters are as follows (see the description of the
+    same name of attribute for the default value):
+    - Type bitmap related parameters: see class NSECBASE
+    - nextname (string): The Next Domain Name field.  The string must be
+      interpreted as a valid domain name.
+    '''
+
     nextname = 'next.example.com'
     def dump_fixedpart(self, f, bitmap_totallen):
         name_wire = encode_name(self.nextname)
@@ -760,6 +847,28 @@ class NSEC(NSECBASE):
         f.write('%s\n' % name_wire)
 
 class NSEC3(NSECBASE):
+    '''Implements rendering NSEC3 RDATA in the test data format.
+
+    Configurable parameters are as follows (see the description of the
+    same name of attribute for the default value):
+    - Type bitmap related parameters: see class NSECBASE
+    - hashalg (8-bit int): The Hash Algorithm field.  Note that
+      currently the only defined algorithm is SHA-1, for which a value
+      of 1 will be used, and it's the default.  So this implementation
+      does not support any string representation right now.
+    - optout (bool): The Opt-Out flag of the Flags field.
+    - mbz (7-bit int): The rest of the Flags field.  This value will
+      be left shifted for 1 bit and then OR-ed with optout to
+      construct the complete Flags field.
+    - iterations (16-bit int): The Iterations field.
+    - saltlen (int): The Salt Length field.
+    - salt (string): The Salt field.  It is converted to a sequence of
+      ascii codes and its hexadecimal representation will be used.
+    - hashlen (int): The Hash Length field.
+    - hash (string): The Next Hashed Owner Name field.  This parameter
+      is interpreted as "salt".
+    '''
+
     hashalg = 1                 # SHA-1
     optout = False              # opt-out flag
     mbz = 0                     # other flag fields (none defined yet)
@@ -791,9 +900,37 @@ class NSEC3(NSECBASE):
                                 encode_string(self.hash)))
 
 class RRSIG(RR):
-    covered = 1                 # A
-    algorithm = 5               # RSA-SHA1
-    labels = -1                 # auto-calculate (#labels of signer)
+    '''Implements rendering RRSIG RDATA in the test data format.
+
+    Configurable parameters are as follows (see the description of the
+    same name of attribute for the default value):
+    - covered (int or string): The Type Covered field.  If specified
+      as an integer, it must be the 16-bit RR type value of the
+      covered type.  If specifed as a string, it must be the textual
+      mnemonic of the type.
+    - algorithm (int or string): The Algorithm field.   If specified
+      as an integer, it must be the 8-bit algorithm number as defined
+      in RFC4034.  If specifed as a string, it must be one of the keys
+      of dict_algorithm (case insensitive).
+    - labels (int): The Labels field.  If omitted (the corresponding
+      variable being set to None), the number of labels of "signer"
+      (excluding the trailing null label as specified in RFC4034) will
+      be used.
+    - originalttl (32-bit int): The Original TTL field.
+    - expiration (32-bit int): The Expiration TTL field.
+    - inception (32-bit int): The Inception TTL field.
+    - tag (16-bit int): The Key Tag field.
+    - signer (string): The Signer's Name field.  The string must be
+      interpreted as a valid domain name.
+    - signature (int): The Signature field.  Right now only a simple
+      integer form is supported.  A prefix of "0" will be prepended if
+      the resulting hexadecimal representation consists of an odd
+      number of characters.
+    '''
+
+    covered = 'A'
+    algorithm = 'RSASHA1'
+    labels = None                 # auto-calculate (#labels of signer)
     originalttl = 3600
     expiration = int(time.mktime(datetime.strptime('20100131120000',
                                                    dnssec_timefmt).timetuple()))
@@ -802,14 +939,21 @@ class RRSIG(RR):
     tag = 0x1035
     signer = 'example.com'
     signature = 0x123456789abcdef123456789abcdef
+
     def dump(self, f):
         name_wire = encode_name(self.signer)
-        sig_wire = '%x' % self.signature 
+        sig_wire = '%x' % self.signature
+        if len(sig_wire) % 2 != 0:
+            sig_wire = '0' + sig_wire
         if self.rdlen is None:
             self.rdlen = int(18 + len(name_wire) / 2 + len(str(sig_wire)) / 2)
         self.dump_header(f, self.rdlen)
 
-        if self.labels < 0:
+        if type(self.covered) is str:
+            self.covered = dict_rrtype[self.covered.lower()]
+        if type(self.algorithm) is str:
+            self.algorithm = dict_algorithm[self.algorithm.lower()]
+        if self.labels is None:
             self.labels = count_namelabels(self.signer)
         f.write('# Covered=%s Algorithm=%s Labels=%d OrigTTL=%d\n' %
                 (code_totext(self.covered, rdict_rrtype),
@@ -824,6 +968,47 @@ class RRSIG(RR):
         f.write('%04x %s %s\n' % (self.tag, name_wire, sig_wire))
 
 class TSIG(RR):
+    '''Implements rendering TSIG RDATA in the test data format.
+
+    As a meta RR type TSIG uses some non common parameters.  This
+    class overrides some of the default attributes of the RR class
+    accordingly:
+    - rr_class is set to 'ANY'
+    - rr_ttl is set to 0
+    Like other derived classes these can be overridden via the spec
+    file.
+
+    Other configurable parameters are as follows (see the description
+    of the same name of attribute for the default value):
+    - algorithm (string): The Algorithm Name field.  The value is
+      generally interpreted as a domain name string, and will
+      typically be one of the standard algorithm names defined in
+      RFC4635.  For convenience, however, a shortcut value "hmac-md5"
+      is allowed instead of the standard "hmac-md5.sig-alg.reg.int".
+    - time_signed (48-bit int): The Time Signed field.
+    - fudge (16-bit int): The Fudge field.
+    - mac_size (int): The MAC Size field.  If omitted, the common value
+      determined by the algorithm will be used.
+    - mac (int or string): The MAC field.  If specified as an integer,
+      the integer value is used as the MAC, possibly with prepended
+      0's so that the total length will be mac_size.  If specifed as a
+      string, it is converted to a sequence of ascii codes and its
+      hexadecimal representation will be used.  So, for example, if
+      "mac" is set to 'abc', it will be converted to '616263'.  Note
+      that in this case the length of "mac" may not be equal to
+      mac_size.  If unspecified, the mac_size number of '78' (ascii
+      code of 'x') will be used.
+    - original_id (16-bit int): The Original ID field.
+    - error (16-bit int): The Error field.
+    - other_len (int): The Other Len field.
+    - other_data (int or string): The Other Data field.  This is
+      interpreted just like "mac" except that other_len is used
+      instead of mac_size.  If unspecified this will be empty unless
+      the "error" is set to 18 (which means the "BADTIME" error), in
+      which case a hexadecimal representation of "time_signed + fudge
+      + 1" will be used.
+    '''
+
     algorithm = 'hmac-sha256'
     time_signed = 1286978795    # arbitrarily chosen default
     fudge = 300