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
archive/tar\
bignum\
bufio\
+ bytes\
compress/flate\
compress/gzip\
container/list\
container/vector\
crypto/aes\
crypto/block\
+ crypto/hmac\
crypto/md5\
crypto/sha1\
datafmt\
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;
+}
// 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
}
}
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
}
}
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.
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.
// 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 {
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".
"io";
"net";
"os";
+ "strings";
"syscall";
"testing";
)
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();
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) {
//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.
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 {
// 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)
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 {
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);
_, errno = socketcall(_LISTEN, uintptr(s), uintptr(n), 0, 0, 0, 0);
return;
}
-
//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
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);
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);
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;
+}
+