From eae8f9a666ce0b8e59deb1b5fa335e892d136df0 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 5 Dec 2018 22:39:04 +0000 Subject: [PATCH 1/2] Try to SO_REUSEPORT on UNIX platforms --- src/yggdrasil/multicast.go | 6 +++++- src/yggdrasil/multicast_other.go | 9 +++++++++ src/yggdrasil/multicast_unix.go | 22 ++++++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 src/yggdrasil/multicast_other.go create mode 100644 src/yggdrasil/multicast_unix.go diff --git a/src/yggdrasil/multicast.go b/src/yggdrasil/multicast.go index 697744cb..749dfcdb 100644 --- a/src/yggdrasil/multicast.go +++ b/src/yggdrasil/multicast.go @@ -1,6 +1,7 @@ package yggdrasil import ( + "context" "fmt" "net" "time" @@ -35,7 +36,10 @@ func (m *multicast) start() error { return err } listenString := fmt.Sprintf("[::]:%v", addr.Port) - conn, err := net.ListenPacket("udp6", listenString) + lc := net.ListenConfig{ + Control: multicastReuse, + } + conn, err := lc.ListenPacket(context.Background(), "udp6", listenString) if err != nil { return err } diff --git a/src/yggdrasil/multicast_other.go b/src/yggdrasil/multicast_other.go new file mode 100644 index 00000000..98fe2df1 --- /dev/null +++ b/src/yggdrasil/multicast_other.go @@ -0,0 +1,9 @@ +// +build !linux,!darwin,!netbsd,!freebsd,!openbsd,!dragonflybsd + +package yggdrasil + +import "syscall" + +func multicastReuse(network string, address string, c syscall.RawConn) error { + return nil +} diff --git a/src/yggdrasil/multicast_unix.go b/src/yggdrasil/multicast_unix.go new file mode 100644 index 00000000..9c6d1f11 --- /dev/null +++ b/src/yggdrasil/multicast_unix.go @@ -0,0 +1,22 @@ +// +build linux darwin netbsd freebsd openbsd dragonflybsd + +package yggdrasil + +import "syscall" +import "golang.org/x/sys/unix" + +func multicastReuse(network string, address string, c syscall.RawConn) error { + var control error + var reuseport error + + control = c.Control(func(fd uintptr) { + reuseport = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEPORT, 1) + }) + + switch { + case reuseport != nil: + return reuseport + default: + return control + } +} From ae48a1721e665c7cc4213cca7d93748301bd702f Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 5 Dec 2018 23:10:50 +0000 Subject: [PATCH 2/2] Try to SO_REUSEADDR on Windows --- src/yggdrasil/multicast_other.go | 2 +- src/yggdrasil/multicast_windows.go | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 src/yggdrasil/multicast_windows.go diff --git a/src/yggdrasil/multicast_other.go b/src/yggdrasil/multicast_other.go index 98fe2df1..8a4ce56c 100644 --- a/src/yggdrasil/multicast_other.go +++ b/src/yggdrasil/multicast_other.go @@ -1,4 +1,4 @@ -// +build !linux,!darwin,!netbsd,!freebsd,!openbsd,!dragonflybsd +// +build !linux,!darwin,!netbsd,!freebsd,!openbsd,!dragonflybsd,!windows package yggdrasil diff --git a/src/yggdrasil/multicast_windows.go b/src/yggdrasil/multicast_windows.go new file mode 100644 index 00000000..13f20315 --- /dev/null +++ b/src/yggdrasil/multicast_windows.go @@ -0,0 +1,22 @@ +// +build windows + +package yggdrasil + +import "syscall" +import "golang.org/x/sys/windows" + +func multicastReuse(network string, address string, c syscall.RawConn) error { + var control error + var reuseaddr error + + control = c.Control(func(fd uintptr) { + reuseaddr = windows.SetsockoptInt(windows.Handle(fd), windows.SOL_SOCKET, windows.SO_REUSEADDR, 1) + }) + + switch { + case reuseaddr != nil: + return reuseaddr + default: + return control + } +}