]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic-sock: provide a pair of get_src/get_dst functions
authorWilly Tarreau <w@1wt.eu>
Mon, 11 Apr 2022 14:20:00 +0000 (16:20 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 11 Apr 2022 17:33:04 +0000 (19:33 +0200)
These functions will allow the connection layer to retrieve a quic_conn's
source or destination when possible. The quic_conn holds the peer's address
but not the local one, and the sockets API doesn't always makes that easy
for datagrams. Thus for frontend connection what we're doing here is to
retrieve the listener's address when the destination address is desired.

Now it finally becomes possible to fetch the source and destination using
"src" and "dst", and to pass an incoming connection's endpoints via the
proxy protocol.

include/haproxy/quic_sock.h
src/proto_quic.c
src/quic_sock.c

index 055818d2afd33ddd34431a500f9ec68dfaefbe81..3e3edd26707d0212702f6e2eb5872281deb20449 100644 (file)
@@ -35,6 +35,8 @@
 #include <haproxy/quic_sock-t.h>
 
 int quic_session_accept(struct connection *cli_conn);
+int quic_sock_get_src(struct connection *conn, struct sockaddr *addr, socklen_t len);
+int quic_sock_get_dst(struct connection *conn, struct sockaddr *addr, socklen_t len);
 int quic_sock_accepting_conn(const struct receiver *rx);
 struct connection *quic_sock_accept_conn(struct listener *l, int *status);
 void quic_sock_fd_iocb(int fd);
index dd37c7655c0c9bd9a182febe2969203120af06a5..b7d50df36d7bc0970e2763bdeccdd4b11ee4bc35 100644 (file)
@@ -75,6 +75,8 @@ struct protocol proto_quic4 = {
        .suspend        = default_suspend_listener,
        .resume         = default_resume_listener,
        .accept_conn    = quic_sock_accept_conn,
+       .get_src        = quic_sock_get_src,
+       .get_dst        = quic_sock_get_dst,
        .connect        = quic_connect_server,
 
        /* binding layer */
@@ -113,6 +115,8 @@ struct protocol proto_quic6 = {
        .suspend        = default_suspend_listener,
        .resume         = default_resume_listener,
        .accept_conn    = quic_sock_accept_conn,
+       .get_src        = quic_sock_get_src,
+       .get_dst        = quic_sock_get_dst,
        .connect        = quic_connect_server,
 
        /* binding layer */
index 8086ff65a60baf07edc1c37950a8636e21ca6a61..022cd54694589fc82eb1fc4d0638eae237fe1385 100644 (file)
@@ -84,6 +84,54 @@ int quic_session_accept(struct connection *cli_conn)
        return -1;
 }
 
+/* Retrieve a connection's source address. Returns -1 on failure. */
+int quic_sock_get_src(struct connection *conn, struct sockaddr *addr, socklen_t len)
+{
+       struct quic_conn *qc;
+
+       if (!conn || !conn->qc)
+               return -1;
+
+       qc = conn->qc;
+       if (conn_is_back(conn)) {
+               /* no source address defined for outgoing connections for now */
+               return -1;
+       } else {
+               /* front connection, return the peer's address */
+               if (len > sizeof(qc->peer_addr))
+                       len = sizeof(qc->peer_addr);
+               memcpy(addr, &qc->peer_addr, len);
+               return 0;
+       }
+}
+
+/* Retrieve a connection's destination address. Returns -1 on failure. */
+int quic_sock_get_dst(struct connection *conn, struct sockaddr *addr, socklen_t len)
+{
+       struct quic_conn *qc;
+
+       if (!conn || !conn->qc)
+               return -1;
+
+       qc = conn->qc;
+       if (conn_is_back(conn)) {
+               /* back connection, return the peer's address */
+               if (len > sizeof(qc->peer_addr))
+                       len = sizeof(qc->peer_addr);
+               memcpy(addr, &qc->peer_addr, len);
+       } else {
+               /* FIXME: front connection, no local address for now, we'll
+                * return the listener's address instead.
+                */
+               BUG_ON(!qc->li);
+
+               if (len > sizeof(qc->li->rx.addr))
+                       len = sizeof(qc->li->rx.addr);
+               memcpy(addr, &qc->li->rx.addr, len);
+       }
+       return 0;
+}
+
 /*
  * Inspired from session_accept_fd().
  * Instantiate a new connection (connection struct) to be attached to <qc>