summaryrefslogtreecommitdiffstats
path: root/src/contrib/conn_pool.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/contrib/conn_pool.h')
-rw-r--r--src/contrib/conn_pool.h128
1 files changed, 128 insertions, 0 deletions
diff --git a/src/contrib/conn_pool.h b/src/contrib/conn_pool.h
new file mode 100644
index 0000000..fece34a
--- /dev/null
+++ b/src/contrib/conn_pool.h
@@ -0,0 +1,128 @@
+/* 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
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <pthread.h>
+#include <stdbool.h>
+#include <sys/socket.h>
+
+#include "contrib/time.h"
+
+typedef intptr_t conn_pool_fd_t;
+extern const conn_pool_fd_t CONN_POOL_FD_INVALID;
+
+typedef void (*conn_pool_close_cb_t)(conn_pool_fd_t fd);
+typedef bool (*conn_pool_invalid_cb_t)(conn_pool_fd_t fd);
+
+typedef struct {
+ struct sockaddr_storage src;
+ struct sockaddr_storage dst;
+ conn_pool_fd_t fd;
+ knot_time_t last_active;
+} conn_pool_memb_t;
+
+typedef struct {
+ size_t capacity;
+ size_t usage;
+ knot_timediff_t timeout;
+ pthread_mutex_t mutex;
+ pthread_t closing_thread;
+ conn_pool_close_cb_t close_cb;
+ conn_pool_invalid_cb_t invalid_cb;
+ conn_pool_memb_t conns[];
+} conn_pool_t;
+
+extern conn_pool_t *global_conn_pool;
+extern conn_pool_t *global_sessticket_pool; // pool for outgoing QUIC connection session tickets
+
+/*!
+ * \brief Allocate connection pool.
+ *
+ * \param capacity Connection pool capacity (must be positive number).
+ * \param timeout Connection timeout (must be positive number).
+ * \param close_cb Callback for closing fd.
+ * \param invalid_cb Callback detecting if given fd is already unusable.
+ *
+ * \return Connection pool or NULL if error.
+ */
+conn_pool_t *conn_pool_init(size_t capacity, knot_timediff_t timeout,
+ conn_pool_close_cb_t close_cb,
+ conn_pool_invalid_cb_t invalid_cb);
+
+/*!
+ * \brief Deallocate the pool, close all connections, terminate closing thread.
+ *
+ * \param pool Connection pool.
+ */
+void conn_pool_deinit(conn_pool_t *pool);
+
+/*!
+ * \brief Get and/or set connection timeout.
+ *
+ * \param pool Connection pool.
+ * \param new_timeout Optional: set new timeout (if positive number).
+ *
+ * \return Previous value of timeout.
+ */
+knot_timediff_t conn_pool_timeout(conn_pool_t *pool,
+ knot_timediff_t new_timeout);
+
+/*!
+ * \brief Try to get an open connection if present, check if alive.
+ *
+ * \param pool Pool to search in.
+ * \param src Connection source address.
+ * \param dst Connection destination address.
+ *
+ * \retval -1 If error (no such connection).
+ * \return >= 0 File descriptor of the connection.
+ */
+conn_pool_fd_t conn_pool_get(conn_pool_t *pool,
+ const struct sockaddr_storage *src,
+ const struct sockaddr_storage *dst);
+
+/*!
+ * \brief Put an open connection to the pool, possibly displacing the oldest one there.
+ *
+ * \param pool Pool to insert into.
+ * \param src Connestion source address.
+ * \param dst Connection destination adress.
+ * \param fd Connection file descriptor.
+ *
+ * \retval -1 If connection stored to free slot.
+ * \retval fd If not able to store connection.
+ * \return >= 0 File descriptor of the displaced old connection.
+ */
+conn_pool_fd_t conn_pool_put(conn_pool_t *pool,
+ const struct sockaddr_storage *src,
+ const struct sockaddr_storage *dst,
+ conn_pool_fd_t fd);
+
+/*!
+ * \brief Default close callback calling close() on given fd.
+ */
+void conn_pool_close_cb_dflt(conn_pool_fd_t fd);
+
+/*!
+ * \brief Default invalidness callback detecting socket not ready to write.
+ */
+bool conn_pool_invalid_cb_dflt(conn_pool_fd_t fd);
+
+/*!
+ * \brief Default invalidness callback always reporting valid fd.
+ */
+bool conn_pool_invalid_cb_allvalid(conn_pool_fd_t fd);