diff --git a/tools/portforward/portforward.go b/tools/portforward/portforward.go index 0e9b369a..357680ed 100644 --- a/tools/portforward/portforward.go +++ b/tools/portforward/portforward.go @@ -23,6 +23,7 @@ import ( "io/ioutil" "net" "net/http" + "sort" "strconv" "strings" "sync" @@ -122,10 +123,14 @@ func parseAddresses(addressesToParse []string) ([]listenAddress, error) { parsed := make(map[string]listenAddress) for _, address := range addressesToParse { if address == "localhost" { - ip := listenAddress{address: "127.0.0.1", protocol: "tcp4", failureMode: "all"} - parsed[ip.address] = ip - ip = listenAddress{address: "::1", protocol: "tcp6", failureMode: "all"} - parsed[ip.address] = ip + if _, exists := parsed["127.0.0.1"]; !exists { + ip := listenAddress{address: "127.0.0.1", protocol: "tcp4", failureMode: "all"} + parsed[ip.address] = ip + } + if _, exists := parsed["::1"]; !exists { + ip := listenAddress{address: "::1", protocol: "tcp6", failureMode: "all"} + parsed[ip.address] = ip + } } else if net.ParseIP(address).To4() != nil { parsed[address] = listenAddress{address: address, protocol: "tcp4", failureMode: "any"} } else if net.ParseIP(address) != nil { @@ -140,6 +145,9 @@ func parseAddresses(addressesToParse []string) ([]listenAddress, error) { addresses[id] = v id++ } + // Sort addresses before returning to get a stable order + sort.Slice(addresses, func(i, j int) bool { return addresses[i].address < addresses[j].address }) + return addresses, nil } diff --git a/tools/portforward/portforward_test.go b/tools/portforward/portforward_test.go index ff2401e7..dd8d4fd5 100644 --- a/tools/portforward/portforward_test.go +++ b/tools/portforward/portforward_test.go @@ -83,6 +83,62 @@ func TestParsePortsAndNew(t *testing.T) { {protocol: "tcp6", address: "::1", failureMode: "all"}, }, }, + { + input: []string{"5000:5000"}, + addresses: []string{"localhost", "::1"}, + expectedPorts: []ForwardedPort{ + {5000, 5000}, + }, + expectedAddresses: []listenAddress{ + {protocol: "tcp4", address: "127.0.0.1", failureMode: "all"}, + {protocol: "tcp6", address: "::1", failureMode: "any"}, + }, + }, + { + input: []string{"5000:5000"}, + addresses: []string{"localhost", "127.0.0.1", "::1"}, + expectedPorts: []ForwardedPort{ + {5000, 5000}, + }, + expectedAddresses: []listenAddress{ + {protocol: "tcp4", address: "127.0.0.1", failureMode: "any"}, + {protocol: "tcp6", address: "::1", failureMode: "any"}, + }, + }, + { + input: []string{"5000:5000"}, + addresses: []string{"localhost", "127.0.0.1", "10.10.10.1"}, + expectedPorts: []ForwardedPort{ + {5000, 5000}, + }, + expectedAddresses: []listenAddress{ + {protocol: "tcp4", address: "127.0.0.1", failureMode: "any"}, + {protocol: "tcp6", address: "::1", failureMode: "all"}, + {protocol: "tcp4", address: "10.10.10.1", failureMode: "any"}, + }, + }, + { + input: []string{"5000:5000"}, + addresses: []string{"127.0.0.1", "::1", "localhost"}, + expectedPorts: []ForwardedPort{ + {5000, 5000}, + }, + expectedAddresses: []listenAddress{ + {protocol: "tcp4", address: "127.0.0.1", failureMode: "any"}, + {protocol: "tcp6", address: "::1", failureMode: "any"}, + }, + }, + { + input: []string{"5000:5000"}, + addresses: []string{"10.0.0.1", "127.0.0.1"}, + expectedPorts: []ForwardedPort{ + {5000, 5000}, + }, + expectedAddresses: []listenAddress{ + {protocol: "tcp4", address: "10.0.0.1", failureMode: "any"}, + {protocol: "tcp4", address: "127.0.0.1", failureMode: "any"}, + }, + }, { input: []string{"5000", "5000:5000", "8888:5000", "5000:8888", ":5000", "0:5000"}, addresses: []string{"127.0.0.1", "::1"},