veyron/runtimes/google/ipc/stream/proxy: Add publish address

The listen address is not always the same at the address that external
users need to connect to. This change adds a new argument to proxy.New()
to specify the published address that clients should connect to.

Change-Id: Ied6a8ece9bc7bc0fc1dfb8f5b305e95faab1a6ee
diff --git a/runtimes/google/daemon/proxyd/main.go b/runtimes/google/daemon/proxyd/main.go
index 9689067..665e625 100644
--- a/runtimes/google/daemon/proxyd/main.go
+++ b/runtimes/google/daemon/proxyd/main.go
@@ -18,10 +18,11 @@
 func main() {
 	var (
 		// TODO(rthellend): Remove the address and protocol flags when the config manager is working.
-		address  = flag.String("address", ":0", "Network address the proxy listens on")
-		protocol = flag.String("protocol", "tcp", "Network type the proxy listens on")
-		httpAddr = flag.String("http", ":14142", "Network address on which the HTTP debug server runs")
-		name     = flag.String("name", "", "Name to mount the proxy as")
+		address    = flag.String("address", ":0", "Network address the proxy listens on")
+		pubAddress = flag.String("published_address", "", "Network address the proxy publishes. If empty, the value of --address will be used")
+		protocol   = flag.String("protocol", "tcp", "Network type the proxy listens on")
+		httpAddr   = flag.String("http", ":14142", "Network address on which the HTTP debug server runs")
+		name       = flag.String("name", "", "Name to mount the proxy as")
 	)
 
 	r := rt.Init()
@@ -32,7 +33,7 @@
 		vlog.Fatal(err)
 	}
 
-	proxy, err := proxy.New(rid, nil, *protocol, *address)
+	proxy, err := proxy.New(rid, nil, *protocol, *address, *pubAddress)
 	if err != nil {
 		vlog.Fatal(err)
 	}
diff --git a/runtimes/google/ipc/full_test.go b/runtimes/google/ipc/full_test.go
index 4729cef..2a6d4d8 100644
--- a/runtimes/google/ipc/full_test.go
+++ b/runtimes/google/ipc/full_test.go
@@ -1014,7 +1014,7 @@
 	if err != nil {
 		vlog.Fatal(err)
 	}
-	proxy, err := proxy.New(rid, nil, "tcp4", "127.0.0.1:0")
+	proxy, err := proxy.New(rid, nil, "tcp4", "127.0.0.1:0", "")
 	if err != nil {
 		vlog.Fatal(err)
 	}
diff --git a/runtimes/google/ipc/stream/proxy/proxy.go b/runtimes/google/ipc/stream/proxy/proxy.go
index e1911aa..6f343d3 100644
--- a/runtimes/google/ipc/stream/proxy/proxy.go
+++ b/runtimes/google/ipc/stream/proxy/proxy.go
@@ -32,12 +32,13 @@
 // Proxy routes virtual circuit (VC) traffic between multiple underlying
 // network connections.
 type Proxy struct {
-	ln        net.Listener
-	rid       naming.RoutingID
-	id        security.PrivateID
-	mu        sync.RWMutex
-	servers   *servermap
-	processes map[*process]struct{}
+	ln         net.Listener
+	rid        naming.RoutingID
+	id         security.PrivateID
+	mu         sync.RWMutex
+	servers    *servermap
+	processes  map[*process]struct{}
+	pubAddress string
 }
 
 // process encapsulates the physical network connection and the routing table
@@ -131,17 +132,21 @@
 
 // New creates a new Proxy that listens for network connections on the provided
 // (network, address) pair and routes VC traffic between accepted connections.
