]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
daemon/worker: add doh_headers_in list
authorTomas Krizek <tomas.krizek@nic.cz>
Thu, 8 Apr 2021 10:57:33 +0000 (12:57 +0200)
committerTomas Krizek <tomas.krizek@nic.cz>
Mon, 24 May 2021 12:20:15 +0000 (14:20 +0200)
daemon/bindings/net.c
daemon/worker.c
daemon/worker.h

index 37ae240018a1e213a0946baf4f74ba0a233c81e0..d41578d4f5b1a7b7989937182023c4b3af3829c9 100644 (file)
@@ -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);
index 586d6e3035a1e90ff5c6b96c6e6d1d6953af6f77..35f82f188dc8facef8c81a88769aa74b475726c3 100644 (file)
@@ -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;
index 51c9099cc11f6ec84f49b4fa9d5e89217fda3fa3..26ae415cfe8293a0bfc9369d4f40778ed0d94a38 100644 (file)
@@ -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 */