('naptr', 'generic'),
('mx', 'generic'),
('ns', 'generic'),
+ ('nsec', 'generic'),
('ptr', 'generic'),
('soa', 'generic'),
('spf', 'generic'),
}
}
+// Note: this function shares common code with buildBitmapsFromText()
+// above, but it is expected that buildBitmapsFromText() will be deleted
+// entirely once the transition to MasterLexer is done for all dependent
+// RR types. So a common method is not made from the two.
+void
+buildBitmapsFromLexer(const char* const rrtype_name,
+ MasterLexer& lexer, vector<uint8_t>& typebits)
+{
+ uint8_t bitmap[8 * 1024]; // 64k bits
+ memset(bitmap, 0, sizeof(bitmap));
+
+ bool have_rrtypes = false;
+ while (true) {
+ const MasterToken& token = lexer.getNextToken();
+ if (token.getType() == MasterToken::END_OF_FILE) {
+ break;
+ }
+
+ have_rrtypes = true;
+ std::string type_str;
+ try {
+ type_str = token.getString();
+ const int code = RRType(type_str).getCode();
+ bitmap[code / 8] |= (0x80 >> (code % 8));
+ } catch (const InvalidRRType&) {
+ isc_throw(InvalidRdataText, "Invalid RRtype in "
+ << rrtype_name << " bitmap: " << type_str);
+ }
+ }
+
+ if (!have_rrtypes) {
+ isc_throw(InvalidRdataText,
+ rrtype_name << " record does not end with RR type string");
+ }
+
+ for (int window = 0; window < 256; ++window) {
+ int octet;
+ for (octet = 31; octet >= 0; octet--) {
+ if (bitmap[window * 32 + octet] != 0) {
+ break;
+ }
+ }
+ if (octet < 0) {
+ continue;
+ }
+ typebits.push_back(window);
+ typebits.push_back(octet + 1);
+ for (int i = 0; i <= octet; ++i) {
+ typebits.push_back(bitmap[window * 32 + i]);
+ }
+ }
+}
+
void
bitmapsToText(const vector<uint8_t>& typebits, ostringstream& oss) {
// In the following loop we use string::at() rather than operator[].
#ifndef NSECBITMAP_H
#define NSECBITMAP_H 1
+#include <dns/master_lexer.h>
+
#include <stdint.h>
#include <sstream>
std::istringstream& iss,
std::vector<uint8_t>& typebits);
+/// \brief Convert textual sequence of RR types read from a lexer into
+/// type bitmaps.
+///
+/// See the other variant above for description.
+///
+/// \exception InvalidRdataText Data read from the given lexer does not
+/// meet the assumption (e.g. including invalid form of RR type, not
+/// ending with an RR type string).
+///
+/// \param rrtype_name Either "NSEC" or "NSEC3"; used as part of exception
+/// messages.
+/// \param lexer MasterLexer that provides consists of a complete
+/// sequence of textual lexemes of RR types for which the corresponding
+/// bits are set.
+/// \param typebits A placeholder for the resulting bitmaps. Expected to be
+/// empty, but it's not checked.
+void buildBitmapsFromLexer(const char* const rrtype_name,
+ isc::dns::MasterLexer& lexer,
+ std::vector<uint8_t>& typebits);
+
/// \brief Convert type bitmaps to textual sequence of RR types.
///
/// This function converts wire-format data of type bitmaps for NSEC/NSEC3
#include <dns/rdata.h>
#include <dns/rdataclass.h>
#include <dns/rdata/generic/detail/nsec_bitmap.h>
+#include <dns/rdata/generic/detail/lexer_util.h>
#include <stdio.h>
#include <time.h>
using namespace isc::util;
using namespace isc::util::encode;
using namespace isc::dns::rdata::generic::detail::nsec;
+using isc::dns::rdata::generic::detail::createNameFromLexer;
// BEGIN_ISC_NAMESPACE
// BEGIN_RDATA_NAMESPACE
impl_ = new NSECImpl(nextname, typebits);
}
+NSEC::NSEC(MasterLexer& lexer, const Name* origin, MasterLoader::Options,
+ MasterLoaderCallbacks&)
+{
+ const Name origin_name(createNameFromLexer(lexer, origin));
+
+ vector<uint8_t> typebits;
+ buildBitmapsFromLexer("NSEC", lexer, typebits);
+
+ impl_ = new NSECImpl(origin_name, typebits);
+}
+
NSEC::NSEC(const NSEC& source) :
Rdata(), impl_(new NSECImpl(*source.impl_))
{}