Allow fallback listen if first listener fails (#6380)

On linux listen() uses kernel features TCP_FASTOPEN, DEFER_ACCEPT

Fixes #6379
master
Harshavardhana 6 years ago committed by kannappanr
parent 85117d554f
commit 8690d62146
  1. 7
      cmd/http/listen_nix.go
  2. 1
      cmd/http/listen_others.go
  3. 4
      cmd/http/listener.go
  4. 53
      cmd/http/listener_test.go

@ -18,7 +18,11 @@
package http package http
import "github.com/valyala/tcplisten" import (
"net"
"github.com/valyala/tcplisten"
)
var cfg = &tcplisten.Config{ var cfg = &tcplisten.Config{
DeferAccept: true, DeferAccept: true,
@ -27,3 +31,4 @@ var cfg = &tcplisten.Config{
// Unix listener with special TCP options. // Unix listener with special TCP options.
var listen = cfg.NewListener var listen = cfg.NewListener
var fallbackListen = net.Listen

@ -22,3 +22,4 @@ import "net"
// Windows, plan9 specific listener. // Windows, plan9 specific listener.
var listen = net.Listen var listen = net.Listen
var fallbackListen = net.Listen

@ -404,7 +404,9 @@ func newHTTPListener(serverAddrs []string,
for _, serverAddr := range serverAddrs { for _, serverAddr := range serverAddrs {
var l net.Listener var l net.Listener
if l, err = listen("tcp4", serverAddr); err != nil { 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) tcpListener, ok := l.(*net.TCPListener)

@ -20,12 +20,10 @@ import (
"bufio" "bufio"
"bytes" "bytes"
"crypto/tls" "crypto/tls"
"errors"
"fmt" "fmt"
"io" "io"
"net" "net"
"net/http" "net/http"
"runtime"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@ -195,27 +193,6 @@ func TestIsHTTPMethod(t *testing.T) {
} }
func TestNewHTTPListener(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) tlsConfig := getTLSConfig(t)
testCases := []struct { testCases := []struct {
@ -226,16 +203,16 @@ func TestNewHTTPListener(t *testing.T) {
writeTimeout time.Duration writeTimeout time.Duration
updateBytesReadFunc func(*http.Request, int) updateBytesReadFunc func(*http.Request, int)
updateBytesWrittenFunc 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{"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, errors.New(remoteAddrErrMsgHost)}, {[]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, errors.New(remoteMissingErr)}, {[]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, errors.New(remoteUnknownErr)}, {[]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, errors.New(remoteAddrErrMsgIP)}, {[]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, errors.New(remoteUnknownErr)}, {[]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, nil}, {[]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, nil}, {[]string{"localhost:0"}, tlsConfig, time.Duration(0), time.Duration(0), time.Duration(0), nil, nil, false},
} }
for _, testCase := range testCases { for _, testCase := range testCases {
@ -250,22 +227,12 @@ func TestNewHTTPListener(t *testing.T) {
testCase.updateBytesWrittenFunc, testCase.updateBytesWrittenFunc,
) )
if testCase.expectedErr == nil { if !testCase.expectedErr {
if err != nil { if err != nil {
t.Fatalf("error: expected = <nil>, got = %v", err) t.Fatalf("error: expected = <nil>, got = %v", err)
} }
} else if err == nil { } else if err == nil {
t.Fatalf("error: expected = %v, got = <nil>", testCase.expectedErr) t.Fatalf("error: expected = %v, got = <nil>", 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 { if err == nil {

Loading…
Cancel
Save