veyron2/ipc: force all protocols, including tcp, to be registered.

- this change implements and uses a consistent mechanism for
  registering the stream transport protocols to be used with RPC.
- it treats 'tcp' the same as any other 'user defined' protocol, such
  as websockets or unixfd
- protocols are generally registered by importing their package, whose
  init function performs the actual registration.
- the protocol packages should only be imported by profiles.
- in a future change, I propose to move lib/tcp, lib/websocket and lib/unixfd
  to profiles/internal.

Change-Id: I139757441b865c9b22778d1f2d9d1d2586357d35
diff --git a/lib/tcp/init.go b/lib/tcp/init.go
new file mode 100644
index 0000000..a62422e
--- /dev/null
+++ b/lib/tcp/init.go
@@ -0,0 +1,37 @@
+package tcp
+
+import (
+	"fmt"
+	"net"
+	"time"
+
+	"veyron.io/veyron/veyron2/ipc/stream"
+
+	"veyron.io/veyron/veyron/lib/websocket"
+)
+
+func dialer(network, address string, timeout time.Duration) (net.Conn, error) {
+	conn, err := net.DialTimeout(network, address, timeout)
+	if err != nil {
+		return nil, err
+	}
+	// For tcp connections we add an extra magic byte so we can differentiate between
+	// raw tcp and websocket on the same port.
+	switch n, err := conn.Write([]byte{websocket.BinaryMagicByte}); {
+	case err != nil:
+		return nil, err
+	case n != 1:
+		return nil, fmt.Errorf("Unable to write the magic byte")
+	}
+	return conn, nil
+}
+
+func listener(network, address string) (net.Listener, error) {
+	return net.Listen(network, address)
+}
+
+func init() {
+	for _, p := range []string{"tcp", "tcp4", "tcp6"} {
+		stream.RegisterProtocol(p, dialer, listener)
+	}
+}
diff --git a/lib/unixfd/unixfd.go b/lib/unixfd/unixfd.go
index 2cdcc36..028dd26 100644
--- a/lib/unixfd/unixfd.go
+++ b/lib/unixfd/unixfd.go
@@ -11,7 +11,9 @@
 	"strconv"
 	"sync"
 	"syscall"
+	"time"
 	"unsafe"
+
 	"veyron.io/veyron/veyron2/ipc/stream"
 )
 
@@ -63,7 +65,11 @@
 	return l.addr
 }
 
