]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
daemon/quic: minor optimizations, remove pointless asserts, discard conn state when...
authorFrantisek Tobias <frantisek.tobias@nic.cz>
Wed, 26 Nov 2025 11:39:26 +0000 (12:39 +0100)
committerFrantisek Tobias <frantisek.tobias@nic.cz>
Wed, 7 Jan 2026 13:39:14 +0000 (14:39 +0100)
daemon/quic_common.h
daemon/quic_conn.c
daemon/quic_conn.h
daemon/quic_demux.c
daemon/quic_stream.c

index 3e84101259970c865d715ad40cffd53abb64f4b5..a1b9821ce20d302ba0f3905f22ca6f6418b407e6 100644 (file)
@@ -44,7 +44,7 @@ typedef enum {
 #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_CONN_CLOSE             (-2000)
 #define QUIC_SEND_EXCESSIVE_LOAD         (-KR_QUIC_ERR_EXCESSIVE_LOAD)
 #define BUCKETS_PER_CONNS 8
 
index 1de244f1f1829b90ca97cd8f8268f57c9a446916..9fdf83060ab30aec893eb57585d1238b91a93401 100644 (file)
@@ -3,20 +3,11 @@
  */
 
 #include "quic_conn.h"
-#include "engine.h"
-#include "lib/generic/trie.h"
-#include "lib/log.h"
-#include "lib/resolve.h"
-#include "network.h"
 #include "quic_stream.h"
 #include "quic_common.h"
 #include "libdnssec/random.h"
 #include "libdnssec/error.h"
-#include "session2.h"
 #include "worker.h"
-#include <libknot/wire.h>
-#include <ngtcp2/ngtcp2.h>
-#include <uv.h>
 
 #define EPHEMERAL_CERT_EXPIRATION_SECONDS_RENEW_BEFORE ((time_t)60*60*24*7)
 
@@ -34,16 +25,15 @@ static int handle_packet(struct pl_quic_conn_sess_data *conn,
                struct protolayer_iter_ctx *ctx)
 {
        uint64_t now = quic_timestamp();
-       const ngtcp2_path *path = ngtcp2_conn_get_path(conn->conn);
        ngtcp2_pkt_info pi = { .ecn = NGTCP2_ECN_NOT_ECT, };
 
        int ret = -1;
        if (ctx->payload.type == PROTOLAYER_PAYLOAD_WIRE_BUF) {
-               ret = ngtcp2_conn_read_pkt(conn->conn, path, &pi,
+               ret = ngtcp2_conn_read_pkt(conn->conn, conn->path, &pi,
                                wire_buf_data(ctx->payload.wire_buf),
                                wire_buf_data_length(ctx->payload.wire_buf), now);
        } else {
-               ret = ngtcp2_conn_read_pkt(conn->conn, path, &pi,
+               ret = ngtcp2_conn_read_pkt(conn->conn, conn->path, &pi,
                                ctx->payload.buffer.buf,
                                ctx->payload.buffer.len, now);
        }
@@ -56,6 +46,11 @@ static int handle_packet(struct pl_quic_conn_sess_data *conn,
 
        switch (ret) {
        case NGTCP2_ERR_RETRY:
+               /* "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." */
+               QUIC_SET_CLOSING(conn);
                return QUIC_SEND_RETRY;
        case NGTCP2_ERR_DROP_CONN:
                QUIC_SET_DRAINING(conn);
@@ -65,7 +60,7 @@ static int handle_packet(struct pl_quic_conn_sess_data *conn,
                break;
        case NGTCP2_ERR_CLOSING:
                /* Since we received the CLOSING, we are not allowed to
-                * send last packet, therefore DRAINING */
+                * send last packet -> elevate to DRAINING */
                QUIC_SET_DRAINING(conn);
                break;
        case NGTCP2_ERR_CRYPTO:
@@ -118,7 +113,6 @@ static int kr_recv_stream_data_cb(ngtcp2_conn *ngconn, uint32_t flags,
        if (datalen == 0) {
                /* This is invalid see ngtcp2_recv_stream_data doc */
                if (!(flags & NGTCP2_STREAM_DATA_FLAG_FIN)) {
-                       // return NGTCP2_PROTOCOL_VIOLATION;
                        return NGTCP2_ERR_CALLBACK_FAILURE;
                }
 
@@ -130,17 +124,15 @@ static int kr_recv_stream_data_cb(ngtcp2_conn *ngconn, uint32_t flags,
 
        if (offset == 0) {
                memcpy(wire_buf_free_space(&stream->pers_inbuf), data, datalen);
-               kr_require(wire_buf_consume(&stream->pers_inbuf, datalen) == kr_ok());
+               wire_buf_consume(&stream->pers_inbuf, datalen);
        } else {
                /* remove size header from new data and add it to the start of wb. */
                memcpy(wire_buf_free_space(&stream->pers_inbuf), data + sizeof(uint16_t), datalen - sizeof(uint16_t));
                knot_wire_write_u16(wire_buf_data(&stream->pers_inbuf),
                                knot_wire_read_u16(wire_buf_data(&stream->pers_inbuf)) + datalen - sizeof(uint16_t));
-               kr_require(wire_buf_consume(&stream->pers_inbuf, datalen - sizeof(uint16_t)) == kr_ok());
+               wire_buf_consume(&stream->pers_inbuf, datalen - sizeof(uint16_t));
        }
 
-       /* we can ignore ret return value, it can only be ENOMEM, at which point
-        * there is nothing we can do anyway and the connection will timeout cleanly */
        (void)ngtcp2_conn_extend_max_stream_offset(ngconn, stream_id, datalen);
        ngtcp2_conn_extend_max_offset(ngconn, datalen);
 
@@ -190,8 +182,6 @@ static int stream_open_cb(ngtcp2_conn *ngconn,
        struct pl_quic_stream_sess_data *stream =
                protolayer_sess_data_get_proto(new_subsession,
                                PROTOLAYER_TYPE_QUIC_STREAM);
-       kr_require(stream);
-
        stream->conn_ref = conn;
        if (conn->streams_count <= 0) {
                add_head(&conn->streams, &stream->list_node);
@@ -200,8 +190,7 @@ static int stream_open_cb(ngtcp2_conn *ngconn,
        }
 
        ++conn->streams_count;
-       kr_require(ngtcp2_conn_set_stream_user_data(ngconn, stream_id,
-                               stream) == NGTCP2_NO_ERROR);
+       ngtcp2_conn_set_stream_user_data(ngconn, stream_id, stream);
 
        return NGTCP2_NO_ERROR;
 }
@@ -288,7 +277,7 @@ static int conn_new_handler(ngtcp2_conn **pconn, const ngtcp2_path *path,
                .acked_stream_data_offset = acked_stream_data_offset_cb,
                .stream_open = stream_open_cb,
                .stream_close = stream_close_cb,
-               // .recv_stateless_rst, TODO - OPTIONAL
+               // .recv_stateless_reset, - OPTIONAL
                // .ngtcp2_crypto_recv_retry_cb, - OPTIONAL
                // .extend_max_streams_bidi - OPTIONAL
                // .extend_max_streams_uni - OPTIONAL
@@ -298,7 +287,7 @@ static int conn_new_handler(ngtcp2_conn **pconn, const ngtcp2_path *path,
                .update_key = ngtcp2_crypto_update_key_cb,
                // .path_validation, - OPTIONAL
                // .select_preferred_addr - OPTIONAL
-               // .recv_stream_rst, TODO - OPTIONAL
+               // .stream_rst, - OPTIONAL
                // .extend_max_remote_streams_bidi - OPTIONAL
                // .extend_max_remote_streams_uni - OPTIONAL
                // .extend_max_stream_data, - OPTIONAL
@@ -386,7 +375,7 @@ static int conn_new_handler(ngtcp2_conn **pconn, const ngtcp2_path *path,
        }
 }
 
-static void kr_quic_set_addrs(struct protolayer_iter_ctx *ctx, ngtcp2_path *path)
+static void kr_quic_set_addrs(struct protolayer_iter_ctx *ctx, ngtcp2_path **path)
 {
        const struct sockaddr *remote = NULL;
        const struct sockaddr *local = NULL;
@@ -403,10 +392,10 @@ static void kr_quic_set_addrs(struct protolayer_iter_ctx *ctx, ngtcp2_path *path
                local = session2_get_sockname(ctx->session);
        }
 
-       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);
+       (*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);
 }
 
 int kr_tls_server_session(struct pl_quic_conn_sess_data *conn)
@@ -451,7 +440,7 @@ int kr_tls_server_session(struct pl_quic_conn_sess_data *conn)
        }
 
        gnutls_certificate_send_x509_rdn_sequence(conn->tls_session, 1);
-       gnutls_certificate_server_set_request(conn->tls_session, GNUTLS_CERT_REQUEST);
+       gnutls_certificate_server_set_request(conn->tls_session, GNUTLS_CERT_IGNORE);
        ret = gnutls_priority_set(conn->tls_session, conn->priority);
 
        conn->server_credentials = tls_credentials_reserve(the_network->tls_credentials);
@@ -540,10 +529,8 @@ int quic_init_server_conn(struct pl_quic_conn_sess_data *conn,
        }
 
        uint64_t now = quic_timestamp();
-       ngtcp2_path path;
-       kr_quic_set_addrs(ctx, &path);
 
-       int ret = conn_new_handler(&conn->conn, &path,
+       int ret = conn_new_handler(&conn->conn, conn->path,
                        &conn->scid, &conn->dcid, &conn->odcid,
                        conn->dec_cids.version,
                        now, true, false,
@@ -584,14 +571,13 @@ static void copy_comm_storage(
 int send_special(struct pl_quic_conn_sess_data *conn,
                struct protolayer_iter_ctx *ctx, int action)
 {
-       kr_require(ctx->payload.type == PROTOLAYER_PAYLOAD_WIRE_BUF);
-       char *err_buf = mm_alloc(&ctx->pool, /* FIXME */2048);
+       char *err_buf = mm_alloc(&ctx->pool, NGTCP2_MAX_UDP_PAYLOAD_SIZE);
        if (!err_buf)
                return kr_error(ENOMEM);
        struct wire_buf err_wb = {
                .buf = err_buf,
                .end = 0,
-               .size = 2048 /*FIXME*/,
+               .size = NGTCP2_MAX_UDP_PAYLOAD_SIZE,
                .start = 0,
        };
 
@@ -619,12 +605,11 @@ int send_special(struct pl_quic_conn_sess_data *conn,
                break;
 
        case QUIC_SEND_RETRY:
-               if (!conn || !ctx->comm || ! ctx->comm->target) {
-                       kr_log_error(DOQ, "unable to send Retry packet due to missing data\n");
+               if (!conn || !ctx->comm) {
+                       kr_log_error(DOQ, "unable to send Retry packet\n");
                        break;
                }
 
-               kr_require(conn && ctx->comm->target);
                init_random_cid(&new_dcid, 0);
 
                if (wire_buf_free_space_length(ctx->payload.wire_buf) <
@@ -636,7 +621,7 @@ int send_special(struct pl_quic_conn_sess_data *conn,
                        ctx->payload.wire_buf->size = NGTCP2_CRYPTO_MAX_RETRY_TOKENLEN;
                        ctx->payload.wire_buf->end = ctx->payload.wire_buf->size;
                }
-               
+
                ret = ngtcp2_crypto_generate_retry_token(
                        retry_token, conn->secret,
                        sizeof(conn->secret), conn->dec_cids.version,
@@ -688,7 +673,7 @@ int send_special(struct pl_quic_conn_sess_data *conn,
                ccerr.error_code = KR_QUIC_ERR_EXCESSIVE_LOAD;
                ret = ngtcp2_conn_write_connection_close(
                        conn->conn,
-                       (ngtcp2_path *)ngtcp2_conn_get_path(conn->conn),
+                       conn->path,
                        &pi,
                        wire_buf_free_space(ctx->payload.wire_buf),
                        wire_buf_free_space_length(ctx->payload.wire_buf),
@@ -700,11 +685,11 @@ int send_special(struct pl_quic_conn_sess_data *conn,
        }
 
        if (ret > 0) {
-               kr_require(wire_buf_consume(ctx->payload.wire_buf, ret) == kr_ok());
-               session2_wrap(conn->h.session,
+               wire_buf_consume(ctx->payload.wire_buf, ret);
+               session2_wrap_after(conn->h.session,
+                               PROTOLAYER_TYPE_QUIC_CONN,
                                ctx->payload,
                                ctx->comm,
-                               NULL,
                                ctx->finished_cb,
                                ctx->finished_cb_baton);
                ret = kr_ok();
@@ -730,6 +715,8 @@ static enum protolayer_iter_cb_result pl_quic_conn_unwrap(void *sess_data,
                ctx->payload = protolayer_payload_wire_buf(wb, false);
        }
 
+       kr_quic_set_addrs(ctx, &conn->path);
+
        if (!conn->conn) {
                copy_comm_storage(conn, &ctx->comm_storage);
 
@@ -767,7 +754,7 @@ static enum protolayer_iter_cb_result pl_quic_conn_unwrap(void *sess_data,
        while (queue_len(conn->pending_unwrap) > 0) {
                session2_unwrap(queue_head(conn->pending_unwrap)->h.session,
                                ctx->payload,
-                               &conn->comm_storage,
+                               NULL /* &conn->comm_storage */,
                                ctx->finished_cb,
                                ctx->finished_cb_baton);
                queue_pop(conn->pending_unwrap);
@@ -791,13 +778,12 @@ static enum protolayer_iter_cb_result pl_quic_conn_wrap(void *sess_data,
                ngtcp2_ssize sent = 0;
                ngtcp2_pkt_info pi = { 0 };
 
-               kr_require(ctx->payload.type == PROTOLAYER_PAYLOAD_WIRE_BUF);
                if (wire_buf_data_length(ctx->payload.wire_buf) > 0) {
                        return protolayer_continue(ctx);
                }
 
-               int nwrite = ngtcp2_conn_writev_stream(conn->conn, 
-                               (ngtcp2_path *)ngtcp2_conn_get_path(conn->conn),
+               int nwrite = ngtcp2_conn_writev_stream(conn->conn,
+                               conn->path,
                                &pi, wire_buf_free_space(ctx->payload.wire_buf),
                                wire_buf_free_space_length(ctx->payload.wire_buf),
                                &sent, NGTCP2_WRITE_STREAM_FLAG_NONE, -1, NULL,
@@ -817,7 +803,7 @@ static enum protolayer_iter_cb_result pl_quic_conn_wrap(void *sess_data,
                        return protolayer_break(ctx, kr_error(EINVAL));
                }
 
-               kr_require(wire_buf_consume(ctx->payload.wire_buf, nwrite) == kr_ok());
+               wire_buf_consume(ctx->payload.wire_buf, nwrite);
        }
 
        ngtcp2_conn_update_pkt_tx_time(conn->conn, quic_timestamp());
@@ -830,7 +816,9 @@ static enum protolayer_iter_cb_result pl_quic_conn_wrap(void *sess_data,
 
 int quic_generate_secret(uint8_t *buf, size_t buflen)
 {
-       kr_require(buf != NULL && buflen > 0 && buflen <= 32);
+       if (unlikely(buf == NULL || buflen > 32)) {
+               return kr_error(EINVAL);
+       }
        uint8_t rand[16], hash[32];
        int ret = dnssec_random_buffer(rand, sizeof(rand));
        if (ret != DNSSEC_EOK) {
@@ -851,8 +839,11 @@ static int pl_quic_conn_sess_init(struct session2 *session, void *sess_data, voi
 {
        struct pl_quic_conn_sess_data *conn = sess_data;
        conn->state = 0;
+       conn->path = calloc(1, sizeof(ngtcp2_path));
+       if (!conn->path) {
+               return kr_error(ENOMEM);
+       }
 
-       kr_require(param);
        struct kr_quic_conn_param *p = param;
        conn->dcid = p->dcid;
        conn->scid = p->scid;
@@ -878,7 +869,6 @@ static int pl_quic_conn_sess_init(struct session2 *session, void *sess_data, voi
 
        conn->comm_storage = *comm;
        session->comm_storage = conn->comm_storage;
-
        queue_init(conn->pending_unwrap);
        conn->is_server = !session->outgoing;
 
@@ -889,7 +879,7 @@ static int pl_quic_conn_sess_init(struct session2 *session, void *sess_data, voi
        conn->streams_count = 0;
        conn->tls_session = NULL;
        conn->server_credentials = NULL;
-       if (quic_generate_secret(conn->secret, sizeof(conn->secret)) != kr_ok()) {
+       if (unlikely(quic_generate_secret(conn->secret, sizeof(conn->secret)) != kr_ok())) {
                pl_quic_conn_sess_deinit(conn->h.session, conn);
                kr_log_error(DOQ, "Failed to init connection session\n");
                return kr_error(EINVAL);
@@ -907,7 +897,7 @@ static int pl_quic_conn_sess_deinit(struct session2 *session, void *sess_data)
        struct pl_quic_conn_sess_data *conn = sess_data;
        while (session2_tasklist_del_first(session, false) != NULL);
 
-       kr_log_debug(DOQ, "Closing connection, %s useful, served %zu streams\n",
+       kr_log_info(DOQ, "Closing connection, %s useful, served %zu streams\n",
                        conn->finished_streams ? "was" : "wasn't",
                        conn->finished_streams);
 
@@ -920,7 +910,6 @@ static int pl_quic_conn_sess_deinit(struct session2 *session, void *sess_data)
                --conn->streams_count;
        }
 
-       kr_require(conn->streams_count == 0);
        if (conn->priority) {
                gnutls_priority_deinit(conn->priority);
        }
@@ -935,6 +924,10 @@ static int pl_quic_conn_sess_deinit(struct session2 *session, void *sess_data)
                kr_log_error(DOQ, "Client side of QUIC is not implemented\n");
        }
 
+       if (conn->path) {
+               free(conn->path);
+       }
+
        conn->priority = NULL;
        conn->tls_session = NULL;
        conn->server_credentials = NULL;
index 69d7d68ec00fff2afe1074c410594e2a1b088e82..493a6649320f607da982ad37bc3cc43ae45937c8 100644 (file)
@@ -17,7 +17,6 @@ typedef struct {
 } quic_params_t;
 
 
-#define KR_QUIC_HANDLE_RET_CLOSE       2000
 #define KR_QUIC_ERR_EXCESSIVE_LOAD     0x4
 #define QUIC_MAX_OPEN_CONNS 1024
 
@@ -89,6 +88,7 @@ struct pl_quic_conn_sess_data {
        ngtcp2_cid odcid;
        ngtcp2_version_cid dec_cids;
        uint8_t secret[32];
+       ngtcp2_path *path;
        struct comm_info comm_storage;
        struct comm_addr_storage comm_addr_storage;
 
index 5f5cbc2b1b5376330cf332bcb0697c3bbd25ae8b..d68263b24134d9cb17a74d413fc3079c8f5ae453 100644 (file)
@@ -8,11 +8,6 @@
 
 #include "libdnssec/random.h"
 #include "contrib/openbsd/siphash.h"
-#include "quic_conn.h"
-#include "session2.h"
-#include "worker.h"
-#include <ngtcp2/ngtcp2.h>
-#include <sys/cdefs.h>
 #include "quic_demux.h"
 
 #define BUCKETS_PER_CONNS 8 // Each connecion has several dCIDs, and each CID takes one hash table bucket.
@@ -54,7 +49,6 @@ void quic_conn_mark_used(struct pl_quic_conn_sess_data *conn,
 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);
@@ -223,8 +217,6 @@ void kr_quic_table_sweep(struct kr_quic_table *table,
                        session2_event(c->h.session->transport.parent,
                                        PROTOLAYER_EVENT_DISCONNECT,
                                        NULL);
-
-
                } else if (kr_quic_conn_timeout(c, &now)) {
                        int ret = ngtcp2_conn_handle_expiry(c->conn, now);
                        if (ret != NGTCP2_NO_ERROR) {
@@ -265,10 +257,11 @@ static enum protolayer_iter_cb_result pl_quic_demux_unwrap(void *sess_data,
        struct pl_quic_conn_sess_data *qconn = NULL;
        struct pl_quic_demux_sess_data *demux = sess_data;
 
-       if (kr_fails_assert(ctx->payload.type == PROTOLAYER_PAYLOAD_WIRE_BUF)) {
-               kr_log_warning(DOQ, "Unexpected payload type in quic-conn\n");
-               return protolayer_break(ctx, kr_error(ENOTSUP));
-       }
+       /* Currently we only receive WIRE_BUF payload */
+       // if (ctx->payload.type == PROTOLAYER_PAYLOAD_WIRE_BUF) {
+       //      kr_log_warning(DOQ, "Unexpected payload type in quic-demux\n");
+       //      return protolayer_break(ctx, kr_error(ENOTSUP));
+       // }
 
        ngtcp2_version_cid dec_cids;
        ngtcp2_cid odcid;
@@ -361,7 +354,8 @@ static enum protolayer_iter_cb_result pl_quic_demux_unwrap(void *sess_data,
                        memcpy(&odcid, &dcid, sizeof(odcid));
                }
 
-               if (!demux->h.session->outgoing) {
+               /* TODO remove likely once outgoing DoQ is supported */
+               if (likely(!demux->h.session->outgoing)) {
                        if (!init_unique_cid(&dcid, 0, demux->conn_table)) {
                                kr_log_error(DOQ, "Failed to initialize unique cid (servers choice)\n");
                                return protolayer_break(ctx, kr_ok());
@@ -388,8 +382,6 @@ static enum protolayer_iter_cb_result pl_quic_demux_unwrap(void *sess_data,
                                        1,
                                        false);
 
-               new_conn_sess->comm_storage = demux->h.session->comm_storage;
-
                struct pl_quic_conn_sess_data *conn_sess_data =
                        protolayer_sess_data_get_proto(new_conn_sess,
                                        PROTOLAYER_TYPE_QUIC_CONN);
@@ -401,12 +393,21 @@ static enum protolayer_iter_cb_result pl_quic_demux_unwrap(void *sess_data,
        ret = session2_unwrap(qconn->h.session,
                        ctx->payload,
                        ctx->comm,
+                       // NULL,
                        ctx->finished_cb,
                        ctx->finished_cb_baton);
 
-       quic_conn_mark_used(qconn, demux->conn_table);
-       // kr_quic_table_sweep(demux->conn_table, ctx);
+       
+       if (!QUIC_CAN_SEND(qconn)) {
+               /* Explicitly remove the connection session. */
+               session2_event(qconn->h.session->transport.parent,
+                               PROTOLAYER_EVENT_DISCONNECT,
+                               NULL);
+               return protolayer_break(ctx, kr_ok());
+       }
 
+       quic_conn_mark_used(qconn, demux->conn_table);
+       kr_quic_table_sweep(demux->conn_table, ctx);
        return protolayer_break(ctx, kr_ok());
 }
 
@@ -493,7 +494,6 @@ static int pl_quic_demux_sess_init(struct session2 *session, void *sess_data, vo
        }
 
        struct tls_credentials *creds = the_network->tls_credentials;
-       kr_require(creds->credentials != NULL);
 
        if (!quic->conn_table) {
                quic->conn_table = kr_quic_table_new(QUIC_MAX_OPEN_CONNS,
@@ -503,8 +503,6 @@ static int pl_quic_demux_sess_init(struct session2 *session, void *sess_data, vo
                        kr_log_error(DOQ, "Failed to create QUIC connection table\n");
                        return kr_error(ENOMEM);
                }
-
-               kr_require(quic->conn_table);
        }
 
        return kr_ok();
@@ -556,11 +554,27 @@ static enum protolayer_event_cb_result pl_quic_demux_event_unwrap(
                struct session2 *session, void *sess_data)
 {
        struct pl_quic_demux_sess_data *demux = sess_data;
+       if (event == PROTOLAYER_EVENT_CLOSE || event == PROTOLAYER_EVENT_FORCE_CLOSE) {
+               while (!EMPTY_HEAP(demux->conn_table->expiry_heap)) {
+                       struct pl_quic_conn_sess_data *c =
+                               *(struct pl_quic_conn_sess_data **)HHEAD(
+                                               demux->conn_table->expiry_heap);
+                       kr_quic_table_rem(c, demux->conn_table);
+                       session2_close(c->h.session);
+               }
+
+               session2_dec_refs(session);
+               return PROTOLAYER_EVENT_CONSUME;
+       }
+
+       if (*baton == NULL) {
+               return PROTOLAYER_EVENT_PROPAGATE;
+       }
+
+       struct pl_quic_conn_sess_data *conn = *baton;
 
        /* received NEW_CONNECTION_ID, update mapping to conn_sess_data */
        if (event == PROTOLAYER_EVENT_CONNECT_UPDATE) {
-               kr_require(*baton);
-               struct pl_quic_conn_sess_data *conn = *baton;
                if (update_connection_id_map(demux, conn) != kr_ok()) {
                        event = PROTOLAYER_EVENT_DISCONNECT;
                        /* fallthrough */
@@ -568,36 +582,16 @@ static enum protolayer_event_cb_result pl_quic_demux_event_unwrap(
        }
 
        if (event == PROTOLAYER_EVENT_CONNECT_RETIRE) {
-               kr_require(*baton);
-               struct pl_quic_conn_sess_data *conn = *baton;
                if (remove_connection_id(demux, &conn->dcid, conn) != kr_ok()) {
                        event = PROTOLAYER_EVENT_DISCONNECT;
                        /* fallthrough */
                }
        }
 
-       if (event == PROTOLAYER_EVENT_CLOSE || event == PROTOLAYER_EVENT_FORCE_CLOSE) {
-               while (!EMPTY_HEAP(demux->conn_table->expiry_heap)) {
-                       struct pl_quic_conn_sess_data *c =
-                               *(struct pl_quic_conn_sess_data **)HHEAD(
-                                               demux->conn_table->expiry_heap);
-                       kr_quic_table_rem(c, demux->conn_table);
-                       session2_event(c->h.session,
-                                       PROTOLAYER_EVENT_DISCONNECT, NULL);
-               }
-
-               session2_dec_refs(session);
-               return PROTOLAYER_EVENT_CONSUME;
-       }
-
        if (event == PROTOLAYER_EVENT_DISCONNECT ||
                        event == PROTOLAYER_EVENT_CONNECT_TIMEOUT) {
-               if (*baton == NULL)
-                       return PROTOLAYER_EVENT_CONSUME;
-
-               struct pl_quic_conn_sess_data *conn = *baton;
                kr_quic_table_rem(conn, demux->conn_table);
-               session2_event(conn->h.session, PROTOLAYER_EVENT_DISCONNECT, NULL);
+               session2_close(conn->h.session);
                return PROTOLAYER_EVENT_CONSUME;
        }
 
index 9575be899ddaff7182558704e6d5301cc615283f..1b7cb8844e2786567631b3d2b98f6dca100ff644 100644 (file)
@@ -4,13 +4,8 @@
 
 #include "lib/resolve.h"
 #include "quic_common.h"
-#include "quic_conn.h"
-#include "session2.h"
-#include <ngtcp2/ngtcp2.h>
 #include "quic_stream.h"
 
-#define OUTBUF_SIZE 4096
-
 /* forward declaration */
 static int send_stream(struct pl_quic_stream_sess_data *stream,
                struct protolayer_iter_ctx *ctx, uint8_t *data,
@@ -25,7 +20,6 @@ static enum protolayer_iter_cb_result pl_quic_stream_unwrap(void *sess_data,
                return protolayer_break(ctx, kr_error(EINVAL));
        }
 
-       kr_assert(stream->incflags & NGTCP2_STREAM_DATA_FLAG_FIN);
        ctx->payload = protolayer_payload_wire_buf(&stream->pers_inbuf, false);
        return protolayer_continue(ctx);
 }
@@ -33,10 +27,6 @@ static enum protolayer_iter_cb_result pl_quic_stream_unwrap(void *sess_data,
 uint8_t *kr_quic_stream_add_data(struct pl_quic_stream_sess_data *s,
                   uint8_t *data, size_t len)
 {
-       if (s == NULL) {
-               return NULL;
-       }
-
        size_t prefix = sizeof(uint16_t);
 
        struct kr_quic_obuf *obuf = malloc(sizeof(*obuf) + prefix + len);
@@ -63,13 +53,13 @@ uint8_t *kr_quic_stream_add_data(struct pl_quic_stream_sess_data *s,
 static enum protolayer_iter_cb_result pl_quic_stream_wrap(void *sess_data,
                void *iter_data, struct protolayer_iter_ctx *ctx)
 {
-       kr_require(ctx->payload.type = PROTOLAYER_PAYLOAD_IOVEC);
        struct pl_quic_stream_sess_data *stream = sess_data;
-       kr_require(stream->stream_id >= 0);
        ngtcp2_ssize sent = 0;
 
-       kr_quic_stream_add_data(stream, ctx->payload.iovec.iov[1].iov_base,
-                       ctx->payload.iovec.iov[1].iov_len);
+       if (unlikely(kr_quic_stream_add_data(stream, ctx->payload.iovec.iov[1].iov_base,
+                       ctx->payload.iovec.iov[1].iov_len) == NULL)) {
+               return kr_error(ENOMEM);
+       }
 
        ctx->payload = protolayer_payload_wire_buf(&stream->outbuf, false);
 
@@ -137,15 +127,13 @@ static int send_stream(struct pl_quic_stream_sess_data *stream,
                *sent = 0;
        }
 
-       kr_require(wire_buf_consume(ctx->payload.wire_buf, nwrite) == kr_ok());
+       wire_buf_consume(ctx->payload.wire_buf, nwrite);
        return nwrite;
 }
 
 void kr_quic_stream_mark_sent(struct pl_quic_stream_sess_data *stream,
                size_t amount_sent)
 {
-       kr_require(stream);
-
        stream->unsent_offset += amount_sent;
        kr_assert(stream->unsent_offset <= stream->unsent_obuf->len);
        if (stream->unsent_offset == stream->unsent_obuf->len) {
@@ -165,16 +153,15 @@ static int pl_quic_stream_sess_init(struct session2 *session,
        struct pl_quic_stream_sess_data *stream = sess_data;
        stream->h.session = session;
 
-       wire_buf_init(&stream->pers_inbuf, OUTBUF_SIZE);
-       wire_buf_init(&stream->outbuf, OUTBUF_SIZE);
+       wire_buf_init(&stream->pers_inbuf, NGTCP2_MAX_UDP_PAYLOAD_SIZE);
+       wire_buf_init(&stream->outbuf, NGTCP2_MAX_UDP_PAYLOAD_SIZE);
 
        session->secure = true;
 
-       kr_require(param);
        struct kr_quic_stream_param *p = param;
        stream->conn = p->conn;
        stream->stream_id = p->stream_id;
-       stream->comm_storage = p->comm_storage;
+       session->comm_storage = p->comm_storage;
 
        if (stream->obufs_size == 0) {
                init_list(&stream->outbufs);
@@ -188,7 +175,6 @@ static int pl_quic_stream_sess_init(struct session2 *session,
 void kr_quic_stream_ack_data(struct pl_quic_stream_sess_data *stream,
                int64_t stream_id, size_t end_acked, bool keep_stream)
 {
-       kr_require(stream);
        struct list *obs = &stream->outbufs;
        struct kr_quic_obuf *first;
 
@@ -206,32 +192,10 @@ void kr_quic_stream_ack_data(struct pl_quic_stream_sess_data *stream,
        }
 }
 
-int update_stream_pers_buffer(struct pl_quic_stream_sess_data *stream,
-               const uint8_t *data, size_t len, int64_t stream_id)
-{
-       kr_require(len > 0 && data && stream);
-
-       if (wire_buf_free_space_length(&stream->pers_inbuf) < len) {
-               size_t inc = MIN(stream->outbuf.size, 1024);
-               char *new_buf = realloc(stream->pers_inbuf.buf,
-                               wire_buf_data_length(&stream->pers_inbuf) + inc);
-               kr_require(new_buf);
-               stream->pers_inbuf.buf = new_buf;
-               stream->pers_inbuf.end += inc;
-               stream->pers_inbuf.size += inc;
-       }
-
-       memcpy(wire_buf_free_space(&stream->pers_inbuf), data, len);
-       kr_require(wire_buf_consume(&stream->pers_inbuf, len) == kr_ok());
-
-       return kr_ok();
-}
-
 static int pl_quic_stream_sess_deinit(struct session2 *session, void *sess_data)
 {
        struct pl_quic_stream_sess_data *stream = sess_data;
        ngtcp2_conn_shutdown_stream(stream->conn, 0, stream->stream_id, 0);
-       kr_require(queue_len(session->waiting) <= 0);
        kr_quic_stream_ack_data(stream, stream->stream_id, SIZE_MAX, false);
        wire_buf_deinit(&stream->pers_inbuf);
        wire_buf_deinit(&stream->outbuf);