summaryrefslogtreecommitdiff
path: root/src/pkg/net
diff options
context:
space:
mode:
authorOndřej Surý <ondrej@sury.org>2011-09-13 13:11:55 +0200
committerOndřej Surý <ondrej@sury.org>2011-09-13 13:11:55 +0200
commit80f18fc933cf3f3e829c5455a1023d69f7b86e52 (patch)
tree4b825dc642cb6eb9a060e54bf8d69288fbee4904 /src/pkg/net
parent28592ee1ea1f5cdffcf85472f9de0285d928cf12 (diff)
downloadgolang-80f18fc933cf3f3e829c5455a1023d69f7b86e52.tar.gz
Imported Upstream version 60
Diffstat (limited to 'src/pkg/net')
-rw-r--r--src/pkg/net/Makefile96
-rw-r--r--src/pkg/net/cgo_bsd.go14
-rw-r--r--src/pkg/net/cgo_linux.go14
-rw-r--r--src/pkg/net/cgo_stub.go25
-rw-r--r--src/pkg/net/cgo_unix.go148
-rw-r--r--src/pkg/net/dial.go153
-rw-r--r--src/pkg/net/dialgoogle_test.go169
-rw-r--r--src/pkg/net/dict/Makefile7
-rw-r--r--src/pkg/net/dict/dict.go212
-rw-r--r--src/pkg/net/dnsclient.go224
-rw-r--r--src/pkg/net/dnsclient_unix.go262
-rw-r--r--src/pkg/net/dnsconfig.go119
-rw-r--r--src/pkg/net/dnsmsg.go780
-rw-r--r--src/pkg/net/dnsmsg_test.go100
-rw-r--r--src/pkg/net/dnsname_test.go65
-rw-r--r--src/pkg/net/fd.go639
-rw-r--r--src/pkg/net/fd_darwin.go120
-rw-r--r--src/pkg/net/fd_freebsd.go116
-rw-r--r--src/pkg/net/fd_linux.go182
-rw-r--r--src/pkg/net/fd_windows.go529
-rw-r--r--src/pkg/net/file.go119
-rw-r--r--src/pkg/net/file_test.go133
-rw-r--r--src/pkg/net/file_windows.go25
-rw-r--r--src/pkg/net/hosts.go86
-rw-r--r--src/pkg/net/hosts_test.go68
-rw-r--r--src/pkg/net/hosts_testdata12
-rw-r--r--src/pkg/net/interface.go123
-rw-r--r--src/pkg/net/interface_bsd.go172
-rw-r--r--src/pkg/net/interface_linux.go185
-rw-r--r--src/pkg/net/interface_stub.go23
-rw-r--r--src/pkg/net/interface_test.go66
-rw-r--r--src/pkg/net/interface_windows.go152
-rw-r--r--src/pkg/net/ip.go614
-rw-r--r--src/pkg/net/ip_test.go215
-rw-r--r--src/pkg/net/ipraw_test.go121
-rw-r--r--src/pkg/net/iprawsock.go363
-rw-r--r--src/pkg/net/ipsock.go323
-rw-r--r--src/pkg/net/lookup_unix.go126
-rw-r--r--src/pkg/net/lookup_windows.go107
-rw-r--r--src/pkg/net/multicast_test.go73
-rw-r--r--src/pkg/net/net.go188
-rw-r--r--src/pkg/net/net_test.go121
-rw-r--r--src/pkg/net/newpollserver.go43
-rw-r--r--src/pkg/net/parse.go204
-rw-r--r--src/pkg/net/parse_test.go50
-rw-r--r--src/pkg/net/pipe.go62
-rw-r--r--src/pkg/net/pipe_test.go57
-rw-r--r--src/pkg/net/port.go70
-rw-r--r--src/pkg/net/port_test.go53
-rw-r--r--src/pkg/net/sendfile_linux.go84
-rw-r--r--src/pkg/net/sendfile_stub.go14
-rw-r--r--src/pkg/net/sendfile_windows.go68
-rw-r--r--src/pkg/net/server_test.go243
-rw-r--r--src/pkg/net/sock.go166
-rw-r--r--src/pkg/net/sock_bsd.go31
-rw-r--r--src/pkg/net/sock_linux.go25
-rw-r--r--src/pkg/net/sock_windows.go25
-rw-r--r--src/pkg/net/srv_test.go29
-rw-r--r--src/pkg/net/tcpsock.go304
-rw-r--r--src/pkg/net/textproto/Makefile15
-rw-r--r--src/pkg/net/textproto/header.go43
-rw-r--r--src/pkg/net/textproto/pipeline.go117
-rw-r--r--src/pkg/net/textproto/reader.go492
-rw-r--r--src/pkg/net/textproto/reader_test.go140
-rw-r--r--src/pkg/net/textproto/textproto.go121
-rw-r--r--src/pkg/net/textproto/writer.go119
-rw-r--r--src/pkg/net/textproto/writer_test.go35
-rw-r--r--src/pkg/net/timeout_test.go57
-rw-r--r--src/pkg/net/udpsock.go323
-rw-r--r--src/pkg/net/unixsock.go449
70 files changed, 0 insertions, 10828 deletions
diff --git a/src/pkg/net/Makefile b/src/pkg/net/Makefile
deleted file mode 100644
index 536fe369d..000000000
--- a/src/pkg/net/Makefile
+++ /dev/null
@@ -1,96 +0,0 @@
-# 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.
-
-include ../../Make.inc
-
-TARG=net
-GOFILES=\
- dial.go\
- dnsclient.go\
- dnsmsg.go\
- fd_$(GOOS).go\
- hosts.go\
- interface.go\
- ip.go\
- ipsock.go\
- iprawsock.go\
- net.go\
- parse.go\
- pipe.go\
- sock.go\
- tcpsock.go\
- udpsock.go\
- unixsock.go\
-
-GOFILES_freebsd=\
- dnsclient_unix.go\
- dnsconfig.go\
- fd.go\
- file.go\
- interface_bsd.go\
- lookup_unix.go\
- newpollserver.go\
- port.go\
- sendfile_stub.go\
- sock_bsd.go\
-
-CGOFILES_freebsd=\
- cgo_bsd.go\
- cgo_unix.go\
-
-GOFILES_darwin=\
- dnsclient_unix.go\
- dnsconfig.go\
- fd.go\
- file.go\
- interface_bsd.go\
- lookup_unix.go\
- newpollserver.go\
- port.go\
- sendfile_stub.go\
- sock_bsd.go\
-
-CGOFILES_darwin=\
- cgo_bsd.go\
- cgo_unix.go\
-
-GOFILES_linux=\
- dnsclient_unix.go\
- dnsconfig.go\
- fd.go\
- file.go\
- interface_linux.go\
- lookup_unix.go\
- newpollserver.go\
- port.go\
- sendfile_linux.go\
- sock_linux.go\
-
-GOFILES_plan9=\
- interface_stub.go\
- lookup_unix.go\
- sendfile_stub.go\
-
-ifeq ($(GOARCH),arm)
-# ARM has no cgo, so use the stubs.
-GOFILES_linux+=cgo_stub.go
-else
-CGOFILES_linux=\
- cgo_linux.go\
- cgo_unix.go
-endif
-
-GOFILES_windows=\
- file_windows.go\
- interface_windows.go\
- lookup_windows.go\
- sendfile_windows.go\
- sock_windows.go\
-
-GOFILES+=$(GOFILES_$(GOOS))
-ifneq ($(CGOFILES_$(GOOS)),)
-CGOFILES+=$(CGOFILES_$(GOOS))
-endif
-
-include ../../Make.pkg
diff --git a/src/pkg/net/cgo_bsd.go b/src/pkg/net/cgo_bsd.go
deleted file mode 100644
index 4984df4a2..000000000
--- a/src/pkg/net/cgo_bsd.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// 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
-
-/*
-#include <netdb.h>
-*/
-import "C"
-
-func cgoAddrInfoMask() C.int {
- return C.AI_MASK
-}
diff --git a/src/pkg/net/cgo_linux.go b/src/pkg/net/cgo_linux.go
deleted file mode 100644
index 8d4413d2d..000000000
--- a/src/pkg/net/cgo_linux.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// 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
-
-/*
-#include <netdb.h>
-*/
-import "C"
-
-func cgoAddrInfoMask() C.int {
- return C.AI_CANONNAME | C.AI_V4MAPPED | C.AI_ALL
-}
diff --git a/src/pkg/net/cgo_stub.go b/src/pkg/net/cgo_stub.go
deleted file mode 100644
index c6277cb65..000000000
--- a/src/pkg/net/cgo_stub.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// 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.
-
-// Stub cgo routines for systems that do not use cgo to do network lookups.
-
-package net
-
-import "os"
-
-func cgoLookupHost(name string) (addrs []string, err os.Error, completed bool) {
- return nil, nil, false
-}
-
-func cgoLookupPort(network, service string) (port int, err os.Error, completed bool) {
- return 0, nil, false
-}
-
-func cgoLookupIP(name string) (addrs []IP, err os.Error, completed bool) {
- return nil, nil, false
-}
-
-func cgoLookupCNAME(name string) (cname string, err os.Error, completed bool) {
- return "", nil, false
-}
diff --git a/src/pkg/net/cgo_unix.go b/src/pkg/net/cgo_unix.go
deleted file mode 100644
index a3711d601..000000000
--- a/src/pkg/net/cgo_unix.go
+++ /dev/null
@@ -1,148 +0,0 @@
-// 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
-
-/*
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-*/
-import "C"
-
-import (
- "os"
- "syscall"
- "unsafe"
-)
-
-func cgoLookupHost(name string) (addrs []string, err os.Error, completed bool) {
- ip, err, completed := cgoLookupIP(name)
- for _, p := range ip {
- addrs = append(addrs, p.String())
- }
- return
-}
-
-func cgoLookupPort(net, service string) (port int, err os.Error, completed bool) {
- var res *C.struct_addrinfo
- var hints C.struct_addrinfo
-
- switch net {
- case "":
- // no hints
- case "tcp", "tcp4", "tcp6":
- hints.ai_socktype = C.SOCK_STREAM
- hints.ai_protocol = C.IPPROTO_TCP
- case "udp", "udp4", "udp6":
- hints.ai_socktype = C.SOCK_DGRAM
- hints.ai_protocol = C.IPPROTO_UDP
- default:
- return 0, UnknownNetworkError(net), true
- }
- if len(net) >= 4 {
- switch net[3] {
- case '4':
- hints.ai_family = C.AF_INET
- case '6':
- hints.ai_family = C.AF_INET6
- }
- }
-
- s := C.CString(service)
- defer C.free(unsafe.Pointer(s))
- if C.getaddrinfo(nil, s, &hints, &res) == 0 {
- defer C.freeaddrinfo(res)
- for r := res; r != nil; r = r.ai_next {
- switch r.ai_family {
- default:
- continue
- case C.AF_INET:
- sa := (*syscall.RawSockaddrInet4)(unsafe.Pointer(r.ai_addr))
- p := (*[2]byte)(unsafe.Pointer(&sa.Port))
- return int(p[0])<<8 | int(p[1]), nil, true
- case C.AF_INET6:
- sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(r.ai_addr))
- p := (*[2]byte)(unsafe.Pointer(&sa.Port))
- return int(p[0])<<8 | int(p[1]), nil, true
- }
- }
- }
- return 0, &AddrError{"unknown port", net + "/" + service}, true
-}
-
-func cgoLookupIPCNAME(name string) (addrs []IP, cname string, err os.Error, completed bool) {
- var res *C.struct_addrinfo
- var hints C.struct_addrinfo
-
- // NOTE(rsc): In theory there are approximately balanced
- // arguments for and against including AI_ADDRCONFIG
- // in the flags (it includes IPv4 results only on IPv4 systems,
- // and similarly for IPv6), but in practice setting it causes
- // getaddrinfo to return the wrong canonical name on Linux.
- // So definitely leave it out.
- hints.ai_flags = (C.AI_ALL | C.AI_V4MAPPED | C.AI_CANONNAME) & cgoAddrInfoMask()
-
- h := C.CString(name)
- defer C.free(unsafe.Pointer(h))
- gerrno, err := C.getaddrinfo(h, nil, &hints, &res)
- if gerrno != 0 {
- var str string
- if gerrno == C.EAI_NONAME {
- str = noSuchHost
- } else if gerrno == C.EAI_SYSTEM {
- str = err.String()
- } else {
- str = C.GoString(C.gai_strerror(gerrno))
- }
- return nil, "", &DNSError{Error: str, Name: name}, true
- }
- defer C.freeaddrinfo(res)
- if res != nil {
- cname = C.GoString(res.ai_canonname)
- if cname == "" {
- cname = name
- }
- if len(cname) > 0 && cname[len(cname)-1] != '.' {
- cname += "."
- }
- }
- for r := res; r != nil; r = r.ai_next {
- // Everything comes back twice, once for UDP and once for TCP.
- if r.ai_socktype != C.SOCK_STREAM {
- continue
- }
- switch r.ai_family {
- default:
- continue
- case C.AF_INET:
- sa := (*syscall.RawSockaddrInet4)(unsafe.Pointer(r.ai_addr))
- addrs = append(addrs, copyIP(sa.Addr[:]))
- case C.AF_INET6:
- sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(r.ai_addr))
- addrs = append(addrs, copyIP(sa.Addr[:]))
- }
- }
- return addrs, cname, nil, true
-}
-
-func cgoLookupIP(name string) (addrs []IP, err os.Error, completed bool) {
- addrs, _, err, completed = cgoLookupIPCNAME(name)
- return
-}
-
-func cgoLookupCNAME(name string) (cname string, err os.Error, completed bool) {
- _, cname, err, completed = cgoLookupIPCNAME(name)
- return
-}
-
-func copyIP(x IP) IP {
- y := make(IP, len(x))
- copy(y, x)
- return y
-}
diff --git a/src/pkg/net/dial.go b/src/pkg/net/dial.go
deleted file mode 100644
index 10c67dcc4..000000000
--- a/src/pkg/net/dial.go
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright 2010 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 "os"
-
-func resolveNetAddr(op, net, addr string) (a Addr, err os.Error) {
- if addr == "" {
- return nil, &OpError{op, net, nil, errMissingAddress}
- }
- switch net {
- case "tcp", "tcp4", "tcp6":
- a, err = ResolveTCPAddr(net, addr)
- case "udp", "udp4", "udp6":
- a, err = ResolveUDPAddr(net, addr)
- case "unix", "unixgram", "unixpacket":
- a, err = ResolveUnixAddr(net, addr)
- case "ip", "ip4", "ip6":
- a, err = ResolveIPAddr(net, addr)
- default:
- err = UnknownNetworkError(net)
- }
- if err != nil {
- return nil, &OpError{op, net + " " + addr, nil, err}
- }
- return
-}
-
-// Dial connects to the address addr on the network net.
-//
-// Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only),
-// "udp", "udp4" (IPv4-only), "udp6" (IPv6-only), "ip", "ip4"
-// (IPv4-only), "ip6" (IPv6-only), "unix" and "unixgram".
-//
-// For IP networks, addresses have the form host:port. If host is
-// a literal IPv6 address, it must be enclosed in square brackets.
-// The functions JoinHostPort and SplitHostPort manipulate
-// addresses in this form.
-//
-// Examples:
-// Dial("tcp", "12.34.56.78:80")
-// Dial("tcp", "google.com:80")
-// Dial("tcp", "[de:ad:be:ef::ca:fe]:80")
-//
-func Dial(net, addr string) (c Conn, err os.Error) {
- addri, err := resolveNetAddr("dial", net, addr)
- if err != nil {
- return nil, err
- }
- switch ra := addri.(type) {
- case *TCPAddr:
- c, err = DialTCP(net, nil, ra)
- case *UDPAddr:
- c, err = DialUDP(net, nil, ra)
- case *UnixAddr:
- c, err = DialUnix(net, nil, ra)
- case *IPAddr:
- c, err = DialIP(net, nil, ra)
- default:
- err = UnknownNetworkError(net)
- }
- if err != nil {
- return nil, &OpError{"dial", net + " " + addr, nil, err}
- }
- return
-}
-
-// 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".
-func Listen(net, laddr string) (l Listener, err os.Error) {
- switch net {
- case "tcp", "tcp4", "tcp6":
- var la *TCPAddr
- if laddr != "" {
- if la, err = ResolveTCPAddr(net, laddr); err != nil {
- return nil, err
- }
- }
- l, err := ListenTCP(net, la)
- if err != nil {
- return nil, err
- }
- return l, nil
- case "unix", "unixpacket":
- var la *UnixAddr
- if laddr != "" {
- if la, err = ResolveUnixAddr(net, laddr); err != nil {
- return nil, err
- }
- }
- l, err := ListenUnix(net, la)
- if err != nil {
- return nil, err
- }
- return l, nil
- }
- return nil, UnknownNetworkError(net)
-}
-
-// ListenPacket announces on the local network address laddr.
-// The network string net must be a packet-oriented network:
-// "udp", "udp4", "udp6", or "unixgram".
-func ListenPacket(net, laddr string) (c PacketConn, err os.Error) {
- switch net {
- case "udp", "udp4", "udp6":
- var la *UDPAddr
- if laddr != "" {
- if la, err = ResolveUDPAddr(net, laddr); err != nil {
- return nil, err
- }
- }
- c, err := ListenUDP(net, la)
- if err != nil {
- return nil, err
- }
- return c, nil
- case "unixgram":
- var la *UnixAddr
- if laddr != "" {
- if la, err = ResolveUnixAddr(net, laddr); err != nil {
- return nil, err
- }
- }
- c, err := DialUnix(net, la, nil)
- if err != nil {
- return nil, err
- }
- return c, nil
- }
-
- var rawnet string
- if rawnet, _, err = splitNetProto(net); err != nil {
- switch rawnet {
- case "ip", "ip4", "ip6":
- var la *IPAddr
- if laddr != "" {
- if la, err = ResolveIPAddr(rawnet, laddr); err != nil {
- return nil, err
- }
- }
- c, err := ListenIP(net, la)
- if err != nil {
- return nil, err
- }
- return c, nil
- }
- }
-
- return nil, UnknownNetworkError(net)
-}
diff --git a/src/pkg/net/dialgoogle_test.go b/src/pkg/net/dialgoogle_test.go
deleted file mode 100644
index 9ad1770da..000000000
--- a/src/pkg/net/dialgoogle_test.go
+++ /dev/null
@@ -1,169 +0,0 @@
-// 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.
-
-package net
-
-import (
- "flag"
- "fmt"
- "io"
- "strings"
- "syscall"
- "testing"
-)
-
-// If an IPv6 tunnel is running, we can try dialing a real IPv6 address.
-var ipv6 = flag.Bool("ipv6", false, "assume ipv6 tunnel is present")
-
-// fd is already connected to the destination, port 80.
-// Run an HTTP request to fetch the appropriate page.
-func fetchGoogle(t *testing.T, fd Conn, network, addr string) {
- req := []byte("GET /intl/en/privacy/ HTTP/1.0\r\nHost: www.google.com\r\n\r\n")
- n, err := fd.Write(req)
-
- buf := make([]byte, 1000)
- n, err = io.ReadFull(fd, buf)
-
- if n < 1000 {
- t.Errorf("fetchGoogle: short HTTP read from %s %s - %v", network, addr, err)
- return
- }
-}
-
-func doDial(t *testing.T, network, addr string) {
- fd, err := Dial(network, addr)
- if err != nil {
- t.Errorf("Dial(%q, %q, %q) = _, %v", network, "", addr, err)
- return
- }
- fetchGoogle(t, fd, network, addr)
- fd.Close()
-}
-
-func TestLookupCNAME(t *testing.T) {
- if testing.Short() {
- // Don't use external network.
- t.Logf("skipping external network test during -short")
- return
- }
- cname, err := LookupCNAME("www.google.com")
- if !strings.HasSuffix(cname, ".l.google.com.") || err != nil {
- t.Errorf(`LookupCNAME("www.google.com.") = %q, %v, want "*.l.google.com.", nil`, cname, err)
- }
-}
-
-var googleaddrsipv4 = []string{
- "%d.%d.%d.%d:80",
- "www.google.com:80",
- "%d.%d.%d.%d:http",
- "www.google.com:http",
- "%03d.%03d.%03d.%03d:0080",
- "[::ffff:%d.%d.%d.%d]:80",
- "[::ffff:%02x%02x:%02x%02x]:80",
- "[0:0:0:0:0000:ffff:%d.%d.%d.%d]:80",
- "[0:0:0:0:000000:ffff:%d.%d.%d.%d]:80",
- "[0:0:0:0:0:ffff::%d.%d.%d.%d]:80",
-}
-
-func TestDialGoogleIPv4(t *testing.T) {
- if testing.Short() {
- // Don't use external network.
- t.Logf("skipping external network test during -short")
- return
- }
-
- // Insert an actual IPv4 address for google.com
- // into the table.
- addrs, err := LookupIP("www.google.com")
- if err != nil {
- t.Fatalf("lookup www.google.com: %v", err)
- }
- var ip IP
- for _, addr := range addrs {
- if x := addr.To4(); x != nil {
- ip = x
- break
- }
- }
- if ip == nil {
- t.Fatalf("no IPv4 addresses for www.google.com")
- }
-
- for i, s := range googleaddrsipv4 {
- if strings.Contains(s, "%") {
- googleaddrsipv4[i] = fmt.Sprintf(s, ip[0], ip[1], ip[2], ip[3])
- }
- }
-
- for i := 0; i < len(googleaddrsipv4); i++ {
- addr := googleaddrsipv4[i]
- if addr == "" {
- continue
- }
- t.Logf("-- %s --", addr)
- doDial(t, "tcp", addr)
- if addr[0] != '[' {
- doDial(t, "tcp4", addr)
- if supportsIPv6 {
- // make sure syscall.SocketDisableIPv6 flag works.
- syscall.SocketDisableIPv6 = true
- doDial(t, "tcp", addr)
- doDial(t, "tcp4", addr)
- syscall.SocketDisableIPv6 = false
- }
- }
- }
-}
-
-var googleaddrsipv6 = []string{
- "[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:80",
- "ipv6.google.com:80",
- "[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:http",
- "ipv6.google.com:http",
-}
-
-func TestDialGoogleIPv6(t *testing.T) {
- if testing.Short() {
- // Don't use external network.
- t.Logf("skipping external network test during -short")
- return
- }
- // Only run tcp6 if the kernel will take it.
- if !*ipv6 || !supportsIPv6 {
- return
- }
-
- // Insert an actual IPv6 address for ipv6.google.com
- // into the table.
- addrs, err := LookupIP("ipv6.google.com")
- if err != nil {
- t.Fatalf("lookup ipv6.google.com: %v", err)
- }
- var ip IP
- for _, addr := range addrs {
- if x := addr.To16(); x != nil {
- ip = x
- break
- }
- }
- if ip == nil {
- t.Fatalf("no IPv6 addresses for ipv6.google.com")
- }
-
- for i, s := range googleaddrsipv6 {
- if strings.Contains(s, "%") {
- googleaddrsipv6[i] = fmt.Sprintf(s, ip[0], ip[1], ip[2], ip[3], ip[4], ip[5], ip[6], ip[7], ip[8], ip[9], ip[10], ip[11], ip[12], ip[13], ip[14], ip[15])
- }
- }
-
- for i := 0; i < len(googleaddrsipv6); i++ {
- addr := googleaddrsipv6[i]
- if addr == "" {
- continue
- }
- t.Logf("-- %s --", addr)
- doDial(t, "tcp", addr)
- doDial(t, "tcp6", addr)
- }
-}
diff --git a/src/pkg/net/dict/Makefile b/src/pkg/net/dict/Makefile
deleted file mode 100644
index eaa9e6531..000000000
--- a/src/pkg/net/dict/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-include ../../../Make.inc
-
-TARG=net/dict
-GOFILES=\
- dict.go\
-
-include ../../../Make.pkg
diff --git a/src/pkg/net/dict/dict.go b/src/pkg/net/dict/dict.go
deleted file mode 100644
index 42f6553ad..000000000
--- a/src/pkg/net/dict/dict.go
+++ /dev/null
@@ -1,212 +0,0 @@
-// Copyright 2010 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 dict implements the Dictionary Server Protocol
-// as defined in RFC 2229.
-package dict
-
-import (
- "container/vector"
- "net/textproto"
- "os"
- "strconv"
- "strings"
-)
-
-// A Client represents a client connection to a dictionary server.
-type Client struct {
- text *textproto.Conn
-}
-
-// Dial returns a new client connected to a dictionary server at
-// addr on the given network.
-func Dial(network, addr string) (*Client, os.Error) {
- text, err := textproto.Dial(network, addr)
- if err != nil {
- return nil, err
- }
- _, _, err = text.ReadCodeLine(220)
- if err != nil {
- text.Close()
- return nil, err
- }
- return &Client{text: text}, nil
-}
-
-// Close closes the connection to the dictionary server.
-func (c *Client) Close() os.Error {
- return c.text.Close()
-}
-
-// A Dict represents a dictionary available on the server.
-type Dict struct {
- Name string // short name of dictionary
- Desc string // long description
-}
-
-// Dicts returns a list of the dictionaries available on the server.
-func (c *Client) Dicts() ([]Dict, os.Error) {
- id, err := c.text.Cmd("SHOW DB")
- if err != nil {
- return nil, err
- }
-
- c.text.StartResponse(id)
- defer c.text.EndResponse(id)
-
- _, _, err = c.text.ReadCodeLine(110)
- if err != nil {
- return nil, err
- }
- lines, err := c.text.ReadDotLines()
- if err != nil {
- return nil, err
- }
- _, _, err = c.text.ReadCodeLine(250)
-
- dicts := make([]Dict, len(lines))
- for i := range dicts {
- d := &dicts[i]
- a, _ := fields(lines[i])
- if len(a) < 2 {
- return nil, textproto.ProtocolError("invalid dictionary: " + lines[i])
- }
- d.Name = a[0]
- d.Desc = a[1]
- }
- return dicts, err
-}
-
-// A Defn represents a definition.
-type Defn struct {
- Dict Dict // Dict where definition was found
- Word string // Word being defined
- Text []byte // Definition text, typically multiple lines
-}
-
-// Define requests the definition of the given word.
-// The argument dict names the dictionary to use,
-// the Name field of a Dict returned by Dicts.
-//
-// The special dictionary name "*" means to look in all the
-// server's dictionaries.
-// The special dictionary name "!" means to look in all the
-// server's dictionaries in turn, stopping after finding the word
-// in one of them.
-func (c *Client) Define(dict, word string) ([]*Defn, os.Error) {
- id, err := c.text.Cmd("DEFINE %s %q", dict, word)
- if err != nil {
- return nil, err
- }
-
- c.text.StartResponse(id)
- defer c.text.EndResponse(id)
-
- _, line, err := c.text.ReadCodeLine(150)
- if err != nil {
- return nil, err
- }
- a, _ := fields(line)
- if len(a) < 1 {
- return nil, textproto.ProtocolError("malformed response: " + line)
- }
- n, err := strconv.Atoi(a[0])
- if err != nil {
- return nil, textproto.ProtocolError("invalid definition count: " + a[0])
- }
- def := make([]*Defn, n)
- for i := 0; i < n; i++ {
- _, line, err = c.text.ReadCodeLine(151)
- if err != nil {
- return nil, err
- }
- a, _ := fields(line)
- if len(a) < 3 {
- // skip it, to keep protocol in sync
- i--
- n--
- def = def[0:n]
- continue
- }
- d := &Defn{Word: a[0], Dict: Dict{a[1], a[2]}}
- d.Text, err = c.text.ReadDotBytes()
- if err != nil {
- return nil, err
- }
- def[i] = d
- }
- _, _, err = c.text.ReadCodeLine(250)
- return def, err
-}
-
-// Fields returns the fields in s.
-// Fields are space separated unquoted words
-// or quoted with single or double quote.
-func fields(s string) ([]string, os.Error) {
- var v vector.StringVector
- i := 0
- for {
- for i < len(s) && (s[i] == ' ' || s[i] == '\t') {
- i++
- }
- if i >= len(s) {
- break
- }
- if s[i] == '"' || s[i] == '\'' {
- q := s[i]
- // quoted string
- var j int
- for j = i + 1; ; j++ {
- if j >= len(s) {
- return nil, textproto.ProtocolError("malformed quoted string")
- }
- if s[j] == '\\' {
- j++
- continue
- }
- if s[j] == q {
- j++
- break
- }
- }
- v.Push(unquote(s[i+1 : j-1]))
- i = j
- } else {
- // atom
- var j int
- for j = i; j < len(s); j++ {
- if s[j] == ' ' || s[j] == '\t' || s[j] == '\\' || s[j] == '"' || s[j] == '\'' {
- break
- }
- }
- v.Push(s[i:j])
- i = j
- }
- if i < len(s) {
- c := s[i]
- if c != ' ' && c != '\t' {
- return nil, textproto.ProtocolError("quotes not on word boundaries")
- }
- }
- }
- return v, nil
-}
-
-func unquote(s string) string {
- if strings.Index(s, "\\") < 0 {
- return s
- }
- b := []byte(s)
- w := 0
- for r := 0; r < len(b); r++ {
- c := b[r]
- if c == '\\' {
- r++
- c = b[r]
- }
- b[w] = c
- w++
- }
- return string(b[0:w])
-}
diff --git a/src/pkg/net/dnsclient.go b/src/pkg/net/dnsclient.go
deleted file mode 100644
index 280b19453..000000000
--- a/src/pkg/net/dnsclient.go
+++ /dev/null
@@ -1,224 +0,0 @@
-// 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.
-
-package net
-
-import (
- "bytes"
- "fmt"
- "os"
- "rand"
-)
-
-// DNSError represents a DNS lookup error.
-type DNSError struct {
- Error string // description of the error
- Name string // name looked for
- Server string // server used
- IsTimeout bool
-}
-
-func (e *DNSError) String() string {
- if e == nil {
- return "<nil>"
- }
- s := "lookup " + e.Name
- if e.Server != "" {
- s += " on " + e.Server
- }
- s += ": " + e.Error
- return s
-}
-
-func (e *DNSError) Timeout() bool { return e.IsTimeout }
-func (e *DNSError) Temporary() bool { return e.IsTimeout }
-
-const noSuchHost = "no such host"
-
-// reverseaddr returns the in-addr.arpa. or ip6.arpa. hostname of the IP
-// address addr suitable for rDNS (PTR) record lookup or an error if it fails
-// to parse the IP address.
-func reverseaddr(addr string) (arpa string, err os.Error) {
- ip := ParseIP(addr)
- if ip == nil {
- return "", &DNSError{Error: "unrecognized address", Name: addr}
- }
- if ip.To4() != nil {
- return fmt.Sprintf("%d.%d.%d.%d.in-addr.arpa.", ip[15], ip[14], ip[13], ip[12]), nil
- }
- // Must be IPv6
- var buf bytes.Buffer
- // Add it, in reverse, to the buffer
- for i := len(ip) - 1; i >= 0; i-- {
- s := fmt.Sprintf("%02x", ip[i])
- buf.WriteByte(s[1])
- buf.WriteByte('.')
- buf.WriteByte(s[0])
- buf.WriteByte('.')
- }
- // Append "ip6.arpa." and return (buf already has the final .)
- return buf.String() + "ip6.arpa.", nil
-}
-
-// Find answer for name in dns message.
-// On return, if err == nil, addrs != nil.
-func answer(name, server string, dns *dnsMsg, qtype uint16) (cname string, addrs []dnsRR, err os.Error) {
- addrs = make([]dnsRR, 0, len(dns.answer))
-
- if dns.rcode == dnsRcodeNameError && dns.recursion_available {
- return "", nil, &DNSError{Error: noSuchHost, Name: name}
- }
- if dns.rcode != dnsRcodeSuccess {
- // None of the error codes make sense
- // for the query we sent. If we didn't get
- // a name error and we didn't get success,
- // the server is behaving incorrectly.
- return "", nil, &DNSError{Error: "server misbehaving", Name: name, Server: server}
- }
-
- // Look for the name.
- // Presotto says it's okay to assume that servers listed in
- // /etc/resolv.conf are recursive resolvers.
- // We asked for recursion, so it should have included
- // all the answers we need in this one packet.
-Cname:
- for cnameloop := 0; cnameloop < 10; cnameloop++ {
- addrs = addrs[0:0]
- for _, rr := range dns.answer {
- if _, justHeader := rr.(*dnsRR_Header); justHeader {
- // Corrupt record: we only have a
- // header. That header might say it's
- // of type qtype, but we don't
- // actually have it. Skip.
- continue
- }
- h := rr.Header()
- if h.Class == dnsClassINET && h.Name == name {
- switch h.Rrtype {
- case qtype:
- addrs = append(addrs, rr)
- case dnsTypeCNAME:
- // redirect to cname
- name = rr.(*dnsRR_CNAME).Cname
- continue Cname
- }
- }
- }
- if len(addrs) == 0 {
- return "", nil, &DNSError{Error: noSuchHost, Name: name, Server: server}
- }
- return name, addrs, nil
- }
-
- return "", nil, &DNSError{Error: "too many redirects", Name: name, Server: server}
-}
-
-func isDomainName(s string) bool {
- // See RFC 1035, RFC 3696.
- if len(s) == 0 {
- return false
- }
- if len(s) > 255 {
- return false
- }
- if s[len(s)-1] != '.' { // simplify checking loop: make name end in dot
- s += "."
- }
-
- last := byte('.')
- ok := false // ok once we've seen a letter
- partlen := 0
- for i := 0; i < len(s); i++ {
- c := s[i]
- switch {
- default:
- return false
- case 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || c == '_':
- ok = true
- partlen++
- case '0' <= c && c <= '9':
- // fine
- partlen++
- case c == '-':
- // byte before dash cannot be dot
- if last == '.' {
- return false
- }
- partlen++
- case c == '.':
- // byte before dot cannot be dot, dash
- if last == '.' || last == '-' {
- return false
- }
- if partlen > 63 || partlen == 0 {
- return false
- }
- partlen = 0
- }
- last = c
- }
-
- return ok
-}
-
-// An SRV represents a single DNS SRV record.
-type SRV struct {
- Target string
- Port uint16
- Priority uint16
- Weight uint16
-}
-
-// byPriorityWeight sorts SRV records by ascending priority and weight.
-type byPriorityWeight []*SRV
-
-func (s byPriorityWeight) Len() int { return len(s) }
-
-func (s byPriorityWeight) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
-
-func (s byPriorityWeight) Less(i, j int) bool {
- return s[i].Priority < s[j].Priority ||
- (s[i].Priority == s[j].Priority && s[i].Weight < s[j].Weight)
-}
-
-// shuffleSRVByWeight shuffles SRV records by weight using the algorithm
-// described in RFC 2782.
-func shuffleSRVByWeight(addrs []*SRV) {
- sum := 0
- for _, addr := range addrs {
- sum += int(addr.Weight)
- }
- for sum > 0 && len(addrs) > 1 {
- s := 0
- n := rand.Intn(sum + 1)
- for i := range addrs {
- s += int(addrs[i].Weight)
- if s >= n {
- if i > 0 {
- t := addrs[i]
- copy(addrs[1:i+1], addrs[0:i])
- addrs[0] = t
- }
- break
- }
- }
- sum -= int(addrs[0].Weight)
- addrs = addrs[1:]
- }
-}
-
-// An MX represents a single DNS MX record.
-type MX struct {
- Host string
- Pref uint16
-}
-
-// byPref implements sort.Interface to sort MX records by preference
-type byPref []*MX
-
-func (s byPref) Len() int { return len(s) }
-
-func (s byPref) Less(i, j int) bool { return s[i].Pref < s[j].Pref }
-
-func (s byPref) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
diff --git a/src/pkg/net/dnsclient_unix.go b/src/pkg/net/dnsclient_unix.go
deleted file mode 100644
index 7f3ef2878..000000000
--- a/src/pkg/net/dnsclient_unix.go
+++ /dev/null
@@ -1,262 +0,0 @@
-// 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.
-
-// DNS client: see RFC 1035.
-// Has to be linked into package net for Dial.
-
-// TODO(rsc):
-// Check periodically whether /etc/resolv.conf has changed.
-// Could potentially handle many outstanding lookups faster.
-// Could have a small cache.
-// Random UDP source port (net.Dial should do that for us).
-// Random request IDs.
-
-package net
-
-import (
- "os"
- "rand"
- "sync"
- "time"
-)
-
-// Send a request on the connection and hope for a reply.
-// Up to cfg.attempts attempts.
-func exchange(cfg *dnsConfig, c Conn, name string, qtype uint16) (*dnsMsg, os.Error) {
- if len(name) >= 256 {
- return nil, &DNSError{Error: "name too long", Name: name}
- }
- out := new(dnsMsg)
- out.id = uint16(rand.Int()) ^ uint16(time.Nanoseconds())
- out.question = []dnsQuestion{
- {name, qtype, dnsClassINET},
- }
- out.recursion_desired = true
- msg, ok := out.Pack()
- if !ok {
- return nil, &DNSError{Error: "internal error - cannot pack message", Name: name}
- }
-
- for attempt := 0; attempt < cfg.attempts; attempt++ {
- n, err := c.Write(msg)
- if err != nil {
- return nil, err
- }
-
- c.SetReadTimeout(int64(cfg.timeout) * 1e9) // nanoseconds
-
- buf := make([]byte, 2000) // More than enough.
- n, err = c.Read(buf)
- if err != nil {
- if e, ok := err.(Error); ok && e.Timeout() {
- continue
- }
- return nil, err
- }
- buf = buf[0:n]
- in := new(dnsMsg)
- if !in.Unpack(buf) || in.id != out.id {
- continue
- }
- return in, nil
- }
- var server string
- if a := c.RemoteAddr(); a != nil {
- server = a.String()
- }
- return nil, &DNSError{Error: "no answer from server", Name: name, Server: server, IsTimeout: true}
-}
-
-
-// Do a lookup for a single name, which must be rooted
-// (otherwise answer will not find the answers).
-func tryOneName(cfg *dnsConfig, name string, qtype uint16) (cname string, addrs []dnsRR, err os.Error) {
- if len(cfg.servers) == 0 {
- return "", nil, &DNSError{Error: "no DNS servers", Name: name}
- }
- for i := 0; i < len(cfg.servers); i++ {
- // Calling Dial here is scary -- we have to be sure
- // not to dial a name that will require a DNS lookup,
- // or Dial will call back here to translate it.
- // The DNS config parser has already checked that
- // all the cfg.servers[i] are IP addresses, which
- // Dial will use without a DNS lookup.
- server := cfg.servers[i] + ":53"
- c, cerr := Dial("udp", server)
- if cerr != nil {
- err = cerr
- continue
- }
- msg, merr := exchange(cfg, c, name, qtype)
- c.Close()
- if merr != nil {
- err = merr
- continue
- }
- cname, addrs, err = answer(name, server, msg, qtype)
- if err == nil || err.(*DNSError).Error == noSuchHost {
- break
- }
- }
- return
-}
-
-func convertRR_A(records []dnsRR) []IP {
- addrs := make([]IP, len(records))
- for i, rr := range records {
- a := rr.(*dnsRR_A).A
- addrs[i] = IPv4(byte(a>>24), byte(a>>16), byte(a>>8), byte(a))
- }
- return addrs
-}
-
-func convertRR_AAAA(records []dnsRR) []IP {
- addrs := make([]IP, len(records))
- for i, rr := range records {
- a := make(IP, 16)
- copy(a, rr.(*dnsRR_AAAA).AAAA[:])
- addrs[i] = a
- }
- return addrs
-}
-
-var cfg *dnsConfig
-var dnserr os.Error
-
-func loadConfig() { cfg, dnserr = dnsReadConfig() }
-
-var onceLoadConfig sync.Once
-
-func lookup(name string, qtype uint16) (cname string, addrs []dnsRR, err os.Error) {
- if !isDomainName(name) {
- return name, nil, &DNSError{Error: "invalid domain name", Name: name}
- }
- onceLoadConfig.Do(loadConfig)
- if dnserr != nil || cfg == nil {
- err = dnserr
- return
- }
- // If name is rooted (trailing dot) or has enough dots,
- // try it by itself first.
- rooted := len(name) > 0 && name[len(name)-1] == '.'
- if rooted || count(name, '.') >= cfg.ndots {
- rname := name
- if !rooted {
- rname += "."
- }
- // Can try as ordinary name.
- cname, addrs, err = tryOneName(cfg, rname, qtype)
- if err == nil {
- return
- }
- }
- if rooted {
- return
- }
-
- // Otherwise, try suffixes.
- for i := 0; i < len(cfg.search); i++ {
- rname := name + "." + cfg.search[i]
- if rname[len(rname)-1] != '.' {
- rname += "."
- }
- cname, addrs, err = tryOneName(cfg, rname, qtype)
- if err == nil {
- return
- }
- }
-
- // Last ditch effort: try unsuffixed.
- rname := name
- if !rooted {
- rname += "."
- }
- cname, addrs, err = tryOneName(cfg, rname, qtype)
- if err == nil {
- return
- }
- return
-}
-
-// goLookupHost is the native Go implementation of LookupHost.
-// Used only if cgoLookupHost refuses to handle the request
-// (that is, only if cgoLookupHost is the stub in cgo_stub.go).
-// Normally we let cgo use the C library resolver instead of
-// depending on our lookup code, so that Go and C get the same
-// answers.
-func goLookupHost(name string) (addrs []string, err os.Error) {
- // Use entries from /etc/hosts if they match.
- addrs = lookupStaticHost(name)
- if len(addrs) > 0 {
- return
- }
- onceLoadConfig.Do(loadConfig)
- if dnserr != nil || cfg == nil {
- err = dnserr
- return
- }
- ips, err := goLookupIP(name)
- if err != nil {
- return
- }
- addrs = make([]string, 0, len(ips))
- for _, ip := range ips {
- addrs = append(addrs, ip.String())
- }
- return
-}
-
-// goLookupIP is the native Go implementation of LookupIP.
-// Used only if cgoLookupIP refuses to handle the request
-// (that is, only if cgoLookupIP is the stub in cgo_stub.go).
-// Normally we let cgo use the C library resolver instead of
-// depending on our lookup code, so that Go and C get the same
-// answers.
-func goLookupIP(name string) (addrs []IP, err os.Error) {
- onceLoadConfig.Do(loadConfig)
- if dnserr != nil || cfg == nil {
- err = dnserr
- return
- }
- var records []dnsRR
- var cname string
- cname, records, err = lookup(name, dnsTypeA)
- if err != nil {
- return
- }
- addrs = convertRR_A(records)
- if cname != "" {
- name = cname
- }
- _, records, err = lookup(name, dnsTypeAAAA)
- if err != nil && len(addrs) > 0 {
- // Ignore error because A lookup succeeded.
- err = nil
- }
- if err != nil {
- return
- }
- addrs = append(addrs, convertRR_AAAA(records)...)
- return
-}
-
-// goLookupCNAME is the native Go implementation of LookupCNAME.
-// Used only if cgoLookupCNAME refuses to handle the request
-// (that is, only if cgoLookupCNAME is the stub in cgo_stub.go).
-// Normally we let cgo use the C library resolver instead of
-// depending on our lookup code, so that Go and C get the same
-// answers.
-func goLookupCNAME(name string) (cname string, err os.Error) {
- onceLoadConfig.Do(loadConfig)
- if dnserr != nil || cfg == nil {
- err = dnserr
- return
- }
- _, rr, err := lookup(name, dnsTypeCNAME)
- if err != nil {
- return
- }
- cname = rr[0].(*dnsRR_CNAME).Cname
- return
-}
diff --git a/src/pkg/net/dnsconfig.go b/src/pkg/net/dnsconfig.go
deleted file mode 100644
index 54e334342..000000000
--- a/src/pkg/net/dnsconfig.go
+++ /dev/null
@@ -1,119 +0,0 @@
-// 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.
-
-// Read system DNS config from /etc/resolv.conf
-
-package net
-
-import "os"
-
-type dnsConfig struct {
- servers []string // servers to use
- search []string // suffixes to append to local name
- ndots int // number of dots in name to trigger absolute lookup
- timeout int // seconds before giving up on packet
- attempts int // lost packets before giving up on server
- rotate bool // round robin among servers
-}
-
-var dnsconfigError os.Error
-
-type DNSConfigError struct {
- Error os.Error
-}
-
-func (e *DNSConfigError) String() string {
- return "error reading DNS config: " + e.Error.String()
-}
-
-func (e *DNSConfigError) Timeout() bool { return false }
-func (e *DNSConfigError) Temporary() bool { return false }
-
-// See resolv.conf(5) on a Linux machine.
-// TODO(rsc): Supposed to call uname() and chop the beginning
-// of the host name to get the default search domain.
-// We assume it's in resolv.conf anyway.
-func dnsReadConfig() (*dnsConfig, os.Error) {
- file, err := open("/etc/resolv.conf")
- if err != nil {
- return nil, &DNSConfigError{err}
- }
- conf := new(dnsConfig)
- conf.servers = make([]string, 3)[0:0] // small, but the standard limit
- conf.search = make([]string, 0)
- conf.ndots = 1
- conf.timeout = 5
- conf.attempts = 2
- conf.rotate = false
- for line, ok := file.readLine(); ok; line, ok = file.readLine() {
- f := getFields(line)
- if len(f) < 1 {
- continue
- }
- switch f[0] {
- case "nameserver": // add one name server
- a := conf.servers
- n := len(a)
- if len(f) > 1 && n < cap(a) {
- // One more check: make sure server name is
- // just an IP address. Otherwise we need DNS
- // to look it up.
- name := f[1]
- switch len(ParseIP(name)) {
- case 16:
- name = "[" + name + "]"
- fallthrough
- case 4:
- a = a[0 : n+1]
- a[n] = name
- conf.servers = a
- }
- }
-
- case "domain": // set search path to just this domain
- if len(f) > 1 {
- conf.search = make([]string, 1)
- conf.search[0] = f[1]
- } else {
- conf.search = make([]string, 0)
- }
-
- case "search": // set search path to given servers
- conf.search = make([]string, len(f)-1)
- for i := 0; i < len(conf.search); i++ {
- conf.search[i] = f[i+1]
- }
-
- case "options": // magic options
- for i := 1; i < len(f); i++ {
- s := f[i]
- switch {
- case len(s) >= 6 && s[0:6] == "ndots:":
- n, _, _ := dtoi(s, 6)
- if n < 1 {
- n = 1
- }
- conf.ndots = n
- case len(s) >= 8 && s[0:8] == "timeout:":
- n, _, _ := dtoi(s, 8)
- if n < 1 {
- n = 1
- }
- conf.timeout = n
- case len(s) >= 8 && s[0:9] == "attempts:":
- n, _, _ := dtoi(s, 9)
- if n < 1 {
- n = 1
- }
- conf.attempts = n
- case s == "rotate":
- conf.rotate = true
- }
- }
- }
- }
- file.close()
-
- return conf, nil
-}
diff --git a/src/pkg/net/dnsmsg.go b/src/pkg/net/dnsmsg.go
deleted file mode 100644
index 640973b13..000000000
--- a/src/pkg/net/dnsmsg.go
+++ /dev/null
@@ -1,780 +0,0 @@
-// 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.
-
-// DNS packet assembly. See RFC 1035.
-//
-// This is intended to support name resolution during net.Dial.
-// It doesn't have to be blazing fast.
-//
-// Rather than write the usual handful of routines to pack and
-// unpack every message that can appear on the wire, we use
-// reflection to write a generic pack/unpack for structs and then
-// use it. Thus, if in the future we need to define new message
-// structs, no new pack/unpack/printing code needs to be written.
-//
-// The first half of this file defines the DNS message formats.
-// The second half implements the conversion to and from wire format.
-// A few of the structure elements have string tags to aid the
-// generic pack/unpack routines.
-//
-// TODO(rsc): There are enough names defined in this file that they're all
-// prefixed with dns. Perhaps put this in its own package later.
-
-package net
-
-import (
- "fmt"
- "os"
- "reflect"
-)
-
-// Packet formats
-
-// Wire constants.
-const (
- // valid dnsRR_Header.Rrtype and dnsQuestion.qtype
- dnsTypeA = 1
- dnsTypeNS = 2
- dnsTypeMD = 3
- dnsTypeMF = 4
- dnsTypeCNAME = 5
- dnsTypeSOA = 6
- dnsTypeMB = 7
- dnsTypeMG = 8
- dnsTypeMR = 9
- dnsTypeNULL = 10
- dnsTypeWKS = 11
- dnsTypePTR = 12
- dnsTypeHINFO = 13
- dnsTypeMINFO = 14
- dnsTypeMX = 15
- dnsTypeTXT = 16
- dnsTypeAAAA = 28
- dnsTypeSRV = 33
-
- // valid dnsQuestion.qtype only
- dnsTypeAXFR = 252
- dnsTypeMAILB = 253
- dnsTypeMAILA = 254
- dnsTypeALL = 255
-
- // valid dnsQuestion.qclass
- dnsClassINET = 1
- dnsClassCSNET = 2
- dnsClassCHAOS = 3
- dnsClassHESIOD = 4
- dnsClassANY = 255
-
- // dnsMsg.rcode
- dnsRcodeSuccess = 0
- dnsRcodeFormatError = 1
- dnsRcodeServerFailure = 2
- dnsRcodeNameError = 3
- dnsRcodeNotImplemented = 4
- dnsRcodeRefused = 5
-)
-
-// The wire format for the DNS packet header.
-type dnsHeader struct {
- Id uint16
- Bits uint16
- Qdcount, Ancount, Nscount, Arcount uint16
-}
-
-const (
- // dnsHeader.Bits
- _QR = 1 << 15 // query/response (response=1)
- _AA = 1 << 10 // authoritative
- _TC = 1 << 9 // truncated
- _RD = 1 << 8 // recursion desired
- _RA = 1 << 7 // recursion available
-)
-
-// DNS queries.
-type dnsQuestion struct {
- Name string `net:"domain-name"` // `net:"domain-name"` specifies encoding; see packers below
- Qtype uint16
- Qclass uint16
-}
-
-// DNS responses (resource records).
-// There are many types of messages,
-// but they all share the same header.
-type dnsRR_Header struct {
- Name string `net:"domain-name"`
- Rrtype uint16
- Class uint16
- Ttl uint32
- Rdlength uint16 // length of data after header
-}
-
-func (h *dnsRR_Header) Header() *dnsRR_Header {
- return h
-}
-
-type dnsRR interface {
- Header() *dnsRR_Header
-}
-
-// Specific DNS RR formats for each query type.
-
-type dnsRR_CNAME struct {
- Hdr dnsRR_Header
- Cname string `net:"domain-name"`
-}
-
-func (rr *dnsRR_CNAME) Header() *dnsRR_Header {
- return &rr.Hdr
-}
-
-type dnsRR_HINFO struct {
- Hdr dnsRR_Header
- Cpu string
- Os string
-}
-
-func (rr *dnsRR_HINFO) Header() *dnsRR_Header {
- return &rr.Hdr
-}
-
-type dnsRR_MB struct {
- Hdr dnsRR_Header
- Mb string `net:"domain-name"`
-}
-
-func (rr *dnsRR_MB) Header() *dnsRR_Header {
- return &rr.Hdr
-}
-
-type dnsRR_MG struct {
- Hdr dnsRR_Header
- Mg string `net:"domain-name"`
-}
-
-func (rr *dnsRR_MG) Header() *dnsRR_Header {
- return &rr.Hdr
-}
-
-type dnsRR_MINFO struct {
- Hdr dnsRR_Header
- Rmail string `net:"domain-name"`
- Email string `net:"domain-name"`
-}
-
-func (rr *dnsRR_MINFO) Header() *dnsRR_Header {
- return &rr.Hdr
-}
-
-type dnsRR_MR struct {
- Hdr dnsRR_Header
- Mr string `net:"domain-name"`
-}
-
-func (rr *dnsRR_MR) Header() *dnsRR_Header {
- return &rr.Hdr
-}
-
-type dnsRR_MX struct {
- Hdr dnsRR_Header
- Pref uint16
- Mx string `net:"domain-name"`
-}
-
-func (rr *dnsRR_MX) Header() *dnsRR_Header {
- return &rr.Hdr
-}
-
-type dnsRR_NS struct {
- Hdr dnsRR_Header
- Ns string `net:"domain-name"`
-}
-
-func (rr *dnsRR_NS) Header() *dnsRR_Header {
- return &rr.Hdr
-}
-
-type dnsRR_PTR struct {
- Hdr dnsRR_Header
- Ptr string `net:"domain-name"`
-}
-
-func (rr *dnsRR_PTR) Header() *dnsRR_Header {
- return &rr.Hdr
-}
-
-type dnsRR_SOA struct {
- Hdr dnsRR_Header
- Ns string `net:"domain-name"`
- Mbox string `net:"domain-name"`
- Serial uint32
- Refresh uint32
- Retry uint32
- Expire uint32
- Minttl uint32
-}
-
-func (rr *dnsRR_SOA) Header() *dnsRR_Header {
- return &rr.Hdr
-}
-
-type dnsRR_TXT struct {
- Hdr dnsRR_Header
- Txt string // not domain name
-}
-
-func (rr *dnsRR_TXT) Header() *dnsRR_Header {
- return &rr.Hdr
-}
-
-type dnsRR_SRV struct {
- Hdr dnsRR_Header
- Priority uint16
- Weight uint16
- Port uint16
- Target string `net:"domain-name"`
-}
-
-func (rr *dnsRR_SRV) Header() *dnsRR_Header {
- return &rr.Hdr
-}
-
-type dnsRR_A struct {
- Hdr dnsRR_Header
- A uint32 `net:"ipv4"`
-}
-
-func (rr *dnsRR_A) Header() *dnsRR_Header {
- return &rr.Hdr
-}
-
-type dnsRR_AAAA struct {
- Hdr dnsRR_Header
- AAAA [16]byte `net:"ipv6"`
-}
-
-func (rr *dnsRR_AAAA) Header() *dnsRR_Header {
- return &rr.Hdr
-}
-
-// Packing and unpacking.
-//
-// All the packers and unpackers take a (msg []byte, off int)
-// and return (off1 int, ok bool). If they return ok==false, they
-// also return off1==len(msg), so that the next unpacker will
-// also fail. This lets us avoid checks of ok until the end of a
-// packing sequence.
-
-// Map of constructors for each RR wire type.
-var rr_mk = map[int]func() dnsRR{
- dnsTypeCNAME: func() dnsRR { return new(dnsRR_CNAME) },
- dnsTypeHINFO: func() dnsRR { return new(dnsRR_HINFO) },
- dnsTypeMB: func() dnsRR { return new(dnsRR_MB) },
- dnsTypeMG: func() dnsRR { return new(dnsRR_MG) },
- dnsTypeMINFO: func() dnsRR { return new(dnsRR_MINFO) },
- dnsTypeMR: func() dnsRR { return new(dnsRR_MR) },
- dnsTypeMX: func() dnsRR { return new(dnsRR_MX) },
- dnsTypeNS: func() dnsRR { return new(dnsRR_NS) },
- dnsTypePTR: func() dnsRR { return new(dnsRR_PTR) },
- dnsTypeSOA: func() dnsRR { return new(dnsRR_SOA) },
- dnsTypeTXT: func() dnsRR { return new(dnsRR_TXT) },
- dnsTypeSRV: func() dnsRR { return new(dnsRR_SRV) },
- dnsTypeA: func() dnsRR { return new(dnsRR_A) },
- dnsTypeAAAA: func() dnsRR { return new(dnsRR_AAAA) },
-}
-
-// Pack a domain name s into msg[off:].
-// Domain names are a sequence of counted strings
-// split at the dots. They end with a zero-length string.
-func packDomainName(s string, msg []byte, off int) (off1 int, ok bool) {
- // Add trailing dot to canonicalize name.
- if n := len(s); n == 0 || s[n-1] != '.' {
- s += "."
- }
-
- // Each dot ends a segment of the name.
- // We trade each dot byte for a length byte.
- // There is also a trailing zero.
- // Check that we have all the space we need.
- tot := len(s) + 1
- if off+tot > len(msg) {
- return len(msg), false
- }
-
- // Emit sequence of counted strings, chopping at dots.
- begin := 0
- for i := 0; i < len(s); i++ {
- if s[i] == '.' {
- if i-begin >= 1<<6 { // top two bits of length must be clear
- return len(msg), false
- }
- msg[off] = byte(i - begin)
- off++
- for j := begin; j < i; j++ {
- msg[off] = s[j]
- off++
- }
- begin = i + 1
- }
- }
- msg[off] = 0
- off++
- return off, true
-}
-
-// Unpack a domain name.
-// In addition to the simple sequences of counted strings above,
-// domain names are allowed to refer to strings elsewhere in the
-// packet, to avoid repeating common suffixes when returning
-// many entries in a single domain. The pointers are marked
-// by a length byte with the top two bits set. Ignoring those
-// two bits, that byte and the next give a 14 bit offset from msg[0]
-// where we should pick up the trail.
-// Note that if we jump elsewhere in the packet,
-// we return off1 == the offset after the first pointer we found,
-// which is where the next record will start.
-// In theory, the pointers are only allowed to jump backward.
-// We let them jump anywhere and stop jumping after a while.
-func unpackDomainName(msg []byte, off int) (s string, off1 int, ok bool) {
- s = ""
- ptr := 0 // number of pointers followed
-Loop:
- for {
- if off >= len(msg) {
- return "", len(msg), false
- }
- c := int(msg[off])
- off++
- switch c & 0xC0 {
- case 0x00:
- if c == 0x00 {
- // end of name
- break Loop
- }
- // literal string
- if off+c > len(msg) {
- return "", len(msg), false
- }
- s += string(msg[off:off+c]) + "."
- off += c
- case 0xC0:
- // pointer to somewhere else in msg.
- // remember location after first ptr,
- // since that's how many bytes we consumed.
- // also, don't follow too many pointers --
- // maybe there's a loop.
- if off >= len(msg) {
- return "", len(msg), false
- }
- c1 := msg[off]
- off++
- if ptr == 0 {
- off1 = off
- }
- if ptr++; ptr > 10 {
- return "", len(msg), false
- }
- off = (c^0xC0)<<8 | int(c1)
- default:
- // 0x80 and 0x40 are reserved
- return "", len(msg), false
- }
- }
- if ptr == 0 {
- off1 = off
- }
- return s, off1, true
-}
-
-// TODO(rsc): Move into generic library?
-// Pack a reflect.StructValue into msg. Struct members can only be uint16, uint32, string,
-// [n]byte, and other (often anonymous) structs.
-func packStructValue(val reflect.Value, msg []byte, off int) (off1 int, ok bool) {
- for i := 0; i < val.NumField(); i++ {
- f := val.Type().Field(i)
- switch fv := val.Field(i); fv.Kind() {
- default:
- fmt.Fprintf(os.Stderr, "net: dns: unknown packing type %v", f.Type)
- return len(msg), false
- case reflect.Struct:
- off, ok = packStructValue(fv, msg, off)
- case reflect.Uint16:
- if off+2 > len(msg) {
- return len(msg), false
- }
- i := fv.Uint()
- msg[off] = byte(i >> 8)
- msg[off+1] = byte(i)
- off += 2
- case reflect.Uint32:
- if off+4 > len(msg) {
- return len(msg), false
- }
- i := fv.Uint()
- msg[off] = byte(i >> 24)
- msg[off+1] = byte(i >> 16)
- msg[off+2] = byte(i >> 8)
- msg[off+3] = byte(i)
- off += 4
- case reflect.Array:
- if fv.Type().Elem().Kind() != reflect.Uint8 {
- fmt.Fprintf(os.Stderr, "net: dns: unknown packing type %v", f.Type)
- return len(msg), false
- }
- n := fv.Len()
- if off+n > len(msg) {
- return len(msg), false
- }
- reflect.Copy(reflect.ValueOf(msg[off:off+n]), fv)
- off += n
- case reflect.String:
- // There are multiple string encodings.
- // The tag distinguishes ordinary strings from domain names.
- s := fv.String()
- switch f.Tag {
- default:
- fmt.Fprintf(os.Stderr, "net: dns: unknown string tag %v", f.Tag)
- return len(msg), false
- case `net:"domain-name"`:
- off, ok = packDomainName(s, msg, off)
- if !ok {
- return len(msg), false
- }
- case "":
- // Counted string: 1 byte length.
- if len(s) > 255 || off+1+len(s) > len(msg) {
- return len(msg), false
- }
- msg[off] = byte(len(s))
- off++
- off += copy(msg[off:], s)
- }
- }
- }
- return off, true
-}
-
-func structValue(any interface{}) reflect.Value {
- return reflect.ValueOf(any).Elem()
-}
-
-func packStruct(any interface{}, msg []byte, off int) (off1 int, ok bool) {
- off, ok = packStructValue(structValue(any), msg, off)
- return off, ok
-}
-
-// TODO(rsc): Move into generic library?
-// Unpack a reflect.StructValue from msg.
-// Same restrictions as packStructValue.
-func unpackStructValue(val reflect.Value, msg []byte, off int) (off1 int, ok bool) {
- for i := 0; i < val.NumField(); i++ {
- f := val.Type().Field(i)
- switch fv := val.Field(i); fv.Kind() {
- default:
- fmt.Fprintf(os.Stderr, "net: dns: unknown packing type %v", f.Type)
- return len(msg), false
- case reflect.Struct:
- off, ok = unpackStructValue(fv, msg, off)
- case reflect.Uint16:
- if off+2 > len(msg) {
- return len(msg), false
- }
- i := uint16(msg[off])<<8 | uint16(msg[off+1])
- fv.SetUint(uint64(i))
- off += 2
- case reflect.Uint32:
- if off+4 > len(msg) {
- return len(msg), false
- }
- i := uint32(msg[off])<<24 | uint32(msg[off+1])<<16 | uint32(msg[off+2])<<8 | uint32(msg[off+3])
- fv.SetUint(uint64(i))
- off += 4
- case reflect.Array:
- if fv.Type().Elem().Kind() != reflect.Uint8 {
- fmt.Fprintf(os.Stderr, "net: dns: unknown packing type %v", f.Type)
- return len(msg), false
- }
- n := fv.Len()
- if off+n > len(msg) {
- return len(msg), false
- }
- reflect.Copy(fv, reflect.ValueOf(msg[off:off+n]))
- off += n
- case reflect.String:
- var s string
- switch f.Tag {
- default:
- fmt.Fprintf(os.Stderr, "net: dns: unknown string tag %v", f.Tag)
- return len(msg), false
- case `net:"domain-name"`:
- s, off, ok = unpackDomainName(msg, off)
- if !ok {
- return len(msg), false
- }
- case "":
- if off >= len(msg) || off+1+int(msg[off]) > len(msg) {
- return len(msg), false
- }
- n := int(msg[off])
- off++
- b := make([]byte, n)
- for i := 0; i < n; i++ {
- b[i] = msg[off+i]
- }
- off += n
- s = string(b)
- }
- fv.SetString(s)
- }
- }
- return off, true
-}
-
-func unpackStruct(any interface{}, msg []byte, off int) (off1 int, ok bool) {
- off, ok = unpackStructValue(structValue(any), msg, off)
- return off, ok
-}
-
-// Generic struct printer.
-// Doesn't care about the string tag `net:"domain-name"`,
-// but does look for an `net:"ipv4"` tag on uint32 variables
-// and the `net:"ipv6"` tag on array variables,
-// printing them as IP addresses.
-func printStructValue(val reflect.Value) string {
- s := "{"
- for i := 0; i < val.NumField(); i++ {
- if i > 0 {
- s += ", "
- }
- f := val.Type().Field(i)
- if !f.Anonymous {
- s += f.Name + "="
- }
- fval := val.Field(i)
- if fv := fval; fv.Kind() == reflect.Struct {
- s += printStructValue(fv)
- } else if fv := fval; (fv.Kind() == reflect.Uint || fv.Kind() == reflect.Uint8 || fv.Kind() == reflect.Uint16 || fv.Kind() == reflect.Uint32 || fv.Kind() == reflect.Uint64 || fv.Kind() == reflect.Uintptr) && f.Tag == `net:"ipv4"` {
- i := fv.Uint()
- s += IPv4(byte(i>>24), byte(i>>16), byte(i>>8), byte(i)).String()
- } else if fv := fval; fv.Kind() == reflect.Array && f.Tag == `net:"ipv6"` {
- i := fv.Interface().([]byte)
- s += IP(i).String()
- } else {
- s += fmt.Sprint(fval.Interface())
- }
- }
- s += "}"
- return s
-}
-
-func printStruct(any interface{}) string { return printStructValue(structValue(any)) }
-
-// Resource record packer.
-func packRR(rr dnsRR, msg []byte, off int) (off2 int, ok bool) {
- var off1 int
- // pack twice, once to find end of header
- // and again to find end of packet.
- // a bit inefficient but this doesn't need to be fast.
- // off1 is end of header
- // off2 is end of rr
- off1, ok = packStruct(rr.Header(), msg, off)
- off2, ok = packStruct(rr, msg, off)
- if !ok {
- return len(msg), false
- }
- // pack a third time; redo header with correct data length
- rr.Header().Rdlength = uint16(off2 - off1)
- packStruct(rr.Header(), msg, off)
- return off2, true
-}
-
-// Resource record unpacker.
-func unpackRR(msg []byte, off int) (rr dnsRR, off1 int, ok bool) {
- // unpack just the header, to find the rr type and length
- var h dnsRR_Header
- off0 := off
- if off, ok = unpackStruct(&h, msg, off); !ok {
- return nil, len(msg), false
- }
- end := off + int(h.Rdlength)
-
- // make an rr of that type and re-unpack.
- // again inefficient but doesn't need to be fast.
- mk, known := rr_mk[int(h.Rrtype)]
- if !known {
- return &h, end, true
- }
- rr = mk()
- off, ok = unpackStruct(rr, msg, off0)
- if off != end {
- return &h, end, true
- }
- return rr, off, ok
-}
-
-// Usable representation of a DNS packet.
-
-// A manually-unpacked version of (id, bits).
-// This is in its own struct for easy printing.
-type dnsMsgHdr struct {
- id uint16
- response bool
- opcode int
- authoritative bool
- truncated bool
- recursion_desired bool
- recursion_available bool
- rcode int
-}
-
-type dnsMsg struct {
- dnsMsgHdr
- question []dnsQuestion
- answer []dnsRR
- ns []dnsRR
- extra []dnsRR
-}
-
-
-func (dns *dnsMsg) Pack() (msg []byte, ok bool) {
- var dh dnsHeader
-
- // Convert convenient dnsMsg into wire-like dnsHeader.
- dh.Id = dns.id
- dh.Bits = uint16(dns.opcode)<<11 | uint16(dns.rcode)
- if dns.recursion_available {
- dh.Bits |= _RA
- }
- if dns.recursion_desired {
- dh.Bits |= _RD
- }
- if dns.truncated {
- dh.Bits |= _TC
- }
- if dns.authoritative {
- dh.Bits |= _AA
- }
- if dns.response {
- dh.Bits |= _QR
- }
-
- // Prepare variable sized arrays.
- question := dns.question
- answer := dns.answer
- ns := dns.ns
- extra := dns.extra
-
- dh.Qdcount = uint16(len(question))
- dh.Ancount = uint16(len(answer))
- dh.Nscount = uint16(len(ns))
- dh.Arcount = uint16(len(extra))
-
- // Could work harder to calculate message size,
- // but this is far more than we need and not
- // big enough to hurt the allocator.
- msg = make([]byte, 2000)
-
- // Pack it in: header and then the pieces.
- off := 0
- off, ok = packStruct(&dh, msg, off)
- for i := 0; i < len(question); i++ {
- off, ok = packStruct(&question[i], msg, off)
- }
- for i := 0; i < len(answer); i++ {
- off, ok = packRR(answer[i], msg, off)
- }
- for i := 0; i < len(ns); i++ {
- off, ok = packRR(ns[i], msg, off)
- }
- for i := 0; i < len(extra); i++ {
- off, ok = packRR(extra[i], msg, off)
- }
- if !ok {
- return nil, false
- }
- return msg[0:off], true
-}
-
-func (dns *dnsMsg) Unpack(msg []byte) bool {
- // Header.
- var dh dnsHeader
- off := 0
- var ok bool
- if off, ok = unpackStruct(&dh, msg, off); !ok {
- return false
- }
- dns.id = dh.Id
- dns.response = (dh.Bits & _QR) != 0
- dns.opcode = int(dh.Bits>>11) & 0xF
- dns.authoritative = (dh.Bits & _AA) != 0
- dns.truncated = (dh.Bits & _TC) != 0
- dns.recursion_desired = (dh.Bits & _RD) != 0
- dns.recursion_available = (dh.Bits & _RA) != 0
- dns.rcode = int(dh.Bits & 0xF)
-
- // Arrays.
- dns.question = make([]dnsQuestion, dh.Qdcount)
- dns.answer = make([]dnsRR, 0, dh.Ancount)
- dns.ns = make([]dnsRR, 0, dh.Nscount)
- dns.extra = make([]dnsRR, 0, dh.Arcount)
-
- var rec dnsRR
-
- for i := 0; i < len(dns.question); i++ {
- off, ok = unpackStruct(&dns.question[i], msg, off)
- }
- for i := 0; i < int(dh.Ancount); i++ {
- rec, off, ok = unpackRR(msg, off)
- if !ok {
- return false
- }
- dns.answer = append(dns.answer, rec)
- }
- for i := 0; i < int(dh.Nscount); i++ {
- rec, off, ok = unpackRR(msg, off)
- if !ok {
- return false
- }
- dns.ns = append(dns.ns, rec)
- }
- for i := 0; i < int(dh.Arcount); i++ {
- rec, off, ok = unpackRR(msg, off)
- if !ok {
- return false
- }
- dns.extra = append(dns.extra, rec)
- }
- // if off != len(msg) {
- // println("extra bytes in dns packet", off, "<", len(msg));
- // }
- return true
-}
-
-func (dns *dnsMsg) String() string {
- s := "DNS: " + printStruct(&dns.dnsMsgHdr) + "\n"
- if len(dns.question) > 0 {
- s += "-- Questions\n"
- for i := 0; i < len(dns.question); i++ {
- s += printStruct(&dns.question[i]) + "\n"
- }
- }
- if len(dns.answer) > 0 {
- s += "-- Answers\n"
- for i := 0; i < len(dns.answer); i++ {
- s += printStruct(dns.answer[i]) + "\n"
- }
- }
- if len(dns.ns) > 0 {
- s += "-- Name servers\n"
- for i := 0; i < len(dns.ns); i++ {
- s += printStruct(dns.ns[i]) + "\n"
- }
- }
- if len(dns.extra) > 0 {
- s += "-- Extra\n"
- for i := 0; i < len(dns.extra); i++ {
- s += printStruct(dns.extra[i]) + "\n"
- }
- }
- return s
-}
diff --git a/src/pkg/net/dnsmsg_test.go b/src/pkg/net/dnsmsg_test.go
deleted file mode 100644
index 06152a01a..000000000
--- a/src/pkg/net/dnsmsg_test.go
+++ /dev/null
@@ -1,100 +0,0 @@
-// 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 (
- "encoding/hex"
- "testing"
-)
-
-func TestDNSParseSRVReply(t *testing.T) {
- data, err := hex.DecodeString(dnsSRVReply)
- if err != nil {
- t.Fatal(err)
- }
- msg := new(dnsMsg)
- ok := msg.Unpack(data)
- if !ok {
- t.Fatalf("unpacking packet failed")
- }
- if g, e := len(msg.answer), 5; g != e {
- t.Errorf("len(msg.answer) = %d; want %d", g, e)
- }
- for idx, rr := range msg.answer {
- if g, e := rr.Header().Rrtype, uint16(dnsTypeSRV); g != e {
- t.Errorf("rr[%d].Header().Rrtype = %d; want %d", idx, g, e)
- }
- if _, ok := rr.(*dnsRR_SRV); !ok {
- t.Errorf("answer[%d] = %T; want *dnsRR_SRV", idx, rr)
- }
- }
- _, addrs, err := answer("_xmpp-server._tcp.google.com.", "foo:53", msg, uint16(dnsTypeSRV))
- if err != nil {
- t.Fatalf("answer: %v", err)
- }
- if g, e := len(addrs), 5; g != e {
- t.Errorf("len(addrs) = %d; want %d", g, e)
- t.Logf("addrs = %#v", addrs)
- }
-}
-
-func TestDNSParseCorruptSRVReply(t *testing.T) {
- data, err := hex.DecodeString(dnsSRVCorruptReply)
- if err != nil {
- t.Fatal(err)
- }
- msg := new(dnsMsg)
- ok := msg.Unpack(data)
- if !ok {
- t.Fatalf("unpacking packet failed")
- }
- if g, e := len(msg.answer), 5; g != e {
- t.Errorf("len(msg.answer) = %d; want %d", g, e)
- }
- for idx, rr := range msg.answer {
- if g, e := rr.Header().Rrtype, uint16(dnsTypeSRV); g != e {
- t.Errorf("rr[%d].Header().Rrtype = %d; want %d", idx, g, e)
- }
- if idx == 4 {
- if _, ok := rr.(*dnsRR_Header); !ok {
- t.Errorf("answer[%d] = %T; want *dnsRR_Header", idx, rr)
- }
- } else {
- if _, ok := rr.(*dnsRR_SRV); !ok {
- t.Errorf("answer[%d] = %T; want *dnsRR_SRV", idx, rr)
- }
- }
- }
- _, addrs, err := answer("_xmpp-server._tcp.google.com.", "foo:53", msg, uint16(dnsTypeSRV))
- if err != nil {
- t.Fatalf("answer: %v", err)
- }
- if g, e := len(addrs), 4; g != e {
- t.Errorf("len(addrs) = %d; want %d", g, e)
- t.Logf("addrs = %#v", addrs)
- }
-}
-
-// Valid DNS SRV reply
-const dnsSRVReply = "0901818000010005000000000c5f786d70702d736572766572045f74637006676f6f67" +
- "6c6503636f6d0000210001c00c002100010000012c00210014000014950c786d70702d" +
- "73657276657234016c06676f6f676c6503636f6d00c00c002100010000012c00210014" +
- "000014950c786d70702d73657276657232016c06676f6f676c6503636f6d00c00c0021" +
- "00010000012c00210014000014950c786d70702d73657276657233016c06676f6f676c" +
- "6503636f6d00c00c002100010000012c00200005000014950b786d70702d7365727665" +
- "72016c06676f6f676c6503636f6d00c00c002100010000012c00210014000014950c78" +
- "6d70702d73657276657231016c06676f6f676c6503636f6d00"
-
-// Corrupt DNS SRV reply, with its final RR having a bogus length
-// (perhaps it was truncated, or it's malicious) The mutation is the
-// capital "FF" below, instead of the proper "21".
-const dnsSRVCorruptReply = "0901818000010005000000000c5f786d70702d736572766572045f74637006676f6f67" +
- "6c6503636f6d0000210001c00c002100010000012c00210014000014950c786d70702d" +
- "73657276657234016c06676f6f676c6503636f6d00c00c002100010000012c00210014" +
- "000014950c786d70702d73657276657232016c06676f6f676c6503636f6d00c00c0021" +
- "00010000012c00210014000014950c786d70702d73657276657233016c06676f6f676c" +
- "6503636f6d00c00c002100010000012c00200005000014950b786d70702d7365727665" +
- "72016c06676f6f676c6503636f6d00c00c002100010000012c00FF0014000014950c78" +
- "6d70702d73657276657231016c06676f6f676c6503636f6d00"
diff --git a/src/pkg/net/dnsname_test.go b/src/pkg/net/dnsname_test.go
deleted file mode 100644
index 70df693f7..000000000
--- a/src/pkg/net/dnsname_test.go
+++ /dev/null
@@ -1,65 +0,0 @@
-// 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.
-
-package net
-
-import (
- "testing"
-)
-
-type testCase struct {
- name string
- result bool
-}
-
-var tests = []testCase{
- // RFC2181, section 11.
- {"_xmpp-server._tcp.google.com", true},
- {"_xmpp-server._tcp.google.com", true},
- {"foo.com", true},
- {"1foo.com", true},
- {"26.0.0.73.com", true},
- {"fo-o.com", true},
- {"fo1o.com", true},
- {"foo1.com", true},
- {"a.b..com", false},
-}
-
-func getTestCases(ch chan<- testCase) {
- defer close(ch)
- var char59 = ""
- var char63 = ""
- var char64 = ""
- for i := 0; i < 59; i++ {
- char59 += "a"
- }
- char63 = char59 + "aaaa"
- char64 = char63 + "a"
-
- for _, tc := range tests {
- ch <- tc
- }
-
- ch <- testCase{char63 + ".com", true}
- ch <- testCase{char64 + ".com", false}
- // 255 char name is fine:
- ch <- testCase{char59 + "." + char63 + "." + char63 + "." +
- char63 + ".com",
- true}
- // 256 char name is bad:
- ch <- testCase{char59 + "a." + char63 + "." + char63 + "." +
- char63 + ".com",
- false}
-}
-
-func TestDNSNames(t *testing.T) {
- ch := make(chan testCase)
- go getTestCases(ch)
- for tc := range ch {
- if isDomainName(tc.name) != tc.result {
- t.Errorf("isDomainName(%v) failed: Should be %v",
- tc.name, tc.result)
- }
- }
-}
diff --git a/src/pkg/net/fd.go b/src/pkg/net/fd.go
deleted file mode 100644
index cd1a21dc3..000000000
--- a/src/pkg/net/fd.go
+++ /dev/null
@@ -1,639 +0,0 @@
-// 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.
-
-package net
-
-import (
- "io"
- "os"
- "sync"
- "syscall"
- "time"
-)
-
-// Network file descriptor.
-type netFD struct {
- // locking/lifetime of sysfd
- sysmu sync.Mutex
- sysref int
- closing bool
-
- // immutable until Close
- sysfd int
- family int
- proto int
- sysfile *os.File
- cr chan bool
- cw chan bool
- net string
- laddr Addr
- raddr Addr
-
- // owned by client
- rdeadline_delta int64
- rdeadline int64
- rio sync.Mutex
- wdeadline_delta int64
- wdeadline int64
- wio sync.Mutex
-
- // owned by fd wait server
- ncr, ncw int
-}
-
-type InvalidConnError struct{}
-
-func (e *InvalidConnError) String() string { return "invalid net.Conn" }
-func (e *InvalidConnError) Temporary() bool { return false }
-func (e *InvalidConnError) Timeout() bool { return false }
-
-// A pollServer helps FDs determine when to retry a non-blocking
-// read or write after they get EAGAIN. When an FD needs to wait,
-// send the fd on s.cr (for a read) or s.cw (for a write) to pass the
-// request to the poll server. Then receive on fd.cr/fd.cw.
-// When the pollServer finds that i/o on FD should be possible
-// again, it will send fd on fd.cr/fd.cw to wake any waiting processes.
-// This protocol is implemented as s.WaitRead() and s.WaitWrite().
-//
-// There is one subtlety: when sending on s.cr/s.cw, the
-// poll server is probably in a system call, waiting for an fd
-// to become ready. It's not looking at the request channels.
-// To resolve this, the poll server waits not just on the FDs it has
-// been given but also its own pipe. After sending on the
-// buffered channel s.cr/s.cw, WaitRead/WaitWrite writes a
-// byte to the pipe, causing the pollServer's poll system call to
-// return. In response to the pipe being readable, the pollServer
-// re-polls its request channels.
-//
-// Note that the ordering is "send request" and then "wake up server".
-// If the operations were reversed, there would be a race: the poll
-// server might wake up and look at the request channel, see that it
-// was empty, and go back to sleep, all before the requester managed
-// to send the request. Because the send must complete before the wakeup,
-// the request channel must be buffered. A buffer of size 1 is sufficient
-// for any request load. If many processes are trying to submit requests,
-// one will succeed, the pollServer will read the request, and then the
-// channel will be empty for the next process's request. A larger buffer
-// might help batch requests.
-//
-// To avoid races in closing, all fd operations are locked and
-// refcounted. when netFD.Close() is called, it calls syscall.Shutdown
-// and sets a closing flag. Only when the last reference is removed
-// will the fd be closed.
-
-type pollServer struct {
- cr, cw chan *netFD // buffered >= 1
- pr, pw *os.File
- poll *pollster // low-level OS hooks
- sync.Mutex // controls pending and deadline
- pending map[int]*netFD
- deadline int64 // next deadline (nsec since 1970)
-}
-
-func (s *pollServer) AddFD(fd *netFD, mode int) {
- intfd := fd.sysfd
- if intfd < 0 {
- // fd closed underfoot
- if mode == 'r' {
- fd.cr <- true
- } else {
- fd.cw <- true
- }
- return
- }
-
- s.Lock()
-
- var t int64
- key := intfd << 1
- if mode == 'r' {
- fd.ncr++
- t = fd.rdeadline
- } else {
- fd.ncw++
- key++
- t = fd.wdeadline
- }
- s.pending[key] = fd
- doWakeup := false
- if t > 0 && (s.deadline == 0 || t < s.deadline) {
- s.deadline = t
- doWakeup = true
- }
-
- wake, err := s.poll.AddFD(intfd, mode, false)
- if err != nil {
- panic("pollServer AddFD " + err.String())
- }
- if wake {
- doWakeup = true
- }
-
- s.Unlock()
-
- if doWakeup {
- s.Wakeup()
- }
-}
-
-var wakeupbuf [1]byte
-
-func (s *pollServer) Wakeup() { s.pw.Write(wakeupbuf[0:]) }
-
-func (s *pollServer) LookupFD(fd int, mode int) *netFD {
- key := fd << 1
- if mode == 'w' {
- key++
- }
- netfd, ok := s.pending[key]
- if !ok {
- return nil
- }
- s.pending[key] = nil, false
- return netfd
-}
-
-func (s *pollServer) WakeFD(fd *netFD, mode int) {
- if mode == 'r' {
- for fd.ncr > 0 {
- fd.ncr--
- fd.cr <- true
- }
- } else {
- for fd.ncw > 0 {
- fd.ncw--
- fd.cw <- true
- }
- }
-}
-
-func (s *pollServer) Now() int64 {
- return time.Nanoseconds()
-}
-
-func (s *pollServer) CheckDeadlines() {
- now := s.Now()
- // TODO(rsc): This will need to be handled more efficiently,
- // probably with a heap indexed by wakeup time.
-
- var next_deadline int64
- for key, fd := range s.pending {
- var t int64
- var mode int
- if key&1 == 0 {
- mode = 'r'
- } else {
- mode = 'w'
- }
- if mode == 'r' {
- t = fd.rdeadline
- } else {
- t = fd.wdeadline
- }
- if t > 0 {
- if t <= now {
- s.pending[key] = nil, false
- if mode == 'r' {
- s.poll.DelFD(fd.sysfd, mode)
- fd.rdeadline = -1
- } else {
- s.poll.DelFD(fd.sysfd, mode)
- fd.wdeadline = -1
- }
- s.WakeFD(fd, mode)
- } else if next_deadline == 0 || t < next_deadline {
- next_deadline = t
- }
- }
- }
- s.deadline = next_deadline
-}
-
-func (s *pollServer) Run() {
- var scratch [100]byte
- s.Lock()
- defer s.Unlock()
- for {
- var t = s.deadline
- if t > 0 {
- t = t - s.Now()
- if t <= 0 {
- s.CheckDeadlines()
- continue
- }
- }
- fd, mode, err := s.poll.WaitFD(s, t)
- if err != nil {
- print("pollServer WaitFD: ", err.String(), "\n")
- return
- }
- if fd < 0 {
- // Timeout happened.
- s.CheckDeadlines()
- continue
- }
- if fd == s.pr.Fd() {
- // Drain our wakeup pipe (we could loop here,
- // but it's unlikely that there are more than
- // len(scratch) wakeup calls).
- s.pr.Read(scratch[0:])
- s.CheckDeadlines()
- } else {
- netfd := s.LookupFD(fd, mode)
- if netfd == nil {
- print("pollServer: unexpected wakeup for fd=", fd, " mode=", string(mode), "\n")
- continue
- }
- s.WakeFD(netfd, mode)
- }
- }
-}
-
-func (s *pollServer) WaitRead(fd *netFD) {
- s.AddFD(fd, 'r')
- <-fd.cr
-}
-
-func (s *pollServer) WaitWrite(fd *netFD) {
- s.AddFD(fd, 'w')
- <-fd.cw
-}
-
-// Network FD methods.
-// All the network FDs use a single pollServer.
-
-var pollserver *pollServer
-var onceStartServer sync.Once
-
-func startServer() {
- p, err := newPollServer()
- if err != nil {
- print("Start pollServer: ", err.String(), "\n")
- }
- pollserver = p
-}
-
-func newFD(fd, family, proto int, net string) (f *netFD, err os.Error) {
- onceStartServer.Do(startServer)
- if e := syscall.SetNonblock(fd, true); e != 0 {
- return nil, os.Errno(e)
- }
- f = &netFD{
- sysfd: fd,
- family: family,
- proto: proto,
- net: net,
- }
- f.cr = make(chan bool, 1)
- f.cw = make(chan bool, 1)
- return f, nil
-}
-
-func (fd *netFD) setAddr(laddr, raddr Addr) {
- fd.laddr = laddr
- fd.raddr = raddr
- var ls, rs string
- if laddr != nil {
- ls = laddr.String()
- }
- if raddr != nil {
- rs = raddr.String()
- }
- fd.sysfile = os.NewFile(fd.sysfd, fd.net+":"+ls+"->"+rs)
-}
-
-func (fd *netFD) connect(ra syscall.Sockaddr) (err os.Error) {
- e := syscall.Connect(fd.sysfd, ra)
- if e == syscall.EINPROGRESS {
- var errno int
- pollserver.WaitWrite(fd)
- e, errno = syscall.GetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_ERROR)
- if errno != 0 {
- return os.NewSyscallError("getsockopt", errno)
- }
- }
- if e != 0 {
- return os.Errno(e)
- }
- return nil
-}
-
-// Add a reference to this fd.
-func (fd *netFD) incref() {
- fd.sysmu.Lock()
- fd.sysref++
- fd.sysmu.Unlock()
-}
-
-// Remove a reference to this FD and close if we've been asked to do so (and
-// there are no references left.
-func (fd *netFD) decref() {
- fd.sysmu.Lock()
- fd.sysref--
- if fd.closing && fd.sysref == 0 && fd.sysfd >= 0 {
- // In case the user has set linger, switch to blocking mode so
- // the close blocks. As long as this doesn't happen often, we
- // can handle the extra OS processes. Otherwise we'll need to
- // use the pollserver for Close too. Sigh.
- syscall.SetNonblock(fd.sysfd, false)
- fd.sysfile.Close()
- fd.sysfile = nil
- fd.sysfd = -1
- }
- fd.sysmu.Unlock()
-}
-
-func (fd *netFD) Close() os.Error {
- if fd == nil || fd.sysfile == nil {
- return os.EINVAL
- }
-
- fd.incref()
- syscall.Shutdown(fd.sysfd, syscall.SHUT_RDWR)
- fd.closing = true
- fd.decref()
- return nil
-}
-
-func (fd *netFD) Read(p []byte) (n int, err os.Error) {
- if fd == nil {
- return 0, os.EINVAL
- }
- fd.rio.Lock()
- defer fd.rio.Unlock()
- fd.incref()
- defer fd.decref()
- if fd.sysfile == nil {
- return 0, os.EINVAL
- }
- if fd.rdeadline_delta > 0 {
- fd.rdeadline = pollserver.Now() + fd.rdeadline_delta
- } else {
- fd.rdeadline = 0
- }
- var oserr os.Error
- for {
- var errno int
- n, errno = syscall.Read(fd.sysfile.Fd(), p)
- if errno == syscall.EAGAIN && fd.rdeadline >= 0 {
- pollserver.WaitRead(fd)
- continue
- }
- if errno != 0 {
- n = 0
- oserr = os.Errno(errno)
- } else if n == 0 && errno == 0 && fd.proto != syscall.SOCK_DGRAM {
- err = os.EOF
- }
- break
- }
- if oserr != nil {
- err = &OpError{"read", fd.net, fd.raddr, oserr}
- }
- return
-}
-
-func (fd *netFD) ReadFrom(p []byte) (n int, sa syscall.Sockaddr, err os.Error) {
- if fd == nil || fd.sysfile == nil {
- return 0, nil, os.EINVAL
- }
- fd.rio.Lock()
- defer fd.rio.Unlock()
- fd.incref()
- defer fd.decref()
- if fd.rdeadline_delta > 0 {
- fd.rdeadline = pollserver.Now() + fd.rdeadline_delta
- } else {
- fd.rdeadline = 0
- }
- var oserr os.Error
- for {
- var errno int
- n, sa, errno = syscall.Recvfrom(fd.sysfd, p, 0)
- if errno == syscall.EAGAIN && fd.rdeadline >= 0 {
- pollserver.WaitRead(fd)
- continue
- }
- if errno != 0 {
- n = 0
- oserr = os.Errno(errno)
- }
- break
- }
- if oserr != nil {
- err = &OpError{"read", fd.net, fd.laddr, oserr}
- }
- return
-}
-
-func (fd *netFD) ReadMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.Sockaddr, err os.Error) {
- if fd == nil || fd.sysfile == nil {
- return 0, 0, 0, nil, os.EINVAL
- }
- fd.rio.Lock()
- defer fd.rio.Unlock()
- fd.incref()
- defer fd.decref()
- if fd.rdeadline_delta > 0 {
- fd.rdeadline = pollserver.Now() + fd.rdeadline_delta
- } else {
- fd.rdeadline = 0
- }
- var oserr os.Error
- for {
- var errno int
- n, oobn, flags, sa, errno = syscall.Recvmsg(fd.sysfd, p, oob, 0)
- if errno == syscall.EAGAIN && fd.rdeadline >= 0 {
- pollserver.WaitRead(fd)
- continue
- }
- if errno != 0 {
- oserr = os.Errno(errno)
- }
- if n == 0 {
- oserr = os.EOF
- }
- break
- }
- if oserr != nil {
- err = &OpError{"read", fd.net, fd.laddr, oserr}
- return
- }
- return
-}
-
-func (fd *netFD) Write(p []byte) (n int, err os.Error) {
- if fd == nil {
- return 0, os.EINVAL
- }
- fd.wio.Lock()
- defer fd.wio.Unlock()
- fd.incref()
- defer fd.decref()
- if fd.sysfile == nil {
- return 0, os.EINVAL
- }
- if fd.wdeadline_delta > 0 {
- fd.wdeadline = pollserver.Now() + fd.wdeadline_delta
- } else {
- fd.wdeadline = 0
- }
- nn := 0
- var oserr os.Error
-
- for {
- n, errno := syscall.Write(fd.sysfile.Fd(), p[nn:])
- if n > 0 {
- nn += n
- }
- if nn == len(p) {
- break
- }
- if errno == syscall.EAGAIN && fd.wdeadline >= 0 {
- pollserver.WaitWrite(fd)
- continue
- }
- if errno != 0 {
- n = 0
- oserr = os.Errno(errno)
- break
- }
- if n == 0 {
- oserr = io.ErrUnexpectedEOF
- break
- }
- }
- if oserr != nil {
- err = &OpError{"write", fd.net, fd.raddr, oserr}
- }
- return nn, err
-}
-
-func (fd *netFD) WriteTo(p []byte, sa syscall.Sockaddr) (n int, err os.Error) {
- if fd == nil || fd.sysfile == nil {
- return 0, os.EINVAL
- }
- fd.wio.Lock()
- defer fd.wio.Unlock()
- fd.incref()
- defer fd.decref()
- if fd.wdeadline_delta > 0 {
- fd.wdeadline = pollserver.Now() + fd.wdeadline_delta
- } else {
- fd.wdeadline = 0
- }
- var oserr os.Error
- for {
- errno := syscall.Sendto(fd.sysfd, p, 0, sa)
- if errno == syscall.EAGAIN && fd.wdeadline >= 0 {
- pollserver.WaitWrite(fd)
- continue
- }
- if errno != 0 {
- oserr = os.Errno(errno)
- }
- break
- }
- if oserr == nil {
- n = len(p)
- } else {
- err = &OpError{"write", fd.net, fd.raddr, oserr}
- }
- return
-}
-
-func (fd *netFD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oobn int, err os.Error) {
- if fd == nil || fd.sysfile == nil {
- return 0, 0, os.EINVAL
- }
- fd.wio.Lock()
- defer fd.wio.Unlock()
- fd.incref()
- defer fd.decref()
- if fd.wdeadline_delta > 0 {
- fd.wdeadline = pollserver.Now() + fd.wdeadline_delta
- } else {
- fd.wdeadline = 0
- }
- var oserr os.Error
- for {
- var errno int
- errno = syscall.Sendmsg(fd.sysfd, p, oob, sa, 0)
- if errno == syscall.EAGAIN && fd.wdeadline >= 0 {
- pollserver.WaitWrite(fd)
- continue
- }
- if errno != 0 {
- oserr = os.Errno(errno)
- }
- break
- }
- if oserr == nil {
- n = len(p)
- oobn = len(oob)
- } else {
- err = &OpError{"write", fd.net, fd.raddr, oserr}
- }
- return
-}
-
-func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (nfd *netFD, err os.Error) {
- if fd == nil || fd.sysfile == nil {
- return nil, os.EINVAL
- }
-
- fd.incref()
- defer fd.decref()
-
- // See ../syscall/exec.go for description of ForkLock.
- // It is okay to hold the lock across syscall.Accept
- // because we have put fd.sysfd into non-blocking mode.
- syscall.ForkLock.RLock()
- var s, e int
- var sa syscall.Sockaddr
- for {
- if fd.closing {
- syscall.ForkLock.RUnlock()
- return nil, os.EINVAL
- }
- s, sa, e = syscall.Accept(fd.sysfd)
- if e != syscall.EAGAIN {
- break
- }
- syscall.ForkLock.RUnlock()
- pollserver.WaitRead(fd)
- syscall.ForkLock.RLock()
- }
- if e != 0 {
- syscall.ForkLock.RUnlock()
- return nil, &OpError{"accept", fd.net, fd.laddr, os.Errno(e)}
- }
- syscall.CloseOnExec(s)
- syscall.ForkLock.RUnlock()
-
- if nfd, err = newFD(s, fd.family, fd.proto, fd.net); err != nil {
- syscall.Close(s)
- return nil, err
- }
- nfd.setAddr(fd.laddr, toAddr(sa))
- return nfd, nil
-}
-
-func (fd *netFD) dup() (f *os.File, err os.Error) {
- ns, e := syscall.Dup(fd.sysfd)
- if e != 0 {
- return nil, &OpError{"dup", fd.net, fd.laddr, os.Errno(e)}
- }
-
- // We want blocking mode for the new fd, hence the double negative.
- if e = syscall.SetNonblock(ns, false); e != 0 {
- return nil, &OpError{"setnonblock", fd.net, fd.laddr, os.Errno(e)}
- }
-
- return os.NewFile(ns, fd.sysfile.Name()), nil
-}
-
-func closesocket(s int) (errno int) {
- return syscall.Close(s)
-}
diff --git a/src/pkg/net/fd_darwin.go b/src/pkg/net/fd_darwin.go
deleted file mode 100644
index 7e3d549eb..000000000
--- a/src/pkg/net/fd_darwin.go
+++ /dev/null
@@ -1,120 +0,0 @@
-// 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 os.Error) {
- p = new(pollster)
- var e int
- if p.kq, e = syscall.Kqueue(); e != 0 {
- return nil, os.NewSyscallError("kqueue", e)
- }
- p.events = p.eventbuf[0:0]
- return p, nil
-}
-
-func (p *pollster) AddFD(fd int, mode int, repeat bool) (bool, os.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_RECEIPT - generate fake EV_ERROR as result of add,
- // rather than waiting for real event
- // EV_ONESHOT - delete the event the first time it triggers
- flags := syscall.EV_ADD | syscall.EV_RECEIPT
- if !repeat {
- flags |= syscall.EV_ONESHOT
- }
- syscall.SetKevent(ev, fd, kmode, flags)
-
- n, e := syscall.Kevent(p.kq, p.kbuf[0:], p.kbuf[0:], nil)
- if e != 0 {
- 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.NewError("kqueue phase error")
- }
- if ev.Data != 0 {
- return false, os.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
- // EV_RECEIPT - generate fake EV_ERROR as result of add,
- // rather than waiting for real event
- syscall.SetKevent(ev, fd, kmode, syscall.EV_DELETE|syscall.EV_RECEIPT)
- syscall.Kevent(p.kq, p.kbuf[0:], p.kbuf[0:], nil)
-}
-
-func (p *pollster) WaitFD(s *pollServer, nsec int64) (fd int, mode int, err os.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[0:], t)
- s.Lock()
-
- if e != 0 {
- 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() os.Error { return os.NewSyscallError("close", syscall.Close(p.kq)) }
diff --git a/src/pkg/net/fd_freebsd.go b/src/pkg/net/fd_freebsd.go
deleted file mode 100644
index e50883e94..000000000
--- a/src/pkg/net/fd_freebsd.go
+++ /dev/null
@@ -1,116 +0,0 @@
-// 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 os.Error) {
- p = new(pollster)
- var e int
- if p.kq, e = syscall.Kqueue(); e != 0 {
- return nil, os.NewSyscallError("kqueue", e)
- }
- p.events = p.eventbuf[0:0]
- return p, nil
-}
-
-func (p *pollster) AddFD(fd int, mode int, repeat bool) (bool, os.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 != 0 {
- 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, os.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 os.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 != 0 {
- 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() os.Error { return os.NewSyscallError("close", syscall.Close(p.kq)) }
diff --git a/src/pkg/net/fd_linux.go b/src/pkg/net/fd_linux.go
deleted file mode 100644
index 70fc344b2..000000000
--- a/src/pkg/net/fd_linux.go
+++ /dev/null
@@ -1,182 +0,0 @@
-// 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 epoll(7).
-
-package net
-
-import (
- "os"
- "syscall"
-)
-
-const (
- readFlags = syscall.EPOLLIN | syscall.EPOLLRDHUP
- writeFlags = syscall.EPOLLOUT
-)
-
-type pollster struct {
- epfd int
-
- // Events we're already waiting for
- // Must hold pollServer lock
- events map[int]uint32
-
- // An event buffer for EpollWait.
- // Used without a lock, may only be used by WaitFD.
- waitEventBuf [10]syscall.EpollEvent
- waitEvents []syscall.EpollEvent
-
- // An event buffer for EpollCtl, to avoid a malloc.
- // Must hold pollServer lock.
- ctlEvent syscall.EpollEvent
-}
-
-func newpollster() (p *pollster, err os.Error) {
- p = new(pollster)
- var e int
-
- // 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 != 0 {
- return nil, os.NewSyscallError("epoll_create", e)
- }
- p.events = make(map[int]uint32)
- return p, nil
-}
-
-func (p *pollster) AddFD(fd int, mode int, repeat bool) (bool, os.Error) {
- // pollServer is locked.
-
- var already bool
- p.ctlEvent.Fd = int32(fd)
- p.ctlEvent.Events, already = p.events[fd]
- if !repeat {
- p.ctlEvent.Events |= syscall.EPOLLONESHOT
- }
- if mode == 'r' {
- p.ctlEvent.Events |= readFlags
- } else {
- p.ctlEvent.Events |= writeFlags
- }
-
- var op int
- if already {
- op = syscall.EPOLL_CTL_MOD
- } else {
- op = syscall.EPOLL_CTL_ADD
- }
- if e := syscall.EpollCtl(p.epfd, op, fd, &p.ctlEvent); e != 0 {
- return false, os.NewSyscallError("epoll_ctl", e)
- }
- p.events[fd] = p.ctlEvent.Events
- return false, nil
-}
-
-func (p *pollster) StopWaiting(fd int, bits uint) {
- // pollServer is locked.
-
- events, already := p.events[fd]
- if !already {
- print("Epoll unexpected fd=", fd, "\n")
- return
- }
-
- // If syscall.EPOLLONESHOT is not set, the wait
- // is a repeating wait, so don't change it.
- if events&syscall.EPOLLONESHOT == 0 {
- return
- }
-
- // Disable the given bits.
- // If we're still waiting for other events, modify the fd
- // event in the kernel. Otherwise, delete it.
- events &= ^uint32(bits)
- if int32(events)&^syscall.EPOLLONESHOT != 0 {
- p.ctlEvent.Fd = int32(fd)
- p.ctlEvent.Events = events
- if e := syscall.EpollCtl(p.epfd, syscall.EPOLL_CTL_MOD, fd, &p.ctlEvent); e != 0 {
- print("Epoll modify fd=", fd, ": ", os.Errno(e).String(), "\n")
- }
- p.events[fd] = events
- } else {
- if e := syscall.EpollCtl(p.epfd, syscall.EPOLL_CTL_DEL, fd, nil); e != 0 {
- print("Epoll delete fd=", fd, ": ", os.Errno(e).String(), "\n")
- }
- p.events[fd] = 0, false
- }
-}
-
-func (p *pollster) DelFD(fd int, mode int) {
- // pollServer is locked.
-
- if mode == 'r' {
- p.StopWaiting(fd, readFlags)
- } else {
- p.StopWaiting(fd, writeFlags)
- }
-
- // Discard any queued up events.
- i := 0
- for i < len(p.waitEvents) {
- if fd == int(p.waitEvents[i].Fd) {
- copy(p.waitEvents[i:], p.waitEvents[i+1:])
- p.waitEvents = p.waitEvents[:len(p.waitEvents)-1]
- } else {
- i++
- }
- }
-}
-
-func (p *pollster) WaitFD(s *pollServer, nsec int64) (fd int, mode int, err os.Error) {
- for len(p.waitEvents) == 0 {
- var msec int = -1
- if nsec > 0 {
- msec = int((nsec + 1e6 - 1) / 1e6)
- }
-
- s.Unlock()
- n, e := syscall.EpollWait(p.epfd, p.waitEventBuf[0:], msec)
- s.Lock()
-
- if e != 0 {
- if e == syscall.EAGAIN || e == syscall.EINTR {
- continue
- }
- return -1, 0, os.NewSyscallError("epoll_wait", e)
- }
- if n == 0 {
- return -1, 0, nil
- }
- p.waitEvents = p.waitEventBuf[0:n]
- }
-
- ev := &p.waitEvents[0]
- p.waitEvents = p.waitEvents[1:]
-
- fd = int(ev.Fd)
-
- if ev.Events&writeFlags != 0 {
- p.StopWaiting(fd, writeFlags)
- return fd, 'w', nil
- }
- if ev.Events&readFlags != 0 {
- p.StopWaiting(fd, readFlags)
- return fd, 'r', nil
- }
-
- // Other events are error conditions - wake whoever is waiting.
- events, _ := p.events[fd]
- if events&writeFlags != 0 {
- p.StopWaiting(fd, writeFlags)
- return fd, 'w', nil
- }
- p.StopWaiting(fd, readFlags)
- return fd, 'r', nil
-}
-
-func (p *pollster) Close() os.Error {
- return os.NewSyscallError("close", syscall.Close(p.epfd))
-}
diff --git a/src/pkg/net/fd_windows.go b/src/pkg/net/fd_windows.go
deleted file mode 100644
index 41d06120a..000000000
--- a/src/pkg/net/fd_windows.go
+++ /dev/null
@@ -1,529 +0,0 @@
-// Copyright 2010 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 (
- "os"
- "runtime"
- "sync"
- "syscall"
- "time"
- "unsafe"
-)
-
-type InvalidConnError struct{}
-
-func (e *InvalidConnError) String() string { return "invalid net.Conn" }
-func (e *InvalidConnError) Temporary() bool { return false }
-func (e *InvalidConnError) Timeout() bool { return false }
-
-var initErr os.Error
-
-func init() {
- var d syscall.WSAData
- e := syscall.WSAStartup(uint32(0x101), &d)
- if e != 0 {
- initErr = os.NewSyscallError("WSAStartup", e)
- }
-}
-
-func closesocket(s syscall.Handle) (errno int) {
- return syscall.Closesocket(s)
-}
-
-// Interface for all io operations.
-type anOpIface interface {
- Op() *anOp
- Name() string
- Submit() (errno int)
-}
-
-// IO completion result parameters.
-type ioResult struct {
- qty uint32
- err int
-}
-
-// anOp implements functionality common to all io operations.
-type anOp struct {
- // Used by IOCP interface, it must be first field
- // of the struct, as our code rely on it.
- o syscall.Overlapped
-
- resultc chan ioResult // io completion results
- errnoc chan int // io submit / cancel operation errors
- fd *netFD
-}
-
-func (o *anOp) Init(fd *netFD) {
- o.fd = fd
- o.resultc = make(chan ioResult, 1)
- o.errnoc = make(chan int)
-}
-
-func (o *anOp) Op() *anOp {
- return o
-}
-
-// bufOp is used by io operations that read / write
-// data from / to client buffer.
-type bufOp struct {
- anOp
- buf syscall.WSABuf
-}
-
-func (o *bufOp) Init(fd *netFD, buf []byte) {
- o.anOp.Init(fd)
- o.buf.Len = uint32(len(buf))
- if len(buf) == 0 {
- o.buf.Buf = nil
- } else {
- o.buf.Buf = (*byte)(unsafe.Pointer(&buf[0]))
- }
-}
-
-// resultSrv will retrieve all io completion results from
-// iocp and send them to the correspondent waiting client
-// goroutine via channel supplied in the request.
-type resultSrv struct {
- iocp syscall.Handle
-}
-
-func (s *resultSrv) Run() {
- var o *syscall.Overlapped
- var key uint32
- var r ioResult
- for {
- r.err = syscall.GetQueuedCompletionStatus(s.iocp, &(r.qty), &key, &o, syscall.INFINITE)
- switch {
- case r.err == 0:
- // Dequeued successfully completed io packet.
- case r.err == syscall.WAIT_TIMEOUT && o == nil:
- // Wait has timed out (should not happen now, but might be used in the future).
- panic("GetQueuedCompletionStatus timed out")
- case o == nil:
- // Failed to dequeue anything -> report the error.
- panic("GetQueuedCompletionStatus failed " + syscall.Errstr(r.err))
- default:
- // Dequeued failed io packet.
- }
- (*anOp)(unsafe.Pointer(o)).resultc <- r
- }
-}
-
-
-// ioSrv executes net io requests.
-type ioSrv struct {
- submchan chan anOpIface // submit io requests
- canchan chan anOpIface // cancel io requests
-}
-
-// ProcessRemoteIO will execute submit io requests on behalf
-// of other goroutines, all on a single os thread, so it can
-// cancel them later. Results of all operations will be sent
-// back to their requesters via channel supplied in request.
-func (s *ioSrv) ProcessRemoteIO() {
- runtime.LockOSThread()
- defer runtime.UnlockOSThread()
- for {
- select {
- case o := <-s.submchan:
- o.Op().errnoc <- o.Submit()
- case o := <-s.canchan:
- o.Op().errnoc <- syscall.CancelIo(syscall.Handle(o.Op().fd.sysfd))
- }
- }
-}
-
-// ExecIO executes a single io operation. It either executes it
-// inline, or, if timeouts are employed, passes the request onto
-// a special goroutine and waits for completion or cancels request.
-func (s *ioSrv) ExecIO(oi anOpIface, deadline_delta int64) (n int, err os.Error) {
- var e int
- o := oi.Op()
- if deadline_delta > 0 {
- // Send request to a special dedicated thread,
- // so it can stop the io with CancelIO later.
- s.submchan <- oi
- e = <-o.errnoc
- } else {
- e = oi.Submit()
- }
- switch e {
- case 0:
- // IO completed immediately, but we need to get our completion message anyway.
- case syscall.ERROR_IO_PENDING:
- // IO started, and we have to wait for it's completion.
- default:
- return 0, &OpError{oi.Name(), o.fd.net, o.fd.laddr, os.Errno(e)}
- }
- // Wait for our request to complete.
- var r ioResult
- if deadline_delta > 0 {
- select {
- case r = <-o.resultc:
- case <-time.After(deadline_delta):
- s.canchan <- oi
- <-o.errnoc
- r = <-o.resultc
- if r.err == syscall.ERROR_OPERATION_ABORTED { // IO Canceled
- r.err = syscall.EWOULDBLOCK
- }
- }
- } else {
- r = <-o.resultc
- }
- if r.err != 0 {
- err = &OpError{oi.Name(), o.fd.net, o.fd.laddr, os.Errno(r.err)}
- }
- return int(r.qty), err
-}
-
-// Start helper goroutines.
-var resultsrv *resultSrv
-var iosrv *ioSrv
-var onceStartServer sync.Once
-
-func startServer() {
- resultsrv = new(resultSrv)
- var errno int
- resultsrv.iocp, errno = syscall.CreateIoCompletionPort(syscall.InvalidHandle, 0, 0, 1)
- if errno != 0 {
- panic("CreateIoCompletionPort failed " + syscall.Errstr(errno))
- }
- go resultsrv.Run()
-
- iosrv = new(ioSrv)
- iosrv.submchan = make(chan anOpIface)
- iosrv.canchan = make(chan anOpIface)
- go iosrv.ProcessRemoteIO()
-}
-
-// Network file descriptor.
-type netFD struct {
- // locking/lifetime of sysfd
- sysmu sync.Mutex
- sysref int
- closing bool
-
- // immutable until Close
- sysfd syscall.Handle
- family int
- proto int
- net string
- laddr Addr
- raddr Addr
-
- // owned by client
- rdeadline_delta int64
- rdeadline int64
- rio sync.Mutex
- wdeadline_delta int64
- wdeadline int64
- wio sync.Mutex
-}
-
-func allocFD(fd syscall.Handle, family, proto int, net string) (f *netFD) {
- f = &netFD{
- sysfd: fd,
- family: family,
- proto: proto,
- net: net,
- }
- runtime.SetFinalizer(f, (*netFD).Close)
- return f
-}
-
-func newFD(fd syscall.Handle, family, proto int, net string) (f *netFD, err os.Error) {
- if initErr != nil {
- return nil, initErr
- }
- onceStartServer.Do(startServer)
- // Associate our socket with resultsrv.iocp.
- if _, e := syscall.CreateIoCompletionPort(syscall.Handle(fd), resultsrv.iocp, 0, 0); e != 0 {
- return nil, os.Errno(e)
- }
- return allocFD(fd, family, proto, net), nil
-}
-
-func (fd *netFD) setAddr(laddr, raddr Addr) {
- fd.laddr = laddr
- fd.raddr = raddr
-}
-
-func (fd *netFD) connect(ra syscall.Sockaddr) (err os.Error) {
- e := syscall.Connect(fd.sysfd, ra)
- if e != 0 {
- return os.Errno(e)
- }
- return nil
-}
-
-// Add a reference to this fd.
-func (fd *netFD) incref() {
- fd.sysmu.Lock()
- fd.sysref++
- fd.sysmu.Unlock()
-}
-
-// Remove a reference to this FD and close if we've been asked to do so (and
-// there are no references left.
-func (fd *netFD) decref() {
- fd.sysmu.Lock()
- fd.sysref--
- if fd.closing && fd.sysref == 0 && fd.sysfd >= 0 {
- // In case the user has set linger, switch to blocking mode so
- // the close blocks. As long as this doesn't happen often, we
- // can handle the extra OS processes. Otherwise we'll need to
- // use the resultsrv for Close too. Sigh.
- syscall.SetNonblock(fd.sysfd, false)
- closesocket(fd.sysfd)
- fd.sysfd = syscall.InvalidHandle
- // no need for a finalizer anymore
- runtime.SetFinalizer(fd, nil)
- }
- fd.sysmu.Unlock()
-}
-
-func (fd *netFD) Close() os.Error {
- if fd == nil || fd.sysfd == syscall.InvalidHandle {
- return os.EINVAL
- }
-
- fd.incref()
- syscall.Shutdown(fd.sysfd, syscall.SHUT_RDWR)
- fd.closing = true
- fd.decref()
- return nil
-}
-
-// Read from network.
-
-type readOp struct {
- bufOp
-}
-
-func (o *readOp) Submit() (errno int) {
- var d, f uint32
- return syscall.WSARecv(syscall.Handle(o.fd.sysfd), &o.buf, 1, &d, &f, &o.o, nil)
-}
-
-func (o *readOp) Name() string {
- return "WSARecv"
-}
-
-func (fd *netFD) Read(buf []byte) (n int, err os.Error) {
- if fd == nil {
- return 0, os.EINVAL
- }
- fd.rio.Lock()
- defer fd.rio.Unlock()
- fd.incref()
- defer fd.decref()
- if fd.sysfd == syscall.InvalidHandle {
- return 0, os.EINVAL
- }
- var o readOp
- o.Init(fd, buf)
- n, err = iosrv.ExecIO(&o, fd.rdeadline_delta)
- if err == nil && n == 0 {
- err = os.EOF
- }
- return
-}
-
-// ReadFrom from network.
-
-type readFromOp struct {
- bufOp
- rsa syscall.RawSockaddrAny
-}
-
-func (o *readFromOp) Submit() (errno int) {
- var d, f uint32
- l := int32(unsafe.Sizeof(o.rsa))
- return syscall.WSARecvFrom(o.fd.sysfd, &o.buf, 1, &d, &f, &o.rsa, &l, &o.o, nil)
-}
-
-func (o *readFromOp) Name() string {
- return "WSARecvFrom"
-}
-
-func (fd *netFD) ReadFrom(buf []byte) (n int, sa syscall.Sockaddr, err os.Error) {
- if fd == nil {
- return 0, nil, os.EINVAL
- }
- if len(buf) == 0 {
- return 0, nil, nil
- }
- fd.rio.Lock()
- defer fd.rio.Unlock()
- fd.incref()
- defer fd.decref()
- if fd.sysfd == syscall.InvalidHandle {
- return 0, nil, os.EINVAL
- }
- var o readFromOp
- o.Init(fd, buf)
- n, err = iosrv.ExecIO(&o, fd.rdeadline_delta)
- sa, _ = o.rsa.Sockaddr()
- return
-}
-
-// Write to network.
-
-type writeOp struct {
- bufOp
-}
-
-func (o *writeOp) Submit() (errno int) {
- var d uint32
- return syscall.WSASend(o.fd.sysfd, &o.buf, 1, &d, 0, &o.o, nil)
-}
-
-func (o *writeOp) Name() string {
- return "WSASend"
-}
-
-func (fd *netFD) Write(buf []byte) (n int, err os.Error) {
- if fd == nil {
- return 0, os.EINVAL
- }
- fd.wio.Lock()
- defer fd.wio.Unlock()
- fd.incref()
- defer fd.decref()
- if fd.sysfd == syscall.InvalidHandle {
- return 0, os.EINVAL
- }
- var o writeOp
- o.Init(fd, buf)
- return iosrv.ExecIO(&o, fd.wdeadline_delta)
-}
-
-// WriteTo to network.
-
-type writeToOp struct {
- bufOp
- sa syscall.Sockaddr
-}
-
-func (o *writeToOp) Submit() (errno int) {
- var d uint32
- return syscall.WSASendto(o.fd.sysfd, &o.buf, 1, &d, 0, o.sa, &o.o, nil)
-}
-
-func (o *writeToOp) Name() string {
- return "WSASendto"
-}
-
-func (fd *netFD) WriteTo(buf []byte, sa syscall.Sockaddr) (n int, err os.Error) {
- if fd == nil {
- return 0, os.EINVAL
- }
- if len(buf) == 0 {
- return 0, nil
- }
- fd.wio.Lock()
- defer fd.wio.Unlock()
- fd.incref()
- defer fd.decref()
- if fd.sysfd == syscall.InvalidHandle {
- return 0, os.EINVAL
- }
- var o writeToOp
- o.Init(fd, buf)
- o.sa = sa
- return iosrv.ExecIO(&o, fd.wdeadline_delta)
-}
-
-// Accept new network connections.
-
-type acceptOp struct {
- anOp
- newsock syscall.Handle
- attrs [2]syscall.RawSockaddrAny // space for local and remote address only
-}
-
-func (o *acceptOp) Submit() (errno int) {
- var d uint32
- l := uint32(unsafe.Sizeof(o.attrs[0]))
- return syscall.AcceptEx(o.fd.sysfd, o.newsock,
- (*byte)(unsafe.Pointer(&o.attrs[0])), 0, l, l, &d, &o.o)
-}
-
-func (o *acceptOp) Name() string {
- return "AcceptEx"
-}
-
-func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (nfd *netFD, err os.Error) {
- if fd == nil || fd.sysfd == syscall.InvalidHandle {
- return nil, os.EINVAL
- }
- fd.incref()
- defer fd.decref()
-
- // Get new socket.
- // See ../syscall/exec.go for description of ForkLock.
- syscall.ForkLock.RLock()
- s, e := syscall.Socket(fd.family, fd.proto, 0)
- if e != 0 {
- syscall.ForkLock.RUnlock()
- return nil, os.Errno(e)
- }
- syscall.CloseOnExec(s)
- syscall.ForkLock.RUnlock()
-
- // Associate our new socket with IOCP.
- onceStartServer.Do(startServer)
- if _, e = syscall.CreateIoCompletionPort(s, resultsrv.iocp, 0, 0); e != 0 {
- return nil, &OpError{"CreateIoCompletionPort", fd.net, fd.laddr, os.Errno(e)}
- }
-
- // Submit accept request.
- var o acceptOp
- o.Init(fd)
- o.newsock = s
- _, err = iosrv.ExecIO(&o, 0)
- if err != nil {
- closesocket(s)
- return nil, err
- }
-
- // Inherit properties of the listening socket.
- e = syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_UPDATE_ACCEPT_CONTEXT, int(fd.sysfd))
- if e != 0 {
- closesocket(s)
- return nil, err
- }
-
- // Get local and peer addr out of AcceptEx buffer.
- var lrsa, rrsa *syscall.RawSockaddrAny
- var llen, rlen int32
- l := uint32(unsafe.Sizeof(*lrsa))
- syscall.GetAcceptExSockaddrs((*byte)(unsafe.Pointer(&o.attrs[0])),
- 0, l, l, &lrsa, &llen, &rrsa, &rlen)
- lsa, _ := lrsa.Sockaddr()
- rsa, _ := rrsa.Sockaddr()
-
- nfd = allocFD(s, fd.family, fd.proto, fd.net)
- nfd.setAddr(toAddr(lsa), toAddr(rsa))
- return nfd, nil
-}
-
-// Unimplemented functions.
-
-func (fd *netFD) dup() (f *os.File, err os.Error) {
- // TODO: Implement this
- return nil, os.NewSyscallError("dup", syscall.EWINDOWS)
-}
-
-func (fd *netFD) ReadMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.Sockaddr, err os.Error) {
- return 0, 0, 0, nil, os.EAFNOSUPPORT
-}
-
-func (fd *netFD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oobn int, err os.Error) {
- return 0, 0, os.EAFNOSUPPORT
-}
diff --git a/src/pkg/net/file.go b/src/pkg/net/file.go
deleted file mode 100644
index 0e411a192..000000000
--- a/src/pkg/net/file.go
+++ /dev/null
@@ -1,119 +0,0 @@
-// 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 (
- "os"
- "syscall"
-)
-
-func newFileFD(f *os.File) (nfd *netFD, err os.Error) {
- fd, errno := syscall.Dup(f.Fd())
- if errno != 0 {
- return nil, os.NewSyscallError("dup", errno)
- }
-
- proto, errno := syscall.GetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_TYPE)
- if errno != 0 {
- return nil, os.NewSyscallError("getsockopt", errno)
- }
-
- toAddr := sockaddrToTCP
- sa, _ := syscall.Getsockname(fd)
- switch sa.(type) {
- default:
- closesocket(fd)
- return nil, os.EINVAL
- case *syscall.SockaddrInet4:
- if proto == syscall.SOCK_DGRAM {
- toAddr = sockaddrToUDP
- } else if proto == syscall.SOCK_RAW {
- toAddr = sockaddrToIP
- }
- case *syscall.SockaddrInet6:
- if proto == syscall.SOCK_DGRAM {
- toAddr = sockaddrToUDP
- } else if proto == syscall.SOCK_RAW {
- toAddr = sockaddrToIP
- }
- case *syscall.SockaddrUnix:
- toAddr = sockaddrToUnix
- if proto == syscall.SOCK_DGRAM {
- toAddr = sockaddrToUnixgram
- } else if proto == syscall.SOCK_SEQPACKET {
- toAddr = sockaddrToUnixpacket
- }
- }
- laddr := toAddr(sa)
- sa, _ = syscall.Getpeername(fd)
- raddr := toAddr(sa)
-
- if nfd, err = newFD(fd, 0, proto, laddr.Network()); err != nil {
- return nil, err
- }
- nfd.setAddr(laddr, raddr)
- return nfd, nil
-}
-
-// FileConn returns a copy of the network connection corresponding to
-// the open file f. It is the caller's responsibility to close f when
-// finished. Closing c does not affect f, and closing f does not
-// affect c.
-func FileConn(f *os.File) (c Conn, err os.Error) {
- fd, err := newFileFD(f)
- if err != nil {
- return nil, err
- }
- switch fd.laddr.(type) {
- case *TCPAddr:
- return newTCPConn(fd), nil
- case *UDPAddr:
- return newUDPConn(fd), nil
- case *UnixAddr:
- return newUnixConn(fd), nil
- case *IPAddr:
- return newIPConn(fd), nil
- }
- fd.Close()
- return nil, os.EINVAL
-}
-
-// FileListener returns a copy of the network listener corresponding
-// to the open file f. It is the caller's responsibility to close l
-// when finished. Closing c does not affect l, and closing l does not
-// affect c.
-func FileListener(f *os.File) (l Listener, err os.Error) {
- fd, err := newFileFD(f)
- if err != nil {
- return nil, err
- }
- switch laddr := fd.laddr.(type) {
- case *TCPAddr:
- return &TCPListener{fd}, nil
- case *UnixAddr:
- return &UnixListener{fd, laddr.Name}, nil
- }
- fd.Close()
- return nil, os.EINVAL
-}
-
-// FilePacketConn returns a copy of the packet network connection
-// corresponding to the open file f. It is the caller's
-// responsibility to close f when finished. Closing c does not affect
-// f, and closing f does not affect c.
-func FilePacketConn(f *os.File) (c PacketConn, err os.Error) {
- fd, err := newFileFD(f)
- if err != nil {
- return nil, err
- }
- switch fd.laddr.(type) {
- case *UDPAddr:
- return newUDPConn(fd), nil
- case *UnixAddr:
- return newUnixConn(fd), nil
- }
- fd.Close()
- return nil, os.EINVAL
-}
diff --git a/src/pkg/net/file_test.go b/src/pkg/net/file_test.go
deleted file mode 100644
index bd1e2c9d7..000000000
--- a/src/pkg/net/file_test.go
+++ /dev/null
@@ -1,133 +0,0 @@
-// 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 (
- "os"
- "reflect"
- "runtime"
- "syscall"
- "testing"
-)
-
-type listenerFile interface {
- Listener
- File() (f *os.File, err os.Error)
-}
-
-type packetConnFile interface {
- PacketConn
- File() (f *os.File, err os.Error)
-}
-
-type connFile interface {
- Conn
- File() (f *os.File, err os.Error)
-}
-
-func testFileListener(t *testing.T, net, laddr string) {
- if net == "tcp" {
- laddr += ":0" // any available port
- }
- l, err := Listen(net, laddr)
- if err != nil {
- t.Fatalf("Listen failed: %v", err)
- }
- defer l.Close()
- lf := l.(listenerFile)
- f, err := lf.File()
- if err != nil {
- t.Fatalf("File failed: %v", err)
- }
- c, err := FileListener(f)
- if err != nil {
- t.Fatalf("FileListener failed: %v", err)
- }
- if !reflect.DeepEqual(l.Addr(), c.Addr()) {
- t.Fatalf("Addrs not equal: %#v != %#v", l.Addr(), c.Addr())
- }
- if err := c.Close(); err != nil {
- t.Fatalf("Close failed: %v", err)
- }
- if err := f.Close(); err != nil {
- t.Fatalf("Close failed: %v", err)
- }
-}
-
-func TestFileListener(t *testing.T) {
- if runtime.GOOS == "windows" {
- return
- }
- testFileListener(t, "tcp", "127.0.0.1")
- testFileListener(t, "tcp", "127.0.0.1")
- if supportsIPv6 && supportsIPv4map {
- testFileListener(t, "tcp", "[::ffff:127.0.0.1]")
- testFileListener(t, "tcp", "127.0.0.1")
- testFileListener(t, "tcp", "[::ffff:127.0.0.1]")
- }
- if syscall.OS == "linux" {
- testFileListener(t, "unix", "@gotest/net")
- testFileListener(t, "unixpacket", "@gotest/net")
- }
-}
-
-func testFilePacketConn(t *testing.T, pcf packetConnFile) {
- f, err := pcf.File()
- if err != nil {
- t.Fatalf("File failed: %v", err)
- }
- c, err := FilePacketConn(f)
- if err != nil {
- t.Fatalf("FilePacketConn failed: %v", err)
- }
- if !reflect.DeepEqual(pcf.LocalAddr(), c.LocalAddr()) {
- t.Fatalf("LocalAddrs not equal: %#v != %#v", pcf.LocalAddr(), c.LocalAddr())
- }
- if err := c.Close(); err != nil {
- t.Fatalf("Close failed: %v", err)
- }
- if err := f.Close(); err != nil {
- t.Fatalf("Close failed: %v", err)
- }
-}
-
-func testFilePacketConnListen(t *testing.T, net, laddr string) {
- l, err := ListenPacket(net, laddr)
- if err != nil {
- t.Fatalf("Listen failed: %v", err)
- }
- testFilePacketConn(t, l.(packetConnFile))
- if err := l.Close(); err != nil {
- t.Fatalf("Close failed: %v", err)
- }
-}
-
-func testFilePacketConnDial(t *testing.T, net, raddr string) {
- c, err := Dial(net, raddr)
- if err != nil {
- t.Fatalf("Dial failed: %v", err)
- }
- testFilePacketConn(t, c.(packetConnFile))
- if err := c.Close(); err != nil {
- t.Fatalf("Close failed: %v", err)
- }
-}
-
-func TestFilePacketConn(t *testing.T) {
- if runtime.GOOS == "windows" {
- return
- }
- testFilePacketConnListen(t, "udp", "127.0.0.1:0")
- testFilePacketConnDial(t, "udp", "127.0.0.1:12345")
- if supportsIPv6 {
- testFilePacketConnListen(t, "udp", "[::1]:0")
- }
- if supportsIPv6 && supportsIPv4map {
- testFilePacketConnDial(t, "udp", "[::ffff:127.0.0.1]:12345")
- }
- if syscall.OS == "linux" {
- testFilePacketConnListen(t, "unixgram", "@gotest1/net")
- }
-}
diff --git a/src/pkg/net/file_windows.go b/src/pkg/net/file_windows.go
deleted file mode 100644
index 94aa58375..000000000
--- a/src/pkg/net/file_windows.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// 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 (
- "os"
- "syscall"
-)
-
-func FileConn(f *os.File) (c Conn, err os.Error) {
- // TODO: Implement this
- return nil, os.NewSyscallError("FileConn", syscall.EWINDOWS)
-}
-
-func FileListener(f *os.File) (l Listener, err os.Error) {
- // TODO: Implement this
- return nil, os.NewSyscallError("FileListener", syscall.EWINDOWS)
-}
-
-func FilePacketConn(f *os.File) (c PacketConn, err os.Error) {
- // TODO: Implement this
- return nil, os.NewSyscallError("FilePacketConn", syscall.EWINDOWS)
-}
diff --git a/src/pkg/net/hosts.go b/src/pkg/net/hosts.go
deleted file mode 100644
index d75e9e038..000000000
--- a/src/pkg/net/hosts.go
+++ /dev/null
@@ -1,86 +0,0 @@
-// 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.
-
-// Read static host/IP entries from /etc/hosts.
-
-package net
-
-import (
- "os"
- "sync"
-)
-
-const cacheMaxAge = int64(300) // 5 minutes.
-
-// hostsPath points to the file with static IP/address entries.
-var hostsPath = "/etc/hosts"
-
-// Simple cache.
-var hosts struct {
- sync.Mutex
- byName map[string][]string
- byAddr map[string][]string
- time int64
- path string
-}
-
-func readHosts() {
- now, _, _ := os.Time()
- hp := hostsPath
- if len(hosts.byName) == 0 || hosts.time+cacheMaxAge <= now || hosts.path != hp {
- hs := make(map[string][]string)
- is := make(map[string][]string)
- var file *file
- if file, _ = open(hp); file == nil {
- return
- }
- for line, ok := file.readLine(); ok; line, ok = file.readLine() {
- if i := byteIndex(line, '#'); i >= 0 {
- // Discard comments.
- line = line[0:i]
- }
- f := getFields(line)
- if len(f) < 2 || ParseIP(f[0]) == nil {
- continue
- }
- for i := 1; i < len(f); i++ {
- h := f[i]
- hs[h] = append(hs[h], f[0])
- is[f[0]] = append(is[f[0]], h)
- }
- }
- // Update the data cache.
- hosts.time, _, _ = os.Time()
- hosts.path = hp
- hosts.byName = hs
- hosts.byAddr = is
- file.close()
- }
-}
-
-// lookupStaticHost looks up the addresses for the given host from /etc/hosts.
-func lookupStaticHost(host string) []string {
- hosts.Lock()
- defer hosts.Unlock()
- readHosts()
- if len(hosts.byName) != 0 {
- if ips, ok := hosts.byName[host]; ok {
- return ips
- }
- }
- return nil
-}
-
-// lookupStaticAddr looks up the hosts for the given address from /etc/hosts.
-func lookupStaticAddr(addr string) []string {
- hosts.Lock()
- defer hosts.Unlock()
- readHosts()
- if len(hosts.byAddr) != 0 {
- if hosts, ok := hosts.byAddr[addr]; ok {
- return hosts
- }
- }
- return nil
-}
diff --git a/src/pkg/net/hosts_test.go b/src/pkg/net/hosts_test.go
deleted file mode 100644
index 1bd00541c..000000000
--- a/src/pkg/net/hosts_test.go
+++ /dev/null
@@ -1,68 +0,0 @@
-// 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.
-
-package net
-
-import (
- "sort"
- "testing"
-)
-
-type hostTest struct {
- host string
- ips []IP
-}
-
-var hosttests = []hostTest{
- {"odin", []IP{
- IPv4(127, 0, 0, 2),
- IPv4(127, 0, 0, 3),
- ParseIP("::2"),
- }},
- {"thor", []IP{
- IPv4(127, 1, 1, 1),
- }},
- {"loki", []IP{}},
- {"ullr", []IP{
- IPv4(127, 1, 1, 2),
- }},
- {"ullrhost", []IP{
- IPv4(127, 1, 1, 2),
- }},
-}
-
-func TestLookupStaticHost(t *testing.T) {
- p := hostsPath
- hostsPath = "hosts_testdata"
- for i := 0; i < len(hosttests); i++ {
- tt := hosttests[i]
- ips := lookupStaticHost(tt.host)
- if len(ips) != len(tt.ips) {
- t.Errorf("# of hosts = %v; want %v",
- len(ips), len(tt.ips))
- return
- }
- for k, v := range ips {
- if tt.ips[k].String() != v {
- t.Errorf("lookupStaticHost(%q) = %v; want %v",
- tt.host, v, tt.ips[k])
- }
- }
- }
- hostsPath = p
-}
-
-func TestLookupHost(t *testing.T) {
- // Can't depend on this to return anything in particular,
- // but if it does return something, make sure it doesn't
- // duplicate addresses (a common bug due to the way
- // getaddrinfo works).
- addrs, _ := LookupHost("localhost")
- sort.Strings(addrs)
- for i := 0; i+1 < len(addrs); i++ {
- if addrs[i] == addrs[i+1] {
- t.Fatalf("LookupHost(\"localhost\") = %v, has duplicate addresses", addrs)
- }
- }
-}
diff --git a/src/pkg/net/hosts_testdata b/src/pkg/net/hosts_testdata
deleted file mode 100644
index b60176389..000000000
--- a/src/pkg/net/hosts_testdata
+++ /dev/null
@@ -1,12 +0,0 @@
-255.255.255.255 broadcasthost
-127.0.0.2 odin
-127.0.0.3 odin # inline comment
-::2 odin
-127.1.1.1 thor
-# aliases
-127.1.1.2 ullr ullrhost
-# Bogus entries that must be ignored.
-123.123.123 loki
-321.321.321.321
-# TODO(yvesj): Should we be able to parse this? From a Darwin system.
-fe80::1%lo0 localhost
diff --git a/src/pkg/net/interface.go b/src/pkg/net/interface.go
deleted file mode 100644
index f6de36f64..000000000
--- a/src/pkg/net/interface.go
+++ /dev/null
@@ -1,123 +0,0 @@
-// 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
-
-package net
-
-import (
- "bytes"
- "fmt"
- "os"
-)
-
-// A HardwareAddr represents a physical hardware address.
-type HardwareAddr []byte
-
-func (a HardwareAddr) String() string {
- var buf bytes.Buffer
- for i, b := range a {
- if i > 0 {
- buf.WriteByte(':')
- }
- fmt.Fprintf(&buf, "%02x", b)
- }
- return buf.String()
-}
-
-// Interface represents a mapping between network interface name
-// and index. It also represents network interface facility
-// information.
-type Interface struct {
- Index int // positive integer that starts at one, zero is never used
- MTU int // maximum transmission unit
- Name string // e.g., "en0", "lo0", "eth0.100"
- HardwareAddr HardwareAddr // IEEE MAC-48, EUI-48 and EUI-64 form
- Flags Flags // e.g., FlagUp, FlagLoopback, FlagMulticast
-}
-
-type Flags uint
-
-const (
- FlagUp Flags = 1 << iota // interface is up
- FlagBroadcast // interface supports broadcast access capability
- FlagLoopback // interface is a loopback interface
- FlagPointToPoint // interface belongs to a point-to-point link
- FlagMulticast // interface supports multicast access capability
-)
-
-var flagNames = []string{
- "up",
- "broadcast",
- "loopback",
- "pointtopoint",
- "multicast",
-}
-
-func (f Flags) String() string {
- s := ""
- for i, name := range flagNames {
- if f&(1<<uint(i)) != 0 {
- if s != "" {
- s += "|"
- }
- s += name
- }
- }
- if s == "" {
- s = "0"
- }
- return s
-}
-
-// Addrs returns interface addresses for a specific interface.
-func (ifi *Interface) Addrs() ([]Addr, os.Error) {
- if ifi == nil {
- return nil, os.NewError("net: invalid interface")
- }
- return interfaceAddrTable(ifi.Index)
-}
-
-// Interfaces returns a list of the systems's network interfaces.
-func Interfaces() ([]Interface, os.Error) {
- return interfaceTable(0)
-}
-
-// InterfaceAddrs returns a list of the system's network interface
-// addresses.
-func InterfaceAddrs() ([]Addr, os.Error) {
- return interfaceAddrTable(0)
-}
-
-// InterfaceByIndex returns the interface specified by index.
-func InterfaceByIndex(index int) (*Interface, os.Error) {
- if index <= 0 {
- return nil, os.NewError("net: invalid interface index")
- }
- ift, err := interfaceTable(index)
- if err != nil {
- return nil, err
- }
- for _, ifi := range ift {
- return &ifi, nil
- }
- return nil, os.NewError("net: no such interface")
-}
-
-// InterfaceByName returns the interface specified by name.
-func InterfaceByName(name string) (*Interface, os.Error) {
- if name == "" {
- return nil, os.NewError("net: invalid interface name")
- }
- ift, err := interfaceTable(0)
- if err != nil {
- return nil, err
- }
- for _, ifi := range ift {
- if name == ifi.Name {
- return &ifi, nil
- }
- }
- return nil, os.NewError("net: no such interface")
-}
diff --git a/src/pkg/net/interface_bsd.go b/src/pkg/net/interface_bsd.go
deleted file mode 100644
index a4c3e71fe..000000000
--- a/src/pkg/net/interface_bsd.go
+++ /dev/null
@@ -1,172 +0,0 @@
-// 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 BSD variants
-
-package net
-
-import (
- "os"
- "syscall"
- "unsafe"
-)
-
-// If the ifindex is zero, interfaceTable returns mappings of all
-// network interfaces. Otheriwse it returns a mapping of a specific
-// interface.
-func interfaceTable(ifindex int) ([]Interface, os.Error) {
- var (
- tab []byte
- e int
- msgs []syscall.RoutingMessage
- ift []Interface
- )
-
- tab, e = syscall.RouteRIB(syscall.NET_RT_IFLIST, ifindex)
- if e != 0 {
- return nil, os.NewSyscallError("route rib", e)
- }
-
- msgs, e = syscall.ParseRoutingMessage(tab)
- if e != 0 {
- return nil, os.NewSyscallError("route message", e)
- }
-
- for _, m := range msgs {
- switch v := m.(type) {
- case *syscall.InterfaceMessage:
- if ifindex == 0 || ifindex == int(v.Header.Index) {
- ifi, err := newLink(v)
- if err != nil {
- return nil, err
- }
- ift = append(ift, ifi...)
- }
- }
- }
-
- return ift, nil
-}
-
-func newLink(m *syscall.InterfaceMessage) ([]Interface, os.Error) {
- var ift []Interface
-
- sas, e := syscall.ParseRoutingSockaddr(m)
- if e != 0 {
- return nil, os.NewSyscallError("route sockaddr", e)
- }
-
- for _, s := range sas {
- switch v := s.(type) {
- case *syscall.SockaddrDatalink:
- // NOTE: SockaddrDatalink.Data is minimum work area,
- // can be larger.
- m.Data = m.Data[unsafe.Offsetof(v.Data):]
- ifi := Interface{Index: int(m.Header.Index), Flags: linkFlags(m.Header.Flags)}
- var name [syscall.IFNAMSIZ]byte
- for i := 0; i < int(v.Nlen); i++ {
- name[i] = byte(m.Data[i])
- }
- ifi.Name = string(name[:v.Nlen])
- ifi.MTU = int(m.Header.Data.Mtu)
- addr := make([]byte, v.Alen)
- for i := 0; i < int(v.Alen); i++ {
- addr[i] = byte(m.Data[int(v.Nlen)+i])
- }
- ifi.HardwareAddr = addr[:v.Alen]
- ift = append(ift, ifi)
- }
- }
-
- return ift, nil
-}
-
-func linkFlags(rawFlags int32) Flags {
- var f Flags
- if rawFlags&syscall.IFF_UP != 0 {
- f |= FlagUp
- }
- if rawFlags&syscall.IFF_BROADCAST != 0 {
- f |= FlagBroadcast
- }
- if rawFlags&syscall.IFF_LOOPBACK != 0 {
- f |= FlagLoopback
- }
- if rawFlags&syscall.IFF_POINTOPOINT != 0 {
- f |= FlagPointToPoint
- }
- if rawFlags&syscall.IFF_MULTICAST != 0 {
- f |= FlagMulticast
- }
- return f
-}
-
-// If the ifindex is zero, interfaceAddrTable returns addresses
-// for all network interfaces. Otherwise it returns addresses
-// for a specific interface.
-func interfaceAddrTable(ifindex int) ([]Addr, os.Error) {
- var (
- tab []byte
- e int
- msgs []syscall.RoutingMessage
- ifat []Addr
- )
-
- tab, e = syscall.RouteRIB(syscall.NET_RT_IFLIST, ifindex)
- if e != 0 {
- return nil, os.NewSyscallError("route rib", e)
- }
-
- msgs, e = syscall.ParseRoutingMessage(tab)
- if e != 0 {
- return nil, os.NewSyscallError("route message", e)
- }
-
- for _, m := range msgs {
- switch v := m.(type) {
- case *syscall.InterfaceAddrMessage:
- if ifindex == 0 || ifindex == int(v.Header.Index) {
- ifa, err := newAddr(v)
- if err != nil {
- return nil, err
- }
- ifat = append(ifat, ifa...)
- }
- }
- }
-
- return ifat, nil
-}
-
-func newAddr(m *syscall.InterfaceAddrMessage) ([]Addr, os.Error) {
- var ifat []Addr
-
- sas, e := syscall.ParseRoutingSockaddr(m)
- if e != 0 {
- return nil, os.NewSyscallError("route sockaddr", e)
- }
-
- for _, s := range sas {
- var ifa IPAddr
- switch v := s.(type) {
- case *syscall.SockaddrInet4:
- ifa.IP = IPv4(v.Addr[0], v.Addr[1], v.Addr[2], v.Addr[3])
- case *syscall.SockaddrInet6:
- 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() ||
- ifa.IP.IsInterfaceLocalMulticast() ||
- ifa.IP.IsLinkLocalMulticast() {
- // remove embedded scope zone ID
- ifa.IP[2], ifa.IP[3] = 0, 0
- }
- }
- ifat = append(ifat, ifa.toAddr())
- }
-
- return ifat, nil
-}
diff --git a/src/pkg/net/interface_linux.go b/src/pkg/net/interface_linux.go
deleted file mode 100644
index e869cd630..000000000
--- a/src/pkg/net/interface_linux.go
+++ /dev/null
@@ -1,185 +0,0 @@
-// 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 Linux
-
-package net
-
-import (
- "os"
- "syscall"
- "unsafe"
-)
-
-// If the ifindex is zero, interfaceTable returns mappings of all
-// network interfaces. Otheriwse it returns a mapping of a specific
-// interface.
-func interfaceTable(ifindex int) ([]Interface, os.Error) {
- var (
- ift []Interface
- tab []byte
- msgs []syscall.NetlinkMessage
- e int
- )
-
- tab, e = syscall.NetlinkRIB(syscall.RTM_GETLINK, syscall.AF_UNSPEC)
- if e != 0 {
- return nil, os.NewSyscallError("netlink rib", e)
- }
-
- msgs, e = syscall.ParseNetlinkMessage(tab)
- if e != 0 {
- return nil, os.NewSyscallError("netlink message", e)
- }
-
- for _, m := range msgs {
- switch m.Header.Type {
- case syscall.NLMSG_DONE:
- goto done
- 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 != 0 {
- return nil, os.NewSyscallError("netlink routeattr", e)
- }
- ifi := newLink(attrs, ifim)
- ift = append(ift, ifi)
- }
- }
- }
-
-done:
- return ift, nil
-}
-
-func newLink(attrs []syscall.NetlinkRouteAttr, ifim *syscall.IfInfomsg) Interface {
- ifi := Interface{Index: int(ifim.Index), Flags: linkFlags(ifim.Flags)}
- for _, a := range attrs {
- switch a.Attr.Type {
- case syscall.IFLA_ADDRESS:
- var nonzero bool
- for _, b := range a.Value {
- if b != 0 {
- nonzero = true
- }
- }
- if nonzero {
- ifi.HardwareAddr = a.Value[:]
- }
- case syscall.IFLA_IFNAME:
- ifi.Name = string(a.Value[:len(a.Value)-1])
- case syscall.IFLA_MTU:
- ifi.MTU = int(uint32(a.Value[3])<<24 | uint32(a.Value[2])<<16 | uint32(a.Value[1])<<8 | uint32(a.Value[0]))
- }
- }
- return ifi
-}
-
-func linkFlags(rawFlags uint32) Flags {
- var f Flags
- if rawFlags&syscall.IFF_UP != 0 {
- f |= FlagUp
- }
- if rawFlags&syscall.IFF_BROADCAST != 0 {
- f |= FlagBroadcast
- }
- if rawFlags&syscall.IFF_LOOPBACK != 0 {
- f |= FlagLoopback
- }
- if rawFlags&syscall.IFF_POINTOPOINT != 0 {
- f |= FlagPointToPoint
- }
- if rawFlags&syscall.IFF_MULTICAST != 0 {
- f |= FlagMulticast
- }
- return f
-}
-
-// If the ifindex is zero, interfaceAddrTable returns addresses
-// for all network interfaces. Otherwise it returns addresses
-// for a specific interface.
-func interfaceAddrTable(ifindex int) ([]Addr, os.Error) {
- var (
- ifat4 []Addr
- ifat6 []Addr
- tab []byte
- msgs4 []syscall.NetlinkMessage
- msgs6 []syscall.NetlinkMessage
- e int
- err os.Error
- )
-
- tab, e = syscall.NetlinkRIB(syscall.RTM_GETADDR, syscall.AF_INET)
- if e != 0 {
- return nil, os.NewSyscallError("netlink rib", e)
- }
- msgs4, e = syscall.ParseNetlinkMessage(tab)
- if e != 0 {
- return nil, os.NewSyscallError("netlink message", e)
- }
- ifat4, err = addrTable(msgs4, ifindex)
- if err != nil {
- return nil, err
- }
-
- tab, e = syscall.NetlinkRIB(syscall.RTM_GETADDR, syscall.AF_INET6)
- if e != 0 {
- return nil, os.NewSyscallError("netlink rib", e)
- }
- msgs6, e = syscall.ParseNetlinkMessage(tab)
- if e != 0 {
- return nil, os.NewSyscallError("netlink message", e)
- }
- ifat6, err = addrTable(msgs6, ifindex)
- if err != nil {
- return nil, err
- }
-
- return append(ifat4, ifat6...), nil
-}
-
-func addrTable(msgs []syscall.NetlinkMessage, ifindex int) ([]Addr, os.Error) {
- var ifat []Addr
-
- for _, m := range msgs {
- switch m.Header.Type {
- case syscall.NLMSG_DONE:
- goto done
- 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 != 0 {
- return nil, os.NewSyscallError("netlink routeattr", e)
- }
- ifat = append(ifat, newAddr(attrs, int(ifam.Family))...)
- }
- }
- }
-
-done:
- return ifat, nil
-}
-
-func newAddr(attrs []syscall.NetlinkRouteAttr, family int) []Addr {
- var ifat []Addr
-
- for _, a := range attrs {
- switch a.Attr.Type {
- case syscall.IFA_ADDRESS:
- ifa := IPAddr{}
- switch family {
- case syscall.AF_INET:
- ifa.IP = IPv4(a.Value[0], a.Value[1], a.Value[2], a.Value[3])
- case syscall.AF_INET6:
- ifa.IP = make(IP, IPv6len)
- copy(ifa.IP, a.Value[:])
- }
- ifat = append(ifat, ifa.toAddr())
- }
- }
-
- return ifat
-}
diff --git a/src/pkg/net/interface_stub.go b/src/pkg/net/interface_stub.go
deleted file mode 100644
index 24a7431c5..000000000
--- a/src/pkg/net/interface_stub.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// 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
-
-package net
-
-import "os"
-
-// If the ifindex is zero, interfaceTable returns mappings of all
-// network interfaces. Otheriwse it returns a mapping of a specific
-// interface.
-func interfaceTable(ifindex int) ([]Interface, os.Error) {
- return nil, nil
-}
-
-// If the ifindex is zero, interfaceAddrTable returns addresses
-// for all network interfaces. Otherwise it returns addresses
-// for a specific interface.
-func interfaceAddrTable(ifindex int) ([]Addr, os.Error) {
- return nil, nil
-}
diff --git a/src/pkg/net/interface_test.go b/src/pkg/net/interface_test.go
deleted file mode 100644
index ac523a049..000000000
--- a/src/pkg/net/interface_test.go
+++ /dev/null
@@ -1,66 +0,0 @@
-// 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 (
- "bytes"
- "testing"
-)
-
-func sameInterface(i, j *Interface) bool {
- if i == nil || j == nil {
- return false
- }
- if i.Index == j.Index && i.Name == j.Name && bytes.Equal(i.HardwareAddr, j.HardwareAddr) {
- return true
- }
- return false
-}
-
-func TestInterfaces(t *testing.T) {
- ift, err := Interfaces()
- if err != nil {
- t.Fatalf("Interfaces() failed: %v", err)
- }
- t.Logf("table: len/cap = %v/%v\n", len(ift), cap(ift))
-
- for _, ifi := range ift {
- ifxi, err := InterfaceByIndex(ifi.Index)
- if err != nil {
- t.Fatalf("InterfaceByIndex(%#q) failed: %v", ifi.Index, err)
- }
- if !sameInterface(ifxi, &ifi) {
- t.Fatalf("InterfaceByIndex(%#q) = %v, want %v", ifi.Index, *ifxi, ifi)
- }
- ifxn, err := InterfaceByName(ifi.Name)
- if err != nil {
- t.Fatalf("InterfaceByName(%#q) failed: %v", ifi.Name, err)
- }
- 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)
- }
- 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())
- }
- t.Logf("\thardware address %q", ifi.HardwareAddr.String())
- }
-}
-
-func TestInterfaceAddrs(t *testing.T) {
- ifat, err := InterfaceAddrs()
- if err != nil {
- t.Fatalf("InterfaceAddrs() failed: %v", err)
- }
- t.Logf("table: len/cap = %v/%v\n", len(ifat), cap(ifat))
-
- for _, ifa := range ifat {
- t.Logf("interface address %q\n", ifa.String())
- }
-}
diff --git a/src/pkg/net/interface_windows.go b/src/pkg/net/interface_windows.go
deleted file mode 100644
index 198e4096f..000000000
--- a/src/pkg/net/interface_windows.go
+++ /dev/null
@@ -1,152 +0,0 @@
-// 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 Windows
-
-package net
-
-import (
- "os"
- "syscall"
- "unsafe"
-)
-
-func bytePtrToString(p *uint8) string {
- a := (*[10000]uint8)(unsafe.Pointer(p))
- i := 0
- for a[i] != 0 {
- i++
- }
- return string(a[:i])
-}
-
-func getAdapterList() (*syscall.IpAdapterInfo, os.Error) {
- b := make([]byte, 1000)
- l := uint32(len(b))
- a := (*syscall.IpAdapterInfo)(unsafe.Pointer(&b[0]))
- e := syscall.GetAdaptersInfo(a, &l)
- if e == syscall.ERROR_BUFFER_OVERFLOW {
- b = make([]byte, l)
- a = (*syscall.IpAdapterInfo)(unsafe.Pointer(&b[0]))
- e = syscall.GetAdaptersInfo(a, &l)
- }
- if e != 0 {
- return nil, os.NewSyscallError("GetAdaptersInfo", e)
- }
- return a, nil
-}
-
-func getInterfaceList() ([]syscall.InterfaceInfo, os.Error) {
- s, e := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP)
- if e != 0 {
- return nil, os.NewSyscallError("Socket", e)
- }
- defer syscall.Closesocket(s)
-
- ii := [20]syscall.InterfaceInfo{}
- ret := uint32(0)
- size := uint32(unsafe.Sizeof(ii))
- e = syscall.WSAIoctl(s, syscall.SIO_GET_INTERFACE_LIST, nil, 0, (*byte)(unsafe.Pointer(&ii[0])), size, &ret, nil, 0)
- if e != 0 {
- return nil, os.NewSyscallError("WSAIoctl", e)
- }
- c := ret / uint32(unsafe.Sizeof(ii[0]))
- return ii[:c-1], nil
-}
-
-
-// If the ifindex is zero, interfaceTable returns mappings of all
-// network interfaces. Otheriwse it returns a mapping of a specific
-// interface.
-func interfaceTable(ifindex int) ([]Interface, os.Error) {
- ai, e := getAdapterList()
- if e != nil {
- return nil, e
- }
-
- ii, e := getInterfaceList()
- if e != nil {
- return nil, e
- }
-
- var ift []Interface
- for ; ai != nil; ai = ai.Next {
- index := ai.Index
- if ifindex == 0 || ifindex == int(index) {
- var flags Flags
-
- row := syscall.MibIfRow{Index: index}
- e := syscall.GetIfEntry(&row)
- if e != 0 {
- return nil, os.NewSyscallError("GetIfEntry", e)
- }
-
- for _, ii := range ii {
- ip := (*syscall.RawSockaddrInet4)(unsafe.Pointer(&ii.Address)).Addr
- ipv4 := IPv4(ip[0], ip[1], ip[2], ip[3])
- ipl := &ai.IpAddressList
- for ipl != nil {
- ips := bytePtrToString(&ipl.IpAddress.String[0])
- if ipv4.Equal(parseIPv4(ips)) {
- break
- }
- ipl = ipl.Next
- }
- if ipl == nil {
- continue
- }
- if ii.Flags&syscall.IFF_UP != 0 {
- flags |= FlagUp
- }
- if ii.Flags&syscall.IFF_LOOPBACK != 0 {
- flags |= FlagLoopback
- }
- if ii.Flags&syscall.IFF_BROADCAST != 0 {
- flags |= FlagBroadcast
- }
- if ii.Flags&syscall.IFF_POINTTOPOINT != 0 {
- flags |= FlagPointToPoint
- }
- if ii.Flags&syscall.IFF_MULTICAST != 0 {
- flags |= FlagMulticast
- }
- }
-
- name := bytePtrToString(&ai.AdapterName[0])
-
- ifi := Interface{
- Index: int(index),
- MTU: int(row.Mtu),
- Name: name,
- HardwareAddr: HardwareAddr(row.PhysAddr[:row.PhysAddrLen]),
- Flags: flags}
- ift = append(ift, ifi)
- }
- }
- return ift, nil
-}
-
-// If the ifindex is zero, interfaceAddrTable returns addresses
-// for all network interfaces. Otherwise it returns addresses
-// for a specific interface.
-func interfaceAddrTable(ifindex int) ([]Addr, os.Error) {
- ai, e := getAdapterList()
- if e != nil {
- return nil, e
- }
-
- var ifat []Addr
- for ; ai != nil; ai = ai.Next {
- index := ai.Index
- if ifindex == 0 || ifindex == int(index) {
- ipl := &ai.IpAddressList
- for ; ipl != nil; ipl = ipl.Next {
- ifa := IPAddr{}
- ifa.IP = parseIPv4(bytePtrToString(&ipl.IpAddress.String[0]))
- ifat = append(ifat, ifa.toAddr())
- }
- }
- }
- return ifat, nil
-}
diff --git a/src/pkg/net/ip.go b/src/pkg/net/ip.go
deleted file mode 100644
index b0e2c4205..000000000
--- a/src/pkg/net/ip.go
+++ /dev/null
@@ -1,614 +0,0 @@
-// 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.
-
-// IP address manipulations
-//
-// IPv4 addresses are 4 bytes; IPv6 addresses are 16 bytes.
-// An IPv4 address can be converted to an IPv6 address by
-// adding a canonical prefix (10 zeros, 2 0xFFs).
-// This library accepts either size of byte array but always
-// returns 16-byte addresses.
-
-package net
-
-import "os"
-
-// IP address lengths (bytes).
-const (
- IPv4len = 4
- IPv6len = 16
-)
-
-// An IP is a single IP address, an array of bytes.
-// Functions in this package accept either 4-byte (IP v4)
-// or 16-byte (IP v6) arrays as input. Unless otherwise
-// specified, functions in this package always return
-// IP addresses in 16-byte form using the canonical
-// embedding.
-//
-// Note that in this documentation, referring to an
-// IP address as an IPv4 address or an IPv6 address
-// is a semantic property of the address, not just the
-// length of the byte array: a 16-byte array can still
-// be an IPv4 address.
-type IP []byte
-
-// An IP mask is an IP address.
-type IPMask []byte
-
-// IPv4 returns the IP address (in 16-byte form) of the
-// IPv4 address a.b.c.d.
-func IPv4(a, b, c, d byte) IP {
- p := make(IP, IPv6len)
- copy(p, v4InV6Prefix)
- p[12] = a
- p[13] = b
- p[14] = c
- p[15] = d
- return p
-}
-
-var v4InV6Prefix = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}
-
-// IPv4Mask returns the IP mask (in 16-byte form) of the
-// IPv4 mask a.b.c.d.
-func IPv4Mask(a, b, c, d byte) IPMask {
- p := make(IPMask, IPv6len)
- for i := 0; i < 12; i++ {
- p[i] = 0xff
- }
- p[12] = a
- p[13] = b
- p[14] = c
- p[15] = d
- return p
-}
-
-// Well-known IPv4 addresses
-var (
- IPv4bcast = IPv4(255, 255, 255, 255) // broadcast
- IPv4allsys = IPv4(224, 0, 0, 1) // all systems
- IPv4allrouter = IPv4(224, 0, 0, 2) // all routers
- IPv4zero = IPv4(0, 0, 0, 0) // all zeros
-)
-
-// Well-known IPv6 addresses
-var (
- IPv6zero = IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- IPv6unspecified = IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- IPv6loopback = IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
- IPv6interfacelocalallnodes = IP{0xff, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}
- IPv6linklocalallnodes = IP{0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}
- IPv6linklocalallrouters = IP{0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x02}
-)
-
-// IsUnspecified returns true if ip is an unspecified address.
-func (ip IP) IsUnspecified() bool {
- if ip.Equal(IPv4zero) || ip.Equal(IPv6unspecified) {
- return true
- }
- return false
-}
-
-// IsLoopback returns true if ip is a loopback address.
-func (ip IP) IsLoopback() bool {
- if ip4 := ip.To4(); ip4 != nil && ip4[0] == 127 {
- return true
- }
- return ip.Equal(IPv6loopback)
-}
-
-// IsMulticast returns true if ip is a multicast address.
-func (ip IP) IsMulticast() bool {
- if ip4 := ip.To4(); ip4 != nil && ip4[0]&0xf0 == 0xe0 {
- return true
- }
- return ip[0] == 0xff
-}
-
-// IsInterfaceLinkLocalMulticast returns true if ip is
-// an interface-local multicast address.
-func (ip IP) IsInterfaceLocalMulticast() bool {
- return len(ip) == IPv6len && ip[0] == 0xff && ip[1]&0x0f == 0x01
-}
-
-// IsLinkLocalMulticast returns true if ip is a link-local
-// multicast address.
-func (ip IP) IsLinkLocalMulticast() bool {
- if ip4 := ip.To4(); ip4 != nil && ip4[0] == 224 && ip4[1] == 0 && ip4[2] == 0 {
- return true
- }
- return ip[0] == 0xff && ip[1]&0x0f == 0x02
-}
-
-// IsLinkLocalUnicast returns true if ip is a link-local
-// unicast address.
-func (ip IP) IsLinkLocalUnicast() bool {
- if ip4 := ip.To4(); ip4 != nil && ip4[0] == 169 && ip4[1] == 254 {
- return true
- }
- return ip[0] == 0xfe && ip[1]&0xc0 == 0x80
-}
-
-// IsGlobalUnicast returns true if ip is a global unicast
-// address.
-func (ip IP) IsGlobalUnicast() bool {
- return !ip.IsUnspecified() &&
- !ip.IsLoopback() &&
- !ip.IsMulticast() &&
- !ip.IsLinkLocalUnicast()
-}
-
-// Is p all zeros?
-func isZeros(p IP) bool {
- for i := 0; i < len(p); i++ {
- if p[i] != 0 {
- return false
- }
- }
- return true
-}
-
-// To4 converts the IPv4 address ip to a 4-byte representation.
-// If ip is not an IPv4 address, To4 returns nil.
-func (ip IP) To4() IP {
- if len(ip) == IPv4len {
- return ip
- }
- if len(ip) == IPv6len &&
- isZeros(ip[0:10]) &&
- ip[10] == 0xff &&
- ip[11] == 0xff {
- return ip[12:16]
- }
- return nil
-}
-
-// To16 converts the IP address ip to a 16-byte representation.
-// If ip is not an IP address (it is the wrong length), To16 returns nil.
-func (ip IP) To16() IP {
- if len(ip) == IPv4len {
- return IPv4(ip[0], ip[1], ip[2], ip[3])
- }
- if len(ip) == IPv6len {
- return ip
- }
- return nil
-}
-
-// Default route masks for IPv4.
-var (
- classAMask = IPv4Mask(0xff, 0, 0, 0)
- classBMask = IPv4Mask(0xff, 0xff, 0, 0)
- classCMask = IPv4Mask(0xff, 0xff, 0xff, 0)
-)
-
-// DefaultMask returns the default IP mask for the IP address ip.
-// Only IPv4 addresses have default masks; DefaultMask returns
-// nil if ip is not a valid IPv4 address.
-func (ip IP) DefaultMask() IPMask {
- if ip = ip.To4(); ip == nil {
- return nil
- }
- switch true {
- case ip[0] < 0x80:
- return classAMask
- case ip[0] < 0xC0:
- return classBMask
- default:
- return classCMask
- }
- return nil // not reached
-}
-
-func allFF(b []byte) bool {
- for _, c := range b {
- if c != 0xff {
- return false
- }
- }
- return true
-}
-
-// Mask returns the result of masking the IP address ip with mask.
-func (ip IP) Mask(mask IPMask) IP {
- n := len(ip)
- if len(mask) == 16 && len(ip) == 4 && allFF(mask[:12]) {
- mask = mask[12:]
- }
- if len(mask) == 4 && len(ip) == 16 && bytesEqual(ip[:12], v4InV6Prefix) {
- ip = ip[12:]
- }
- if n != len(mask) {
- return nil
- }
- out := make(IP, n)
- for i := 0; i < n; i++ {
- out[i] = ip[i] & mask[i]
- }
- return out
-}
-
-// Convert i to decimal string.
-func itod(i uint) string {
- if i == 0 {
- return "0"
- }
-
- // Assemble decimal in reverse order.
- var b [32]byte
- bp := len(b)
- for ; i > 0; i /= 10 {
- bp--
- b[bp] = byte(i%10) + '0'
- }
-
- return string(b[bp:])
-}
-
-// Convert i to hexadecimal string.
-func itox(i uint) string {
- if i == 0 {
- return "0"
- }
-
- // Assemble hexadecimal in reverse order.
- var b [32]byte
- bp := len(b)
- for ; i > 0; i /= 16 {
- bp--
- b[bp] = "0123456789abcdef"[byte(i%16)]
- }
-
- return string(b[bp:])
-}
-
-// String returns the string form of the IP address ip.
-// If the address is an IPv4 address, the string representation
-// is dotted decimal ("74.125.19.99"). Otherwise the representation
-// is IPv6 ("2001:4860:0:2001::68").
-func (ip IP) String() string {
- p := ip
-
- if len(ip) == 0 {
- return ""
- }
-
- // If IPv4, use dotted notation.
- if p4 := p.To4(); len(p4) == 4 {
- return itod(uint(p4[0])) + "." +
- itod(uint(p4[1])) + "." +
- itod(uint(p4[2])) + "." +
- itod(uint(p4[3]))
- }
- if len(p) != IPv6len {
- return "?"
- }
-
- // Find longest run of zeros.
- e0 := -1
- e1 := -1
- for i := 0; i < 16; i += 2 {
- j := i
- for j < 16 && p[j] == 0 && p[j+1] == 0 {
- j += 2
- }
- if j > i && j-i > e1-e0 {
- e0 = i
- e1 = j
- }
- }
- // The symbol "::" MUST NOT be used to shorten just one 16 bit 0 field.
- if e1-e0 <= 2 {
- e0 = -1
- e1 = -1
- }
-
- // Print with possible :: in place of run of zeros
- var s string
- for i := 0; i < 16; i += 2 {
- if i == e0 {
- s += "::"
- i = e1
- if i >= 16 {
- break
- }
- } else if i > 0 {
- s += ":"
- }
- s += itox((uint(p[i]) << 8) | uint(p[i+1]))
- }
- return s
-}
-
-// Equal returns true if ip and x are the same IP address.
-// An IPv4 address and that same address in IPv6 form are
-// considered to be equal.
-func (ip IP) Equal(x IP) bool {
- if len(ip) == len(x) {
- return bytesEqual(ip, x)
- }
- if len(ip) == 4 && len(x) == 16 {
- return bytesEqual(x[0:12], v4InV6Prefix) && bytesEqual(ip, x[12:])
- }
- if len(ip) == 16 && len(x) == 4 {
- return bytesEqual(ip[0:12], v4InV6Prefix) && bytesEqual(ip[12:], x)
- }
- return false
-}
-
-func bytesEqual(x, y []byte) bool {
- if len(x) != len(y) {
- return false
- }
- for i, b := range x {
- if y[i] != b {
- return false
- }
- }
- return true
-}
-
-// If mask is a sequence of 1 bits followed by 0 bits,
-// return the number of 1 bits.
-func simpleMaskLength(mask IPMask) int {
- var n int
- for i, v := range mask {
- if v == 0xff {
- n += 8
- continue
- }
- // found non-ff byte
- // count 1 bits
- for v&0x80 != 0 {
- n++
- v <<= 1
- }
- // rest must be 0 bits
- if v != 0 {
- return -1
- }
- for i++; i < len(mask); i++ {
- if mask[i] != 0 {
- return -1
- }
- }
- break
- }
- return n
-}
-
-// String returns the string representation of mask.
-// If the mask is in the canonical form--ones followed by zeros--the
-// string representation is just the decimal number of ones.
-// If the mask is in a non-canonical form, it is formatted
-// as an IP address.
-func (mask IPMask) String() string {
- switch len(mask) {
- case 4:
- n := simpleMaskLength(mask)
- if n >= 0 {
- return itod(uint(n + (IPv6len-IPv4len)*8))
- }
- case 16:
- n := simpleMaskLength(mask)
- if n >= 12*8 {
- return itod(uint(n - 12*8))
- }
- }
- return IP(mask).String()
-}
-
-// Parse IPv4 address (d.d.d.d).
-func parseIPv4(s string) IP {
- var p [IPv4len]byte
- i := 0
- for j := 0; j < IPv4len; j++ {
- if i >= len(s) {
- // Missing octets.
- return nil
- }
- if j > 0 {
- if s[i] != '.' {
- return nil
- }
- i++
- }
- var (
- n int
- ok bool
- )
- n, i, ok = dtoi(s, i)
- if !ok || n > 0xFF {
- return nil
- }
- p[j] = byte(n)
- }
- if i != len(s) {
- return nil
- }
- return IPv4(p[0], p[1], p[2], p[3])
-}
-
-// Parse IPv6 address. Many forms.
-// The basic form is a sequence of eight colon-separated
-// 16-bit hex numbers separated by colons,
-// as in 0123:4567:89ab:cdef:0123:4567:89ab:cdef.
-// Two exceptions:
-// * A run of zeros can be replaced with "::".
-// * The last 32 bits can be in IPv4 form.
-// Thus, ::ffff:1.2.3.4 is the IPv4 address 1.2.3.4.
-func parseIPv6(s string) IP {
- p := make(IP, 16)
- ellipsis := -1 // position of ellipsis in p
- i := 0 // index in string s
-
- // Might have leading ellipsis
- if len(s) >= 2 && s[0] == ':' && s[1] == ':' {
- ellipsis = 0
- i = 2
- // Might be only ellipsis
- if i == len(s) {
- return p
- }
- }
-
- // Loop, parsing hex numbers followed by colon.
- j := 0
- for j < IPv6len {
- // Hex number.
- n, i1, ok := xtoi(s, i)
- if !ok || n > 0xFFFF {
- return nil
- }
-
- // If followed by dot, might be in trailing IPv4.
- if i1 < len(s) && s[i1] == '.' {
- if ellipsis < 0 && j != IPv6len-IPv4len {
- // Not the right place.
- return nil
- }
- if j+IPv4len > IPv6len {
- // Not enough room.
- return nil
- }
- p4 := parseIPv4(s[i:])
- if p4 == nil {
- return nil
- }
- p[j] = p4[12]
- p[j+1] = p4[13]
- p[j+2] = p4[14]
- p[j+3] = p4[15]
- i = len(s)
- j += 4
- break
- }
-
- // Save this 16-bit chunk.
- p[j] = byte(n >> 8)
- p[j+1] = byte(n)
- j += 2
-
- // Stop at end of string.
- i = i1
- if i == len(s) {
- break
- }
-
- // Otherwise must be followed by colon and more.
- if s[i] != ':' || i+1 == len(s) {
- return nil
- }
- i++
-
- // Look for ellipsis.
- if s[i] == ':' {
- if ellipsis >= 0 { // already have one
- return nil
- }
- ellipsis = j
- if i++; i == len(s) { // can be at end
- break
- }
- }
- }
-
- // Must have used entire string.
- if i != len(s) {
- return nil
- }
-
- // If didn't parse enough, expand ellipsis.
- if j < IPv6len {
- if ellipsis < 0 {
- return nil
- }
- n := IPv6len - j
- for k := j - 1; k >= ellipsis; k-- {
- p[k+n] = p[k]
- }
- for k := ellipsis + n - 1; k >= ellipsis; k-- {
- p[k] = 0
- }
- }
- return p
-}
-
-// A ParseError represents a malformed text string and the type of string that was expected.
-type ParseError struct {
- Type string
- Text string
-}
-
-func (e *ParseError) String() string {
- return "invalid " + e.Type + ": " + e.Text
-}
-
-func parseIP(s string) IP {
- if p := parseIPv4(s); p != nil {
- return p
- }
- if p := parseIPv6(s); p != nil {
- return p
- }
- return nil
-}
-
-// ParseIP parses s as an IP address, returning the result.
-// The string s can be in dotted decimal ("74.125.19.99")
-// or IPv6 ("2001:4860:0:2001::68") form.
-// If s is not a valid textual representation of an IP address,
-// ParseIP returns nil.
-func ParseIP(s string) IP {
- if p := parseIPv4(s); p != nil {
- return p
- }
- return parseIPv6(s)
-}
-
-// ParseCIDR parses s as a CIDR notation IP address and mask,
-// like "192.168.100.1/24", "2001:DB8::/48", as defined in
-// RFC 4632 and RFC 4291.
-func ParseCIDR(s string) (ip IP, mask IPMask, err os.Error) {
- i := byteIndex(s, '/')
- if i < 0 {
- return nil, nil, &ParseError{"CIDR address", s}
- }
- ipstr, maskstr := s[:i], s[i+1:]
- iplen := 4
- ip = parseIPv4(ipstr)
- if ip == nil {
- iplen = 16
- ip = parseIPv6(ipstr)
- }
- nn, i, ok := dtoi(maskstr, 0)
- if ip == nil || !ok || i != len(maskstr) || nn < 0 || nn > 8*iplen {
- return nil, nil, &ParseError{"CIDR address", s}
- }
- n := uint(nn)
- if iplen == 4 {
- v4mask := ^uint32(0xffffffff >> n)
- mask = IPv4Mask(byte(v4mask>>24), byte(v4mask>>16), byte(v4mask>>8), byte(v4mask))
- } else {
- mask = make(IPMask, 16)
- for i := 0; i < 16; i++ {
- if n >= 8 {
- mask[i] = 0xff
- n -= 8
- continue
- }
- mask[i] = ^byte(0xff >> n)
- n = 0
-
- }
- }
- // address must not have any bits not in mask
- for i := range ip {
- if ip[i]&^mask[i] != 0 {
- return nil, nil, &ParseError{"CIDR address", s}
- }
- }
- return ip, mask, nil
-}
diff --git a/src/pkg/net/ip_test.go b/src/pkg/net/ip_test.go
deleted file mode 100644
index b189b10c4..000000000
--- a/src/pkg/net/ip_test.go
+++ /dev/null
@@ -1,215 +0,0 @@
-// 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.
-
-package net
-
-import (
- "bytes"
- "reflect"
- "testing"
- "os"
- "runtime"
-)
-
-func isEqual(a, b []byte) bool {
- if a == nil && b == nil {
- return true
- }
- if a == nil || b == nil {
- return false
- }
- return bytes.Equal(a, b)
-}
-
-var parseiptests = []struct {
- in string
- out IP
-}{
- {"127.0.1.2", IPv4(127, 0, 1, 2)},
- {"127.0.0.1", IPv4(127, 0, 0, 1)},
- {"127.0.0.256", nil},
- {"abc", nil},
- {"123:", nil},
- {"::ffff:127.0.0.1", IPv4(127, 0, 0, 1)},
- {"2001:4860:0:2001::68", IP{0x20, 0x01, 0x48, 0x60, 0, 0, 0x20, 0x01, 0, 0, 0, 0, 0, 0, 0x00, 0x68}},
- {"::ffff:4a7d:1363", IPv4(74, 125, 19, 99)},
-}
-
-func TestParseIP(t *testing.T) {
- for _, tt := range parseiptests {
- if out := ParseIP(tt.in); !isEqual(out, tt.out) {
- t.Errorf("ParseIP(%#q) = %v, want %v", tt.in, out, tt.out)
- }
- }
-}
-
-var ipstringtests = []struct {
- in IP
- out string
-}{
- // cf. RFC 5952 (A Recommendation for IPv6 Address Text Representation)
- {IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0x1, 0x23, 0, 0x12, 0, 0x1},
- "2001:db8::123:12:1"},
- {IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1},
- "2001:db8::1"},
- {IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0x1, 0, 0, 0, 0x1, 0, 0, 0, 0x1},
- "2001:db8:0:1:0:1:0:1"},
- {IP{0x20, 0x1, 0xd, 0xb8, 0, 0x1, 0, 0, 0, 0x1, 0, 0, 0, 0x1, 0, 0},
- "2001:db8:1:0:1:0:1:0"},
- {IP{0x20, 0x1, 0, 0, 0, 0, 0, 0, 0, 0x1, 0, 0, 0, 0, 0, 0x1},
- "2001::1:0:0:1"},
- {IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0x1, 0, 0, 0, 0, 0, 0},
- "2001:db8:0:0:1::"},
- {IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0x1, 0, 0, 0, 0, 0, 0x1},
- "2001:db8::1:0:0:1"},
- {IP{0x20, 0x1, 0xD, 0xB8, 0, 0, 0, 0, 0, 0xA, 0, 0xB, 0, 0xC, 0, 0xD},
- "2001:db8::a:b:c:d"},
-}
-
-func TestIPString(t *testing.T) {
- for _, tt := range ipstringtests {
- if out := tt.in.String(); out != tt.out {
- t.Errorf("IP.String(%v) = %#q, want %#q", tt.in, out, tt.out)
- }
- }
-}
-
-var parsecidrtests = []struct {
- in string
- ip IP
- mask IPMask
- err os.Error
-}{
- {"135.104.0.0/32", IPv4(135, 104, 0, 0), IPv4Mask(255, 255, 255, 255), nil},
- {"0.0.0.0/24", IPv4(0, 0, 0, 0), IPv4Mask(255, 255, 255, 0), nil},
- {"135.104.0.0/24", IPv4(135, 104, 0, 0), IPv4Mask(255, 255, 255, 0), nil},
- {"135.104.0.1/32", IPv4(135, 104, 0, 1), IPv4Mask(255, 255, 255, 255), nil},
- {"135.104.0.1/24", nil, nil, &ParseError{"CIDR address", "135.104.0.1/24"}},
- {"::1/128", ParseIP("::1"), IPMask(ParseIP("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")), nil},
- {"abcd:2345::/127", ParseIP("abcd:2345::"), IPMask(ParseIP("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe")), nil},
- {"abcd:2345::/65", ParseIP("abcd:2345::"), IPMask(ParseIP("ffff:ffff:ffff:ffff:8000::")), nil},
- {"abcd:2345::/64", ParseIP("abcd:2345::"), IPMask(ParseIP("ffff:ffff:ffff:ffff::")), nil},
- {"abcd:2345::/63", ParseIP("abcd:2345::"), IPMask(ParseIP("ffff:ffff:ffff:fffe::")), nil},
- {"abcd:2345::/33", ParseIP("abcd:2345::"), IPMask(ParseIP("ffff:ffff:8000::")), nil},
- {"abcd:2345::/32", ParseIP("abcd:2345::"), IPMask(ParseIP("ffff:ffff::")), nil},
- {"abcd:2344::/31", ParseIP("abcd:2344::"), IPMask(ParseIP("ffff:fffe::")), nil},
- {"abcd:2300::/24", ParseIP("abcd:2300::"), IPMask(ParseIP("ffff:ff00::")), nil},
- {"abcd:2345::/24", nil, nil, &ParseError{"CIDR address", "abcd:2345::/24"}},
- {"2001:DB8::/48", ParseIP("2001:DB8::"), IPMask(ParseIP("ffff:ffff:ffff::")), nil},
-}
-
-func TestParseCIDR(t *testing.T) {
- for _, tt := range parsecidrtests {
- if ip, mask, err := ParseCIDR(tt.in); !isEqual(ip, tt.ip) || !isEqual(mask, tt.mask) || !reflect.DeepEqual(err, tt.err) {
- t.Errorf("ParseCIDR(%q) = %v, %v, %v; want %v, %v, %v", tt.in, ip, mask, err, tt.ip, tt.mask, tt.err)
- }
- }
-}
-
-var splitjointests = []struct {
- Host string
- Port string
- Join string
-}{
- {"www.google.com", "80", "www.google.com:80"},
- {"127.0.0.1", "1234", "127.0.0.1:1234"},
- {"::1", "80", "[::1]:80"},
-}
-
-func TestSplitHostPort(t *testing.T) {
- for _, tt := range splitjointests {
- if host, port, err := SplitHostPort(tt.Join); host != tt.Host || port != tt.Port || err != nil {
- t.Errorf("SplitHostPort(%q) = %q, %q, %v; want %q, %q, nil", tt.Join, host, port, err, tt.Host, tt.Port)
- }
- }
-}
-
-func TestJoinHostPort(t *testing.T) {
- for _, tt := range splitjointests {
- if join := JoinHostPort(tt.Host, tt.Port); join != tt.Join {
- t.Errorf("JoinHostPort(%q, %q) = %q; want %q", tt.Host, tt.Port, join, tt.Join)
- }
- }
-}
-
-var ipaftests = []struct {
- in IP
- af4 bool
- af6 bool
-}{
- {IPv4bcast, true, false},
- {IPv4allsys, true, false},
- {IPv4allrouter, true, false},
- {IPv4zero, true, false},
- {IPv4(224, 0, 0, 1), true, false},
- {IPv4(127, 0, 0, 1), true, false},
- {IPv4(240, 0, 0, 1), true, false},
- {IPv6unspecified, false, true},
- {IPv6loopback, false, true},
- {IPv6interfacelocalallnodes, false, true},
- {IPv6linklocalallnodes, false, true},
- {IPv6linklocalallrouters, false, true},
- {ParseIP("ff05::a:b:c:d"), false, true},
- {ParseIP("fe80::1:2:3:4"), false, true},
- {ParseIP("2001:db8::123:12:1"), false, true},
-}
-
-func TestIPAddrFamily(t *testing.T) {
- for _, tt := range ipaftests {
- if af := tt.in.To4() != nil; af != tt.af4 {
- t.Errorf("verifying IPv4 address family for %#q = %v, want %v", tt.in, af, tt.af4)
- }
- if af := len(tt.in) == IPv6len && tt.in.To4() == nil; af != tt.af6 {
- t.Errorf("verifying IPv6 address family for %#q = %v, want %v", tt.in, af, tt.af6)
- }
- }
-}
-
-var ipscopetests = []struct {
- scope func(IP) bool
- in IP
- ok bool
-}{
- {IP.IsUnspecified, IPv4zero, true},
- {IP.IsUnspecified, IPv4(127, 0, 0, 1), false},
- {IP.IsUnspecified, IPv6unspecified, true},
- {IP.IsUnspecified, IPv6interfacelocalallnodes, false},
- {IP.IsLoopback, IPv4(127, 0, 0, 1), true},
- {IP.IsLoopback, IPv4(127, 255, 255, 254), true},
- {IP.IsLoopback, IPv4(128, 1, 2, 3), false},
- {IP.IsLoopback, IPv6loopback, true},
- {IP.IsLoopback, IPv6linklocalallrouters, false},
- {IP.IsMulticast, IPv4(224, 0, 0, 0), true},
- {IP.IsMulticast, IPv4(239, 0, 0, 0), true},
- {IP.IsMulticast, IPv4(240, 0, 0, 0), false},
- {IP.IsMulticast, IPv6linklocalallnodes, true},
- {IP.IsMulticast, IP{0xff, 0x05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, true},
- {IP.IsMulticast, IP{0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
- {IP.IsLinkLocalMulticast, IPv4(224, 0, 0, 0), true},
- {IP.IsLinkLocalMulticast, IPv4(239, 0, 0, 0), false},
- {IP.IsLinkLocalMulticast, IPv6linklocalallrouters, true},
- {IP.IsLinkLocalMulticast, IP{0xff, 0x05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
- {IP.IsLinkLocalUnicast, IPv4(169, 254, 0, 0), true},
- {IP.IsLinkLocalUnicast, IPv4(169, 255, 0, 0), false},
- {IP.IsLinkLocalUnicast, IP{0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, true},
- {IP.IsLinkLocalUnicast, IP{0xfe, 0xc0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
- {IP.IsGlobalUnicast, IPv4(240, 0, 0, 0), true},
- {IP.IsGlobalUnicast, IPv4(232, 0, 0, 0), false},
- {IP.IsGlobalUnicast, IPv4(169, 254, 0, 0), false},
- {IP.IsGlobalUnicast, IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0x1, 0x23, 0, 0x12, 0, 0x1}, true},
- {IP.IsGlobalUnicast, IP{0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
- {IP.IsGlobalUnicast, IP{0xff, 0x05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
-}
-
-func name(f interface{}) string {
- return runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name()
-}
-
-func TestIPAddrScope(t *testing.T) {
- for _, tt := range ipscopetests {
- if ok := tt.scope(tt.in); ok != tt.ok {
- t.Errorf("%s(%#q) = %v, want %v", name(tt.scope), tt.in, ok, tt.ok)
- }
- }
-}
diff --git a/src/pkg/net/ipraw_test.go b/src/pkg/net/ipraw_test.go
deleted file mode 100644
index 7cc9604b5..000000000
--- a/src/pkg/net/ipraw_test.go
+++ /dev/null
@@ -1,121 +0,0 @@
-// 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.
-
-
-// TODO(cw): ListenPacket test, Read() test, ipv6 test &
-// Dial()/Listen() level tests
-
-package net
-
-import (
- "bytes"
- "flag"
- "os"
- "testing"
-)
-
-const ICMP_ECHO_REQUEST = 8
-const ICMP_ECHO_REPLY = 0
-
-// returns a suitable 'ping request' packet, with id & seq and a
-// payload length of pktlen
-func makePingRequest(id, seq, pktlen int, filler []byte) []byte {
- p := make([]byte, pktlen)
- copy(p[8:], bytes.Repeat(filler, (pktlen-8)/len(filler)+1))
-
- p[0] = ICMP_ECHO_REQUEST // type
- p[1] = 0 // code
- p[2] = 0 // cksum
- p[3] = 0 // cksum
- p[4] = uint8(id >> 8) // id
- p[5] = uint8(id & 0xff) // id
- p[6] = uint8(seq >> 8) // sequence
- p[7] = uint8(seq & 0xff) // sequence
-
- // calculate icmp checksum
- cklen := len(p)
- s := uint32(0)
- for i := 0; i < (cklen - 1); i += 2 {
- s += uint32(p[i+1])<<8 | uint32(p[i])
- }
- if cklen&1 == 1 {
- s += uint32(p[cklen-1])
- }
- s = (s >> 16) + (s & 0xffff)
- s = s + (s >> 16)
-
- // place checksum back in header; using ^= avoids the
- // assumption the checksum bytes are zero
- p[2] ^= uint8(^s & 0xff)
- p[3] ^= uint8(^s >> 8)
-
- return p
-}
-
-func parsePingReply(p []byte) (id, seq int) {
- id = int(p[4])<<8 | int(p[5])
- seq = int(p[6])<<8 | int(p[7])
- return
-}
-
-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")
-
-// test (raw) IP socket using ICMP
-func TestICMP(t *testing.T) {
- if os.Getuid() != 0 {
- t.Logf("test disabled; must be root")
- return
- }
-
- var (
- laddr *IPAddr
- err os.Error
- )
- if *srchost != "" {
- laddr, err = ResolveIPAddr("ip4", *srchost)
- if err != nil {
- t.Fatalf(`net.ResolveIPAddr("ip4", %v") = %v, %v`, *srchost, laddr, err)
- }
- }
-
- raddr, err := ResolveIPAddr("ip4", *dsthost)
- if err != nil {
- t.Fatalf(`net.ResolveIPAddr("ip4", %v") = %v, %v`, *dsthost, raddr, err)
- }
-
- c, err := ListenIP("ip4:icmp", laddr)
- if err != nil {
- t.Fatalf(`net.ListenIP("ip4:icmp", %v) = %v, %v`, *srchost, c, err)
- }
-
- sendid := os.Getpid() & 0xffff
- const sendseq = 61455
- const pingpktlen = 128
- sendpkt := makePingRequest(sendid, sendseq, pingpktlen, []byte("Go Go Gadget Ping!!!"))
-
- n, err := c.WriteToIP(sendpkt, raddr)
- if err != nil || n != pingpktlen {
- t.Fatalf(`net.WriteToIP(..., %v) = %v, %v`, raddr, n, err)
- }
-
- c.SetTimeout(100e6)
- resp := make([]byte, 1024)
- for {
- n, from, err := c.ReadFrom(resp)
- if err != nil {
- t.Fatalf(`ReadFrom(...) = %v, %v, %v`, n, from, err)
- }
- if resp[0] != ICMP_ECHO_REPLY {
- continue
- }
- rcvid, rcvseq := parsePingReply(resp)
- if rcvid != sendid || rcvseq != sendseq {
- t.Fatalf(`Ping reply saw id,seq=0x%x,0x%x (expected 0x%x, 0x%x)`, rcvid, rcvseq, sendid, sendseq)
- }
- return
- }
- t.Fatalf("saw no ping return")
-}
diff --git a/src/pkg/net/iprawsock.go b/src/pkg/net/iprawsock.go
deleted file mode 100644
index 43047a78e..000000000
--- a/src/pkg/net/iprawsock.go
+++ /dev/null
@@ -1,363 +0,0 @@
-// Copyright 2010 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.
-
-// (Raw) IP sockets
-
-package net
-
-import (
- "os"
- "sync"
- "syscall"
-)
-
-var onceReadProtocols sync.Once
-
-func sockaddrToIP(sa syscall.Sockaddr) Addr {
- switch sa := sa.(type) {
- case *syscall.SockaddrInet4:
- return &IPAddr{sa.Addr[0:]}
- case *syscall.SockaddrInet6:
- return &IPAddr{sa.Addr[0:]}
- }
- return nil
-}
-
-// IPAddr represents the address of a IP end point.
-type IPAddr struct {
- IP IP
-}
-
-// Network returns the address's network name, "ip".
-func (a *IPAddr) Network() string { return "ip" }
-
-func (a *IPAddr) String() string {
- if a == nil {
- return "<nil>"
- }
- return a.IP.String()
-}
-
-func (a *IPAddr) family() int {
- if a == nil || len(a.IP) <= 4 {
- return syscall.AF_INET
- }
- if a.IP.To4() != nil {
- return syscall.AF_INET
- }
- return syscall.AF_INET6
-}
-
-func (a *IPAddr) sockaddr(family int) (syscall.Sockaddr, os.Error) {
- return ipToSockaddr(family, a.IP, 0)
-}
-
-func (a *IPAddr) toAddr() sockaddr {
- if a == nil { // nil *IPAddr
- return nil // nil interface
- }
- return a
-}
-
-// ResolveIPAddr parses addr as a IP address and resolves domain
-// names to numeric addresses on the network net, which must be
-// "ip", "ip4" or "ip6". A literal IPv6 host address must be
-// enclosed in square brackets, as in "[::]".
-func ResolveIPAddr(net, addr string) (*IPAddr, os.Error) {
- ip, err := hostToIP(net, addr)
- if err != nil {
- return nil, err
- }
- return &IPAddr{ip}, nil
-}
-
-// IPConn is the implementation of the Conn and PacketConn
-// interfaces for IP network connections.
-type IPConn struct {
- fd *netFD
-}
-
-func newIPConn(fd *netFD) *IPConn { return &IPConn{fd} }
-
-func (c *IPConn) ok() bool { return c != nil && c.fd != nil }
-
-// Implementation of the Conn interface - see Conn for documentation.
-
-// Read implements the net.Conn Read method.
-func (c *IPConn) Read(b []byte) (n int, err os.Error) {
- n, _, err = c.ReadFrom(b)
- return
-}
-
-// Write implements the net.Conn Write method.
-func (c *IPConn) Write(b []byte) (n int, err os.Error) {
- if !c.ok() {
- return 0, os.EINVAL
- }
- return c.fd.Write(b)
-}
-
-// Close closes the IP connection.
-func (c *IPConn) Close() os.Error {
- if !c.ok() {
- return os.EINVAL
- }
- err := c.fd.Close()
- c.fd = nil
- return err
-}
-
-// LocalAddr returns the local network address.
-func (c *IPConn) LocalAddr() Addr {
- if !c.ok() {
- return nil
- }
- return c.fd.laddr
-}
-
-// RemoteAddr returns the remote network address, a *IPAddr.
-func (c *IPConn) RemoteAddr() Addr {
- if !c.ok() {
- return nil
- }
- return c.fd.raddr
-}
-
-// SetTimeout implements the net.Conn SetTimeout method.
-func (c *IPConn) SetTimeout(nsec int64) os.Error {
- if !c.ok() {
- return os.EINVAL
- }
- return setTimeout(c.fd, nsec)
-}
-
-// SetReadTimeout implements the net.Conn SetReadTimeout method.
-func (c *IPConn) SetReadTimeout(nsec int64) os.Error {
- if !c.ok() {
- return os.EINVAL
- }
- return setReadTimeout(c.fd, nsec)
-}
-
-// SetWriteTimeout implements the net.Conn SetWriteTimeout method.
-func (c *IPConn) SetWriteTimeout(nsec int64) os.Error {
- if !c.ok() {
- return os.EINVAL
- }
- return setWriteTimeout(c.fd, nsec)
-}
-
-// SetReadBuffer sets the size of the operating system's
-// receive buffer associated with the connection.
-func (c *IPConn) SetReadBuffer(bytes int) os.Error {
- if !c.ok() {
- return os.EINVAL
- }
- return setReadBuffer(c.fd, bytes)
-}
-
-// SetWriteBuffer sets the size of the operating system's
-// transmit buffer associated with the connection.
-func (c *IPConn) SetWriteBuffer(bytes int) os.Error {
- if !c.ok() {
- return os.EINVAL
- }
- return setWriteBuffer(c.fd, bytes)
-}
-
-// IP-specific methods.
-
-// ReadFromIP reads a IP packet from c, copying the payload into b.
-// It returns the number of bytes copied into b and the return address
-// that was on the packet.
-//
-// ReadFromIP can be made to time out and return an error with
-// Timeout() == true after a fixed time limit; see SetTimeout and
-// SetReadTimeout.
-func (c *IPConn) ReadFromIP(b []byte) (n int, addr *IPAddr, err os.Error) {
- if !c.ok() {
- return 0, nil, os.EINVAL
- }
- // TODO(cw,rsc): consider using readv if we know the family
- // type to avoid the header trim/copy
- n, sa, err := c.fd.ReadFrom(b)
- switch sa := sa.(type) {
- case *syscall.SockaddrInet4:
- addr = &IPAddr{sa.Addr[0:]}
- if len(b) >= 4 { // discard ipv4 header
- hsize := (int(b[0]) & 0xf) * 4
- copy(b, b[hsize:])
- n -= hsize
- }
- case *syscall.SockaddrInet6:
- addr = &IPAddr{sa.Addr[0:]}
- }
- return
-}
-
-// ReadFrom implements the net.PacketConn ReadFrom method.
-func (c *IPConn) ReadFrom(b []byte) (n int, addr Addr, err os.Error) {
- if !c.ok() {
- return 0, nil, os.EINVAL
- }
- n, uaddr, err := c.ReadFromIP(b)
- return n, uaddr.toAddr(), err
-}
-
-// WriteToIP writes a IP packet to addr via c, copying the payload from b.
-//
-// WriteToIP can be made to time out and return
-// an error with Timeout() == true after a fixed time limit;
-// see SetTimeout and SetWriteTimeout.
-// On packet-oriented connections, write timeouts are rare.
-func (c *IPConn) WriteToIP(b []byte, addr *IPAddr) (n int, err os.Error) {
- if !c.ok() {
- return 0, os.EINVAL
- }
- sa, err1 := addr.sockaddr(c.fd.family)
- if err1 != nil {
- return 0, &OpError{Op: "write", Net: "ip", Addr: addr, Error: err1}
- }
- return c.fd.WriteTo(b, sa)
-}
-
-// WriteTo implements the net.PacketConn WriteTo method.
-func (c *IPConn) WriteTo(b []byte, addr Addr) (n int, err os.Error) {
- if !c.ok() {
- return 0, os.EINVAL
- }
- a, ok := addr.(*IPAddr)
- if !ok {
- return 0, &OpError{"writeto", "ip", addr, os.EINVAL}
- }
- return c.WriteToIP(b, a)
-}
-
-// Convert "host" into IP address.
-func hostToIP(net, host string) (ip IP, err os.Error) {
- var addr IP
- // Try as an IP address.
- addr = ParseIP(host)
- if addr == nil {
- filter := anyaddr
- if net != "" && net[len(net)-1] == '4' {
- filter = ipv4only
- }
- if net != "" && net[len(net)-1] == '6' {
- filter = ipv6only
- }
- // Not an IP address. Try as a DNS name.
- addrs, err1 := LookupHost(host)
- if err1 != nil {
- err = err1
- goto Error
- }
- addr = firstFavoriteAddr(filter, addrs)
- if addr == nil {
- // should not happen
- err = &AddrError{"LookupHost returned no suitable address", addrs[0]}
- goto Error
- }
- }
- return addr, nil
-Error:
- return nil, err
-}
-
-var protocols map[string]int
-
-func readProtocols() {
- protocols = make(map[string]int)
- if file, err := open("/etc/protocols"); err == nil {
- for line, ok := file.readLine(); ok; line, ok = file.readLine() {
- // tcp 6 TCP # transmission control protocol
- if i := byteIndex(line, '#'); i >= 0 {
- line = line[0:i]
- }
- f := getFields(line)
- if len(f) < 2 {
- continue
- }
- if proto, _, ok := dtoi(f[1], 0); ok {
- protocols[f[0]] = proto
- for _, alias := range f[2:] {
- protocols[alias] = proto
- }
- }
- }
- file.close()
- }
-}
-
-func splitNetProto(netProto string) (net string, proto int, err os.Error) {
- onceReadProtocols.Do(readProtocols)
- i := last(netProto, ':')
- if i < 0 { // no colon
- return "", 0, os.NewError("no IP protocol specified")
- }
- net = netProto[0:i]
- protostr := netProto[i+1:]
- proto, i, ok := dtoi(protostr, 0)
- if !ok || i != len(protostr) {
- // lookup by name
- proto, ok = protocols[protostr]
- if ok {
- return
- }
- }
- return
-}
-
-// DialIP connects to the remote address raddr on the network net,
-// which must be "ip", "ip4", or "ip6".
-func DialIP(netProto string, laddr, raddr *IPAddr) (c *IPConn, err os.Error) {
- net, proto, err := splitNetProto(netProto)
- if err != nil {
- return
- }
- switch net {
- case "ip", "ip4", "ip6":
- default:
- return nil, UnknownNetworkError(net)
- }
- if raddr == nil {
- return nil, &OpError{"dial", "ip", nil, errMissingAddress}
- }
- fd, e := internetSocket(net, laddr.toAddr(), raddr.toAddr(), syscall.SOCK_RAW, proto, "dial", sockaddrToIP)
- if e != nil {
- return nil, e
- }
- return newIPConn(fd), nil
-}
-
-// ListenIP listens for incoming IP packets addressed to the
-// local address laddr. The returned connection c's ReadFrom
-// and WriteTo methods can be used to receive and send IP
-// packets with per-packet addressing.
-func ListenIP(netProto string, laddr *IPAddr) (c *IPConn, err os.Error) {
- net, proto, err := splitNetProto(netProto)
- if err != nil {
- return
- }
- switch net {
- case "ip", "ip4", "ip6":
- default:
- return nil, UnknownNetworkError(net)
- }
- fd, e := internetSocket(net, laddr.toAddr(), nil, syscall.SOCK_RAW, proto, "dial", sockaddrToIP)
- if e != nil {
- return nil, e
- }
- return newIPConn(fd), nil
-}
-
-// BindToDevice binds an IPConn to a network interface.
-func (c *IPConn) BindToDevice(device string) os.Error {
- if !c.ok() {
- return os.EINVAL
- }
- c.fd.incref()
- defer c.fd.decref()
- return os.NewSyscallError("setsockopt", syscall.BindToDevice(c.fd.sysfd, device))
-}
diff --git a/src/pkg/net/ipsock.go b/src/pkg/net/ipsock.go
deleted file mode 100644
index e831d9afc..000000000
--- a/src/pkg/net/ipsock.go
+++ /dev/null
@@ -1,323 +0,0 @@
-// 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.
-
-// IP sockets
-
-package net
-
-import (
- "os"
- "syscall"
-)
-
-// Should we try to use the IPv4 socket interface if we're
-// only dealing with IPv4 sockets? As long as the host system
-// understands IPv6, it's okay to pass IPv4 addresses to the IPv6
-// interface. That simplifies our code and is most general.
-// Unfortunately, we need to run on kernels built without IPv6
-// support too. So probe the kernel to figure it out.
-//
-// probeIPv6Stack probes both basic IPv6 capability and IPv6 IPv4-
-// mapping capability which is controlled by IPV6_V6ONLY socket
-// option and/or kernel state "net.inet6.ip6.v6only".
-// It returns two boolean values. If the first boolean value is
-// true, kernel supports basic IPv6 functionality. If the second
-// boolean value is true, kernel supports IPv6 IPv4-mapping.
-func probeIPv6Stack() (supportsIPv6, supportsIPv4map bool) {
- var probes = []struct {
- la TCPAddr
- ok bool
- }{
- // IPv6 communication capability
- {TCPAddr{IP: ParseIP("::1")}, false},
- // IPv6 IPv4-mapped address communication capability
- {TCPAddr{IP: IPv4(127, 0, 0, 1)}, false},
- }
-
- for i := range probes {
- s, errno := syscall.Socket(syscall.AF_INET6, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
- if errno != 0 {
- continue
- }
- defer closesocket(s)
- sa, err := probes[i].la.toAddr().sockaddr(syscall.AF_INET6)
- if err != nil {
- continue
- }
- errno = syscall.Bind(s, sa)
- if errno != 0 {
- continue
- }
- probes[i].ok = true
- }
-
- return probes[0].ok, probes[1].ok
-}
-
-var supportsIPv6, supportsIPv4map = probeIPv6Stack()
-
-// favoriteAddrFamily returns the appropriate address family to
-// the given net, raddr, laddr and mode. At first it figures
-// address family out from the net. If mode indicates "listen"
-// and laddr.(type).IP is nil, it assumes that the user wants to
-// make a passive connection with wildcard address family, both
-// INET and INET6, and wildcard address. Otherwise guess: if the
-// addresses are IPv4 then returns INET, or else returns INET6.
-func favoriteAddrFamily(net string, raddr, laddr sockaddr, mode string) int {
- switch net[len(net)-1] {
- case '4':
- return syscall.AF_INET
- case '6':
- return syscall.AF_INET6
- }
-
- if mode == "listen" {
- switch a := laddr.(type) {
- case *TCPAddr:
- if a.IP == nil && supportsIPv6 {
- return syscall.AF_INET6
- }
- case *UDPAddr:
- if a.IP == nil && supportsIPv6 {
- return syscall.AF_INET6
- }
- case *IPAddr:
- if a.IP == nil && supportsIPv6 {
- return syscall.AF_INET6
- }
- }
- }
-
- if (laddr == nil || laddr.family() == syscall.AF_INET) &&
- (raddr == nil || raddr.family() == syscall.AF_INET) {
- return syscall.AF_INET
- }
- return syscall.AF_INET6
-}
-
-func firstFavoriteAddr(filter func(IP) IP, addrs []string) (addr IP) {
- if filter == anyaddr {
- // We'll take any IP address, but since the dialing code
- // does not yet try multiple addresses, prefer to use
- // an IPv4 address if possible. This is especially relevant
- // if localhost resolves to [ipv6-localhost, ipv4-localhost].
- // Too much code assumes localhost == ipv4-localhost.
- addr = firstSupportedAddr(ipv4only, addrs)
- if addr == nil {
- addr = firstSupportedAddr(anyaddr, addrs)
- }
- } else {
- addr = firstSupportedAddr(filter, addrs)
- }
- return
-}
-
-func firstSupportedAddr(filter func(IP) IP, addrs []string) IP {
- for _, s := range addrs {
- if addr := filter(ParseIP(s)); addr != nil {
- return addr
- }
- }
- return nil
-}
-
-func anyaddr(x IP) IP {
- if x4 := x.To4(); x4 != nil {
- return x4
- }
- if supportsIPv6 {
- return x
- }
- return nil
-}
-
-func ipv4only(x IP) IP { return x.To4() }
-
-func ipv6only(x IP) IP {
- // Only return addresses that we can use
- // with the kernel's IPv6 addressing modes.
- if len(x) == IPv6len && x.To4() == nil && supportsIPv6 {
- return x
- }
- return nil
-}
-
-// TODO(rsc): if syscall.OS == "linux", we're supposed to read
-// /proc/sys/net/core/somaxconn,
-// to take advantage of kernels that have raised the limit.
-func listenBacklog() int { return syscall.SOMAXCONN }
-
-// Internet sockets (TCP, UDP)
-
-// A sockaddr represents a TCP or UDP network address that can
-// be converted into a syscall.Sockaddr.
-type sockaddr interface {
- Addr
- sockaddr(family int) (syscall.Sockaddr, os.Error)
- family() int
-}
-
-func internetSocket(net string, laddr, raddr sockaddr, socktype, proto int, mode string, toAddr func(syscall.Sockaddr) Addr) (fd *netFD, err os.Error) {
- var oserr os.Error
- var la, ra syscall.Sockaddr
- family := favoriteAddrFamily(net, raddr, laddr, mode)
- if laddr != nil {
- if la, oserr = laddr.sockaddr(family); oserr != nil {
- goto Error
- }
- }
- if raddr != nil {
- if ra, oserr = raddr.sockaddr(family); oserr != nil {
- goto Error
- }
- }
- fd, oserr = socket(net, family, socktype, proto, la, ra, toAddr)
- if oserr != nil {
- goto Error
- }
- return fd, nil
-
-Error:
- addr := raddr
- if mode == "listen" {
- addr = laddr
- }
- return nil, &OpError{mode, net, addr, oserr}
-}
-
-type InvalidAddrError string
-
-func (e InvalidAddrError) String() string { return string(e) }
-func (e InvalidAddrError) Timeout() bool { return false }
-func (e InvalidAddrError) Temporary() bool { return false }
-
-func ipToSockaddr(family int, ip IP, port int) (syscall.Sockaddr, os.Error) {
- switch family {
- case syscall.AF_INET:
- if len(ip) == 0 {
- ip = IPv4zero
- }
- if ip = ip.To4(); ip == nil {
- return nil, InvalidAddrError("non-IPv4 address")
- }
- s := new(syscall.SockaddrInet4)
- for i := 0; i < IPv4len; i++ {
- s.Addr[i] = ip[i]
- }
- s.Port = port
- return s, nil
- case syscall.AF_INET6:
- if len(ip) == 0 {
- ip = IPv6zero
- }
- // IPv4 callers use 0.0.0.0 to mean "announce on any available address".
- // In IPv6 mode, Linux treats that as meaning "announce on 0.0.0.0",
- // which it refuses to do. Rewrite to the IPv6 all zeros.
- if ip.Equal(IPv4zero) {
- ip = IPv6zero
- }
- if ip = ip.To16(); ip == nil {
- return nil, InvalidAddrError("non-IPv6 address")
- }
- s := new(syscall.SockaddrInet6)
- for i := 0; i < IPv6len; i++ {
- s.Addr[i] = ip[i]
- }
- s.Port = port
- return s, nil
- }
- return nil, InvalidAddrError("unexpected socket family")
-}
-
-// SplitHostPort splits a network address of the form
-// "host:port" or "[host]:port" into host and port.
-// The latter form must be used when host contains a colon.
-func SplitHostPort(hostport string) (host, port string, err os.Error) {
- // The port starts after the last colon.
- i := last(hostport, ':')
- if i < 0 {
- err = &AddrError{"missing port in address", hostport}
- return
- }
-
- host, port = hostport[0:i], hostport[i+1:]
-
- // Can put brackets around host ...
- if len(host) > 0 && host[0] == '[' && host[len(host)-1] == ']' {
- host = host[1 : len(host)-1]
- } else {
- // ... but if there are no brackets, no colons.
- if byteIndex(host, ':') >= 0 {
- err = &AddrError{"too many colons in address", hostport}
- return
- }
- }
- return
-}
-
-// JoinHostPort combines host and port into a network address
-// of the form "host:port" or, if host contains a colon, "[host]:port".
-func JoinHostPort(host, port string) string {
- // If host has colons, have to bracket it.
- if byteIndex(host, ':') >= 0 {
- return "[" + host + "]:" + port
- }
- return host + ":" + port
-}
-
-// Convert "host:port" into IP address and port.
-func hostPortToIP(net, hostport string) (ip IP, iport int, err os.Error) {
- var (
- addr IP
- p, i int
- ok bool
- )
- host, port, err := SplitHostPort(hostport)
- if err != nil {
- goto Error
- }
-
- if host != "" {
- // Try as an IP address.
- addr = ParseIP(host)
- if addr == nil {
- filter := anyaddr
- if net != "" && net[len(net)-1] == '4' {
- filter = ipv4only
- }
- if net != "" && net[len(net)-1] == '6' {
- filter = ipv6only
- }
- // Not an IP address. Try as a DNS name.
- addrs, err1 := LookupHost(host)
- if err1 != nil {
- err = err1
- goto Error
- }
- addr = firstFavoriteAddr(filter, addrs)
- if addr == nil {
- // should not happen
- err = &AddrError{"LookupHost returned no suitable address", addrs[0]}
- goto Error
- }
- }
- }
-
- p, i, ok = dtoi(port, 0)
- if !ok || i != len(port) {
- p, err = LookupPort(net, port)
- if err != nil {
- goto Error
- }
- }
- if p < 0 || p > 0xFFFF {
- err = &AddrError{"invalid port", port}
- goto Error
- }
-
- return addr, p, nil
-
-Error:
- return nil, 0, err
-}
diff --git a/src/pkg/net/lookup_unix.go b/src/pkg/net/lookup_unix.go
deleted file mode 100644
index 168d3fa6d..000000000
--- a/src/pkg/net/lookup_unix.go
+++ /dev/null
@@ -1,126 +0,0 @@
-// 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 (
- "os"
- "rand"
- "sort"
-)
-
-// LookupHost looks up the given host using the local resolver.
-// It returns an array of that host's addresses.
-func LookupHost(host string) (addrs []string, err os.Error) {
- addrs, err, ok := cgoLookupHost(host)
- if !ok {
- addrs, err = goLookupHost(host)
- }
- return
-}
-
-// LookupIP looks up host using the local resolver.
-// It returns an array of that host's IPv4 and IPv6 addresses.
-func LookupIP(host string) (addrs []IP, err os.Error) {
- addrs, err, ok := cgoLookupIP(host)
- if !ok {
- addrs, err = goLookupIP(host)
- }
- return
-}
-
-// LookupPort looks up the port for the given network and service.
-func LookupPort(network, service string) (port int, err os.Error) {
- port, err, ok := cgoLookupPort(network, service)
- if !ok {
- port, err = goLookupPort(network, service)
- }
- return
-}
-
-// LookupCNAME returns the canonical DNS host for the given name.
-// Callers that do not care about the canonical name can call
-// LookupHost or LookupIP directly; both take care of resolving
-// the canonical name as part of the lookup.
-func LookupCNAME(name string) (cname string, err os.Error) {
- cname, err, ok := cgoLookupCNAME(name)
- if !ok {
- cname, err = goLookupCNAME(name)
- }
- return
-}
-
-// LookupSRV tries to resolve an SRV query of the given service,
-// protocol, and domain name, as specified in RFC 2782. In most cases
-// the proto argument can be the same as the corresponding
-// Addr.Network(). The returned records are sorted by priority
-// and randomized by weight within a priority.
-func LookupSRV(service, proto, name string) (cname string, addrs []*SRV, err os.Error) {
- target := "_" + service + "._" + proto + "." + name
- var records []dnsRR
- cname, records, err = lookup(target, dnsTypeSRV)
- if err != nil {
- return
- }
- addrs = make([]*SRV, len(records))
- for i, rr := range records {
- r := rr.(*dnsRR_SRV)
- addrs[i] = &SRV{r.Target, r.Port, r.Priority, r.Weight}
- }
- sort.Sort(byPriorityWeight(addrs))
- i := 0
- for j := 1; j < len(addrs); j++ {
- if addrs[i].Priority != addrs[j].Priority {
- shuffleSRVByWeight(addrs[i:j])
- i = j
- }
- }
- shuffleSRVByWeight(addrs[i:len(addrs)])
- return
-}
-
-// LookupMX returns the DNS MX records for the given domain name sorted by preference.
-func LookupMX(name string) (mx []*MX, err os.Error) {
- _, rr, err := lookup(name, dnsTypeMX)
- if err != nil {
- return
- }
- mx = make([]*MX, len(rr))
- for i := range rr {
- r := rr[i].(*dnsRR_MX)
- mx[i] = &MX{r.Mx, r.Pref}
- }
- // Shuffle the records to match RFC 5321 when sorted
- for i := range mx {
- j := rand.Intn(i + 1)
- mx[i], mx[j] = mx[j], mx[i]
- }
- sort.Sort(byPref(mx))
- return
-}
-
-// LookupAddr performs a reverse lookup for the given address, returning a list
-// of names mapping to that address.
-func LookupAddr(addr string) (name []string, err os.Error) {
- name = lookupStaticAddr(addr)
- if len(name) > 0 {
- return
- }
- var arpa string
- arpa, err = reverseaddr(addr)
- if err != nil {
- return
- }
- var records []dnsRR
- _, records, err = lookup(arpa, dnsTypePTR)
- if err != nil {
- return
- }
- name = make([]string, len(records))
- for i := range records {
- r := records[i].(*dnsRR_PTR)
- name[i] = r.Ptr
- }
- return
-}
diff --git a/src/pkg/net/lookup_windows.go b/src/pkg/net/lookup_windows.go
deleted file mode 100644
index 16b37f56c..000000000
--- a/src/pkg/net/lookup_windows.go
+++ /dev/null
@@ -1,107 +0,0 @@
-// 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.
-
-package net
-
-import (
- "syscall"
- "unsafe"
- "os"
- "sync"
-)
-
-var hostentLock sync.Mutex
-var serventLock sync.Mutex
-
-func LookupHost(name string) (addrs []string, err os.Error) {
- ips, err := LookupIP(name)
- if err != nil {
- return
- }
- addrs = make([]string, 0, len(ips))
- for _, ip := range ips {
- addrs = append(addrs, ip.String())
- }
- return
-}
-
-func LookupIP(name string) (addrs []IP, err os.Error) {
- hostentLock.Lock()
- defer hostentLock.Unlock()
- h, e := syscall.GetHostByName(name)
- if e != 0 {
- return nil, os.NewSyscallError("GetHostByName", e)
- }
- switch h.AddrType {
- case syscall.AF_INET:
- i := 0
- addrs = make([]IP, 100) // plenty of room to grow
- for p := (*[100](*[4]byte))(unsafe.Pointer(h.AddrList)); i < cap(addrs) && p[i] != nil; i++ {
- addrs[i] = IPv4(p[i][0], p[i][1], p[i][2], p[i][3])
- }
- addrs = addrs[0:i]
- default: // TODO(vcc): Implement non IPv4 address lookups.
- return nil, os.NewSyscallError("LookupHost", syscall.EWINDOWS)
- }
- return addrs, nil
-}
-
-func LookupPort(network, service string) (port int, err os.Error) {
- switch network {
- case "tcp4", "tcp6":
- network = "tcp"
- case "udp4", "udp6":
- network = "udp"
- }
- serventLock.Lock()
- defer serventLock.Unlock()
- s, e := syscall.GetServByName(service, network)
- if e != 0 {
- return 0, os.NewSyscallError("GetServByName", e)
- }
- return int(syscall.Ntohs(s.Port)), nil
-}
-
-func LookupCNAME(name string) (cname string, err os.Error) {
- var r *syscall.DNSRecord
- e := syscall.DnsQuery(name, syscall.DNS_TYPE_CNAME, 0, nil, &r, nil)
- if int(e) != 0 {
- return "", os.NewSyscallError("LookupCNAME", int(e))
- }
- defer syscall.DnsRecordListFree(r, 1)
- if r != nil && r.Type == syscall.DNS_TYPE_CNAME {
- v := (*syscall.DNSPTRData)(unsafe.Pointer(&r.Data[0]))
- cname = syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.Host))[:]) + "."
- }
- return
-}
-
-func LookupSRV(service, proto, name string) (cname string, addrs []*SRV, err os.Error) {
- var r *syscall.DNSRecord
- target := "_" + service + "._" + proto + "." + name
- e := syscall.DnsQuery(target, syscall.DNS_TYPE_SRV, 0, nil, &r, nil)
- if int(e) != 0 {
- return "", nil, os.NewSyscallError("LookupSRV", int(e))
- }
- defer syscall.DnsRecordListFree(r, 1)
- addrs = make([]*SRV, 100)
- i := 0
- for p := r; p != nil && p.Type == syscall.DNS_TYPE_SRV; p = p.Next {
- v := (*syscall.DNSSRVData)(unsafe.Pointer(&p.Data[0]))
- addrs[i] = &SRV{syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.Target))[:]), v.Port, v.Priority, v.Weight}
- i++
- }
- addrs = addrs[0:i]
- return name, addrs, nil
-}
-
-// TODO(brainman): implement LookupMX and LookupAddr.
-
-func LookupMX(name string) (mx []*MX, err os.Error) {
- return nil, os.NewSyscallError("LookupMX", syscall.EWINDOWS)
-}
-
-func LookupAddr(addr string) (name []string, err os.Error) {
- return nil, os.NewSyscallError("LookupAddr", syscall.EWINDOWS)
-}
diff --git a/src/pkg/net/multicast_test.go b/src/pkg/net/multicast_test.go
deleted file mode 100644
index be6dbf2dc..000000000
--- a/src/pkg/net/multicast_test.go
+++ /dev/null
@@ -1,73 +0,0 @@
-// 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 (
- "flag"
- "runtime"
- "testing"
-)
-
-var multicast = flag.Bool("multicast", false, "enable multicast tests")
-
-func TestMulticastJoinAndLeave(t *testing.T) {
- if runtime.GOOS == "windows" {
- return
- }
- if !*multicast {
- t.Logf("test disabled; use --multicast to enable")
- return
- }
-
- addr := &UDPAddr{
- IP: IPv4zero,
- Port: 0,
- }
- // open a UDPConn
- conn, err := ListenUDP("udp4", addr)
- if err != nil {
- t.Fatal(err)
- }
- defer conn.Close()
-
- // try to join group
- mcast := IPv4(224, 0, 0, 254)
- err = conn.JoinGroup(mcast)
- if err != nil {
- t.Fatal(err)
- }
-
- // try to leave group
- err = conn.LeaveGroup(mcast)
- if err != nil {
- t.Fatal(err)
- }
-}
-
-func TestJoinFailureWithIPv6Address(t *testing.T) {
- if !*multicast {
- t.Logf("test disabled; use --multicast to enable")
- return
- }
- addr := &UDPAddr{
- IP: IPv4zero,
- Port: 0,
- }
-
- // open a UDPConn
- conn, err := ListenUDP("udp4", addr)
- if err != nil {
- t.Fatal(err)
- }
- defer conn.Close()
-
- // try to join group
- mcast := ParseIP("ff02::1")
- err = conn.JoinGroup(mcast)
- if err == nil {
- t.Fatal("JoinGroup succeeded, should fail")
- }
- t.Logf("%s", err)
-}
diff --git a/src/pkg/net/net.go b/src/pkg/net/net.go
deleted file mode 100644
index 5c84d3434..000000000
--- a/src/pkg/net/net.go
+++ /dev/null
@@ -1,188 +0,0 @@
-// 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.
-
-// Package net provides a portable interface to Unix networks sockets,
-// including TCP/IP, UDP, domain name resolution, and Unix domain sockets.
-package net
-
-// TODO(rsc):
-// support for raw ethernet sockets
-
-import "os"
-
-// Addr represents a network end point address.
-type Addr interface {
- Network() string // name of the network
- String() string // string form of address
-}
-
-// Conn is a generic stream-oriented network connection.
-type Conn interface {
- // Read reads data from the connection.
- // Read can be made to time out and return a net.Error with Timeout() == true
- // after a fixed time limit; see SetTimeout and SetReadTimeout.
- Read(b []byte) (n int, err os.Error)
-
- // Write writes data to the connection.
- // Write can be made to time out and return a net.Error with Timeout() == true
- // after a fixed time limit; see SetTimeout and SetWriteTimeout.
- Write(b []byte) (n int, err os.Error)
-
- // Close closes the connection.
- Close() os.Error
-
- // LocalAddr returns the local network address.
- LocalAddr() Addr
-
- // RemoteAddr returns the remote network address.
- RemoteAddr() Addr
-
- // SetTimeout sets the read and write deadlines associated
- // with the connection.
- SetTimeout(nsec int64) os.Error
-
- // SetReadTimeout sets the time (in nanoseconds) that
- // Read will wait for data before returning an error with Timeout() == true.
- // Setting nsec == 0 (the default) disables the deadline.
- SetReadTimeout(nsec int64) os.Error
-
- // SetWriteTimeout sets the time (in nanoseconds) that
- // Write will wait to send its data before returning an error with Timeout() == true.
- // Setting nsec == 0 (the default) disables the deadline.
- // Even if write times out, it may return n > 0, indicating that
- // some of the data was successfully written.
- SetWriteTimeout(nsec int64) os.Error
-}
-
-// An Error represents a network error.
-type Error interface {
- os.Error
- Timeout() bool // Is the error a timeout?
- Temporary() bool // Is the error temporary?
-}
-
-// PacketConn is a generic packet-oriented network connection.
-type PacketConn interface {
- // ReadFrom reads a packet from the connection,
- // copying the payload into b. It returns the number of
- // bytes copied into b and the return address that
- // was on the packet.
- // ReadFrom can be made to time out and return
- // an error with Timeout() == true after a fixed time limit;
- // see SetTimeout and SetReadTimeout.
- ReadFrom(b []byte) (n int, addr Addr, err os.Error)
-
- // WriteTo writes a packet with payload b to addr.
- // WriteTo can be made to time out and return
- // an error with Timeout() == true after a fixed time limit;
- // see SetTimeout and SetWriteTimeout.
- // On packet-oriented connections, write timeouts are rare.
- WriteTo(b []byte, addr Addr) (n int, err os.Error)
-
- // Close closes the connection.
- Close() os.Error
-
- // LocalAddr returns the local network address.
- LocalAddr() Addr
-
- // SetTimeout sets the read and write deadlines associated
- // with the connection.
- SetTimeout(nsec int64) os.Error
-
- // SetReadTimeout sets the time (in nanoseconds) that
- // Read will wait for data before returning an error with Timeout() == true.
- // Setting nsec == 0 (the default) disables the deadline.
- SetReadTimeout(nsec int64) os.Error
-
- // SetWriteTimeout sets the time (in nanoseconds) that
- // Write will wait to send its data before returning an error with Timeout() == true.
- // Setting nsec == 0 (the default) disables the deadline.
- // Even if write times out, it may return n > 0, indicating that
- // some of the data was successfully written.
- SetWriteTimeout(nsec int64) os.Error
-}
-
-// A Listener is a generic network listener for stream-oriented protocols.
-type Listener interface {
- // Accept waits for and returns the next connection to the listener.
- Accept() (c Conn, err os.Error)
-
- // Close closes the listener.
- Close() os.Error
-
- // Addr returns the listener's network address.
- Addr() Addr
-}
-
-var errMissingAddress = os.NewError("missing address")
-
-type OpError struct {
- Op string
- Net string
- Addr Addr
- Error os.Error
-}
-
-func (e *OpError) String() string {
- if e == nil {
- return "<nil>"
- }
- s := e.Op
- if e.Net != "" {
- s += " " + e.Net
- }
- if e.Addr != nil {
- s += " " + e.Addr.String()
- }
- s += ": " + e.Error.String()
- return s
-}
-
-type temporary interface {
- Temporary() bool
-}
-
-func (e *OpError) Temporary() bool {
- t, ok := e.Error.(temporary)
- return ok && t.Temporary()
-}
-
-type timeout interface {
- Timeout() bool
-}
-
-func (e *OpError) Timeout() bool {
- t, ok := e.Error.(timeout)
- return ok && t.Timeout()
-}
-
-type AddrError struct {
- Error string
- Addr string
-}
-
-func (e *AddrError) String() string {
- if e == nil {
- return "<nil>"
- }
- s := e.Error
- if e.Addr != "" {
- s += " " + e.Addr
- }
- return s
-}
-
-func (e *AddrError) Temporary() bool {
- return false
-}
-
-func (e *AddrError) Timeout() bool {
- return false
-}
-
-type UnknownNetworkError string
-
-func (e UnknownNetworkError) String() string { return "unknown network " + string(e) }
-func (e UnknownNetworkError) Temporary() bool { return false }
-func (e UnknownNetworkError) Timeout() bool { return false }
diff --git a/src/pkg/net/net_test.go b/src/pkg/net/net_test.go
deleted file mode 100644
index 698a84527..000000000
--- a/src/pkg/net/net_test.go
+++ /dev/null
@@ -1,121 +0,0 @@
-// 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.
-
-package net
-
-import (
- "flag"
- "regexp"
- "testing"
-)
-
-var runErrorTest = flag.Bool("run_error_test", false, "let TestDialError check for dns errors")
-
-type DialErrorTest struct {
- Net string
- Raddr string
- Pattern string
-}
-
-var dialErrorTests = []DialErrorTest{
- {
- "datakit", "mh/astro/r70",
- "dial datakit mh/astro/r70: unknown network datakit",
- },
- {
- "tcp", "127.0.0.1:☺",
- "dial tcp 127.0.0.1:☺: unknown port tcp/☺",
- },
- {
- "tcp", "no-such-name.google.com.:80",
- "dial tcp no-such-name.google.com.:80: lookup no-such-name.google.com.( on .*)?: no (.*)",
- },
- {
- "tcp", "no-such-name.no-such-top-level-domain.:80",
- "dial tcp no-such-name.no-such-top-level-domain.:80: lookup no-such-name.no-such-top-level-domain.( on .*)?: no (.*)",
- },
- {
- "tcp", "no-such-name:80",
- `dial tcp no-such-name:80: lookup no-such-name\.(.*\.)?( on .*)?: no (.*)`,
- },
- {
- "tcp", "mh/astro/r70:http",
- "dial tcp mh/astro/r70:http: lookup mh/astro/r70: invalid domain name",
- },
- {
- "unix", "/etc/file-not-found",
- "dial unix /etc/file-not-found: no such file or directory",
- },
- {
- "unix", "/etc/",
- "dial unix /etc/: (permission denied|socket operation on non-socket|connection refused)",
- },
- {
- "unixpacket", "/etc/file-not-found",
- "dial unixpacket /etc/file-not-found: no such file or directory",
- },
- {
- "unixpacket", "/etc/",
- "dial unixpacket /etc/: (permission denied|socket operation on non-socket|connection refused)",
- },
-}
-
-func TestDialError(t *testing.T) {
- if !*runErrorTest {
- t.Logf("test disabled; use --run_error_test to enable")
- return
- }
- for i, tt := range dialErrorTests {
- c, e := Dial(tt.Net, tt.Raddr)
- if c != nil {
- c.Close()
- }
- if e == nil {
- t.Errorf("#%d: nil error, want match for %#q", i, tt.Pattern)
- continue
- }
- s := e.String()
- match, _ := regexp.MatchString(tt.Pattern, s)
- if !match {
- t.Errorf("#%d: %q, want match for %#q", i, s, tt.Pattern)
- }
- }
-}
-
-var revAddrTests = []struct {
- Addr string
- Reverse string
- ErrPrefix string
-}{
- {"1.2.3.4", "4.3.2.1.in-addr.arpa.", ""},
- {"245.110.36.114", "114.36.110.245.in-addr.arpa.", ""},
- {"::ffff:12.34.56.78", "78.56.34.12.in-addr.arpa.", ""},
- {"::1", "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.", ""},
- {"1::", "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.0.0.ip6.arpa.", ""},
- {"1234:567::89a:bcde", "e.d.c.b.a.9.8.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.7.6.5.0.4.3.2.1.ip6.arpa.", ""},
- {"1234:567:fefe:bcbc:adad:9e4a:89a:bcde", "e.d.c.b.a.9.8.0.a.4.e.9.d.a.d.a.c.b.c.b.e.f.e.f.7.6.5.0.4.3.2.1.ip6.arpa.", ""},
- {"1.2.3", "", "unrecognized address"},
- {"1.2.3.4.5", "", "unrecognized address"},
- {"1234:567:bcbca::89a:bcde", "", "unrecognized address"},
- {"1234:567::bcbc:adad::89a:bcde", "", "unrecognized address"},
-}
-
-func TestReverseAddress(t *testing.T) {
- for i, tt := range revAddrTests {
- a, e := reverseaddr(tt.Addr)
- if len(tt.ErrPrefix) > 0 && e == nil {
- t.Errorf("#%d: expected %q, got <nil> (error)", i, tt.ErrPrefix)
- continue
- }
- if len(tt.ErrPrefix) == 0 && e != nil {
- t.Errorf("#%d: expected <nil>, got %q (error)", i, e)
- }
- if e != nil && e.(*DNSError).Error != tt.ErrPrefix {
- t.Errorf("#%d: expected %q, got %q (mismatched error)", i, tt.ErrPrefix, e.(*DNSError).Error)
- }
- if a != tt.Reverse {
- t.Errorf("#%d: expected %q, got %q (reverse address)", i, tt.Reverse, a)
- }
- }
-}
diff --git a/src/pkg/net/newpollserver.go b/src/pkg/net/newpollserver.go
deleted file mode 100644
index 427208701..000000000
--- a/src/pkg/net/newpollserver.go
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2010 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 (
- "os"
- "syscall"
-)
-
-func newPollServer() (s *pollServer, err os.Error) {
- s = new(pollServer)
- s.cr = make(chan *netFD, 1)
- s.cw = make(chan *netFD, 1)
- if s.pr, s.pw, err = os.Pipe(); err != nil {
- return nil, err
- }
- var e int
- if e = syscall.SetNonblock(s.pr.Fd(), true); e != 0 {
- goto Errno
- }
- if e = syscall.SetNonblock(s.pw.Fd(), true); e != 0 {
- goto Errno
- }
- if s.poll, err = newpollster(); err != nil {
- goto Error
- }
- if _, err = s.poll.AddFD(s.pr.Fd(), 'r', true); err != nil {
- s.poll.Close()
- goto Error
- }
- s.pending = make(map[int]*netFD)
- go s.Run()
- return s, nil
-
-Errno:
- err = &os.PathError{"setnonblock", s.pr.Name(), os.Errno(e)}
-Error:
- s.pr.Close()
- s.pw.Close()
- return nil, err
-}
diff --git a/src/pkg/net/parse.go b/src/pkg/net/parse.go
deleted file mode 100644
index de46830d2..000000000
--- a/src/pkg/net/parse.go
+++ /dev/null
@@ -1,204 +0,0 @@
-// 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.
-
-// Simple file i/o and string manipulation, to avoid
-// depending on strconv and bufio and strings.
-
-package net
-
-import (
- "io"
- "os"
-)
-
-type file struct {
- file *os.File
- data []byte
- atEOF bool
-}
-
-func (f *file) close() { f.file.Close() }
-
-func (f *file) getLineFromData() (s string, ok bool) {
- data := f.data
- i := 0
- for i = 0; i < len(data); i++ {
- if data[i] == '\n' {
- s = string(data[0:i])
- ok = true
- // move data
- i++
- n := len(data) - i
- copy(data[0:], data[i:])
- f.data = data[0:n]
- return
- }
- }
- if f.atEOF && len(f.data) > 0 {
- // EOF, return all we have
- s = string(data)
- f.data = f.data[0:0]
- ok = true
- }
- return
-}
-
-func (f *file) readLine() (s string, ok bool) {
- if s, ok = f.getLineFromData(); ok {
- return
- }
- if len(f.data) < cap(f.data) {
- ln := len(f.data)
- n, err := io.ReadFull(f.file, f.data[ln:cap(f.data)])
- if n >= 0 {
- f.data = f.data[0 : ln+n]
- }
- if err == os.EOF {
- f.atEOF = true
- }
- }
- s, ok = f.getLineFromData()
- return
-}
-
-func open(name string) (*file, os.Error) {
- fd, err := os.Open(name)
- if err != nil {
- return nil, err
- }
- return &file{fd, make([]byte, 1024)[0:0], false}, nil
-}
-
-func byteIndex(s string, c byte) int {
- for i := 0; i < len(s); i++ {
- if s[i] == c {
- return i
- }
- }
- return -1
-}
-
-// Count occurrences in s of any bytes in t.
-func countAnyByte(s string, t string) int {
- n := 0
- for i := 0; i < len(s); i++ {
- if byteIndex(t, s[i]) >= 0 {
- n++
- }
- }
- return n
-}
-
-// Split s at any bytes in t.
-func splitAtBytes(s string, t string) []string {
- a := make([]string, 1+countAnyByte(s, t))
- n := 0
- last := 0
- for i := 0; i < len(s); i++ {
- if byteIndex(t, s[i]) >= 0 {
- if last < i {
- a[n] = string(s[last:i])
- n++
- }
- last = i + 1
- }
- }
- if last < len(s) {
- a[n] = string(s[last:])
- n++
- }
- return a[0:n]
-}
-
-func getFields(s string) []string { return splitAtBytes(s, " \r\t\n") }
-
-// Bigger than we need, not too big to worry about overflow
-const big = 0xFFFFFF
-
-// Decimal to integer starting at &s[i0].
-// Returns number, new offset, success.
-func dtoi(s string, i0 int) (n int, i int, ok bool) {
- n = 0
- for i = i0; i < len(s) && '0' <= s[i] && s[i] <= '9'; i++ {
- n = n*10 + int(s[i]-'0')
- if n >= big {
- return 0, i, false
- }
- }
- if i == i0 {
- return 0, i, false
- }
- return n, i, true
-}
-
-// Hexadecimal to integer starting at &s[i0].
-// Returns number, new offset, success.
-func xtoi(s string, i0 int) (n int, i int, ok bool) {
- n = 0
- for i = i0; i < len(s); i++ {
- if '0' <= s[i] && s[i] <= '9' {
- n *= 16
- n += int(s[i] - '0')
- } else if 'a' <= s[i] && s[i] <= 'f' {
- n *= 16
- n += int(s[i]-'a') + 10
- } else if 'A' <= s[i] && s[i] <= 'F' {
- n *= 16
- n += int(s[i]-'A') + 10
- } else {
- break
- }
- if n >= big {
- return 0, i, false
- }
- }
- if i == i0 {
- return 0, i, false
- }
- return n, i, true
-}
-
-// Integer to decimal.
-func itoa(i int) string {
- var buf [30]byte
- n := len(buf)
- neg := false
- if i < 0 {
- i = -i
- neg = true
- }
- ui := uint(i)
- for ui > 0 || n == len(buf) {
- n--
- buf[n] = byte('0' + ui%10)
- ui /= 10
- }
- if neg {
- n--
- buf[n] = '-'
- }
- return string(buf[n:])
-}
-
-// Number of occurrences of b in s.
-func count(s string, b byte) int {
- n := 0
- for i := 0; i < len(s); i++ {
- if s[i] == b {
- n++
- }
- }
- return n
-}
-
-// Index of rightmost occurrence of b in s.
-func last(s string, b byte) int {
- i := len(s)
- for i--; i >= 0; i-- {
- if s[i] == b {
- break
- }
- }
- return i
-}
diff --git a/src/pkg/net/parse_test.go b/src/pkg/net/parse_test.go
deleted file mode 100644
index 226f354d3..000000000
--- a/src/pkg/net/parse_test.go
+++ /dev/null
@@ -1,50 +0,0 @@
-// 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.
-
-package net
-
-import (
- "bufio"
- "os"
- "testing"
- "runtime"
-)
-
-func TestReadLine(t *testing.T) {
- // /etc/services file does not exist on windows.
- if runtime.GOOS == "windows" {
- return
- }
- filename := "/etc/services" // a nice big file
-
- fd, err := os.Open(filename)
- if err != nil {
- t.Fatalf("open %s: %v", filename, err)
- }
- br := bufio.NewReader(fd)
-
- file, err := open(filename)
- if file == nil {
- t.Fatalf("net.open(%s) = nil", filename)
- }
-
- lineno := 1
- byteno := 0
- for {
- bline, berr := br.ReadString('\n')
- if n := len(bline); n > 0 {
- bline = bline[0 : n-1]
- }
- line, ok := file.readLine()
- if (berr != nil) != !ok || bline != line {
- t.Fatalf("%s:%d (#%d)\nbufio => %q, %v\nnet => %q, %v",
- filename, lineno, byteno, bline, berr, line, ok)
- }
- if !ok {
- break
- }
- lineno++
- byteno += len(line) + 1
- }
-}
diff --git a/src/pkg/net/pipe.go b/src/pkg/net/pipe.go
deleted file mode 100644
index c0bbd356b..000000000
--- a/src/pkg/net/pipe.go
+++ /dev/null
@@ -1,62 +0,0 @@
-package net
-
-import (
- "io"
- "os"
-)
-
-// Pipe creates a synchronous, in-memory, full duplex
-// network connection; both ends implement the Conn interface.
-// Reads on one end are matched with writes on the other,
-// copying data directly between the two; there is no internal
-// buffering.
-func Pipe() (Conn, Conn) {
- r1, w1 := io.Pipe()
- r2, w2 := io.Pipe()
-
- return &pipe{r1, w2}, &pipe{r2, w1}
-}
-
-type pipe struct {
- *io.PipeReader
- *io.PipeWriter
-}
-
-type pipeAddr int
-
-func (pipeAddr) Network() string {
- return "pipe"
-}
-
-func (pipeAddr) String() string {
- return "pipe"
-}
-
-func (p *pipe) Close() os.Error {
- err := p.PipeReader.Close()
- err1 := p.PipeWriter.Close()
- if err == nil {
- err = err1
- }
- return err
-}
-
-func (p *pipe) LocalAddr() Addr {
- return pipeAddr(0)
-}
-
-func (p *pipe) RemoteAddr() Addr {
- return pipeAddr(0)
-}
-
-func (p *pipe) SetTimeout(nsec int64) os.Error {
- return os.NewError("net.Pipe does not support timeouts")
-}
-
-func (p *pipe) SetReadTimeout(nsec int64) os.Error {
- return os.NewError("net.Pipe does not support timeouts")
-}
-
-func (p *pipe) SetWriteTimeout(nsec int64) os.Error {
- return os.NewError("net.Pipe does not support timeouts")
-}
diff --git a/src/pkg/net/pipe_test.go b/src/pkg/net/pipe_test.go
deleted file mode 100644
index 7e4c6db44..000000000
--- a/src/pkg/net/pipe_test.go
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2010 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 (
- "bytes"
- "io"
- "os"
- "testing"
-)
-
-func checkWrite(t *testing.T, w io.Writer, data []byte, c chan int) {
- n, err := w.Write(data)
- if err != nil {
- t.Errorf("write: %v", err)
- }
- if n != len(data) {
- t.Errorf("short write: %d != %d", n, len(data))
- }
- c <- 0
-}
-
-func checkRead(t *testing.T, r io.Reader, data []byte, wantErr os.Error) {
- buf := make([]byte, len(data)+10)
- n, err := r.Read(buf)
- if err != wantErr {
- t.Errorf("read: %v", err)
- return
- }
- if n != len(data) || !bytes.Equal(buf[0:n], data) {
- t.Errorf("bad read: got %q", buf[0:n])
- return
- }
-}
-
-// Test a simple read/write/close sequence.
-// Assumes that the underlying io.Pipe implementation
-// is solid and we're just testing the net wrapping.
-
-func TestPipe(t *testing.T) {
- c := make(chan int)
- cli, srv := Pipe()
- go checkWrite(t, cli, []byte("hello, world"), c)
- checkRead(t, srv, []byte("hello, world"), nil)
- <-c
- go checkWrite(t, srv, []byte("line 2"), c)
- checkRead(t, cli, []byte("line 2"), nil)
- <-c
- go checkWrite(t, cli, []byte("a third line"), c)
- checkRead(t, srv, []byte("a third line"), nil)
- <-c
- go srv.Close()
- checkRead(t, cli, nil, os.EOF)
- cli.Close()
-}
diff --git a/src/pkg/net/port.go b/src/pkg/net/port.go
deleted file mode 100644
index 8f8327a37..000000000
--- a/src/pkg/net/port.go
+++ /dev/null
@@ -1,70 +0,0 @@
-// 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.
-
-// Read system port mappings from /etc/services
-
-package net
-
-import (
- "os"
- "sync"
-)
-
-var services map[string]map[string]int
-var servicesError os.Error
-var onceReadServices sync.Once
-
-func readServices() {
- services = make(map[string]map[string]int)
- var file *file
- if file, servicesError = open("/etc/services"); servicesError != nil {
- return
- }
- for line, ok := file.readLine(); ok; line, ok = file.readLine() {
- // "http 80/tcp www www-http # World Wide Web HTTP"
- if i := byteIndex(line, '#'); i >= 0 {
- line = line[0:i]
- }
- f := getFields(line)
- if len(f) < 2 {
- continue
- }
- portnet := f[1] // "tcp/80"
- port, j, ok := dtoi(portnet, 0)
- if !ok || port <= 0 || j >= len(portnet) || portnet[j] != '/' {
- continue
- }
- netw := portnet[j+1:] // "tcp"
- m, ok1 := services[netw]
- if !ok1 {
- m = make(map[string]int)
- services[netw] = m
- }
- for i := 0; i < len(f); i++ {
- if i != 1 { // f[1] was port/net
- m[f[i]] = port
- }
- }
- }
- file.close()
-}
-
-// goLookupPort is the native Go implementation of LookupPort.
-func goLookupPort(network, service string) (port int, err os.Error) {
- onceReadServices.Do(readServices)
-
- switch network {
- case "tcp4", "tcp6":
- network = "tcp"
- case "udp4", "udp6":
- network = "udp"
- }
-
- if m, ok := services[network]; ok {
- if port, ok = m[service]; ok {
- return
- }
- }
- return 0, &AddrError{"unknown port", network + "/" + service}
-}
diff --git a/src/pkg/net/port_test.go b/src/pkg/net/port_test.go
deleted file mode 100644
index 329b169f3..000000000
--- a/src/pkg/net/port_test.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// 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.
-
-package net
-
-import (
- "testing"
-)
-
-type portTest struct {
- netw string
- name string
- port int
- ok bool
-}
-
-var porttests = []portTest{
- {"tcp", "echo", 7, true},
- {"tcp", "discard", 9, true},
- {"tcp", "systat", 11, true},
- {"tcp", "daytime", 13, true},
- {"tcp", "chargen", 19, true},
- {"tcp", "ftp-data", 20, true},
- {"tcp", "ftp", 21, true},
- {"tcp", "telnet", 23, true},
- {"tcp", "smtp", 25, true},
- {"tcp", "time", 37, true},
- {"tcp", "domain", 53, true},
- {"tcp", "finger", 79, true},
-
- {"udp", "echo", 7, true},
- {"udp", "tftp", 69, true},
- {"udp", "bootpc", 68, true},
- {"udp", "bootps", 67, true},
- {"udp", "domain", 53, true},
- {"udp", "ntp", 123, true},
- {"udp", "snmp", 161, true},
- {"udp", "syslog", 514, true},
-
- {"--badnet--", "zzz", 0, false},
- {"tcp", "--badport--", 0, false},
-}
-
-func TestLookupPort(t *testing.T) {
- for i := 0; i < len(porttests); i++ {
- tt := porttests[i]
- if port, err := LookupPort(tt.netw, tt.name); port != tt.port || (err == nil) != tt.ok {
- t.Errorf("LookupPort(%q, %q) = %v, %s; want %v",
- tt.netw, tt.name, port, err, tt.port)
- }
- }
-}
diff --git a/src/pkg/net/sendfile_linux.go b/src/pkg/net/sendfile_linux.go
deleted file mode 100644
index 6a5a06c8c..000000000
--- a/src/pkg/net/sendfile_linux.go
+++ /dev/null
@@ -1,84 +0,0 @@
-// 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 (
- "io"
- "os"
- "syscall"
-)
-
-// maxSendfileSize is the largest chunk size we ask the kernel to copy
-// at a time.
-const maxSendfileSize int = 4 << 20
-
-// sendFile copies the contents of r to c using the sendfile
-// system call to minimize copies.
-//
-// if handled == true, sendFile returns the number of bytes copied and any
-// non-EOF error.
-//
-// if handled == false, sendFile performed no work.
-func sendFile(c *netFD, r io.Reader) (written int64, err os.Error, handled bool) {
- var remain int64 = 1 << 62 // by default, copy until EOF
-
- lr, ok := r.(*io.LimitedReader)
- if ok {
- remain, r = lr.N, lr.R
- if remain <= 0 {
- return 0, nil, true
- }
- }
- f, ok := r.(*os.File)
- if !ok {
- return 0, nil, false
- }
-
- c.wio.Lock()
- defer c.wio.Unlock()
- c.incref()
- defer c.decref()
- if c.wdeadline_delta > 0 {
- // This is a little odd that we're setting the timeout
- // for the entire file but Write has the same issue
- // (if one slurps the whole file into memory and
- // do one large Write). At least they're consistent.
- c.wdeadline = pollserver.Now() + c.wdeadline_delta
- } else {
- c.wdeadline = 0
- }
-
- dst := c.sysfd
- src := f.Fd()
- for remain > 0 {
- n := maxSendfileSize
- if int64(n) > remain {
- n = int(remain)
- }
- n, errno := syscall.Sendfile(dst, src, nil, n)
- if n > 0 {
- written += int64(n)
- remain -= int64(n)
- }
- if n == 0 && errno == 0 {
- break
- }
- if errno == syscall.EAGAIN && c.wdeadline >= 0 {
- pollserver.WaitWrite(c)
- continue
- }
- if errno != 0 {
- // This includes syscall.ENOSYS (no kernel
- // support) and syscall.EINVAL (fd types which
- // don't implement sendfile together)
- err = &OpError{"sendfile", c.net, c.raddr, os.Errno(errno)}
- break
- }
- }
- if lr != nil {
- lr.N = remain
- }
- return written, err, written > 0
-}
diff --git a/src/pkg/net/sendfile_stub.go b/src/pkg/net/sendfile_stub.go
deleted file mode 100644
index 43e8104e9..000000000
--- a/src/pkg/net/sendfile_stub.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// 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 (
- "io"
- "os"
-)
-
-func sendFile(c *netFD, r io.Reader) (n int64, err os.Error, handled bool) {
- return 0, nil, false
-}
diff --git a/src/pkg/net/sendfile_windows.go b/src/pkg/net/sendfile_windows.go
deleted file mode 100644
index 3772eee24..000000000
--- a/src/pkg/net/sendfile_windows.go
+++ /dev/null
@@ -1,68 +0,0 @@
-// 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 (
- "io"
- "os"
- "syscall"
-)
-
-type sendfileOp struct {
- anOp
- src syscall.Handle // source
- n uint32
-}
-
-func (o *sendfileOp) Submit() (errno int) {
- return syscall.TransmitFile(o.fd.sysfd, o.src, o.n, 0, &o.o, nil, syscall.TF_WRITE_BEHIND)
-}
-
-func (o *sendfileOp) Name() string {
- return "TransmitFile"
-}
-
-// sendFile copies the contents of r to c using the TransmitFile
-// system call to minimize copies.
-//
-// if handled == true, sendFile returns the number of bytes copied and any
-// non-EOF error.
-//
-// if handled == false, sendFile performed no work.
-//
-// Note that sendfile for windows does not suppport >2GB file.
-func sendFile(c *netFD, r io.Reader) (written int64, err os.Error, handled bool) {
- var n int64 = 0 // by default, copy until EOF
-
- lr, ok := r.(*io.LimitedReader)
- if ok {
- n, r = lr.N, lr.R
- if n <= 0 {
- return 0, nil, true
- }
- }
- f, ok := r.(*os.File)
- if !ok {
- return 0, nil, false
- }
-
- c.wio.Lock()
- defer c.wio.Unlock()
- c.incref()
- defer c.decref()
-
- var o sendfileOp
- o.Init(c)
- o.n = uint32(n)
- o.src = f.Fd()
- done, err := iosrv.ExecIO(&o, 0)
- if err != nil {
- return 0, err, false
- }
- if lr != nil {
- lr.N -= int64(done)
- }
- return int64(done), nil, true
-}
diff --git a/src/pkg/net/server_test.go b/src/pkg/net/server_test.go
deleted file mode 100644
index 36780d789..000000000
--- a/src/pkg/net/server_test.go
+++ /dev/null
@@ -1,243 +0,0 @@
-// 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.
-
-package net
-
-import (
- "flag"
- "io"
- "os"
- "strings"
- "syscall"
- "testing"
- "runtime"
-)
-
-// Do not test empty datagrams by default.
-// It causes unexplained timeouts on some systems,
-// including Snow Leopard. I think that the kernel
-// doesn't quite expect them.
-var testUDP = flag.Bool("udp", false, "whether to test UDP datagrams")
-
-func runEcho(fd io.ReadWriter, done chan<- int) {
- var buf [1024]byte
-
- for {
- n, err := fd.Read(buf[0:])
- if err != nil || n == 0 || string(buf[:n]) == "END" {
- break
- }
- fd.Write(buf[0:n])
- }
- done <- 1
-}
-
-func runServe(t *testing.T, network, addr string, listening chan<- string, done chan<- int) {
- l, err := Listen(network, addr)
- if err != nil {
- t.Fatalf("net.Listen(%q, %q) = _, %v", network, addr, err)
- }
- listening <- l.Addr().String()
-
- for {
- fd, err := l.Accept()
- if err != nil {
- break
- }
- echodone := make(chan int)
- go runEcho(fd, echodone)
- <-echodone // make sure Echo stops
- l.Close()
- }
- done <- 1
-}
-
-func connect(t *testing.T, network, addr string, isEmpty bool) {
- var fd Conn
- var err os.Error
- if network == "unixgram" {
- fd, err = DialUnix(network, &UnixAddr{addr + ".local", network}, &UnixAddr{addr, network})
- } else {
- fd, err = Dial(network, addr)
- }
- if err != nil {
- t.Fatalf("net.Dial(%q, %q) = _, %v", network, addr, err)
- }
- fd.SetReadTimeout(1e9) // 1s
-
- var b []byte
- if !isEmpty {
- b = []byte("hello, world\n")
- }
- var b1 [100]byte
-
- n, err1 := fd.Write(b)
- if n != len(b) {
- t.Fatalf("fd.Write(%q) = %d, %v", b, n, err1)
- }
-
- n, err1 = fd.Read(b1[0:])
- if n != len(b) || err1 != nil {
- t.Fatalf("fd.Read() = %d, %v (want %d, nil)", n, err1, len(b))
- }
-
- // Send explicit ending for unixpacket.
- // Older Linux kernels do stop reads on close.
- if network == "unixpacket" {
- fd.Write([]byte("END"))
- }
-
- fd.Close()
-}
-
-func doTest(t *testing.T, network, listenaddr, dialaddr string) {
- t.Logf("Test %q %q %q\n", network, listenaddr, dialaddr)
- switch listenaddr {
- case "", "0.0.0.0", "[::]", "[::ffff:0.0.0.0]":
- if testing.Short() || avoidMacFirewall {
- t.Logf("skip wildcard listen during short test")
- return
- }
- }
- listening := make(chan string)
- done := make(chan int)
- if network == "tcp" || network == "tcp4" || network == "tcp6" {
- listenaddr += ":0" // any available port
- }
- go runServe(t, network, listenaddr, listening, done)
- addr := <-listening // wait for server to start
- if network == "tcp" || network == "tcp4" || network == "tcp6" {
- dialaddr += addr[strings.LastIndex(addr, ":"):]
- }
- connect(t, network, dialaddr, false)
- <-done // make sure server stopped
-}
-
-func TestTCPServer(t *testing.T) {
- doTest(t, "tcp", "", "127.0.0.1")
- doTest(t, "tcp", "0.0.0.0", "127.0.0.1")
- doTest(t, "tcp", "127.0.0.1", "127.0.0.1")
- doTest(t, "tcp4", "", "127.0.0.1")
- doTest(t, "tcp4", "0.0.0.0", "127.0.0.1")
- doTest(t, "tcp4", "127.0.0.1", "127.0.0.1")
- if supportsIPv6 {
- doTest(t, "tcp", "", "[::1]")
- doTest(t, "tcp", "[::]", "[::1]")
- doTest(t, "tcp", "[::1]", "[::1]")
- doTest(t, "tcp6", "", "[::1]")
- doTest(t, "tcp6", "[::]", "[::1]")
- doTest(t, "tcp6", "[::1]", "[::1]")
- }
- if supportsIPv6 && supportsIPv4map {
- doTest(t, "tcp", "[::ffff:0.0.0.0]", "127.0.0.1")
- doTest(t, "tcp", "[::]", "127.0.0.1")
- doTest(t, "tcp4", "[::ffff:0.0.0.0]", "127.0.0.1")
- doTest(t, "tcp6", "", "127.0.0.1")
- doTest(t, "tcp6", "[::ffff:0.0.0.0]", "127.0.0.1")
- doTest(t, "tcp6", "[::]", "127.0.0.1")
- doTest(t, "tcp", "127.0.0.1", "[::ffff:127.0.0.1]")
- doTest(t, "tcp", "[::ffff:127.0.0.1]", "127.0.0.1")
- doTest(t, "tcp4", "127.0.0.1", "[::ffff:127.0.0.1]")
- doTest(t, "tcp4", "[::ffff:127.0.0.1]", "127.0.0.1")
- doTest(t, "tcp6", "127.0.0.1", "[::ffff:127.0.0.1]")
- doTest(t, "tcp6", "[::ffff:127.0.0.1]", "127.0.0.1")
- }
-}
-
-func TestUnixServer(t *testing.T) {
- // "unix" sockets are not supported on windows.
- if runtime.GOOS == "windows" {
- return
- }
- os.Remove("/tmp/gotest.net")
- doTest(t, "unix", "/tmp/gotest.net", "/tmp/gotest.net")
- os.Remove("/tmp/gotest.net")
- if syscall.OS == "linux" {
- doTest(t, "unixpacket", "/tmp/gotest.net", "/tmp/gotest.net")
- os.Remove("/tmp/gotest.net")
- // Test abstract unix domain socket, a Linux-ism
- doTest(t, "unix", "@gotest/net", "@gotest/net")
- doTest(t, "unixpacket", "@gotest/net", "@gotest/net")
- }
-}
-
-func runPacket(t *testing.T, network, addr string, listening chan<- string, done chan<- int) {
- c, err := ListenPacket(network, addr)
- if err != nil {
- t.Fatalf("net.ListenPacket(%q, %q) = _, %v", network, addr, err)
- }
- listening <- c.LocalAddr().String()
- c.SetReadTimeout(10e6) // 10ms
- var buf [1000]byte
-Run:
- for {
- n, addr, err := c.ReadFrom(buf[0:])
- if e, ok := err.(Error); ok && e.Timeout() {
- select {
- case done <- 1:
- break Run
- default:
- continue Run
- }
- }
- if err != nil {
- break
- }
- if _, err = c.WriteTo(buf[0:n], addr); err != nil {
- t.Fatalf("WriteTo %v: %v", addr, err)
- }
- }
- c.Close()
- done <- 1
-}
-
-func doTestPacket(t *testing.T, network, listenaddr, dialaddr string, isEmpty bool) {
- t.Logf("TestPacket %s %s %s\n", network, listenaddr, dialaddr)
- listening := make(chan string)
- done := make(chan int)
- if network == "udp" {
- listenaddr += ":0" // any available port
- }
- go runPacket(t, network, listenaddr, listening, done)
- addr := <-listening // wait for server to start
- if network == "udp" {
- dialaddr += addr[strings.LastIndex(addr, ":"):]
- }
- connect(t, network, dialaddr, isEmpty)
- <-done // tell server to stop
- <-done // wait for stop
-}
-
-func TestUDPServer(t *testing.T) {
- if !*testUDP {
- return
- }
- for _, isEmpty := range []bool{false, true} {
- doTestPacket(t, "udp", "0.0.0.0", "127.0.0.1", isEmpty)
- doTestPacket(t, "udp", "", "127.0.0.1", isEmpty)
- if supportsIPv6 && supportsIPv4map {
- doTestPacket(t, "udp", "[::]", "[::ffff:127.0.0.1]", isEmpty)
- doTestPacket(t, "udp", "[::]", "127.0.0.1", isEmpty)
- doTestPacket(t, "udp", "0.0.0.0", "[::ffff:127.0.0.1]", isEmpty)
- }
- }
-}
-
-func TestUnixDatagramServer(t *testing.T) {
- // "unix" sockets are not supported on windows.
- if runtime.GOOS == "windows" {
- return
- }
- for _, isEmpty := range []bool{false} {
- os.Remove("/tmp/gotest1.net")
- os.Remove("/tmp/gotest1.net.local")
- doTestPacket(t, "unixgram", "/tmp/gotest1.net", "/tmp/gotest1.net", isEmpty)
- os.Remove("/tmp/gotest1.net")
- os.Remove("/tmp/gotest1.net.local")
- if syscall.OS == "linux" {
- // Test abstract unix domain socket, a Linux-ism
- doTestPacket(t, "unixgram", "@gotest1/net", "@gotest1/net", isEmpty)
- }
- }
-}
diff --git a/src/pkg/net/sock.go b/src/pkg/net/sock.go
deleted file mode 100644
index 821716e43..000000000
--- a/src/pkg/net/sock.go
+++ /dev/null
@@ -1,166 +0,0 @@
-// 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.
-
-// Sockets
-
-package net
-
-import (
- "io"
- "os"
- "reflect"
- "syscall"
-)
-
-// Boolean to int.
-func boolint(b bool) int {
- if b {
- return 1
- }
- return 0
-}
-
-// Generic socket creation.
-func socket(net string, f, p, t int, la, ra syscall.Sockaddr, toAddr func(syscall.Sockaddr) Addr) (fd *netFD, err os.Error) {
- // See ../syscall/exec.go for description of ForkLock.
- syscall.ForkLock.RLock()
- s, e := syscall.Socket(f, p, t)
- if e != 0 {
- syscall.ForkLock.RUnlock()
- return nil, os.Errno(e)
- }
- syscall.CloseOnExec(s)
- syscall.ForkLock.RUnlock()
-
- setKernelSpecificSockopt(s, f)
-
- if la != nil {
- e = syscall.Bind(s, la)
- if e != 0 {
- closesocket(s)
- return nil, os.Errno(e)
- }
- }
-
- if fd, err = newFD(s, f, p, net); err != nil {
- closesocket(s)
- return nil, err
- }
-
- if ra != nil {
- if err = fd.connect(ra); err != nil {
- fd.Close()
- return nil, err
- }
- }
-
- sa, _ := syscall.Getsockname(s)
- laddr := toAddr(sa)
- sa, _ = syscall.Getpeername(s)
- raddr := toAddr(sa)
-
- fd.setAddr(laddr, raddr)
- return fd, nil
-}
-
-func setsockoptInt(fd *netFD, level, opt int, value int) os.Error {
- return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, level, opt, value))
-}
-
-func setsockoptNsec(fd *netFD, level, opt int, nsec int64) os.Error {
- var tv = syscall.NsecToTimeval(nsec)
- return os.NewSyscallError("setsockopt", syscall.SetsockoptTimeval(fd.sysfd, level, opt, &tv))
-}
-
-func setReadBuffer(fd *netFD, bytes int) os.Error {
- fd.incref()
- defer fd.decref()
- return setsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_RCVBUF, bytes)
-}
-
-func setWriteBuffer(fd *netFD, bytes int) os.Error {
- fd.incref()
- defer fd.decref()
- return setsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_SNDBUF, bytes)
-}
-
-func setReadTimeout(fd *netFD, nsec int64) os.Error {
- fd.rdeadline_delta = nsec
- return nil
-}
-
-func setWriteTimeout(fd *netFD, nsec int64) os.Error {
- fd.wdeadline_delta = nsec
- return nil
-}
-
-func setTimeout(fd *netFD, nsec int64) os.Error {
- if e := setReadTimeout(fd, nsec); e != nil {
- return e
- }
- return setWriteTimeout(fd, nsec)
-}
-
-func setReuseAddr(fd *netFD, reuse bool) os.Error {
- fd.incref()
- defer fd.decref()
- return setsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, boolint(reuse))
-}
-
-func bindToDevice(fd *netFD, dev string) os.Error {
- // TODO(rsc): call setsockopt with null-terminated string pointer
- return os.EINVAL
-}
-
-func setDontRoute(fd *netFD, dontroute bool) os.Error {
- fd.incref()
- defer fd.decref()
- return setsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_DONTROUTE, boolint(dontroute))
-}
-
-func setKeepAlive(fd *netFD, keepalive bool) os.Error {
- fd.incref()
- defer fd.decref()
- return setsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, boolint(keepalive))
-}
-
-func setNoDelay(fd *netFD, noDelay bool) os.Error {
- fd.incref()
- defer fd.decref()
- return setsockoptInt(fd, syscall.IPPROTO_TCP, syscall.TCP_NODELAY, boolint(noDelay))
-}
-
-func setLinger(fd *netFD, sec int) os.Error {
- var l syscall.Linger
- if sec >= 0 {
- l.Onoff = 1
- l.Linger = int32(sec)
- } else {
- l.Onoff = 0
- l.Linger = 0
- }
- fd.incref()
- defer fd.decref()
- e := syscall.SetsockoptLinger(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_LINGER, &l)
- return os.NewSyscallError("setsockopt", e)
-}
-
-type UnknownSocketError struct {
- sa syscall.Sockaddr
-}
-
-func (e *UnknownSocketError) String() string {
- return "unknown socket address type " + reflect.TypeOf(e.sa).String()
-}
-
-type writerOnly struct {
- io.Writer
-}
-
-// Fallback implementation of io.ReaderFrom's ReadFrom, when sendfile isn't
-// applicable.
-func genericReadFrom(w io.Writer, r io.Reader) (n int64, err os.Error) {
- // Use wrapper to hide existing r.ReadFrom from io.Copy.
- return io.Copy(writerOnly{w}, r)
-}
diff --git a/src/pkg/net/sock_bsd.go b/src/pkg/net/sock_bsd.go
deleted file mode 100644
index 5fd52074a..000000000
--- a/src/pkg/net/sock_bsd.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// 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.
-
-// Sockets for BSD variants
-
-package net
-
-import (
- "syscall"
-)
-
-func setKernelSpecificSockopt(s, f int) {
- // Allow reuse of recently-used addresses.
- syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1)
-
- // Allow reuse of recently-used ports.
- // This option is supported only in descendants of 4.4BSD,
- // to make an effective multicast application and an application
- // that requires quick draw possible.
- syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEPORT, 1)
-
- // Allow broadcast.
- syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1)
-
- if f == syscall.AF_INET6 {
- // using ip, tcp, udp, etc.
- // allow both protocols even if the OS default is otherwise.
- syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, 0)
- }
-}
diff --git a/src/pkg/net/sock_linux.go b/src/pkg/net/sock_linux.go
deleted file mode 100644
index ec31e803b..000000000
--- a/src/pkg/net/sock_linux.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// 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.
-
-// Sockets for Linux
-
-package net
-
-import (
- "syscall"
-)
-
-func setKernelSpecificSockopt(s, f int) {
- // Allow reuse of recently-used addresses.
- syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1)
-
- // Allow broadcast.
- syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1)
-
- if f == syscall.AF_INET6 {
- // using ip, tcp, udp, etc.
- // allow both protocols even if the OS default is otherwise.
- syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, 0)
- }
-}
diff --git a/src/pkg/net/sock_windows.go b/src/pkg/net/sock_windows.go
deleted file mode 100644
index c6dbd0465..000000000
--- a/src/pkg/net/sock_windows.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// 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.
-
-// Sockets for Windows
-
-package net
-
-import (
- "syscall"
-)
-
-func setKernelSpecificSockopt(s syscall.Handle, f int) {
- // Allow reuse of recently-used addresses and ports.
- syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1)
-
- // Allow broadcast.
- syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1)
-
- if f == syscall.AF_INET6 {
- // using ip, tcp, udp, etc.
- // allow both protocols even if the OS default is otherwise.
- syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, 0)
- }
-}
diff --git a/src/pkg/net/srv_test.go b/src/pkg/net/srv_test.go
deleted file mode 100644
index f1c7a0ab4..000000000
--- a/src/pkg/net/srv_test.go
+++ /dev/null
@@ -1,29 +0,0 @@
-// 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.
-
-// TODO It would be nice to use a mock DNS server, to eliminate
-// external dependencies.
-
-package net
-
-import (
- "runtime"
- "testing"
-)
-
-var avoidMacFirewall = runtime.GOOS == "darwin"
-
-func TestGoogleSRV(t *testing.T) {
- if testing.Short() || avoidMacFirewall {
- t.Logf("skipping test to avoid external network")
- return
- }
- _, addrs, err := LookupSRV("xmpp-server", "tcp", "google.com")
- if err != nil {
- t.Errorf("failed: %s", err)
- }
- if len(addrs) == 0 {
- t.Errorf("no results")
- }
-}
diff --git a/src/pkg/net/tcpsock.go b/src/pkg/net/tcpsock.go
deleted file mode 100644
index 9ee6c14f7..000000000
--- a/src/pkg/net/tcpsock.go
+++ /dev/null
@@ -1,304 +0,0 @@
-// 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.
-
-// TCP sockets
-
-package net
-
-import (
- "io"
- "os"
- "syscall"
-)
-
-func sockaddrToTCP(sa syscall.Sockaddr) Addr {
- switch sa := sa.(type) {
- case *syscall.SockaddrInet4:
- return &TCPAddr{sa.Addr[0:], sa.Port}
- case *syscall.SockaddrInet6:
- return &TCPAddr{sa.Addr[0:], sa.Port}
- }
- return nil
-}
-
-// TCPAddr represents the address of a TCP end point.
-type TCPAddr struct {
- IP IP
- Port int
-}
-
-// Network returns the address's network name, "tcp".
-func (a *TCPAddr) Network() string { return "tcp" }
-
-func (a *TCPAddr) String() string {
- if a == nil {
- return "<nil>"
- }
- return JoinHostPort(a.IP.String(), itoa(a.Port))
-}
-
-func (a *TCPAddr) family() int {
- if a == nil || len(a.IP) <= 4 {
- return syscall.AF_INET
- }
- if a.IP.To4() != nil {
- return syscall.AF_INET
- }
- return syscall.AF_INET6
-}
-
-func (a *TCPAddr) sockaddr(family int) (syscall.Sockaddr, os.Error) {
- return ipToSockaddr(family, a.IP, a.Port)
-}
-
-func (a *TCPAddr) toAddr() sockaddr {
- if a == nil { // nil *TCPAddr
- return nil // nil interface
- }
- return a
-}
-
-// ResolveTCPAddr parses addr as a TCP address of the form
-// host:port and resolves domain names or port names to
-// numeric addresses on the network net, which must be "tcp",
-// "tcp4" or "tcp6". A literal IPv6 host address must be
-// enclosed in square brackets, as in "[::]:80".
-func ResolveTCPAddr(net, addr string) (*TCPAddr, os.Error) {
- ip, port, err := hostPortToIP(net, addr)
- if err != nil {
- return nil, err
- }
- return &TCPAddr{ip, port}, nil
-}
-
-// TCPConn is an implementation of the Conn interface
-// for TCP network connections.
-type TCPConn struct {
- fd *netFD
-}
-
-func newTCPConn(fd *netFD) *TCPConn {
- c := &TCPConn{fd}
- c.SetNoDelay(true)
- return c
-}
-
-func (c *TCPConn) ok() bool { return c != nil && c.fd != nil }
-
-// Implementation of the Conn interface - see Conn for documentation.
-
-// Read implements the net.Conn Read method.
-func (c *TCPConn) Read(b []byte) (n int, err os.Error) {
- if !c.ok() {
- return 0, os.EINVAL
- }
- return c.fd.Read(b)
-}
-
-// ReadFrom implements the io.ReaderFrom ReadFrom method.
-func (c *TCPConn) ReadFrom(r io.Reader) (int64, os.Error) {
- if n, err, handled := sendFile(c.fd, r); handled {
- return n, err
- }
- return genericReadFrom(c, r)
-}
-
-// Write implements the net.Conn Write method.
-func (c *TCPConn) Write(b []byte) (n int, err os.Error) {
- if !c.ok() {
- return 0, os.EINVAL
- }
- return c.fd.Write(b)
-}
-
-// Close closes the TCP connection.
-func (c *TCPConn) Close() os.Error {
- if !c.ok() {
- return os.EINVAL
- }
- err := c.fd.Close()
- c.fd = nil
- return err
-}
-
-// LocalAddr returns the local network address, a *TCPAddr.
-func (c *TCPConn) LocalAddr() Addr {
- if !c.ok() {
- return nil
- }
- return c.fd.laddr
-}
-
-// RemoteAddr returns the remote network address, a *TCPAddr.
-func (c *TCPConn) RemoteAddr() Addr {
- if !c.ok() {
- return nil
- }
- return c.fd.raddr
-}
-
-// SetTimeout implements the net.Conn SetTimeout method.
-func (c *TCPConn) SetTimeout(nsec int64) os.Error {
- if !c.ok() {
- return os.EINVAL
- }
- return setTimeout(c.fd, nsec)
-}
-
-// SetReadTimeout implements the net.Conn SetReadTimeout method.
-func (c *TCPConn) SetReadTimeout(nsec int64) os.Error {
- if !c.ok() {
- return os.EINVAL
- }
- return setReadTimeout(c.fd, nsec)
-}
-
-// SetWriteTimeout implements the net.Conn SetWriteTimeout method.
-func (c *TCPConn) SetWriteTimeout(nsec int64) os.Error {
- if !c.ok() {
- return os.EINVAL
- }
- return setWriteTimeout(c.fd, nsec)
-}
-
-// SetReadBuffer sets the size of the operating system's
-// receive buffer associated with the connection.
-func (c *TCPConn) SetReadBuffer(bytes int) os.Error {
- if !c.ok() {
- return os.EINVAL
- }
- return setReadBuffer(c.fd, bytes)
-}
-
-// SetWriteBuffer sets the size of the operating system's
-// transmit buffer associated with the connection.
-func (c *TCPConn) SetWriteBuffer(bytes int) os.Error {
- if !c.ok() {
- return os.EINVAL
- }
- return setWriteBuffer(c.fd, bytes)
-}
-
-// SetLinger sets the behavior of Close() on a connection
-// which still has data waiting to be sent or to be acknowledged.
-//
-// If sec < 0 (the default), Close returns immediately and
-// the operating system finishes sending the data in the background.
-//
-// If sec == 0, Close returns immediately and the operating system
-// discards any unsent or unacknowledged data.
-//
-// If sec > 0, Close blocks for at most sec seconds waiting for
-// data to be sent and acknowledged.
-func (c *TCPConn) SetLinger(sec int) os.Error {
- if !c.ok() {
- return os.EINVAL
- }
- return setLinger(c.fd, sec)
-}
-
-// SetKeepAlive sets whether the operating system should send
-// keepalive messages on the connection.
-func (c *TCPConn) SetKeepAlive(keepalive bool) os.Error {
- if !c.ok() {
- return os.EINVAL
- }
- return setKeepAlive(c.fd, keepalive)
-}
-
-// SetNoDelay controls whether the operating system should delay
-// packet transmission in hopes of sending fewer packets
-// (Nagle's algorithm). The default is true (no delay), meaning
-// that data is sent as soon as possible after a Write.
-func (c *TCPConn) SetNoDelay(noDelay bool) os.Error {
- if !c.ok() {
- return os.EINVAL
- }
- return setNoDelay(c.fd, noDelay)
-}
-
-// File returns a copy of the underlying os.File, set to blocking mode.
-// It is the caller's responsibility to close f when finished.
-// Closing c does not affect f, and closing f does not affect c.
-func (c *TCPConn) File() (f *os.File, err os.Error) { return c.fd.dup() }
-
-// DialTCP connects to the remote address raddr on the network net,
-// which must be "tcp", "tcp4", or "tcp6". If laddr is not nil, it is used
-// as the local address for the connection.
-func DialTCP(net string, laddr, raddr *TCPAddr) (c *TCPConn, err os.Error) {
- if raddr == nil {
- return nil, &OpError{"dial", "tcp", nil, errMissingAddress}
- }
- fd, e := internetSocket(net, laddr.toAddr(), raddr.toAddr(), syscall.SOCK_STREAM, 0, "dial", sockaddrToTCP)
- if e != nil {
- return nil, e
- }
- return newTCPConn(fd), nil
-}
-
-// TCPListener is a TCP network listener.
-// Clients should typically use variables of type Listener
-// instead of assuming TCP.
-type TCPListener struct {
- fd *netFD
-}
-
-// 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 string, laddr *TCPAddr) (l *TCPListener, err os.Error) {
- fd, err := internetSocket(net, laddr.toAddr(), nil, syscall.SOCK_STREAM, 0, "listen", sockaddrToTCP)
- if err != nil {
- return nil, err
- }
- errno := syscall.Listen(fd.sysfd, listenBacklog())
- if errno != 0 {
- closesocket(fd.sysfd)
- return nil, &OpError{"listen", "tcp", laddr, os.Errno(errno)}
- }
- l = new(TCPListener)
- l.fd = fd
- return l, nil
-}
-
-// AcceptTCP accepts the next incoming call and returns the new connection
-// and the remote address.
-func (l *TCPListener) AcceptTCP() (c *TCPConn, err os.Error) {
- if l == nil || l.fd == nil || l.fd.sysfd < 0 {
- return nil, os.EINVAL
- }
- fd, err := l.fd.accept(sockaddrToTCP)
- if err != nil {
- return nil, err
- }
- return newTCPConn(fd), nil
-}
-
-// Accept implements the Accept method in the Listener interface;
-// it waits for the next call and returns a generic Conn.
-func (l *TCPListener) Accept() (c Conn, err os.Error) {
- c1, err := l.AcceptTCP()
- if err != nil {
- return nil, err
- }
- return c1, nil
-}
-
-// Close stops listening on the TCP address.
-// Already Accepted connections are not closed.
-func (l *TCPListener) Close() os.Error {
- if l == nil || l.fd == nil {
- return os.EINVAL
- }
- return l.fd.Close()
-}
-
-// Addr returns the listener's network address, a *TCPAddr.
-func (l *TCPListener) Addr() Addr { return l.fd.laddr }
-
-// File returns a copy of the underlying os.File, set to blocking mode.
-// It is the caller's responsibility to close f when finished.
-// Closing c does not affect f, and closing f does not affect c.
-func (l *TCPListener) File() (f *os.File, err os.Error) { return l.fd.dup() }
diff --git a/src/pkg/net/textproto/Makefile b/src/pkg/net/textproto/Makefile
deleted file mode 100644
index cadf3ab69..000000000
--- a/src/pkg/net/textproto/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2010 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.
-
-include ../../../Make.inc
-
-TARG=net/textproto
-GOFILES=\
- header.go\
- pipeline.go\
- reader.go\
- textproto.go\
- writer.go\
-
-include ../../../Make.pkg
diff --git a/src/pkg/net/textproto/header.go b/src/pkg/net/textproto/header.go
deleted file mode 100644
index 288deb2ce..000000000
--- a/src/pkg/net/textproto/header.go
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2010 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 textproto
-
-// A MIMEHeader represents a MIME-style header mapping
-// keys to sets of values.
-type MIMEHeader map[string][]string
-
-// Add adds the key, value pair to the header.
-// It appends to any existing values associated with key.
-func (h MIMEHeader) Add(key, value string) {
- key = CanonicalMIMEHeaderKey(key)
- h[key] = append(h[key], value)
-}
-
-// Set sets the header entries associated with key to
-// the single element value. It replaces any existing
-// values associated with key.
-func (h MIMEHeader) Set(key, value string) {
- h[CanonicalMIMEHeaderKey(key)] = []string{value}
-}
-
-// Get gets the first value associated with the given key.
-// If there are no values associated with the key, Get returns "".
-// Get is a convenience method. For more complex queries,
-// access the map directly.
-func (h MIMEHeader) Get(key string) string {
- if h == nil {
- return ""
- }
- v := h[CanonicalMIMEHeaderKey(key)]
- if len(v) == 0 {
- return ""
- }
- return v[0]
-}
-
-// Del deletes the values associated with key.
-func (h MIMEHeader) Del(key string) {
- h[CanonicalMIMEHeaderKey(key)] = nil, false
-}
diff --git a/src/pkg/net/textproto/pipeline.go b/src/pkg/net/textproto/pipeline.go
deleted file mode 100644
index 8c25884b3..000000000
--- a/src/pkg/net/textproto/pipeline.go
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright 2010 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 textproto
-
-import (
- "sync"
-)
-
-// A Pipeline manages a pipelined in-order request/response sequence.
-//
-// To use a Pipeline p to manage multiple clients on a connection,
-// each client should run:
-//
-// id := p.Next() // take a number
-//
-// p.StartRequest(id) // wait for turn to send request
-// «send request»
-// p.EndRequest(id) // notify Pipeline that request is sent
-//
-// p.StartResponse(id) // wait for turn to read response
-// «read response»
-// p.EndResponse(id) // notify Pipeline that response is read
-//
-// A pipelined server can use the same calls to ensure that
-// responses computed in parallel are written in the correct order.
-type Pipeline struct {
- mu sync.Mutex
- id uint
- request sequencer
- response sequencer
-}
-
-// Next returns the next id for a request/response pair.
-func (p *Pipeline) Next() uint {
- p.mu.Lock()
- id := p.id
- p.id++
- p.mu.Unlock()
- return id
-}
-
-// StartRequest blocks until it is time to send (or, if this is a server, receive)
-// the request with the given id.
-func (p *Pipeline) StartRequest(id uint) {
- p.request.Start(id)
-}
-
-// EndRequest notifies p that the request with the given id has been sent
-// (or, if this is a server, received).
-func (p *Pipeline) EndRequest(id uint) {
- p.request.End(id)
-}
-
-// StartResponse blocks until it is time to receive (or, if this is a server, send)
-// the request with the given id.
-func (p *Pipeline) StartResponse(id uint) {
- p.response.Start(id)
-}
-
-// EndResponse notifies p that the response with the given id has been received
-// (or, if this is a server, sent).
-func (p *Pipeline) EndResponse(id uint) {
- p.response.End(id)
-}
-
-// A sequencer schedules a sequence of numbered events that must
-// happen in order, one after the other. The event numbering must start
-// at 0 and increment without skipping. The event number wraps around
-// safely as long as there are not 2^32 simultaneous events pending.
-type sequencer struct {
- mu sync.Mutex
- id uint
- wait map[uint]chan uint
-}
-
-// Start waits until it is time for the event numbered id to begin.
-// That is, except for the first event, it waits until End(id-1) has
-// been called.
-func (s *sequencer) Start(id uint) {
- s.mu.Lock()
- if s.id == id {
- s.mu.Unlock()
- return
- }
- c := make(chan uint)
- if s.wait == nil {
- s.wait = make(map[uint]chan uint)
- }
- s.wait[id] = c
- s.mu.Unlock()
- <-c
-}
-
-// End notifies the sequencer that the event numbered id has completed,
-// allowing it to schedule the event numbered id+1. It is a run-time error
-// to call End with an id that is not the number of the active event.
-func (s *sequencer) End(id uint) {
- s.mu.Lock()
- if s.id != id {
- panic("out of sync")
- }
- id++
- s.id = id
- if s.wait == nil {
- s.wait = make(map[uint]chan uint)
- }
- c, ok := s.wait[id]
- if ok {
- s.wait[id] = nil, false
- }
- s.mu.Unlock()
- if ok {
- c <- 1
- }
-}
diff --git a/src/pkg/net/textproto/reader.go b/src/pkg/net/textproto/reader.go
deleted file mode 100644
index e65374903..000000000
--- a/src/pkg/net/textproto/reader.go
+++ /dev/null
@@ -1,492 +0,0 @@
-// Copyright 2010 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 textproto
-
-import (
- "bufio"
- "bytes"
- "container/vector"
- "io"
- "io/ioutil"
- "os"
- "strconv"
-)
-
-// BUG(rsc): To let callers manage exposure to denial of service
-// attacks, Reader should allow them to set and reset a limit on
-// the number of bytes read from the connection.
-
-// A Reader implements convenience methods for reading requests
-// or responses from a text protocol network connection.
-type Reader struct {
- R *bufio.Reader
- dot *dotReader
-}
-
-// NewReader returns a new Reader reading from r.
-func NewReader(r *bufio.Reader) *Reader {
- return &Reader{R: r}
-}
-
-// ReadLine reads a single line from r,
-// eliding the final \n or \r\n from the returned string.
-func (r *Reader) ReadLine() (string, os.Error) {
- line, err := r.ReadLineBytes()
- return string(line), err
-}
-
-// ReadLineBytes is like ReadLine but returns a []byte instead of a string.
-func (r *Reader) ReadLineBytes() ([]byte, os.Error) {
- r.closeDot()
- line, err := r.R.ReadBytes('\n')
- n := len(line)
- if n > 0 && line[n-1] == '\n' {
- n--
- if n > 0 && line[n-1] == '\r' {
- n--
- }
- }
- return line[0:n], err
-}
-
-// ReadContinuedLine reads a possibly continued line from r,
-// eliding the final trailing ASCII white space.
-// Lines after the first are considered continuations if they
-// begin with a space or tab character. In the returned data,
-// continuation lines are separated from the previous line
-// only by a single space: the newline and leading white space
-// are removed.
-//
-// For example, consider this input:
-//
-// Line 1
-// continued...
-// Line 2
-//
-// The first call to ReadContinuedLine will return "Line 1 continued..."
-// and the second will return "Line 2".
-//
-// A line consisting of only white space is never continued.
-//
-func (r *Reader) ReadContinuedLine() (string, os.Error) {
- line, err := r.ReadContinuedLineBytes()
- return string(line), err
-}
-
-// trim returns s with leading and trailing spaces and tabs removed.
-// It does not assume Unicode or UTF-8.
-func trim(s []byte) []byte {
- i := 0
- for i < len(s) && (s[i] == ' ' || s[i] == '\t') {
- i++
- }
- n := len(s)
- for n > i && (s[n-1] == ' ' || s[n-1] == '\t') {
- n--
- }
- return s[i:n]
-}
-
-// ReadContinuedLineBytes is like ReadContinuedLine but
-// returns a []byte instead of a string.
-func (r *Reader) ReadContinuedLineBytes() ([]byte, os.Error) {
- // Read the first line.
- line, err := r.ReadLineBytes()
- if err != nil {
- return line, err
- }
- if len(line) == 0 { // blank line - no continuation
- return line, nil
- }
- line = trim(line)
-
- // Look for a continuation line.
- c, err := r.R.ReadByte()
- if err != nil {
- // Delay err until we read the byte next time.
- return line, nil
- }
- if c != ' ' && c != '\t' {
- // Not a continuation.
- r.R.UnreadByte()
- return line, nil
- }
-
- // Read continuation lines.
- for {
- // Consume leading spaces; one already gone.
- for {
- c, err = r.R.ReadByte()
- if err != nil {
- break
- }
- if c != ' ' && c != '\t' {
- r.R.UnreadByte()
- break
- }
- }
- var cont []byte
- cont, err = r.ReadLineBytes()
- cont = trim(cont)
- line = append(line, ' ')
- line = append(line, cont...)
- if err != nil {
- break
- }
-
- // Check for leading space on next line.
- if c, err = r.R.ReadByte(); err != nil {
- break
- }
- if c != ' ' && c != '\t' {
- r.R.UnreadByte()
- break
- }
- }
-
- // Delay error until next call.
- if len(line) > 0 {
- err = nil
- }
- return line, err
-}
-
-func (r *Reader) readCodeLine(expectCode int) (code int, continued bool, message string, err os.Error) {
- line, err := r.ReadLine()
- if err != nil {
- return
- }
- if len(line) < 4 || line[3] != ' ' && line[3] != '-' {
- err = ProtocolError("short response: " + line)
- return
- }
- continued = line[3] == '-'
- code, err = strconv.Atoi(line[0:3])
- if err != nil || code < 100 {
- err = ProtocolError("invalid response code: " + line)
- return
- }
- message = line[4:]
- if 1 <= expectCode && expectCode < 10 && code/100 != expectCode ||
- 10 <= expectCode && expectCode < 100 && code/10 != expectCode ||
- 100 <= expectCode && expectCode < 1000 && code != expectCode {
- err = &Error{code, message}
- }
- return
-}
-
-// ReadCodeLine reads a response code line of the form
-// code message
-// where code is a 3-digit status code and the message
-// extends to the rest of the line. An example of such a line is:
-// 220 plan9.bell-labs.com ESMTP
-//
-// If the prefix of the status does not match the digits in expectCode,
-// ReadCodeLine returns with err set to &Error{code, message}.
-// For example, if expectCode is 31, an error will be returned if
-// the status is not in the range [310,319].
-//
-// If the response is multi-line, ReadCodeLine returns an error.
-//
-// An expectCode <= 0 disables the check of the status code.
-//
-func (r *Reader) ReadCodeLine(expectCode int) (code int, message string, err os.Error) {
- code, continued, message, err := r.readCodeLine(expectCode)
- if err == nil && continued {
- err = ProtocolError("unexpected multi-line response: " + message)
- }
- return
-}
-
-// ReadResponse reads a multi-line response of the form
-// code-message line 1
-// code-message line 2
-// ...
-// code message line n
-// where code is a 3-digit status code. Each line should have the same code.
-// The response is terminated by a line that uses a space between the code and
-// the message line rather than a dash. Each line in message is separated by
-// a newline (\n).
-//
-// If the prefix of the status does not match the digits in expectCode,
-// ReadResponse returns with err set to &Error{code, message}.
-// For example, if expectCode is 31, an error will be returned if
-// the status is not in the range [310,319].
-//
-// An expectCode <= 0 disables the check of the status code.
-//
-func (r *Reader) ReadResponse(expectCode int) (code int, message string, err os.Error) {
- code, continued, message, err := r.readCodeLine(expectCode)
- for err == nil && continued {
- var code2 int
- var moreMessage string
- code2, continued, moreMessage, err = r.readCodeLine(expectCode)
- if code != code2 {
- err = ProtocolError("status code mismatch: " + strconv.Itoa(code) + ", " + strconv.Itoa(code2))
- }
- message += "\n" + moreMessage
- }
- return
-}
-
-// DotReader returns a new Reader that satisfies Reads using the
-// decoded text of a dot-encoded block read from r.
-// The returned Reader is only valid until the next call
-// to a method on r.
-//
-// Dot encoding is a common framing used for data blocks
-// in text protocols such as SMTP. The data consists of a sequence
-// of lines, each of which ends in "\r\n". The sequence itself
-// ends at a line containing just a dot: ".\r\n". Lines beginning
-// with a dot are escaped with an additional dot to avoid
-// looking like the end of the sequence.
-//
-// The decoded form returned by the Reader's Read method
-// rewrites the "\r\n" line endings into the simpler "\n",
-// removes leading dot escapes if present, and stops with error os.EOF
-// after consuming (and discarding) the end-of-sequence line.
-func (r *Reader) DotReader() io.Reader {
- r.closeDot()
- r.dot = &dotReader{r: r}
- return r.dot
-}
-
-type dotReader struct {
- r *Reader
- state int
-}
-
-// Read satisfies reads by decoding dot-encoded data read from d.r.
-func (d *dotReader) Read(b []byte) (n int, err os.Error) {
- // Run data through a simple state machine to
- // elide leading dots, rewrite trailing \r\n into \n,
- // and detect ending .\r\n line.
- const (
- stateBeginLine = iota // beginning of line; initial state; must be zero
- stateDot // read . at beginning of line
- stateDotCR // read .\r at beginning of line
- stateCR // read \r (possibly at end of line)
- stateData // reading data in middle of line
- stateEOF // reached .\r\n end marker line
- )
- br := d.r.R
- for n < len(b) && d.state != stateEOF {
- var c byte
- c, err = br.ReadByte()
- if err != nil {
- if err == os.EOF {
- err = io.ErrUnexpectedEOF
- }
- break
- }
- switch d.state {
- case stateBeginLine:
- if c == '.' {
- d.state = stateDot
- continue
- }
- if c == '\r' {
- d.state = stateCR
- continue
- }
- d.state = stateData
-
- case stateDot:
- if c == '\r' {
- d.state = stateDotCR
- continue
- }
- if c == '\n' {
- d.state = stateEOF
- continue
- }
- d.state = stateData
-
- case stateDotCR:
- if c == '\n' {
- d.state = stateEOF
- continue
- }
- // Not part of .\r\n.
- // Consume leading dot and emit saved \r.
- br.UnreadByte()
- c = '\r'
- d.state = stateData
-
- case stateCR:
- if c == '\n' {
- d.state = stateBeginLine
- break
- }
- // Not part of \r\n. Emit saved \r
- br.UnreadByte()
- c = '\r'
- d.state = stateData
-
- case stateData:
- if c == '\r' {
- d.state = stateCR
- continue
- }
- if c == '\n' {
- d.state = stateBeginLine
- }
- }
- b[n] = c
- n++
- }
- if err == nil && d.state == stateEOF {
- err = os.EOF
- }
- if err != nil && d.r.dot == d {
- d.r.dot = nil
- }
- return
-}
-
-// closeDot drains the current DotReader if any,
-// making sure that it reads until the ending dot line.
-func (r *Reader) closeDot() {
- if r.dot == nil {
- return
- }
- buf := make([]byte, 128)
- for r.dot != nil {
- // When Read reaches EOF or an error,
- // it will set r.dot == nil.
- r.dot.Read(buf)
- }
-}
-
-// ReadDotBytes reads a dot-encoding and returns the decoded data.
-//
-// See the documentation for the DotReader method for details about dot-encoding.
-func (r *Reader) ReadDotBytes() ([]byte, os.Error) {
- return ioutil.ReadAll(r.DotReader())
-}
-
-// ReadDotLines reads a dot-encoding and returns a slice
-// containing the decoded lines, with the final \r\n or \n elided from each.
-//
-// See the documentation for the DotReader method for details about dot-encoding.
-func (r *Reader) ReadDotLines() ([]string, os.Error) {
- // We could use ReadDotBytes and then Split it,
- // but reading a line at a time avoids needing a
- // large contiguous block of memory and is simpler.
- var v vector.StringVector
- var err os.Error
- for {
- var line string
- line, err = r.ReadLine()
- if err != nil {
- if err == os.EOF {
- err = io.ErrUnexpectedEOF
- }
- break
- }
-
- // Dot by itself marks end; otherwise cut one dot.
- if len(line) > 0 && line[0] == '.' {
- if len(line) == 1 {
- break
- }
- line = line[1:]
- }
- v.Push(line)
- }
- return v, err
-}
-
-// ReadMIMEHeader reads a MIME-style header from r.
-// The header is a sequence of possibly continued Key: Value lines
-// ending in a blank line.
-// The returned map m maps CanonicalMIMEHeaderKey(key) to a
-// sequence of values in the same order encountered in the input.
-//
-// For example, consider this input:
-//
-// My-Key: Value 1
-// Long-Key: Even
-// Longer Value
-// My-Key: Value 2
-//
-// Given that input, ReadMIMEHeader returns the map:
-//
-// map[string][]string{
-// "My-Key": {"Value 1", "Value 2"},
-// "Long-Key": {"Even Longer Value"},
-// }
-//
-func (r *Reader) ReadMIMEHeader() (MIMEHeader, os.Error) {
- m := make(MIMEHeader)
- for {
- kv, err := r.ReadContinuedLineBytes()
- if len(kv) == 0 {
- return m, err
- }
-
- // Key ends at first colon; must not have spaces.
- i := bytes.IndexByte(kv, ':')
- if i < 0 || bytes.IndexByte(kv[0:i], ' ') >= 0 {
- return m, ProtocolError("malformed MIME header line: " + string(kv))
- }
- key := CanonicalMIMEHeaderKey(string(kv[0:i]))
-
- // Skip initial spaces in value.
- i++ // skip colon
- for i < len(kv) && (kv[i] == ' ' || kv[i] == '\t') {
- i++
- }
- value := string(kv[i:])
-
- v := vector.StringVector(m[key])
- v.Push(value)
- m[key] = v
-
- if err != nil {
- return m, err
- }
- }
- panic("unreachable")
-}
-
-// CanonicalMIMEHeaderKey returns the canonical format of the
-// MIME header key s. The canonicalization converts the first
-// letter and any letter following a hyphen to upper case;
-// the rest are converted to lowercase. For example, the
-// canonical key for "accept-encoding" is "Accept-Encoding".
-func CanonicalMIMEHeaderKey(s string) string {
- // Quick check for canonical encoding.
- needUpper := true
- for i := 0; i < len(s); i++ {
- c := s[i]
- if needUpper && 'a' <= c && c <= 'z' {
- goto MustRewrite
- }
- if !needUpper && 'A' <= c && c <= 'Z' {
- goto MustRewrite
- }
- needUpper = c == '-'
- }
- return s
-
-MustRewrite:
- // Canonicalize: first letter upper case
- // and upper case after each dash.
- // (Host, User-Agent, If-Modified-Since).
- // MIME headers are ASCII only, so no Unicode issues.
- a := []byte(s)
- upper := true
- for i, v := range a {
- if upper && 'a' <= v && v <= 'z' {
- a[i] = v + 'A' - 'a'
- }
- if !upper && 'A' <= v && v <= 'Z' {
- a[i] = v + 'a' - 'A'
- }
- upper = v == '-'
- }
- return string(a)
-}
diff --git a/src/pkg/net/textproto/reader_test.go b/src/pkg/net/textproto/reader_test.go
deleted file mode 100644
index 0658e58b8..000000000
--- a/src/pkg/net/textproto/reader_test.go
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright 2010 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 textproto
-
-import (
- "bufio"
- "io"
- "os"
- "reflect"
- "strings"
- "testing"
-)
-
-type canonicalHeaderKeyTest struct {
- in, out string
-}
-
-var canonicalHeaderKeyTests = []canonicalHeaderKeyTest{
- {"a-b-c", "A-B-C"},
- {"a-1-c", "A-1-C"},
- {"User-Agent", "User-Agent"},
- {"uSER-aGENT", "User-Agent"},
- {"user-agent", "User-Agent"},
- {"USER-AGENT", "User-Agent"},
-}
-
-func TestCanonicalMIMEHeaderKey(t *testing.T) {
- for _, tt := range canonicalHeaderKeyTests {
- if s := CanonicalMIMEHeaderKey(tt.in); s != tt.out {
- t.Errorf("CanonicalMIMEHeaderKey(%q) = %q, want %q", tt.in, s, tt.out)
- }
- }
-}
-
-func reader(s string) *Reader {
- return NewReader(bufio.NewReader(strings.NewReader(s)))
-}
-
-func TestReadLine(t *testing.T) {
- r := reader("line1\nline2\n")
- s, err := r.ReadLine()
- if s != "line1" || err != nil {
- t.Fatalf("Line 1: %s, %v", s, err)
- }
- s, err = r.ReadLine()
- if s != "line2" || err != nil {
- t.Fatalf("Line 2: %s, %v", s, err)
- }
- s, err = r.ReadLine()
- if s != "" || err != os.EOF {
- t.Fatalf("EOF: %s, %v", s, err)
- }
-}
-
-func TestReadContinuedLine(t *testing.T) {
- r := reader("line1\nline\n 2\nline3\n")
- s, err := r.ReadContinuedLine()
- if s != "line1" || err != nil {
- t.Fatalf("Line 1: %s, %v", s, err)
- }
- s, err = r.ReadContinuedLine()
- if s != "line 2" || err != nil {
- t.Fatalf("Line 2: %s, %v", s, err)
- }
- s, err = r.ReadContinuedLine()
- if s != "line3" || err != nil {
- t.Fatalf("Line 3: %s, %v", s, err)
- }
- s, err = r.ReadContinuedLine()
- if s != "" || err != os.EOF {
- t.Fatalf("EOF: %s, %v", s, err)
- }
-}
-
-func TestReadCodeLine(t *testing.T) {
- r := reader("123 hi\n234 bye\n345 no way\n")
- code, msg, err := r.ReadCodeLine(0)
- if code != 123 || msg != "hi" || err != nil {
- t.Fatalf("Line 1: %d, %s, %v", code, msg, err)
- }
- code, msg, err = r.ReadCodeLine(23)
- if code != 234 || msg != "bye" || err != nil {
- t.Fatalf("Line 2: %d, %s, %v", code, msg, err)
- }
- code, msg, err = r.ReadCodeLine(346)
- if code != 345 || msg != "no way" || err == nil {
- t.Fatalf("Line 3: %d, %s, %v", code, msg, err)
- }
- if e, ok := err.(*Error); !ok || e.Code != code || e.Msg != msg {
- t.Fatalf("Line 3: wrong error %v\n", err)
- }
- code, msg, err = r.ReadCodeLine(1)
- if code != 0 || msg != "" || err != os.EOF {
- t.Fatalf("EOF: %d, %s, %v", code, msg, err)
- }
-}
-
-func TestReadDotLines(t *testing.T) {
- r := reader("dotlines\r\n.foo\r\n..bar\n...baz\nquux\r\n\r\n.\r\nanother\n")
- s, err := r.ReadDotLines()
- want := []string{"dotlines", "foo", ".bar", "..baz", "quux", ""}
- if !reflect.DeepEqual(s, want) || err != nil {
- t.Fatalf("ReadDotLines: %v, %v", s, err)
- }
-
- s, err = r.ReadDotLines()
- want = []string{"another"}
- if !reflect.DeepEqual(s, want) || err != io.ErrUnexpectedEOF {
- t.Fatalf("ReadDotLines2: %v, %v", s, err)
- }
-}
-
-func TestReadDotBytes(t *testing.T) {
- r := reader("dotlines\r\n.foo\r\n..bar\n...baz\nquux\r\n\r\n.\r\nanot.her\r\n")
- b, err := r.ReadDotBytes()
- want := []byte("dotlines\nfoo\n.bar\n..baz\nquux\n\n")
- if !reflect.DeepEqual(b, want) || err != nil {
- t.Fatalf("ReadDotBytes: %q, %v", b, err)
- }
-
- b, err = r.ReadDotBytes()
- want = []byte("anot.her\n")
- if !reflect.DeepEqual(b, want) || err != io.ErrUnexpectedEOF {
- t.Fatalf("ReadDotBytes2: %q, %v", b, err)
- }
-}
-
-func TestReadMIMEHeader(t *testing.T) {
- r := reader("my-key: Value 1 \r\nLong-key: Even \n Longer Value\r\nmy-Key: Value 2\r\n\n")
- m, err := r.ReadMIMEHeader()
- want := MIMEHeader{
- "My-Key": {"Value 1", "Value 2"},
- "Long-Key": {"Even Longer Value"},
- }
- if !reflect.DeepEqual(m, want) || err != nil {
- t.Fatalf("ReadMIMEHeader: %v, %v; want %v", m, err, want)
- }
-}
diff --git a/src/pkg/net/textproto/textproto.go b/src/pkg/net/textproto/textproto.go
deleted file mode 100644
index 9f19b5495..000000000
--- a/src/pkg/net/textproto/textproto.go
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2010 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 textproto implements generic support for text-based request/response
-// protocols in the style of HTTP, NNTP, and SMTP.
-//
-// The package provides:
-//
-// Error, which represents a numeric error response from
-// a server.
-//
-// Pipeline, to manage pipelined requests and responses
-// in a client.
-//
-// Reader, to read numeric response code lines,
-// key: value headers, lines wrapped with leading spaces
-// on continuation lines, and whole text blocks ending
-// with a dot on a line by itself.
-//
-// Writer, to write dot-encoded text blocks.
-//
-package textproto
-
-import (
- "bufio"
- "fmt"
- "io"
- "net"
- "os"
-)
-
-// An Error represents a numeric error response from a server.
-type Error struct {
- Code int
- Msg string
-}
-
-func (e *Error) String() string {
- return fmt.Sprintf("%03d %s", e.Code, e.Msg)
-}
-
-// A ProtocolError describes a protocol violation such
-// as an invalid response or a hung-up connection.
-type ProtocolError string
-
-func (p ProtocolError) String() string {
- return string(p)
-}
-
-// A Conn represents a textual network protocol connection.
-// It consists of a Reader and Writer to manage I/O
-// and a Pipeline to sequence concurrent requests on the connection.
-// These embedded types carry methods with them;
-// see the documentation of those types for details.
-type Conn struct {
- Reader
- Writer
- Pipeline
- conn io.ReadWriteCloser
-}
-
-// NewConn returns a new Conn using conn for I/O.
-func NewConn(conn io.ReadWriteCloser) *Conn {
- return &Conn{
- Reader: Reader{R: bufio.NewReader(conn)},
- Writer: Writer{W: bufio.NewWriter(conn)},
- conn: conn,
- }
-}
-
-// Close closes the connection.
-func (c *Conn) Close() os.Error {
- return c.conn.Close()
-}
-
-// Dial connects to the given address on the given network using net.Dial
-// and then returns a new Conn for the connection.
-func Dial(network, addr string) (*Conn, os.Error) {
- c, err := net.Dial(network, addr)
- if err != nil {
- return nil, err
- }
- return NewConn(c), nil
-}
-
-// Cmd is a convenience method that sends a command after
-// waiting its turn in the pipeline. The command text is the
-// result of formatting format with args and appending \r\n.
-// Cmd returns the id of the command, for use with StartResponse and EndResponse.
-//
-// For example, a client might run a HELP command that returns a dot-body
-// by using:
-//
-// id, err := c.Cmd("HELP")
-// if err != nil {
-// return nil, err
-// }
-//
-// c.StartResponse(id)
-// defer c.EndResponse(id)
-//
-// if _, _, err = c.ReadCodeLine(110); err != nil {
-// return nil, err
-// }
-// text, err := c.ReadDotAll()
-// if err != nil {
-// return nil, err
-// }
-// return c.ReadCodeLine(250)
-//
-func (c *Conn) Cmd(format string, args ...interface{}) (id uint, err os.Error) {
- id = c.Next()
- c.StartRequest(id)
- err = c.PrintfLine(format, args...)
- c.EndRequest(id)
- if err != nil {
- return 0, err
- }
- return id, nil
-}
diff --git a/src/pkg/net/textproto/writer.go b/src/pkg/net/textproto/writer.go
deleted file mode 100644
index 4e705f6c3..000000000
--- a/src/pkg/net/textproto/writer.go
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2010 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 textproto
-
-import (
- "bufio"
- "fmt"
- "io"
- "os"
-)
-
-// A Writer implements convenience methods for writing
-// requests or responses to a text protocol network connection.
-type Writer struct {
- W *bufio.Writer
- dot *dotWriter
-}
-
-// NewWriter returns a new Writer writing to w.
-func NewWriter(w *bufio.Writer) *Writer {
- return &Writer{W: w}
-}
-
-var crnl = []byte{'\r', '\n'}
-var dotcrnl = []byte{'.', '\r', '\n'}
-
-// PrintfLine writes the formatted output followed by \r\n.
-func (w *Writer) PrintfLine(format string, args ...interface{}) os.Error {
- w.closeDot()
- fmt.Fprintf(w.W, format, args...)
- w.W.Write(crnl)
- return w.W.Flush()
-}
-
-// DotWriter returns a writer that can be used to write a dot-encoding to w.
-// It takes care of inserting leading dots when necessary,
-// translating line-ending \n into \r\n, and adding the final .\r\n line
-// when the DotWriter is closed. The caller should close the
-// DotWriter before the next call to a method on w.
-//
-// See the documentation for Reader's DotReader method for details about dot-encoding.
-func (w *Writer) DotWriter() io.WriteCloser {
- w.closeDot()
- w.dot = &dotWriter{w: w}
- return w.dot
-}
-
-func (w *Writer) closeDot() {
- if w.dot != nil {
- w.dot.Close() // sets w.dot = nil
- }
-}
-
-type dotWriter struct {
- w *Writer
- state int
-}
-
-const (
- wstateBeginLine = iota // beginning of line; initial state; must be zero
- wstateCR // wrote \r (possibly at end of line)
- wstateData // writing data in middle of line
-)
-
-func (d *dotWriter) Write(b []byte) (n int, err os.Error) {
- bw := d.w.W
- for n < len(b) {
- c := b[n]
- switch d.state {
- case wstateBeginLine:
- d.state = wstateData
- if c == '.' {
- // escape leading dot
- bw.WriteByte('.')
- }
- fallthrough
-
- case wstateData:
- if c == '\r' {
- d.state = wstateCR
- }
- if c == '\n' {
- bw.WriteByte('\r')
- d.state = wstateBeginLine
- }
-
- case wstateCR:
- d.state = wstateData
- if c == '\n' {
- d.state = wstateBeginLine
- }
- }
- if err = bw.WriteByte(c); err != nil {
- break
- }
- n++
- }
- return
-}
-
-func (d *dotWriter) Close() os.Error {
- if d.w.dot == d {
- d.w.dot = nil
- }
- bw := d.w.W
- switch d.state {
- default:
- bw.WriteByte('\r')
- fallthrough
- case wstateCR:
- bw.WriteByte('\n')
- fallthrough
- case wstateBeginLine:
- bw.Write(dotcrnl)
- }
- return bw.Flush()
-}
diff --git a/src/pkg/net/textproto/writer_test.go b/src/pkg/net/textproto/writer_test.go
deleted file mode 100644
index e03ab5e15..000000000
--- a/src/pkg/net/textproto/writer_test.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2010 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 textproto
-
-import (
- "bufio"
- "bytes"
- "testing"
-)
-
-func TestPrintfLine(t *testing.T) {
- var buf bytes.Buffer
- w := NewWriter(bufio.NewWriter(&buf))
- err := w.PrintfLine("foo %d", 123)
- if s := buf.String(); s != "foo 123\r\n" || err != nil {
- t.Fatalf("s=%q; err=%s", s, err)
- }
-}
-
-func TestDotWriter(t *testing.T) {
- var buf bytes.Buffer
- w := NewWriter(bufio.NewWriter(&buf))
- d := w.DotWriter()
- n, err := d.Write([]byte("abc\n.def\n..ghi\n.jkl\n."))
- if n != 21 || err != nil {
- t.Fatalf("Write: %d, %s", n, err)
- }
- d.Close()
- want := "abc\r\n..def\r\n...ghi\r\n..jkl\r\n..\r\n.\r\n"
- if s := buf.String(); s != want {
- t.Fatalf("wrote %q", s)
- }
-}
diff --git a/src/pkg/net/timeout_test.go b/src/pkg/net/timeout_test.go
deleted file mode 100644
index 0dbab5846..000000000
--- a/src/pkg/net/timeout_test.go
+++ /dev/null
@@ -1,57 +0,0 @@
-// 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.
-
-package net
-
-import (
- "os"
- "testing"
- "time"
-)
-
-func testTimeout(t *testing.T, network, addr string, readFrom bool) {
- fd, err := Dial(network, addr)
- if err != nil {
- t.Errorf("dial %s %s failed: %v", network, addr, err)
- return
- }
- defer fd.Close()
- t0 := time.Nanoseconds()
- fd.SetReadTimeout(1e8) // 100ms
- var b [100]byte
- var n int
- var err1 os.Error
- if readFrom {
- n, _, err1 = fd.(PacketConn).ReadFrom(b[0:])
- } else {
- n, err1 = fd.Read(b[0:])
- }
- t1 := time.Nanoseconds()
- what := "Read"
- if readFrom {
- what = "ReadFrom"
- }
- if n != 0 || err1 == nil || !err1.(Error).Timeout() {
- t.Errorf("fd.%s on %s %s did not return 0, timeout: %v, %v", what, network, addr, n, err1)
- }
- if t1-t0 < 0.5e8 || t1-t0 > 1.5e8 {
- t.Errorf("fd.%s on %s %s took %f seconds, expected 0.1", what, network, addr, float64(t1-t0)/1e9)
- }
-}
-
-func TestTimeoutUDP(t *testing.T) {
- testTimeout(t, "udp", "127.0.0.1:53", false)
- testTimeout(t, "udp", "127.0.0.1:53", true)
-}
-
-func TestTimeoutTCP(t *testing.T) {
- // set up a listener that won't talk back
- listening := make(chan string)
- done := make(chan int)
- go runServe(t, "tcp", "127.0.0.1:0", listening, done)
- addr := <-listening
-
- testTimeout(t, "tcp", addr, false)
- <-done
-}
diff --git a/src/pkg/net/udpsock.go b/src/pkg/net/udpsock.go
deleted file mode 100644
index 94e249d62..000000000
--- a/src/pkg/net/udpsock.go
+++ /dev/null
@@ -1,323 +0,0 @@
-// 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.
-
-// UDP sockets
-
-package net
-
-import (
- "os"
- "syscall"
-)
-
-func sockaddrToUDP(sa syscall.Sockaddr) Addr {
- switch sa := sa.(type) {
- case *syscall.SockaddrInet4:
- return &UDPAddr{sa.Addr[0:], sa.Port}
- case *syscall.SockaddrInet6:
- return &UDPAddr{sa.Addr[0:], sa.Port}
- }
- return nil
-}
-
-// UDPAddr represents the address of a UDP end point.
-type UDPAddr struct {
- IP IP
- Port int
-}
-
-// Network returns the address's network name, "udp".
-func (a *UDPAddr) Network() string { return "udp" }
-
-func (a *UDPAddr) String() string {
- if a == nil {
- return "<nil>"
- }
- return JoinHostPort(a.IP.String(), itoa(a.Port))
-}
-
-func (a *UDPAddr) family() int {
- if a == nil || len(a.IP) <= 4 {
- return syscall.AF_INET
- }
- if a.IP.To4() != nil {
- return syscall.AF_INET
- }
- return syscall.AF_INET6
-}
-
-func (a *UDPAddr) sockaddr(family int) (syscall.Sockaddr, os.Error) {
- return ipToSockaddr(family, a.IP, a.Port)
-}
-
-func (a *UDPAddr) toAddr() sockaddr {
- if a == nil { // nil *UDPAddr
- return nil // nil interface
- }
- return a
-}
-
-// ResolveUDPAddr parses addr as a UDP address of the form
-// host:port and resolves domain names or port names to
-// numeric addresses on the network net, which must be "udp",
-// "udp4" or "udp6". A literal IPv6 host address must be
-// enclosed in square brackets, as in "[::]:80".
-func ResolveUDPAddr(net, addr string) (*UDPAddr, os.Error) {
- ip, port, err := hostPortToIP(net, addr)
- if err != nil {
- return nil, err
- }
- return &UDPAddr{ip, port}, nil
-}
-
-// UDPConn is the implementation of the Conn and PacketConn
-// interfaces for UDP network connections.
-type UDPConn struct {
- fd *netFD
-}
-
-func newUDPConn(fd *netFD) *UDPConn { return &UDPConn{fd} }
-
-func (c *UDPConn) ok() bool { return c != nil && c.fd != nil }
-
-// Implementation of the Conn interface - see Conn for documentation.
-
-// Read implements the net.Conn Read method.
-func (c *UDPConn) Read(b []byte) (n int, err os.Error) {
- if !c.ok() {
- return 0, os.EINVAL
- }
- return c.fd.Read(b)
-}
-
-// Write implements the net.Conn Write method.
-func (c *UDPConn) Write(b []byte) (n int, err os.Error) {
- if !c.ok() {
- return 0, os.EINVAL
- }
- return c.fd.Write(b)
-}
-
-// Close closes the UDP connection.
-func (c *UDPConn) Close() os.Error {
- if !c.ok() {
- return os.EINVAL
- }
- err := c.fd.Close()
- c.fd = nil
- return err
-}
-
-// LocalAddr returns the local network address.
-func (c *UDPConn) LocalAddr() Addr {
- if !c.ok() {
- return nil
- }
- return c.fd.laddr
-}
-
-// RemoteAddr returns the remote network address, a *UDPAddr.
-func (c *UDPConn) RemoteAddr() Addr {
- if !c.ok() {
- return nil
- }
- return c.fd.raddr
-}
-
-// SetTimeout implements the net.Conn SetTimeout method.
-func (c *UDPConn) SetTimeout(nsec int64) os.Error {
- if !c.ok() {
- return os.EINVAL
- }
- return setTimeout(c.fd, nsec)
-}
-
-// SetReadTimeout implements the net.Conn SetReadTimeout method.
-func (c *UDPConn) SetReadTimeout(nsec int64) os.Error {
- if !c.ok() {
- return os.EINVAL
- }
- return setReadTimeout(c.fd, nsec)
-}
-
-// SetWriteTimeout implements the net.Conn SetWriteTimeout method.
-func (c *UDPConn) SetWriteTimeout(nsec int64) os.Error {
- if !c.ok() {
- return os.EINVAL
- }
- return setWriteTimeout(c.fd, nsec)
-}
-
-// SetReadBuffer sets the size of the operating system's
-// receive buffer associated with the connection.
-func (c *UDPConn) SetReadBuffer(bytes int) os.Error {
- if !c.ok() {
- return os.EINVAL
- }
- return setReadBuffer(c.fd, bytes)
-}
-
-// SetWriteBuffer sets the size of the operating system's
-// transmit buffer associated with the connection.
-func (c *UDPConn) SetWriteBuffer(bytes int) os.Error {
- if !c.ok() {
- return os.EINVAL
- }
- return setWriteBuffer(c.fd, bytes)
-}
-
-// UDP-specific methods.
-
-// ReadFromUDP reads a UDP packet from c, copying the payload into b.
-// It returns the number of bytes copied into b and the return address
-// that was on the packet.
-//
-// ReadFromUDP can be made to time out and return an error with Timeout() == true
-// after a fixed time limit; see SetTimeout and SetReadTimeout.
-func (c *UDPConn) ReadFromUDP(b []byte) (n int, addr *UDPAddr, err os.Error) {
- if !c.ok() {
- return 0, nil, os.EINVAL
- }
- n, sa, err := c.fd.ReadFrom(b)
- switch sa := sa.(type) {
- case *syscall.SockaddrInet4:
- addr = &UDPAddr{sa.Addr[0:], sa.Port}
- case *syscall.SockaddrInet6:
- addr = &UDPAddr{sa.Addr[0:], sa.Port}
- }
- return
-}
-
-// ReadFrom implements the net.PacketConn ReadFrom method.
-func (c *UDPConn) ReadFrom(b []byte) (n int, addr Addr, err os.Error) {
- if !c.ok() {
- return 0, nil, os.EINVAL
- }
- n, uaddr, err := c.ReadFromUDP(b)
- return n, uaddr.toAddr(), err
-}
-
-// WriteToUDP writes a UDP packet to addr via c, copying the payload from b.
-//
-// WriteToUDP can be made to time out and return
-// an error with Timeout() == true after a fixed time limit;
-// see SetTimeout and SetWriteTimeout.
-// On packet-oriented connections, write timeouts are rare.
-func (c *UDPConn) WriteToUDP(b []byte, addr *UDPAddr) (n int, err os.Error) {
- if !c.ok() {
- return 0, os.EINVAL
- }
- sa, err1 := addr.sockaddr(c.fd.family)
- if err1 != nil {
- return 0, &OpError{Op: "write", Net: "udp", Addr: addr, Error: err1}
- }
- return c.fd.WriteTo(b, sa)
-}
-
-// WriteTo implements the net.PacketConn WriteTo method.
-func (c *UDPConn) WriteTo(b []byte, addr Addr) (n int, err os.Error) {
- if !c.ok() {
- return 0, os.EINVAL
- }
- a, ok := addr.(*UDPAddr)
- if !ok {
- return 0, &OpError{"writeto", "udp", addr, os.EINVAL}
- }
- return c.WriteToUDP(b, a)
-}
-
-// DialUDP connects to the remote address raddr on the network net,
-// which must be "udp", "udp4", or "udp6". If laddr is not nil, it is used
-// as the local address for the connection.
-func DialUDP(net string, laddr, raddr *UDPAddr) (c *UDPConn, err os.Error) {
- switch net {
- case "udp", "udp4", "udp6":
- default:
- return nil, UnknownNetworkError(net)
- }
- if raddr == nil {
- return nil, &OpError{"dial", "udp", nil, errMissingAddress}
- }
- fd, e := internetSocket(net, laddr.toAddr(), raddr.toAddr(), syscall.SOCK_DGRAM, 0, "dial", sockaddrToUDP)
- if e != nil {
- return nil, e
- }
- return newUDPConn(fd), nil
-}
-
-// ListenUDP listens for incoming UDP packets addressed to the
-// local address laddr. The returned connection c's ReadFrom
-// and WriteTo methods can be used to receive and send UDP
-// packets with per-packet addressing.
-func ListenUDP(net string, laddr *UDPAddr) (c *UDPConn, err os.Error) {
- switch net {
- case "udp", "udp4", "udp6":
- default:
- return nil, UnknownNetworkError(net)
- }
- if laddr == nil {
- return nil, &OpError{"listen", "udp", nil, errMissingAddress}
- }
- fd, e := internetSocket(net, laddr.toAddr(), nil, syscall.SOCK_DGRAM, 0, "dial", sockaddrToUDP)
- if e != nil {
- return nil, e
- }
- return newUDPConn(fd), nil
-}
-
-// BindToDevice binds a UDPConn to a network interface.
-func (c *UDPConn) BindToDevice(device string) os.Error {
- if !c.ok() {
- return os.EINVAL
- }
- c.fd.incref()
- defer c.fd.decref()
- return os.NewSyscallError("setsockopt", syscall.BindToDevice(c.fd.sysfd, device))
-}
-
-// File returns a copy of the underlying os.File, set to blocking mode.
-// It is the caller's responsibility to close f when finished.
-// Closing c does not affect f, and closing f does not affect c.
-func (c *UDPConn) File() (f *os.File, err os.Error) { return c.fd.dup() }
-
-var errInvalidMulticast = os.NewError("invalid IPv4 multicast address")
-
-// JoinGroup joins the IPv4 multicast group named by addr.
-// The UDPConn must use the "udp4" network.
-func (c *UDPConn) JoinGroup(addr IP) os.Error {
- if !c.ok() {
- return os.EINVAL
- }
- ip := addr.To4()
- if ip == nil {
- return &OpError{"joingroup", "udp", &IPAddr{ip}, errInvalidMulticast}
- }
- mreq := &syscall.IPMreq{
- Multiaddr: [4]byte{ip[0], ip[1], ip[2], ip[3]},
- }
- err := os.NewSyscallError("setsockopt", syscall.SetsockoptIPMreq(c.fd.sysfd, syscall.IPPROTO_IP, syscall.IP_ADD_MEMBERSHIP, mreq))
- if err != nil {
- return &OpError{"joingroup", "udp", &IPAddr{ip}, err}
- }
- return nil
-}
-
-// LeaveGroup exits the IPv4 multicast group named by addr.
-func (c *UDPConn) LeaveGroup(addr IP) os.Error {
- if !c.ok() {
- return os.EINVAL
- }
- ip := addr.To4()
- if ip == nil {
- return &OpError{"leavegroup", "udp", &IPAddr{ip}, errInvalidMulticast}
- }
- mreq := &syscall.IPMreq{
- Multiaddr: [4]byte{ip[0], ip[1], ip[2], ip[3]},
- }
- err := os.NewSyscallError("setsockopt", syscall.SetsockoptIPMreq(c.fd.sysfd, syscall.IPPROTO_IP, syscall.IP_DROP_MEMBERSHIP, mreq))
- if err != nil {
- return &OpError{"leavegroup", "udp", &IPAddr{ip}, err}
- }
- return nil
-}
diff --git a/src/pkg/net/unixsock.go b/src/pkg/net/unixsock.go
deleted file mode 100644
index 8c26a7baf..000000000
--- a/src/pkg/net/unixsock.go
+++ /dev/null
@@ -1,449 +0,0 @@
-// 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.
-
-// Unix domain sockets
-
-package net
-
-import (
- "os"
- "syscall"
-)
-
-func unixSocket(net string, laddr, raddr *UnixAddr, mode string) (fd *netFD, err os.Error) {
- var proto int
- switch net {
- default:
- return nil, UnknownNetworkError(net)
- case "unix":
- proto = syscall.SOCK_STREAM
- case "unixgram":
- proto = syscall.SOCK_DGRAM
- case "unixpacket":
- proto = syscall.SOCK_SEQPACKET
- }
-
- var la, ra syscall.Sockaddr
- switch mode {
- default:
- panic("unixSocket mode " + mode)
-
- case "dial":
- if laddr != nil {
- la = &syscall.SockaddrUnix{Name: laddr.Name}
- }
- if raddr != nil {
- ra = &syscall.SockaddrUnix{Name: raddr.Name}
- } else if proto != syscall.SOCK_DGRAM || laddr == nil {
- return nil, &OpError{Op: mode, Net: net, Error: errMissingAddress}
- }
-
- case "listen":
- if laddr == nil {
- return nil, &OpError{mode, net, nil, errMissingAddress}
- }
- la = &syscall.SockaddrUnix{Name: laddr.Name}
- if raddr != nil {
- return nil, &OpError{Op: mode, Net: net, Addr: raddr, Error: &AddrError{Error: "unexpected remote address", Addr: raddr.String()}}
- }
- }
-
- f := sockaddrToUnix
- if proto == syscall.SOCK_DGRAM {
- f = sockaddrToUnixgram
- } else if proto == syscall.SOCK_SEQPACKET {
- f = sockaddrToUnixpacket
- }
-
- fd, oserr := socket(net, syscall.AF_UNIX, proto, 0, la, ra, f)
- if oserr != nil {
- goto Error
- }
- return fd, nil
-
-Error:
- addr := raddr
- if mode == "listen" {
- addr = laddr
- }
- return nil, &OpError{Op: mode, Net: net, Addr: addr, Error: oserr}
-}
-
-// UnixAddr represents the address of a Unix domain socket end point.
-type UnixAddr struct {
- Name string
- Net string
-}
-
-func sockaddrToUnix(sa syscall.Sockaddr) Addr {
- if s, ok := sa.(*syscall.SockaddrUnix); ok {
- return &UnixAddr{s.Name, "unix"}
- }
- return nil
-}
-
-func sockaddrToUnixgram(sa syscall.Sockaddr) Addr {
- if s, ok := sa.(*syscall.SockaddrUnix); ok {
- return &UnixAddr{s.Name, "unixgram"}
- }
- return nil
-}
-
-func sockaddrToUnixpacket(sa syscall.Sockaddr) Addr {
- if s, ok := sa.(*syscall.SockaddrUnix); ok {
- return &UnixAddr{s.Name, "unixpacket"}
- }
- return nil
-}
-
-func protoToNet(proto int) string {
- switch proto {
- case syscall.SOCK_STREAM:
- return "unix"
- case syscall.SOCK_SEQPACKET:
- return "unixpacket"
- case syscall.SOCK_DGRAM:
- return "unixgram"
- default:
- panic("protoToNet unknown protocol")
- }
- return ""
-}
-
-// Network returns the address's network name, "unix" or "unixgram".
-func (a *UnixAddr) Network() string {
- return a.Net
-}
-
-func (a *UnixAddr) String() string {
- if a == nil {
- return "<nil>"
- }
- return a.Name
-}
-
-func (a *UnixAddr) toAddr() Addr {
- if a == nil { // nil *UnixAddr
- return nil // nil interface
- }
- return a
-}
-
-// ResolveUnixAddr parses addr as a Unix domain socket address.
-// The string net gives the network name, "unix", "unixgram" or
-// "unixpacket".
-func ResolveUnixAddr(net, addr string) (*UnixAddr, os.Error) {
- switch net {
- case "unix":
- case "unixpacket":
- case "unixgram":
- default:
- return nil, UnknownNetworkError(net)
- }
- return &UnixAddr{addr, net}, nil
-}
-
-// UnixConn is an implementation of the Conn interface
-// for connections to Unix domain sockets.
-type UnixConn struct {
- fd *netFD
-}
-
-func newUnixConn(fd *netFD) *UnixConn { return &UnixConn{fd} }
-
-func (c *UnixConn) ok() bool { return c != nil && c.fd != nil }
-
-// Implementation of the Conn interface - see Conn for documentation.
-
-// Read implements the net.Conn Read method.
-func (c *UnixConn) Read(b []byte) (n int, err os.Error) {
- if !c.ok() {
- return 0, os.EINVAL
- }
- return c.fd.Read(b)
-}
-
-// Write implements the net.Conn Write method.
-func (c *UnixConn) Write(b []byte) (n int, err os.Error) {
- if !c.ok() {
- return 0, os.EINVAL
- }
- return c.fd.Write(b)
-}
-
-// Close closes the Unix domain connection.
-func (c *UnixConn) Close() os.Error {
- if !c.ok() {
- return os.EINVAL
- }
- err := c.fd.Close()
- c.fd = nil
- return err
-}
-
-// LocalAddr returns the local network address, a *UnixAddr.
-// Unlike in other protocols, LocalAddr is usually nil for dialed connections.
-func (c *UnixConn) LocalAddr() Addr {
- if !c.ok() {
- return nil
- }
- return c.fd.laddr
-}
-
-// RemoteAddr returns the remote network address, a *UnixAddr.
-// Unlike in other protocols, RemoteAddr is usually nil for connections
-// accepted by a listener.
-func (c *UnixConn) RemoteAddr() Addr {
- if !c.ok() {
- return nil
- }
- return c.fd.raddr
-}
-
-// SetTimeout implements the net.Conn SetTimeout method.
-func (c *UnixConn) SetTimeout(nsec int64) os.Error {
- if !c.ok() {
- return os.EINVAL
- }
- return setTimeout(c.fd, nsec)
-}
-
-// SetReadTimeout implements the net.Conn SetReadTimeout method.
-func (c *UnixConn) SetReadTimeout(nsec int64) os.Error {
- if !c.ok() {
- return os.EINVAL
- }
- return setReadTimeout(c.fd, nsec)
-}
-
-// SetWriteTimeout implements the net.Conn SetWriteTimeout method.
-func (c *UnixConn) SetWriteTimeout(nsec int64) os.Error {
- if !c.ok() {
- return os.EINVAL
- }
- return setWriteTimeout(c.fd, nsec)
-}
-
-// SetReadBuffer sets the size of the operating system's
-// receive buffer associated with the connection.
-func (c *UnixConn) SetReadBuffer(bytes int) os.Error {
- if !c.ok() {
- return os.EINVAL
- }
- return setReadBuffer(c.fd, bytes)
-}
-
-// SetWriteBuffer sets the size of the operating system's
-// transmit buffer associated with the connection.
-func (c *UnixConn) SetWriteBuffer(bytes int) os.Error {
- if !c.ok() {
- return os.EINVAL
- }
- return setWriteBuffer(c.fd, bytes)
-}
-
-// ReadFromUnix reads a packet from c, copying the payload into b.
-// It returns the number of bytes copied into b and the return address
-// that was on the packet.
-//
-// ReadFromUnix can be made to time out and return
-// an error with Timeout() == true after a fixed time limit;
-// see SetTimeout and SetReadTimeout.
-func (c *UnixConn) ReadFromUnix(b []byte) (n int, addr *UnixAddr, err os.Error) {
- if !c.ok() {
- return 0, nil, os.EINVAL
- }
- n, sa, err := c.fd.ReadFrom(b)
- switch sa := sa.(type) {
- case *syscall.SockaddrUnix:
- addr = &UnixAddr{sa.Name, protoToNet(c.fd.proto)}
- }
- return
-}
-
-// ReadFrom implements the net.PacketConn ReadFrom method.
-func (c *UnixConn) ReadFrom(b []byte) (n int, addr Addr, err os.Error) {
- if !c.ok() {
- return 0, nil, os.EINVAL
- }
- n, uaddr, err := c.ReadFromUnix(b)
- return n, uaddr.toAddr(), err
-}
-
-// WriteToUnix writes a packet to addr via c, copying the payload from b.
-//
-// WriteToUnix can be made to time out and return
-// an error with Timeout() == true after a fixed time limit;
-// see SetTimeout and SetWriteTimeout.
-// On packet-oriented connections, write timeouts are rare.
-func (c *UnixConn) WriteToUnix(b []byte, addr *UnixAddr) (n int, err os.Error) {
- if !c.ok() {
- return 0, os.EINVAL
- }
- if addr.Net != protoToNet(c.fd.proto) {
- return 0, os.EAFNOSUPPORT
- }
- sa := &syscall.SockaddrUnix{Name: addr.Name}
- return c.fd.WriteTo(b, sa)
-}
-
-// WriteTo implements the net.PacketConn WriteTo method.
-func (c *UnixConn) WriteTo(b []byte, addr Addr) (n int, err os.Error) {
- if !c.ok() {
- return 0, os.EINVAL
- }
- a, ok := addr.(*UnixAddr)
- if !ok {
- return 0, &OpError{"writeto", "unix", addr, os.EINVAL}
- }
- return c.WriteToUnix(b, a)
-}
-
-func (c *UnixConn) ReadMsgUnix(b, oob []byte) (n, oobn, flags int, addr *UnixAddr, err os.Error) {
- if !c.ok() {
- return 0, 0, 0, nil, os.EINVAL
- }
- n, oobn, flags, sa, err := c.fd.ReadMsg(b, oob)
- switch sa := sa.(type) {
- case *syscall.SockaddrUnix:
- addr = &UnixAddr{sa.Name, protoToNet(c.fd.proto)}
- }
- return
-}
-
-func (c *UnixConn) WriteMsgUnix(b, oob []byte, addr *UnixAddr) (n, oobn int, err os.Error) {
- if !c.ok() {
- return 0, 0, os.EINVAL
- }
- if addr != nil {
- if addr.Net != protoToNet(c.fd.proto) {
- return 0, 0, os.EAFNOSUPPORT
- }
- sa := &syscall.SockaddrUnix{Name: addr.Name}
- return c.fd.WriteMsg(b, oob, sa)
- }
- return c.fd.WriteMsg(b, oob, nil)
-}
-
-// File returns a copy of the underlying os.File, set to blocking mode.
-// It is the caller's responsibility to close f when finished.
-// Closing c does not affect f, and closing f does not affect c.
-func (c *UnixConn) File() (f *os.File, err os.Error) { return c.fd.dup() }
-
-// DialUnix connects to the remote address raddr on the network net,
-// which must be "unix" or "unixgram". If laddr is not nil, it is used
-// as the local address for the connection.
-func DialUnix(net string, laddr, raddr *UnixAddr) (c *UnixConn, err os.Error) {
- fd, e := unixSocket(net, laddr, raddr, "dial")
- if e != nil {
- return nil, e
- }
- return newUnixConn(fd), nil
-}
-
-// UnixListener is a Unix domain socket listener.
-// Clients should typically use variables of type Listener
-// instead of assuming Unix domain sockets.
-type UnixListener struct {
- fd *netFD
- path string
-}
-
-// ListenUnix announces on the Unix domain socket laddr and returns a Unix listener.
-// Net must be "unix" (stream sockets).
-func ListenUnix(net string, laddr *UnixAddr) (l *UnixListener, err os.Error) {
- if net != "unix" && net != "unixgram" && net != "unixpacket" {
- return nil, UnknownNetworkError(net)
- }
- if laddr != nil {
- laddr = &UnixAddr{laddr.Name, net} // make our own copy
- }
- fd, err := unixSocket(net, laddr, nil, "listen")
- if err != nil {
- return nil, err
- }
- e1 := syscall.Listen(fd.sysfd, 8) // listenBacklog());
- if e1 != 0 {
- closesocket(fd.sysfd)
- return nil, &OpError{Op: "listen", Net: "unix", Addr: laddr, Error: os.Errno(e1)}
- }
- return &UnixListener{fd, laddr.Name}, nil
-}
-
-// AcceptUnix accepts the next incoming call and returns the new connection
-// and the remote address.
-func (l *UnixListener) AcceptUnix() (c *UnixConn, err os.Error) {
- if l == nil || l.fd == nil {
- return nil, os.EINVAL
- }
- fd, e := l.fd.accept(sockaddrToUnix)
- if e != nil {
- return nil, e
- }
- c = newUnixConn(fd)
- return c, nil
-}
-
-// Accept implements the Accept method in the Listener interface;
-// it waits for the next call and returns a generic Conn.
-func (l *UnixListener) Accept() (c Conn, err os.Error) {
- c1, err := l.AcceptUnix()
- if err != nil {
- return nil, err
- }
- return c1, nil
-}
-
-// Close stops listening on the Unix address.
-// Already accepted connections are not closed.
-func (l *UnixListener) Close() os.Error {
- if l == nil || l.fd == nil {
- return os.EINVAL
- }
-
- // The operating system doesn't clean up
- // the file that announcing created, so
- // we have to clean it up ourselves.
- // There's a race here--we can't know for
- // sure whether someone else has come along
- // and replaced our socket name already--
- // but this sequence (remove then close)
- // is at least compatible with the auto-remove
- // sequence in ListenUnix. It's only non-Go
- // programs that can mess us up.
- if l.path[0] != '@' {
- syscall.Unlink(l.path)
- }
- err := l.fd.Close()
- l.fd = nil
- return err
-}
-
-// Addr returns the listener's network address.
-func (l *UnixListener) Addr() Addr { return l.fd.laddr }
-
-// File returns a copy of the underlying os.File, set to blocking mode.
-// It is the caller's responsibility to close f when finished.
-// Closing c does not affect f, and closing f does not affect c.
-func (l *UnixListener) File() (f *os.File, err os.Error) { return l.fd.dup() }
-
-// ListenUnixgram listens for incoming Unix datagram packets addressed to the
-// local address laddr. The returned connection c's ReadFrom
-// and WriteTo methods can be used to receive and send UDP
-// packets with per-packet addressing. The network net must be "unixgram".
-func ListenUnixgram(net string, laddr *UnixAddr) (c *UDPConn, err os.Error) {
- switch net {
- case "unixgram":
- default:
- return nil, UnknownNetworkError(net)
- }
- if laddr == nil {
- return nil, &OpError{"listen", "unixgram", nil, errMissingAddress}
- }
- fd, e := unixSocket(net, laddr, nil, "listen")
- if e != nil {
- return nil, e
- }
- return newUDPConn(fd), nil
-}