Prevent dynamic allocation of previously allocated ports
Docker-DCO-1.1-Signed-off-by: Andy Kipp <andy@rstudio.com> (github: kippandrew)
This commit is contained in:
parent
f14c0866ec
commit
f7b6fbbd76
2 changed files with 32 additions and 7 deletions
|
@ -100,22 +100,30 @@ func ReleaseAll() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func registerDynamicPort(ip net.IP, proto string) (int, error) {
|
func registerDynamicPort(ip net.IP, proto string) (int, error) {
|
||||||
allocated := defaultAllocatedPorts[proto]
|
|
||||||
|
|
||||||
port := nextPort(proto)
|
|
||||||
if port > EndPortRange {
|
|
||||||
return 0, ErrPortExceedsRange
|
|
||||||
}
|
|
||||||
|
|
||||||
if !equalsDefault(ip) {
|
if !equalsDefault(ip) {
|
||||||
registerIP(ip)
|
registerIP(ip)
|
||||||
|
|
||||||
ipAllocated := otherAllocatedPorts[ip.String()][proto]
|
ipAllocated := otherAllocatedPorts[ip.String()][proto]
|
||||||
ipAllocated.Push(port)
|
|
||||||
} else {
|
port, err := findNextPort(proto, ipAllocated)
|
||||||
allocated.Push(port)
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
}
|
}
|
||||||
|
ipAllocated.Push(port)
|
||||||
return port, nil
|
return port, nil
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
allocated := defaultAllocatedPorts[proto]
|
||||||
|
|
||||||
|
port, err := findNextPort(proto, allocated)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
allocated.Push(port)
|
||||||
|
return port, nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func registerSetPort(ip net.IP, proto string, port int) error {
|
func registerSetPort(ip net.IP, proto string, port int) error {
|
||||||
|
@ -142,6 +150,16 @@ func equalsDefault(ip net.IP) bool {
|
||||||
return ip == nil || ip.Equal(defaultIP)
|
return ip == nil || ip.Equal(defaultIP)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func findNextPort(proto string, allocated *collections.OrderedIntSet) (int, error) {
|
||||||
|
port := 0
|
||||||
|
for port = nextPort(proto); allocated.Exists(port); port = nextPort(proto) {
|
||||||
|
}
|
||||||
|
if port > EndPortRange {
|
||||||
|
return 0, ErrPortExceedsRange
|
||||||
|
}
|
||||||
|
return port, nil
|
||||||
|
}
|
||||||
|
|
||||||
func nextPort(proto string) int {
|
func nextPort(proto string) int {
|
||||||
c := currentDynamicPort[proto] + 1
|
c := currentDynamicPort[proto] + 1
|
||||||
currentDynamicPort[proto] = c
|
currentDynamicPort[proto] = c
|
||||||
|
|
|
@ -181,4 +181,11 @@ func TestPortAllocation(t *testing.T) {
|
||||||
if _, err := RequestPort(ip, "tcp", 80); err != nil {
|
if _, err := RequestPort(ip, "tcp", 80); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
port, err = RequestPort(ip, "tcp", 0)
|
||||||
|
port2, err := RequestPort(ip, "tcp", port+1)
|
||||||
|
port3, err := RequestPort(ip, "tcp", 0)
|
||||||
|
if port3 == port2 {
|
||||||
|
t.Fatal("A dynamic port should never allocate a used port")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue