add Addr() string to net.Listener interface.
use it to avoid use of fixed ports in tests.
convert google/net/rpc to gotest

R=r
DELTA=523  (275 added, 229 deleted, 19 changed)
OCL=30458
CL=30460
diff --git a/src/pkg/Makefile b/src/pkg/Makefile
index 3339a9d..b8eb864 100644
--- a/src/pkg/Makefile
+++ b/src/pkg/Makefile
@@ -70,12 +70,14 @@
 	archive/tar\
 	bignum\
 	bufio\
+	bytes\
 	compress/flate\
 	compress/gzip\
 	container/list\
 	container/vector\
 	crypto/aes\
 	crypto/block\
+	crypto/hmac\
 	crypto/md5\
 	crypto/sha1\
 	datafmt\
diff --git a/src/pkg/net/fd.go b/src/pkg/net/fd.go
index 9404ed0..befcd55 100644
--- a/src/pkg/net/fd.go
+++ b/src/pkg/net/fd.go
@@ -427,3 +427,12 @@
 	return nfd, nil
 }
 
+func (fd *netFD) addr() string {
+	sa, err := syscall.Getsockname(fd.fd);
+	if err != 0 {
+		return "";
+	}
+	// TODO(rsc): woud like to say err not err1 but 6g complains
+	addr, err1 := sockaddrToString(sa);
+	return addr;
+}
diff --git a/src/pkg/net/net.go b/src/pkg/net/net.go
index 5c442e6..8d7e7ba 100644
--- a/src/pkg/net/net.go
+++ b/src/pkg/net/net.go
@@ -440,18 +440,15 @@
 	// Parse addresses (unless they are empty).
 	var lip, rip IP;
 	var lport, rport int;
