|
@@ -143,6 +143,48 @@ private:
|
|
|
pushSource(filename);
|
|
|
}
|
|
|
|
|
|
+ RRType parseRRParams(bool& explicit_ttl) {
|
|
|
+ // Find TTL, class and type. Both TTL and class are
|
|
|
+ // optional and may occur in any order if they exist. TTL
|
|
|
+ // and class come before type which must exist.
|
|
|
+ //
|
|
|
+ // [<TTL>] [<class>] <type> <RDATA>
|
|
|
+ // [<class>] [<TTL>] <type> <RDATA>
|
|
|
+ MasterToken rrparam_token = lexer_.getNextToken(MasterToken::STRING);
|
|
|
+
|
|
|
+ // Try TTL
|
|
|
+ if (setCurrentTTL(rrparam_token.getString())) {
|
|
|
+ explicit_ttl = true;
|
|
|
+ rrparam_token = lexer_.getNextToken(MasterToken::STRING);
|
|
|
+ } else {
|
|
|
+ // If it's not a TTL here, continue and try again
|
|
|
+ // after the RR class below.
|
|
|
+ }
|
|
|
+
|
|
|
+ boost::scoped_ptr<RRClass> rrclass;
|
|
|
+ try {
|
|
|
+ rrclass.reset(new RRClass(rrparam_token.getString()));
|
|
|
+ rrparam_token = lexer_.getNextToken(MasterToken::STRING);
|
|
|
+ } catch (const InvalidRRClass&) {
|
|
|
+ // If it's not an rrclass here, use the zone's class.
|
|
|
+ rrclass.reset(new RRClass(zone_class_));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!explicit_ttl && rrclass &&
|
|
|
+ setCurrentTTL(rrparam_token.getString())) {
|
|
|
+ explicit_ttl = true;
|
|
|
+ rrparam_token = lexer_.getNextToken(MasterToken::STRING);
|
|
|
+ }
|
|
|
+ if (*rrclass != zone_class_) {
|
|
|
+ // It doesn't really matter much what type of exception
|
|
|
+ // we throw, we catch it just below.
|
|
|
+ isc_throw(isc::BadValue, "Class mismatch: " << *rrclass <<
|
|
|
+ "vs. " << zone_class_);
|
|
|
+ }
|
|
|
+
|
|
|
+ return (RRType(rrparam_token.getString()));
|
|
|
+ }
|
|
|
+
|
|
|
// Upper limit check when recognizing a specific TTL value from the
|
|
|
// zone file ($TTL, the RR's TTL field, or the SOA minimum). RFC2181
|
|
|
// Section 8 limits the range of TTL values to unsigned 32-bit integers,
|
|
@@ -380,72 +422,22 @@ MasterLoader::MasterLoaderImpl::loadIncremental(size_t count_limit) {
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
- const Name name(name_string.beg, name_string.len,
|
|
|
- &zone_origin_);
|
|
|
-
|
|
|
- // Find TTL, class and type. Both TTL and class are
|
|
|
- // optional and may occur in any order if they exist. TTL
|
|
|
- // and class come before type which must exist.
|
|
|
- //
|
|
|
- // [<TTL>] [<class>] <type> <RDATA>
|
|
|
- // [<class>] [<TTL>] <type> <RDATA>
|
|
|
+ const Name name(name_string.beg, name_string.len, &zone_origin_);
|
|
|
|
|
|
// The parameters
|
|
|
- MasterToken rrparam_token = lexer_.getNextToken();
|
|
|
-
|
|
|
- boost::scoped_ptr<RRClass> rrclass;
|
|
|
- try {
|
|
|
- rrclass.reset(new RRClass(rrparam_token.getString()));
|
|
|
- rrparam_token = lexer_.getNextToken();
|
|
|
- } catch (const InvalidRRClass&) {
|
|
|
- // If it's not an rrclass here, continue and try again
|
|
|
- // after the TTL below.
|
|
|
- }
|
|
|
-
|
|
|
bool explicit_ttl = false;
|
|
|
- if (rrparam_token.getType() == MasterToken::STRING) {
|
|
|
- // Try TTL
|
|
|
- if (setCurrentTTL(rrparam_token.getString())) {
|
|
|
- explicit_ttl = true;
|
|
|
- rrparam_token = lexer_.getNextToken();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (!rrclass) {
|
|
|
- try {
|
|
|
- rrclass.reset(new RRClass(rrparam_token.getString()));
|
|
|
- rrparam_token = lexer_.getNextToken();
|
|
|
- } catch (const InvalidRRClass&) {
|
|
|
- // If it's not an rrclass here, use the zone's class.
|
|
|
- rrclass.reset(new RRClass(zone_class_));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Return the last token
|
|
|
- lexer_.ungetToken();
|
|
|
-
|
|
|
- const RRType rrtype(getString());
|
|
|
-
|
|
|
- // TODO: Some more validation?
|
|
|
- if (*rrclass != zone_class_) {
|
|
|
- // It doesn't really matter much what type of exception
|
|
|
- // we throw, we catch it just below.
|
|
|
- isc_throw(isc::BadValue, "Class mismatch: " << *rrclass <<
|
|
|
- "vs. " << zone_class_);
|
|
|
- }
|
|
|
+ const RRType rrtype = parseRRParams(explicit_ttl);
|
|
|
// TODO: Check if it is SOA, it should be at the origin.
|
|
|
|
|
|
- const rdata::RdataPtr rdata(rdata::createRdata(rrtype, *rrclass,
|
|
|
- lexer_,
|
|
|
- &zone_origin_,
|
|
|
- options_,
|
|
|
- callbacks_));
|
|
|
+ const rdata::RdataPtr rdata =
|
|
|
+ rdata::createRdata(rrtype, zone_class_, lexer_, &zone_origin_,
|
|
|
+ options_, callbacks_);
|
|
|
// In case we get NULL, it means there was error creating
|
|
|
// the Rdata. The errors should have been reported by
|
|
|
// callbacks_ already. We need to decide if we want to continue
|
|
|
// or not.
|
|
|
if (rdata) {
|
|
|
- add_callback_(name, *rrclass, rrtype,
|
|
|
+ add_callback_(name, zone_class_, rrtype,
|
|
|
getCurrentTTL(explicit_ttl, rrtype, rdata),
|
|
|
rdata);
|
|
|
|