From ba0f616acc63cbf6e0694854496d8f64f2724496 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 1 Oct 2020 18:42:08 +0200 Subject: [PATCH] buffer: statically allocate buffers We need a total of 3 buffers: - Input buffer - Output buffer - Duplicated buffer for broadcast forward --- src/buffer.c | 54 +++++++++++++++++++++++++++++++++++++++++++------ src/buffer.h | 11 +++++----- src/fastd.c | 3 +++ src/handshake.h | 2 +- 4 files changed, 57 insertions(+), 13 deletions(-) diff --git a/src/buffer.c b/src/buffer.c index 9a0965f..f6d616d 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -11,13 +11,41 @@ */ +#define FASTD_BUFFER_COUNT 3 + + #include "fastd.h" -/** - Allocate a new buffer +/** The pool of statically allocated buffers */ +static fastd_buffer_t *buffers = NULL; - A buffer can have head and tail space which allows changing with data size without moving the data. + +/** Initializes the buffer pool */ +void fastd_init_buffers(void) { + size_t i; + for (i = 0; i < FASTD_BUFFER_COUNT; i++) { + fastd_buffer_t *buffer = + fastd_alloc_aligned(sizeof(*buffer) + ctx.max_buffer, sizeof(fastd_block128_t)); + fastd_buffer_free(buffer); + } +} + +/** Frees the buffer pool */ +void fastd_cleanup_buffers(void) { + size_t i; + for (i = 0; i < FASTD_BUFFER_COUNT; i++) + free(fastd_buffer_alloc(0, 0)); + + if (buffers) + exit_bug("too many buffers to free"); +} + + +/** + Allocates a new buffer from the buffer pool + + A buffer can have headspace which allows changing the data pointer without moving the data. The buffer is always allocated aligned to 16 bytes to allow efficient access for SIMD instructions etc. in crypto implementations @@ -25,12 +53,26 @@ fastd_buffer_t *fastd_buffer_alloc(size_t len, size_t headroom) { size_t base_len = alignto(headroom + len, sizeof(fastd_block128_t)); if (base_len > ctx.max_buffer) - exit_fatal("BUG: oversized buffer alloc", base_len, ctx.max_buffer); + exit_fatal("BUG: oversized buffer alloc (%Z > %Z)", base_len, ctx.max_buffer); + + fastd_buffer_t *buffer = buffers; + if (!buffer) + exit_bug("out of buffers"); + + if (buffer->len != SIZE_MAX) + exit_bug("dirty freed buffer"); + + buffers = buffer->data; - fastd_buffer_t *buffer = fastd_alloc_aligned(sizeof(*buffer) + base_len, sizeof(fastd_block128_t)); - buffer->base_len = base_len; buffer->data = buffer->base + headroom; buffer->len = len; return buffer; } + +/** Returns a buffer to the buffer pool */ +void fastd_buffer_free(fastd_buffer_t *buffer) { + buffer->len = SIZE_MAX; + buffer->data = buffers; + buffers = buffer; +} diff --git a/src/buffer.h b/src/buffer.h index 4f79cdb..fda0cd6 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -22,7 +22,6 @@ struct fastd_buffer { void *data; /**< The beginning of the actual data in the buffer */ size_t len; /**< The data length */ - size_t base_len; /**< The size of the allocated memory area */ uint8_t base[] __attribute__((aligned(16))); /**< Buffer space */ }; @@ -33,7 +32,12 @@ struct fastd_buffer_view { }; +void fastd_init_buffers(void); +void fastd_cleanup_buffers(void); + + fastd_buffer_t *fastd_buffer_alloc(size_t len, size_t headroom); +void fastd_buffer_free(fastd_buffer_t *buffer); /** Duplicates a buffer */ @@ -43,11 +47,6 @@ static inline fastd_buffer_t *fastd_buffer_dup(const fastd_buffer_t *buffer, siz return new_buffer; } -/** Frees a buffer */ -static inline void fastd_buffer_free(fastd_buffer_t *buffer) { - free(buffer); -} - /** Returns the amount of headroom a buffer has (the number of bytes that can be pushed) diff --git a/src/fastd.c b/src/fastd.c index 8150745..0d62f9f 100644 --- a/src/fastd.c +++ b/src/fastd.c @@ -524,6 +524,7 @@ static inline void init(int argc, char *argv[]) { on_up(ctx.iface); fastd_configure_peers(); + fastd_init_buffers(); if (conf.drop_caps == DROP_CAPS_ON) drop_caps(); @@ -608,6 +609,8 @@ static inline void cleanup(void) { delete_peers(); + fastd_cleanup_buffers(); + if (ctx.iface) { on_down(ctx.iface); fastd_iface_close(ctx.iface); diff --git a/src/handshake.h b/src/handshake.h index e9a8910..c12343a 100644 --- a/src/handshake.h +++ b/src/handshake.h @@ -125,7 +125,7 @@ static inline uint16_t fastd_handshake_tlv_len(const fastd_buffer_t *buffer) { static inline uint8_t *fastd_handshake_extend(fastd_buffer_t *buffer, fastd_handshake_record_type_t type, size_t len) { uint8_t *dst = buffer->data + buffer->len; - if ((uint8_t *)buffer->data + buffer->len + RECORD_LEN(len) > buffer->base + buffer->base_len) + if ((uint8_t *)buffer->data + buffer->len + RECORD_LEN(len) > buffer->base + ctx.max_buffer) exit_bug("not enough buffer allocated for handshake"); buffer->len += RECORD_LEN(len);