From 8690d62146aabab8ac4f53e0c29cf515cfc650d0 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Fri, 31 Aug 2018 13:17:05 -0700 Subject: [PATCH] Allow fallback listen if first listener fails (#6380) On linux listen() uses kernel features TCP_FASTOPEN, DEFER_ACCEPT Fixes #6379 --- cmd/http/listen_nix.go | 7 +++++- cmd/http/listen_others.go | 1 + cmd/http/listener.go | 4 ++- cmd/http/listener_test.go | 53 ++++++++------------------------------- 4 files changed, 20 insertions(+), 45 deletions(-) diff --git a/cmd/http/listen_nix.go b/cmd/http/listen_nix.go index c6f6cb0da..0904e8df4 100644 --- a/cmd/http/listen_nix.go +++ b/cmd/http/listen_nix.go @@ -18,7 +18,11 @@ package http -import "github.com/valyala/tcplisten" +import ( + "net" + + "github.com/valyala/tcplisten" +) var cfg = &tcplisten.Config{ DeferAccept: true, @@ -27,3 +31,4 @@ var cfg = &tcplisten.Config{ // Unix listener with special TCP options. var listen = cfg.NewListener +var fallbackListen = net.Listen diff --git a/cmd/http/listen_others.go b/cmd/http/listen_others.go index d1d69fdf2..5216cc415 100644 --- a/cmd/http/listen_others.go +++ b/cmd/http/listen_others.go @@ -22,3 +22,4 @@ import "net" // Windows, plan9 specific listener. var listen = net.Listen +var fallbackListen = net.Listen diff --git a/cmd/http/listener.go b/cmd/http/listener.go index 82ad97c6b..7647f0345 100644 --- a/cmd/http/listener.go +++ b/cmd/http/listener.go @@ -404,7 +404,9 @@ func newHTTPListener(serverAddrs []string, for _, serverAddr := range serverAddrs { var l net.Listener if l, err = listen("tcp4", serverAddr); err != nil { - return nil, err + if l, err = fallbackListen("tcp4", serverAddr); err != nil { + return nil, err + } } tcpListener, ok := l.(*net.TCPListener) diff --git a/cmd/http/listener_test.go b/cmd/http/listener_test.go index d9ded6dbf..eef072438 100644 --- a/cmd/http/listener_test.go +++ b/cmd/http/listener_test.go @@ -20,12 +20,10 @@ import ( "bufio" "bytes" "crypto/tls" - "errors" "fmt" "io" "net" "net/http" - "runtime" "strconv" "strings" "sync" @@ -195,27 +193,6 @@ func TestIsHTTPMethod(t *testing.T) { } func TestNewHTTPListener(t *testing.T) { - errMsg := ": no such host" - - remoteAddrErrMsgIP := "cannot bind to \"93.184.216.34:65432\": cannot assign requested address" - if runtime.GOOS == "windows" { - remoteAddrErrMsgIP = "listen tcp 93.184.216.34:65432: bind: The requested address is not valid in its context." - } - remoteAddrErrMsgHost := "cannot bind to \"example.org:65432\": cannot assign requested address" - if runtime.GOOS == "windows" { - remoteAddrErrMsgHost = "listen tcp 93.184.216.34:65432: bind: The requested address is not valid in its context." - } - - remoteMissingErr := "address unknown-host: missing port in address" - if runtime.GOOS == "windows" { - remoteMissingErr = "listen tcp: address unknown-host: missing port in address" - } - - remoteUnknownErr := "lookup unknown-host" + errMsg - if runtime.GOOS == "windows" { - remoteUnknownErr = "listen tcp: lookup unknown-host" + errMsg - } - tlsConfig := getTLSConfig(t) testCases := []struct { @@ -226,16 +203,16 @@ func TestNewHTTPListener(t *testing.T) { writeTimeout time.Duration updateBytesReadFunc func(*http.Request, int) updateBytesWrittenFunc func(*http.Request, int) - expectedErr error + expectedErr bool }{ - {[]string{"93.184.216.34:65432"}, nil, time.Duration(0), time.Duration(0), time.Duration(0), nil, nil, errors.New(remoteAddrErrMsgIP)}, - {[]string{"example.org:65432"}, nil, time.Duration(0), time.Duration(0), time.Duration(0), nil, nil, errors.New(remoteAddrErrMsgHost)}, - {[]string{"unknown-host"}, nil, time.Duration(0), time.Duration(0), time.Duration(0), nil, nil, errors.New(remoteMissingErr)}, - {[]string{"unknown-host:65432"}, nil, time.Duration(0), time.Duration(0), time.Duration(0), nil, nil, errors.New(remoteUnknownErr)}, - {[]string{"localhost:65432", "93.184.216.34:65432"}, nil, time.Duration(0), time.Duration(0), time.Duration(0), nil, nil, errors.New(remoteAddrErrMsgIP)}, - {[]string{"localhost:65432", "unknown-host:65432"}, nil, time.Duration(0), time.Duration(0), time.Duration(0), nil, nil, errors.New(remoteUnknownErr)}, - {[]string{"localhost:0"}, nil, time.Duration(0), time.Duration(0), time.Duration(0), nil, nil, nil}, - {[]string{"localhost:0"}, tlsConfig, time.Duration(0), time.Duration(0), time.Duration(0), nil, nil, nil}, + {[]string{"93.184.216.34:65432"}, nil, time.Duration(0), time.Duration(0), time.Duration(0), nil, nil, true}, + {[]string{"example.org:65432"}, nil, time.Duration(0), time.Duration(0), time.Duration(0), nil, nil, true}, + {[]string{"unknown-host"}, nil, time.Duration(0), time.Duration(0), time.Duration(0), nil, nil, true}, + {[]string{"unknown-host:65432"}, nil, time.Duration(0), time.Duration(0), time.Duration(0), nil, nil, true}, + {[]string{"localhost:65432", "93.184.216.34:65432"}, nil, time.Duration(0), time.Duration(0), time.Duration(0), nil, nil, true}, + {[]string{"localhost:65432", "unknown-host:65432"}, nil, time.Duration(0), time.Duration(0), time.Duration(0), nil, nil, true}, + {[]string{"localhost:0"}, nil, time.Duration(0), time.Duration(0), time.Duration(0), nil, nil, false}, + {[]string{"localhost:0"}, tlsConfig, time.Duration(0), time.Duration(0), time.Duration(0), nil, nil, false}, } for _, testCase := range testCases { @@ -250,22 +227,12 @@ func TestNewHTTPListener(t *testing.T) { testCase.updateBytesWrittenFunc, ) - if testCase.expectedErr == nil { + if !testCase.expectedErr { if err != nil { t.Fatalf("error: expected = , got = %v", err) } } else if err == nil { t.Fatalf("error: expected = %v, got = ", testCase.expectedErr) - } else { - var match bool - if strings.HasSuffix(testCase.expectedErr.Error(), errMsg) { - match = strings.HasSuffix(err.Error(), errMsg) - } else { - match = (testCase.expectedErr.Error() == err.Error()) - } - if !match { - t.Fatalf("error: expected = %v, got = %v", testCase.expectedErr, err) - } } if err == nil {