]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
daemon/engine: build OPT RR in advance
authorMarek Vavruša <marek.vavrusa@nic.cz>
Wed, 22 Jul 2015 10:45:03 +0000 (12:45 +0200)
committerMarek Vavruša <marek.vavrusa@nic.cz>
Wed, 22 Jul 2015 10:45:03 +0000 (12:45 +0200)
daemon/engine.c
daemon/worker.c
lib/resolve.c
lib/resolve.h

index 5db9afa3a7cc266452f4f0c63d9f22536acb00be..e91aef6eb0c5eafbdaf73f141164451f50589609 100644 (file)
@@ -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) {
index 71c43f9de613238a535b014aaf116756638f470b..3cf883d1e3801690a10e0cfc1bb65b973b8a6ca7 100644 (file)
@@ -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 = {
index 0e8af332a75b82d113e0606f31b8d1a765e88318..85b968e7f4077fba111fcb6df339c461eb50b339 100644 (file)
@@ -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 */
index 3f1ddb7ac2dcfa72eb8cd375a1ae8758897fa697..c7e9e0b36c0003ee9ded009cfb73192116b8c1ae 100644 (file)
@@ -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;
 };