Commit 5d2ee9d9 authored by Russ Cox's avatar Russ Cox

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
parent f39fcd7e
...@@ -70,12 +70,14 @@ TEST=\ ...@@ -70,12 +70,14 @@ TEST=\
archive/tar\ archive/tar\
bignum\ bignum\
bufio\ bufio\
bytes\
compress/flate\ compress/flate\
compress/gzip\ compress/gzip\
container/list\ container/list\
container/vector\ container/vector\
crypto/aes\ crypto/aes\
crypto/block\ crypto/block\
crypto/hmac\
crypto/md5\ crypto/md5\
crypto/sha1\ crypto/sha1\
datafmt\ datafmt\
......
...@@ -427,3 +427,12 @@ func (fd *netFD) accept() (nfd *netFD, err os.Error) { ...@@ -427,3 +427,12 @@ func (fd *netFD) accept() (nfd *netFD, err os.Error) {
return nfd, nil 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;
}
...@@ -440,18 +440,15 @@ func internetSocket(net, laddr, raddr string, proto int, mode string) (fd *netFD ...@@ -440,18 +440,15 @@ func internetSocket(net, laddr, raddr string, proto int, mode string) (fd *netFD
// Parse addresses (unless they are empty). // Parse addresses (unless they are empty).
var lip, rip IP; var lip, rip IP;
var lport, rport int; var lport, rport int;
var lerr, rerr os.Error;
if laddr != "" { if laddr != "" {
lip, lport, lerr = hostPortToIP(net, laddr, mode); if lip, lport, err = hostPortToIP(net, laddr, mode); err != nil {
if lerr != nil { return
return nil, lerr
} }
} }
if raddr != "" { if raddr != "" {
rip, rport, rerr = hostPortToIP(net, raddr, mode); if rip, rport, err = hostPortToIP(net, raddr, mode); err != nil {
if rerr != nil { return
return nil, rerr
} }
} }
...@@ -482,15 +479,13 @@ func internetSocket(net, laddr, raddr string, proto int, mode string) (fd *netFD ...@@ -482,15 +479,13 @@ func internetSocket(net, laddr, raddr string, proto int, mode string) (fd *netFD
var la, ra syscall.Sockaddr; var la, ra syscall.Sockaddr;
if lip != nil { if lip != nil {
la, lerr = ipToSockaddr(family, lip, lport); if la, err = ipToSockaddr(family, lip, lport); err != nil {
if lerr != nil { return
return nil, lerr
} }
} }
if rip != nil { if rip != nil {
ra, rerr = ipToSockaddr(family, rip, rport); if ra, err = ipToSockaddr(family, rip, rport); err != nil {
if rerr != nil { return
return nil, rerr
} }
} }
...@@ -727,6 +722,11 @@ func (l *ListenerUnix) Close() os.Error { ...@@ -727,6 +722,11 @@ func (l *ListenerUnix) Close() os.Error {
return err; 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. // 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 // If the string laddr is not empty, it is used as the local address
// for the connection. // for the connection.
...@@ -776,6 +776,7 @@ func Dial(net, laddr, raddr string) (c Conn, err os.Error) { ...@@ -776,6 +776,7 @@ func Dial(net, laddr, raddr string) (c Conn, err os.Error) {
type Listener interface { type Listener interface {
Accept() (c Conn, raddr string, err os.Error); Accept() (c Conn, raddr string, err os.Error);
Close() os.Error; Close() os.Error;
Addr() string; // Listener's network address
} }
// ListenerTCP is a TCP network listener. // ListenerTCP is a TCP network listener.
...@@ -783,11 +784,12 @@ type Listener interface { ...@@ -783,11 +784,12 @@ type Listener interface {
// instead of assuming TCP. // instead of assuming TCP.
type ListenerTCP struct { type ListenerTCP struct {
fd *netFD; fd *netFD;
laddr string
} }
// ListenTCP announces on the TCP address laddr and returns a TCP listener. // ListenTCP announces on the TCP address laddr and returns a TCP listener.
// Net must be "tcp", "tcp4", or "tcp6". // 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) { func ListenTCP(net, laddr string) (l *ListenerTCP, err os.Error) {
fd, e := internetSocket(net, laddr, "", syscall.SOCK_STREAM, "listen"); fd, e := internetSocket(net, laddr, "", syscall.SOCK_STREAM, "listen");
if e != nil { if e != nil {
...@@ -835,6 +837,11 @@ func (l *ListenerTCP) Close() os.Error { ...@@ -835,6 +837,11 @@ func (l *ListenerTCP) Close() os.Error {
return l.fd.Close() 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. // Listen announces on the local network address laddr.
// The network string net must be "tcp", "tcp4", "tcp6", // The network string net must be "tcp", "tcp4", "tcp6",
// "unix", or "unix-dgram". // "unix", or "unix-dgram".
......
...@@ -8,6 +8,7 @@ import ( ...@@ -8,6 +8,7 @@ import (
"io"; "io";
"net"; "net";
"os"; "os";
"strings";
"syscall"; "syscall";
"testing"; "testing";
) )
...@@ -25,12 +26,12 @@ func runEcho(fd io.ReadWriter, done chan<- int) { ...@@ -25,12 +26,12 @@ func runEcho(fd io.ReadWriter, done chan<- int) {
done <- 1 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); l, err := net.Listen(network, addr);
if err != nil { if err != nil {
t.Fatalf("net.Listen(%q, %q) = _, %v", network, addr, err); t.Fatalf("net.Listen(%q, %q) = _, %v", network, addr, err);
} }
listening <- 1; listening <- l.Addr();
for { for {
fd, addr, err := l.Accept(); fd, addr, err := l.Accept();
...@@ -68,20 +69,26 @@ func connect(t *testing.T, network, addr string) { ...@@ -68,20 +69,26 @@ func connect(t *testing.T, network, addr string) {
func doTest(t *testing.T, network, listenaddr, dialaddr string) { func doTest(t *testing.T, network, listenaddr, dialaddr string) {
t.Logf("Test %s %s %s\n", network, listenaddr, dialaddr); t.Logf("Test %s %s %s\n", network, listenaddr, dialaddr);
listening := make(chan int); listening := make(chan string);
done := make(chan int); done := make(chan int);
if network == "tcp" {
listenaddr += ":0"; // any available port
}
go runServe(t, network, listenaddr, listening, done); 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); connect(t, network, dialaddr);
<-done; // make sure server stopped <-done; // make sure server stopped
} }
func TestTcpServer(t *testing.T) { func TestTcpServer(t *testing.T) {
doTest(t, "tcp", "0.0.0.0:9997", "127.0.0.1:9997"); doTest(t, "tcp", "0.0.0.0", "127.0.0.1");
doTest(t, "tcp", "[::]:9997", "[::ffff:127.0.0.1]:9997"); doTest(t, "tcp", "[::]", "[::ffff:127.0.0.1]");
doTest(t, "tcp", "[::]:9997", "127.0.0.1:9997"); doTest(t, "tcp", "[::]", "127.0.0.1");
doTest(t, "tcp", ":9997", "127.0.0.1:9997"); doTest(t, "tcp", "", "127.0.0.1");
doTest(t, "tcp", "0.0.0.0:9997", "[::ffff:127.0.0.1]:9997"); doTest(t, "tcp", "0.0.0.0", "[::ffff:127.0.0.1]");
} }
func TestUnixServer(t *testing.T) { func TestUnixServer(t *testing.T) {
......
...@@ -164,6 +164,8 @@ func Sleep(ns int64) (errno int) { ...@@ -164,6 +164,8 @@ func Sleep(ns int64) (errno int) {
//sys connect(s int, addr uintptr, addrlen _Socklen) (errno int) //sys connect(s int, addr uintptr, addrlen _Socklen) (errno int)
//sys socket(domain int, typ int, proto int) (fd int, 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 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 // For testing: clients can set this flag to force
// creation of IPv6 sockets to return EAFNOSUPPORT. // creation of IPv6 sockets to return EAFNOSUPPORT.
...@@ -292,6 +294,24 @@ func Accept(fd int) (nfd int, sa Sockaddr, errno int) { ...@@ -292,6 +294,24 @@ func Accept(fd int) (nfd int, sa Sockaddr, errno int) {
return; 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) { func Bind(fd int, sa Sockaddr) (errno int) {
ptr, n, err := sa.sockaddr(); ptr, n, err := sa.sockaddr();
if err != 0 { if err != 0 {
...@@ -345,8 +365,6 @@ func Kevent(kq int, changes, events []Kevent_t, timeout *Timespec) (n int, errno ...@@ -345,8 +365,6 @@ func Kevent(kq int, changes, events []Kevent_t, timeout *Timespec) (n int, errno
// Acct(name nil-string) (errno int) // Acct(name nil-string) (errno int)
// Futimes(fd int, timeval *Timeval) (errno int) // Pointer to 2 timevals! // Futimes(fd int, timeval *Timeval) (errno int) // Pointer to 2 timevals!
// Gethostuuid(uuid *byte, timeout *Timespec) (errno int) // 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) // Getsockopt(s int, level int, name int, val *byte, vallen *int) (errno int)
// Madvise(addr *byte, len int, behav int) (errno int) // Madvise(addr *byte, len int, behav int) (errno int)
// Mprotect(addr *byte, len int, prot int) (errno int) // Mprotect(addr *byte, len int, prot int) (errno int)
......
...@@ -324,6 +324,24 @@ func Accept(fd int) (nfd int, sa Sockaddr, errno int) { ...@@ -324,6 +324,24 @@ func Accept(fd int) (nfd int, sa Sockaddr, errno int) {
return; 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) { func Bind(fd int, sa Sockaddr) (errno int) {
ptr, n, err := sa.sockaddr(); ptr, n, err := sa.sockaddr();
if err != 0 { if err != 0 {
......
...@@ -99,6 +99,18 @@ func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, errno int) { ...@@ -99,6 +99,18 @@ func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, errno int) {
return; 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) { func bind(s int, addr uintptr, addrlen _Socklen) (errno int) {
var _ int; var _ int;
_, errno = socketcall(_BIND, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0); _, errno = socketcall(_BIND, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0);
...@@ -127,4 +139,3 @@ func Listen(s int, n int) (errno int) { ...@@ -127,4 +139,3 @@ func Listen(s int, n int) (errno int) {
_, errno = socketcall(_LISTEN, uintptr(s), uintptr(n), 0, 0, 0, 0); _, errno = socketcall(_LISTEN, uintptr(s), uintptr(n), 0, 0, 0, 0);
return; return;
} }
...@@ -36,6 +36,8 @@ import "syscall" ...@@ -36,6 +36,8 @@ import "syscall"
//sys setgroups(n int, list *_Gid_t) (errno int) //sys setgroups(n int, list *_Gid_t) (errno int)
//sys setsockopt(s int, level int, name int, val uintptr, vallen int) (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 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 { func Getpagesize() int {
return 4096 return 4096
......
...@@ -68,6 +68,18 @@ func setsockopt(s int, level int, name int, val uintptr, vallen int) (errno int) ...@@ -68,6 +68,18 @@ func setsockopt(s int, level int, name int, val uintptr, vallen int) (errno int)
return; 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) { 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))); r0, r1, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)));
n = int(r0); n = int(r0);
......
...@@ -68,6 +68,18 @@ func setsockopt(s int, level int, name int, val uintptr, vallen int) (errno int) ...@@ -68,6 +68,18 @@ func setsockopt(s int, level int, name int, val uintptr, vallen int) (errno int)
return; 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) { 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))); r0, r1, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)));
n = int(r0); n = int(r0);
......
...@@ -760,5 +760,17 @@ func socket(domain int, typ int, proto int) (fd int, errno int) { ...@@ -760,5 +760,17 @@ func socket(domain int, typ int, proto int) (fd int, errno int) {
return; 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;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment