BIND 10 #2377: define dns::MasterLoad class

BIND 10 Development do-not-reply at isc.org
Fri Oct 19 07:12:48 UTC 2012


#2377: define dns::MasterLoad class
-------------------------------------+-------------------------------------
            Reporter:  jinmei        |                        Owner:
                Type:  task          |  UnAssigned
            Priority:  medium        |                       Status:  new
           Component:  libdns++      |                    Milestone:  New
           Sensitive:  0             |  Tasks
         Sub-Project:  DNS           |                     Keywords:
Estimated Difficulty:  0             |              Defect Severity:  N/A
         Total Hours:  0             |  Feature Depending on Ticket:
                                     |  loadzone-ng
                                     |          Add Hours to Ticket:  0
                                     |                    Internal?:  0
-------------------------------------+-------------------------------------
 Subtask of #2368.  Depend on #2376 (and #2374, but we may be able
 to do it in parallel by using a mock or templated lexer).

 It's the BIND 10 port of BIND 9's lib/dns/master.c features, and
 especially the load_text() function.

 After thinking about it I propose creating a class, not just a free
 function, so we can keep the load state and suspend it, and support
 incremental loading.

 Also, in the initial implementation we skip most of the richer
 features, like `$something`, flexible ordering or omission of TTL,
 type, class.  Overall we assume the same thing as the current
 masterLoad(), but since we use a complete lexer it's a bit more
 complete.

 The tentative class definition is as follows:

 {{{#!cpp
 class MasterLoader {
 public:
     Options {
         MANY_ERRORS,            // lenient mode
             // also eventually some check policies like "check NS name"
     };
     MasterLoader(const char* const master_file,
                  const Name& zone_origin, RRClass zone_class
                  LoaderContextBase& context,
                  Options options);

     // Parse up to count_limit RRs, combining them into RRsets and
     // call context_.add().
     // Make sure keeping this method readable.  If it's getting bigger,
     // consider delegating some subtask to separate private methods.
     // return true if completed; false otherwise.
     bool loadIncremental(size_t count_limit);

     // this should be a trivial wrapper of loadIncremental
     void load();

 private:
     struct MasterLoaderImpl;
     MasterLoaderImpl* impl_;
     // impl class has:
     LoaderContextBase context_;
     MasterLexer lexer_;
     // For guessing TTLs
     bool ttl_known_;
     bool default_ttl_known_;
 };
 }}}

 The main goal of this ticket is to complete the initial implementation
 of loadIncremental().  To do so, first read BIND 9's load_text() and
 understand the basic flow.  A sample code snippet of our simplified
 version would be as follows:

 {{{#!cpp
 bool
 MasterLoader::loadIncremental(size_t count_limit) {
     size_t count = 0;  // number of loop iterations, up to count_limit
     do {
         const MasterLexer::Token token = lexer.getNextToken();
         // some trivial cases, like EOF
         if (token.type == MasterToken::STRING ||
             token.type == MasterToken::QSTRING) {
             const string str_token = token.getStringRegion();
             // "$" handling.  (not now)

             // Determine owner name
             const dns::Name new_name(token.string_value,
 include_ctx.origin);
             if (include_ctx.current_name != new_name) {
                 context_.add();
             }

             // (may need some more for $ORIGIN/$INCLUDE here)

             // reject out-of-zone name for primary
         } else {
             // error. call context.error(), if !lenient, throw.
         }

         // Find TTL, class and type. (some can be omitted, order is
 flexible)
         // For now we assume same as masterLoad().

         // if new type, add previous.

         // Read rdata contents.
         ConstRdataPtr rdata = rdata::createRdata(...);

         // Various checks (skip for now except this)
         // If it's SOA, check if it's zone_origin.

         rrset = prev_rrset;
         if (!rrset) { /* create one */ }
         else if (rrset->getTTL() != rrttl) adjust_ttl;
         rrset->addRdata(rdata);
     } while (!done && (count_limit != 0 && count++ < count_limit));

     // Commit what has not yet been committed.
     context_.add(rrset);
 }
 }}}

 createRdata() will need to extended, but for now, use the bare string
 version.

-- 
Ticket URL: <http://bind10.isc.org/ticket/2377>
BIND 10 Development <http://bind10.isc.org>
BIND 10 Development


More information about the bind10-tickets mailing list