From 987c08a5e2023ad3dffc9ff21701bc59e174d253 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Fri, 8 Apr 2022 18:05:41 +0200 Subject: [PATCH] MINOR: connection: rearrange conn_get_src/dst to be a bit more extensible We'll want conn_get_src/dst to support other means of retrieving these respective IP addresses, but the functions as they're designed are a bit too restrictive for now. This patch arranges them to have a default error fallback allowing to test different mechanisms. In addition we now make sure the underlying protocol is of type stream before calling the family's get_src/dst as it makes no sense to do that on dgram sockets for example. --- include/haproxy/connection.h | 40 +++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/include/haproxy/connection.h b/include/haproxy/connection.h index bc26f73b5..098bc9cb0 100644 --- a/include/haproxy/connection.h +++ b/include/haproxy/connection.h @@ -348,17 +348,27 @@ static inline int conn_get_src(struct connection *conn) if (conn->flags & CO_FL_ADDR_FROM_SET) return 1; - if (!conn_ctrl_ready(conn) || !conn->ctrl->fam->get_src) - return 0; + if (!conn_ctrl_ready(conn)) + goto fail; if (!sockaddr_alloc(&conn->src, NULL, 0)) - return 0; + goto fail; + if (conn->ctrl->proto_type != PROTO_TYPE_STREAM) + goto fail; + + /* most other socket-based stream protocols will use their socket family's functions */ if (conn->ctrl->fam->get_src && !(conn->flags & CO_FL_FDLESS) && conn->ctrl->fam->get_src(conn->handle.fd, (struct sockaddr *)conn->src, sizeof(*conn->src), - obj_type(conn->target) != OBJ_TYPE_LISTENER) == -1) - return 0; + obj_type(conn->target) != OBJ_TYPE_LISTENER) != -1) + goto done; + + /* no other means */ + fail: + sockaddr_free(&conn->src); + return 0; + done: conn->flags |= CO_FL_ADDR_FROM_SET; return 1; } @@ -372,17 +382,27 @@ static inline int conn_get_dst(struct connection *conn) if (conn->flags & CO_FL_ADDR_TO_SET) return 1; - if (!conn_ctrl_ready(conn) || !conn->ctrl->fam->get_dst) - return 0; + if (!conn_ctrl_ready(conn)) + goto fail; if (!sockaddr_alloc(&conn->dst, NULL, 0)) - return 0; + goto fail; + if (conn->ctrl->proto_type != PROTO_TYPE_STREAM) + goto fail; + + /* most other socket-based stream protocols will use their socket family's functions */ if (conn->ctrl->fam->get_dst && !(conn->flags & CO_FL_FDLESS) && conn->ctrl->fam->get_dst(conn->handle.fd, (struct sockaddr *)conn->dst, sizeof(*conn->dst), - obj_type(conn->target) != OBJ_TYPE_LISTENER) == -1) - return 0; + obj_type(conn->target) != OBJ_TYPE_LISTENER) != -1) + goto done; + + /* no other means */ + fail: + sockaddr_free(&conn->dst); + return 0; + done: conn->flags |= CO_FL_ADDR_TO_SET; return 1; }