]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
daemon/quic: remove old reference implementation
authorFrantisek Tobias <frantisek.tobias@nic.cz>
Tue, 23 Sep 2025 09:53:50 +0000 (11:53 +0200)
committerFrantisek Tobias <frantisek.tobias@nic.cz>
Wed, 7 Jan 2026 13:39:14 +0000 (14:39 +0100)
daemon/quic.c [deleted file]
daemon/quic.h [deleted file]

diff --git a/daemon/quic.c b/daemon/quic.c
deleted file mode 100644 (file)
index 70295dc..0000000
+++ /dev/null
@@ -1,1796 +0,0 @@
-// /*  Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
-//  *  SPDX-License-Identifier: GPL-3.0-or-later
-//  */
-//
-// #include <asm-generic/errno-base.h>
-// #include <asm-generic/errno.h>
-// #include <bits/types/struct_iovec.h>
-// #include <gnutls/x509.h>
-// #include <gnutls/gnutls.h>
-// #include <gnutls/crypto.h>
-// #include "lib/defines.h"
-// #include "lib/log.h"
-// #include "lib/resolve-impl.h"
-// #include "mempattern.h"
-// #include "session2.h"
-// #include "network.h"
-// #include "lib/resolve.h"
-// // #include "libknot/quic/quic.h"
-// #include "libdnssec/random.h"
-// #include <libknot/wire.h>
-// #include <libknot/xdp/tcp_iobuf.h>
-// #include <stdint.h>
-// #include <contrib/ucw/heap.h>
-// #include <contrib/ucw/lists.h>
-// #include <ngtcp2/ngtcp2.h>
-// #include <ngtcp2/ngtcp2_crypto.h>
-// #include <ngtcp2/ngtcp2_crypto_gnutls.h>
-// #include "contrib/openbsd/siphash.h"
-// #include "lib/utils.h"
-// #include "libdnssec/error.h"
-//
-// #include <stddef.h>
-// #include <netinet/in.h>
-//
-// #include <stdlib.h>
-// #include <string.h>
-// #include <uv.h>
-// #include <worker.h>
-//
-// // FIXME: For now just to perform the pin check once HS finishes
-// #include <libknot/quic/tls_common.h>
-//
-// #include "quic.h"
-// #include "quic_stream.h"
-//
-// /** Implementation overview
-//  * From a very high standpoint a DoQ query is handled as follows:
-//  * As a server side we only react to incoming communication from
-//  * the client. Every time client flushes his prepared pkt, we try
-//  * to respond by either:
-//  *   1. Driving the handshake process forward or
-//  *   2. resolving the query and provinding the response.
-//  *
-//  * In other words any time pl_quic_unwrap is invoked, we:
-//  * 1. Check the connection table to either resume a connection or
-//  *   create a new one.
-//  *
-//  * 2. Read all the data provided in the protolayer_payload.
-//  *   2.1. If the read data contains any ACK frames (i.e. the pkt is not 0RTT)
-//  *     we shift the left side of "send but not acked" buffer.
-//  *
-//  * 3. Attempt to create a response.
-//  *   3.1. In case the query has not been as of yet fully received and acked.
-//  *     we just call ngtcp2_conn_writev_stream with no data (see ngtcp2 doc.).
-//  *     ngtcp2 takes care of all that is neccesary for a succesful conclusion
-//  *     of a quic HS.
-//  *   3.2. In case we received STREAM FIN we know that client has no more data
-//  *     to send and we can begin resolving the query. RFC 9250 requires
-//  *     a stream to be used for exactly one query. Since the client has
-//  *     closed his write endpoint and we have send all we had, we can
-//  *     now close the entire stream.
-//  *
-//  * 4. The connection will remain in memory, allowing the user
-//  *   to simply open a new stream and send the next query.
-//  *
-//  * This overview ignores crutial details, special cases, and whole
-//  * sections of the implementation. Refer to RFC 9000, RF 9001, RFC 9250, 
-//  * https://nghttp2.org/ngtcp2/index.html, and the code itself
-//  * for a comprehensive understanding.
-//  */
-//
-// /* TODO discuss size */
-// #define OUTBUF_SIZE 131072
-//
-// static uint64_t cid2hash(const ngtcp2_cid *cid, kr_quic_table_t *table);
-// kr_quic_conn_t *kr_quic_table_lookup(const ngtcp2_cid *cid, kr_quic_table_t *table);
-// kr_quic_cid_t **kr_quic_table_lookup2(const ngtcp2_cid *cid, kr_quic_table_t *table);
-// kr_quic_cid_t **kr_quic_table_insert(kr_quic_conn_t *conn, const ngtcp2_cid *cid,
-//                                     kr_quic_table_t *table);
-// static int pl_quic_client_init(struct session2 *session,
-//                            pl_quic_sess_data_t *quic,
-//                            tls_client_param_t *param);
-// int kr_quic_send(kr_quic_table_t *quic_table, struct kr_quic_conn *conn,
-//             struct protolayer_iter_ctx *ctx, int action,
-//             ngtcp2_version_cid *decoded_cids,
-//             unsigned max_msgs, kr_quic_send_flag_t flags);
-//
-// uint64_t quic_timestamp(void);
-//
-// #define set_application_error(ctx, error_code, reason, reason_len) \
-//     ngtcp2_ccerr_set_application_error(&(ctx)->last_err, \
-//             error_code, reason, reason_len)
-// #define set_transport_error(ctx, error_code, reason, reason_len) \
-//     ngtcp2_ccerr_set_transport_error(&(ctx)->last_err, \
-//             error_code, reason, reason_len)
-//
-// static int cmp_expiry_heap_nodes(void *c1, void *c2)
-// {
-//     if (((kr_quic_conn_t *)c1)->next_expiry < ((kr_quic_conn_t *)c2)->next_expiry)
-//             return -1;
-//
-//     if (((kr_quic_conn_t *)c1)->next_expiry > ((kr_quic_conn_t *)c2)->next_expiry)
-//             return 1;
-//
-//     return 0;
-// }
-//
-// static void kr_quic_rand_cb(uint8_t *dest, size_t destlen,
-//     const ngtcp2_rand_ctx *rand_ctx)
-// {
-//     (void)rand_ctx;
-//     dnssec_random_buffer(dest, destlen);
-// }
-//
-// uint64_t quic_timestamp(void)
-// {
-//     struct timespec ts;
-//     if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0)
-//             return 0;
-//
-//     return ((uint64_t)ts.tv_sec * NGTCP2_SECONDS) + (uint64_t)ts.tv_nsec;
-// }
-//
-// // ngtcp2_conn *get_ngtcp2_conn(void *user_data)
-// // {
-// //  if (!user_data)
-// //          return NULL;
-// //
-// //  pl_quic_sess_data_t *ctx = (pl_quic_sess_data_t *)user_data;
-// //  return ctx->conn;
-// // }
-//
-// static void init_random_cid(ngtcp2_cid *cid, size_t len)
-// {
-//     if (len == 0)
-//             len = SERVER_DEFAULT_SCIDLEN;
-//
-//     cid->datalen = dnssec_random_buffer(cid->data, len) == DNSSEC_EOK ? len : 0;
-// }
-//
-// static bool init_unique_cid(ngtcp2_cid *cid, size_t len, kr_quic_table_t *table)
-// {
-//     do {
-//             if (init_random_cid(cid, len), cid->datalen == 0)
-//                     return false;
-//
-//     } while (kr_quic_table_lookup(cid, table) != NULL);
-//
-//     return true;
-// }
-//
-// kr_quic_conn_t *kr_quic_table_add(ngtcp2_conn *ngconn, const ngtcp2_cid *cid,
-//                                  kr_quic_table_t *table)
-// {
-//     kr_quic_conn_t *conn = calloc(1, sizeof(*conn));
-//     if (conn == NULL)
-//             return NULL;
-//
-//     /* FIXME magic numbers */
-//     conn->conn = ngconn;
-//     conn->quic_table = table;
-//     conn->stream_inprocess = -1;
-//     conn->qlog_fd = -1;
-//     wire_buf_init(&conn->unwrap_buf, 1200);
-//
-//     conn->next_expiry = UINT64_MAX;
-//     if (!heap_insert(table->expiry_heap, (heap_val_t *)conn)) {
-//             free(conn);
-//             return NULL;
-//     }
-//
-//     kr_quic_cid_t **addto = kr_quic_table_insert(conn, cid, table);
-//     if (addto == NULL) {
-//             heap_delete(table->expiry_heap, heap_find(table->expiry_heap, (heap_val_t *)conn));
-//             free(conn);
-//             return NULL;
-//     }
-//
-//     table->usage++;
-//
-//     return conn;
-// }
-//
-// kr_quic_cid_t **kr_quic_table_insert(kr_quic_conn_t *conn, const ngtcp2_cid *cid,
-//                                     kr_quic_table_t *table)
-// {
-//     uint64_t hash = cid2hash(cid, table);
-//
-//     kr_quic_cid_t *cidobj = malloc(sizeof(*cidobj));
-//     if (cidobj == NULL)
-//             return NULL;
-//
-//     static_assert(sizeof(*cid) <= sizeof(cidobj->cid_placeholder),
-//                     "insufficient placeholder for CID struct");
-//     memcpy(cidobj->cid_placeholder, cid, sizeof(*cid));
-//     cidobj->conn = conn;
-//
-//     kr_quic_cid_t **addto = table->conns + (hash % table->size);
-//     cidobj->next = *addto;
-//     *addto = cidobj;
-//     table->pointers++;
-//
-//     return addto;
-// }
-//
-// static int kr_recv_stream_data_cb(ngtcp2_conn *conn, uint32_t flags,
-//     int64_t stream_id, uint64_t offset, const uint8_t *data,
-//     size_t datalen, void *user_data, void *stream_user_data)
-// {
-//     (void)(stream_user_data); // always NULL
-//     (void)(offset); // QUIC shall ensure that data arrive in-order
-//
-//     struct kr_quic_conn *qconn = (struct kr_quic_conn *)user_data;
-//     assert(ctx->conn == conn);
-//
-//     int ret = kr_quic_stream_recv_data(qconn, stream_id, data, datalen,
-//                     (flags & NGTCP2_STREAM_DATA_FLAG_FIN));
-//
-//     return ret == KNOT_EOK ? 0 : NGTCP2_ERR_CALLBACK_FAILURE;
-// }
-//
-// void kr_quic_table_rem2(kr_quic_cid_t **pcid, kr_quic_table_t *table)
-// {
-//     kr_quic_cid_t *cid = *pcid;
-//     *pcid = cid->next;
-//     free(cid);
-//     table->pointers--;
-// }
-//
-// void kr_quic_table_rem(kr_quic_conn_t *conn, kr_quic_table_t *table)
-// {
-//     if (conn == NULL || conn->conn == NULL || table == NULL)
-//             return;
-//
-//     for (ssize_t i = conn->streams_count - 1; i >= 0; i--)
-//             kr_quic_conn_stream_free(conn, (i + conn->first_stream_id) * 4);
-//
-//     assert(conn->streams_count <= 0);
-//     assert(conn->obufs_size == 0);
-//
-//     size_t num_scid = ngtcp2_conn_get_scid(conn->conn, NULL);
-//     ngtcp2_cid *scids = calloc(num_scid, sizeof(*scids));
-//     ngtcp2_conn_get_scid(conn->conn, scids);
-//
-//     for (size_t i = 0; i < num_scid && scids; i++) {
-//             kr_quic_cid_t **pcid = kr_quic_table_lookup2(&scids[i], table);
-//             assert(pcid != NULL);
-//             if (*pcid == NULL)
-//                     continue;
-//
-//             assert((*pcid)->conn == conn);
-//             kr_quic_table_rem2(pcid, table);
-//     }
-//
-//     int pos = heap_find(table->expiry_heap, (heap_val_t *)conn);
-//     heap_delete(table->expiry_heap, pos);
-//
-//     free(scids);
-//
-//     wire_buf_deinit(&conn->unwrap_buf);
-//     gnutls_deinit(conn->tls_session);
-//     ngtcp2_conn_del(conn->conn);
-//     conn->conn = NULL;
-//
-//     // free(conn);
-//
-//     table->usage--;
-// }
-//
-// static int get_new_connection_id(ngtcp2_conn *conn, ngtcp2_cid *cid,
-//                                  uint8_t *token, size_t cidlen,
-//                                  void *user_data)
-// {
-//     kr_quic_conn_t *ctx = (kr_quic_conn_t *)user_data;
-//     assert(ctx->conn == conn);
-//
-//     if (!init_unique_cid(cid, cidlen, ctx->quic_table))
-//             return NGTCP2_ERR_CALLBACK_FAILURE;
-//
-//     kr_quic_cid_t **addto = kr_quic_table_insert(ctx, cid, ctx->quic_table);
-//     (void)addto;
-//
-//     // FIXME: remove?
-//     // ctx->dcid = cid;
-//
-//     if (token != NULL &&
-//         ngtcp2_crypto_generate_stateless_reset_token(
-//                 token, (uint8_t *)ctx->quic_table->hash_secret,
-//                 sizeof(ctx->quic_table->hash_secret), cid) != 0) {
-//             return NGTCP2_ERR_CALLBACK_FAILURE;
-//     }
-//
-//     return 0;
-// }
-//
-// static int handshake_confirmed_cb(ngtcp2_conn *conn, void *ctx)
-// {
-//     (void)conn;
-//     kr_log_info(DOQ, "Handshake confirmed\n");
-//     // ctx->state = CONNECTED;
-//     return kr_ok();
-// }
-//
-// static int handshake_completed_cb(ngtcp2_conn *conn, void *user_data)
-// {
-//     kr_log_info(DOQ, "Handshake completed\n");
-//     kr_quic_conn_t *ctx = (kr_quic_conn_t *)user_data;
-//     assert(ctx->conn == conn);
-//
-//     assert(!(ctx->flags & kr_QUIC_CONN_HANDSHAKE_DONE));
-//     ctx->flags |= KR_QUIC_CONN_HANDSHAKE_DONE;
-//
-//     if (!ngtcp2_conn_is_server(conn)) {
-//             return NGTCP2_NO_ERROR;
-//             // TODO: Perform certificate pin check
-//             // return knot_tls_pin_check(ctx->tls_session, ctx->quic_table->creds)
-//             //        == KNOT_EOK ? 0 : NGTCP2_ERR_CALLBACK_FAILURE;
-//             // return NGTCP2_ERR_CALLBACK_FAILURE;
-//     }
-//
-//     if (gnutls_session_ticket_send(ctx->tls_session, 1, 0) != GNUTLS_E_SUCCESS) {
-//             return -1;
-//     }
-//
-//     uint8_t token[NGTCP2_CRYPTO_MAX_REGULAR_TOKENLEN];
-//     ngtcp2_path path = *ngtcp2_conn_get_path(ctx->conn);
-//     uint64_t ts = quic_timestamp();
-//     ngtcp2_ssize tokenlen = ngtcp2_crypto_generate_regular_token(token,
-//                     (uint8_t *)ctx->quic_table->hash_secret,
-//                     sizeof(ctx->quic_table->hash_secret),
-//                     path.remote.addr, path.remote.addrlen, ts);
-//
-//     if (tokenlen < 0
-//             || ngtcp2_conn_submit_new_token(ctx->conn, token, tokenlen) != 0)
-//             return NGTCP2_ERR_CALLBACK_FAILURE;
-//
-//     return 0;
-// }
-//
-// static void quic_debug_cb(void *user_data, const char *format, ...)
-// {
-//     char buf[256];
-//     va_list args;
-//     va_start(args, format);
-//     (void)vsnprintf(buf, sizeof(buf), format, args);
-//     kr_log_warning(DOQ, "%s\n", buf);
-//     va_end(args);
-// }
-//
-// int recv_crypto_data(ngtcp2_conn *conn,
-//              ngtcp2_encryption_level encryption_level, uint64_t offset,
-//              const uint8_t *data, size_t datalen, void *user_data)
-// {
-//
-//     return ngtcp2_crypto_recv_crypto_data_cb(conn, encryption_level, offset, data,
-//              datalen, user_data);
-// }
-//
-// int do_hp_mask(uint8_t *dest, const ngtcp2_crypto_cipher *hp,
-//             const ngtcp2_crypto_cipher_ctx *hp_ctx, const uint8_t *sample)
-// {
-//     if (ngtcp2_crypto_hp_mask(dest, hp, hp_ctx, sample) != 0) {
-//             return NGTCP2_ERR_CALLBACK_FAILURE;
-//     }
-//
-//     kr_log_debug(DOQ, "hp mask installed %s %d %s %d\n", dest, NGTCP2_HP_MASKLEN, sample, NGTCP2_HP_SAMPLELEN);
-//
-//     return 0;
-// }
-//
-// static int stream_open_cb(ngtcp2_conn *conn, int64_t stream_id, void *user_data)
-// {
-//     kr_log_info(DOQ, "remote endpoint has opened a stream: %ld\n", stream_id);
-//     return kr_ok();
-// }
-//
-// static int stream_close_cb(ngtcp2_conn *conn, uint32_t flags, int64_t stream_id,
-//                      uint64_t app_error_code, void *user_data, void *stream_user_data)
-// {
-//     struct kr_quic_conn *qconn = (struct kr_quic_conn *)user_data;
-//     assert(qconn->conn == conn);
-//
-//     // NOTE possible error is stored in (flags & NGTCP2_STREAM_CLOSE_FLAG_APP_ERROR_CODE_SET)
-//
-//     bool keep = !ngtcp2_conn_is_server(conn);
-//     if (!keep) {
-//             kr_quic_conn_stream_free(qconn, stream_id);
-//     }
-//     return kr_ok();
-// }
-//
-// // TODO: Perhaps move path creating here, It would make sence even though
-// // it is just a simple function call
-// static int conn_new_handler(ngtcp2_conn **pconn, const ngtcp2_path *path,
-//             const ngtcp2_cid *scid, const ngtcp2_cid *dcid,
-//             const ngtcp2_cid *odcid, uint32_t version,
-//             uint64_t now, uint64_t idle_timeout_ns,
-//             kr_quic_conn_t *qconn, bool server, bool retry_sent)
-// {
-//     kr_require(qconn->quic_table != NULL);
-//     kr_quic_table_t *qtable = qconn->quic_table;
-//
-//     const ngtcp2_callbacks callbacks = {
-//             // .client_initial = ngtcp2_crypto_client_initial_cb, // client side callback
-//             .recv_client_initial = ngtcp2_crypto_recv_client_initial_cb,
-//             .recv_crypto_data = ngtcp2_crypto_recv_crypto_data_cb,
-//             .handshake_completed = handshake_completed_cb, // handshake_completed_cb - OPTIONAL
-//             // NULL, // recv_version_negotiation not needed on server, nor kxdpgun - OPTIONAL
-//             .encrypt = ngtcp2_crypto_encrypt_cb,
-//             .decrypt = ngtcp2_crypto_decrypt_cb,
-//             .hp_mask = ngtcp2_crypto_hp_mask_cb,
-//             .recv_stream_data = kr_recv_stream_data_cb, // recv_stream_data, TODO? - OPTIONAL
-//             // NULL, // acked_stream_data_offset_cb, TODO - OPTIONAL
-//             .stream_open = stream_open_cb, // stream_opened - OPTIONAL
-//             .stream_close = stream_close_cb,
-//             // NULL,// recv_stateless_rst, TODO - OPTIONAL
-//             // ngtcp2_crypto_recv_retry_cb, - OPTIONAL
-//             // NULL, // extend_max_streams_bidi - OPTIONAL
-//             // NULL, // extend_max_streams_uni - OPTIONAL
-//             .rand = kr_quic_rand_cb,
-//             .get_new_connection_id = get_new_connection_id,
-//             // NULL, // remove_connection_id, TODO - OPTIONAL
-//             .update_key = ngtcp2_crypto_update_key_cb,
-//             // NULL, // path_validation, - OPTIONAL
-//             // NULL, // select_preferred_addr - OPTIONAL
-//             // NULL,// recv_stream_rst, TODO - OPTIONAL
-//             // NULL, // extend_max_remote_streams_bidi, might be useful to some allocation optimizations? - OPTIONAL
-//             // NULL, // extend_max_remote_streams_uni - OPTIONAL
-//             // NULL, // extend_max_stream_data, - OPTIONAL
-//             // NULL, // dcid_status - OPTIONAL
-//             .handshake_confirmed = handshake_confirmed_cb,
-//             // NULL, // recv_new_token - OPTIONAL
-//             .delete_crypto_aead_ctx = ngtcp2_crypto_delete_crypto_aead_ctx_cb,
-//             .delete_crypto_cipher_ctx = ngtcp2_crypto_delete_crypto_cipher_ctx_cb,
-//             // NULL, // recv_datagram - OPTIONAL
-//             // NULL, // ack_datagram - OPTIONAL
-//             // NULL, // lost_datagram - OPTIONAL
-//             .get_path_challenge_data = ngtcp2_crypto_get_path_challenge_data_cb,
-//             // NULL, // stream_stop_sending - OPTIONAL
-//             .version_negotiation = ngtcp2_crypto_version_negotiation_cb,
-//             // NULL, // recv_rx_key - OPTIONAL
-//             // NULL, // recv_rx_key - OPTIONAL
-//             // .recv_rx_key = recv_rx_key_conf_cb,
-//             // .recv_tx_key = recv_tx_key_conf_cb,
-//     };
-//
-//     ngtcp2_settings settings;
-//     ngtcp2_settings_default(&settings);
-//     settings.initial_ts = now;
-//
-//     if (KR_LOG_LEVEL_IS(LOG_DEBUG)) {
-//     // if (qtable->log_cb != NULL) {
-//             settings.log_printf = quic_debug_cb;
-//     }
-//
-//     // Probablu set bu default, set NULL to disable qlog
-//     // if (qtable->qlog_dir != NULL) {
-//             // settings.qlog_write = user_printf;
-//     // }
-//
-//     if (qtable->udp_payload_limit != 0) {
-//             settings.max_tx_udp_payload_size = qtable->udp_payload_limit;
-//     }
-//
-//     // settings.handshake_timeout = idle_timeout_ns;
-//     // NOTE setting handshake timeout to idle_timeout for simplicity
-//     settings.handshake_timeout = UINT64_MAX; // Do not time out for now
-//     settings.no_pmtud = true;
-//
-//     ngtcp2_transport_params params;
-//     ngtcp2_transport_params_default(&params);
-//
-//     /** This informs peer that active migration might not be available.
-//      * Peer might still attempt to migrate. see RFC 9000/5.2.3 */
-//     params.disable_active_migration = true;
-//
-//     /** There is no use for unidirectional streams for us */
-//     params.initial_max_streams_uni = 1024;
-//     params.initial_max_streams_bidi = 1024;
-//     params.initial_max_stream_data_bidi_local = NGTCP2_MAX_VARINT;
-//     params.initial_max_stream_data_bidi_remote = 102400;
-//     params.initial_max_data = NGTCP2_MAX_VARINT;
-//
-//     // ignore for now; allow any
-//     params.max_idle_timeout = 0;
-//
-//     // params.stateless_reset_token_present = 1;
-//     // params.active_connection_id_limit = 8;
-//
-//     if (odcid != NULL) {
-//             params.original_dcid = *odcid;
-//             params.original_dcid_present = 1;
-//     }
-//
-//     if (retry_sent && scid != NULL) {
-//             params.retry_scid = *scid;
-//             params.retry_scid_present = 1;
-//     }
-//
-//     // TODO: ngtcp2_server example generates stateles reset token here
-//
-//     if (retry_sent) {
-//             assert(scid);
-//             params.retry_scid_present = 1;
-//             params.retry_scid = *scid;
-//     }
-//     if (dnssec_random_buffer(params.stateless_reset_token, NGTCP2_STATELESS_RESET_TOKENLEN) != kr_ok()) {
-//             return KNOT_ERROR;
-//     }
-//
-//     if (server) {
-//             // WARNING: scid and dcid have to be swapped here
-//             // see (https://nghttp2.org/ngtcp2/programmers-guide.html Creating ngtcp2_conn object)
-//             const ngtcp2_cid *swapped_clients_dcid = scid;
-//             const ngtcp2_cid *swapped_clients_scid = dcid;
-//             return ngtcp2_conn_server_new(pconn, swapped_clients_dcid,
-//                             swapped_clients_scid, path, version,
-//                             &callbacks, &settings, &params, NULL, qconn);
-//     } else {
-//             return ngtcp2_conn_client_new(pconn, dcid, scid, path, version, &callbacks,
-//                                           &settings, &params, NULL, qconn);
-//     }
-// }
-//
-//
-// int kr_tls_session(struct gnutls_session_int **session,
-//             struct tls_credentials *creds,
-//             struct gnutls_priority_st *priority,
-//             bool quic, // TODO remove, this function will only be used by doq
-//             bool early_data,
-//             bool server)
-// {
-//     if (session == NULL || creds == NULL || priority == NULL)
-//             return kr_error(EINVAL);
-//
-//     // TODO remove, this function will only be used by doq
-//     const char *alpn = quic ? "\x03""doq" : "\x03""dot";
-//
-//     gnutls_init_flags_t flags = GNUTLS_NO_SIGNAL;
-//     if (early_data) {
-//             flags |= GNUTLS_ENABLE_EARLY_DATA;
-// #ifdef ENABLE_QUIC // Next flags aren't available in older GnuTLS versions.
-//             if (quic) {
-//                     flags |= GNUTLS_NO_END_OF_EARLY_DATA;
-//             }
-// #endif
-//     }
-//
-//     flags |= GNUTLS_SAFE_PADDING_CHECK;
-//
-//     int ret = gnutls_init(session, (server ? GNUTLS_SERVER : GNUTLS_CLIENT) | flags);
-//     if (ret == GNUTLS_E_SUCCESS) {
-//             gnutls_certificate_send_x509_rdn_sequence(*session, 1);
-//             gnutls_certificate_server_set_request(*session, GNUTLS_CERT_REQUEST);
-//             ret = gnutls_priority_set(*session, priority);
-//     }
-//
-//     // if (server && ret == GNUTLS_E_SUCCESS) {
-//     //      kr_log_info(DOQ, "gnutls_ticket sanity: %d %d %d %s\n",
-//     //                      session == NULL, (&creds->tls_ticket_key) == NULL,
-//     //                      creds->tls_ticket_key.size != 64, creds->tls_ticket_key.data);
-//     //      ret = gnutls_session_ticket_enable_server(*session, &creds->tls_ticket_key);
-//     // }
-//
-//     if (ret == GNUTLS_E_SUCCESS) {
-//             const gnutls_datum_t alpn_datum = { (void *)"doq", '\x03' };
-//             gnutls_alpn_set_protocols(*session, &alpn_datum, 1, GNUTLS_ALPN_MANDATORY);
-//
-//             if (early_data) {
-//                     gnutls_record_set_max_early_data_size(*session, 0xffffffffu);
-//             }
-//
-//             if (server) {
-//                     gnutls_anti_replay_enable(*session, creds->tls_anti_replay);
-//             }
-//
-//             ret = gnutls_credentials_set(*session, GNUTLS_CRD_CERTIFICATE,
-//                             creds->credentials);
-//     }
-//
-//     if (ret != GNUTLS_E_SUCCESS) {
-//             kr_log_error(DOQ, "tls session init failed: %s (%d)\n",
-//                             gnutls_strerror(ret), ret);
-//             gnutls_deinit(*session);
-//             *session = NULL;
-//     }
-//
-//     return ret; // == GNUTLS_E_SUCCESS ? KNOT_EOK : KNOT_ERROR;
-// }
-//
-// static ngtcp2_conn *get_conn(ngtcp2_crypto_conn_ref *conn_ref)
-// {
-//     return ((kr_quic_conn_t *)conn_ref->user_data)->conn;
-// }
-//
-// static int tls_init_conn_session(kr_quic_conn_t *conn, bool server)
-// {
-//     int ret = kr_tls_session(&conn->tls_session, conn->quic_table->creds,
-//                                conn->quic_table->priority, true, true, server);
-//     if (ret != KNOT_EOK)
-//             return kr_error(ret);
-//
-//     ret = (server)
-//             ? ngtcp2_crypto_gnutls_configure_server_session(conn->tls_session)
-//             : ngtcp2_crypto_gnutls_configure_client_session(conn->tls_session);
-//     if (ret != NGTCP2_NO_ERROR) {
-//             kr_log_info(DOQ, "Failed to configure crypto session\n");
-//             return kr_error(ret);
-//     }
-//
-//     conn->conn_ref = (nc_conn_ref_placeholder_t) {
-//             .get_conn = get_conn,
-//             .user_data = conn,
-//     };
-//
-//     gnutls_session_set_ptr(conn->tls_session, &conn->conn_ref);
-//     ngtcp2_conn_set_tls_native_handle(conn->conn, conn->tls_session);
-//
-//     return kr_ok();
-// }
-//
-// kr_quic_table_t *kr_quic_table_new(size_t max_conns, size_t max_ibufs, size_t max_obufs,
-//                                        size_t udp_payload, struct tls_credentials *creds)
-// {
-// #define BUCKETS_PER_CONNS 8
-//     size_t table_size = max_conns * BUCKETS_PER_CONNS;
-//
-//     kr_quic_table_t *new_table = calloc(1, sizeof(*new_table) + (table_size * sizeof(new_table->conns[0])));
-//     if (new_table == NULL || creds == NULL) {
-//             kr_log_error(DOQ, "Calloc in kr_quic_table_new_failed %d %d\n",
-//                             new_table == NULL, creds == NULL);
-//             return NULL;
-//     }
-//
-//     new_table->size = table_size;
-//     new_table->max_conns = max_conns;
-//     new_table->ibufs_max = max_ibufs;
-//     new_table->obufs_max = max_obufs;
-//     new_table->obufs_size = 0;
-//     new_table->udp_payload_limit = udp_payload;
-//
-//     // int ret = gnutls_certificate_allocate_credentials(&new_table->creds->credentials);
-//     // if (ret != GNUTLS_E_SUCCESS) {
-//     //      kr_log_error(DOQ, "Failed to allocate TLS credentials (%d) %s\n",
-//     //                      ret, gnutls_strerror(ret));
-//     //      goto failed;
-//     // }
-//
-//
-//     // NOTE: Taken from tls-proxy.c/96, we might need to use this
-//     // to enforce the use of tls1.3 (tls1.3 compat mode might be problematic)
-//     // knot-dns has experienced issues with it in the past
-//     //
-//     // static const char * const tlsv13_priorities =
-//     //      "NORMAL:" /* GnuTLS defaults */
-//     //      "-VERS-TLS1.0:-VERS-TLS1.1:-VERS-TLS1.2:+VERS-TLS1.3:" /* TLS 1.3 only */
-//     //      "-VERS-SSL3.0:-ARCFOUR-128:-COMP-ALL:+COMP-NULL";
-//
-//     int ret = gnutls_priority_init2(&new_table->priority, NULL, NULL, 0);
-//     if (ret != GNUTLS_E_SUCCESS) {
-//             free(new_table);
-//             return NULL;
-//     }
-//
-//     new_table->expiry_heap = malloc(sizeof(struct heap));
-//     if (new_table->expiry_heap == NULL
-//             || !heap_init(new_table->expiry_heap, cmp_expiry_heap_nodes, 0)) {
-//             gnutls_priority_deinit(new_table->priority);
-//             free(new_table->expiry_heap);
-//             free(new_table);
-//             kr_log_error(DOQ, "Expiry heap malloc in kr_quic_table_new_failed\n");
-//             return NULL;
-//     }
-//
-//     new_table->creds = creds;
-//
-//     new_table->hash_secret[0] = dnssec_random_uint64_t();
-//     new_table->hash_secret[1] = dnssec_random_uint64_t();
-//     new_table->hash_secret[2] = dnssec_random_uint64_t();
-//     new_table->hash_secret[3] = dnssec_random_uint64_t();
-//
-//     return new_table;
-// }
-//
-// static int pl_quic_sess_init(struct session2 *session, void *sess_data, void *param)
-// {
-//     pl_quic_sess_data_t *quic = sess_data;
-//     session->secure = true;
-//     queue_init(quic->wrap_queue);
-//     queue_init(quic->unwrap_queue);
-//
-//     if (!the_network->tls_credentials) {
-//             kr_log_info(DOQ, "tls credentials were not present at the start of DoQ iteration\n");
-//             the_network->tls_credentials = tls_get_ephemeral_credentials();
-//             if (!the_network->tls_credentials) {
-//                     kr_log_error(TLS, "X.509 credentials are missing, and ephemeral credentials failed; no TLS\n");
-//                     return kr_error(EINVAL);
-//             }
-//
-//             kr_log_info(TLS, "Using ephemeral TLS credentials\n");
-//     }
-//
-//     struct tls_credentials *creds = the_network->tls_credentials;
-//     kr_require(creds->credentials != NULL);
-//
-//     if (!quic->conn_table) {
-//             // 9000/4.6: only streams with a stream ID less than
-//             // (max_streams * 4 + first_stream_id_of_type) can be opened
-//             // bufsizes -> magic nums from knot (see: libknot/.../quic-requestor.c)
-//             quic->conn_table = kr_quic_table_new(
-//                     1024, 4096, 4096, NGTCP2_MAX_UDP_PAYLOAD_SIZE, creds);
-//
-//             if (!quic->conn_table) {
-//                     kr_log_error(DOQ, "Failed to create QUIC connection table\n");
-//                     return kr_error(ENOMEM);
-//             }
-//
-//             kr_require(quic->conn_table);
-//             quic->conn_count = 0;
-//     }
-//
-//     wire_buf_init(&quic->outbuf, OUTBUF_SIZE);
-//
-//     // TODO set setings?
-//
-//     return 0;
-// }
-//
-// void kr_quic_cleanup(kr_quic_conn_t *conns[], size_t n_conns)
-// {
-//     for (size_t i = 0; i < n_conns; i++) {
-//             if (conns[i] != NULL && conns[i]->conn == NULL) {
-//                     free(conns[i]);
-//                     for (size_t j = i + 1; j < n_conns; j++) {
-//                             if (conns[j] == conns[i]) {
-//                                     conns[j] = NULL;
-//                             }
-//                     }
-//             }
-//     }
-// }
-//
-// static void kr_conn_heap_reschedule(kr_quic_conn_t *conn, kr_quic_table_t *table)
-// {
-//     heap_replace(table->expiry_heap, heap_find(table->expiry_heap, (heap_val_t *)conn), (heap_val_t *)conn);
-// }
-//
-// static void kr_quic_conn_mark_used(kr_quic_conn_t *conn, kr_quic_table_t *table)
-// {
-//     conn->next_expiry = ngtcp2_conn_get_expiry(conn->conn);
-//     kr_conn_heap_reschedule(conn, table);
-// }
-//
-// bool kr_quic_conn_timeout(kr_quic_conn_t *conn, uint64_t *now)
-// {
-//     if (*now == 0)
-//             *now = quic_timestamp();
-//
-//     return *now > ngtcp2_conn_get_expiry(conn->conn);
-// }
-//
-// // TODO
-// // static void send_excessive_load(kr_quic_conn_t *conn, struct kr_quic_reply *reply,
-// //          kr_quic_table_t *table)
-// // {
-// //  if (reply != NULL) {
-// //          reply->handle_ret = KR_QUIC_ERR_EXCESSIVE_LOAD;
-// //          (void)kr_quic_send(table, conn, reply, 0, 0);
-// //  }
-// // }
-// //
-// // void kr_quic_table_sweep(kr_quic_table_t *table, struct kr_quic_reply *sweep_reply,
-// //          struct kr_sweep_stats *stats)
-// // {
-// //  uint64_t now = 0;
-// //  if (table == NULL || stats == NULL) {
-// //          return;
-// //  }
-// //
-// //  while (!EMPTY_HEAP(table->expiry_heap)) {
-// //          kr_quic_conn_t *c = *(kr_quic_conn_t **)HHEAD(table->expiry_heap);
-// //          if ((c->flags & KNOT_QUIC_CONN_BLOCKED)) {
-// //                  break; // highly inprobable
-// //          } else if (table->usage > table->max_conns) {
-// //                  // kr_sweep_stats_incr(stats, KNOT_SWEEP_CTR_LIMIT_CONN);
-// //                  send_excessive_load(c, sweep_reply, table);
-// //                  kr_quic_table_rem(c, table);
-// //          } else if (table->obufs_size > table->obufs_max) {
-// //                  // kr_sweep_stats_incr(stats, KNOT_SWEEP_CTR_LIMIT_OBUF);
-// //                  send_excessive_load(c, sweep_reply, table);
-// //                  kr_quic_table_rem(c, table);
-// //          } else if (table->ibufs_size > table->ibufs_max) {
-// //                  // kr_sweep_stats_incr(stats, KNOT_SWEEP_CTR_LIMIT_IBUF);
-// //                  send_excessive_load(c, sweep_reply, table);
-// //                  kr_quic_table_rem(c, table);
-// //          } else if (quic_conn_timeout(c, &now)) {
-// //                  int ret = ngtcp2_conn_handle_expiry(c->conn, now);
-// //                  if (ret != NGTCP2_NO_ERROR) { // usually NGTCP2_ERR_IDLE_CLOSE or NGTCP2_ERR_HANDSHAKE_TIMEOUT
-// //                          // kr_sweep_stats_incr(stats, KNOT_SWEEP_CTR_TIMEOUT);
-// //                          kr_quic_table_rem(c, table);
-// //                  } else {
-// //                          if (sweep_reply != NULL) {
-// //                                  sweep_reply->handle_ret = KNOT_EOK;
-// //                                  (void)kr_quic_send(table, c, sweep_reply, 0, 0);
-// //                          }
-// //                          kr_quic_conn_mark_used(c, table);
-// //                  }
-// //          }
-// //          kr_quic_cleanup(&c, 1);
-// //
-// //          if (*(kr_quic_conn_t **)HHEAD(table->expiry_heap) == c) { // HHEAD already handled, NOOP, avoid infinite loop
-// //                  break;
-// //          }
-// //  }
-// // }
-//
-// void kr_quic_table_free(kr_quic_table_t *table)
-// {
-//     if (table != NULL) {
-//             while (!EMPTY_HEAP(table->expiry_heap)) {
-//                     kr_quic_conn_t *c = *(kr_quic_conn_t **)HHEAD(table->expiry_heap);
-//                     kr_quic_table_rem(c, table);
-//                     kr_quic_cleanup(&c, 1);
-//                     // free(c);
-//             }
-//             assert(table->usage == 0);
-//             assert(table->pointers == 0);
-//             assert(table->ibufs_size == 0);
-//             assert(table->obufs_size == 0);
-//
-//             gnutls_priority_deinit(table->priority);
-//             heap_deinit(table->expiry_heap);
-//             free(table->expiry_heap);
-//             free(table);
-//     }
-// }
-//
-// static int pl_quic_sess_deinit(struct session2 *session, void *data)
-// {
-//     pl_quic_sess_data_t *quic = data;
-//     queue_deinit(quic->unwrap_queue);
-//     queue_deinit(quic->wrap_queue);
-//     kr_quic_table_free(quic->conn_table);
-//     wire_buf_deinit(&quic->outbuf);
-//
-//     return kr_ok();
-// }
-//
-// static int pl_quic_client_init(struct session2 *session,
-//                            pl_quic_sess_data_t *quic,
-//                            tls_client_param_t *param)
-// {
-//     // knot_quic_conn_t *cl_conn = NULL;
-//     //
-//     // knot_quic_conn_t *out_conn;
-//     //
-//     // // calls conn new
-//     // int ret = knot_quic_client((knot_quic_table_t *)quic->conn_table,
-//     //                         (struct sockaddr_in6 *)session->comm_storage.dst_addr,
-//     //                         (struct sockaddr_in6 *)session->comm_storage.comm_addr,
-//     //                         NULL, /* server_name - I do not see the point for this arg */
-//     //                         &out_conn);
-//     // if (ret == KNOT_EOK) {
-//     //      // kr_log_warning(DOQ, "Failed to create quic client");
-//     //      return -1;
-//     // }
-//
-//     return kr_ok();
-// }
-//
-// static uint64_t cid2hash(const ngtcp2_cid *cid, kr_quic_table_t *table)
-// {
-//     SIPHASH_CTX ctx;
-//     kr_require(table->hash_secret != NULL);
-//     SipHash24_Init(&ctx, (const SIPHASH_KEY *)(table->hash_secret));
-//     SipHash24_Update(&ctx, cid->data, MIN(cid->datalen, 8));
-//     uint64_t ret = SipHash24_End(&ctx);
-//     return ret;
-// }
-//
-// kr_quic_cid_t **kr_quic_table_lookup2(const ngtcp2_cid *cid, kr_quic_table_t *table)
-// {
-//     uint64_t hash = cid2hash(cid, table);
-//
-//     kr_quic_cid_t **res = table->conns + (hash % table->size);
-//     while (*res != NULL && !ngtcp2_cid_eq(cid, (const ngtcp2_cid *)(*res)->cid_placeholder)) {
-//             res = &(*res)->next;
-//     }
-//     return res;
-// }
-//
-// kr_quic_conn_t *kr_quic_table_lookup(const ngtcp2_cid *cid, kr_quic_table_t *table)
-// {
-//     kr_quic_cid_t **pcid = kr_quic_table_lookup2(cid, table);
-//     assert(pcid != NULL);
-//     return *pcid == NULL ? NULL : (*pcid)->conn;
-// }
-//
-// bool kr_quic_require_retry(kr_quic_table_t *table)
-// {
-//     (void)table;
-//     return false;
-// }
-//
-// static int kr_quic_set_addrs(struct protolayer_iter_ctx *ctx, ngtcp2_path *path)
-// {
-//     const struct sockaddr *remote = NULL;
-//     const struct sockaddr *local = NULL;
-//
-//     if (ctx->session->outgoing) {
-//             remote = ctx->comm->dst_addr;
-//             local = ctx->comm->src_addr;
-//     } else {
-//             remote = ctx->comm->src_addr;
-//             local = ctx->comm->dst_addr;
-//     }
-//
-//     if (local == NULL) {
-//             local = session2_get_sockname(ctx->session);
-//             // struct sockaddr_storage ss;
-//             // memset(&ss, 0, sizeof(ss));
-//             //
-//             // struct sockaddr_in *addr = (struct sockaddr_in *)&ss;
-//             // addr->sin_family = AF_INET;
-//             // addr->sin_port = htons(8u);
-//             // inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
-//             //
-//             // struct sockaddr *nlocal 
-//             // };
-//             // local = 
-//     }
-//
-//     path->remote.addr = (struct sockaddr *)remote;
-//     path->remote.addrlen = kr_sockaddr_len(remote);
-//     path->local.addr = (struct sockaddr *)local;
-//     path->local.addrlen = kr_sockaddr_len(local);
-//
-//     return kr_ok();
-// }
-//
-// static int quic_init_server_conn(kr_quic_table_t *table,
-//             struct protolayer_iter_ctx *ctx,
-//             uint64_t idle_timeout,
-//             ngtcp2_cid *scid, ngtcp2_cid *dcid, ngtcp2_version_cid decoded_cids,
-//             const uint8_t *payload, size_t payload_len,
-//             kr_quic_conn_t **out_conn)
-// {
-//     if (!table || !ctx|| !out_conn || !scid || !dcid) {
-//             kr_log_error(DOQ, "conn params were null\n");
-//             return kr_error(EINVAL);
-//     }
-//
-//     int ret = EXIT_FAILURE;
-//     ngtcp2_cid odcid = { 0 };
-//
-//     uint64_t now = quic_timestamp(); // the timestamps needs to be collected AFTER the check for blocked conn
-//     ngtcp2_path path;
-//     kr_quic_set_addrs(ctx, &path);
-//
-//     kr_require(*out_conn == NULL);
-//
-//     ngtcp2_pkt_hd header = { 0 };
-//     ret = ngtcp2_accept(&header, payload, payload_len);
-//     if (ret != 0) {
-//             ret = -QUIC_SEND_STATELESS_RESET;
-//             goto finish;
-//     }
-//
-//     // TODO This never happens (kr_quic_require_retry just returns false)
-//     // if (header.tokenlen == 0
-//     //              && kr_quic_require_retry(table) /* TBD */) {
-//     //      ret = -QUIC_SEND_RETRY;
-//     //      goto finish;
-//     // }
-//
-//     if (header.tokenlen > 0) {
-//             if (header.token[0] == NGTCP2_CRYPTO_TOKEN_MAGIC_RETRY) {
-//                     ret = ngtcp2_crypto_verify_retry_token(
-//                             &odcid, header.token, header.tokenlen,
-//                             (const uint8_t *)table->hash_secret,
-//                             sizeof(table->hash_secret), header.version,
-//                             // (const struct sockaddr *)reply->ip_rem,
-//                             path.remote.addr,
-//                             path.remote.addrlen,
-//                             dcid, idle_timeout, now // NOTE setting retry token validity to idle_timeout for simplicity
-//                     );
-//             } else {
-//                     ret = ngtcp2_crypto_verify_regular_token(
-//                             header.token, header.tokenlen,
-//                             (const uint8_t *)table->hash_secret,
-//                             sizeof(table->hash_secret),
-//                             // (const struct sockaddr *)reply->ip_rem,
-//                             path.remote.addr,
-//                             path.remote.addrlen,
-//                             QUIC_REGULAR_TOKEN_TIMEOUT, now
-//                     );
-//             }
-//
-//             if (ret != 0)
-//                     goto finish;
-//
-//     } else {
-//             // ngtcp2_cid_init(&odcid, dcid->data, dcid->datalen);
-//             memcpy(&odcid, dcid, sizeof(odcid));
-//             kr_assert(ngtcp2_cid_eq(&odcid, dcid));
-//     }
-//
-//     // server chooses his CID to his liking
-//     if (!init_unique_cid(dcid, 0, table)) {
-//             kr_log_error(DOQ, "Failed to initialize unique cid (servers choice)\n");
-//             ret = kr_error(-1);
-//             goto finish;
-//     }
-//
-//     *out_conn = kr_quic_table_add(NULL, dcid, table);
-//     if (*out_conn == NULL) {
-//             kr_log_error(DOQ, "Failed to create new connection\n");
-//             ret = kr_error(ENOMEM);
-//             goto finish;
-//     }
-//
-//     ret = conn_new_handler(&(*out_conn)->conn, &path,
-//                     &header.scid, dcid, &header.dcid,
-//                     decoded_cids.version, now, idle_timeout,
-//                     *out_conn, true, header.tokenlen > 0);
-//
-//     if (ret >= 0) {
-//             ret = tls_init_conn_session(*out_conn, true);
-//     } else {
-//             kr_quic_table_rem(*out_conn, table);
-//             // free(*out_conn);
-//             kr_log_error(DOQ, "Failed to create new server connection\n");
-//             goto finish;
-//     }
-//
-//     return kr_ok();
-//
-// finish:
-//     // WARNING: This looks like it is here for thread return values,
-//     // therefore useless for us
-//     // reply->handle_ret = ret;
-//     return ret;
-// }
-//
-// static int handle_packet(struct pl_quic_sess_data *quic,
-//             struct protolayer_iter_ctx *ctx, const uint8_t *pkt,
-//             size_t pktlen, struct quic_target *target,
-//             ngtcp2_version_cid *dec_cids, struct kr_quic_conn **out_conn,
-//             int *action)
-// {
-//     *action = 0;
-//     kr_quic_conn_t *qconn = NULL;
-//
-//     // Initial comm processing
-//     // ngtcp2_version_cid decoded_cids = { 0 };
-//     // FIXME: duplicate read, reread in quic_init_server_conn (accept)
-//     int ret = ngtcp2_pkt_decode_version_cid(dec_cids, pkt,
-//                     pktlen, SERVER_DEFAULT_SCIDLEN);
-//
-//     /* If Version Negotiation is required, this function
-//      * returns NGTCP2_ERR_VERSION_NEGOTIATION.
-//      * Unlike the other error cases, all fields of dest are assigned
-//      * see https://nghttp2.org/ngtcp2/ngtcp2_pkt_decode_version_cid.html */
-//     if (ret != NGTCP2_NO_ERROR && ret != NGTCP2_ERR_VERSION_NEGOTIATION) {
-//             kr_log_warning(DOQ, "Could not decode pkt header: (%d) %s \n",
-//                             ret, ngtcp2_strerror(ret));
-//             return kr_ok();
-//     }
-//     uint32_t supported_quic[1] = { NGTCP2_PROTO_VER_V1 };
-//     ngtcp2_cid_init(&target->dcid, dec_cids->dcid, dec_cids->dcidlen);
-//     ngtcp2_cid_init(&target->scid, dec_cids->scid, dec_cids->scidlen);
-//     if (ret == NGTCP2_ERR_VERSION_NEGOTIATION) {
-//             *action = -QUIC_SEND_VERSION_NEGOTIATION;
-//             return kr_ok();
-//             // goto finish
-//     }
-//
-//     qconn = kr_quic_table_lookup(&target->dcid, quic->conn_table);
-//     if (!qconn) {
-//             struct protolayer_data_param data_param = {
-//                     .protocol = PROTOLAYER_TYPE_QUIC,
-//                     .param = NULL /* TODO! */
-//             };
-//
-//             struct session2 *conn_sess = session2_new(SESSION2_TRANSPORT_PARENT,
-//                             KR_PROTO_DOQ,
-//                             &data_param,
-//                             0,
-//                             false);
-//
-//             /* TODO react accordingly to errcodes from accept.
-//              * not all errors are terminal nor are all quiet,
-//              * see which case warrants the payload to be discarded
-//              * (we have to avoid looping over one bad pkt indefinitelly) */
-//             if ((ret = quic_init_server_conn(quic->conn_table, ctx,
-//                              UINT64_MAX - 1, &target->scid, &target->dcid,
-//                              *dec_cids, pkt, pktlen, &qconn)) != kr_ok()) {
-//                     return ret;
-//             }
-//
-//             /* Should not happen, if it did we certainly cannot
-//              * continue in the communication
-//              * Perhaps kr_require is too strong, this situation
-//              * shouldn't corelate with kresd run.
-//              * TODO: switch to condition and failed resolution */
-//             kr_require(qconn);
-//             // continue;
-//     }
-//
-//     uint64_t now = quic_timestamp();
-//     const ngtcp2_path *path = ngtcp2_conn_get_path(qconn->conn);
-//     ngtcp2_pkt_info pi = { .ecn = NGTCP2_ECN_NOT_ECT, };
-//
-//     // while (ngtcp2_conn_read_pkt(qconn->conn, path, &pi, pkt, pktlen, now) == 0);
-//     ret = ngtcp2_conn_read_pkt(qconn->conn, path, &pi, pkt, pktlen, now);
-//
-//     *out_conn = qconn;
-//     /* FIXME: inacurate error handling */
-//     if (ret == NGTCP2_ERR_DRAINING) { // doq received CONNECTION_CLOSE from the counterpart
-//             kr_quic_table_rem(qconn, quic->conn_table);
-//             wire_buf_reset(ctx->payload.wire_buf);
-//             *action = KR_QUIC_HANDLE_RET_CLOSE;
-//             free(*out_conn);
-//             return kr_ok();
-//
-//     } else if (ngtcp2_err_is_fatal(ret)) { // connection doomed
-//             kr_log_error(DOQ, "fatal error in ngtcp2_conn_read_pkt: %s (%d)", ngtcp2_strerror(ret), ret);
-//             // if (ret == NGTCP2_ERR_CALLBACK_FAILURE) {
-//                     // ret = kr_error(KNOT_EBADCERT);
-//             // } else {
-//             //      ret = kr_error();
-//             // }
-//             kr_quic_table_rem(qconn, quic->conn_table);
-//             return ret;
-//
-//     } else if (ret == NGTCP2_ERR_RETRY) {
-//             kr_log_info(DOQ, "server will perform address validation via Retry packet\n");
-//             *action = QUIC_SEND_RETRY;
-//             wire_buf_reset(ctx->payload.wire_buf);
-//             return kr_ok();
-//
-//     } else if (ret != NGTCP2_NO_ERROR) { // non-fatal error, discard packet
-//             kr_log_error(DOQ, "discarding recieved pkt: %s (%d)", ngtcp2_strerror(ret), ret);
-//             ret = KNOT_EOK;
-//             return ret;
-//     }
-//
-//     ngtcp2_conn_handle_expiry(qconn->conn, now);
-//
-//     /* given the 0 return value the pkt has been processed */
-//     wire_buf_reset(ctx->payload.wire_buf);
-//     return kr_ok();
-// }
-//
-// static int get_query(struct protolayer_iter_ctx *ctx,
-//             struct kr_quic_conn *qconn, struct quic_target *target)
-// {
-//     kr_require(wire_buf_data_length(&qconn->unwrap_buf) == 0);
-//
-//     int64_t stream_id;
-//     struct kr_quic_stream *stream;
-//     stream = kr_quic_stream_get_process(qconn, &stream_id);
-//
-//     /* no stream has finished payload (should not happen) */
-//     kr_require(stream);
-//
-//     size_t to_write = wire_buf_data_length(&stream->pers_inbuf);
-//     ctx->payload = protolayer_payload_wire_buf(&stream->pers_inbuf,
-//                     false);
-//
-//     target->stream_id = stream_id;
-//     ctx->comm->target = target;
-//
-//     if (to_write > wire_buf_free_space_length(&qconn->unwrap_buf)) {
-//             kr_log_error(DOQ, "unwrap buf is not big enough\n");
-//             return kr_error(ENOMEM);
-//     }
-//
-//     memcpy(wire_buf_free_space(&qconn->unwrap_buf),
-//             wire_buf_data(&stream->pers_inbuf), to_write);
-//     wire_buf_consume(&qconn->unwrap_buf, to_write);
-//     wire_buf_trim(&stream->pers_inbuf, to_write);
-//     if (wire_buf_data_length(&stream->pers_inbuf) == 0) {
-//             wire_buf_deinit(&stream->pers_inbuf);
-//             memset(&stream->pers_inbuf, 0, sizeof(struct wire_buf));
-//     }
-//
-//     return to_write;
-// }
-//
-// static int collect_queries(struct protolayer_iter_ctx *ctx,
-//             struct kr_quic_conn *qconn, struct quic_target *target)
-// {
-//     kr_require(wire_buf_data_length(&qconn->unwrap_buf) == 0);
-//     size_t free_space = wire_buf_free_space_length(&qconn->unwrap_buf);
-//     uint16_t queries_agregated = 0;
-//
-//     int64_t stream_id;
-//     struct kr_quic_stream *stream;
-//     while (qconn != NULL
-//             && (stream = kr_quic_stream_get_process(qconn,
-//                             &stream_id)) != NULL) {
-//
-//             size_t to_write = wire_buf_data_length(&stream->pers_inbuf);
-//             ctx->payload = protolayer_payload_wire_buf(&stream->pers_inbuf,
-//                             false);
-//
-//             target->stream_id = stream_id;
-//             ctx->comm->target = target;
-//
-//             kr_assert(to_write > 0);
-//             if (to_write > free_space) {
-//                     kr_log_error(DOQ, "unwrap buf is not big enough\n");
-//                     return kr_error(ENOMEM);
-//             }
-//
-//             memcpy(wire_buf_free_space(&qconn->unwrap_buf),
-//                     wire_buf_data(&stream->pers_inbuf), to_write);
-//             wire_buf_consume(&qconn->unwrap_buf, to_write);
-//             wire_buf_trim(&stream->pers_inbuf, to_write);
-//             if (wire_buf_data_length(&stream->pers_inbuf) == 0) {
-//                     wire_buf_deinit(&stream->pers_inbuf);
-//                     memset(&stream->pers_inbuf, 0, sizeof(struct wire_buf));
-//             }
-//
-//             free_space -= to_write;
-//             ++queries_agregated;
-//     }
-//
-//     return queries_agregated;
-// }
-//
-// static enum protolayer_iter_cb_result pl_quic_unwrap(void *sess_data,
-//             void *iter_data, struct protolayer_iter_ctx *ctx)
-// {
-//     int ret = kr_ok();
-//     kr_quic_conn_t *qconn = NULL;
-//     struct pl_quic_sess_data *quic = sess_data;
-//
-//     queue_push(quic->unwrap_queue, ctx);
-//
-//     /* TODO Verify this doesn't leak */
-//     struct quic_target *target = malloc(sizeof(struct quic_target));
-//     kr_require(target);
-//
-//     while (protolayer_queue_has_payload(&quic->unwrap_queue)) {
-//             kr_assert(ctx->payload.type == PROTOLAYER_PAYLOAD_WIRE_BUF);
-//             ngtcp2_version_cid dec_cids;
-//             int action;
-//
-//             ret = handle_packet(quic,
-//                             ctx,
-//                             wire_buf_data(ctx->payload.wire_buf),
-//                             wire_buf_data_length(ctx->payload.wire_buf),
-//                             target, &dec_cids, &qconn, &action);
-//             /* not all fails should be quiet, some require a response from
-//              * our side (kr_quic_send with given action) TODO! */
-//             if (ret != kr_ok()) {
-//                     goto fail;
-//             }
-//             if (action == KR_QUIC_HANDLE_RET_CLOSE) {
-//                     ret = kr_ok();
-//                     goto fail;
-//             }
-//
-//             if (qconn->stream_inprocess == -1) {
-//                     kr_quic_send(quic->conn_table, qconn, ctx, action,
-//                                     &dec_cids, QUIC_MAX_SEND_PER_RECV, 0);
-//                     ret = kr_ok();
-//                     goto fail;
-//             }
-//
-//             if (kr_fails_assert(queue_len(quic->unwrap_queue) == 1)) {
-//                     ret = kr_error(EINVAL);
-//                     goto fail;
-//             }
-//
-//             /* WARNING: this has been moved */
-//             // struct protolayer_iter_ctx *ctx_head = queue_head(quic->unwrap_queue);
-//             // if (!kr_fails_assert(ctx == ctx_head)) {
-//             //      protolayer_break(ctx, kr_error(EINVAL));
-//             //      ctx = ctx_head;
-//             // }
-//     }
-//
-//     struct protolayer_iter_ctx *ctx_head = queue_head(quic->unwrap_queue);
-//     if (!kr_fails_assert(ctx == ctx_head))
-//             queue_pop(quic->unwrap_queue);
-//
-//     while (qconn->streams_pending) {
-//             if ((ret = get_query(ctx, qconn, target)) <= 0)
-//                     goto fail;
-//
-//             ctx->payload = protolayer_payload_wire_buf(&qconn->unwrap_buf,
-//                             false);
-//
-//             if (qconn->streams_pending == 0) {
-//                     return protolayer_continue(ctx);
-//             }
-//
-//             /* FIXME should we ignore the result? */
-//             session2_unwrap_after(ctx->session,
-//                             PROTOLAYER_TYPE_QUIC,
-//                             ctx->payload,
-//                             ctx->comm,
-//                             ctx->finished_cb,
-//                             ctx->finished_cb_baton);
-//     }
-//
-//     // if ((ret = collect_queries(ctx, qconn, target)) > 0) {
-//     //      ctx->payload = protolayer_payload_wire_buf(&qconn->unwrap_buf,
-//     //                      false);
-//     //      return protolayer_continue(ctx);
-//     // }
-//
-//     free(target);
-//     return protolayer_break(ctx, ret);
-//
-// fail:
-//     ctx_head = queue_head(quic->unwrap_queue);
-//     if (!kr_fails_assert(ctx == ctx_head))
-//             queue_pop(quic->unwrap_queue);
-//
-//     free(target);
-//     return protolayer_break(ctx, ret);
-// }
-//
-// /* TODO perhaps also move to quic_stream */
-// static int send_stream(struct protolayer_iter_ctx *ctx,
-//             // struct protolayer_payload *outwb,
-//             kr_quic_conn_t *qconn, int64_t stream_id,
-//             uint8_t *data, size_t len, bool fin, ngtcp2_ssize *sent)
-// {
-//     /* require empty wire_buf TODO maybe remove*/
-//     kr_require(wire_buf_data_length(ctx->payload.wire_buf) == 0);
-//
-//     assert(stream_id >= 0 || (data == NULL && len == 0));
-//
-//     while (stream_id >= 0 && !kr_quic_stream_exists(qconn, stream_id)) {
-//             int64_t opened = 0;
-//             kr_log_info(DOQ, "Openning bidirectional stream no: %zu\n",
-//                             stream_id);
-//
-//             int ret = ngtcp2_conn_open_bidi_stream(qconn->conn,
-//                             &opened, NULL);
-//             if (ret != kr_ok()) {
-//                     kr_log_warning(DOQ, "remote endpoint isn't ready for streams: %s (%d)\n",
-//                                     ngtcp2_strerror(ret), ret);
-//                     return ret;
-//             }
-//             kr_require((bool)(opened == stream_id) == kr_quic_stream_exists(qconn, stream_id));
-//     }
-//
-//     uint32_t fl = ((stream_id >= 0 && fin) ? NGTCP2_WRITE_STREAM_FLAG_FIN
-//                                            : NGTCP2_WRITE_STREAM_FLAG_NONE);
-//
-//     ngtcp2_vec vec = { .base = data, .len = len };
-//     ngtcp2_pkt_info pi = { 0 };
-//
-//     const ngtcp2_path *path = ngtcp2_conn_get_path(qconn->conn);
-//
-//     ngtcp2_conn_info info = { 0 };
-//     ngtcp2_conn_get_conn_info(qconn->conn, &info);
-//     int nwrite = ngtcp2_conn_writev_stream(qconn->conn, path, &pi,
-//                     wire_buf_free_space(ctx->payload.wire_buf),
-//                     wire_buf_free_space_length(ctx->payload.wire_buf),
-//                     sent, fl, stream_id, &vec,
-//                     (stream_id >= 0 ? 1 : 0), quic_timestamp());
-//
-//     /* TODO:
-//      * This packet may contain frames other than STREAM frame. The
-//      * packet might not contain STREAM frame if other frames
-//      * occupy the packet. In that case, *pdatalen would
-//      * be -1 if pdatalen is not NULL. */
-//     // TODO: abstract error printing, likely shared across many ngtcp2_ calls
-//     if (nwrite < 0) {
-//             kr_log_error(DOQ, "writev_stream to %zu failed %s (%d)\n",
-//                             stream_id, ngtcp2_strerror(nwrite), nwrite);
-//             if (len)
-//                     return nwrite;
-//
-//             goto exit;
-//     } else if (*sent >= 0) {
-//             /* TODO this data has to be kept untill acked */
-//             vec.len -= *sent;
-//     }
-//
-//     if (wire_buf_consume(ctx->payload.wire_buf, nwrite) != kr_ok()) {
-//             kr_log_error(DOQ, "Wire_buf failed to consume: %s (%d)\n",
-//                             ngtcp2_strerror(nwrite), nwrite);
-//             goto exit;
-//     }
-//
-//     /* called from wrap, proceed to the next layer */
-//     if (len) {
-//             return protolayer_continue(ctx);
-//     }
-//
-//     /* called from unwrap, respond with QUIC communication data */
-//     if (nwrite || *sent)  {
-//             int wrap_ret = session2_wrap_after(ctx->session,
-//                             PROTOLAYER_TYPE_QUIC, ctx->payload, ctx->comm,
-//                             ctx->finished_cb, ctx->finished_cb_baton);
-//
-//             if (wrap_ret < 0) {
-//                     nwrite = wrap_ret;
-//             }
-//
-//     } else {
-//             // TODO?
-//     }
-//
-// exit:
-//     // wire_buf_deinit(wb);
-//     // mm_free(&ctx->pool, wb);
-//
-//     return len != 0 ? protolayer_break(ctx, nwrite) : nwrite;
-// }
-//
-// /* Function for sending speciall packets, requires
-//  * a message (which special data are we to send: CONN_CLOSE, RESET, ...)
-//  * and a buffer to store the pkt in, for now ctx->payloay.wb
-//  * For now only kr_quic_send ever call send_special, though this might proove
-//  * to cause issues in situation where the connection has NOT been established
-//  * and we still would like to send data (i.e. we do not have decoded cids)
-//  * The only time we need to send_special without having at least the cids
-//  * is then the decode_v_cid fails with NGTCP2_ERR_VERSION_NEGOTIATION */
-// static int send_special(struct protolayer_iter_ctx *ctx,
-//             kr_quic_table_t *quic_table, int action,
-//             ngtcp2_version_cid *decoded_cids,
-//             struct kr_quic_conn *conn)
-//             // kr_quic_conn_t *relay /* only for connection close */)
-// {
-//     if (wire_buf_data_length(ctx->payload.wire_buf) != 0) {
-//             kr_log_error(DOQ, "wire_buf in quic/send_special is expected to be empty\n");
-//             return kr_error(EINVAL);
-//     }
-//
-//     uint64_t now = quic_timestamp();
-//     int dvc_ret = NGTCP2_ERR_FATAL;
-//
-//     // if ((message == -QUIC_SEND_VERSION_NEGOTIATION
-//     //              || message == -QUIC_SEND_RETRY)
-//     //              && rpl->in_payload != NULL && rpl->in_payload->iov_len > 0) {
-//     //      dvc_ret = ngtcp2_pkt_decode_version_cid(
-//     //              &decoded_cids, rpl->in_payload->iov_base,
-//     //              rpl->in_payload->iov_len, SERVER_DEFAULT_SCIDLEN);
-//     // }
-//
-//     uint8_t rnd = 0;
-//     dnssec_random_buffer(&rnd, sizeof(rnd));
-//     uint32_t supported_quic[1] = { NGTCP2_PROTO_VER_V1 };
-//     ngtcp2_cid new_dcid;
-//     uint8_t retry_token[NGTCP2_CRYPTO_MAX_RETRY_TOKENLEN];
-//     uint8_t stateless_reset_token[NGTCP2_STATELESS_RESET_TOKENLEN];
-//     uint8_t sreset_rand[NGTCP2_MIN_STATELESS_RESET_RANDLEN];
-//     dnssec_random_buffer(sreset_rand, sizeof(sreset_rand));
-//     ngtcp2_ccerr ccerr;
-//     ngtcp2_ccerr_default(&ccerr);
-//     ngtcp2_pkt_info pi = { 0 };
-//
-//     // struct sockaddr_storage path_loc = { 0 }, path_rem = { 0 };
-//     // ngtcp2_path path = { .local  = { .addr = (struct sockaddr *)&path_loc, .addrlen = sizeof(path_loc) },
-//     //                      .remote = { .addr = (struct sockaddr *)&path_rem, .addrlen = sizeof(path_rem) },
-//     //                      .user_data = NULL };
-//     // ??
-//     // bool find_path = (rpl->ip_rem == NULL);
-//     // ??
-//     // assert(find_path == (bool)(rpl->ip_loc == NULL));
-//     // ??
-//     // assert(!find_path || rpl->handle_ret == -QUIC_SEND_EXCESSIVE_LOAD);
-//
-//     int ret = 0;
-//     switch (action) {
-//     case -QUIC_SEND_VERSION_NEGOTIATION:
-//             ret = ngtcp2_pkt_write_version_negotiation(
-//                     wire_buf_free_space(ctx->payload.wire_buf),
-//                     wire_buf_free_space_length(ctx->payload.wire_buf),
-//                     rnd, decoded_cids->scid, decoded_cids->scidlen,
-//                     decoded_cids->dcid, decoded_cids->dcidlen, supported_quic,
-//                     sizeof(supported_quic) / sizeof(*supported_quic)
-//             );
-//             break;
-//             
-//     /* Returned by ngtcp2_conn_read_pkt
-//      * Server must perform address validation by sending Retry packet
-//      * (see `ngtcp2_crypto_write_retry` and `ngtcp2_pkt_write_retry`),
-//      * and discard the connection state.  Client application does not
-//      * get this error code. */
-//     case -QUIC_SEND_RETRY:
-//             // ngtcp2_cid_init(&dcid, decoded_cids->dcid, decoded_cids->dcidlen);
-//             // ngtcp2_cid_init(&scid, decoded_cids->scid, decoded_cids->scidlen);
-//             if (!conn || !ctx->comm || ! ctx->comm->target) {
-//                     kr_log_error(DOQ, "unable to send Retry packet due to missing data\n");
-//                     // return kr_error(EINVAL);
-//                     break;
-//             }
-//
-//             kr_require(conn && ctx->comm->target);
-//             ngtcp2_addr remote = ngtcp2_conn_get_path(conn->conn)->remote;
-//             struct quic_target *target = ctx->comm->target;
-//             init_random_cid(&new_dcid, 0);
-//
-//             ret = ngtcp2_crypto_generate_retry_token(
-//                     retry_token, (const uint8_t *)quic_table->hash_secret,
-//                     sizeof(quic_table->hash_secret), decoded_cids->version,
-//                     (const struct sockaddr *)remote.addr, remote.addrlen,
-//                     &new_dcid, &target->dcid, now
-//             );
-//
-//             if (ret >= 0) {
-//                     ret = ngtcp2_crypto_write_retry(
-//                             wire_buf_free_space(ctx->payload.wire_buf),
-//                             wire_buf_free_space_length(ctx->payload.wire_buf),
-//                             decoded_cids->version, &target->scid,
-//                             &new_dcid, &target->dcid,
-//                             retry_token, ret
-//                     );
-//                     if (ret == -1) {
-//                             // TODO
-//                     }
-//             } else {
-//                     kr_log_error(DOQ, "failed to generate Retry token\n");
-//                     // return kr_error(ret);
-//             }
-//             break;
-//     case -QUIC_SEND_STATELESS_RESET:
-//             ret = ngtcp2_pkt_write_stateless_reset(
-//                     wire_buf_free_space(ctx->payload.wire_buf),
-//                     wire_buf_free_space_length(ctx->payload.wire_buf),
-//                     stateless_reset_token, sreset_rand, sizeof(sreset_rand)
-//             );
-//             break;
-//     case -QUIC_SEND_CONN_CLOSE:
-//             ret = ngtcp2_conn_write_connection_close(
-//                     conn->conn, NULL, &pi,
-//                     wire_buf_free_space(ctx->payload.wire_buf),
-//                     wire_buf_free_space_length(ctx->payload.wire_buf),
-//                     &ccerr, now
-//             );
-//             break;
-//     case -QUIC_SEND_EXCESSIVE_LOAD:
-//             ccerr.type = NGTCP2_CCERR_TYPE_APPLICATION;
-//             ccerr.error_code = KR_QUIC_ERR_EXCESSIVE_LOAD;
-//             ret = ngtcp2_conn_write_connection_close(
-//                     conn->conn,
-//                     /* can this contain nonsence data? */
-//                     ngtcp2_conn_get_path(conn->conn),
-//                     &pi,
-//                     wire_buf_free_space(ctx->payload.wire_buf),
-//                     wire_buf_free_space_length(ctx->payload.wire_buf),
-//                     &ccerr, now
-//             );
-//             break;
-//     default:
-//             ret = kr_error(EINVAL);
-//             break;
-//     }
-//
-//     if (ret < 0) {
-//             wire_buf_reset(ctx->payload.wire_buf);
-//     } else {
-//             if (wire_buf_consume(ctx->payload.wire_buf, ret) == kr_ok()) {
-//                     int wrap_ret = session2_wrap_after(ctx->session,
-//                                     PROTOLAYER_TYPE_QUIC, ctx->payload, ctx->comm,
-//                                     ctx->finished_cb, ctx->finished_cb_baton);
-//                     if (wrap_ret < 0) {
-//                             ret = wrap_ret;
-//                     }
-//
-//             } else {
-//                     kr_log_error(DOQ, "Wire_buf failed to consume: %s (%d)\n",
-//                                     ngtcp2_strerror(ret), ret);
-//                     // goto exit;
-//             }
-//     }
-//
-//     return ret;
-// }
-//
-// int kr_quic_send(kr_quic_table_t *quic_table /* FIXME maybe unused */,
-//             struct kr_quic_conn *conn,
-//             // void *sess_data,
-//             struct protolayer_iter_ctx *ctx,
-//             int action,
-//             ngtcp2_version_cid *decoded_cids,
-//             unsigned max_msgs,
-//             kr_quic_send_flag_t flags)
-// {
-//     if (quic_table == NULL || conn == NULL /* || reply == NULL */) {
-//             return kr_error(EINVAL);
-//     } else if ((conn->flags & KR_QUIC_CONN_BLOCKED) && !(flags & KR_QUIC_SEND_IGNORE_BLOCKED)) {
-//             return kr_error(EINVAL);
-//     } else if (action != 0) {
-//             return send_special(ctx, quic_table, action, decoded_cids, conn);
-//     } else if (conn == NULL) {
-//             return kr_error(EINVAL);
-//     } else if (conn->conn == NULL) {
-//             return kr_ok();
-//     }
-//
-//     if (!(conn->flags & KR_QUIC_CONN_HANDSHAKE_DONE)) {
-//             max_msgs = 1;
-//     }
-//
-//     unsigned sent_msgs = 0, stream_msgs = 0, ignore_last = ((flags & KR_QUIC_SEND_IGNORE_LASTBYTE) ? 1 : 0);
-//     int ret = 1;
-//
-//     for (int64_t si = 0; si < conn->streams_count && sent_msgs < max_msgs; /* NO INCREMENT */) {
-//             int64_t stream_id = 4 * (conn->first_stream_id + si);
-//
-//             ngtcp2_ssize sent = 0;
-//             size_t uf = conn->streams[si].unsent_offset;
-//             kr_quic_obuf_t *uo = conn->streams[si].unsent_obuf;
-//             if (uo == NULL) {
-//                     si++;
-//                     continue;
-//             }
-//
-//             bool fin = (((node_t *)uo->node.next)->next == NULL) && ignore_last == 0;
-//
-//             kr_log_info(DOQ, "About to SEND_STREAM fin: %d stream_id: %zu fsi: %zu streams_count: %d\n",
-//                        fin, stream_id, conn->first_stream_id, conn->streams_count);
-//
-//             ret = send_stream(ctx, conn, stream_id, uo->buf + uf,
-//                               uo->len - uf - ignore_last, fin, &sent);
-//
-//             /* FIXME: just an attempted hotfix
-//              * ok this actually worked, but it shadows an underlying issue
-//              * and leaks more than a decapitated elephant */
-//             if (ret == NGTCP2_ERR_STREAM_SHUT_WR) {
-//                     // kr_quic_stream_mark_sent(conn, stream_id, sent);
-//                     si++;
-//                     continue;
-//             }
-//
-//             if (ret < 0 || ret == PROTOLAYER_ITER_CB_RESULT_MAGIC) {
-//                     return ret;
-//             }
-//
-//             sent_msgs++;
-//             stream_msgs++;
-//             if (sent > 0 && ignore_last > 0) {
-//                     sent++;
-//             }
-//             if (sent > 0) {
-//                     kr_quic_stream_mark_sent(conn, stream_id, sent);
-//             }
-//
-//             if (stream_msgs >= max_msgs / conn->streams_count) {
-//                     stream_msgs = 0;
-//                     si++; // if this stream is sending too much, give chance to other streams
-//             }
-//     }
-//
-//     while (ret == 1) {
-//             ngtcp2_ssize unused = 0;
-//             ret = send_stream(ctx, conn, -1, NULL, 0, false, &unused);
-//     }
-//
-//     // Might not be the correct place to call this
-//     ngtcp2_conn_update_pkt_tx_time(conn->conn, quic_timestamp());
-//     return sent_msgs;
-// }
-//
-// /* For now we assume any iovec payload we get
-//  * will just be a single (the second iovec, first one holds size)
-//  * giant buffer. FIXME if proper iovec support ever comes. */
-// static enum protolayer_iter_cb_result pl_quic_wrap(
-//             void *sess_data, void *iter_data,
-//             struct protolayer_iter_ctx *ctx)
-// {
-//     int ret;
-//     pl_quic_sess_data_t *quic = sess_data;
-//     queue_push(quic->wrap_queue, ctx);
-//     struct quic_target *target = ctx->comm_storage.target;
-//     ngtcp2_cid *dcid = &target->dcid;
-//     uint64_t stream_id = target->stream_id;
-//
-//     kr_log_info(DOQ, "Quic wrap prototype: %s\n",
-//                     protolayer_payload_name(ctx->payload.type));
-//
-//     while (protolayer_queue_has_payload(&quic->wrap_queue)) {
-//             struct protolayer_iter_ctx *data = queue_head(quic->wrap_queue);
-//
-//             queue_pop(quic->wrap_queue);
-//             if (!data || !data->comm || !data->comm->target) {
-//                     kr_log_error(DOQ, "missing required transport information in wrap direction\n");
-//                     kr_require(false);
-//                     return protolayer_break(ctx, kr_error(EINVAL));
-//             }
-//
-//             kr_quic_conn_t *conn = kr_quic_table_lookup(dcid, quic->conn_table);
-//             if (!conn) {
-//                     kr_log_warning(DOQ, "Missing associated connection\n");
-//                     /* There is nothing we can do */
-//                     return protolayer_break(ctx, EINVAL /* TODO */);
-//             }
-//
-//             // TODO remove
-//             knot_pkt_t *ans = kr_request_ensure_answer(ctx->req);
-//             kr_require(ans != NULL);
-//
-//             kr_require(data->payload.type == PROTOLAYER_PAYLOAD_IOVEC);
-//             kr_quic_stream_add_data(conn, stream_id,
-//                             &data->payload);
-//
-//             struct wire_buf *wb = mm_alloc(&ctx->pool, sizeof(*wb));
-//             char *buf = mm_alloc(&ctx->pool, 1200 /* FIXME this makes no sence */);
-//             kr_require(buf);
-//             *wb = (struct wire_buf){
-//                     .buf = buf,
-//                     .size = 1200 /* FIXME this makes no sence */
-//             };
-//
-//             data->payload = protolayer_payload_wire_buf(wb, false);
-//             ret = kr_quic_send(quic->conn_table,
-//                             conn,
-//                             data,
-//                             0,
-//                             NULL,
-//                             QUIC_MAX_SEND_PER_RECV,
-//                             0 /* no flags */);
-//             if (ret <= 0)
-//                     break;
-//
-//             // if (ret == PROTOLAYER_ITER_CB_RESULT_MAGIC) {
-//             //      free(ctx->comm_storage.target);
-//             // }
-//     }
-//
-//     // FIXME: certainly not here, this leaks as is
-//     // free(ctx->comm_storage.target);
-//     // free(ctx->comm_storage.target);
-//     return ret;
-//
-//     // return protolayer_continue(ctx);
-//     // return protolayer_break(ctx, kr_ok());
-// }
-//
-// static enum protolayer_event_cb_result pl_quic_event_unwrap(
-//             enum protolayer_event_type event, void **baton,
-//             struct session2 *session, void *sess_data)
-// {
-//     kr_log_warning(DOQ, "IN event_unwrap\n");
-//     return PROTOLAYER_EVENT_PROPAGATE;
-// }
-//
-// static enum protolayer_event_cb_result pl_quic_event_wrap(
-//             enum protolayer_event_type event, void **baton,
-//             struct session2 *session, void *sess_data)
-// {
-//     kr_log_warning(DOQ, "IN event_wrap\n");
-//     return PROTOLAYER_EVENT_PROPAGATE;
-// }
-//
-// static void pl_quic_request_init(struct session2 *session,
-//             struct kr_request *req,
-//             void *sess_data)
-// {
-//     kr_log_warning(DOQ, "IN request init\n");
-//     req->qsource.comm_flags.quic = true;
-//     // struct pl_quic_sess_data *quic = sess_data;
-//     // quic->req = req;
-//
-//     // req->qsource.stream_id = session->comm_storage.target;
-// }
-//
-// __attribute__((constructor))
-// static void quic_protolayers_init(void)
-// {
-//     protolayer_globals[PROTOLAYER_TYPE_QUIC] = (struct protolayer_globals) {
-//             .sess_size = sizeof(struct pl_quic_sess_data),
-//             // .iter_size = sizeof(struct ),
-//             .wire_buf_overhead = MAX_QUIC_FRAME_SIZE,
-//             // .iter_init = pl_quic_iter_init,
-//             // .iter_deinit = pl_quic_iter_deinit,
-//             .sess_init = pl_quic_sess_init,
-//             .sess_deinit = pl_quic_sess_deinit,
-//             .unwrap = pl_quic_unwrap,
-//             .wrap = pl_quic_wrap,
-//             .event_unwrap = pl_quic_event_unwrap,
-//             .event_wrap = pl_quic_event_wrap,
-//             .request_init = pl_quic_request_init,
-//     };
-// }
diff --git a/daemon/quic.h b/daemon/quic.h
deleted file mode 100644 (file)
index 64871e7..0000000
+++ /dev/null
@@ -1,279 +0,0 @@
-/*  Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
- *  SPDX-License-Identifier: GPL-3.0-or-later
- */
-
-#pragma once
-
-#include <bits/types/struct_iovec.h>
-#include <stdbool.h>
-#include <ngtcp2/ngtcp2.h>
-#include <ngtcp2/ngtcp2_crypto.h>
-#include <ngtcp2/ngtcp2_crypto_gnutls.h>
-// #include "daemon/tls.h"
-
-#include <gnutls/x509.h>
-#include <gnutls/gnutls.h>
-#include <gnutls/crypto.h>
-#include "lib/generic/queue.h"
-#include "lib/log.h"
-#include "session2.h"
-#include "network.h"
-#include "lib/resolve.h"
-// #include "libknot/quic/quic.h"
-#include "libdnssec/random.h"
-#include <stdint.h>
-#include <contrib/ucw/heap.h>
-#include <contrib/ucw/lists.h>
-#include "contrib/openbsd/siphash.h"
-#include "lib/utils.h"
-#include "libdnssec/error.h"
-
-#include <stddef.h>
-#include <netinet/in.h>
-
-#include <worker.h>
-
-// those are equivalent to contrib/ucw/lists.h  just must not be included.
-// typedef struct kr_quic_ucw_node {
-//     struct kr_quic_ucw_node *next, *prev;
-// } kr_quic_ucw_node_t;
-// typedef struct kr_quic_ucw_list {
-//     kr_quic_ucw_node_t head, tail;
-// } kr_quic_ucw_list_t;
-
-
-#define MAX_QUIC_FRAME_SIZE 65536
-
-typedef enum {
-       CLOSED,    // Initialized
-       CONNECTED, // RTT-0
-       VERIFIED,  // RTT-1
-} quic_state_t;
-
-typedef queue_t(struct kr_quic_obuf *) quic_out_q;
-
-/** RFC 9250 4.3.  DoQ Error Codes */
-typedef enum {
-       /*! No error.  This is used when the connection or stream needs to be
-           closed, but there is no error to signal. */
-       DOQ_NO_ERROR = 0x0,
-       /*! The DoQ implementation encountered an internal error and is
-           incapable of pursuing the transaction or the connection. */
-       DOQ_INTERNAL_ERROR = 0x1,
-       /*! The DoQ implementation encountered a protocol error and is forcibly
-           aborting the connection. */
-       DOQ_PROTOCOL_ERROR = 0x2,
-       /*! A DoQ client uses this to signal that it wants to cancel an
-           outstanding transaction. */
-       DOQ_REQUEST_CANCELLED = 0x3,
-       /*! A DoQ implementation uses this to signal when closing a connection
-           due to excessive load. */
-       DOQ_EXCESSIVE_LOAD = 0x4,
-       /*!  A DoQ implementation uses this in the absence of a more specific
-            error code. */
-       DOQ_UNSPECIFIED_ERROR = 0x5,
-       /*! Alternative error code used for tests. */
-       DOQ_ERROR_RESERVED = 0xd098ea5e
-} quic_doq_error_t;
-
-
-/** QUIC parameters. */
-typedef struct {
-       /*! Use QUIC indicator. */
-       bool enable;
-} quic_params_t;
-
-#define SERVER_DEFAULT_SCIDLEN 18
-#define ENABLE_QUIC
-
-#define KR_QUIC_HANDLE_RET_CLOSE       2000
-#define KR_QUIC_ERR_EXCESSIVE_LOAD     0x4
-
-// Macros from knot quic impl
-#define SERVER_DEFAULT_SCIDLEN 18
-#define QUIC_REGULAR_TOKEN_TIMEOUT (24 * 3600 * 1000000000LLU)
-#define QUIC_SEND_VERSION_NEGOTIATION    NGTCP2_ERR_VERSION_NEGOTIATION
-#define QUIC_SEND_RETRY                  NGTCP2_ERR_RETRY
-#define QUIC_SEND_STATELESS_RESET        (-NGTCP2_STATELESS_RESET_TOKENLEN)
-#define QUIC_SEND_CONN_CLOSE             (-KR_QUIC_HANDLE_RET_CLOSE)
-#define QUIC_SEND_EXCESSIVE_LOAD         (-KR_QUIC_ERR_EXCESSIVE_LOAD)
-// this limits the number of un-finished streams per conn
-// i.e. if response has been recvd with FIN, it doesn't count
-#define MAX_STREAMS_PER_CONN 10
-
-typedef enum {
-       KR_QUIC_SEND_IGNORE_LASTBYTE = (1 << 0),
-       KR_QUIC_SEND_IGNORE_BLOCKED  = (1 << 1),
-} kr_quic_send_flag_t;
-
-// TODO maybe rename to something more in line with iter_data
-struct pl_quic_state {
-       struct protolayer_data h;
-       struct kr_quic_conn *qconn;
-       /* struct ortt_ NOTE: Or some other data */ ;
-};
-
-/* here the dcid and per query stream_id
- * gets stored in quic_unwrap and read in quic_wrap */
-struct quic_target {
-       ngtcp2_cid dcid;
-       ngtcp2_cid scid; // maybe redundant
-       uint64_t stream_id;
-};
-
-struct kr_quic_conn;
-typedef struct kr_quic_cid {
-       uint8_t cid_placeholder[32];
-       struct kr_quic_conn *conn;
-       struct kr_quic_cid *next;
-} kr_quic_cid_t;
-
-typedef enum {
-       KNOT_QUIC_TABLE_CLIENT_ONLY = (1 << 0),
-} kr_quic_table_flag_t;
-
-typedef struct {
-       void *get_conn;
-       void *user_data;
-} nc_conn_ref_placeholder_t;
-
-typedef struct kr_quic_table {
-       kr_quic_table_flag_t flags;
-       /* general "settings" for connections */
-       size_t size;
-       size_t usage;
-       size_t pointers;
-       size_t max_conns;
-       size_t ibufs_max;
-       size_t obufs_max;
-       size_t ibufs_size;
-       size_t obufs_size;
-       size_t udp_payload_limit;
-       void (*log_cb)(const char *);
-       const char *qlog_dir;
-       uint64_t hash_secret[4];
-       struct tls_credentials *creds;
-       struct gnutls_priority_st *priority;
-       struct heap *expiry_heap;
-       kr_quic_cid_t *conns[];
-} kr_quic_table_t;
-
-typedef struct kr_quic_obuf {
-       // struct kr_quic_ucw_list *node;
-       struct node node;
-       size_t len;
-       // struct wire_buf buf;?
-       uint8_t buf[];
-} kr_quic_obuf_t;
-
-typedef enum {
-       KR_QUIC_CONN_HANDSHAKE_DONE = (1 << 0),
-       KR_QUIC_CONN_SESSION_TAKEN  = (1 << 1),
-       KR_QUIC_CONN_BLOCKED        = (1 << 2),
-       KR_QUIC_CONN_AUTHORIZED     = (1 << 3),
-} kr_quic_conn_flag_t;
-
-typedef struct kr_tcp_inbufs_upd_res {
-       size_t n_inbufs;
-       struct kr_tcp_inbufs_upd_res *next;
-       struct iovec inbufs[];
-} kr_tcp_inbufs_udp_res_t;
-
-struct kr_quic_stream {
-       // struct iovec inbuf;
-       struct wire_buf pers_inbuf;
-       // struct kr_tcp_inbufs_upd_res *inbufs;
-
-       size_t firstib_consumed;
-       /* stores data that has been sent out and awaits acknowledgement and
-        * data that has just been created and is waiting to be sent out */
-       /* ucw */struct list outbufs;
-
-       // /* ucw */struct kr_quic_ucw_list outbufs;
-       // /*ucw_*/queue_t(struct kr_quic_obuf) outbufs;
-       // /*ucw_*/list_t outbufs;
-
-       /* FIXME Properly implement everywhere
-        * kr_quic_stream_ack_data uses this to check the
-        * stream is really finished, without proper handling
-        * no stream will ever be deleted */
-       /* size of all outbufs */
-       size_t obufs_size;
-
-       /* pointer to somewhere in outbufs */
-       struct kr_quic_obuf *unsent_obuf;
-       /* offset of the first unacked data in the entire stream
-        * (not just current unsent_obuf) */
-       size_t first_offset;
-       /* number of sent out bytes in the current unsent_obuf
-        * if we send >= to the unsent_obuf size the list attemps
-        * to advance to the next unsent_obuf and this value is reset to 0 */
-       size_t unsent_offset;
-};
-
-typedef struct kr_quic_conn {
-       int heap_node_placeholder; // MUST be first field of the struct
-       uint64_t next_expiry;
-
-       // placeholder for internal struct ngtcp2_crypto_conn_ref
-       nc_conn_ref_placeholder_t conn_ref;
-
-       // conn_table next conn link
-       struct ngtcp2_conn *conn;
-       struct kr_quic_conn *next;
-
-       gnutls_session_t tls_session;
-
-       // crypto callbacks
-       ngtcp2_crypto_conn_ref crypto_ref;
-
-       // QUIC stream abstraction
-       // TODO sentinel for streams?
-       struct kr_quic_stream *streams;
-       // number of allocated streams structures
-       int16_t streams_count;
-       // index of first stream that has complete incomming data to be processed (aka inbuf_fin)
-       int16_t stream_inprocess;
-       // stream_id/4 of first allocated stream
-       int64_t first_stream_id;
-       // count of streams with finished queries pending a resolution
-       uint16_t streams_pending;
-
-       ngtcp2_ccerr last_error;
-       kr_quic_conn_flag_t flags;
-       int qlog_fd;
-
-       // TODO: consider removing
-       size_t ibufs_size;
-       size_t obufs_size;
-
-       // // TODO: Definitelly move
-       // ngtcp2_pkt_info pi;
-       // ngtcp2_cid *dcid;
-       // ngtcp2_cid *scid;
-
-       // back-pointer
-       // FIXME: could this be removed?
-       struct kr_quic_table *quic_table;
-
-       struct wire_buf unwrap_buf;
-
-} kr_quic_conn_t;
-
-typedef struct pl_quic_sess_data {
-       struct protolayer_data h;
-       quic_params_t params;
-       ngtcp2_settings settings;
-
-       uint32_t conn_count;
-       protolayer_iter_ctx_queue_t unwrap_queue;
-       protolayer_iter_ctx_queue_t wrap_queue;
-       // protolayer_iter_ctx_queue_t resend_queue;
-       struct wire_buf outbuf;
-
-       kr_quic_table_t *conn_table;
-       uint64_t first_stream_id;
-
-       struct kr_request *req;
-       // quic_state_t state;
-} pl_quic_sess_data_t;