From ebd18e2d209504c57151cb997ee169c8bad1982e Mon Sep 17 00:00:00 2001 From: Frantisek Tobias Date: Wed, 26 Nov 2025 12:39:26 +0100 Subject: [PATCH] daemon/quic: minor optimizations, remove pointless asserts, discard conn state when RETRY pkt is sent --- daemon/quic_common.h | 2 +- daemon/quic_conn.c | 103 ++++++++++++++++++++----------------------- daemon/quic_conn.h | 2 +- daemon/quic_demux.c | 80 ++++++++++++++++----------------- daemon/quic_stream.c | 52 ++++------------------ 5 files changed, 95 insertions(+), 144 deletions(-) diff --git a/daemon/quic_common.h b/daemon/quic_common.h index 3e8410125..a1b9821ce 100644 --- a/daemon/quic_common.h +++ b/daemon/quic_common.h @@ -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 diff --git a/daemon/quic_conn.c b/daemon/quic_conn.c index 1de244f1f..9fdf83060 100644 --- a/daemon/quic_conn.c +++ b/daemon/quic_conn.c @@ -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 -#include -#include #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; diff --git a/daemon/quic_conn.h b/daemon/quic_conn.h index 69d7d68ec..493a66493 100644 --- a/daemon/quic_conn.h +++ b/daemon/quic_conn.h @@ -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; diff --git a/daemon/quic_demux.c b/daemon/quic_demux.c index 5f5cbc2b1..d68263b24 100644 --- a/daemon/quic_demux.c +++ b/daemon/quic_demux.c @@ -8,11 +8,6 @@ #include "libdnssec/random.h" #include "contrib/openbsd/siphash.h" -#include "quic_conn.h" -#include "session2.h" -#include "worker.h" -#include -#include #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; } diff --git a/daemon/quic_stream.c b/daemon/quic_stream.c index 9575be899..1b7cb8844 100644 --- a/daemon/quic_stream.c +++ b/daemon/quic_stream.c @@ -4,13 +4,8 @@ #include "lib/resolve.h" #include "quic_common.h" -#include "quic_conn.h" -#include "session2.h" -#include #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); -- 2.47.3