From 246f976ef95b3d08f08c4496dea7f1663ae4a337 Mon Sep 17 00:00:00 2001 From: Kristof Provost Date: Wed, 18 Dec 2024 17:10:29 +0100 Subject: [PATCH] if_ovpn: improve reconnect handling When a DCO client reconnects (e.g. on server restart) OpenVPN may create a new socket rather than reusing the existing one. This used to be rejected because we expect all peers to use the same socket. However, if there are no peers it's safe to release the previous socket and install the tunnel function on the new one. See also: https://redmine.pfsense.org/issues/15928 MFC after: 2 weeks Sponsored by: Rubicon Communications, LLC ("Netgate") (cherry picked from commit 3624de5394991c0cacd42d5a3b33e35c1a002e09) --- sys/net/if_ovpn.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/sys/net/if_ovpn.c b/sys/net/if_ovpn.c index be75eff74d3..de792098102 100644 --- a/sys/net/if_ovpn.c +++ b/sys/net/if_ovpn.c @@ -628,8 +628,20 @@ ovpn_new_peer(struct ifnet *ifp, const nvlist_t *nvl) } /* Must be the same socket as for other peers on this interface. */ - if (sc->so != NULL && so != sc->so) - goto error_locked; + if (sc->so != NULL && so != sc->so) { + if (! RB_EMPTY(&sc->peers)) { + ret = EBUSY; + goto error_locked; + } + + /* + * If we have no peers we can safely release the socket and accept + * a new one. + */ + ret = udp_set_kernel_tunneling(sc->so, NULL, NULL, NULL); + sorele(sc->so); + sc->so = NULL; + } if (sc->so == NULL) sc->so = so;