[Openvpn-devel,v2,1/2] port-share: Normalize IPv4-mapped IPv6 addresses

Message ID b16cab79-188f-41a3-af32-f944a387400f@gmx.de
State New
Headers show
Series [Openvpn-devel,v2,1/2] port-share: Normalize IPv4-mapped IPv6 addresses | expand

Commit Message

corubba Dec. 16, 2024, 12:22 p.m. UTC
Before passing IPv4-mapped IPv6 addresses to the proxy journal,
translate them to plain IPv4 addresses. Whether the connection was
accepted by OpenVPN on a "dual stack" socket is of no importance to the
proxy receiver.

Signed-off-by: Corubba Smith <corubba@gmx.de>
---
 src/openvpn/ps.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

--
2.47.1

Patch

diff --git a/src/openvpn/ps.c b/src/openvpn/ps.c
index 06bf91a8..36ea63b8 100644
--- a/src/openvpn/ps.c
+++ b/src/openvpn/ps.c
@@ -330,6 +330,22 @@  proxy_list_housekeeping(struct proxy_connection **list)
     }
 }

+/*
+ * In-place transformation of an openvpn_sockaddr with an IPv4-mapped IPv6
+ * address to one with a plain IPv4 address. No-op otherwise.
+ */
+static void
+transform_mapped_v4_sockaddr(struct openvpn_sockaddr *sock)
+{
+    if (sock->addr.sa.sa_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&sock->addr.in6.sin6_addr))
+    {
+        sock->addr.in4.sin_family = AF_INET;
+        /* sin_port and sin6_port are the same already */
+        memcpy(&sock->addr.in4.sin_addr, &sock->addr.in6.sin6_addr.s6_addr[12], 4);
+        memset(&sock->addr.in4 + 1, 0, sizeof(sock->addr) - sizeof(sock->addr.in4));
+    }
+}
+
 /*
  * Record IP/port of client in filesystem, so that server receiving
  * the proxy can determine true client origin.
@@ -349,6 +365,8 @@  journal_add(const char *journal_dir, struct proxy_connection *pc, struct proxy_c
     if (!getpeername(pc->sd, (struct sockaddr *) &from.addr.sa, &slen)
         && !getsockname(cp->sd, (struct sockaddr *) &to.addr.sa, &dlen))
     {
+        transform_mapped_v4_sockaddr(&from);
+        transform_mapped_v4_sockaddr(&to);
         const char *f = print_openvpn_sockaddr(&from, &gc);
         const char *t = print_openvpn_sockaddr(&to, &gc);
         fnlen =  strlen(journal_dir) + strlen(t) + 2;