From 8d8405475d4f179074e4129dcc7fcd9b50214d34 Mon Sep 17 00:00:00 2001 From: Aleksandr Razumov Date: Mon, 13 May 2019 21:14:34 +0300 Subject: [PATCH] cli: fallback while trying reuseport --- internal/cli/run.go | 19 +++++++++++++++---- internal/cli/run_test.go | 4 ++-- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/internal/cli/run.go b/internal/cli/run.go index e0af62a..c36e4e9 100644 --- a/internal/cli/run.go +++ b/internal/cli/run.go @@ -31,7 +31,7 @@ import ( ) // ListenUDPAndServe listens on laddr and process incoming packets. -func ListenUDPAndServe(serverNet, laddr string, u *server.Updater) error { +func ListenUDPAndServe(log *zap.Logger, serverNet, laddr string, u *server.Updater) error { var ( c net.PacketConn err error @@ -39,6 +39,17 @@ func ListenUDPAndServe(serverNet, laddr string, u *server.Updater) error { opt := u.Get() if reuseport.Available() && opt.ReusePort { c, err = reuseport.ListenPacket(serverNet, laddr) + if err != nil { + // Trying to listen without reuseport. + // Sometimes reuseport.Available() can be true, but for subset + // of interfaces it is not available. + reusePortErr := err + c, err = net.ListenPacket(serverNet, laddr) + if err == nil { + opt.ReusePort = false + log.Warn("failed to use REUSEPORT, falling back to non-reuseport", zap.Error(reusePortErr)) + } + } } else { c, err = net.ListenPacket(serverNet, laddr) } @@ -338,7 +349,7 @@ func protocolNotSupported(err error) bool { return false } -func runRoot(v *viper.Viper, listenFunc func(serverNet, laddr string, u *server.Updater) error) { +func runRoot(v *viper.Viper, listenFunc func(log *zap.Logger, serverNet, laddr string, u *server.Updater) error) { l := getLogger(v) wg := new(sync.WaitGroup) listeners := getListeners(v, l) @@ -348,7 +359,7 @@ func runRoot(v *viper.Viper, listenFunc func(serverNet, laddr string, u *server. defer wg.Done() lg := l.With(zap.String("addr", ln.adrr), zap.String("network", "udp")) lg.Info("gortc/gortcd listening") - if err := listenFunc(ln.net, ln.adrr, ln.u); err != nil { + if err := listenFunc(lg, ln.net, ln.adrr, ln.u); err != nil { if ln.fromAny && protocolNotSupported(err) { // See https://github.com/gortc/gortcd/issues/32 // Should be ok to make it non configurable. @@ -362,7 +373,7 @@ func runRoot(v *viper.Viper, listenFunc func(serverNet, laddr string, u *server. wg.Wait() } -func getRoot(v *viper.Viper, listenFunc func(serverNet, laddr string, u *server.Updater) error) *cobra.Command { +func getRoot(v *viper.Viper, listenFunc func(log *zap.Logger, serverNet, laddr string, u *server.Updater) error) *cobra.Command { cmd := &cobra.Command{ Use: "gortcd", Short: "gortcd is STUN and TURN server", diff --git a/internal/cli/run_test.go b/internal/cli/run_test.go index 76c14fc..1c69784 100644 --- a/internal/cli/run_test.go +++ b/internal/cli/run_test.go @@ -191,7 +191,7 @@ func TestGetListeners(t *testing.T) { func TestRootRun(t *testing.T) { t.Run("Listen by flag", func(t *testing.T) { v := getViper() - cmd := getRoot(v, func(serverNet, laddr string, u *server.Updater) error { + cmd := getRoot(v, func(log *zap.Logger, serverNet, laddr string, u *server.Updater) error { if laddr != "127.0.0.1:0" { t.Errorf("unexpected laddr %q", laddr) } @@ -210,7 +210,7 @@ func TestRootRun(t *testing.T) { "127.0.0.1:12111": false, "127.0.0.1:12112": false, } - cmd := getRoot(v, func(serverNet, laddr string, u *server.Updater) error { + cmd := getRoot(v, func(log *zap.Logger, serverNet, laddr string, u *server.Updater) error { mux.Lock() defer mux.Unlock() if addrMet[laddr] {