summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Hák <jan.hak@nic.cz>2023-05-10 14:44:46 +0200
committerDaniel Salzman <daniel.salzman@nic.cz>2023-05-23 10:42:01 +0200
commit92ccde72e0313175a932b6c1fd781425c4a2b9cd (patch)
treebc217ef9b0b33822e73e4508ce47a902ff669db8
parentlibknot: remove of unused static functions (diff)
downloadknot-92ccde72e0313175a932b6c1fd781425c4a2b9cd.tar.xz
knot-92ccde72e0313175a932b6c1fd781425c4a2b9cd.zip
libknot: remove pointer to iovec from linked-list node to save some space in memory
-rw-r--r--src/knot/query/quic-requestor.c14
-rw-r--r--src/knot/server/handler.c8
-rw-r--r--src/knot/server/xdp-handler.c3
-rw-r--r--src/libknot/xdp/tcp_iobuf.c21
-rw-r--r--src/libknot/xdp/tcp_iobuf.h8
-rw-r--r--src/utils/common/quic.c2
-rw-r--r--src/utils/kxdpgun/main.c4
-rw-r--r--tests/libknot/test_xdp_tcp.c23
8 files changed, 48 insertions, 35 deletions
diff --git a/src/knot/query/quic-requestor.c b/src/knot/query/quic-requestor.c
index 3514c5e3c..fe36369ce 100644
--- a/src/knot/query/quic-requestor.c
+++ b/src/knot/query/quic-requestor.c
@@ -177,11 +177,12 @@ int knot_qreq_recv(struct knot_quic_reply *r, struct iovec *out, int timeout_ms)
knot_tinbufu_res_t *firstib = stream->inbufs;
if (firstib != NULL && firstib->n_inbufs >= 2) { // first inbuf has been processed last time
assert(firstib->n_inbufs == 2);
- if (firstib->inbufs[1].iov_len > out->iov_len) {
+ struct iovec *inbufs = knot_tinbufu_res_inbufs(firstib);
+ if (inbufs[1].iov_len > out->iov_len) {
return KNOT_ESPACE;
}
- out->iov_len = firstib->inbufs[1].iov_len;
- memcpy(out->iov_base, firstib->inbufs[1].iov_base, out->iov_len);
+ out->iov_len = inbufs[1].iov_len;
+ memcpy(out->iov_base, inbufs[1].iov_base, out->iov_len);
stream->inbufs = firstib->next;
free(firstib);
return KNOT_EOK;
@@ -207,9 +208,10 @@ int knot_qreq_recv(struct knot_quic_reply *r, struct iovec *out, int timeout_ms)
return KNOT_ESEMCHECK; // this hardly happens
}
- if (firstib->inbufs[0].iov_len <= out->iov_len) {
- out->iov_len = firstib->inbufs[0].iov_len;
- memcpy(out->iov_base, firstib->inbufs[0].iov_base, out->iov_len);
+ struct iovec *inbufs = knot_tinbufu_res_inbufs(firstib);
+ if (inbufs[0].iov_len <= out->iov_len) {
+ out->iov_len = inbufs[0].iov_len;
+ memcpy(out->iov_base, inbufs[0].iov_base, out->iov_len);
if (firstib->n_inbufs < 2) {
stream->inbufs = firstib->next;
free(firstib);
diff --git a/src/knot/server/handler.c b/src/knot/server/handler.c
index 3d14dda58..15e2812f4 100644
--- a/src/knot/server/handler.c
+++ b/src/knot/server/handler.c
@@ -105,7 +105,8 @@ void handle_quic_streams(knot_quic_conn_t *conn, knotd_qdata_params_t *params,
while (conn != NULL && (stream = knot_quic_stream_get_process(conn, &stream_id)) != NULL) {
assert(stream->inbufs != NULL);
assert(stream->inbufs->n_inbufs > 0);
- assert(stream->inbufs->inbufs[0].iov_len > 0);
+ struct iovec *inbufs = knot_tinbufu_res_inbufs(stream->inbufs);
+ assert(inbufs[0].iov_len > 0);
if (msg) {
#ifdef ENABLE_XDP
params_xdp_update(params, KNOTD_QUERY_PROTO_QUIC, msg,
@@ -114,10 +115,9 @@ void handle_quic_streams(knot_quic_conn_t *conn, knotd_qdata_params_t *params,
} else {
params_update(params, knot_quic_conn_rtt(conn), conn);
}
- // NOTE: if multiple buffers in inbuf_fin, only the first is used and rest ignored
- handle_quic_stream(conn, stream_id, &stream->inbufs->inbufs[0], layer, params,
+ // NOTE: only the first msg in the stream is used, the rest is dropped.
+ handle_quic_stream(conn, stream_id, &inbufs[0], layer, params,
ans_buf, sizeof(ans_buf));
-
while (stream->inbufs != NULL) {
struct knot_tinbufu_res *tofree = stream->inbufs;
stream->inbufs = tofree->next;
diff --git a/src/knot/server/xdp-handler.c b/src/knot/server/xdp-handler.c
index e60dcfd41..09064795d 100644
--- a/src/knot/server/xdp-handler.c
+++ b/src/knot/server/xdp-handler.c
@@ -216,7 +216,8 @@ static void handle_tcp(xdp_handle_ctx_t *ctx, knot_layer_t *layer,
// Consume the query.
params_xdp_update(params, KNOTD_QUERY_PROTO_TCP, ctx->msg_recv,
rl->conn->establish_rtt, NULL);
- handle_query(params, layer, &rl->inbf->inbufs[j], NULL);
+ struct iovec *inbufs = knot_tinbufu_res_inbufs(rl->inbf);
+ handle_query(params, layer, &inbufs[j], NULL);
// Process the reply.
knot_pkt_t *ans = knot_pkt_new(ans_buf, sizeof(ans_buf), layer->mm);
diff --git a/src/libknot/xdp/tcp_iobuf.c b/src/libknot/xdp/tcp_iobuf.c
index 65342d0de..e450e36ec 100644
--- a/src/libknot/xdp/tcp_iobuf.c
+++ b/src/libknot/xdp/tcp_iobuf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2022 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+/* Copyright (C) 2023 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
@@ -56,16 +56,13 @@ static void iov_append(struct iovec *what, const struct iovec *with)
static knot_tinbufu_res_t *tinbufu_alloc(size_t inbuf_count, size_t first_inbuf)
{
- knot_tinbufu_res_t *res = malloc(sizeof(*res) + inbuf_count*sizeof(*res->inbufs) + first_inbuf);
+ knot_tinbufu_res_t *res = malloc(sizeof(*res) + inbuf_count*sizeof(struct iovec) + first_inbuf);
if (res == NULL) {
return NULL;
}
res->next = NULL;
res->n_inbufs = inbuf_count;
- res->inbufs = (void *)(res + 1);
- res->inbufs[0].iov_base = (void *)(res->inbufs + inbuf_count);
- res->inbufs[0].iov_len = 0;
return res;
}
@@ -150,9 +147,9 @@ int knot_tcp_inbuf_update(struct iovec *buffer, struct iovec data, bool alloc_bu
return KNOT_ENOMEM;
}
- uint8_t *out_buf_ptr = (uint8_t *)(out->inbufs + iov_cnt);
+ cur = knot_tinbufu_res_inbufs(out);
+ uint8_t *out_buf_ptr = (uint8_t *)(cur + iov_cnt);
data_use = data;
- cur = out->inbufs;
if (buffer->iov_len >= 2) { // at least some data in buffer
struct iovec bf = {
.iov_base = buffer->iov_base + sizeof(uint16_t),
@@ -172,7 +169,7 @@ int knot_tcp_inbuf_update(struct iovec *buffer, struct iovec data, bool alloc_bu
}
if (alloc_bufs) {
- for (; cur != out->inbufs + iov_cnt; ++cur) {
+ for (; cur != knot_tinbufu_res_inbufs(out) + iov_cnt; ++cur) {
cur->iov_base = out_buf_ptr;
cur->iov_len = 0;
data_use.iov_len = tcp_payload_len(&data);
@@ -183,7 +180,7 @@ int knot_tcp_inbuf_update(struct iovec *buffer, struct iovec data, bool alloc_bu
out_buf_ptr = cur->iov_base + cur->iov_len;
}
} else {
- for (; cur != out->inbufs + iov_cnt; ++cur) {
+ for (; cur != knot_tinbufu_res_inbufs(out) + iov_cnt; ++cur) {
cur->iov_len = tcp_payload_len(&data);
iov_inc(&data, 2);
cur->iov_base = data.iov_base;
@@ -301,3 +298,9 @@ size_t knot_tcp_outbufs_usage(knot_tcp_outbuf_t *bufs)
}
return res;
}
+
+_public_
+struct iovec *knot_tinbufu_res_inbufs(knot_tinbufu_res_t *node)
+{
+ return (struct iovec *)(node + 1);
+}
diff --git a/src/libknot/xdp/tcp_iobuf.h b/src/libknot/xdp/tcp_iobuf.h
index 9df38ee1f..6b7311e1d 100644
--- a/src/libknot/xdp/tcp_iobuf.h
+++ b/src/libknot/xdp/tcp_iobuf.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2022 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+/* Copyright (C) 2023 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
@@ -52,7 +52,6 @@ typedef struct knot_sweep_stats {
} knot_sweep_stats_t;
typedef struct knot_tinbufu_res {
- struct iovec *inbufs;
size_t n_inbufs;
struct knot_tinbufu_res *next;
} knot_tinbufu_res_t;
@@ -125,4 +124,9 @@ void knot_tcp_outbufs_can_send(knot_tcp_outbuf_t *bufs, ssize_t window_size, boo
*/
size_t knot_tcp_outbufs_usage(knot_tcp_outbuf_t *bufs);
+/*!
+ * \brief Return pointer to parsed iovec
+ */
+struct iovec *knot_tinbufu_res_inbufs(knot_tinbufu_res_t *node);
+
/*! @} */
diff --git a/src/utils/common/quic.c b/src/utils/common/quic.c
index 777aed8e6..af435c559 100644
--- a/src/utils/common/quic.c
+++ b/src/utils/common/quic.c
@@ -405,7 +405,7 @@ static int quic_respcpy(quic_ctx_t *ctx, uint8_t *buf, const size_t buf_len)
assert(ctx && buf && buf_len > 0);
if (ctx->stream.in_parsed != NULL) {
knot_tinbufu_res_t *cur = ctx->stream.in_parsed;
- struct iovec *it = &cur->inbufs[ctx->stream.in_parsed_it];
+ struct iovec *it = &knot_tinbufu_res_inbufs(cur)[ctx->stream.in_parsed_it];
if (buf_len < it->iov_len) {
return KNOT_ENOMEM;
}
diff --git a/src/utils/kxdpgun/main.c b/src/utils/kxdpgun/main.c
index 03f00447b..3cf6c126d 100644
--- a/src/utils/kxdpgun/main.c
+++ b/src/utils/kxdpgun/main.c
@@ -702,7 +702,7 @@ void *xdp_gun_thread(void *_ctx)
break;
}
for (size_t j = 0; rl->inbf != NULL && j < rl->inbf->n_inbufs; j++) {
- if (check_dns_payload(&rl->inbf->inbufs[j], ctx, &local_stats)) {
+ if (check_dns_payload(&knot_tinbufu_res_inbufs(rl->inbf)[j], ctx, &local_stats)) {
if (!(ctx->ignore1 & KXDPGUN_IGNORE_CLOSE)) {
rl->answer = XDP_TCP_CLOSE;
}
@@ -779,7 +779,7 @@ void *xdp_gun_thread(void *_ctx)
stream0 = knot_quic_conn_get_stream(conn, 0, false);
if (stream0 != NULL && stream0->inbufs != NULL) {
- check_dns_payload(&stream0->inbufs->inbufs[0], ctx, &local_stats);
+ check_dns_payload(&knot_tinbufu_res_inbufs(stream0->inbufs)[0], ctx, &local_stats);
free(stream0->inbufs);
stream0->inbufs = NULL;
diff --git a/tests/libknot/test_xdp_tcp.c b/tests/libknot/test_xdp_tcp.c
index f0d6b6ba1..7d99c0393 100644
--- a/tests/libknot/test_xdp_tcp.c
+++ b/tests/libknot/test_xdp_tcp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2022 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+/* Copyright (C) 2023 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
@@ -315,8 +315,9 @@ void test_data_fragments(void)
ok(rls[0].conn != NULL, "fragments0: connection present");
ok(rls[0].conn == test_conn, "fragments0: same connection");
is_int(1, rls[0].inbf->n_inbufs, "fragments0: inbufs count");
- is_int(3, rls[0].inbf->inbufs[0].iov_len, "fragments0: data length");
- is_int(0, memcmp("xyz", rls[0].inbf->inbufs[0].iov_base, rls[0].inbf->inbufs[0].iov_len), "fragments0: data");
+ struct iovec *inbufs = knot_tinbufu_res_inbufs(rls[0].inbf);
+ is_int(3, inbufs[0].iov_len, "fragments0: data length");
+ is_int(0, memcmp("xyz", inbufs[0].iov_base, inbufs[0].iov_len), "fragments0: data");
is_int(KNOT_XDP_MSG_ACK, rls[1].auto_answer, "fragments[1]: auto answer");
is_int(XDP_TCP_NOOP, rls[1].action, "fragments[1]: action"); // NOTE: NOOP
@@ -328,17 +329,19 @@ void test_data_fragments(void)
ok(rls[0].conn != NULL, "fragments2: connection present");
ok(rls[0].conn == test_conn, "fragments2: same connection");
is_int(2, rls[2].inbf->n_inbufs, "fragments2: inbufs count");
- is_int(4, rls[2].inbf->inbufs[0].iov_len, "fragments2-0: data length");
- is_int(0, memcmp("abcd", rls[2].inbf->inbufs[0].iov_base, rls[2].inbf->inbufs[0].iov_len), "fragments2-0: data");
- is_int(1, rls[2].inbf->inbufs[1].iov_len, "fragments2-1: data length");
- is_int(0, memcmp("i", rls[2].inbf->inbufs[1].iov_base, rls[2].inbf->inbufs[1].iov_len), "fragments2-1: data");
+ inbufs = knot_tinbufu_res_inbufs(rls[2].inbf);
+ is_int(4, inbufs[0].iov_len, "fragments2-0: data length");
+ is_int(0, memcmp("abcd", inbufs[0].iov_base, inbufs[0].iov_len), "fragments2-0: data");
+ is_int(1, inbufs[1].iov_len, "fragments2-1: data length");
+ is_int(0, memcmp("i", inbufs[1].iov_base, inbufs[1].iov_len), "fragments2-1: data");
is_int(KNOT_XDP_MSG_ACK, rls[3].auto_answer, "fragments[3]: auto answer");
ok(rls[0].conn != NULL, "fragments3: connection present");
ok(rls[0].conn == test_conn, "fragments3: same connection");
is_int(1, rls[3].inbf->n_inbufs, "fragments3: inbufs count");
- is_int(2, rls[3].inbf->inbufs[0].iov_len, "fragments3: data length");
- is_int(0, memcmp("AB", rls[3].inbf->inbufs[0].iov_base, rls[3].inbf->inbufs[0].iov_len), "fragments3: data");
+ inbufs = knot_tinbufu_res_inbufs(rls[3].inbf);
+ is_int(2, inbufs[0].iov_len, "fragments3: data length");
+ is_int(0, memcmp("AB", inbufs[0].iov_base, inbufs[0].iov_len), "fragments3: data");
knot_tcp_cleanup(test_table, rls, 4);
}
@@ -499,7 +502,7 @@ void test_ibufs_size(void)
check_sent(CONNS, 0, 0, 0);
is_int(192, test_table->inbufs_total, "inbufs: after change");
is_int(0, rls[1].action, "inbufs: one relay");
- is_int(10, rls[0].inbf->inbufs[0].iov_len, "inbufs: data length");
+ is_int(10, knot_tinbufu_res_inbufs(rls[0].inbf)[0].iov_len, "inbufs: data length");
knot_tcp_cleanup(test_table, rls, CONNS);
// now free some