-	var lerr, rerr os.Error;
 
 	if laddr != "" {
-		lip, lport, lerr = hostPortToIP(net, laddr, mode);
-		if lerr != nil {
-			return nil, lerr
+		if lip, lport, err = hostPortToIP(net, laddr, mode); err != nil {
+			return
 		}
 	}
 	if raddr != "" {
-		rip, rport, rerr = hostPortToIP(net, raddr, mode);
-		if rerr != nil {
-			return nil, rerr
+		if rip, rport, err = hostPortToIP(net, raddr, mode); err != nil {
+			return
 		}
 	}
 
@@ -482,15 +479,13 @@
 
 	var la, ra syscall.Sockaddr;
 	if lip != nil {
-		la, lerr = ipToSockaddr(family, lip, lport);
-		if lerr != nil {
-			return nil, lerr
+		if la, err = ipToSockaddr(family, lip, lport); err != nil {
+			return
 		}
 	}
 	if rip != nil {
-		ra, rerr = ipToSockaddr(family, rip, rport);
-		if rerr != nil {
-			return nil, rerr
+		if ra, err = ipToSockaddr(family, rip, rport); err != nil {
+			return
 		}
 	}
 
@@ -727,6 +722,11 @@
 	return err;
 }
 
+// Addr returns the listener's network address.
+func (l *ListenerUnix) Addr() string {
+	return l.fd.addr();
+}
+
 // Dial connects to the remote address raddr on the network net.
 // If the string laddr is not empty, it is used as the local address
 // for the connection.
@@ -776,6 +776,7 @@
 type Listener interface {
 	Accept() (c Conn, raddr string, err os.Error);
 	Close() os.Error;
+	Addr() string;	// Listener's network address
 }
 
 // ListenerTCP is a TCP network listener.
@@ -783,11 +784,12 @@
 // instead of assuming TCP.
 type ListenerTCP struct {
 	fd *netFD;
-	laddr string
 }
 
 // ListenTCP announces on the TCP address laddr and returns a TCP listener.
 // Net must be "tcp", "tcp4", or "tcp6".
+// If laddr has a port of 0, it means to listen on some available port.
+// The caller can use l.Addr() to retrieve the chosen address.
 func ListenTCP(net, laddr string) (l *ListenerTCP, err os.Error) {
 	fd, e := internetSocket(net, laddr, "", syscall.SOCK_STREAM, "listen");
 	if e != nil {
@@ -835,6 +837,11 @@
 	return l.fd.Close()
 }
 
+// Addr returns the listener's network address.
+func (l *ListenerTCP) Addr() string {
+	return l.fd.addr();
+}
+
 // Listen announces on the local network address laddr.
 // The network string net must be "tcp", "tcp4", "tcp6",
 // "unix", or "unix-dgram".
diff --git a/src/pkg/net/server_test.go b/src/pkg/net/server_test.go
index 586b553..f1c7134 100644
--- a/src/pkg/net/server_test.go
+++ b/src/pkg/net/server_test.go
@@ -8,6 +8,7 @@
 	"io";
 	"net";
 	"os";
+	"strings";
 	"syscall";
 	"testing";
 )
@@ -25,12 +26,12 @@
 	done <- 1
 }
 
-func runServe(t *testing.T, network, addr string, listening, done chan<- int) {
+func runServe(t *testing.T, network, addr string, listening chan<- string, done chan<- int) {
 	l, err := net.Listen(network, addr);
 	if err != nil {
 		t.Fatalf("net.Listen(%q, %q) = _, %v", network, addr, err);
 	}
-	listening <- 1;
+	listening <- l.Addr();
 
 	for {
 		fd, addr, err := l.Accept();
@@ -68,20 +69,26 @@
 
 func doTest(t *testing.T, network, listenaddr, dialaddr string) {
 	t.Logf("Test %s %s %s\n", network, listenaddr, dialaddr);
-	listening := make(chan int);
+	listening := make(chan string);
 	done := make(chan int);
+	if network == "tcp" {
+		listenaddr += ":0";	// any available port
+	}
 	go runServe(t, network, listenaddr, listening, done);
-	<-listening;	// wait for server to start
+	addr := <-listening;	// wait for server to start
+	if network == "tcp" {
+		dialaddr += addr[strings.LastIndex(addr, ":"):len(addr)];
+	}
 	connect(t, network, dialaddr);
 	<-done;	// make sure server stopped
 }
 
 func TestTcpServer(t *testing.T) {
-	doTest(t,  "tcp", "0.0.0.0:9997", "127.0.0.1:9997");
-	doTest(t, "tcp", "[::]:9997", "[::ffff:127.0.0.1]:9997");
-	doTest(t, "tcp", "[::]:9997", "127.0.0.1:9997");
-	doTest(t, "tcp", ":9997", "127.0.0.1:9997");
-	doTest(t, "tcp", "0.0.0.0:9997", "[::ffff:127.0.0.1]:9997");
+	doTest(t,  "tcp", "0.0.0.0", "127.0.0.1");
+	doTest(t, "tcp", "[::]", "[::ffff:127.0.0.1]");
+	doTest(t, "tcp", "[::]", "127.0.0.1");
+	doTest(t, "tcp", "", "127.0.0.1");
+	doTest(t, "tcp", "0.0.0.0", "[::ffff:127.0.0.1]");
 }
 
 func TestUnixServer(t *testing.T) {
diff --git a/src/pkg/syscall/syscall_darwin.go b/src/pkg/syscall/syscall_darwin.go
index 8ea78c6..dcb92e0 100644
--- a/src/pkg/syscall/syscall_darwin.go
+++ b/src/pkg/syscall/syscall_darwin.go
@@ -164,6 +164,8 @@
 //sys	connect(s int, addr uintptr, addrlen _Socklen) (errno int)
 //sys	socket(domain int, typ int, proto int) (fd int, errno int)
 //sys	setsockopt(s int, level int, name int, val uintptr, vallen int) (errno int)
+//sys	getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (errno int)
+//sys	getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (errno int)
 
 // For testing: clients can set this flag to force
 // creation of IPv6 sockets to return EAFNOSUPPORT.
@@ -292,6 +294,24 @@
 	return;
 }
 
+func Getsockname(fd int) (sa Sockaddr, errno int) {
+	var rsa RawSockaddrAny;
+	var len _Socklen = SizeofSockaddrAny;
+	if errno = getsockname(fd, &rsa, &len); errno != 0 {
+		return;
+	}
+	return anyToSockaddr(&rsa);
+}
+
+func Getpeername(fd int) (sa Sockaddr, errno int) {
+	var rsa RawSockaddrAny;
+	var len _Socklen = SizeofSockaddrAny;
+	if errno = getpeername(fd, &rsa, &len); errno != 0 {
+		return;
+	}
+	return anyToSockaddr(&rsa);
+}
+
 func Bind(fd int, sa Sockaddr) (errno int) {
 	ptr, n, err := sa.sockaddr();
 	if err != 0 {
@@ -345,8 +365,6 @@
 //	Acct(name nil-string) (errno int)
 //	Futimes(fd int, timeval *Timeval) (errno int)	// Pointer to 2 timevals!
 //	Gethostuuid(uuid *byte, timeout *Timespec) (errno int)
-//	Getpeername(fd int, addr *Sockaddr, addrlen *int) (errno int)
-//	Getsockname(fd int, addr *Sockaddr, addrlen *int) (errno int)
 //	Getsockopt(s int, level int, name int, val *byte, vallen *int) (errno int)
 //	Madvise(addr *byte, len int, behav int) (errno int)
 //	Mprotect(addr *byte, len int, prot int) (errno int)
diff --git a/src/pkg/syscall/syscall_linux.go b/src/pkg/syscall/syscall_linux.go
index ae3eee7..4c9ac28 100644
--- a/src/pkg/syscall/syscall_linux.go
+++ b/src/pkg/syscall/syscall_linux.go
@@ -324,6 +324,24 @@
 	return;
 }
 
+func Getsockname(fd int) (sa Sockaddr, errno int) {
+	var rsa RawSockaddrAny;
+	var len _Socklen = SizeofSockaddrAny;
+	if errno = getsockname(fd, &rsa, &len); errno != 0 {
+		return;
+	}
+	return anyToSockaddr(&rsa);
+}
+
+func Getpeername(fd int) (sa Sockaddr, errno int) {
+	var rsa RawSockaddrAny;
+	var len _Socklen = SizeofSockaddrAny;
+	if errno = getpeername(fd, &rsa, &len); errno != 0 {
+		return;
+	}
+	return anyToSockaddr(&rsa);
+}
+
 func Bind(fd int, sa Sockaddr) (errno int) {
 	ptr, n, err := sa.sockaddr();
 	if err != 0 {
diff --git a/src/pkg/syscall/syscall_linux_386.go b/src/pkg/syscall/syscall_linux_386.go
index f20ec10..b44428e 100644
--- a/src/pkg/syscall/syscall_linux_386.go
+++ b/src/pkg/syscall/syscall_linux_386.go
@@ -99,6 +99,18 @@
 	return;
 }
 
+func getsockname(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (errno int) {
+	var _ int;
+	_, errno = socketcall(_GETSOCKNAME, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0);
+	return;
+}
+
+func getpeername(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (errno int) {
+	var _ int;
+	_, errno = socketcall(_GETPEERNAME, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0);
+	return;
+}
+
 func bind(s int, addr uintptr, addrlen _Socklen) (errno int) {
 	var _ int;
 	_, errno = socketcall(_BIND, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0);
@@ -127,4 +139,3 @@
 	_, errno = socketcall(_LISTEN, uintptr(s), uintptr(n), 0, 0, 0, 0);
 	return;
 }
-
diff --git a/src/pkg/syscall/syscall_linux_amd64.go b/src/pkg/syscall/syscall_linux_amd64.go
index 3455184..4f7b33b 100644
--- a/src/pkg/syscall/syscall_linux_amd64.go
+++ b/src/pkg/syscall/syscall_linux_amd64.go
@@ -36,6 +36,8 @@
 //sys	setgroups(n int, list *_Gid_t) (errno int)
 //sys	setsockopt(s int, level int, name int, val uintptr, vallen int) (errno int)
 //sys	socket(domain int, typ int, proto int) (fd int, errno int)
+//sys	getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (errno int)
+//sys	getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (errno int)
 
 func Getpagesize() int {
 	return 4096
diff --git a/src/pkg/syscall/zsyscall_darwin_386.go b/src/pkg/syscall/zsyscall_darwin_386.go
index 6974c83..6241efa 100644
--- a/src/pkg/syscall/zsyscall_darwin_386.go
+++ b/src/pkg/syscall/zsyscall_darwin_386.go
@@ -68,6 +68,18 @@
 	return;
 }
 
+func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (errno int) {
+	r0, r1, e1 := Syscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)));
+	errno = int(e1);
+	return;
+}
+
+func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (errno int) {
+	r0, r1, e1 := Syscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)));
+	errno = int(e1);
+	return;
+}
+
 func kevent(kq int, change uintptr, nchange int, event uintptr, nevent int, timeout *Timespec) (n int, errno int) {
 	r0, r1, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)));
 	n = int(r0);
diff --git a/src/pkg/syscall/zsyscall_darwin_amd64.go b/src/pkg/syscall/zsyscall_darwin_amd64.go
index e6b9991..49e17d4 100644
--- a/src/pkg/syscall/zsyscall_darwin_amd64.go
+++ b/src/pkg/syscall/zsyscall_darwin_amd64.go
@@ -68,6 +68,18 @@
 	return;
 }
 
+func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (errno int) {
+	r0, r1, e1 := Syscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)));
+	errno = int(e1);
+	return;
+}
+
+func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (errno int) {
+	r0, r1, e1 := Syscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)));
+	errno = int(e1);
+	return;
+}
+
 func kevent(kq int, change uintptr, nchange int, event uintptr, nevent int, timeout *Timespec) (n int, errno int) {
 	r0, r1, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)));
 	n = int(r0);
diff --git a/src/pkg/syscall/zsyscall_linux_amd64.go b/src/pkg/syscall/zsyscall_linux_amd64.go
index 0766b83..09f21df 100644
--- a/src/pkg/syscall/zsyscall_linux_amd64.go
+++ b/src/pkg/syscall/zsyscall_linux_amd64.go
@@ -760,5 +760,17 @@
 	return;
 }
 
+func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (errno int) {
+	r0, r1, e1 := Syscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)));
+	errno = int(e1);
+	return;
+}
+
+func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (errno int) {
+	r0, r1, e1 := Syscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)));
+	errno = int(e1);
+	return;
+}
+