From d9879333e39afc1119a41c691176fff75344d6c5 Mon Sep 17 00:00:00 2001 From: maximvarentsov Date: Fri, 14 Aug 2026 15:51:22 +0200 Subject: [PATCH] Tunnel inbound: Share the fake UDP reply socket address on OpenBSD Every reply to a client is sent from a socket bound to the original destination with SO_BINDANY, and one such socket is created per session. Two clients talking to the same destination, two phones resolving over the same DNS server for instance, therefore bind the same address and port twice, and the second bind fails with EADDRINUSE, leaving that session without answers. SO_REUSEADDR does not help here: on OpenBSD it is only promoted to allow a duplicate binding for multicast addresses, so a unicast address needs SO_REUSEPORT on both sockets. The Linux implementation of FakeUDP already sets both options. --- proxy/dokodemo/fakeudp_openbsd.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/proxy/dokodemo/fakeudp_openbsd.go b/proxy/dokodemo/fakeudp_openbsd.go index 8fcbcbea931f..bb3ac7298b5f 100644 --- a/proxy/dokodemo/fakeudp_openbsd.go +++ b/proxy/dokodemo/fakeudp_openbsd.go @@ -35,6 +35,11 @@ func FakeUDP(addr *net.UDPAddr, mark int) (net.PacketConn, error) { if err = unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_REUSEADDR, 1); err != nil { return nil, &net.OpError{Op: "fake", Err: fmt.Errorf("set socket option SO_REUSEADDR: %w", err)} } + // Several client sessions can be answered from the same original + // destination at the same time, so the address has to be shareable. + if err = unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_REUSEPORT, 1); err != nil { + return nil, &net.OpError{Op: "fake", Err: fmt.Errorf("set socket option SO_REUSEPORT: %w", err)} + } sockaddr := &unix.SockaddrInet4{Port: addr.Port} copy(sockaddr.Addr[:], ip4)