net: doc, doc-inspired cleanup
R=r
DELTA=368 (87 added, 14 deleted, 267 changed)
OCL=25773
CL=25786
diff --git a/src/lib/net/net.go b/src/lib/net/net.go
index db70819..c01c105 100644
--- a/src/lib/net/net.go
+++ b/src/lib/net/net.go
@@ -16,12 +16,10 @@
MissingAddress = os.NewError("missing address");
UnknownNetwork = os.NewError("unknown network");
UnknownHost = os.NewError("unknown host");
- DNS_Error = os.NewError("dns error looking up host");
- UnknownPort = os.NewError("unknown port");
- UnknownsocketFamily = os.NewError("unknown socket family");
+ UnknownSocketFamily = os.NewError("unknown socket family");
)
-func LookupHost(name string) (name1 string, addrs []string, err *os.Error)
+func LookupHost(name string) (cname string, addrs []string, err *os.Error)
// Split "host:port" into "host" and "port".
// Host cannot contain colons unless it is bracketed.
@@ -75,7 +73,7 @@
var addr []byte;
if host == "" {
if mode == "listen" {
- addr = IPnoaddr; // wildcard - listen to all
+ addr = IPzero; // wildcard - listen to all
} else {
return nil, 0, MissingAddress;
}
@@ -103,9 +101,9 @@
p, i, ok := dtoi(port, 0);
if !ok || i != len(port) {
- p, ok = LookupPort(net, port);
- if !ok {
- return nil, 0, UnknownPort
+ p, err = LookupPort(net, port);
+ if err != nil {
+ return nil, 0, err
}
}
if p < 0 || p > 0xFFFF {
@@ -119,14 +117,14 @@
func sockaddrToHostPort(sa *syscall.Sockaddr) (hostport string, err *os.Error) {
switch sa.Family {
case syscall.AF_INET, syscall.AF_INET6:
- addr, port, e := SockaddrToIP(sa);
+ addr, port, e := sockaddrToIP(sa);
if e != nil {
return "", e
}
- host := IPToString(addr);
+ host := addr.String();
return joinHostPort(host, strconv.Itoa(port)), nil;
default:
- return "", UnknownsocketFamily
+ return "", UnknownSocketFamily
}
return "", nil // not reached
}
@@ -308,7 +306,7 @@
(fd *netFD, err *os.Error)
{
// Parse addresses (unless they are empty).
- var lip, rip []byte;
+ var lip, rip IP;
var lport, rport int;
var lerr, rerr *os.Error;
@@ -336,7 +334,7 @@
default:
// Otherwise, guess.
// If the addresses are IPv4 and we prefer IPv4, use 4; else 6.
- if preferIPv4 && ToIPv4(lip) != nil && ToIPv4(rip) != nil {
+ if preferIPv4 && lip.To4() != nil && rip.To4() != nil {
vers = 4
} else {
vers = 6
@@ -346,10 +344,10 @@
var cvt func(addr []byte, port int) (sa *syscall.Sockaddr, err *os.Error);
var family int64;
if vers == 4 {
- cvt = IPv4ToSockaddr;
+ cvt = v4ToSockaddr;
family = syscall.AF_INET
} else {
- cvt = IPv6ToSockaddr;
+ cvt = v6ToSockaddr;
family = syscall.AF_INET6
}
@@ -437,13 +435,17 @@
// TODO: raw ethernet connections
-
+// A Conn is a generic network connection.
type Conn interface {
Read(b []byte) (n int, err *os.Error);
Write(b []byte) (n int, err *os.Error);
+ Close() *os.Error;
+
+ // For UDP sockets.
ReadFrom(b []byte) (n int, addr string, err *os.Error);
WriteTo(addr string, b []byte) (n int, err *os.Error);
- Close() *os.Error;
+
+ // Methods that have meaning only on some networks.
SetReadBuffer(bytes int) *os.Error;
SetWriteBuffer(bytes int) *os.Error;
SetTimeout(nsec int64) *os.Error;
@@ -456,16 +458,21 @@
BindToDevice(dev string) *os.Error;
}
-
-// Dial's arguments are the network, local address, and remote address.
+// 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.
+//
+// Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only),
+// "udp", "udp4" (IPv4-only), and "udp6" (IPv6-only).
+//
+// For IP networks, addresses have the form host:port. If host is
+// a literal IPv6 address, it must be enclosed in square brackets.
+//
// Examples:
// Dial("tcp", "", "12.34.56.78:80")
+// Dial("tcp", "", "google.com:80")
// Dial("tcp", "", "[de:ad:be:ef::ca:fe]:80")
// Dial("tcp", "127.0.0.1:123", "127.0.0.1:88")
-//
-// Eventually, we plan to allow names in addition to IP addresses,
-// but that requires writing a DNS library.
-
func Dial(net, laddr, raddr string) (c Conn, err *os.Error) {
switch net {
case "tcp", "tcp4", "tcp6":
@@ -492,23 +499,29 @@
return nil, UnknownNetwork
}
-
+// A Listener is a generic network listener.
+// Accept waits for the next connection and Close closes the connection.
type Listener interface {
Accept() (c Conn, raddr string, err *os.Error);
Close() *os.Error;
}
+// ListenerTCP is a TCP network listener.
+// Clients should typically use variables of type 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".
func ListenTCP(net, laddr string) (l *ListenerTCP, err *os.Error) {
fd, e := internetSocket(net, laddr, "", syscall.SOCK_STREAM, "listen");
if e != nil {
return nil, e
}
- r, e1 := syscall.Listen(fd.fd, ListenBacklog());
+ r, e1 := syscall.Listen(fd.fd, listenBacklog());
if e1 != 0 {
syscall.Close(fd.fd);
return nil, os.ErrnoToError(e1)
@@ -518,6 +531,8 @@
return l, nil
}
+// AcceptTCP accepts the next incoming call and returns the new connection
+// and the remote address.
func (l *ListenerTCP) AcceptTCP() (c *ConnTCP, raddr string, err *os.Error) {
if l == nil || l.fd == nil || l.fd.fd < 0 {
return nil, "", os.EINVAL
@@ -535,6 +550,8 @@
return newConnTCP(fd, raddr), raddr, nil
}
+// Accept implements the accept method in the Listener interface;
+// it waits for the next call and returns a generic Conn.
func (l *ListenerTCP) Accept() (c Conn, raddr string, err *os.Error) {
c1, r1, e1 := l.AcceptTCP();
if e1 != nil {
@@ -543,6 +560,8 @@
return c1, r1, nil
}
+// Close stops listening on the TCP address.
+// Already Accepted connections are not closed.
func (l *ListenerTCP) Close() *os.Error {
if l == nil || l.fd == nil {
return os.EINVAL
@@ -550,6 +569,8 @@
return l.fd.Close()
}
+// Listen announces on the local network address laddr.
+// The network string net must be "tcp", "tcp4", or "tcp6".
func Listen(net, laddr string) (l Listener, err *os.Error) {
switch net {
case "tcp", "tcp4", "tcp6":
@@ -561,6 +582,7 @@
/*
more here
*/
+ // BUG(rsc): Listen should support UDP.
}
return nil, UnknownNetwork
}