From ff5d57b02250f6c26cfb622cf253c58fed2f6a84 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Wed, 17 Jul 2019 18:37:02 +0200 Subject: [PATCH] MINOR: connection: create a new pool for struct sockaddr_storage This pool will be used to allocate storage for source and destination addresses used in connections. Two functions sockaddr_{alloc,free}() were added and will have to be used everywhere an address is needed. These ones are safe for progressive replacement as they check that the existing pointer is set before replacing it. The pool is not yet used during allocation nor freeing. Also they operate on pointers to pointers so they will perform checks and replace values. The free one nulls the pointer. --- include/proto/connection.h | 32 ++++++++++++++++++++++++++++++++ src/connection.c | 1 + 2 files changed, 33 insertions(+) diff --git a/include/proto/connection.h b/include/proto/connection.h index a55f7a231..c1ce51d22 100644 --- a/include/proto/connection.h +++ b/include/proto/connection.h @@ -34,6 +34,7 @@ extern struct pool_head *pool_head_connection; extern struct pool_head *pool_head_connstream; +extern struct pool_head *pool_head_sockaddr; extern struct xprt_ops *registered_xprt[XPRT_ENTRIES]; extern struct mux_proto_list mux_proto_list; @@ -491,6 +492,37 @@ static inline void conn_clear_xprt_done_cb(struct connection *conn) conn->xprt_done_cb = NULL; } +/* Allocates a struct sockaddr from the pool if needed, assigns it to *sap and + * returns it. If is NULL, the address is always allocated and returned. + * if is non-null, an address will only be allocated if it points to a + * non-null pointer. In this case the allocated address will be assigned there. + * In both situations the new pointer is returned. + */ +static inline struct sockaddr_storage *sockaddr_alloc(struct sockaddr_storage **sap) +{ + struct sockaddr_storage *sa; + + if (sap && *sap) + return *sap; + + sa = pool_alloc(pool_head_sockaddr); + if (sap) + *sap = sa; + return sa; +} + +/* Releases the struct sockaddr potentially pointed to by to the pool. It + * may be NULL or may point to NULL. If is not NULL, a NULL is placed + * there. + */ +static inline void sockaddr_free(struct sockaddr_storage **sap) +{ + if (!sap) + return; + pool_free(pool_head_sockaddr, *sap); + *sap = NULL; +} + /* Tries to allocate a new connection and initialized its main fields. The * connection is returned on success, NULL on failure. The connection must * be released using pool_free() or conn_free(). diff --git a/src/connection.c b/src/connection.c index eabeaa001..0277309ac 100644 --- a/src/connection.c +++ b/src/connection.c @@ -31,6 +31,7 @@ DECLARE_POOL(pool_head_connection, "connection", sizeof(struct connection)); DECLARE_POOL(pool_head_connstream, "conn_stream", sizeof(struct conn_stream)); +DECLARE_POOL(pool_head_sockaddr, "sockaddr", sizeof(struct sockaddr_storage)); struct xprt_ops *registered_xprt[XPRT_ENTRIES] = { NULL, };