From 772bb48010a172a9a872d83089b069cc14752490 Mon Sep 17 00:00:00 2001 From: David Scott Date: Sun, 3 Apr 2016 20:52:12 +0100 Subject: [PATCH] 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 --- alpine/packages/proxy/main.go | 45 +++++++++++++++++++++++++++++----- alpine/packages/proxy/proxy.go | 6 +++-- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/alpine/packages/proxy/main.go b/alpine/packages/proxy/main.go index 383a580f2..fda26965d 100644 --- a/alpine/packages/proxy/main.go +++ b/alpine/packages/proxy/main.go @@ -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 +} diff --git a/alpine/packages/proxy/proxy.go b/alpine/packages/proxy/proxy.go index b6fce56b2..f730bc22e 100644 --- a/alpine/packages/proxy/proxy.go +++ b/alpine/packages/proxy/proxy.go @@ -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) {