From b0fe8ce6f1f0add1fcea24946363a787c1c8c09a Mon Sep 17 00:00:00 2001 From: Tomas Krizek Date: Thu, 8 Apr 2021 12:57:33 +0200 Subject: [PATCH] daemon/worker: add doh_headers_in list --- daemon/bindings/net.c | 50 +++++++++++++++++++++++++++++++++++++++++++ daemon/worker.c | 6 ++++++ daemon/worker.h | 6 ++++++ 3 files changed, 62 insertions(+) diff --git a/daemon/bindings/net.c b/daemon/bindings/net.c index 37ae24001..d41578d4f 100644 --- a/daemon/bindings/net.c +++ b/daemon/bindings/net.c @@ -435,6 +435,55 @@ static int net_tls(lua_State *L) return 1; } +/** Select HTTP headers to subscribe to for incoming DoH requests. */ +static int net_doh_headers_in(lua_State *L) +{ + doh_headerlist_t *headers = &the_worker->doh_headers_in; + int i; + const char *name; + + /* Only return current configuration. */ + if (lua_gettop(L) == 0) { + lua_newtable(L); + for (i = 0; i < headers->len; i++) { + lua_pushinteger(L, i + 1); + name = headers->at[i]; + lua_pushlstring(L, name, strlen(name)); + lua_settable(L, -3); + } + return 1; + } + + if (lua_gettop(L) != 1) + lua_error_p(L, "net.doh_headers_in() takes one parameter (string or table)"); + + if (!lua_istable(L, 1) && !lua_isstring(L, 1)) + lua_error_p(L, "net.doh_headers_in() argument must be string or table"); + + /* Clear existing headers. */ + for (i = 0; i < headers->len; i++) + free(headers->at[i]); + array_clear(*headers); + + if (lua_istable(L, 1)) { + for (i = 1; !lua_isnil(L, -1); i++) { + lua_pushinteger(L, i); + lua_gettable(L, 1); + if (lua_isnil(L, -1)) /* missing value - end iteration */ + break; + if (!lua_isstring(L, -1)) + lua_error_p(L, "net.doh_headers_in() argument table can only contain strings"); + name = lua_tostring(L, -1); + array_push(*headers, strdup(name)); + } + } else if (lua_isstring(L, 1)) { + name = lua_tostring(L, 1); + array_push(*headers, strdup(name)); + } + + return 0; +} + /** Return a lua table with TLS authentication parameters. * The format is the same as passed to policy.TLS_FORWARD(); * more precisely, it's in a compatible canonical form. */ @@ -1083,6 +1132,7 @@ int kr_bindings_net(lua_State *L) { "bpf_set", net_bpf_set }, { "bpf_clear", net_bpf_clear }, { "register_endpoint_kind", net_register_endpoint_kind }, + { "doh_headers_in", net_doh_headers_in }, { NULL, NULL } }; luaL_register(L, "net", lib); diff --git a/daemon/worker.c b/daemon/worker.c index 586d6e303..35f82f188 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -2149,6 +2149,10 @@ void worker_deinit(void) trie_free(worker->subreq_out); worker->subreq_out = NULL; + for (int i = 0; i < worker->doh_headers_in.len; i++) + free(worker->doh_headers_in.at[i]); + array_clear(worker->doh_headers_in); + reclaim_mp_freelist(&worker->pool_mp); mp_delete(worker->pkt_pool.ctx); worker->pkt_pool.ctx = NULL; @@ -2183,6 +2187,8 @@ int worker_init(struct engine *engine, int worker_count) worker->out_addr4.sin_family = AF_UNSPEC; worker->out_addr6.sin6_family = AF_UNSPEC; + array_init(worker->doh_headers_in); + int ret = worker_reserve(worker, MP_FREELIST_SIZE); if (ret) return ret; worker->next_request_uid = UINT16_MAX + 1; diff --git a/daemon/worker.h b/daemon/worker.h index 51c9099cc..26ae415cf 100644 --- a/daemon/worker.h +++ b/daemon/worker.h @@ -157,6 +157,9 @@ typedef array_t(struct mempool *) mp_freelist_t; /** List of query resolution tasks. */ typedef array_t(struct qr_task *) qr_tasklist_t; +/** List of HTTP header names. */ +typedef array_t(const char *) doh_headerlist_t; + /** \details Worker state is meant to persist during the whole life of daemon. */ struct worker_ctx { struct engine *engine; @@ -185,6 +188,9 @@ struct worker_ctx { mp_freelist_t pool_mp; knot_mm_t pkt_pool; unsigned int next_request_uid; + + /* HTTP Headers for DoH. */ + doh_headerlist_t doh_headers_in; }; /** @endcond */ -- 2.47.3