-func unixFDConn(address string) (net.Conn, error) {
+func unixFDConn(protocol, address string, timeout time.Duration) (net.Conn, error) {
+	// TODO(cnicolaou): have this respect the timeout. Possibly have a helper
+	// function that can be generally used for this, but in practice, I think
+	// it'll be cleaner to use the underlying protocol's deadline support of it
+	// has it.
 	fd, err := strconv.ParseInt(address, 10, 32)
 	if err != nil {
 		return nil, err
@@ -100,8 +106,8 @@
 	return c.addr
 }
 
-func unixFDListen(address string) (net.Listener, error) {
-	conn, err := unixFDConn(address)
+func unixFDListen(protocol, address string) (net.Listener, error) {
+	conn, err := unixFDConn(protocol, address, 0)
 	if err != nil {
 		return nil, err
 	}
diff --git a/lib/unixfd/unixfd_test.go b/lib/unixfd/unixfd_test.go
index 74a2c65..91a3e33 100644
--- a/lib/unixfd/unixfd_test.go
+++ b/lib/unixfd/unixfd_test.go
@@ -12,13 +12,13 @@
 
 func dial(fd *fileDescriptor) (net.Conn, net.Addr, error) {
 	addr := fd.releaseAddr()
-	conn, err := unixFDConn(addr.String())
+	conn, err := unixFDConn(Network, addr.String(), 0)
 	return conn, addr, err
 }
 
 func listen(fd *fileDescriptor) (net.Listener, net.Addr, error) {
 	addr := fd.releaseAddr()
-	l, err := unixFDListen(addr.String())
+	l, err := unixFDListen(Network, addr.String())
 	return l, addr, err
 }
 
@@ -161,11 +161,11 @@
 		t.Fatalf("unexpected data %q", data)
 	}
 
-	a, err := unixFDConn(caddr.String())
+	a, err := unixFDConn(Network, caddr.String(), 0)
 	if err != nil {
 		t.Fatalf("dial %v: %v", caddr, err)
 	}
-	b, err := unixFDConn(saddr.String())
+	b, err := unixFDConn(Network, saddr.String(), 0)
 	if err != nil {
 		t.Fatalf("dial %v: %v", saddr, err)
 	}
diff --git a/lib/websocket/init.go b/lib/websocket/init.go
new file mode 100644
index 0000000..ac60189
--- /dev/null
+++ b/lib/websocket/init.go
@@ -0,0 +1,27 @@
+package websocket
+
+import (
+	"net"
+	"time"
+
+	"veyron.io/veyron/veyron2/ipc/stream"
+)
+
+func wsListener(protocol, address string) (net.Listener, error) {
+	ln, err := net.Listen(protocol, address)
+	if err != nil {
+		return nil, err
+	}
+	return NewListener(ln)
+}
+
+func wsDialer(protocol, address string, timeout time.Duration) (net.Conn, error) {
+	// TODO(cnicolaou): implement timeout support.
+	return Dial(address)
+}
+
+func init() {
+	for _, p := range []string{"ws", "ws4", "ws6"} {
+		stream.RegisterProtocol(p, wsDialer, wsListener)
+	}
+}
diff --git a/runtimes/google/ipc/stream/wslistener/listener.go b/lib/websocket/listener.go
similarity index 96%
rename from runtimes/google/ipc/stream/wslistener/listener.go
rename to lib/websocket/listener.go
index 79dc035..80cc980 100644
--- a/runtimes/google/ipc/stream/wslistener/listener.go
+++ b/lib/websocket/listener.go
@@ -1,6 +1,6 @@
 // +build !nacl
 
-package wslistener
+package websocket
 
 import (
 	"bufio"
@@ -10,12 +10,11 @@
 	"net/http"
 	"sync"
 
-	vwebsocket "veyron.io/veyron/veyron/lib/websocket"
-	"veyron.io/veyron/veyron/runtimes/google/lib/upcqueue"
+	"github.com/gorilla/websocket"
 
 	"veyron.io/veyron/veyron2/vlog"
 
-	"github.com/gorilla/websocket"
+	"veyron.io/veyron/veyron/runtimes/google/lib/upcqueue"
 )
 
 var errListenerIsClosed = errors.New("Listener has been Closed")
@@ -93,7 +92,7 @@
 	return l.ln.Addr()
 }
 
-func NewListener(netLn net.Listener) net.Listener {
+func NewListener(netLn net.Listener) (net.Listener, error) {
 	ln := &wsTCPListener{
 		q:     upcqueue.New(),
 		httpQ: upcqueue.New(),
@@ -121,19 +120,18 @@
 			vlog.Errorf("Rejected a non-websocket request: %v", err)
 			return
 		}
-		conn := vwebsocket.WebsocketConn(ws)
+		conn := WebsocketConn(ws)
 		if err := ln.q.Put(conn); err != nil {
 			vlog.VI(1).Infof("Shutting down conn from %s (local address: %s) as Put failed: %v", ws.RemoteAddr(), ws.LocalAddr(), err)
 			ws.Close()
 			return
 		}
-
 	}
 	ln.wsServer = http.Server{
 		Handler: http.HandlerFunc(handler),
 	}
 	go ln.wsServer.Serve(httpListener)
-	return ln
+	return ln, nil
 }
 
 func (ln *wsTCPListener) netAcceptLoop() {
diff --git a/lib/websocket/listener_nacl.go b/lib/websocket/listener_nacl.go
new file mode 100644
index 0000000..df89e2b
--- /dev/null
+++ b/lib/websocket/listener_nacl.go
@@ -0,0 +1,17 @@
+// +build nacl
+
+package websocket
+
+import (
+	"fmt"
+	"net"
+)
+
+// Websocket listeners are not supported in NaCl.
+// This file is needed for compilation only.
+
+const BinaryMagicByte byte = 0x90
+
+func NewListener(netLn net.Listener) (net.Listener, error) {
+	return nil, fmt.Errorf("Websocket NewListener called in nacl code!")
+}
diff --git a/profiles/chrome/chrome.go b/profiles/chrome/chrome.go
index cfead4e..9d16365 100644
--- a/profiles/chrome/chrome.go
+++ b/profiles/chrome/chrome.go
@@ -9,7 +9,8 @@
 	"veyron.io/veyron/veyron2/options"
 	"veyron.io/veyron/veyron2/rt"
 
-	"veyron.io/veyron/veyron/profiles"
+	_ "veyron.io/veyron/veyron/lib/websocket"
+	"veyron.io/veyron/veyron/profiles/internal/platform"
 )
 
 var ListenSpec = ipc.ListenSpec{}
@@ -35,7 +36,7 @@
 }
 
 func (*chrome) Platform() *veyron2.Platform {
-	p, _ := profiles.Platform()
+	p, _ := platform.Platform()
 	return p
 }
 
diff --git a/profiles/doc.go b/profiles/doc.go
index 635df9d..3c4ab07 100644
--- a/profiles/doc.go
+++ b/profiles/doc.go
@@ -10,11 +10,14 @@
 //
 // Profiles register themselves by calling veyron2/rt.RegisterProfile in their
 // init function and are hence are chosen by importing them into an
-// applications main package. More specific packages may use functionality
-// exposed by more general packages and rely on go's module dependency
-// algorithm to execute the init function from the more specific package
-// after the less specific one and hence override the earlier Profile
-// registration.
+// applications main package. It is possible, but discouraged, for more
+// specific packages may use functionality exposed by more general packages
+// and rely on go's module dependency algorithm to execute the init function
+// from the more specific package after the less specific one and hence
+// override the earlier Profile registration. This is discouraged because it
+// is harder for the reader to track the dependencies to see what is included
+// by each package. Commonly used functionality is placed in profiles/internal
+// for use by all profiles.
 //
 // This top level directory contains a 'generic' Profile and utility routines
 // used by other Profiles. It should be imported whenever possible and
diff --git a/profiles/gce/init.go b/profiles/gce/init.go
index b0143a7..d0f666c 100644
--- a/profiles/gce/init.go
+++ b/profiles/gce/init.go
@@ -17,8 +17,11 @@
 	"veyron.io/veyron/veyron/lib/appcycle"
 	"veyron.io/veyron/veyron/lib/flags"
 	"veyron.io/veyron/veyron/lib/netstate"
-	"veyron.io/veyron/veyron/profiles"
+	_ "veyron.io/veyron/veyron/lib/tcp"
+	_ "veyron.io/veyron/veyron/lib/websocket"
 	"veyron.io/veyron/veyron/profiles/internal/gce"
+	"veyron.io/veyron/veyron/profiles/internal/platform"
+	_ "veyron.io/veyron/veyron/runtimes/google/rt"
 )
 
 var (
@@ -49,8 +52,8 @@
 }
 
 func (p *profile) Platform() *veyron2.Platform {
-	platform, _ := profiles.Platform()
-	return platform
+	pstr, _ := platform.Platform()
+	return pstr
 }
 
 func (p *profile) String() string {
diff --git a/profiles/generic.go b/profiles/generic.go
index 96ddcb7..7442cda 100644
--- a/profiles/generic.go
+++ b/profiles/generic.go
@@ -7,7 +7,10 @@
 	"veyron.io/veyron/veyron2/rt"
 
 	"veyron.io/veyron/veyron/lib/appcycle"
+	_ "veyron.io/veyron/veyron/lib/tcp"
+	_ "veyron.io/veyron/veyron/lib/websocket"
 	"veyron.io/veyron/veyron/profiles/internal"
+	"veyron.io/veyron/veyron/profiles/internal/platform"
 	_ "veyron.io/veyron/veyron/runtimes/google/rt"
 )
 
