[Openvpn-devel,3/2] port-share: Add unix-socket and udp support for proxy protocol

Message ID 27c62e07-1f28-4e2a-b68d-32963f6d6da9@gmx.de
State Superseded
Headers show
Series proxy protocol v2 for port-share | expand

Commit Message

corubba Dec. 14, 2024, 11:21 p.m. UTC
Subject: [PATCH 3/3] port-share: Add unix-socket and udp support for proxy
 protocol v2

Just in case it is ever needed.

Signed-off-by: corubba <corubba@gmx.de>
---
 src/openvpn/ps.c     | 42 +++++++++++++++++++++++++++++++++++-------
 src/openvpn/socket.h |  1 +
 2 files changed, 36 insertions(+), 7 deletions(-)

--
2.47.1

Patch

diff --git a/src/openvpn/ps.c b/src/openvpn/ps.c
index b5d04c5b..b34df315 100644
--- a/src/openvpn/ps.c
+++ b/src/openvpn/ps.c
@@ -400,18 +400,19 @@  journal_add(const char *journal_dir, struct proxy_connection *pc, struct proxy_c
 static void
 send_proxy_protocol_v2_header(const struct proxy_connection *const pc, const struct proxy_connection *const cp)
 {
-    static const uint8_t PP2_AF_UNSPEC = 0x0, PP2_AF_INET = 0x1, PP2_AF_INET6 = 0x2;
-    static const uint8_t PP2_PROTO_STREAM = 0x1;
+    static const uint8_t PP2_AF_UNSPEC = 0x0, PP2_AF_INET = 0x1, PP2_AF_INET6 = 0x2, PP2_AF_UNIX = 0x3;
+    static const uint8_t PP2_PROTO_UNSPEC = 0x0, PP2_PROTO_STREAM = 0x1, PP2_PROTO_DGRAM = 0x2;

     struct openvpn_sockaddr src, dst;
-    socklen_t src_len, dst_len;
-    unsigned char header[52] = {
+    socklen_t src_len, dst_len, socket_type_len;
+    unsigned char header[232] = {
         "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A" /* signature */
         "\x21" /* version=2 + command=proxy */
         /* initialize the rest to zero for now */
     };
-    uint8_t addr_fam, header_len = 16;
+    uint8_t addr_fam, proto, header_len = 16;
     uint16_t addr_len;
+    int socket_type;

     src_len = sizeof(src.addr);
     dst_len = sizeof(dst.addr);
@@ -467,7 +468,14 @@  send_proxy_protocol_v2_header(const struct proxy_connection *const pc, const str
             memcpy(&header[50], &dst.addr.in6.sin6_port, sizeof(dst.addr.in6.sin6_port));
             break;

-        /* AF_UNIX is currently not suppported by OpenVPN */
+        case AF_UNIX:
+            addr_fam = PP2_AF_UNIX;
+            addr_len = 216;
+            ASSERT(108 >= sizeof(src.addr.un.sun_path));
+            ASSERT(108 >= sizeof(dst.addr.un.sun_path));
+            memcpy(&header[16], &src.addr.un.sun_path, 108);
+            memcpy(&header[124], &dst.addr.un.sun_path, 108);
+            break;

         default:
             addr_fam = PP2_AF_UNSPEC;
@@ -475,7 +483,27 @@  send_proxy_protocol_v2_header(const struct proxy_connection *const pc, const str
             break;
     }

-    const uint8_t proto = PP2_PROTO_STREAM; /* DGRAM is currently not supported by port-share */
+    socket_type_len = sizeof(socket_type);
+    if (0 != getsockopt(pc->sd, SOL_SOCKET, SO_TYPE, &socket_type, &socket_type_len))
+    {
+        msg(M_WARN, "PORT SHARE PROXY: getting socket type failed");
+        socket_type = -1; /* fallback to unspec */
+    }
+    switch (socket_type)
+    {
+        case SOCK_STREAM:
+            proto = PP2_PROTO_STREAM;
+            break;
+
+        case SOCK_DGRAM:
+            proto = PP2_PROTO_DGRAM;
+            break;
+
+        default:
+            proto = PP2_PROTO_UNSPEC;
+            break;
+    }
+
     header[13] = (addr_fam << 4) | proto;

     /* TLV is currently not implemented */
diff --git a/src/openvpn/socket.h b/src/openvpn/socket.h
index 465d92ba..3578b3c3 100644
--- a/src/openvpn/socket.h
+++ b/src/openvpn/socket.h
@@ -69,6 +69,7 @@  struct openvpn_sockaddr
         struct sockaddr sa;
         struct sockaddr_in in4;
         struct sockaddr_in6 in6;
+        struct sockaddr_un un;
     } addr;
 };