Merge pull request #50669 from akerouanton/dont-reuseaddr-for-UDP

libnet/pa: don't set SO_REUSEADDR on UDP sockets
This commit is contained in:
Albin Kerouanton
2025-08-08 15:31:09 +02:00
committed by GitHub
2 changed files with 25 additions and 2 deletions

View File

@@ -122,8 +122,10 @@ func bindTCPOrUDP(addr netip.AddrPort, typ int, proto types.Protocol) (_ *os.Fil
}
}()
if err := syscall.SetsockoptInt(sd, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1); err != nil {
return nil, fmt.Errorf("failed to setsockopt(SO_REUSEADDR) for %s/%s: %w", addr, proto, err)
if proto == syscall.IPPROTO_TCP {
if err := syscall.SetsockoptInt(sd, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1); err != nil {
return nil, fmt.Errorf("failed to setsockopt(SO_REUSEADDR) for %s/%s: %w", addr, proto, err)
}
}
if domain == syscall.AF_INET6 {

View File

@@ -3,7 +3,9 @@ package portallocator
import (
"io"
"net"
"net/netip"
"os"
"syscall"
"testing"
"github.com/ishidawataru/sctp"
@@ -207,3 +209,22 @@ func TestRepeatAllocation(t *testing.T) {
})
}
}
func TestOnlyOneSocketBindsUDPPort(t *testing.T) {
const port = 5000
addr := netip.MustParseAddr("127.0.0.1")
// Simulate another process binding to the same UDP port.
f, err := bindTCPOrUDP(netip.AddrPortFrom(addr, port), syscall.SOCK_DGRAM, syscall.IPPROTO_UDP)
assert.NilError(t, err)
defer f.Close()
// Then try to allocate that port using the OSAllocator.
alloc := OSAllocator{allocator: newInstance()}
_, socks, err := alloc.RequestPortsInRange([]net.IP{addr.AsSlice()}, syscall.IPPROTO_UDP, port, port)
// In case RequestPortsInRange succeeded, close the sockets to not affect subsequent tests
defer closeSocks(t, socks)
assert.ErrorContains(t, err, "failed to bind host port")
assert.Equal(t, len(socks), 0)
}