dc->d_kernelTimestamp = tv;
#endif
dc->d_proxyProtocolValues = std::move(proxyProtocolValues);
- dc->d_routingTag = routingTag;
+ dc->d_routingTag = std::move(routingTag);
MT->makeThread(startDoResolve, (void*) dc.release()); // deletes dc
return 0;
return match;
}
-// bool MemRecursorCache::entryMatches(MemRecursorCache::OrderedTagIterator_t& entry, uint16_t qt, bool requireAuth)
-// {
-// // MUTEX SHOULD BE ACQUIRED
-// if (requireAuth && !entry->d_auth)
-// return false;
-
-// bool match = (entry->d_qtype == qt || qt == QType::ANY ||
-// (qt == QType::ADDR && (entry->d_qtype == QType::A || entry->d_qtype == QType::AAAA)));
-// //cerr << match << "T " << qt << ':' << entry->d_qtype << ' ' << entry->d_rtag << endl;
-// return match;
-// }
-
// returns -1 for no hits
int32_t MemRecursorCache::get(time_t now, const DNSName &qname, const QType& qt, bool requireAuth, vector<DNSRecord>* res, const ComboAddress& who, const OptTag& routingTag, vector<std::shared_ptr<RRSIGRecordContent>>* signatures, std::vector<std::shared_ptr<DNSRecord>>* authorityRecs, bool* variable, vState* state, bool* wasAuth)
{
}
bool entryMatches(OrderedTagIterator_t& entry, uint16_t qt, bool requireAuth, const ComboAddress& who);
- //bool entryMatches(OrderedTagIterator_t& entry, uint16_t qt, bool requireAuth);
Entries getEntries(MapCombo& map, const DNSName &qname, const QType& qt, const OptTag& rtag);
cache_t::const_iterator getEntryUsingECSIndex(MapCombo& map, time_t now, const DNSName &qname, uint16_t qtype, bool requireAuth, const ComboAddress& who);
int32_t handleHit(MapCombo& map, OrderedTagIterator_t& entry, const DNSName& qname, vector<DNSRecord>* res, vector<std::shared_ptr<RRSIGRecordContent>>* signatures, std::vector<std::shared_ptr<DNSRecord>>* authorityRecs, bool* variable, vState* state, bool* wasAuth);
.. versionadded:: 4.4.0
A ``routingTag`` can be returned, which is used as an extra name to identify records in the record cache.
+ If a routing tag is set and a record would be stored with an ENDS subnetmask in the record cache, it will be
+ stored with the tag instead. New request using the same tag will be served by the record in the records cache,
+ avoiding querying authoritative servers.
The tagged packetcache can e.g. be used to answer queries from cache that have e.g. been filtered for certain IPs (this logic should be implemented in :func:`gettag`).
This ensure that queries are answered quickly compared to setting :attr:`dq.variable <DNSQuestion.variable>` to true.
// Now insert some tagged entries
for (counter = 0; counter < 50; ++counter) {
DNSName a = DNSName("hello ") + DNSName(std::to_string(counter));
- BOOST_CHECK_EQUAL(DNSName(a.toString()), a);
-
MRC.replace(now, a, QType(QType::A), rset0tagged, signatures, authRecords, true, boost::optional<Netmask>("128.0.0.0/8"), string("mytagA"));
}
BOOST_CHECK_EQUAL(MRC.size(), 150U);
BOOST_CHECK_LT(MRC.get(now, power, QType(QType::A), false, &retrieved, ComboAddress("127.0.0.1"), boost::none), 0);
BOOST_REQUIRE_EQUAL(retrieved.size(), 0U);
- // if no tag given and no-non-tagged entries are available nothing should be retrieved even if address matches
+ // if no tag given and no-non-tagged entries matches nothing shoudl be returned
BOOST_CHECK_LT(MRC.get(now, power, QType(QType::A), false, &retrieved, ComboAddress("192.0.2.2"), boost::none), 0);
BOOST_REQUIRE_EQUAL(retrieved.size(), 0U);
BOOST_REQUIRE_EQUAL(retrieved.size(), 1U);
BOOST_CHECK_EQUAL(getRR<ARecordContent>(retrieved.at(0))->getCA().toString(), dr3Content.toString());
+ // If no tag given we should be able to retrieve the netmask specific record
+ BOOST_CHECK_EQUAL(MRC.get(now, power, QType(QType::A), false, &retrieved, ComboAddress("192.0.3.1"), boost::none), (ttd - now));
+ BOOST_REQUIRE_EQUAL(retrieved.size(), 1U);
+ BOOST_CHECK_EQUAL(getRR<ARecordContent>(retrieved.at(0))->getCA().toString(), dr2Content.toString());
+
// tagged specific should still be returned for a matching tag, address is not used
BOOST_CHECK_EQUAL(MRC.get(now, power, QType(QType::A), false, &retrieved, ComboAddress("192.0.2.2"), string("mytag")), (ttd - now));
BOOST_REQUIRE_EQUAL(retrieved.size(), 1U);
query = dns.message.make_query(nameECS, 'TXT', 'IN', use_edns=True, options=[ecso], payload=512)
self.sendECSQuery(query, expected3)
- # And see if an unknown tag does hit the last
+ # And see if an unknown tag from the same subnet does hit the last
self.setRoutingTag('baz')
- query = dns.message.make_query(nameECS, 'TXT', 'IN')
+ ecso = clientsubnetoption.ClientSubnetOption('192.0.3.2', 32)
+ query = dns.message.make_query(nameECS, 'TXT', 'IN', use_edns=True, options=[ecso], payload=512)
self.checkECSQueryHit(query, expected3)
- return # remove this line to peek at cache
+ # And a no tag and no subnet query does hit the general case
+ self.setRoutingTag(None)
+ query = dns.message.make_query(nameECS, 'TXT', 'IN')
+ self.sendECSQuery(query, expected2)
+
+ # And a unknown tag and no subnet query does hit the general case
+ self.setRoutingTag('bag')
+ query = dns.message.make_query(nameECS, 'TXT', 'IN')
+ self.sendECSQuery(query, expected2)
+
+ #return # remove this line to peek at cache
rec_controlCmd = [os.environ['RECCONTROL'],
'--config-dir=%s' % 'configs/' + self._confdir,
'dump-cache x']
try:
- expected = 'dumped 5 records\n'
+ expected = 'dumped 6 records\n'
ret = subprocess.check_output(rec_controlCmd, stderr=subprocess.STDOUT)
self.assertEqual(ret, expected)
query = dns.message.make_query(nameECS, 'TXT', 'IN', use_edns=True, options=[ecso], payload=512)
self.sendECSQuery(query, expected3)
- # And see if an unknown tag does hit the last
+ # And see if an unknown tag from the same subnet does hit the last
self.setRoutingTag('baz')
- query = dns.message.make_query(nameECS, 'TXT', 'IN')
+ ecso = clientsubnetoption.ClientSubnetOption('192.0.3.2', 32)
+ query = dns.message.make_query(nameECS, 'TXT', 'IN', use_edns=True, options=[ecso], payload=512)
self.checkECSQueryHit(query, expected3)
+ # And a no tag and no subnet query does hit the general case
+ self.setRoutingTag(None)
+ query = dns.message.make_query(nameECS, 'TXT', 'IN')
+ self.sendECSQuery(query, expected2)
+
+ # And a unknown tag and no subnet query does hit the general case
+ self.setRoutingTag('bag')
+ query = dns.message.make_query(nameECS, 'TXT', 'IN')
+ self.sendECSQuery(query, expected2)
+
return #remove this line to peek at cache
rec_controlCmd = [os.environ['RECCONTROL'],
'--config-dir=%s' % 'configs/' + self._confdir,
'dump-cache y']
try:
- expected = 'dumped 5 records\n'
+ expected = 'dumped 6 records\n'
ret = subprocess.check_output(rec_controlCmd, stderr=subprocess.STDOUT)
self.assertEqual(ret, expected)