-func New(rid naming.RoutingID, identity security.PrivateID, network, address string) (*Proxy, error) {
+func New(rid naming.RoutingID, identity security.PrivateID, network, address, pubAddress string) (*Proxy, error) {
 	ln, err := net.Listen(network, address)
 	if err != nil {
 		return nil, fmt.Errorf("net.Listen(%q, %q) failed: %v", network, address, err)
 	}
+	if len(pubAddress) == 0 {
+		pubAddress = ln.Addr().String()
+	}
 	proxy := &Proxy{
-		ln:        ln,
-		rid:       rid,
-		id:        identity,
-		servers:   &servermap{m: make(map[naming.RoutingID]*server)},
-		processes: make(map[*process]struct{}),
+		ln:         ln,
+		rid:        rid,
+		id:         identity,
+		servers:    &servermap{m: make(map[naming.RoutingID]*server)},
+		processes:  make(map[*process]struct{}),
+		pubAddress: pubAddress,
 	}
 	go proxy.listenLoop()
 	return proxy, nil
@@ -441,7 +446,7 @@
 // Endpoint returns the endpoint of the proxy service.  By Dialing a VC to this
 // endpoint, processes can have their services exported through the proxy.
 func (p *Proxy) Endpoint() naming.Endpoint {
-	return version.Endpoint(p.ln.Addr().Network(), p.ln.Addr().String(), p.rid)
+	return version.Endpoint(p.ln.Addr().Network(), p.pubAddress, p.rid)
 }
 
 // Shutdown stops the proxy service, closing all network connections.
diff --git a/runtimes/google/ipc/stream/proxy/proxy_test.go b/runtimes/google/ipc/stream/proxy/proxy_test.go
index 96b0678..c2ceb14 100644
--- a/runtimes/google/ipc/stream/proxy/proxy_test.go
+++ b/runtimes/google/ipc/stream/proxy/proxy_test.go
@@ -23,7 +23,7 @@
 	// machines cannot resolve IPv6 addresses.
 	// As of April 2014, https://developers.google.com/compute/docs/networking
 	// said that IPv6 is not yet supported.
-	proxy, err := proxy.New(naming.FixedRoutingID(0xbbbbbbbbbbbbbbbb), nil, "tcp4", "127.0.0.1:0")
+	proxy, err := proxy.New(naming.FixedRoutingID(0xbbbbbbbbbbbbbbbb), nil, "tcp4", "127.0.0.1:0", "")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -83,7 +83,7 @@
 }
 
 func TestDuplicateRoutingID(t *testing.T) {
-	proxy, err := proxy.New(naming.FixedRoutingID(0xbbbbbbbbbbbbbbbb), nil, "tcp4", "127.0.0.1:0")
+	proxy, err := proxy.New(naming.FixedRoutingID(0xbbbbbbbbbbbbbbbb), nil, "tcp4", "127.0.0.1:0", "")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -110,7 +110,7 @@
 }
 
 func TestProxyIdentity(t *testing.T) {
-	proxy, err := proxy.New(naming.FixedRoutingID(0xbbbbbbbbbbbbbbbb), security.FakePrivateID("proxy"), "tcp4", "127.0.0.1:0")
+	proxy, err := proxy.New(naming.FixedRoutingID(0xbbbbbbbbbbbbbbbb), security.FakePrivateID("proxy"), "tcp4", "127.0.0.1:0", "")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -134,7 +134,7 @@
 }
 
 func TestServerIdentity(t *testing.T) {
-	proxy, err := proxy.New(naming.FixedRoutingID(0xbbbbbbbbbbbbbbbb), nil, "tcp4", "127.0.0.1:0")
+	proxy, err := proxy.New(naming.FixedRoutingID(0xbbbbbbbbbbbbbbbb), nil, "tcp4", "127.0.0.1:0", "")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -171,7 +171,7 @@
 }
 
 func TestHostPort(t *testing.T) {
-	proxy, err := proxy.New(naming.FixedRoutingID(0xbbbbbbbbbbbbbbbb), nil, "tcp4", "127.0.0.1:0")
+	proxy, err := proxy.New(naming.FixedRoutingID(0xbbbbbbbbbbbbbbbb), nil, "tcp4", "127.0.0.1:0", "")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -188,7 +188,7 @@
 }
 
 func TestClientBecomesServer(t *testing.T) {
-	proxy, err := proxy.New(naming.FixedRoutingID(0xbbbbbbbbbbbbbbbb), nil, "tcp4", "127.0.0.1:0")
+	proxy, err := proxy.New(naming.FixedRoutingID(0xbbbbbbbbbbbbbbbb), nil, "tcp4", "127.0.0.1:0", "")
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/services/wspr/wsprd/lib/wspr_test.go b/services/wspr/wsprd/lib/wspr_test.go
index 288a365..830e3f7 100644
--- a/services/wspr/wsprd/lib/wspr_test.go
+++ b/services/wspr/wsprd/lib/wspr_test.go
@@ -131,7 +131,7 @@
 		return nil, err
 	}
 
-	return proxy.New(rid, nil, "tcp", "127.0.0.1:0")
+	return proxy.New(rid, nil, "tcp", "127.0.0.1:0", "")
 }
 
 func startMountTableServer() (ipc.Server, naming.Endpoint, error) {