#endif
#include "dnsrecords.hh"
-void NSECRecordContent::report(void)
-{
- regist(1, 47, &make, &make, "NSEC");
-}
-
-DNSRecordContent* NSECRecordContent::make(const string& content)
-{
- return new NSECRecordContent(content);
-}
-
-NSECRecordContent::NSECRecordContent(const string& content, const string& zone)
+class NSECBitmapGenerator
{
- RecordTextReader rtr(content, zone);
- rtr.xfrName(d_next);
-
- while(!rtr.eof()) {
- uint16_t type;
- rtr.xfrType(type);
- d_set.insert(type);
+public:
+ NSECBitmapGenerator(DNSPacketWriter& pw_): pw(pw_)
+ {
+ memset(res, 0, sizeof(res));
}
-}
-void NSECRecordContent::toPacket(DNSPacketWriter& pw)
-{
- pw.xfrName(d_next);
-
- uint8_t res[34];
- set<uint16_t>::const_iterator i;
- int oldWindow = -1;
- int window = 0;
- int len = 0;
- string tmp;
-
- for(i=d_set.begin(); i != d_set.end(); ++i){
- uint16_t bit = (*i)%256;
- window = static_cast<int>((*i) / 256);
+ void set(uint16_t type)
+ {
+ uint16_t bit = type % 256;
+ int window = static_cast<int>(type / 256);
if (window != oldWindow) {
if (oldWindow > -1) {
- res[0] = static_cast<unsigned char>(oldWindow);
- res[1] = static_cast<unsigned char>(len);
- tmp.assign(res, res+len+2);
- pw.xfrBlob(tmp);
+ res[0] = static_cast<unsigned char>(oldWindow);
+ res[1] = static_cast<unsigned char>(len);
+ tmp.assign(res, res+len+2);
+ pw.xfrBlob(tmp);
}
- memset(res, 0, 34);
+ memset(res, 0, sizeof(res));
oldWindow = window;
}
res[2+bit/8] |= 1 << (7-(bit%8));
len=1+bit/8;
}
- res[0] = static_cast<unsigned char>(window);
- res[1] = static_cast<unsigned char>(len);
- tmp.assign(res, res+len+2);
- pw.xfrBlob(tmp);
+ void finish()
+ {
+ res[0] = static_cast<unsigned char>(oldWindow);
+ res[1] = static_cast<unsigned char>(len);
+ if (len) {
+ tmp.assign(res, res+len+2);
+ pw.xfrBlob(tmp);
+ }
+ }
+
+private:
+ DNSPacketWriter& pw;
+ /* one byte for the window,
+ one for the length,
+ then the maximum of 32 bytes */
+ uint8_t res[34];
+ int oldWindow{-1};
+ int len{0};
+ string tmp;
+};
+
+void NSECBitmap::toPacket(DNSPacketWriter& pw)
+{
+ NSECBitmapGenerator nbg(pw);
+ if (d_bitset) {
+ size_t count = d_bitset->count();
+ size_t found = 0;
+ for(size_t idx = 0; idx < nbTypes && found < count; ++idx){
+ if (!d_bitset->test(idx)) {
+ continue;
+ }
+ found++;
+ nbg.set(idx);
+ }
+ }
+ else {
+ for (const auto& type : d_set) {
+ nbg.set(type);
+ }
+ }
+
+ nbg.finish();
}
-NSECRecordContent::DNSRecordContent* NSECRecordContent::make(const DNSRecord &dr, PacketReader& pr)
+void NSECBitmap::fromPacket(PacketReader& pr)
{
- NSECRecordContent* ret=new NSECRecordContent();
- pr.xfrName(ret->d_next);
string bitmap;
pr.xfrBlob(bitmap);
-
+
// 00 06 20 00 00 00 00 03 -> NS RRSIG NSEC ( 2, 46, 47 ) counts from left
- if(bitmap.empty())
- return ret;
+ if(bitmap.empty()) {
+ return;
+ }
- if(bitmap.size() < 2)
+ if(bitmap.size() < 2) {
throw MOADNSException("NSEC record with impossibly small bitmap");
+ }
for(unsigned int n = 0; n+1 < bitmap.size();) {
unsigned int window=static_cast<unsigned char>(bitmap[n++]);
unsigned int blen=static_cast<unsigned char>(bitmap[n++]);
// end if zero padding and ensure packet length
- if(window == 0 && blen == 0) break;
- if(n + blen > bitmap.size())
+ if(window == 0 && blen == 0) {
+ break;
+ }
+
+ if(n + blen > bitmap.size()) {
throw MOADNSException("NSEC record with bitmap length > packet length");
+ }
for(unsigned int k=0; k < blen; k++) {
uint8_t val=bitmap[n++];
- for(int bit = 0; bit < 8 ; ++bit , val>>=1)
+ for(int bit = 0; bit < 8 ; ++bit , val>>=1) {
if(val & 1) {
- ret->d_set.insert((7-bit) + 8*(k) + 256*window);
+ set((7-bit) + 8*(k) + 256*window);
}
}
+ }
+ }
+}
+
+string NSECBitmap::getZoneRepresentation() const
+{
+ string ret;
+
+ if (d_bitset) {
+ size_t count = d_bitset->count();
+ size_t found = 0;
+ for(size_t idx = 0; idx < nbTypes && found < count; ++idx) {
+ if (!d_bitset->test(idx)) {
+ continue;
+ }
+ found++;
+
+ ret+=" ";
+ ret+=DNSRecordContent::NumberToType(idx);
+ }
+ }
+ else {
+ for(const auto& type : d_set) {
+ ret+=" ";
+ ret+=DNSRecordContent::NumberToType(type);
+ }
+ }
+
+ return ret;
+}
+
+void NSECRecordContent::report(void)
+{
+ regist(1, 47, &make, &make, "NSEC");
+}
+
+std::shared_ptr<DNSRecordContent> NSECRecordContent::make(const string& content)
+{
+ return std::make_shared<NSECRecordContent>(content);
+}
+
+NSECRecordContent::NSECRecordContent(const string& content, const string& zone)
+{
+ RecordTextReader rtr(content, DNSName(zone));
+ rtr.xfrName(d_next);
+
+ while(!rtr.eof()) {
+ uint16_t type;
+ rtr.xfrType(type);
+ set(type);
}
+}
+
+void NSECRecordContent::toPacket(DNSPacketWriter& pw)
+{
+ pw.xfrName(d_next);
+ d_bitmap.toPacket(pw);
+}
+
+std::shared_ptr<NSECRecordContent::DNSRecordContent> NSECRecordContent::make(const DNSRecord &dr, PacketReader& pr)
+{
+ auto ret=std::make_shared<NSECRecordContent>();
+ pr.xfrName(ret->d_next);
+
+ ret->d_bitmap.fromPacket(pr);
+
return ret;
}
string ret;
RecordTextWriter rtw(ret);
rtw.xfrName(d_next);
-
- for(set<uint16_t>::const_iterator i=d_set.begin(); i!=d_set.end(); ++i) {
- ret+=" ";
- ret+=NumberToType(*i);
- }
-
- return ret;
+
+ return ret + d_bitmap.getZoneRepresentation();
}
////// begin of NSEC3
regist(1, 50, &make, &make, "NSEC3");
}
-DNSRecordContent* NSEC3RecordContent::make(const string& content)
+std::shared_ptr<DNSRecordContent> NSEC3RecordContent::make(const string& content)
{
- return new NSEC3RecordContent(content);
+ return std::make_shared<NSEC3RecordContent>(content);
}
NSEC3RecordContent::NSEC3RecordContent(const string& content, const string& zone)
{
- RecordTextReader rtr(content, zone);
+ RecordTextReader rtr(content, DNSName(zone));
rtr.xfr8BitInt(d_algorithm);
rtr.xfr8BitInt(d_flags);
rtr.xfr16BitInt(d_iterations);
while(!rtr.eof()) {
uint16_t type;
rtr.xfrType(type);
- d_set.insert(type);
+ set(type);
}
}
pw.xfr8BitInt(d_nexthash.length());
pw.xfrBlob(d_nexthash);
-
- uint8_t res[34];
- set<uint16_t>::const_iterator i;
- int oldWindow = -1;
- int window = 0;
- int len = 0;
- string tmp;
- for(i=d_set.begin(); i != d_set.end(); ++i){
- uint16_t bit = (*i)%256;
- window = static_cast<int>((*i) / 256);
-
- if (window != oldWindow) {
- if (oldWindow > -1) {
- res[0] = static_cast<unsigned char>(oldWindow);
- res[1] = static_cast<unsigned char>(len);
- tmp.assign(res, res+len+2);
- pw.xfrBlob(tmp);
- }
- memset(res, 0, 34);
- oldWindow = window;
- }
- res[2+bit/8] |= 1 << (7-(bit%8));
- len=1+bit/8;
- }
-
- res[0] = static_cast<unsigned char>(window);
- res[1] = static_cast<unsigned char>(len);
-
- if (len) {
- tmp.assign(res, res+len+2);
- pw.xfrBlob(tmp);
- }
+ d_bitmap.toPacket(pw);
}
-NSEC3RecordContent::DNSRecordContent* NSEC3RecordContent::make(const DNSRecord &dr, PacketReader& pr)
+std::shared_ptr<NSEC3RecordContent::DNSRecordContent> NSEC3RecordContent::make(const DNSRecord &dr, PacketReader& pr)
{
- NSEC3RecordContent* ret=new NSEC3RecordContent();
+ auto ret=std::make_shared<NSEC3RecordContent>();
pr.xfr8BitInt(ret->d_algorithm);
pr.xfr8BitInt(ret->d_flags);
pr.xfr16BitInt(ret->d_iterations);
pr.xfr8BitInt(len);
pr.xfrBlob(ret->d_nexthash, len);
-
- string bitmap;
- pr.xfrBlob(bitmap);
-
- // 00 06 20 00 00 00 00 03 -> NS RRSIG NSEC ( 2, 46, 47 ) counts from left
-
- if(bitmap.empty())
- return ret;
- if(bitmap.size() < 2)
- throw MOADNSException("NSEC3 record with impossibly small bitmap");
-
- for(unsigned int n = 0; n+1 < bitmap.size();) {
- unsigned int window=static_cast<unsigned char>(bitmap[n++]);
- unsigned int innerlen=static_cast<unsigned char>(bitmap[n++]);
-
- // end if zero padding and ensure packet length
- if(window == 0&&innerlen == 0) break;
- if(n+innerlen>bitmap.size())
- throw MOADNSException("NSEC record with bitmap length > packet length");
-
- for(unsigned int k=0; k < innerlen; k++) {
- uint8_t val=bitmap[n++];
- for(int bit = 0; bit < 8 ; ++bit , val>>=1)
- if(val & 1) {
- ret->d_set.insert((7-bit) + 8*(k) + 256*window);
- }
- }
- }
+ ret->d_bitmap.fromPacket(pr);
return ret;
}
rtw.xfrHexBlob(d_salt);
rtw.xfrBase32HexBlob(d_nexthash);
- for(set<uint16_t>::const_iterator i=d_set.begin(); i!=d_set.end(); ++i) {
- ret+=" ";
- ret+=NumberToType(*i);
- }
-
- return ret;
+
+ return ret + d_bitmap.getZoneRepresentation();
}
regist(254, 51, &make, &make, "NSEC3PARAM");
}
-DNSRecordContent* NSEC3PARAMRecordContent::make(const string& content)
+std::shared_ptr<DNSRecordContent> NSEC3PARAMRecordContent::make(const string& content)
{
- return new NSEC3PARAMRecordContent(content);
+ return std::make_shared<NSEC3PARAMRecordContent>(content);
}
NSEC3PARAMRecordContent::NSEC3PARAMRecordContent(const string& content, const string& zone)
{
- RecordTextReader rtr(content, zone);
+ RecordTextReader rtr(content, DNSName(zone));
rtr.xfr8BitInt(d_algorithm);
rtr.xfr8BitInt(d_flags);
rtr.xfr16BitInt(d_iterations);
pw.xfrBlob(d_salt);
}
-NSEC3PARAMRecordContent::DNSRecordContent* NSEC3PARAMRecordContent::make(const DNSRecord &dr, PacketReader& pr)
+std::shared_ptr<NSEC3PARAMRecordContent::DNSRecordContent> NSEC3PARAMRecordContent::make(const DNSRecord &dr, PacketReader& pr)
{
- NSEC3PARAMRecordContent* ret=new NSEC3PARAMRecordContent();
+ auto ret=std::make_shared<NSEC3PARAMRecordContent>();
pr.xfr8BitInt(ret->d_algorithm);
pr.xfr8BitInt(ret->d_flags);
pr.xfr16BitInt(ret->d_iterations);