proxy: determine "my" address by examining the "docker" forward

When requesting a port forward we currently need to know the VM's
address from the point of view of the port forwarder. The easiest way to
discover this is to read it from the existing "docker" port forward.

Note this should all be revamped once we have vsock support.

Signed-off-by: David Scott <dave.scott@docker.com>
This commit is contained in:
David Scott 2016-04-03 20:52:12 +01:00
parent b29a44b4a8
commit 772bb48010
2 changed files with 43 additions and 8 deletions

View File

@ -11,9 +11,9 @@ import (
)
func main() {
host, container := parseHostContainerAddrs()
host, port, container := parseHostContainerAddrs()
err := exposePort(host)
err := exposePort(host, port)
if err != nil {
sendError(err)
}
@ -29,7 +29,7 @@ func main() {
os.Exit(0)
}
func exposePort(host net.Addr) error {
func exposePort(host net.Addr, port int) error {
name := host.String()
log.Printf("exposePort %s\n", name)
err := os.Mkdir("/port/"+name, 0)
@ -42,7 +42,12 @@ func exposePort(host net.Addr) error {
log.Printf("Failed to open /port/%s/ctl: %#v\n", name, err)
return err
}
_, err = ctl.WriteString(fmt.Sprintf("%s:%s", name, name))
me, err := getMyAddress()
if err != nil {
log.Printf("Failed to determine my local address: %#v\n", err)
return err
}
_, err = ctl.WriteString(fmt.Sprintf("%s:%s:%d", name, me, port))
if err != nil {
log.Printf("Failed to open /port/%s/ctl: %#v\n", name, err)
return err
@ -58,14 +63,17 @@ func exposePort(host net.Addr) error {
log.Printf("Failed to read from /port/%s/ctl: %#v\n", name, err)
return err
}
// TODO: consider whether close/clunk of ctl would be a better tear down
// signal
ctl.Close()
response := string(results[0:count])
if strings.HasPrefix(response, "ERROR ") {
os.Remove("/port/" + name + "/ctl")
response = strings.Trim(response[6:], " \t\r\n")
return errors.New(response)
}
// TODO: consider whether close/clunk of ctl would be a better tear down
// signal
return nil
}
@ -77,3 +85,28 @@ func unexposePort(host net.Addr) {
log.Printf("Failed to remove /port/%s: %#v\n", name, err)
}
}
var myAddress string
// getMyAddress returns a string representing my address from the host's
// point of view. For now this is an IP address but it soon should be a vsock
// port.
func getMyAddress() (string, error) {
if myAddress != "" {
return myAddress, nil
}
d, err := os.Open("/port/docker")
if err != nil {
return "", err
}
defer d.Close()
bytes := make([]byte, 100)
count, err := d.Read(bytes)
if err != nil {
return "", err
}
s := string(bytes)[0:count]
bits := strings.Split(s, ":")
myAddress = bits[2]
return myAddress, nil
}

View File

@ -32,7 +32,7 @@ func sendOK() {
// parseHostContainerAddrs parses the flags passed on reexec to create the TCP or UDP
// net.Addrs to map the host and container ports
func parseHostContainerAddrs() (host net.Addr, container net.Addr) {
func parseHostContainerAddrs() (host net.Addr, port int, container net.Addr) {
var (
proto = flag.String("proto", "tcp", "proxy protocol")
hostIP = flag.String("host-ip", "", "host ip")
@ -46,15 +46,17 @@ func parseHostContainerAddrs() (host net.Addr, container net.Addr) {
switch *proto {
case "tcp":
host = &net.TCPAddr{IP: net.ParseIP(*hostIP), Port: *hostPort}
port = *hostPort
container = &net.TCPAddr{IP: net.ParseIP(*containerIP), Port: *containerPort}
case "udp":
host = &net.UDPAddr{IP: net.ParseIP(*hostIP), Port: *hostPort}
port = *hostPort
container = &net.UDPAddr{IP: net.ParseIP(*containerIP), Port: *containerPort}
default:
log.Fatalf("unsupported protocol %s", *proto)
}
return host, container
return host, port, container
}
func handleStopSignals(p proxy.Proxy) {