@@ -41,8 +44,8 @@
 }
 
 func (*generic) Platform() *veyron2.Platform {
-	p, _ := Platform()
-	return p
+	pstr, _ := platform.Platform()
+	return pstr
 }
 
 func (g *generic) Init(rt veyron2.Runtime, _ *config.Publisher) (veyron2.AppCycle, error) {
diff --git a/profiles/platform_darwin.go b/profiles/internal/platform/platform_darwin.go
similarity index 97%
rename from profiles/platform_darwin.go
rename to profiles/internal/platform/platform_darwin.go
index c4a36fa..22d788c 100644
--- a/profiles/platform_darwin.go
+++ b/profiles/internal/platform/platform_darwin.go
@@ -1,4 +1,4 @@
-package profiles
+package platform
 
 // #include <sys/utsname.h>
 // #include <errno.h>
diff --git a/profiles/platform_linux.go b/profiles/internal/platform/platform_linux.go
similarity index 97%
rename from profiles/platform_linux.go
rename to profiles/internal/platform/platform_linux.go
index f0d969f..5a34b14 100644
--- a/profiles/platform_linux.go
+++ b/profiles/internal/platform/platform_linux.go
@@ -1,4 +1,4 @@
-package profiles
+package platform
 
 import (
 	"syscall"
diff --git a/profiles/platform_nacl.go b/profiles/internal/platform/platform_nacl.go
similarity index 96%
rename from profiles/platform_nacl.go
rename to profiles/internal/platform/platform_nacl.go
index 0b73e9c..5ae8c67 100644
--- a/profiles/platform_nacl.go
+++ b/profiles/internal/platform/platform_nacl.go
@@ -1,6 +1,6 @@
 // +build nacl
 
-package profiles
+package platform
 
 import (
 	"veyron.io/veyron/veyron2"
diff --git a/profiles/uts_str_linux_arm.go b/profiles/internal/platform/uts_str_linux_arm.go
similarity index 94%
rename from profiles/uts_str_linux_arm.go
rename to profiles/internal/platform/uts_str_linux_arm.go
index f2326ab..c519595 100644
--- a/profiles/uts_str_linux_arm.go
+++ b/profiles/internal/platform/uts_str_linux_arm.go
@@ -1,6 +1,6 @@
 // +build linux,arm
 
-package profiles
+package platform
 
 // str converts the input byte slice to a string, ignoring everything following
 // a null character (including the null character).
diff --git a/profiles/uts_str_linux_nonarm.go b/profiles/internal/platform/uts_str_linux_nonarm.go
similarity index 94%
rename from profiles/uts_str_linux_nonarm.go
rename to profiles/internal/platform/uts_str_linux_nonarm.go
index 4a97742..84256e5 100644
--- a/profiles/uts_str_linux_nonarm.go
+++ b/profiles/internal/platform/uts_str_linux_nonarm.go
@@ -1,6 +1,6 @@
 // +build linux,!arm
 
-package profiles
+package platform
 
 // str converts the input byte slice to a string, ignoring everything following
 // a null character (including the null character).
diff --git a/profiles/roaming/roaming.go b/profiles/roaming/roaming.go
index 837a5b8..4bf8b26 100644
--- a/profiles/roaming/roaming.go
+++ b/profiles/roaming/roaming.go
@@ -22,9 +22,13 @@
 	"veyron.io/veyron/veyron/lib/flags"
 	"veyron.io/veyron/veyron/lib/netconfig"
 	"veyron.io/veyron/veyron/lib/netstate"
-	"veyron.io/veyron/veyron/profiles"
+	_ "veyron.io/veyron/veyron/lib/tcp"
+	_ "veyron.io/veyron/veyron/lib/websocket"
 	"veyron.io/veyron/veyron/profiles/internal"
+	"veyron.io/veyron/veyron/profiles/internal/platform"
+	_ "veyron.io/veyron/veyron/runtimes/google/rt"
 	"veyron.io/veyron/veyron/services/mgmt/debug"
+
 	// TODO(cnicolaou,ashankar): move this into flags.
 	sflag "veyron.io/veyron/veyron/security/flag"
 )
@@ -56,8 +60,8 @@
 }
 
 func (p *profile) Platform() *veyron2.Platform {
-	platform, _ := profiles.Platform()
-	return platform
+	pstr, _ := platform.Platform()
+	return pstr
 }
 
 func (p *profile) Name() string {
diff --git a/profiles/static/static.go b/profiles/static/static.go
index 2720f1d..86cda56 100644
--- a/profiles/static/static.go
+++ b/profiles/static/static.go
@@ -14,8 +14,11 @@
 	"veyron.io/veyron/veyron/lib/appcycle"
 	"veyron.io/veyron/veyron/lib/flags"
 	"veyron.io/veyron/veyron/lib/netstate"
-	"veyron.io/veyron/veyron/profiles"
+	_ "veyron.io/veyron/veyron/lib/tcp"
+	_ "veyron.io/veyron/veyron/lib/websocket"
 	"veyron.io/veyron/veyron/profiles/internal"
+	"veyron.io/veyron/veyron/profiles/internal/platform"
+	_ "veyron.io/veyron/veyron/runtimes/google/rt"
 	"veyron.io/veyron/veyron/services/mgmt/debug"
 	// TODO(cnicolaou,ashankar): move this into flags.
 	sflag "veyron.io/veyron/veyron/security/flag"
@@ -53,8 +56,8 @@
 }
 
 func (*static) Platform() *veyron2.Platform {
-	p, _ := profiles.Platform()
-	return p
+	pstr, _ := platform.Platform()
+	return pstr
 }
 
 func (p *static) Init(rt veyron2.Runtime, _ *config.Publisher) (veyron2.AppCycle, error) {
diff --git a/runtimes/google/ipc/full_test.go b/runtimes/google/ipc/full_test.go
index 221978b..c796e26 100644
--- a/runtimes/google/ipc/full_test.go
+++ b/runtimes/google/ipc/full_test.go
@@ -27,9 +27,10 @@
 	"veyron.io/veyron/veyron2/vlog"
 
 	"veyron.io/veyron/veyron/lib/netstate"
+	_ "veyron.io/veyron/veyron/lib/tcp"
 	"veyron.io/veyron/veyron/lib/testutil"
 	tsecurity "veyron.io/veyron/veyron/lib/testutil/security"
-	"veyron.io/veyron/veyron/lib/websocket"
+	_ "veyron.io/veyron/veyron/lib/websocket"
 	imanager "veyron.io/veyron/veyron/runtimes/google/ipc/stream/manager"
 	"veyron.io/veyron/veyron/runtimes/google/ipc/stream/vc"
 	"veyron.io/veyron/veyron/runtimes/google/lib/publisher"
@@ -38,10 +39,6 @@
 	ivtrace "veyron.io/veyron/veyron/runtimes/google/vtrace"
 )
 
-func init() {
-	stream.RegisterProtocol("ws", websocket.Dial, nil)
-}
-
 var (
 	errMethod  = verror.Make(verror.Aborted, nil)
 	clock      = new(fakeClock)
diff --git a/runtimes/google/ipc/stream/manager/manager.go b/runtimes/google/ipc/stream/manager/manager.go
index a96c725..a2ad073 100644
--- a/runtimes/google/ipc/stream/manager/manager.go
+++ b/runtimes/google/ipc/stream/manager/manager.go
@@ -9,17 +9,17 @@
 	"sync"
 	"time"
 
-	"veyron.io/veyron/veyron/lib/stats"
-	"veyron.io/veyron/veyron/runtimes/google/ipc/stream/crypto"
-	"veyron.io/veyron/veyron/runtimes/google/ipc/stream/vif"
-	"veyron.io/veyron/veyron/runtimes/google/ipc/stream/wslistener"
-	"veyron.io/veyron/veyron/runtimes/google/ipc/version"
-	inaming "veyron.io/veyron/veyron/runtimes/google/naming"
-
 	"veyron.io/veyron/veyron2/ipc/stream"
 	"veyron.io/veyron/veyron2/naming"
 	"veyron.io/veyron/veyron2/verror"
 	"veyron.io/veyron/veyron2/vlog"
+
+	"veyron.io/veyron/veyron/lib/stats"
+	"veyron.io/veyron/veyron/lib/websocket"
+	"veyron.io/veyron/veyron/runtimes/google/ipc/stream/crypto"
+	"veyron.io/veyron/veyron/runtimes/google/ipc/stream/vif"
+	"veyron.io/veyron/veyron/runtimes/google/ipc/version"
+	inaming "veyron.io/veyron/veyron/runtimes/google/naming"
 )
 
 var errShutDown = errors.New("manager has been shut down")
@@ -63,22 +63,9 @@
 
 func dial(network, address string, timeout time.Duration) (net.Conn, error) {
 	if d, _ := stream.RegisteredProtocol(network); d != nil {
-		return d(address)
+		return d(network, address, timeout)
 	}
-	conn, err := net.DialTimeout(network, address, timeout)
-	if err != nil || !strings.HasPrefix(network, "tcp") {
-		return conn, err
-	}
-
-	// For tcp connections we add an extra magic byte so we can differentiate between
-	// raw tcp and websocket on the same port.
-	switch n, err := conn.Write([]byte{wslistener.BinaryMagicByte}); {
-	case err != nil:
-		return nil, err
-	case n != 1:
-		return nil, fmt.Errorf("Unable to write the magic byte")
-	}
-	return conn, nil
+	return nil, fmt.Errorf("unknown network %s", network)
 }
 
 // FindOrDialVIF returns the network connection (VIF) to the provided address
@@ -160,9 +147,9 @@
 
 func listen(protocol, address string) (net.Listener, error) {
 	if _, l := stream.RegisteredProtocol(protocol); l != nil {
-		return l(address)
+		return l(protocol, address)
 	}
-	return net.Listen(protocol, address)
+	return nil, fmt.Errorf("unknown network %s", protocol)
 }
 
 func (m *manager) Listen(protocol, address string, opts ...stream.ListenerOpt) (stream.Listener, naming.Endpoint, error) {
@@ -196,7 +183,12 @@
 	// If the protocol is tcp, we add the listener that supports both tcp and websocket
 	// so that javascript can talk to this server.
 	if strings.HasPrefix(protocol, "tcp") {
-		netln = wslistener.NewListener(netln)
+		wsln, err := websocket.NewListener(netln)
+		if err != nil {
+			netln.Close()
+			return nil, nil, err
+		}
+		netln = wsln
 	}
 	ln := newNetListener(m, netln, opts)
 	m.listeners[ln] = true
diff --git a/runtimes/google/ipc/stream/manager/manager_test.go b/runtimes/google/ipc/stream/manager/manager_test.go
index 829800f..aa66c0d 100644
--- a/runtimes/google/ipc/stream/manager/manager_test.go
+++ b/runtimes/google/ipc/stream/manager/manager_test.go
@@ -12,7 +12,6 @@
 	"testing"
 	"time"
 
-	"veyron.io/veyron/veyron/lib/websocket"
 	"veyron.io/veyron/veyron2/ipc/stream"
 	"veyron.io/veyron/veyron2/naming"
 	"veyron.io/veyron/veyron2/security"
@@ -20,8 +19,10 @@
 
 	"veyron.io/veyron/veyron/lib/expect"
 	"veyron.io/veyron/veyron/lib/modules"
+	_ "veyron.io/veyron/veyron/lib/tcp"
 	"veyron.io/veyron/veyron/lib/testutil"
 	tsecurity "veyron.io/veyron/veyron/lib/testutil/security"
+	_ "veyron.io/veyron/veyron/lib/websocket"
 	"veyron.io/veyron/veyron/runtimes/google/ipc/stream/vc"
 	"veyron.io/veyron/veyron/runtimes/google/ipc/version"
 	inaming "veyron.io/veyron/veyron/runtimes/google/naming"
@@ -39,7 +40,6 @@
 	// introduces less variance in the behavior of the test.
 	runtime.GOMAXPROCS(1)
 	modules.RegisterChild("runServer", "", runServer)
-	stream.RegisterProtocol("ws", websocket.Dial, nil)
 }
 
 func testSimpleFlow(t *testing.T, useWebsocket bool) {
@@ -673,10 +673,10 @@
 	server := InternalNew(naming.FixedRoutingID(0x55555555))
 	client := InternalNew(naming.FixedRoutingID(0xcccccccc))
 
-	dialer := func(addr string) (net.Conn, error) {
+	dialer := func(_, _ string, _ time.Duration) (net.Conn, error) {
 		return nil, fmt.Errorf("tn.Dial")
 	}
-	listener := func(addr string) (net.Listener, error) {
+	listener := func(_, _ string) (net.Listener, error) {
 		return nil, fmt.Errorf("tn.Listen")
 	}
 	stream.RegisterProtocol("tn", dialer, listener)
@@ -692,7 +692,7 @@
 	}
 
 	// Need a functional listener to test Dial.
-	listener = func(addr string) (net.Listener, error) {
+	listener = func(_, addr string) (net.Listener, error) {
 		return net.Listen("tcp", addr)
 	}
 
diff --git a/runtimes/google/ipc/stream/proxy/proxy.go b/runtimes/google/ipc/stream/proxy/proxy.go
index 0da73ce..eddef79 100644
--- a/runtimes/google/ipc/stream/proxy/proxy.go
+++ b/runtimes/google/ipc/stream/proxy/proxy.go
@@ -6,23 +6,23 @@
 	"net"
 	"sync"
 
-	"veyron.io/veyron/veyron/runtimes/google/ipc/stream/crypto"
-	"veyron.io/veyron/veyron/runtimes/google/ipc/stream/id"
-	"veyron.io/veyron/veyron/runtimes/google/ipc/stream/message"
-	"veyron.io/veyron/veyron/runtimes/google/ipc/stream/vc"
-	"veyron.io/veyron/veyron/runtimes/google/ipc/stream/vif"
-	"veyron.io/veyron/veyron/runtimes/google/ipc/stream/wslistener"
-	"veyron.io/veyron/veyron/runtimes/google/ipc/version"
-	"veyron.io/veyron/veyron/runtimes/google/lib/bqueue"
-	"veyron.io/veyron/veyron/runtimes/google/lib/bqueue/drrqueue"
-	"veyron.io/veyron/veyron/runtimes/google/lib/iobuf"
-	"veyron.io/veyron/veyron/runtimes/google/lib/upcqueue"
-
 	"veyron.io/veyron/veyron2/naming"
 	"veyron.io/veyron/veyron2/security"
 	"veyron.io/veyron/veyron2/verror"
 	"veyron.io/veyron/veyron2/vlog"
 	"veyron.io/veyron/veyron2/vom"
+
+	"veyron.io/veyron/veyron/lib/websocket"
+	"veyron.io/veyron/veyron/runtimes/google/ipc/stream/crypto"
+	"veyron.io/veyron/veyron/runtimes/google/ipc/stream/id"
+	"veyron.io/veyron/veyron/runtimes/google/ipc/stream/message"
+	"veyron.io/veyron/veyron/runtimes/google/ipc/stream/vc"
+	"veyron.io/veyron/veyron/runtimes/google/ipc/stream/vif"
+	"veyron.io/veyron/veyron/runtimes/google/ipc/version"
+	"veyron.io/veyron/veyron/runtimes/google/lib/bqueue"
+	"veyron.io/veyron/veyron/runtimes/google/lib/bqueue/drrqueue"
+	"veyron.io/veyron/veyron/runtimes/google/lib/iobuf"
+	"veyron.io/veyron/veyron/runtimes/google/lib/upcqueue"
 )
 
 var (
@@ -136,7 +136,10 @@
 	if err != nil {
 		return nil, fmt.Errorf("net.Listen(%q, %q) failed: %v", network, address, err)
 	}
-	ln = wslistener.NewListener(ln)
+	ln, err = websocket.NewListener(ln)
+	if err != nil {
+		return nil, err
+	}
 	if len(pubAddress) == 0 {
 		pubAddress = ln.Addr().String()
 	}
diff --git a/runtimes/google/ipc/stream/proxy/proxy_test.go b/runtimes/google/ipc/stream/proxy/proxy_test.go
index c2d9f62..efb08e0 100644
--- a/runtimes/google/ipc/stream/proxy/proxy_test.go
+++ b/runtimes/google/ipc/stream/proxy/proxy_test.go
@@ -11,6 +11,7 @@
 	"veyron.io/veyron/veyron2/ipc/stream"
 	"veyron.io/veyron/veyron2/naming"
 
+	_ "veyron.io/veyron/veyron/lib/tcp"
 	"veyron.io/veyron/veyron/lib/testutil"
 	tsecurity "veyron.io/veyron/veyron/lib/testutil/security"
 	"veyron.io/veyron/veyron/runtimes/google/ipc/stream/manager"
diff --git a/runtimes/google/ipc/stream/wslistener/listener_nacl.go b/runtimes/google/ipc/stream/wslistener/listener_nacl.go
deleted file mode 100644
index 686dfff..0000000
--- a/runtimes/google/ipc/stream/wslistener/listener_nacl.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// +build nacl
-
-package wslistener
-
-import (
-	"net"
-)
-
-// Websocket listeners are not supported in NaCl.
-// This file is needed for compilation only.
-
-const BinaryMagicByte byte = 0x90
-
-func NewListener(netLn net.Listener) net.Listener {
-	panic("Websocket NewListener called in nacl code!")
-}
diff --git a/runtimes/google/naming/namespace/all_test.go b/runtimes/google/naming/namespace/all_test.go
index 272bbfe..64c1cd2 100644
--- a/runtimes/google/naming/namespace/all_test.go
+++ b/runtimes/google/naming/namespace/all_test.go
@@ -11,7 +11,6 @@
 	"veyron.io/veyron/veyron2"
 	"veyron.io/veyron/veyron2/context"
 	"veyron.io/veyron/veyron2/ipc"
-	"veyron.io/veyron/veyron2/ipc/stream"
 	"veyron.io/veyron/veyron2/naming"
 	"veyron.io/veyron/veyron2/options"
 	"veyron.io/veyron/veyron2/rt"
@@ -20,7 +19,6 @@
 	"veyron.io/veyron/veyron2/vlog"
 
 	"veyron.io/veyron/veyron/lib/testutil"
-	"veyron.io/veyron/veyron/lib/websocket"
 	_ "veyron.io/veyron/veyron/profiles"
 	"veyron.io/veyron/veyron/runtimes/google/naming/namespace"
 	vsecurity "veyron.io/veyron/veyron/security"
@@ -29,7 +27,6 @@
 
 func init() {
 	testutil.Init()
-	stream.RegisterProtocol("ws", websocket.Dial, nil)
 }
 
 func createRuntimes(t *testing.T) (sr, r veyron2.Runtime, cleanup func()) {
diff --git a/runtimes/google/vtrace/vtrace_test.go b/runtimes/google/vtrace/vtrace_test.go
index bc9cb87..c359323 100644
--- a/runtimes/google/vtrace/vtrace_test.go
+++ b/runtimes/google/vtrace/vtrace_test.go
@@ -4,12 +4,6 @@
 	"strings"
 	"testing"
 
-	iipc "veyron.io/veyron/veyron/runtimes/google/ipc"
-	"veyron.io/veyron/veyron/runtimes/google/ipc/stream/manager"
-	tnaming "veyron.io/veyron/veyron/runtimes/google/testing/mocks/naming"
-	truntime "veyron.io/veyron/veyron/runtimes/google/testing/mocks/runtime"
-	ivtrace "veyron.io/veyron/veyron/runtimes/google/vtrace"
-
 	"veyron.io/veyron/veyron2/context"
 	"veyron.io/veyron/veyron2/ipc"
 	"veyron.io/veyron/veyron2/ipc/stream"
@@ -17,6 +11,13 @@
 	"veyron.io/veyron/veyron2/security"
 	"veyron.io/veyron/veyron2/vlog"
 	"veyron.io/veyron/veyron2/vtrace"
+
+	_ "veyron.io/veyron/veyron/lib/tcp"
+	iipc "veyron.io/veyron/veyron/runtimes/google/ipc"
+	"veyron.io/veyron/veyron/runtimes/google/ipc/stream/manager"
+	tnaming "veyron.io/veyron/veyron/runtimes/google/testing/mocks/naming"
+	truntime "veyron.io/veyron/veyron/runtimes/google/testing/mocks/runtime"
+	ivtrace "veyron.io/veyron/veyron/runtimes/google/vtrace"
 )
 
 // We need a special way to create contexts for tests.  We