package net cleanup

added ReadFrom/WriteTo for packet protocols like UDP.
simplified the net.Conn interface.
added new net.PacketConn interface for packet protocols.
implemented proper UDP listener.

cleaned up LocalAddr/RemoteAddr methods - cache in netFD.

threw away various unused methods.

an interface change:
introduced net.Addr as a network address interface,
to avoid conversion of UDP host:port to string and
back for every ReadFrom/WriteTo sequence.

another interface change:
since signature of Listener.Accept was changing anyway,
dropped the middle return value, because it is available
as c.RemoteAddr().  (the Accept signature predates the
existence of that method.)

Dial and Listen still accept strings, but the proto-specific
versions DialTCP, ListenUDP, etc. take net.Addr instead.

because the generic Dial didn't change and because
no one calls Accept directly (only indirectly via the http
server), very little code will be affected by these interface
changes.

design comments welcome.

R=p
CC=go-dev, r
http://go/go-review/1018017
diff --git a/src/pkg/net/fd.go b/src/pkg/net/fd.go
index 0f42239..64d505a 100644
--- a/src/pkg/net/fd.go
+++ b/src/pkg/net/fd.go
@@ -17,12 +17,14 @@
 type netFD struct {
 	// immutable until Close
 	fd int;
+	family int;
+	proto int;
 	file *os.File;
 	cr chan *netFD;
 	cw chan *netFD;
 	net string;
-	laddr string;
-	raddr string;
+	laddr Addr;
+	raddr Addr;
 
 	// owned by client
 	rdeadline_delta int64;
@@ -289,7 +291,7 @@
 
 var pollserver *pollServer
 
-func _StartServer() {
+func startServer() {
 	p, err := newPollServer();
 	if err != nil {
 		print("Start pollServer: ", err.String(), "\n")
@@ -297,19 +299,27 @@
 	pollserver = p
 }
 
-func newFD(fd int, net, laddr, raddr string) (f *netFD, err os.Error) {
-	if pollserver == nil {
-		once.Do(_StartServer);
-	}
+func newFD(fd, family, proto int, net string, laddr, raddr Addr) (f *netFD, err os.Error) {
+	once.Do(startServer);
 	if e := syscall.SetNonblock(fd, true); e != 0 {
-		return nil, &os.PathError{"setnonblock", laddr, os.Errno(e)};
+		return nil, &OpError{"setnonblock", net, laddr, os.Errno(e)};
 	}
-	f = new(netFD);
-	f.fd = fd;
-	f.net = net;
-	f.laddr = laddr;
-	f.raddr = raddr;
-	f.file = os.NewFile(fd, net + "!" + laddr + "->" + raddr);
+	f = &netFD{
+		fd: fd,
+		family: family,
+		proto: proto,
+		net: net,
+		laddr: laddr,
+		raddr: raddr,
+	};
+	var ls, rs string;
+	if laddr != nil {
+		ls = laddr.String();
+	}
+	if raddr != nil {
+		rs = raddr.String();
+	}
+	f.file = os.NewFile(fd, net + ":" + ls + "->" + rs);
 	f.cr = make(chan *netFD, 1);
 	f.cw = make(chan *netFD, 1);
 	return f, nil
@@ -322,24 +332,6 @@
 	return e == os.EAGAIN;
 }
 
-func (fd *netFD) addr() string {
-	sa, e := syscall.Getsockname(fd.fd);
-	if e != 0 {
-		return "";
-	}
-	addr, _ := sockaddrToString(sa);
-	return addr;
-}
-
-func (fd *netFD) remoteAddr() string {
-	sa, e := syscall.Getpeername(fd.fd);
-	if e != 0 {
-		return "";
-	}
-	addr, _ := sockaddrToString(sa);
-	return addr;
-}
-
 func (fd *netFD) Close() os.Error {
 	if fd == nil || fd.file == nil {
 		return os.EINVAL
@@ -413,7 +405,7 @@
 	return nn, err
 }
 
-func (fd *netFD) accept() (nfd *netFD, err os.Error) {
+func (fd *netFD) accept(toAddr func(syscall.Sockaddr)Addr) (nfd *netFD, err os.Error) {
 	if fd == nil || fd.file == nil {
 		return nil, os.EINVAL
 	}
@@ -435,16 +427,12 @@
 	}
 	if e != 0 {
 		syscall.ForkLock.RUnlock();
-		return nil, &os.PathError{"accept", fd.addr(), os.Errno(e)}
+		return nil, &OpError{"accept", fd.net, fd.laddr, os.Errno(e)}
 	}
 	syscall.CloseOnExec(s);
 	syscall.ForkLock.RUnlock();
 
-	raddr, err1 := sockaddrToString(sa);
-	if err1 != nil {
-		raddr = "invalid-address";
-	}
-	if nfd, err = newFD(s, fd.net, fd.laddr, raddr); err != nil {
+	if nfd, err = newFD(s, fd.family, fd.proto, fd.net, fd.laddr, toAddr(sa)); err != nil {
 		syscall.Close(s);
 		return nil, err
 	}