]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: protocol: add get_src() and get_dst() at the protocol level
authorWilly Tarreau <w@1wt.eu>
Fri, 8 Apr 2022 11:49:17 +0000 (13:49 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 11 Apr 2022 17:33:04 +0000 (19:33 +0200)
Right now the proto_fam descriptor provides a family-specific
get_src() and get_dst() pair of calls to retrieve a socket's source
or destination address. However this only works for connected mode
sockets. QUIC provides its own stream protocol, which relies on a
datagram protocol underneath, so the get_src()/get_dst() at that
protocol's family will not work, and QUIC would need to provide its
own.

This patch implements get_src() and get_dst() at the protocol level
from a connection, and makes sure that conn_get_src()/conn_get_dst()
will automatically use them if defined before falling back to the
family's pair of functions.

include/haproxy/connection.h
include/haproxy/protocol-t.h

index 098bc9cb097405c615e00eca8d7ca265c7196863..1d200308f0bd0e8169498e798031e7f9779a0325 100644 (file)
@@ -354,6 +354,11 @@ static inline int conn_get_src(struct connection *conn)
        if (!sockaddr_alloc(&conn->src, NULL, 0))
                goto fail;
 
+       /* some stream protocols may provide their own get_src/dst functions */
+       if (conn->ctrl->get_src &&
+           conn->ctrl->get_src(conn, (struct sockaddr *)conn->src, sizeof(*conn->src)) != -1)
+               goto done;
+
        if (conn->ctrl->proto_type != PROTO_TYPE_STREAM)
                goto fail;
 
@@ -388,6 +393,11 @@ static inline int conn_get_dst(struct connection *conn)
        if (!sockaddr_alloc(&conn->dst, NULL, 0))
                goto fail;
 
+       /* some stream protocols may provide their own get_src/dst functions */
+       if (conn->ctrl->get_dst &&
+           conn->ctrl->get_dst(conn, (struct sockaddr *)conn->dst, sizeof(*conn->dst)) != -1)
+               goto done;
+
        if (conn->ctrl->proto_type != PROTO_TYPE_STREAM)
                goto fail;
 
index 895ad3bc53af74011ebeb9c6fedd500bb9908185..8f51a7a51ca6c82109d9ffabee1946244b10d9ac 100644 (file)
@@ -75,8 +75,8 @@ struct proto_fam {
        int l3_addrlen;                                 /* layer3 address length, used by hashes */
        int (*addrcmp)(const struct sockaddr_storage *, const struct sockaddr_storage *); /* compare addresses (like memcmp) */
        int (*bind)(struct receiver *rx, char **errmsg); /* bind a receiver */
-       int (*get_src)(int fd, struct sockaddr *, socklen_t, int dir); /* syscall used to retrieve src addr */
-       int (*get_dst)(int fd, struct sockaddr *, socklen_t, int dir); /* syscall used to retrieve dst addr */
+       int (*get_src)(int fd, struct sockaddr *, socklen_t, int dir); /* syscall used to retrieve connection's src addr */
+       int (*get_dst)(int fd, struct sockaddr *, socklen_t, int dir); /* syscall used to retrieve connection's dst addr */
        void (*set_port)(struct sockaddr_storage *, int port);  /* set the port on the address; NULL if not implemented */
 };
 
@@ -103,6 +103,7 @@ struct protocol {
        int (*suspend)(struct listener *l);             /* try to suspend the listener */
        int (*resume)(struct listener *l);              /* try to resume a suspended listener */
        struct connection *(*accept_conn)(struct listener *l, int *status); /* accept a new connection */
+
        /* functions acting on connections */
        void (*ctrl_init)(struct connection *);         /* completes initialization of the connection */
        void (*ctrl_close)(struct connection *);        /* completes release of the connection */
@@ -110,6 +111,8 @@ struct protocol {
        int (*drain)(struct connection *);              /* drain pending data; 0=failed, >0=success */
        int (*check_events)(struct connection *conn, int event_type);  /* subscribe to socket events */
        void (*ignore_events)(struct connection *conn, int event_type);  /* unsubscribe from socket events */
+       int (*get_src)(struct connection *conn, struct sockaddr *, socklen_t); /* retrieve connection's source address; -1=fail */
+       int (*get_dst)(struct connection *conn, struct sockaddr *, socklen_t); /* retrieve connection's dest address; -1=fail */
 
        /* functions acting on the receiver */
        int (*rx_suspend)(struct receiver *rx);         /* temporarily suspend this receiver for a soft restart */