diff --git a/libnetwork/portmapper/mapper.go b/libnetwork/portmapper/mapper.go index c03fd4f614..3315158c97 100644 --- a/libnetwork/portmapper/mapper.go +++ b/libnetwork/portmapper/mapper.go @@ -17,6 +17,7 @@ type mapping struct { container net.Addr } +// newProxy is used to mock out the proxy server in tests var newProxy = newProxyCommand var ( @@ -214,7 +215,7 @@ func (pm *PortMapper) Unmap(host net.Addr) error { return ErrUnknownBackendAddressType } -//ReMapAll will re-apply all port mappings +// ReMapAll re-applies all port mappings func (pm *PortMapper) ReMapAll() { pm.lock.Lock() defer pm.lock.Unlock() diff --git a/libnetwork/portmapper/mock_proxy.go b/libnetwork/portmapper/mock_proxy_test.go similarity index 100% rename from libnetwork/portmapper/mock_proxy.go rename to libnetwork/portmapper/mock_proxy_test.go diff --git a/libnetwork/portmapper/proxy.go b/libnetwork/portmapper/proxy.go index f945851d54..9ab70ffa0e 100644 --- a/libnetwork/portmapper/proxy.go +++ b/libnetwork/portmapper/proxy.go @@ -3,17 +3,11 @@ package portmapper import ( "fmt" "io" - "io/ioutil" "net" - "os" - "os/exec" - "time" "github.com/ishidawataru/sctp" ) -var userlandProxyCommandName = "docker-proxy" - type userlandProxy interface { Start() error Stop() error @@ -29,60 +23,6 @@ const ( ipv6 ipVersion = "6" ) -// proxyCommand wraps an exec.Cmd to run the userland TCP and UDP -// proxies as separate processes. -type proxyCommand struct { - cmd *exec.Cmd -} - -func (p *proxyCommand) Start() error { - r, w, err := os.Pipe() - if err != nil { - return fmt.Errorf("proxy unable to open os.Pipe %s", err) - } - defer r.Close() - p.cmd.ExtraFiles = []*os.File{w} - if err := p.cmd.Start(); err != nil { - return err - } - w.Close() - - errchan := make(chan error, 1) - go func() { - buf := make([]byte, 2) - r.Read(buf) - - if string(buf) != "0\n" { - errStr, err := ioutil.ReadAll(r) - if err != nil { - errchan <- fmt.Errorf("Error reading exit status from userland proxy: %v", err) - return - } - - errchan <- fmt.Errorf("Error starting userland proxy: %s", errStr) - return - } - errchan <- nil - }() - - select { - case err := <-errchan: - return err - case <-time.After(16 * time.Second): - return fmt.Errorf("Timed out proxy starting the userland proxy") - } -} - -func (p *proxyCommand) Stop() error { - if p.cmd.Process != nil { - if err := p.cmd.Process.Signal(os.Interrupt); err != nil { - return err - } - return p.cmd.Wait() - } - return nil -} - // dummyProxy just listen on some port, it is needed to prevent accidental // port allocations on bound port, because without userland proxy we using // iptables rules and not net.Listen diff --git a/libnetwork/portmapper/proxy_linux.go b/libnetwork/portmapper/proxy_linux.go index 947cd0ba4b..d09d334036 100644 --- a/libnetwork/portmapper/proxy_linux.go +++ b/libnetwork/portmapper/proxy_linux.go @@ -1,12 +1,18 @@ package portmapper import ( + "fmt" + "io/ioutil" "net" + "os" "os/exec" "strconv" "syscall" + "time" ) +const userlandProxyCommandName = "docker-proxy" + func newProxyCommand(proto string, hostIP net.IP, hostPort int, containerIP net.IP, containerPort int, proxyPath string) (userlandProxy, error) { path := proxyPath if proxyPath == "" { @@ -36,3 +42,57 @@ func newProxyCommand(proto string, hostIP net.IP, hostPort int, containerIP net. }, }, nil } + +// proxyCommand wraps an exec.Cmd to run the userland TCP and UDP +// proxies as separate processes. +type proxyCommand struct { + cmd *exec.Cmd +} + +func (p *proxyCommand) Start() error { + r, w, err := os.Pipe() + if err != nil { + return fmt.Errorf("proxy unable to open os.Pipe %s", err) + } + defer r.Close() + p.cmd.ExtraFiles = []*os.File{w} + if err := p.cmd.Start(); err != nil { + return err + } + w.Close() + + errchan := make(chan error, 1) + go func() { + buf := make([]byte, 2) + r.Read(buf) + + if string(buf) != "0\n" { + errStr, err := ioutil.ReadAll(r) + if err != nil { + errchan <- fmt.Errorf("Error reading exit status from userland proxy: %v", err) + return + } + + errchan <- fmt.Errorf("Error starting userland proxy: %s", errStr) + return + } + errchan <- nil + }() + + select { + case err := <-errchan: + return err + case <-time.After(16 * time.Second): + return fmt.Errorf("Timed out proxy starting the userland proxy") + } +} + +func (p *proxyCommand) Stop() error { + if p.cmd.Process != nil { + if err := p.cmd.Process.Signal(os.Interrupt); err != nil { + return err + } + return p.cmd.Wait() + } + return nil +}