summaryrefslogtreecommitdiffstats
path: root/src/libknot/quic/quic_conn.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libknot/quic/quic_conn.c')
-rw-r--r--src/libknot/quic/quic_conn.c35
1 files changed, 30 insertions, 5 deletions
diff --git a/src/libknot/quic/quic_conn.c b/src/libknot/quic/quic_conn.c
index 6616573..1a3b9df 100644
--- a/src/libknot/quic/quic_conn.c
+++ b/src/libknot/quic/quic_conn.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2023 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+/* Copyright (C) 2024 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -29,6 +29,7 @@
#include "libdnssec/random.h"
#include "libknot/attribute.h"
#include "libknot/error.h"
+#include "libknot/quic/tls_common.h"
#include "libknot/quic/quic.h"
#include "libknot/xdp/tcp_iobuf.h"
#include "libknot/wire.h"
@@ -45,7 +46,7 @@ static int cmp_expiry_heap_nodes(void *c1, void *c2)
_public_
knot_quic_table_t *knot_quic_table_new(size_t max_conns, size_t max_ibufs, size_t max_obufs,
- size_t udp_payload, struct knot_quic_creds *creds)
+ size_t udp_payload, struct knot_creds *creds)
{
size_t table_size = max_conns * BUCKETS_PER_CONNS;
@@ -61,9 +62,17 @@ knot_quic_table_t *knot_quic_table_new(size_t max_conns, size_t max_ibufs, size_
res->obufs_max = max_obufs;
res->udp_payload_limit = udp_payload;
+ int ret = gnutls_priority_init2(&res->priority, KNOT_TLS_PRIORITIES, NULL,
+ GNUTLS_PRIORITY_INIT_DEF_APPEND);
+ if (ret != GNUTLS_E_SUCCESS) {
+ free(res);
+ return NULL;
+ }
+
res->expiry_heap = malloc(sizeof(struct heap));
if (res->expiry_heap == NULL || !heap_init(res->expiry_heap, cmp_expiry_heap_nodes, 0)) {
free(res->expiry_heap);
+ gnutls_priority_deinit(res->priority);
free(res);
return NULL;
}
@@ -92,6 +101,7 @@ void knot_quic_table_free(knot_quic_table_t *table)
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);
@@ -118,7 +128,9 @@ void knot_quic_table_sweep(knot_quic_table_t *table, struct knot_quic_reply *swe
while (!EMPTY_HEAP(table->expiry_heap)) {
knot_quic_conn_t *c = *(knot_quic_conn_t **)HHEAD(table->expiry_heap);
- if (table->usage > table->max_conns) {
+ if ((c->flags & KNOT_QUIC_CONN_BLOCKED)) {
+ break; // highly inprobable
+ } else if (table->usage > table->max_conns) {
knot_sweep_stats_incr(stats, KNOT_SWEEP_CTR_LIMIT_CONN);
send_excessive_load(c, sweep_reply, table);
knot_quic_table_rem(c, table);
@@ -476,7 +488,7 @@ uint8_t *knot_quic_stream_add_data(knot_quic_conn_t *conn, int64_t stream_id,
add_tail((list_t *)&s->outbufs, (node_t *)obuf);
s->obufs_size += obuf->len;
conn->obufs_size += obuf->len;
- conn->quic_table->obufs_size += obuf->len;
+ ATOMIC_ADD(conn->quic_table->obufs_size, obuf->len);
return obuf->buf + prefix;
}
@@ -497,7 +509,7 @@ void knot_quic_stream_ack_data(knot_quic_conn_t *conn, int64_t stream_id,
assert(HEAD(*obs) != first); // help CLANG analyzer understand what rem_node did and that further usage of HEAD(*obs) is safe
s->obufs_size -= first->len;
conn->obufs_size -= first->len;
- conn->quic_table->obufs_size -= first->len;
+ ATOMIC_SUB(conn->quic_table->obufs_size, first->len);
s->first_offset += first->len;
free(first);
if (s->unsent_obuf == first) {
@@ -556,6 +568,19 @@ void knot_quic_stream_mark_sent(knot_quic_conn_t *conn, int64_t stream_id,
}
_public_
+void knot_quic_conn_block(knot_quic_conn_t *conn, bool block)
+{
+ if (block) {
+ conn->flags |= KNOT_QUIC_CONN_BLOCKED;
+ conn->next_expiry = UINT64_MAX;
+ conn_heap_reschedule(conn, conn->quic_table);
+ } else {
+ conn->flags &= ~KNOT_QUIC_CONN_BLOCKED;
+ quic_conn_mark_used(conn, conn->quic_table);
+ }
+}
+
+_public_
void knot_quic_cleanup(knot_quic_conn_t *conns[], size_t n_conns)
{
for (size_t i = 0; i < n_conns; i++) {