fix: allow bind on ipv6 loopback failures (#16388)

This commit is contained in:
Allan Roger Reid 2023-01-10 19:17:39 -08:00 committed by GitHub
parent 1ece3d1dfe
commit 9815dac48f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 2 deletions

View File

@ -21,6 +21,7 @@ import (
"context"
"fmt"
"net"
"strings"
"syscall"
)
@ -136,20 +137,49 @@ func newHTTPListener(ctx context.Context, serverAddrs []string) (listener *httpL
}
}()
isLocalhost := false
for _, serverAddr := range serverAddrs {
host, _, err := net.SplitHostPort(serverAddr)
if err == nil {
if strings.EqualFold(host, "localhost") {
isLocalhost = true
}
}
}
// Silently ignore failure to bind on DNS cached ipv6 loopback iff user specifies "localhost"
for _, serverAddr := range serverAddrs {
var l net.Listener
if l, err = listenCfg.Listen(ctx, "tcp", serverAddr); err != nil {
if isLocalhost && strings.HasPrefix(serverAddr, "[::1]") {
continue
}
return nil, err
}
tcpListener, ok := l.(*net.TCPListener)
if !ok {
return nil, fmt.Errorf("unexpected listener type found %v, expected net.TCPListener", l)
err = fmt.Errorf("unexpected listener type found %v, expected net.TCPListener", l)
if isLocalhost && strings.HasPrefix(serverAddr, "[::1]") {
continue
}
return nil, err
}
tcpListeners = append(tcpListeners, tcpListener)
}
// Fail if no listeners found
if len(tcpListeners) == 0 {
// Report specific issue
if err != nil {
return nil, err
}
// Report general issue
err = fmt.Errorf("%v listeners found, expected at least 1", 0)
return nil, err
}
listener = &httpListener{
tcpListeners: tcpListeners,
acceptCh: make(chan acceptResult, len(tcpListeners)),

View File

@ -142,17 +142,18 @@ func TestNewHTTPListener(t *testing.T) {
{[]string{"example.org:65432"}, time.Duration(0), time.Duration(0), time.Duration(0), true},
{[]string{"unknown-host"}, time.Duration(0), time.Duration(0), time.Duration(0), true},
{[]string{"unknown-host:65432"}, time.Duration(0), time.Duration(0), time.Duration(0), true},
{[]string{"localhost:65432"}, time.Duration(0), time.Duration(0), time.Duration(0), false},
{[]string{"localhost:65432", "93.184.216.34:65432"}, time.Duration(0), time.Duration(0), time.Duration(0), true},
{[]string{"localhost:65432", "unknown-host:65432"}, time.Duration(0), time.Duration(0), time.Duration(0), true},
{[]string{"localhost:0"}, time.Duration(0), time.Duration(0), time.Duration(0), false},
{[]string{"localhost:0"}, time.Duration(0), time.Duration(0), time.Duration(0), false},
{[]string{"[::1]:9090", "localhost:0"}, time.Duration(0), time.Duration(0), time.Duration(0), false},
}
for _, testCase := range testCases {
listener, err := newHTTPListener(context.Background(),
testCase.serverAddrs,
)
if !testCase.expectedErr {
if err != nil {
t.Fatalf("error: expected = <nil>, got = %v", err)