Skip to content
Snippets Groups Projects
Commit 3d1ee641 authored by Marek Vavruša's avatar Marek Vavruša
Browse files

lib/layer: answer both m12n/full names from cache

previously only queried names were resolved from cache, this meant that if the target name was present in cache but a server on the search path dropped from it, it would refetch it - this is a problem when a loadbalancer with very short TTL was in search path
parent 24705086
No related branches found
No related tags found
No related merge requests found
......@@ -50,7 +50,7 @@ static const knot_dname_t *minimized_qname(struct kr_query *query, uint16_t *qty
{
/* Minimization disabled. */
const knot_dname_t *qname = query->sname;
if (query->flags & QUERY_NO_MINIMIZE) {
if (query->flags & (QUERY_NO_MINIMIZE|QUERY_CACHED)) {
return qname;
}
......
......@@ -54,10 +54,9 @@ static void adjust_ttl(knot_rrset_t *rr, uint32_t drift)
}
}
static int loot_cache(namedb_txn_t *txn, knot_pkt_t *pkt, uint8_t tag, uint32_t timestamp)
static int loot_cache_set(namedb_txn_t *txn, knot_pkt_t *pkt, uint8_t tag, const knot_dname_t *qname,
uint16_t rrtype, uint32_t timestamp)
{
const knot_dname_t *qname = knot_pkt_qname(pkt);
uint16_t rrtype = knot_pkt_qtype(pkt);
struct kr_cache_entry *entry;
entry = kr_cache_peek(txn, tag, qname, rrtype, &timestamp);
if (!entry) { /* Not in the cache */
......@@ -91,6 +90,24 @@ static int loot_cache(namedb_txn_t *txn, knot_pkt_t *pkt, uint8_t tag, uint32_t
return ret;
}
static int loot_cache(namedb_txn_t *txn, knot_pkt_t *pkt, struct kr_query *qry, uint8_t tag)
{
uint32_t timestamp = qry->timestamp.tv_sec;
/* Try direct match first */
const knot_dname_t *qname = qry->sname;
uint16_t rrtype = qry->stype;
int ret = loot_cache_set(txn, pkt, tag, qname, rrtype, timestamp);
if (ret == kr_error(ENOENT)) {
/* Try minimized name second */
qname = knot_pkt_qname(pkt);
rrtype = knot_pkt_qtype(pkt);
if (!knot_dname_is_equal(qname, qry->sname)) {
ret = loot_cache_set(txn, pkt, tag, qname, rrtype, timestamp);
}
}
return ret;
}
static int peek(knot_layer_t *ctx, knot_pkt_t *pkt)
{
struct kr_request *req = ctx->data;
......@@ -109,8 +126,7 @@ static int peek(knot_layer_t *ctx, knot_pkt_t *pkt)
if (kr_cache_txn_begin(cache, &txn, NAMEDB_RDONLY) != 0) {
return ctx->state;
}
uint32_t timestamp = qry->timestamp.tv_sec;
if (loot_cache(&txn, pkt, get_tag(req->answer), timestamp) != 0) {
if (loot_cache(&txn, pkt, qry, get_tag(req->answer)) != 0) {
kr_cache_txn_abort(&txn);
return ctx->state;
}
......
......@@ -53,11 +53,9 @@ static int loot_rr(namedb_txn_t *txn, knot_pkt_t *pkt, const knot_dname_t *name,
return kr_ok();
}
static int loot_cache(namedb_txn_t *txn, knot_pkt_t *pkt, uint32_t timestamp)
static int loot_cache_set(namedb_txn_t *txn, knot_pkt_t *pkt, const knot_dname_t *qname,
uint16_t rrclass, uint16_t rrtype, uint32_t timestamp)
{
const knot_dname_t *qname = knot_pkt_qname(pkt);
uint16_t rrclass = knot_pkt_qclass(pkt);
uint16_t rrtype = knot_pkt_qtype(pkt);
int ret = loot_rr(txn, pkt, qname, rrtype, rrclass, timestamp);
if (ret == kr_error(ENOENT) && rrtype != KNOT_RRTYPE_CNAME) { /* Chase CNAME if no direct hit */
ret = loot_rr(txn, pkt, qname, KNOT_RRTYPE_CNAME, rrclass, timestamp);
......@@ -65,6 +63,25 @@ static int loot_cache(namedb_txn_t *txn, knot_pkt_t *pkt, uint32_t timestamp)
return ret;
}
static int loot_cache(namedb_txn_t *txn, knot_pkt_t *pkt, struct kr_query *qry)
{
uint32_t timestamp = qry->timestamp.tv_sec;
/* Try direct match first */
const knot_dname_t *qname = qry->sname;
uint16_t rrclass = qry->sclass;
uint16_t rrtype = qry->stype;
int ret = loot_cache_set(txn, pkt, qname, rrclass, rrtype, timestamp);
if (ret == kr_error(ENOENT)) {
/* Try minimized name second */
qname = knot_pkt_qname(pkt);
rrtype = knot_pkt_qtype(pkt);
if (!knot_dname_is_equal(qname, qry->sname)) {
ret = loot_cache_set(txn, pkt, qname, rrclass, rrtype, timestamp);
}
}
return ret;
}
static int peek(knot_layer_t *ctx, knot_pkt_t *pkt)
{
struct kr_request *req = ctx->data;
......@@ -84,8 +101,7 @@ static int peek(knot_layer_t *ctx, knot_pkt_t *pkt)
* it may either be a CNAME chain or direct answer.
* Only one step of the chain is resolved at a time.
*/
uint32_t timestamp = qry->timestamp.tv_sec;
int ret = loot_cache(&txn, pkt, timestamp);
int ret = loot_cache(&txn, pkt, qry);
kr_cache_txn_abort(&txn);
if (ret == 0) {
DEBUG_MSG("=> satisfied from cache\n");
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment