mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
daemon/links: fix port-sorting with mixed protocols
The intent of this sorting was twofold; - the "default" port of the container to be the first TCP port (if present) - consecutive port-mappings with the same protocol to be together so that port-ranges would produce an env-var describing the range. The current sorting would sort TCP ports before UDP (or SCTP) port, but only if they had the same port-number. This could result in range-detection incorrectly combining TCP and UDP (or SCTP) ports in the same range. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
@@ -54,11 +54,7 @@ func (l *Link) ToEnv() []string {
|
||||
alias := strings.ReplaceAll(strings.ToUpper(n), "-", "_")
|
||||
|
||||
// sort the ports so that we can bulk the continuous ports together
|
||||
nat.Sort(l.Ports, func(ip, jp nat.Port) bool {
|
||||
// If the two ports have the same number, tcp takes priority
|
||||
// Sort in desc order
|
||||
return ip.Int() < jp.Int() || (ip.Int() == jp.Int() && strings.ToLower(ip.Proto()) == "tcp")
|
||||
})
|
||||
nat.Sort(l.Ports, withTCPPriority)
|
||||
|
||||
for i := 0; i < len(l.Ports); {
|
||||
p := l.Ports[i]
|
||||
@@ -108,6 +104,23 @@ func (l *Link) ToEnv() []string {
|
||||
return env
|
||||
}
|
||||
|
||||
// withTCPPriority prioritizes ports using TCP over other protocols before
|
||||
// comparing port-number and protocol.
|
||||
func withTCPPriority(ip, jp nat.Port) bool {
|
||||
if strings.EqualFold(ip.Proto(), jp.Proto()) {
|
||||
return ip.Int() < jp.Int()
|
||||
}
|
||||
|
||||
if strings.EqualFold(ip.Proto(), "tcp") {
|
||||
return true
|
||||
}
|
||||
if strings.EqualFold(jp.Proto(), "tcp") {
|
||||
return false
|
||||
}
|
||||
|
||||
return strings.ToLower(ip.Proto()) < strings.ToLower(jp.Proto())
|
||||
}
|
||||
|
||||
func nextContiguous(ports []nat.Port, value int, index int) int {
|
||||
if index+1 == len(ports) {
|
||||
return index
|
||||
|
||||
@@ -60,6 +60,35 @@ func TestLinkEnv(t *testing.T) {
|
||||
assert.DeepEqual(t, expectedEnv, actual)
|
||||
}
|
||||
|
||||
// TestSortPorts verifies that ports are sorted with TCP taking priority,
|
||||
// and ports with the same protocol to be sorted by port.
|
||||
func TestSortPorts(t *testing.T) {
|
||||
ports := []nat.Port{
|
||||
"6379/tcp",
|
||||
"6376/udp",
|
||||
"6380/tcp",
|
||||
"6376/sctp",
|
||||
"6381/tcp",
|
||||
"6381/udp",
|
||||
"6375/udp",
|
||||
"6375/sctp",
|
||||
}
|
||||
|
||||
expected := []nat.Port{
|
||||
"6379/tcp",
|
||||
"6380/tcp",
|
||||
"6381/tcp",
|
||||
"6375/sctp",
|
||||
"6376/sctp",
|
||||
"6375/udp",
|
||||
"6376/udp",
|
||||
"6381/udp",
|
||||
}
|
||||
|
||||
nat.Sort(ports, withTCPPriority)
|
||||
assert.DeepEqual(t, expected, ports)
|
||||
}
|
||||
|
||||
func TestLinkMultipleEnv(t *testing.T) {
|
||||
actual := EnvVars("172.0.17.3", "172.0.17.2", "/db/docker", []string{"PASSWORD=gordon"}, nat.PortSet{
|
||||
"6379/tcp": struct{}{},
|
||||
|
||||
Reference in New Issue
Block a user