diff --git a/include/haproxy/quic_sock.h b/include/haproxy/quic_sock.h index 055818d2a..3e3edd267 100644 --- a/include/haproxy/quic_sock.h +++ b/include/haproxy/quic_sock.h @@ -35,6 +35,8 @@ #include 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); diff --git a/src/proto_quic.c b/src/proto_quic.c index dd37c7655..b7d50df36 100644 --- a/src/proto_quic.c +++ b/src/proto_quic.c @@ -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 */ diff --git a/src/quic_sock.c b/src/quic_sock.c index 8086ff65a..022cd5469 100644 --- a/src/quic_sock.c +++ b/src/quic_sock.c @@ -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