diff --git a/libnetwork/drivers/bridge/bridge.go b/libnetwork/drivers/bridge/bridge.go index 0b93eb60b0..777f7b162e 100644 --- a/libnetwork/drivers/bridge/bridge.go +++ b/libnetwork/drivers/bridge/bridge.go @@ -50,6 +50,7 @@ type configuration struct { EnableIPForwarding bool EnableIPTables bool EnableUserlandProxy bool + UserlandProxyPath string } // networkConfiguration for network specific configuration @@ -638,7 +639,7 @@ func (d *driver) createNetwork(config *networkConfiguration) error { id: config.ID, endpoints: make(map[string]*bridgeEndpoint), config: config, - portMapper: portmapper.New(), + portMapper: portmapper.New(d.config.UserlandProxyPath), driver: d, } diff --git a/libnetwork/drivers/bridge/setup_ip_tables_test.go b/libnetwork/drivers/bridge/setup_ip_tables_test.go index 20c70734ae..edfb2907fc 100644 --- a/libnetwork/drivers/bridge/setup_ip_tables_test.go +++ b/libnetwork/drivers/bridge/setup_ip_tables_test.go @@ -124,7 +124,7 @@ func assertChainConfig(d *driver, t *testing.T) { // Assert function which pushes chains based on bridge config parameters. func assertBridgeConfig(config *networkConfiguration, br *bridgeInterface, d *driver, t *testing.T) { - nw := bridgeNetwork{portMapper: portmapper.New(), + nw := bridgeNetwork{portMapper: portmapper.New(""), config: config} nw.driver = d diff --git a/libnetwork/portmapper/mapper.go b/libnetwork/portmapper/mapper.go index 6a1bb08ffb..7f2a67c89f 100644 --- a/libnetwork/portmapper/mapper.go +++ b/libnetwork/portmapper/mapper.go @@ -38,19 +38,22 @@ type PortMapper struct { currentMappings map[string]*mapping lock sync.Mutex + proxyPath string + Allocator *portallocator.PortAllocator } // New returns a new instance of PortMapper -func New() *PortMapper { - return NewWithPortAllocator(portallocator.Get()) +func New(proxyPath string) *PortMapper { + return NewWithPortAllocator(portallocator.Get(), proxyPath) } // NewWithPortAllocator returns a new instance of PortMapper which will use the specified PortAllocator -func NewWithPortAllocator(allocator *portallocator.PortAllocator) *PortMapper { +func NewWithPortAllocator(allocator *portallocator.PortAllocator, proxyPath string) *PortMapper { return &PortMapper{ currentMappings: make(map[string]*mapping), Allocator: allocator, + proxyPath: proxyPath, } } @@ -90,7 +93,7 @@ func (pm *PortMapper) MapRange(container net.Addr, hostIP net.IP, hostPortStart, } if useProxy { - m.userlandProxy, err = newProxy(proto, hostIP, allocatedHostPort, container.(*net.TCPAddr).IP, container.(*net.TCPAddr).Port) + m.userlandProxy, err = newProxy(proto, hostIP, allocatedHostPort, container.(*net.TCPAddr).IP, container.(*net.TCPAddr).Port, pm.proxyPath) if err != nil { return nil, err } @@ -110,7 +113,7 @@ func (pm *PortMapper) MapRange(container net.Addr, hostIP net.IP, hostPortStart, } if useProxy { - m.userlandProxy, err = newProxy(proto, hostIP, allocatedHostPort, container.(*net.UDPAddr).IP, container.(*net.UDPAddr).Port) + m.userlandProxy, err = newProxy(proto, hostIP, allocatedHostPort, container.(*net.UDPAddr).IP, container.(*net.UDPAddr).Port, pm.proxyPath) if err != nil { return nil, err } diff --git a/libnetwork/portmapper/mapper_test.go b/libnetwork/portmapper/mapper_test.go index 510a4291dc..7c93f8c8e8 100644 --- a/libnetwork/portmapper/mapper_test.go +++ b/libnetwork/portmapper/mapper_test.go @@ -15,7 +15,7 @@ func init() { } func TestSetIptablesChain(t *testing.T) { - pm := New() + pm := New("") c := &iptables.ChainInfo{ Name: "TEST", @@ -32,7 +32,7 @@ func TestSetIptablesChain(t *testing.T) { } func TestMapTCPPorts(t *testing.T) { - pm := New() + pm := New("") dstIP1 := net.ParseIP("192.168.0.1") dstIP2 := net.ParseIP("192.168.0.2") dstAddr1 := &net.TCPAddr{IP: dstIP1, Port: 80} @@ -111,7 +111,7 @@ func TestGetUDPIPAndPort(t *testing.T) { } func TestMapUDPPorts(t *testing.T) { - pm := New() + pm := New("") dstIP1 := net.ParseIP("192.168.0.1") dstIP2 := net.ParseIP("192.168.0.2") dstAddr1 := &net.UDPAddr{IP: dstIP1, Port: 80} @@ -157,7 +157,7 @@ func TestMapUDPPorts(t *testing.T) { } func TestMapAllPortsSingleInterface(t *testing.T) { - pm := New() + pm := New("") dstIP1 := net.ParseIP("0.0.0.0") srcAddr1 := &net.TCPAddr{Port: 1080, IP: net.ParseIP("172.16.0.1")} @@ -196,7 +196,7 @@ func TestMapAllPortsSingleInterface(t *testing.T) { } func TestMapTCPDummyListen(t *testing.T) { - pm := New() + pm := New("") dstIP := net.ParseIP("0.0.0.0") dstAddr := &net.TCPAddr{IP: dstIP, Port: 80} @@ -233,7 +233,7 @@ func TestMapTCPDummyListen(t *testing.T) { } func TestMapUDPDummyListen(t *testing.T) { - pm := New() + pm := New("") dstIP := net.ParseIP("0.0.0.0") dstAddr := &net.UDPAddr{IP: dstIP, Port: 80} diff --git a/libnetwork/portmapper/mock_proxy.go b/libnetwork/portmapper/mock_proxy.go index 587026f9ce..ceb7b02926 100644 --- a/libnetwork/portmapper/mock_proxy.go +++ b/libnetwork/portmapper/mock_proxy.go @@ -2,7 +2,7 @@ package portmapper import "net" -func newMockProxyCommand(proto string, hostIP net.IP, hostPort int, containerIP net.IP, containerPort int) (userlandProxy, error) { +func newMockProxyCommand(proto string, hostIP net.IP, hostPort int, containerIP net.IP, containerPort int, userlandProxyPath string) (userlandProxy, error) { return &mockProxyCommand{}, nil } diff --git a/libnetwork/portmapper/proxy.go b/libnetwork/portmapper/proxy.go index 25a341a98f..6a4adbb872 100644 --- a/libnetwork/portmapper/proxy.go +++ b/libnetwork/portmapper/proxy.go @@ -25,15 +25,18 @@ type proxyCommand struct { cmd *exec.Cmd } -func newProxyCommand(proto string, hostIP net.IP, hostPort int, containerIP net.IP, containerPort int) (userlandProxy, error) { - cmd, err := exec.LookPath(userlandProxyCommandName) - - if err != nil { - return nil, err +func newProxyCommand(proto string, hostIP net.IP, hostPort int, containerIP net.IP, containerPort int, proxyPath string) (userlandProxy, error) { + path := proxyPath + if proxyPath == "" { + cmd, err := exec.LookPath(userlandProxyCommandName) + if err != nil { + return nil, err + } + path = cmd } args := []string{ - cmd, + path, "-proto", proto, "-host-ip", hostIP.String(), "-host-port", strconv.Itoa(hostPort), @@ -43,7 +46,7 @@ func newProxyCommand(proto string, hostIP net.IP, hostPort int, containerIP net. return &proxyCommand{ cmd: &exec.Cmd{ - Path: cmd, + Path: path, Args: args, SysProcAttr: &syscall.SysProcAttr{ Pdeathsig: syscall.SIGTERM, // send a sigterm to the proxy if the daemon process dies