x.ref: for CLs 9907 and 9908 that cleanup address selection in v23/rpc.

MultiPart: 3/4
Change-Id: I72ffca8ad774850e0a28d139da5cf7cb9ab546c0
diff --git a/profiles/roaming/net_watcher.go b/profiles/roaming/net_watcher.go
index 579fafb..f4880d4 100644
--- a/profiles/roaming/net_watcher.go
+++ b/profiles/roaming/net_watcher.go
@@ -8,12 +8,14 @@
 
 import (
 	"fmt"
+	"os"
 	"strings"
 
+	"v.io/x/lib/netstate"
+
 	"v.io/v23"
 	"v.io/v23/config"
 
-	"v.io/x/lib/netstate"
 	"v.io/x/ref/profiles/roaming"
 )
 
@@ -25,8 +27,26 @@
 	fmt.Println("Profile: ", profileName)
 
 	accessible, err := netstate.GetAccessibleIPs()
-	routes := netstate.GetRoutes()
-	fmt.Printf("Routes:\n%s\n", strings.Replace(routes.String(), ")", ")\n", -1))
+	interfaces, err := netstate.GetAllInterfaces()
+
+	fmt.Printf("Addresses\n")
+	for _, addr := range accessible {
+		fmt.Printf("%s\n", addr.DebugString())
+	}
+
+	fmt.Printf("\nInterfaces\n")
+	for _, ifc := range interfaces {
+		fmt.Printf("%s\n", ifc)
+	}
+
+	fmt.Printf("\nRoutes\n")
+	for _, ifc := range interfaces {
+		if ipifc, ok := ifc.(netstate.IPNetworkInterface); ok {
+			if routes := ipifc.IPRoutes(); len(routes) > 0 {
+				fmt.Printf("%s: %s\n", ifc.Name(), routes)
+			}
+		}
+	}
 
 	listenSpec := v23.GetListenSpec(ctx)
 	chooser := listenSpec.AddressChooser
@@ -36,17 +56,17 @@
 		}
 	}
 
-	if chosen, err := listenSpec.AddressChooser("tcp", accessible); err != nil {
+	if chosen, err := listenSpec.AddressChooser("tcp", accessible.AsNetAddrs()); err != nil {
 		fmt.Printf("Failed to chosen address %s\n", err)
 	} else {
-		al := netstate.AddrList(chosen)
+		al := netstate.ConvertToAddresses(chosen)
 		fmt.Printf("Chosen:\n%s\n", strings.Replace(al.String(), ") ", ")\n", -1))
 	}
 
 	ch := make(chan config.Setting, 10)
-	settings, err := v23.GetPublisher(ctx).ForkStream(roaming.SettingsStreamName, ch)
+	settings, err := listenSpec.StreamPublisher.ForkStream(roaming.SettingsStreamName, ch)
 	if err != nil {
-		r.Logger().Infof("failed to fork stream: %s", err)
+		fmt.Fprintf(os.Stderr, "failed to fork stream: %s\n", err)
 	}
 	for _, setting := range settings.Latest {
 		fmt.Println("Setting: ", setting)
diff --git a/profiles/roaming/proxy.go b/profiles/roaming/proxy.go
index ed9a6b6..845ad11 100644
--- a/profiles/roaming/proxy.go
+++ b/profiles/roaming/proxy.go
@@ -7,12 +7,13 @@
 import (
 	"v.io/v23/context"
 	"v.io/v23/naming"
+	"v.io/v23/rpc"
 
 	"v.io/x/ref/profiles/internal/rpc/stream/proxy"
 )
 
 // NewProxy creates a new Proxy that listens for network connections on the provided
 // (network, address) pair and routes VC traffic between accepted connections.
-func NewProxy(ctx *context.T, network, address, pubAddress string, names ...string) (shutdown func(), endpoint naming.Endpoint, err error) {
-	return proxy.New(ctx, network, address, pubAddress, names...)
+func NewProxy(ctx *context.T, spec rpc.ListenSpec, names ...string) (shutdown func(), endpoint naming.Endpoint, err error) {
+	return proxy.New(ctx, spec, names...)
 }
diff --git a/profiles/roaming/roaminginit.go b/profiles/roaming/roaminginit.go
index f09f1c6..4996320 100644
--- a/profiles/roaming/roaminginit.go
+++ b/profiles/roaming/roaminginit.go
@@ -15,14 +15,17 @@
 
 import (
 	"flag"
+	"net"
+
+	"v.io/x/lib/netconfig"
+	"v.io/x/lib/netstate"
+	"v.io/x/lib/vlog"
 
 	"v.io/v23"
 	"v.io/v23/config"
 	"v.io/v23/context"
 	"v.io/v23/rpc"
-	"v.io/x/lib/netconfig"
-	"v.io/x/lib/netstate"
-	"v.io/x/lib/vlog"
+
 	"v.io/x/ref/lib/flags"
 	"v.io/x/ref/lib/security/securityflag"
 	"v.io/x/ref/profiles/internal"
@@ -65,8 +68,11 @@
 	// 1:1 NAT configuration.
 	if !internal.HasPublicIP(vlog.Log) {
 		if addr := internal.GCEPublicAddress(vlog.Log); addr != nil {
-			listenSpec.AddressChooser = func(string, []rpc.Address) ([]rpc.Address, error) {
-				return []rpc.Address{&netstate.AddrIfc{addr, "nat", nil}}, nil
+			listenSpec.AddressChooser = func(string, []net.Addr) ([]net.Addr, error) {
+				// TODO(cnicolaou): the protocol at least should
+				// be configurable, or maybe there's a profile specific
+				// flag to configure both the protocol and address.
+				return []net.Addr{netstate.NewNetAddr("wsh", addr.String())}, nil
 			}
 			runtime, ctx, shutdown, err := rt.Init(ctx, ac, nil, &listenSpec, commonFlags.RuntimeFlags(), reservedDispatcher)
 			if err != nil {
@@ -146,6 +152,7 @@
 	for {
 		select {
 		case <-watcher.Channel():
+			netstate.InvalidateCache()
 			cur, err := netstate.GetAccessibleIPs()
 			if err != nil {
 				vlog.Errorf("failed to read network state: %s", err)
@@ -163,10 +170,10 @@
 			}
 			if len(removed) > 0 {
 				vlog.VI(2).Infof("Sending removed: %s", removed)
-				ch <- rpc.NewRmAddrsSetting(removed)
+				ch <- rpc.NewRmAddrsSetting(removed.AsNetAddrs())
 			}
 			// We will always send the best currently available address
-			if chosen, err := listenSpec.AddressChooser(listenSpec.Addrs[0].Protocol, cur); err == nil && chosen != nil {
+			if chosen, err := listenSpec.AddressChooser(listenSpec.Addrs[0].Protocol, cur.AsNetAddrs()); err == nil && chosen != nil {
 				vlog.VI(2).Infof("Sending added and chosen: %s", chosen)
 				ch <- rpc.NewAddAddrsSetting(chosen)
 			} else {