mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
bridge: retry any proxy set up failures until we get a successful port, defeats a race condition
Docker-DCO-1.1-Signed-off-by: Erik Hollensbe <github@hollensbe.org> (github: erikh)
This commit is contained in:
parent
f0489ce3a9
commit
91ba337931
1 changed files with 31 additions and 15 deletions
|
@ -380,7 +380,7 @@ func AllocatePort(job *engine.Job) engine.Status {
|
|||
ip = defaultBindingIP
|
||||
id = job.Args[0]
|
||||
hostIP = job.Getenv("HostIP")
|
||||
hostPort = job.GetenvInt("HostPort")
|
||||
origHostPort = job.GetenvInt("HostPort")
|
||||
containerPort = job.GetenvInt("ContainerPort")
|
||||
proto = job.Getenv("Proto")
|
||||
network = currentInterfaces[id]
|
||||
|
@ -390,29 +390,45 @@ func AllocatePort(job *engine.Job) engine.Status {
|
|||
ip = net.ParseIP(hostIP)
|
||||
}
|
||||
|
||||
// host ip, proto, and host port
|
||||
hostPort, err = portallocator.RequestPort(ip, proto, hostPort)
|
||||
if err != nil {
|
||||
return job.Error(err)
|
||||
}
|
||||
|
||||
var (
|
||||
hostPort int
|
||||
container net.Addr
|
||||
host net.Addr
|
||||
)
|
||||
|
||||
if proto == "tcp" {
|
||||
host = &net.TCPAddr{IP: ip, Port: hostPort}
|
||||
container = &net.TCPAddr{IP: network.IP, Port: containerPort}
|
||||
} else {
|
||||
host = &net.UDPAddr{IP: ip, Port: hostPort}
|
||||
container = &net.UDPAddr{IP: network.IP, Port: containerPort}
|
||||
/*
|
||||
Try up to 10 times to get a port that's not already allocated.
|
||||
|
||||
In the event of failure to bind, return the error that portmapper.Map
|
||||
yields.
|
||||
*/
|
||||
for i := 0; i < 10; i++ {
|
||||
// host ip, proto, and host port
|
||||
hostPort, err = portallocator.RequestPort(ip, proto, origHostPort)
|
||||
|
||||
if err != nil {
|
||||
return job.Error(err)
|
||||
}
|
||||
|
||||
if proto == "tcp" {
|
||||
host = &net.TCPAddr{IP: ip, Port: hostPort}
|
||||
container = &net.TCPAddr{IP: network.IP, Port: containerPort}
|
||||
} else {
|
||||
host = &net.UDPAddr{IP: ip, Port: hostPort}
|
||||
container = &net.UDPAddr{IP: network.IP, Port: containerPort}
|
||||
}
|
||||
|
||||
if err = portmapper.Map(container, ip, hostPort); err == nil {
|
||||
break
|
||||
}
|
||||
|
||||
job.Logf("Failed to bind %s:%d for container address %s:%d. Trying another port.", ip.String(), hostPort, network.IP.String(), containerPort)
|
||||
}
|
||||
|
||||
if err := portmapper.Map(container, ip, hostPort); err != nil {
|
||||
portallocator.ReleasePort(ip, proto, hostPort)
|
||||
if err != nil {
|
||||
return job.Error(err)
|
||||
}
|
||||
|
||||
network.PortMappings = append(network.PortMappings, host)
|
||||
|
||||
out := engine.Env{}
|
||||
|
|
Loading…
Reference in a new issue