From: Remi Gacogne Date: Wed, 14 Jun 2017 16:16:26 +0000 (+0200) Subject: rec: Make more specific Netmask < to less specific ones X-Git-Tag: rec-4.1.0-alpha1~6^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a009559d3bc4d648edc3b5fff062b622bbde2389;p=thirdparty%2Fpdns.git rec: Make more specific Netmask < to less specific ones Having the most specific ones first, then the less specific ones then the empty one makes it easier to match the most specific first. --- diff --git a/pdns/iputils.hh b/pdns/iputils.hh index a4a4862c0a..30849cd6b3 100644 --- a/pdns/iputils.hh +++ b/pdns/iputils.hh @@ -444,7 +444,23 @@ public: bool operator<(const Netmask& rhs) const { - return tie(d_network, d_bits) < tie(rhs.d_network, rhs.d_bits); + if (empty() && !rhs.empty()) + return false; + + if (!empty() && rhs.empty()) + return true; + + if (d_bits > rhs.d_bits) + return true; + if (d_bits < rhs.d_bits) + return false; + + return d_network < rhs.d_network; + } + + bool operator>(const Netmask& rhs) const + { + return rhs.operator<(*this); } bool operator==(const Netmask& rhs) const diff --git a/pdns/recursordist/test-recursorcache_cc.cc b/pdns/recursordist/test-recursorcache_cc.cc index 1974bbea8a..cebc9685bf 100644 --- a/pdns/recursordist/test-recursorcache_cc.cc +++ b/pdns/recursordist/test-recursorcache_cc.cc @@ -256,6 +256,47 @@ BOOST_AUTO_TEST_CASE(test_RecursorCacheSimple) { BOOST_REQUIRE_EQUAL(retrieved.size(), 1); BOOST_CHECK_EQUAL(getRR(retrieved.at(0))->getCA().toString(), dr2Content.toString()); + // Most specific netmask test + // wipe everything + MRC.doWipeCache(DNSName("."), true); + BOOST_CHECK_EQUAL(MRC.size(), 0); + records.clear(); + + // insert an entry for 192.0.0.1/8 + records.clear(); + records.push_back(dr2); + MRC.replace(now, power, QType(QType::A), records, signatures, true, boost::optional("192.0.0.1/8")); + BOOST_CHECK_EQUAL(MRC.size(), 1); + + /* same as dr2 except for the actual IP */ + DNSRecord dr4; + ComboAddress dr4Content("192.0.2.126"); + dr4.d_name = power; + dr4.d_type = QType::A; + dr4.d_class = QClass::IN; + dr4.d_content = std::make_shared(dr4Content); + dr4.d_ttl = static_cast(ttd); + dr4.d_place = DNSResourceRecord::AUTHORITY; + + // insert an other entry but for 192.168.0.1/31 + records.clear(); + records.push_back(dr4); + MRC.replace(now, power, QType(QType::A), records, signatures, true, boost::optional("192.168.0.1/31")); + // we should not have replaced any existing entry + BOOST_CHECK_EQUAL(MRC.size(), 2); + + // insert the same than the first one but for 192.168.0.2/32 + records.clear(); + records.push_back(dr2); + MRC.replace(now, power, QType(QType::A), records, signatures, true, boost::optional("192.168.0.2/32")); + // we should not have replaced any existing entry + BOOST_CHECK_EQUAL(MRC.size(), 3); + + // we should get the most specific entry for 192.168.0.1, so the second one + BOOST_CHECK_EQUAL(MRC.get(now, power, QType(QType::A), &retrieved, ComboAddress("192.168.0.1"), nullptr), (ttd-now)); + BOOST_REQUIRE_EQUAL(retrieved.size(), 1); + BOOST_CHECK_EQUAL(getRR(retrieved.at(0))->getCA().toString(), dr4Content.toString()); + retrieved.clear(); } catch(const PDNSException& e) { cerr<<"Had error: "< specific32); + BOOST_CHECK(specific24 < specific16); + BOOST_CHECK(specific16 > specific24); + + Netmask sameMask1("192.0.0.0/16"); + Netmask sameMask2("192.0.0.1/16"); + BOOST_CHECK(sameMask1 < sameMask2); + BOOST_CHECK(sameMask2 > sameMask1); + + /* An empty Netmask should be larger than + every others. */ + Netmask empty = Netmask(); + Netmask full("255.255.255.255/32"); + BOOST_CHECK(empty > all); + BOOST_CHECK(all < empty); + BOOST_CHECK(empty > full); + BOOST_CHECK(full < empty); } BOOST_AUTO_TEST_CASE(test_NetmaskGroup) {