Commit c39158b3 authored by Marek Vavruša's avatar Marek Vavruša

daemon/engine: build OPT RR in advance

parent f824df96
......@@ -202,16 +202,23 @@ void *namedb_lmdb_mkopts(const char *conf, size_t maxsize)
static int init_resolver(struct engine *engine)
{
/* Open resolution context */
engine->resolver.pool = engine->pool;
engine->resolver.modules = &engine->modules;
/* Create OPT RR */
engine->resolver.opt_rr = mm_alloc(engine->pool, sizeof(knot_rrset_t));
if (!engine->resolver.opt_rr) {
return kr_error(ENOMEM);
}
knot_edns_init(engine->resolver.opt_rr, KR_EDNS_PAYLOAD, 0, KR_EDNS_VERSION, engine->pool);
/* Set default root hints */
kr_zonecut_init(&engine->resolver.root_hints, (const uint8_t *)"", engine->pool);
kr_zonecut_set_sbelt(&engine->resolver, &engine->resolver.root_hints);
/* Open NS rtt + reputation cache */
engine->resolver.cache_rtt = malloc(lru_size(kr_nsrep_lru_t, LRU_RTT_SIZE));
engine->resolver.cache_rtt = mm_alloc(engine->pool, lru_size(kr_nsrep_lru_t, LRU_RTT_SIZE));
if (engine->resolver.cache_rtt) {
lru_init(engine->resolver.cache_rtt, LRU_RTT_SIZE);
}
engine->resolver.cache_rep = malloc(lru_size(kr_nsrep_lru_t, LRU_REP_SIZE));
engine->resolver.cache_rep = mm_alloc(engine->pool, lru_size(kr_nsrep_lru_t, LRU_REP_SIZE));
if (engine->resolver.cache_rep) {
lru_init(engine->resolver.cache_rep, LRU_REP_SIZE);
}
......@@ -267,6 +274,7 @@ int engine_init(struct engine *engine, mm_ctx_t *pool)
/* Initialize resolver */
ret = init_resolver(engine);
if (ret != 0) {
engine_deinit(engine);
return ret;
}
/* Initialize network */
......@@ -294,13 +302,13 @@ void engine_deinit(struct engine *engine)
return;
}
/* Only close sockets and services,
* no need to clean up mempool. */
network_deinit(&engine->net);
kr_zonecut_deinit(&engine->resolver.root_hints);
kr_cache_close(&engine->resolver.cache);
lru_deinit(engine->resolver.cache_rtt);
free(engine->resolver.cache_rtt);
lru_deinit(engine->resolver.cache_rep);
free(engine->resolver.cache_rep);
/* Unload modules. */
for (size_t i = 0; i < engine->modules.len; ++i) {
......
......@@ -93,12 +93,13 @@ static struct qr_task *qr_task_create(struct worker_ctx *worker, uv_handle_t *ha
{
/* How much can client handle? */
size_t answer_max = KNOT_WIRE_MIN_PKTSIZE;
size_t pktbuf_max = KR_EDNS_PAYLOAD;
if (!addr && handle) { /* TCP */
answer_max = KNOT_WIRE_MAX_PKTSIZE;
pktbuf_max = KNOT_WIRE_MAX_PKTSIZE;
} else if (knot_pkt_has_edns(query)) { /* EDNS */
answer_max = MAX(knot_edns_get_payload(query->opt_rr), KNOT_WIRE_MIN_PKTSIZE);
}
size_t pktbuf_max = MAX(KNOT_EDNS_MAX_UDP_PAYLOAD, answer_max);
/* Recycle available mempool if possible */
mm_ctx_t pool = {
......
......@@ -208,6 +208,9 @@ static int sendrecv(struct sockaddr *addr, int proto, const knot_pkt_t *query, k
static int edns_put(knot_pkt_t *pkt)
{
if (!pkt->opt_rr) {
return kr_ok();
}
/* Reclaim reserved size. */
int ret = knot_pkt_reclaim(pkt, knot_edns_wire_size(pkt->opt_rr));
if (ret != 0) {
......@@ -218,17 +221,9 @@ static int edns_put(knot_pkt_t *pkt)
return knot_pkt_put(pkt, KNOT_COMPR_HINT_NONE, pkt->opt_rr, KNOT_PF_FREE);
}
static int edns_create(knot_pkt_t *pkt, knot_pkt_t *template)
static int edns_create(knot_pkt_t *pkt, knot_pkt_t *template, struct kr_request *req)
{
/* Create empty OPT RR */
pkt->opt_rr = mm_alloc(&pkt->mm, sizeof(*pkt->opt_rr));
if (!pkt->opt_rr) {
return kr_error(ENOMEM);
}
int ret = knot_edns_init(pkt->opt_rr, KR_EDNS_PAYLOAD, 0, KR_EDNS_VERSION, &pkt->mm);
if (ret != 0) {
return ret;
}
pkt->opt_rr = knot_rrset_copy(req->ctx->opt_rr, &pkt->mm);
/* Set DO bit if set (DNSSEC requested). */
if (knot_pkt_has_dnssec(template)) {
knot_edns_set_do(pkt->opt_rr);
......@@ -236,7 +231,7 @@ static int edns_create(knot_pkt_t *pkt, knot_pkt_t *template)
return knot_pkt_reserve(pkt, knot_edns_wire_size(pkt->opt_rr));
}
static int answer_prepare(knot_pkt_t *answer, knot_pkt_t *query)
static int answer_prepare(knot_pkt_t *answer, knot_pkt_t *query, struct kr_request *req)
{
if (!knot_wire_get_rd(query->wire)) {
return kr_error(ENOSYS); /* Only recursive service */
......@@ -246,7 +241,7 @@ static int answer_prepare(knot_pkt_t *answer, knot_pkt_t *query)
}
/* Handle EDNS in the query */
if (knot_pkt_has_edns(query)) {
int ret = edns_create(answer, query);
int ret = edns_create(answer, query, req);
if (ret != 0){
return ret;
}
......@@ -275,7 +270,7 @@ static int query_finalize(struct kr_request *request, knot_pkt_t *pkt)
int ret = 0;
knot_pkt_begin(pkt, KNOT_ADDITIONAL);
if (!(qry->flags & QUERY_SAFEMODE)) {
ret = edns_create(pkt, request->answer);
ret = edns_create(pkt, request->answer, request);
if (ret == 0) {
ret = edns_put(pkt);
}
......@@ -384,7 +379,7 @@ int kr_resolve_consume(struct kr_request *request, knot_pkt_t *packet)
/* Empty resolution plan, push packet as the new query */
if (packet && kr_rplan_empty(rplan)) {
if (answer_prepare(request->answer, packet) != 0) {
if (answer_prepare(request->answer, packet, request) != 0) {
return KNOT_STATE_FAIL;
}
/* Start query resolution */
......
......@@ -109,6 +109,7 @@ struct kr_context
kr_nsrep_lru_t *cache_rtt;
kr_nsrep_lru_t *cache_rep;
module_array_t *modules;
knot_rrset_t *opt_rr;
uint32_t options;
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment