BIND 10 #2387: support generic version of rdata::createRdata(text) in DNSKEY, NSEC3, NSEC3PARAM

BIND 10 Development do-not-reply at isc.org
Wed Mar 13 17:15:30 UTC 2013


#2387: support generic version of rdata::createRdata(text) in DNSKEY, NSEC3,
NSEC3PARAM
-------------------------------------+-------------------------------------
            Reporter:  jinmei        |                        Owner:
                Type:  task          |  jinmei
            Priority:  medium        |                       Status:
           Component:  libdns++      |  reviewing
            Keywords:                |                    Milestone:
           Sensitive:  0             |  Sprint-20130319
         Sub-Project:  DNS           |                   Resolution:
Estimated Difficulty:  5             |                 CVSS Scoring:
         Total Hours:  0             |              Defect Severity:  N/A
                                     |  Feature Depending on Ticket:
                                     |  loadzone-ng
                                     |          Add Hours to Ticket:  0
                                     |                    Internal?:  0
-------------------------------------+-------------------------------------

Comment (by jinmei):

 '''nsec3param_common.h'''

 - This doesn't seem to be very correct:
 {{{#!cpp
 /// \exception MasterLexer::LexerError There was a failure reading a
 /// field from the MasterLexer.
 }}}
   "failure" sounds like a low level (quite unexpected) error such as
   an I/O error, but `LexerError` is more expected to be thrown against
   syntax errors (such as a string given when a number is expected or
   an unexpected end of input).

 '''dnskey_48.cc'''
 - the doxygen doc for the constructors share some amount of text.  I'd
   unify them, e.g., by referring from one to the other.
 - is this good?
 {{{#!cpp
     while (true) {
         const MasterToken& token = lexer.getNextToken();
         if (token.getType() != MasterToken::STRING) {
             break;
         }
         keydatastr.append(token.getString());
     }
 }}}
   This way, even if the lexer founds a syntax error, it exits from the
   loop just like the normal case and the error detection is left to
   the caller.  It seems to me better if we keep extracting strings
   exclusively until we see end of line/input and catch any
   intermediate error at the exact point.  BTW, I found nsec_bitmap.cc
   has the same issue.
 - probably marginal, but it'd be slightly more efficient if we use the
   other version of `getString()`
 {{{#!cpp
     string keydatastr, keydata_token;
     while (true) {
         const MasterToken& token =
             lexer.getNextToken(MasterToken::STRING, true);
         if (token.getType() != MasterToken::STRING) {
             break;
         }
         token.getString(keydata_token);
         keydatastr.append(keydata_token);
     }
 }}}
   (and while it's out of scope of this ticket, the same point applies
   to buildBitmapsFromLexer() regarding `type_str`).
 - not directly related to this ticket, but what's the rationale of
   this?
 {{{#!cpp
     if (keydatastr.size() == 0) {
         isc_throw(InvalidRdataText, "Missing DNSKEY digest");
     }
 }}}
 - ditto, but this one too:
 {{{#!cpp
     if (algorithm == 1 && keydata.size() < 3) {
         isc_throw(InvalidRdataLength, "DNSKEY keydata too short");
     }
 }}}
 - and why don't we do the same check for the "from wire" case if we
   need to do it?
 - and, if we allow empty key this code is not really correct:
 {{{#!cpp
     buffer.readData(&keydata[0], rdata_len);
 }}}
   because accessing `[0]` is invalid for an empty vector.

 '''nsec3_50.cc'''
 - redundant doc (see dnskey comments)
 - this can be a reference:
 {{{#!cpp
     const string nexthash =
 lexer.getNextToken(MasterToken::STRING).getString();
 }}}
  (and the line is too long)
 - this can be a reference:
 {{{#!cpp
     const MasterToken token = lexer.getNextToken();
 }}}
 - is it possible to avoid doing `ungetToken()` here:
 {{{#!cpp
     if ((token.getType() == MasterToken::END_OF_LINE) ||
         (token.getType() == MasterToken::END_OF_FILE)) {
          empty_bitmap = true;
     }

     lexer.ungetToken();
 }}}
   by unifying it in `buildBitmapsFromLexer`?  `ungetToken` for a
   string is a bit expensive because you'd need to copy it twice.

 '''nsec3param_51.cc'''
 - redundant doc (see dnskey comments)

 '''masterload_unittest.cc'''

 Is that intentional there are two '#' signs here?
 {{{
 // doesn't support them. This test should be fixed and re-enabled by
 // ##2381, or deleted.
 }}}

 '''tests in general'''

 It looks suboptimal that string and lexer versions have different sets
 of tests (e.g., badText and createFromLexer for DNSKEY).  They cause
 duplicates/redundancy, as well as incomplete cases.  I'd generally
 unify these cases.  See, for example, `Rdata_IN_A_Test::createFromText`.

 '''rdata_dnskey_unittest.cc'''

 - This case is now moot:
 {{{#!cpp
     // Missing algorithm
     EXPECT_THROW(generic::DNSKEY("257 3 5BEAAEFTd"), InvalidRdataText);
 }}}
   This test was specifically crafted for this code:
 {{{#!cpp
     unsigned int flags, protocol, algorithm;
     stringbuf keydatabuf;

     iss >> flags >> protocol >> algorithm >> &keydatabuf;
 }}}
   which would incorrectly accept the above invalid input.  It doesn't
   make much sense to use the same test case because our lexer is never
   confused with token boundary this way.  If we really want to check
   the "missing algorithm" case, we should at least make the base64
   part valid; otherwise it may not be really clear if the
   implementation correctly detects the algorithm is missing.
 - Likewise, this one:
 {{{#!cpp
     // How about this?  It's even more confusing for the parser because
     // it could be ambiguous '51 EAAA' vs '5 1EAA..'. But we first parse
     // the other fields before we parse the public key, so we reject
     // this.
     EXPECT_THROW(generic::DNSKEY("257 3 51EAAEFTd"), InvalidRdataText);
 }}}
   "how about this?" part doesn't make sense any more, and it's not
   really confusing at all (the input is obviously invalid).  And, it's
   not even clear whether we need two cases like this.
 - cases where a non number is used for a number field are missing.
   checking spaces in base64 also seems to be missing.  there may be
   some other missed cases.  Please check corner cases as if it were
   developed test-driven.

 '''rdata_nsec3_unittest.cc'''

 - number vs non-number cases seem to be missing.  there may be some
   other.

 '''rdata_nsec3param_unittest.cc'''

 - number vs non-number cases seem to be missing.  bad hex case is
   missing.  there may be some other.

-- 
Ticket URL: <http://bind10.isc.org/ticket/2387#comment:14>
BIND 10 Development <http://bind10.isc.org>
BIND 10 Development


More information about the bind10-tickets mailing list