openvpn icon indicating copy to clipboard operation
openvpn copied to clipboard

Listening on the same port on both TCP and UDP. (2.7alpha)

Open edthepurple opened this issue 7 months ago • 6 comments

Hello.

could someone please share how to do this?

I tried

proto tcp-server port 8443 topology subnet

proto udp port 8443 topology subnet

but didn't work. TCP/UDP: Socket bind failed on local address [AF_INET]xx.yy.zz.xx:8443: Address already in use (errno=98)

edthepurple avatar Jun 26 '25 00:06 edthepurple

You need to use multiple --local entries to configure multiple sockets. Please check the manpage about how to use it.

ordex avatar Jun 26 '25 06:06 ordex

I did check the manpage before opening an issue. but sadly there was no example and I couldn't figure it out.

edthepurple avatar Jun 26 '25 06:06 edthepurple

local * 8443 tcp
local * 8443 udp

cron2 avatar Jun 26 '25 07:06 cron2

Thank you so much.

edthepurple avatar Jun 26 '25 08:06 edthepurple

When doing this, openvpn crashes after a while with this being logged:

2025-06-28 16:27:19 tcp4-server:127.0.0.1:43998 Assertion failed at socket.h:823 (0) 2025-06-28 16:27:19 tcp4-server:127.0.0.1:43998 Exiting due to fatal error

edthepurple avatar Jun 28 '25 18:06 edthepurple

This is interesting, and it doesn't crash for me...

Can you share some additional log lines, with verb 4? I guess this is an incoming session which is not speaking proper OpenVPN protocol, so ends up messing up some data structures.

Socket.h line 823 is this

static inline bool
addr_port_match(const struct openvpn_sockaddr *a1, const struct openvpn_sockaddr *a2)
{
    switch (a1->addr.sa.sa_family)
    {
        case AF_INET:
            return a1->addr.in4.sin_addr.s_addr == a2->addr.in4.sin_addr.s_addr
                   && a1->addr.in4.sin_port == a2->addr.in4.sin_port;
 
        case AF_INET6:
            return IN6_ARE_ADDR_EQUAL(&a1->addr.in6.sin6_addr, &a2->addr.in6.sin6_addr)
                   && a1->addr.in6.sin6_port == a2->addr.in6.sin6_port;
    }
    ASSERT(0);
    return false;

so this basically compares incoming packets/connections to the "something already existing", and the ASSERT(0) is "it is not IPv4 and not IPv6 but we don't really know what to do now".

This is clearly a bug (thanks), we just need to know how to trigger it, and then we can fix it.

Copying in @ordex and @itsGiaan because the multisocket code is their baby.

cron2 avatar Jun 28 '25 18:06 cron2

I will attach the log with verb 4 once it crashes again. in the meantime, let me give a little bit more info.

in addition to this, on a server listening on the same port on both protocols using 2 local directives; sometimes (appears random) TCP clients disconnect with "connection reset" being logged on their side, and it immediately reconnects, then immediately disconnect and this loop continues for as long as it wants to (all the client sees is dozens of "PUSH_REQUEST"s being logged; and the udp on the same openvpn instance stays stable.

it may be unrelated but I'm using this https://github.com/fac/auth-script-openvpn/ for authentication (against a mysql server) because auth-user-pass-verify causes everyone to experience packet loss/timeout when someone else is authenticating.

edthepurple avatar Jun 29 '25 06:06 edthepurple

one more thing, with the same version and same authentication plugin, it doesn't crash when tcp and udp are seperated into different openvpn instances so it may be definetely related to the multi socket feature.

edthepurple avatar Jun 29 '25 11:06 edthepurple

openvpn.log

here's openvpn.log after a similar crash with verb 4

edthepurple avatar Jun 29 '25 12:06 edthepurple

@edthepurple, would you mind sharing your config files?

itsGiaan avatar Jun 30 '25 08:06 itsGiaan

script-security 3

local * 8443 udp local * 8443 tcp

server 10.8.0.0 255.255.252.0

keepalive 10 90 float

dev tun0 auth SHA256

dh /etc/openvpn/keys/dh.pem ca /etc/openvpn/keys/ca.crt cert /etc/openvpn/easy-rsa/pki/issued/EdVPN.crt key /etc/openvpn/easy-rsa/pki/private/EdVPN.key

status /etc/openvpn/log/status.log 1 status-version 2 log /etc/openvpn/log/openvpn.log verb 4

push "dhcp-option DNS 8.8.8.8" push "dhcp-option DISABLE-NBT" push "redirect-gateway def1"

username-as-common-name verify-client-cert none

plugin /usr/local/lib/openvpn/plugins/openvpn-plugin-auth-script.so /etc/openvpn/scripts/auth.sh

tun-mtu 1280 sndbuf 0 rcvbuf 0 reneg-sec 0

server-ipv6 2a01:4f8:c013:e7ac:eded::/112 push "redirect-gateway def1 bypass-dhcp" push "route-ipv6 2000::/3"

mute-replay-warnings persist-key persist-tun

edthepurple avatar Jun 30 '25 08:06 edthepurple

So this should be fixed with git master as of

commit fd93e4ad8245e1fd9530a6c1f89cb66c047f3abe Author: Gianmarco De Gregori Date: Fri Jul 18 20:55:53 2025 +0200

 Multi-socket: Fix assert triggered by stale peer-id reuse

to be relased as "2.7_alpha3" next week (at least that's the plan). @edthepurple can you test this and report whether you still see ASSERT()s?

cron2 avatar Jul 18 '25 19:07 cron2

So, 2.7_alpha3 release happened yesterday.

cron2 avatar Aug 01 '25 14:08 cron2

Hello and thank you for your contributions. I have installed the latest alpha build and it's been running for more than 12 hours without errors or abnormalities on a server with +500 users.

edthepurple avatar Aug 02 '25 13:08 edthepurple