mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-29 13:38:00 +00:00
proxy: don't fail if the Listen in the VM fails with EADDRNOTAVAIL
The purpose of the `slirp-proxy` is to expose ports on the Mac or
Windows host. In d5bd7d690a
we added
an additional `Listen` inside the VM for backwards compatibility
with software that expected to be able to listen on `0.0.0.0` in
one container and then access this easily from other containers
using an IP bound to the VM (instead of using a first-class network
to connect the containers or discovering a real IP of the host).
Before this patch we could only expose ports on if the Listen
succeeds on both the host and the VM. In practice this meant that
we could only expose ports on `0.0.0.0` and `127.0.0.1`; attempts
to expose ports on specific interfaces on the host would fail.
This patch treats the EADDRNOTAVAIL error from the Listen inside
the VM as a soft failure, and still attempts to Listen on the host.
If the Listen on the host fails it is still a hard failure.
This allows ports to be exposed on specific IPs used on the host.
Fixes [docker/pinata#5080]
Signed-off-by: David Scott <dave.scott@docker.com>
This commit is contained in:
parent
7d4e6f4a8b
commit
c6757075d0
@ -8,6 +8,7 @@ import (
|
||||
"os"
|
||||
"proxy/libproxy"
|
||||
"strings"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func onePort() {
|
||||
@ -17,7 +18,7 @@ func onePort() {
|
||||
var err error
|
||||
|
||||
if localIP {
|
||||
ipP, err = libproxy.NewIPProxy(host, container)
|
||||
ipP, err = listenInVM(host, container)
|
||||
if err != nil {
|
||||
sendError(err)
|
||||
}
|
||||
@ -40,6 +41,27 @@ func onePort() {
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
// Best-effort attempt to listen on the address in the VM. This is for
|
||||
// backwards compatibility with software that expects to be able to listen on
|
||||
// 0.0.0.0 and then connect from within a container to the external port.
|
||||
// If the address doesn't exist in the VM (i.e. it exists only on the host)
|
||||
// then this is not a hard failure.
|
||||
func listenInVM(host net.Addr, container net.Addr) (libproxy.Proxy, error) {
|
||||
ipP, err := libproxy.NewIPProxy(host, container)
|
||||
if err == nil {
|
||||
return ipP, nil
|
||||
}
|
||||
if opError, ok := err.(*net.OpError); ok {
|
||||
if syscallError, ok := opError.Err.(*os.SyscallError); ok {
|
||||
if syscallError.Err == syscall.EADDRNOTAVAIL {
|
||||
log.Printf("Address %s doesn't exist in the VM: only binding on the host", host)
|
||||
return nil, nil // Non-fatal error
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func exposePort(host net.Addr, container net.Addr) (*os.File, error) {
|
||||
name := host.Network() + ":" + host.String() + ":" + container.Network() + ":" + container.String()
|
||||
log.Printf("exposePort %s\n", name)
|
||||
|
Loading…
Reference in New Issue
Block a user