mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Emulate DNAT in userland for loopback-to-loopback connections. This makes container ports available from localhost.
This commit is contained in:
parent
61259ab4b4
commit
930e9a7e43
1 changed files with 46 additions and 0 deletions
46
network.go
46
network.go
|
@ -4,6 +4,7 @@ import (
|
|||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"os/exec"
|
||||
|
@ -221,10 +222,55 @@ func (mapper *PortMapper) Map(port int, dest net.TCPAddr) error {
|
|||
if err := mapper.iptablesForward("-A", port, dest); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mapper.mapping[port] = dest
|
||||
listener, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", port))
|
||||
if err != nil {
|
||||
mapper.Unmap(port)
|
||||
return err
|
||||
}
|
||||
// FIXME: store the listener so we can close it at Unmap
|
||||
go proxy(listener, "tcp", dest.String())
|
||||
return nil
|
||||
}
|
||||
|
||||
// proxy listens for socket connections on `listener`, and forwards them unmodified
|
||||
// to `proto:address`
|
||||
func proxy(listener net.Listener, proto, address string) error {
|
||||
Debugf("proxying to %s:%s", proto, address)
|
||||
defer Debugf("Done proxying to %s:%s", proto, address)
|
||||
for {
|
||||
Debugf("Listening on %s", listener)
|
||||
src, err := listener.Accept()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
Debugf("Connecting to %s:%s", proto, address)
|
||||
dst, err := net.Dial(proto, address)
|
||||
if err != nil {
|
||||
log.Printf("Error connecting to %s:%s: %s", proto, address, err)
|
||||
src.Close()
|
||||
continue
|
||||
}
|
||||
Debugf("Connected to backend, splicing")
|
||||
splice(src, dst)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func halfSplice(dst, src net.Conn) error {
|
||||
_, err := io.Copy(dst, src)
|
||||
// FIXME: on EOF from a tcp connection, pass WriteClose()
|
||||
dst.Close()
|
||||
src.Close()
|
||||
return err
|
||||
}
|
||||
|
||||
func splice(a, b net.Conn) {
|
||||
go halfSplice(a, b)
|
||||
go halfSplice(b, a)
|
||||
}
|
||||
|
||||
func (mapper *PortMapper) Unmap(port int) error {
|
||||
dest, ok := mapper.mapping[port]
|
||||
if !ok {
|
||||
|
|
Loading…
Add table
Reference in a new issue