aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/net
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2012-01-13 05:11:45 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2012-01-13 05:11:45 +0000
commitdf4aa89a5e7acb315655f193e7f549e8d32367e2 (patch)
treeeb5eccc07097c5fcf940967f33ab84a7d47c96fe /libgo/go/net
parentf83fa0bf8f411697ec908cfa86ee6faf4cd9c476 (diff)
downloadgcc-df4aa89a5e7acb315655f193e7f549e8d32367e2.zip
gcc-df4aa89a5e7acb315655f193e7f549e8d32367e2.tar.gz
gcc-df4aa89a5e7acb315655f193e7f549e8d32367e2.tar.bz2
libgo: Update to weekly.2011-12-22.
From-SVN: r183150
Diffstat (limited to 'libgo/go/net')
-rw-r--r--libgo/go/net/cgo_stub.go2
-rw-r--r--libgo/go/net/dial.go66
-rw-r--r--libgo/go/net/dial_test.go88
-rw-r--r--libgo/go/net/dnsclient_unix.go2
-rw-r--r--libgo/go/net/dnsconfig.go2
-rw-r--r--libgo/go/net/fd.go10
-rw-r--r--libgo/go/net/fd_linux.go16
-rw-r--r--libgo/go/net/fd_netbsd.go116
-rw-r--r--libgo/go/net/fd_openbsd.go1
-rw-r--r--libgo/go/net/file.go2
-rw-r--r--libgo/go/net/http/client.go17
-rw-r--r--libgo/go/net/http/jar.go30
-rw-r--r--libgo/go/net/http/readrequest_test.go2
-rw-r--r--libgo/go/net/http/request_test.go18
-rw-r--r--libgo/go/net/http/serve_test.go6
-rw-r--r--libgo/go/net/interface_bsd.go97
-rw-r--r--libgo/go/net/interface_linux.go73
-rw-r--r--libgo/go/net/interface_netbsd.go14
-rw-r--r--libgo/go/net/interface_test.go57
-rw-r--r--libgo/go/net/ip.go3
-rw-r--r--libgo/go/net/ipraw_test.go1
-rw-r--r--libgo/go/net/iprawsock_posix.go2
-rw-r--r--libgo/go/net/ipsock_posix.go2
-rw-r--r--libgo/go/net/lookup_unix.go2
-rw-r--r--libgo/go/net/net.go8
-rw-r--r--libgo/go/net/newpollserver.go2
-rw-r--r--libgo/go/net/port.go2
-rw-r--r--libgo/go/net/rpc/server_test.go20
-rw-r--r--libgo/go/net/sendfile_stub.go2
-rw-r--r--libgo/go/net/sock.go2
-rw-r--r--libgo/go/net/sock_bsd.go2
-rw-r--r--libgo/go/net/tcpsock_posix.go2
-rw-r--r--libgo/go/net/textproto/reader_test.go2
-rw-r--r--libgo/go/net/udpsock_posix.go2
-rw-r--r--libgo/go/net/unixsock_posix.go2
35 files changed, 514 insertions, 161 deletions
diff --git a/libgo/go/net/cgo_stub.go b/libgo/go/net/cgo_stub.go
index fbe6150..66aff83 100644
--- a/libgo/go/net/cgo_stub.go
+++ b/libgo/go/net/cgo_stub.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build openbsd
+// +build nocgo
// Stub cgo routines for systems that do not use cgo to do network lookups.
diff --git a/libgo/go/net/dial.go b/libgo/go/net/dial.go
index 43866dc..00acb84 100644
--- a/libgo/go/net/dial.go
+++ b/libgo/go/net/dial.go
@@ -4,6 +4,10 @@
package net
+import (
+ "time"
+)
+
func resolveNetAddr(op, net, addr string) (a Addr, err error) {
if addr == "" {
return nil, &OpError{op, net, nil, errMissingAddress}
@@ -42,11 +46,15 @@ func resolveNetAddr(op, net, addr string) (a Addr, err error) {
// Dial("tcp", "google.com:80")
// Dial("tcp", "[de:ad:be:ef::ca:fe]:80")
//
-func Dial(net, addr string) (c Conn, err error) {
+func Dial(net, addr string) (Conn, error) {
addri, err := resolveNetAddr("dial", net, addr)
if err != nil {
return nil, err
}
+ return dialAddr(net, addr, addri)
+}
+
+func dialAddr(net, addr string, addri Addr) (c Conn, err error) {
switch ra := addri.(type) {
case *TCPAddr:
c, err = DialTCP(net, nil, ra)
@@ -65,6 +73,62 @@ func Dial(net, addr string) (c Conn, err error) {
return
}
+// DialTimeout acts like Dial but takes a timeout.
+// The timeout includes name resolution, if required.
+func DialTimeout(net, addr string, timeout time.Duration) (Conn, error) {
+ // TODO(bradfitz): the timeout should be pushed down into the
+ // net package's event loop, so on timeout to dead hosts we
+ // don't have a goroutine sticking around for the default of
+ // ~3 minutes.
+ t := time.NewTimer(timeout)
+ defer t.Stop()
+ type pair struct {
+ Conn
+ error
+ }
+ ch := make(chan pair, 1)
+ resolvedAddr := make(chan Addr, 1)
+ go func() {
+ addri, err := resolveNetAddr("dial", net, addr)
+ if err != nil {
+ ch <- pair{nil, err}
+ return
+ }
+ resolvedAddr <- addri // in case we need it for OpError
+ c, err := dialAddr(net, addr, addri)
+ ch <- pair{c, err}
+ }()
+ select {
+ case <-t.C:
+ // Try to use the real Addr in our OpError, if we resolved it
+ // before the timeout. Otherwise we just use stringAddr.
+ var addri Addr
+ select {
+ case a := <-resolvedAddr:
+ addri = a
+ default:
+ addri = &stringAddr{net, addr}
+ }
+ err := &OpError{
+ Op: "dial",
+ Net: net,
+ Addr: addri,
+ Err: &timeoutError{},
+ }
+ return nil, err
+ case p := <-ch:
+ return p.Conn, p.error
+ }
+ panic("unreachable")
+}
+
+type stringAddr struct {
+ net, addr string
+}
+
+func (a stringAddr) Network() string { return a.net }
+func (a stringAddr) String() string { return a.addr }
+
// Listen announces on the local network address laddr.
// The network string net must be a stream-oriented
// network: "tcp", "tcp4", "tcp6", or "unix", or "unixpacket".
diff --git a/libgo/go/net/dial_test.go b/libgo/go/net/dial_test.go
new file mode 100644
index 0000000..16b7263
--- /dev/null
+++ b/libgo/go/net/dial_test.go
@@ -0,0 +1,88 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package net
+
+import (
+ "runtime"
+ "testing"
+ "time"
+)
+
+func newLocalListener(t *testing.T) Listener {
+ ln, err := Listen("tcp", "127.0.0.1:0")
+ if err != nil {
+ ln, err = Listen("tcp6", "[::1]:0")
+ }
+ if err != nil {
+ t.Fatal(err)
+ }
+ return ln
+}
+
+func TestDialTimeout(t *testing.T) {
+ ln := newLocalListener(t)
+ defer ln.Close()
+
+ errc := make(chan error)
+
+ const SOMAXCONN = 0x80 // copied from syscall, but not always available
+ const numConns = SOMAXCONN + 10
+
+ // TODO(bradfitz): It's hard to test this in a portable
+ // way. This is unforunate, but works for now.
+ switch runtime.GOOS {
+ case "linux":
+ // The kernel will start accepting TCP connections before userspace
+ // gets a chance to not accept them, so fire off a bunch to fill up
+ // the kernel's backlog. Then we test we get a failure after that.
+ for i := 0; i < numConns; i++ {
+ go func() {
+ _, err := DialTimeout("tcp", ln.Addr().String(), 200*time.Millisecond)
+ errc <- err
+ }()
+ }
+ case "darwin":
+ // At least OS X 10.7 seems to accept any number of
+ // connections, ignoring listen's backlog, so resort
+ // to connecting to a hopefully-dead 127/8 address.
+ go func() {
+ _, err := DialTimeout("tcp", "127.0.71.111:80", 200*time.Millisecond)
+ errc <- err
+ }()
+ default:
+ // TODO(bradfitz): this probably doesn't work on
+ // Windows? SOMAXCONN is huge there. I'm not sure how
+ // listen works there.
+ // OpenBSD may have a reject route to 10/8.
+ // FreeBSD likely works, but is untested.
+ t.Logf("skipping test on %q; untested.", runtime.GOOS)
+ return
+ }
+
+ connected := 0
+ for {
+ select {
+ case <-time.After(15 * time.Second):
+ t.Fatal("too slow")
+ case err := <-errc:
+ if err == nil {
+ connected++
+ if connected == numConns {
+ t.Fatal("all connections connected; expected some to time out")
+ }
+ } else {
+ terr, ok := err.(timeout)
+ if !ok {
+ t.Fatalf("got error %q; want error with timeout interface", err)
+ }
+ if !terr.Timeout() {
+ t.Fatalf("got error %q; not a timeout", err)
+ }
+ // Pass. We saw a timeout error.
+ return
+ }
+ }
+ }
+}
diff --git a/libgo/go/net/dnsclient_unix.go b/libgo/go/net/dnsclient_unix.go
index 79a958e..07e72cc 100644
--- a/libgo/go/net/dnsclient_unix.go
+++ b/libgo/go/net/dnsclient_unix.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin freebsd linux openbsd
+// +build darwin freebsd linux netbsd openbsd
// DNS client: see RFC 1035.
// Has to be linked into package net for Dial.
diff --git a/libgo/go/net/dnsconfig.go b/libgo/go/net/dnsconfig.go
index 379fec9..c0ab802 100644
--- a/libgo/go/net/dnsconfig.go
+++ b/libgo/go/net/dnsconfig.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin freebsd linux openbsd
+// +build darwin freebsd linux netbsd openbsd
// Read system DNS config from /etc/resolv.conf
diff --git a/libgo/go/net/fd.go b/libgo/go/net/fd.go
index 5318c51..3dec9f4 100644
--- a/libgo/go/net/fd.go
+++ b/libgo/go/net/fd.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin freebsd linux openbsd
+// +build darwin freebsd linux netbsd openbsd
package net
@@ -377,14 +377,6 @@ func (fd *netFD) CloseWrite() error {
return fd.shutdown(syscall.SHUT_WR)
}
-type timeoutError struct{}
-
-func (e *timeoutError) Error() string { return "i/o timeout" }
-func (e *timeoutError) Timeout() bool { return true }
-func (e *timeoutError) Temporary() bool { return true }
-
-var errTimeout error = &timeoutError{}
-
func (fd *netFD) Read(p []byte) (n int, err error) {
if fd == nil {
return 0, os.EINVAL
diff --git a/libgo/go/net/fd_linux.go b/libgo/go/net/fd_linux.go
index 8e07833..c8df9c9 100644
--- a/libgo/go/net/fd_linux.go
+++ b/libgo/go/net/fd_linux.go
@@ -37,11 +37,17 @@ func newpollster() (p *pollster, err error) {
p = new(pollster)
var e error
- // The arg to epoll_create is a hint to the kernel
- // about the number of FDs we will care about.
- // We don't know, and since 2.6.8 the kernel ignores it anyhow.
- if p.epfd, e = syscall.EpollCreate(16); e != nil {
- return nil, os.NewSyscallError("epoll_create", e)
+ if p.epfd, e = syscall.EpollCreate1(syscall.EPOLL_CLOEXEC); e != nil {
+ if e != syscall.ENOSYS {
+ return nil, os.NewSyscallError("epoll_create1", e)
+ }
+ // The arg to epoll_create is a hint to the kernel
+ // about the number of FDs we will care about.
+ // We don't know, and since 2.6.8 the kernel ignores it anyhow.
+ if p.epfd, e = syscall.EpollCreate(16); e != nil {
+ return nil, os.NewSyscallError("epoll_create", e)
+ }
+ syscall.CloseOnExec(p.epfd)
}
p.events = make(map[int]uint32)
return p, nil
diff --git a/libgo/go/net/fd_netbsd.go b/libgo/go/net/fd_netbsd.go
new file mode 100644
index 0000000..31d0744
--- /dev/null
+++ b/libgo/go/net/fd_netbsd.go
@@ -0,0 +1,116 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Waiting for FDs via kqueue/kevent.
+
+package net
+
+import (
+ "os"
+ "syscall"
+)
+
+type pollster struct {
+ kq int
+ eventbuf [10]syscall.Kevent_t
+ events []syscall.Kevent_t
+
+ // An event buffer for AddFD/DelFD.
+ // Must hold pollServer lock.
+ kbuf [1]syscall.Kevent_t
+}
+
+func newpollster() (p *pollster, err error) {
+ p = new(pollster)
+ if p.kq, err = syscall.Kqueue(); err != nil {
+ return nil, os.NewSyscallError("kqueue", err)
+ }
+ syscall.CloseOnExec(p.kq)
+ p.events = p.eventbuf[0:0]
+ return p, nil
+}
+
+func (p *pollster) AddFD(fd int, mode int, repeat bool) (bool, error) {
+ // pollServer is locked.
+
+ var kmode int
+ if mode == 'r' {
+ kmode = syscall.EVFILT_READ
+ } else {
+ kmode = syscall.EVFILT_WRITE
+ }
+ ev := &p.kbuf[0]
+ // EV_ADD - add event to kqueue list
+ // EV_ONESHOT - delete the event the first time it triggers
+ flags := syscall.EV_ADD
+ if !repeat {
+ flags |= syscall.EV_ONESHOT
+ }
+ syscall.SetKevent(ev, fd, kmode, flags)
+
+ n, e := syscall.Kevent(p.kq, p.kbuf[:], nil, nil)
+ if e != nil {
+ return false, os.NewSyscallError("kevent", e)
+ }
+ if n != 1 || (ev.Flags&syscall.EV_ERROR) == 0 || int(ev.Ident) != fd || int(ev.Filter) != kmode {
+ return false, os.NewSyscallError("kqueue phase error", e)
+ }
+ if ev.Data != 0 {
+ return false, syscall.Errno(int(ev.Data))
+ }
+ return false, nil
+}
+
+func (p *pollster) DelFD(fd int, mode int) {
+ // pollServer is locked.
+
+ var kmode int
+ if mode == 'r' {
+ kmode = syscall.EVFILT_READ
+ } else {
+ kmode = syscall.EVFILT_WRITE
+ }
+ ev := &p.kbuf[0]
+ // EV_DELETE - delete event from kqueue list
+ syscall.SetKevent(ev, fd, kmode, syscall.EV_DELETE)
+ syscall.Kevent(p.kq, p.kbuf[:], nil, nil)
+}
+
+func (p *pollster) WaitFD(s *pollServer, nsec int64) (fd int, mode int, err error) {
+ var t *syscall.Timespec
+ for len(p.events) == 0 {
+ if nsec > 0 {
+ if t == nil {
+ t = new(syscall.Timespec)
+ }
+ *t = syscall.NsecToTimespec(nsec)
+ }
+
+ s.Unlock()
+ nn, e := syscall.Kevent(p.kq, nil, p.eventbuf[:], t)
+ s.Lock()
+
+ if e != nil {
+ if e == syscall.EINTR {
+ continue
+ }
+ return -1, 0, os.NewSyscallError("kevent", e)
+ }
+ if nn == 0 {
+ return -1, 0, nil
+ }
+ p.events = p.eventbuf[0:nn]
+ }
+ ev := &p.events[0]
+ p.events = p.events[1:]
+ fd = int(ev.Ident)
+ if ev.Filter == syscall.EVFILT_READ {
+ mode = 'r'
+ } else {
+ mode = 'w'
+ }
+ return fd, mode, nil
+}
+
+func (p *pollster) Close() error { return os.NewSyscallError("close", syscall.Close(p.kq)) }
diff --git a/libgo/go/net/fd_openbsd.go b/libgo/go/net/fd_openbsd.go
index e52ac35..31d0744 100644
--- a/libgo/go/net/fd_openbsd.go
+++ b/libgo/go/net/fd_openbsd.go
@@ -26,6 +26,7 @@ func newpollster() (p *pollster, err error) {
if p.kq, err = syscall.Kqueue(); err != nil {
return nil, os.NewSyscallError("kqueue", err)
}
+ syscall.CloseOnExec(p.kq)
p.events = p.eventbuf[0:0]
return p, nil
}
diff --git a/libgo/go/net/file.go b/libgo/go/net/file.go
index bf8cd9d..4ac280b 100644
--- a/libgo/go/net/file.go
+++ b/libgo/go/net/file.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin freebsd linux openbsd
+// +build darwin freebsd linux netbsd openbsd
package net
diff --git a/libgo/go/net/http/client.go b/libgo/go/net/http/client.go
index 211ac44..a4f8f19 100644
--- a/libgo/go/net/http/client.go
+++ b/libgo/go/net/http/client.go
@@ -38,6 +38,11 @@ type Client struct {
// If CheckRedirect is nil, the Client uses its default policy,
// which is to stop after 10 consecutive requests.
CheckRedirect func(req *Request, via []*Request) error
+
+ // Jar specifies the cookie jar.
+ // If Jar is nil, cookies are not sent in requests and ignored
+ // in responses.
+ Jar CookieJar
}
// DefaultClient is the default Client and is used by Get, Head, and Post.
@@ -180,6 +185,11 @@ func (c *Client) doFollowingRedirects(ireq *Request) (r *Response, err error) {
return nil, errors.New("http: nil Request.URL")
}
+ jar := c.Jar
+ if jar == nil {
+ jar = blackHoleJar{}
+ }
+
req := ireq
urlStr := "" // next relative or absolute URL to fetch (after first request)
for redirect := 0; ; redirect++ {
@@ -203,12 +213,19 @@ func (c *Client) doFollowingRedirects(ireq *Request) (r *Response, err error) {
break
}
}
+ for _, cookie := range jar.Cookies(req.URL) {
+ req.AddCookie(cookie)
+ }
}
urlStr = req.URL.String()
if r, err = send(req, c.Transport); err != nil {
break
}
+ if c := r.Cookies(); len(c) > 0 {
+ jar.SetCookies(req.URL, c)
+ }
+
if shouldRedirect(r.StatusCode) {
r.Body.Close()
if urlStr = r.Header.Get("Location"); urlStr == "" {
diff --git a/libgo/go/net/http/jar.go b/libgo/go/net/http/jar.go
new file mode 100644
index 0000000..2c2caa2
--- /dev/null
+++ b/libgo/go/net/http/jar.go
@@ -0,0 +1,30 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package http
+
+import (
+ "net/url"
+)
+
+// A CookieJar manages storage and use of cookies in HTTP requests.
+//
+// Implementations of CookieJar must be safe for concurrent use by multiple
+// goroutines.
+type CookieJar interface {
+ // SetCookies handles the receipt of the cookies in a reply for the
+ // given URL. It may or may not choose to save the cookies, depending
+ // on the jar's policy and implementation.
+ SetCookies(u *url.URL, cookies []*Cookie)
+
+ // Cookies returns the cookies to send in a request for the given URL.
+ // It is up to the implementation to honor the standard cookie use
+ // restrictions such as in RFC 6265.
+ Cookies(u *url.URL) []*Cookie
+}
+
+type blackHoleJar struct{}
+
+func (blackHoleJar) SetCookies(u *url.URL, cookies []*Cookie) {}
+func (blackHoleJar) Cookies(u *url.URL) []*Cookie { return nil }
diff --git a/libgo/go/net/http/readrequest_test.go b/libgo/go/net/http/readrequest_test.go
index c64fff6..ad7e3c0 100644
--- a/libgo/go/net/http/readrequest_test.go
+++ b/libgo/go/net/http/readrequest_test.go
@@ -219,7 +219,7 @@ func TestReadRequest(t *testing.T) {
t.Errorf("#%d: Body = %q want %q", i, body, tt.Body)
}
if !reflect.DeepEqual(tt.Trailer, req.Trailer) {
- t.Errorf("%#d. Trailers differ.\n got: %v\nwant: %v", i, req.Trailer, tt.Trailer)
+ t.Errorf("#%d. Trailers differ.\n got: %v\nwant: %v", i, req.Trailer, tt.Trailer)
}
}
}
diff --git a/libgo/go/net/http/request_test.go b/libgo/go/net/http/request_test.go
index 714cb64..7b78645 100644
--- a/libgo/go/net/http/request_test.go
+++ b/libgo/go/net/http/request_test.go
@@ -202,8 +202,8 @@ func validateTestMultipartContents(t *testing.T, req *Request, allMem bool) {
if g, e := req.FormValue("texta"), textaValue; g != e {
t.Errorf("texta value = %q, want %q", g, e)
}
- if g, e := req.FormValue("texta"), textaValue; g != e {
- t.Errorf("texta value = %q, want %q", g, e)
+ if g, e := req.FormValue("textb"), textbValue; g != e {
+ t.Errorf("textb value = %q, want %q", g, e)
}
if g := req.FormValue("missing"); g != "" {
t.Errorf("missing value = %q, want empty string", g)
@@ -214,14 +214,16 @@ func validateTestMultipartContents(t *testing.T, req *Request, allMem bool) {
t.Error(n, " is *os.File, should not be")
}
}
- fd := testMultipartFile(t, req, "filea", "filea.txt", fileaContents)
- assertMem("filea", fd)
- fd = testMultipartFile(t, req, "fileb", "fileb.txt", filebContents)
+ fda := testMultipartFile(t, req, "filea", "filea.txt", fileaContents)
+ defer fda.Close()
+ assertMem("filea", fda)
+ fdb := testMultipartFile(t, req, "fileb", "fileb.txt", filebContents)
+ defer fdb.Close()
if allMem {
- assertMem("fileb", fd)
+ assertMem("fileb", fdb)
} else {
- if _, ok := fd.(*os.File); !ok {
- t.Errorf("fileb has unexpected underlying type %T", fd)
+ if _, ok := fdb.(*os.File); !ok {
+ t.Errorf("fileb has unexpected underlying type %T", fdb)
}
}
diff --git a/libgo/go/net/http/serve_test.go b/libgo/go/net/http/serve_test.go
index c68e661..24e6b50 100644
--- a/libgo/go/net/http/serve_test.go
+++ b/libgo/go/net/http/serve_test.go
@@ -1164,15 +1164,15 @@ func BenchmarkClientServer(b *testing.B) {
for i := 0; i < b.N; i++ {
res, err := Get(ts.URL)
if err != nil {
- panic("Get: " + err.Error())
+ b.Fatal("Get:", err)
}
all, err := ioutil.ReadAll(res.Body)
if err != nil {
- panic("ReadAll: " + err.Error())
+ b.Fatal("ReadAll:", err)
}
body := string(all)
if body != "Hello world.\n" {
- panic("Got body: " + body)
+ b.Fatal("Got body:", body)
}
}
diff --git a/libgo/go/net/interface_bsd.go b/libgo/go/net/interface_bsd.go
index e896d43..907f80a 100644
--- a/libgo/go/net/interface_bsd.go
+++ b/libgo/go/net/interface_bsd.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin freebsd openbsd
+// +build darwin freebsd netbsd openbsd
// Network interface identification for BSD variants
@@ -18,21 +18,16 @@ import (
// network interfaces. Otheriwse it returns a mapping of a specific
// interface.
func interfaceTable(ifindex int) ([]Interface, error) {
- var (
- tab []byte
- e error
- msgs []syscall.RoutingMessage
- ift []Interface
- )
-
- tab, e = syscall.RouteRIB(syscall.NET_RT_IFLIST, ifindex)
- if e != nil {
- return nil, os.NewSyscallError("route rib", e)
+ var ift []Interface
+
+ tab, err := syscall.RouteRIB(syscall.NET_RT_IFLIST, ifindex)
+ if err != nil {
+ return nil, os.NewSyscallError("route rib", err)
}
- msgs, e = syscall.ParseRoutingMessage(tab)
- if e != nil {
- return nil, os.NewSyscallError("route message", e)
+ msgs, err := syscall.ParseRoutingMessage(tab)
+ if err != nil {
+ return nil, os.NewSyscallError("route message", err)
}
for _, m := range msgs {
@@ -54,9 +49,9 @@ func interfaceTable(ifindex int) ([]Interface, error) {
func newLink(m *syscall.InterfaceMessage) ([]Interface, error) {
var ift []Interface
- sas, e := syscall.ParseRoutingSockaddr(m)
- if e != nil {
- return nil, os.NewSyscallError("route sockaddr", e)
+ sas, err := syscall.ParseRoutingSockaddr(m)
+ if err != nil {
+ return nil, os.NewSyscallError("route sockaddr", err)
}
for _, s := range sas {
@@ -108,21 +103,16 @@ func linkFlags(rawFlags int32) Flags {
// for all network interfaces. Otherwise it returns addresses
// for a specific interface.
func interfaceAddrTable(ifindex int) ([]Addr, error) {
- var (
- tab []byte
- e error
- msgs []syscall.RoutingMessage
- ifat []Addr
- )
-
- tab, e = syscall.RouteRIB(syscall.NET_RT_IFLIST, ifindex)
- if e != nil {
- return nil, os.NewSyscallError("route rib", e)
+ var ifat []Addr
+
+ tab, err := syscall.RouteRIB(syscall.NET_RT_IFLIST, ifindex)
+ if err != nil {
+ return nil, os.NewSyscallError("route rib", err)
}
- msgs, e = syscall.ParseRoutingMessage(tab)
- if e != nil {
- return nil, os.NewSyscallError("route message", e)
+ msgs, err := syscall.ParseRoutingMessage(tab)
+ if err != nil {
+ return nil, os.NewSyscallError("route message", err)
}
for _, m := range msgs {
@@ -133,7 +123,7 @@ func interfaceAddrTable(ifindex int) ([]Addr, error) {
if err != nil {
return nil, err
}
- ifat = append(ifat, ifa...)
+ ifat = append(ifat, ifa)
}
}
}
@@ -141,32 +131,41 @@ func interfaceAddrTable(ifindex int) ([]Addr, error) {
return ifat, nil
}
-func newAddr(m *syscall.InterfaceAddrMessage) ([]Addr, error) {
- var ifat []Addr
+func newAddr(m *syscall.InterfaceAddrMessage) (Addr, error) {
+ ifa := &IPNet{}
- sas, e := syscall.ParseRoutingSockaddr(m)
- if e != nil {
- return nil, os.NewSyscallError("route sockaddr", e)
+ sas, err := syscall.ParseRoutingSockaddr(m)
+ if err != nil {
+ return nil, os.NewSyscallError("route sockaddr", err)
}
- for _, s := range sas {
+ for i, s := range sas {
switch v := s.(type) {
case *syscall.SockaddrInet4:
- ifa := &IPAddr{IP: IPv4(v.Addr[0], v.Addr[1], v.Addr[2], v.Addr[3])}
- ifat = append(ifat, ifa.toAddr())
+ switch i {
+ case 0:
+ ifa.Mask = IPv4Mask(v.Addr[0], v.Addr[1], v.Addr[2], v.Addr[3])
+ case 1:
+ ifa.IP = IPv4(v.Addr[0], v.Addr[1], v.Addr[2], v.Addr[3])
+ }
case *syscall.SockaddrInet6:
- ifa := &IPAddr{IP: make(IP, IPv6len)}
- copy(ifa.IP, v.Addr[:])
- // NOTE: KAME based IPv6 protcol stack usually embeds
- // the interface index in the interface-local or link-
- // local address as the kernel-internal form.
- if ifa.IP.IsLinkLocalUnicast() {
- // remove embedded scope zone ID
- ifa.IP[2], ifa.IP[3] = 0, 0
+ switch i {
+ case 0:
+ ifa.Mask = make(IPMask, IPv6len)
+ copy(ifa.Mask, v.Addr[:])
+ case 1:
+ ifa.IP = make(IP, IPv6len)
+ copy(ifa.IP, v.Addr[:])
+ // NOTE: KAME based IPv6 protcol stack usually embeds
+ // the interface index in the interface-local or link-
+ // local address as the kernel-internal form.
+ if ifa.IP.IsLinkLocalUnicast() {
+ // remove embedded scope zone ID
+ ifa.IP[2], ifa.IP[3] = 0, 0
+ }
}
- ifat = append(ifat, ifa.toAddr())
}
}
- return ifat, nil
+ return ifa, nil
}
diff --git a/libgo/go/net/interface_linux.go b/libgo/go/net/interface_linux.go
index 96db718..c0887c5 100644
--- a/libgo/go/net/interface_linux.go
+++ b/libgo/go/net/interface_linux.go
@@ -17,21 +17,16 @@ import (
// network interfaces. Otheriwse it returns a mapping of a specific
// interface.
func interfaceTable(ifindex int) ([]Interface, error) {
- var (
- ift []Interface
- tab []byte
- msgs []syscall.NetlinkMessage
- e error
- )
+ var ift []Interface
- tab, e = syscall.NetlinkRIB(syscall.RTM_GETLINK, syscall.AF_UNSPEC)
- if e != nil {
- return nil, os.NewSyscallError("netlink rib", e)
+ tab, err := syscall.NetlinkRIB(syscall.RTM_GETLINK, syscall.AF_UNSPEC)
+ if err != nil {
+ return nil, os.NewSyscallError("netlink rib", err)
}
- msgs, e = syscall.ParseNetlinkMessage(tab)
- if e != nil {
- return nil, os.NewSyscallError("netlink message", e)
+ msgs, err := syscall.ParseNetlinkMessage(tab)
+ if err != nil {
+ return nil, os.NewSyscallError("netlink message", err)
}
for _, m := range msgs {
@@ -41,11 +36,11 @@ func interfaceTable(ifindex int) ([]Interface, error) {
case syscall.RTM_NEWLINK:
ifim := (*syscall.IfInfomsg)(unsafe.Pointer(&m.Data[0]))
if ifindex == 0 || ifindex == int(ifim.Index) {
- attrs, e := syscall.ParseNetlinkRouteAttr(&m)
- if e != nil {
- return nil, os.NewSyscallError("netlink routeattr", e)
+ attrs, err := syscall.ParseNetlinkRouteAttr(&m)
+ if err != nil {
+ return nil, os.NewSyscallError("netlink routeattr", err)
}
- ifi := newLink(attrs, ifim)
+ ifi := newLink(ifim, attrs)
ift = append(ift, ifi)
}
}
@@ -55,7 +50,7 @@ done:
return ift, nil
}
-func newLink(attrs []syscall.NetlinkRouteAttr, ifim *syscall.IfInfomsg) Interface {
+func newLink(ifim *syscall.IfInfomsg, attrs []syscall.NetlinkRouteAttr) Interface {
ifi := Interface{Index: int(ifim.Index), Flags: linkFlags(ifim.Flags)}
for _, a := range attrs {
switch a.Attr.Type {
@@ -102,19 +97,19 @@ func linkFlags(rawFlags uint32) Flags {
// for all network interfaces. Otherwise it returns addresses
// for a specific interface.
func interfaceAddrTable(ifindex int) ([]Addr, error) {
- tab, e := syscall.NetlinkRIB(syscall.RTM_GETADDR, syscall.AF_UNSPEC)
- if e != nil {
- return nil, os.NewSyscallError("netlink rib", e)
+ tab, err := syscall.NetlinkRIB(syscall.RTM_GETADDR, syscall.AF_UNSPEC)
+ if err != nil {
+ return nil, os.NewSyscallError("netlink rib", err)
}
- msgs, e := syscall.ParseNetlinkMessage(tab)
- if e != nil {
- return nil, os.NewSyscallError("netlink message", e)
+ msgs, err := syscall.ParseNetlinkMessage(tab)
+ if err != nil {
+ return nil, os.NewSyscallError("netlink message", err)
}
- ifat, e := addrTable(msgs, ifindex)
- if e != nil {
- return nil, e
+ ifat, err := addrTable(msgs, ifindex)
+ if err != nil {
+ return nil, err
}
return ifat, nil
@@ -130,11 +125,11 @@ func addrTable(msgs []syscall.NetlinkMessage, ifindex int) ([]Addr, error) {
case syscall.RTM_NEWADDR:
ifam := (*syscall.IfAddrmsg)(unsafe.Pointer(&m.Data[0]))
if ifindex == 0 || ifindex == int(ifam.Index) {
- attrs, e := syscall.ParseNetlinkRouteAttr(&m)
- if e != nil {
- return nil, os.NewSyscallError("netlink routeattr", e)
+ attrs, err := syscall.ParseNetlinkRouteAttr(&m)
+ if err != nil {
+ return nil, os.NewSyscallError("netlink routeattr", err)
}
- ifat = append(ifat, newAddr(attrs, int(ifam.Family))...)
+ ifat = append(ifat, newAddr(attrs, int(ifam.Family), int(ifam.Prefixlen)))
}
}
}
@@ -143,25 +138,23 @@ done:
return ifat, nil
}
-func newAddr(attrs []syscall.NetlinkRouteAttr, family int) []Addr {
- var ifat []Addr
-
+func newAddr(attrs []syscall.NetlinkRouteAttr, family, pfxlen int) Addr {
+ ifa := &IPNet{}
for _, a := range attrs {
switch a.Attr.Type {
case syscall.IFA_ADDRESS:
switch family {
case syscall.AF_INET:
- ifa := &IPAddr{IP: IPv4(a.Value[0], a.Value[1], a.Value[2], a.Value[3])}
- ifat = append(ifat, ifa.toAddr())
+ ifa.IP = IPv4(a.Value[0], a.Value[1], a.Value[2], a.Value[3])
+ ifa.Mask = CIDRMask(pfxlen, 8*IPv4len)
case syscall.AF_INET6:
- ifa := &IPAddr{IP: make(IP, IPv6len)}
+ ifa.IP = make(IP, IPv6len)
copy(ifa.IP, a.Value[:])
- ifat = append(ifat, ifa.toAddr())
+ ifa.Mask = CIDRMask(pfxlen, 8*IPv6len)
}
}
}
-
- return ifat
+ return ifa
}
// If the ifindex is zero, interfaceMulticastAddrTable returns
@@ -169,8 +162,8 @@ func newAddr(attrs []syscall.NetlinkRouteAttr, family int) []Addr {
// addresses for a specific interface.
func interfaceMulticastAddrTable(ifindex int) ([]Addr, error) {
var (
- ifi *Interface
err error
+ ifi *Interface
)
if ifindex > 0 {
diff --git a/libgo/go/net/interface_netbsd.go b/libgo/go/net/interface_netbsd.go
new file mode 100644
index 0000000..4150e9a
--- /dev/null
+++ b/libgo/go/net/interface_netbsd.go
@@ -0,0 +1,14 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Network interface identification for NetBSD
+
+package net
+
+// If the ifindex is zero, interfaceMulticastAddrTable returns
+// addresses for all network interfaces. Otherwise it returns
+// addresses for a specific interface.
+func interfaceMulticastAddrTable(ifindex int) ([]Addr, error) {
+ return nil, nil
+}
diff --git a/libgo/go/net/interface_test.go b/libgo/go/net/interface_test.go
index cc61491..4ce01dc 100644
--- a/libgo/go/net/interface_test.go
+++ b/libgo/go/net/interface_test.go
@@ -24,7 +24,7 @@ func sameInterface(i, j *Interface) bool {
func TestInterfaces(t *testing.T) {
ift, err := Interfaces()
if err != nil {
- t.Fatalf("Interfaces() failed: %v", err)
+ t.Fatalf("Interfaces failed: %v", err)
}
t.Logf("table: len/cap = %v/%v\n", len(ift), cap(ift))
@@ -43,34 +43,57 @@ func TestInterfaces(t *testing.T) {
if !sameInterface(ifxn, &ifi) {
t.Fatalf("InterfaceByName(%#q) = %v, want %v", ifi.Name, *ifxn, ifi)
}
- ifat, err := ifi.Addrs()
- if err != nil {
- t.Fatalf("Interface.Addrs() failed: %v", err)
- }
- ifmat, err := ifi.MulticastAddrs()
- if err != nil {
- t.Fatalf("Interface.MulticastAddrs() failed: %v", err)
- }
t.Logf("%q: flags %q, ifindex %v, mtu %v\n", ifi.Name, ifi.Flags.String(), ifi.Index, ifi.MTU)
- for _, ifa := range ifat {
- t.Logf("\tinterface address %q\n", ifa.String())
- }
- for _, ifma := range ifmat {
- t.Logf("\tjoined group address %q\n", ifma.String())
- }
t.Logf("\thardware address %q", ifi.HardwareAddr.String())
+ testInterfaceAddrs(t, &ifi)
+ testInterfaceMulticastAddrs(t, &ifi)
}
}
func TestInterfaceAddrs(t *testing.T) {
ifat, err := InterfaceAddrs()
if err != nil {
- t.Fatalf("InterfaceAddrs() failed: %v", err)
+ t.Fatalf("InterfaceAddrs failed: %v", err)
}
t.Logf("table: len/cap = %v/%v\n", len(ifat), cap(ifat))
+ testAddrs(t, ifat)
+}
+
+func testInterfaceAddrs(t *testing.T, ifi *Interface) {
+ ifat, err := ifi.Addrs()
+ if err != nil {
+ t.Fatalf("Interface.Addrs failed: %v", err)
+ }
+ testAddrs(t, ifat)
+}
+
+func testInterfaceMulticastAddrs(t *testing.T, ifi *Interface) {
+ ifmat, err := ifi.MulticastAddrs()
+ if err != nil {
+ t.Fatalf("Interface.MulticastAddrs failed: %v", err)
+ }
+ testMulticastAddrs(t, ifmat)
+}
+func testAddrs(t *testing.T, ifat []Addr) {
for _, ifa := range ifat {
- t.Logf("interface address %q\n", ifa.String())
+ switch ifa.(type) {
+ case *IPAddr, *IPNet:
+ t.Logf("\tinterface address %q\n", ifa.String())
+ default:
+ t.Errorf("\tunexpected type: %T", ifa)
+ }
+ }
+}
+
+func testMulticastAddrs(t *testing.T, ifmat []Addr) {
+ for _, ifma := range ifmat {
+ switch ifma.(type) {
+ case *IPAddr:
+ t.Logf("\tjoined group address %q\n", ifma.String())
+ default:
+ t.Errorf("\tunexpected type: %T", ifma)
+ }
}
}
diff --git a/libgo/go/net/ip.go b/libgo/go/net/ip.go
index 4a38882..979d7ac 100644
--- a/libgo/go/net/ip.go
+++ b/libgo/go/net/ip.go
@@ -450,6 +450,9 @@ func (n *IPNet) String() string {
return nn.String() + "/" + itod(uint(l))
}
+// Network returns the address's network name, "ip+net".
+func (n *IPNet) Network() string { return "ip+net" }
+
// Parse IPv4 address (d.d.d.d).
func parseIPv4(s string) IP {
var p [IPv4len]byte
diff --git a/libgo/go/net/ipraw_test.go b/libgo/go/net/ipraw_test.go
index 60c405a..67a4049 100644
--- a/libgo/go/net/ipraw_test.go
+++ b/libgo/go/net/ipraw_test.go
@@ -59,6 +59,7 @@ func parsePingReply(p []byte) (id, seq int) {
}
var srchost = flag.String("srchost", "", "Source of the ICMP ECHO request")
+
// 127.0.0.1 because this is an IPv4-specific test.
var dsthost = flag.String("dsthost", "127.0.0.1", "Destination for the ICMP ECHO request")
diff --git a/libgo/go/net/iprawsock_posix.go b/libgo/go/net/iprawsock_posix.go
index d3cb38a..7bb4c7d 100644
--- a/libgo/go/net/iprawsock_posix.go
+++ b/libgo/go/net/iprawsock_posix.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin freebsd linux openbsd windows
+// +build darwin freebsd linux netbsd openbsd windows
// (Raw) IP sockets
diff --git a/libgo/go/net/ipsock_posix.go b/libgo/go/net/ipsock_posix.go
index f0ca7da..d141c05 100644
--- a/libgo/go/net/ipsock_posix.go
+++ b/libgo/go/net/ipsock_posix.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin freebsd linux openbsd windows
+// +build darwin freebsd linux netbsd openbsd windows
package net
diff --git a/libgo/go/net/lookup_unix.go b/libgo/go/net/lookup_unix.go
index aae6d6c..5c47547 100644
--- a/libgo/go/net/lookup_unix.go
+++ b/libgo/go/net/lookup_unix.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin freebsd linux openbsd
+// +build darwin freebsd linux netbsd openbsd
package net
diff --git a/libgo/go/net/net.go b/libgo/go/net/net.go
index 48f0ae7..b236dfd 100644
--- a/libgo/go/net/net.go
+++ b/libgo/go/net/net.go
@@ -157,6 +157,14 @@ func (e *OpError) Timeout() bool {
return ok && t.Timeout()
}
+type timeoutError struct{}
+
+func (e *timeoutError) Error() string { return "i/o timeout" }
+func (e *timeoutError) Timeout() bool { return true }
+func (e *timeoutError) Temporary() bool { return true }
+
+var errTimeout error = &timeoutError{}
+
type AddrError struct {
Err string
Addr string
diff --git a/libgo/go/net/newpollserver.go b/libgo/go/net/newpollserver.go
index 035df4a..a410bb6 100644
--- a/libgo/go/net/newpollserver.go
+++ b/libgo/go/net/newpollserver.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin freebsd linux openbsd
+// +build darwin freebsd linux netbsd openbsd
package net
diff --git a/libgo/go/net/port.go b/libgo/go/net/port.go
index 80597f7..16780da 100644
--- a/libgo/go/net/port.go
+++ b/libgo/go/net/port.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin freebsd linux openbsd
+// +build darwin freebsd linux netbsd openbsd
// Read system port mappings from /etc/services
diff --git a/libgo/go/net/rpc/server_test.go b/libgo/go/net/rpc/server_test.go
index a52a86e..c1845fa 100644
--- a/libgo/go/net/rpc/server_test.go
+++ b/libgo/go/net/rpc/server_test.go
@@ -516,12 +516,10 @@ func benchmarkEndToEnd(dial func() (*Client, error), b *testing.B) {
for atomic.AddInt32(&N, -1) >= 0 {
err = client.Call("Arith.Add", args, reply)
if err != nil {
- fmt.Printf("Add: expected no error but got string %q", err.Error())
- panic("rpc error")
+ b.Fatalf("rpc error: Add: expected no error but got string %q", err.Error())
}
if reply.C != args.A+args.B {
- fmt.Printf("Add: expected %d got %d", reply.C, args.A+args.B)
- panic("rpc error")
+ b.Fatalf("rpc error: Add: expected %d got %d", reply.C, args.A+args.B)
}
}
wg.Done()
@@ -536,8 +534,7 @@ func benchmarkEndToEndAsync(dial func() (*Client, error), b *testing.B) {
once.Do(startServer)
client, err := dial()
if err != nil {
- fmt.Println("error dialing", err)
- return
+ b.Fatalf("error dialing:", err)
}
// Asynchronous calls
@@ -561,12 +558,11 @@ func benchmarkEndToEndAsync(dial func() (*Client, error), b *testing.B) {
}()
go func() {
for call := range res {
- a := call.Args.(*Args).A
- b := call.Args.(*Args).B
- c := call.Reply.(*Reply).C
- if a+b != c {
- fmt.Printf("Add: expected %d got %d", a+b, c)
- panic("incorrect reply")
+ A := call.Args.(*Args).A
+ B := call.Args.(*Args).B
+ C := call.Reply.(*Reply).C
+ if A+B != C {
+ b.Fatalf("incorrect reply: Add: expected %d got %d", A+B, C)
}
<-gate
if atomic.AddInt32(&recv, -1) == 0 {
diff --git a/libgo/go/net/sendfile_stub.go b/libgo/go/net/sendfile_stub.go
index b0adea4..ff76ab9 100644
--- a/libgo/go/net/sendfile_stub.go
+++ b/libgo/go/net/sendfile_stub.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin freebsd openbsd
+// +build darwin freebsd netbsd openbsd
package net
diff --git a/libgo/go/net/sock.go b/libgo/go/net/sock.go
index 777f204..dc07392 100644
--- a/libgo/go/net/sock.go
+++ b/libgo/go/net/sock.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin freebsd linux openbsd windows
+// +build darwin freebsd linux netbsd openbsd windows
// Sockets
diff --git a/libgo/go/net/sock_bsd.go b/libgo/go/net/sock_bsd.go
index 7025edf..816e4fc 100644
--- a/libgo/go/net/sock_bsd.go
+++ b/libgo/go/net/sock_bsd.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin freebsd openbsd
+// +build darwin freebsd netbsd openbsd
// Sockets for BSD variants
diff --git a/libgo/go/net/tcpsock_posix.go b/libgo/go/net/tcpsock_posix.go
index 44890ba..a7c09c7 100644
--- a/libgo/go/net/tcpsock_posix.go
+++ b/libgo/go/net/tcpsock_posix.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin freebsd linux openbsd windows
+// +build darwin freebsd linux netbsd openbsd windows
// TCP sockets
diff --git a/libgo/go/net/textproto/reader_test.go b/libgo/go/net/textproto/reader_test.go
index 5aefe39..0460c1c 100644
--- a/libgo/go/net/textproto/reader_test.go
+++ b/libgo/go/net/textproto/reader_test.go
@@ -203,7 +203,7 @@ func TestRFC959Lines(t *testing.T) {
t.Errorf("#%d: code=%d, want %d", i, code, tt.wantCode)
}
if msg != tt.wantMsg {
- t.Errorf("%#d: msg=%q, want %q", i, msg, tt.wantMsg)
+ t.Errorf("#%d: msg=%q, want %q", i, msg, tt.wantMsg)
}
}
}
diff --git a/libgo/go/net/udpsock_posix.go b/libgo/go/net/udpsock_posix.go
index c25ec9c..6bb1571 100644
--- a/libgo/go/net/udpsock_posix.go
+++ b/libgo/go/net/udpsock_posix.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin freebsd linux openbsd windows
+// +build darwin freebsd linux netbsd openbsd windows
// UDP sockets
diff --git a/libgo/go/net/unixsock_posix.go b/libgo/go/net/unixsock_posix.go
index 929f640..10632c1 100644
--- a/libgo/go/net/unixsock_posix.go
+++ b/libgo/go/net/unixsock_posix.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin freebsd linux openbsd windows
+// +build darwin freebsd linux netbsd openbsd windows
// Unix domain sockets