diff options
author | Jan Hák <jan.hak@nic.cz> | 2023-05-10 14:44:46 +0200 |
---|---|---|
committer | Daniel Salzman <daniel.salzman@nic.cz> | 2023-05-23 10:42:01 +0200 |
commit | 92ccde72e0313175a932b6c1fd781425c4a2b9cd (patch) | |
tree | bc217ef9b0b33822e73e4508ce47a902ff669db8 | |
parent | libknot: remove of unused static functions (diff) | |
download | knot-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.c | 14 | ||||
-rw-r--r-- | src/knot/server/handler.c | 8 | ||||
-rw-r--r-- | src/knot/server/xdp-handler.c | 3 | ||||
-rw-r--r-- | src/libknot/xdp/tcp_iobuf.c | 21 | ||||
-rw-r--r-- | src/libknot/xdp/tcp_iobuf.h | 8 | ||||
-rw-r--r-- | src/utils/common/quic.c | 2 | ||||
-rw-r--r-- | src/utils/kxdpgun/main.c | 4 | ||||
-rw-r--r-- | tests/libknot/test_xdp_tcp.c | 23 |
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 |