From: Marek VavruĊĦa Date: Wed, 22 Jul 2015 10:45:03 +0000 (+0200) Subject: daemon/engine: build OPT RR in advance X-Git-Tag: v1.0.0-beta1~64 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c39158b3b1a0f93a047bc13736e722699895a30f;p=thirdparty%2Fknot-resolver.git daemon/engine: build OPT RR in advance --- diff --git a/daemon/engine.c b/daemon/engine.c index 5db9afa3a..e91aef6eb 100644 --- a/daemon/engine.c +++ b/daemon/engine.c @@ -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) { diff --git a/daemon/worker.c b/daemon/worker.c index 71c43f9de..3cf883d1e 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -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 = { diff --git a/lib/resolve.c b/lib/resolve.c index 0e8af332a..85b968e7f 100644 --- a/lib/resolve.c +++ b/lib/resolve.c @@ -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 */ diff --git a/lib/resolve.h b/lib/resolve.h index 3f1ddb7ac..c7e9e0b36 100644 --- a/lib/resolve.h +++ b/lib/resolve.h @@ -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; };