veyron/runtimes/google/ipc: Pass the preferred protocols to the
InternalNewServer so it can use them when resolving the proxy name to an
endpoint.

Change-Id: Ic2bffecd727fc5eef7422c48ac215d93677794b6
diff --git a/runtimes/google/ipc/server.go b/runtimes/google/ipc/server.go
index b90dbe4..78c638f 100644
--- a/runtimes/google/ipc/server.go
+++ b/runtimes/google/ipc/server.go
@@ -36,18 +36,19 @@
 
 type server struct {
 	sync.Mutex
-	ctx              context.T                         // context used by the server to make internal RPCs.
-	streamMgr        stream.Manager                    // stream manager to listen for new flows.
-	publisher        publisher.Publisher               // publisher to publish mounttable mounts.
-	listenerOpts     []stream.ListenerOpt              // listener opts passed to Listen.
-	listeners        map[stream.Listener]*dhcpListener // listeners created by Listen.
-	disp             ipc.Dispatcher                    // dispatcher to serve RPCs
-	dispReserved     ipc.Dispatcher                    // dispatcher for reserved methods
-	active           sync.WaitGroup                    // active goroutines we've spawned.
-	stopped          bool                              // whether the server has been stopped.
-	stoppedChan      chan struct{}                     // closed when the server has been stopped.
-	ns               naming.Namespace
-	servesMountTable bool
+	ctx                context.T                         // context used by the server to make internal RPCs.
+	streamMgr          stream.Manager                    // stream manager to listen for new flows.
+	publisher          publisher.Publisher               // publisher to publish mounttable mounts.
+	listenerOpts       []stream.ListenerOpt              // listener opts passed to Listen.
+	listeners          map[stream.Listener]*dhcpListener // listeners created by Listen.
+	disp               ipc.Dispatcher                    // dispatcher to serve RPCs
+	dispReserved       ipc.Dispatcher                    // dispatcher for reserved methods
+	active             sync.WaitGroup                    // active goroutines we've spawned.
+	stopped            bool                              // whether the server has been stopped.
+	stoppedChan        chan struct{}                     // closed when the server has been stopped.
+	preferredProtocols []string                          // protocols to use when resolving proxy name to endpoint.
+	ns                 naming.Namespace
+	servesMountTable   bool
 	// TODO(cnicolaou): remove this when the publisher tracks published names
 	// and can return an appropriate error for RemoveName on a name that
 	// wasn't 'Added' for this server.
@@ -69,6 +70,12 @@
 	ch        chan config.Setting // channel to receive settings over
 }
 
+// This option is used to sort and filter the endpoints when resolving the
+// proxy name from a mounttable.
+type PreferredServerResolveProtocols []string
+
+func (PreferredServerResolveProtocols) IPCServerOpt() {}
+
 func InternalNewServer(ctx context.T, streamMgr stream.Manager, ns naming.Namespace, store *ivtrace.Store, opts ...ipc.ServerOpt) (ipc.Server, error) {
 	ctx, _ = ivtrace.WithNewSpan(ctx, "NewServer")
 	statsPrefix := naming.Join("ipc", "server", "routing-id", streamMgr.RoutingID().String())
@@ -101,6 +108,8 @@
 			s.servesMountTable = bool(opt)
 		case options.ReservedNameDispatcher:
 			s.dispReserved = opt.Dispatcher
+		case PreferredServerResolveProtocols:
+			s.preferredProtocols = []string(opt)
 		}
 	}
 	blessingsStatsName := naming.Join(statsPrefix, "security", "blessings")
@@ -141,7 +150,12 @@
 	} else {
 		names = append(names, address)
 	}
-	for _, n := range names {
+	// An empty set of protocols means all protocols...
+	ordered, err := filterAndOrderServers(names, s.preferredProtocols)
+	if err != nil {
+		return "", err
+	}
+	for _, n := range ordered {
 		address, suffix := naming.SplitAddressName(n)
 		if suffix != "" {
 			continue