diff --git a/src/pkg/net/dial.go b/src/pkg/net/dial.go
index 752f81b618cc241363dea057d07c186872884218..a85e3c673bfe835f096a86b5a5497e1dcf93d43b 100644
--- a/src/pkg/net/dial.go
+++ b/src/pkg/net/dial.go
@@ -5,6 +5,7 @@
 package net
 
 import (
+	"runtime"
 	"time"
 )
 
@@ -36,7 +37,7 @@ func parseDialNetwork(net string) (afnet string, proto int, err error) {
 	return "", 0, UnknownNetworkError(net)
 }
 
-func resolveNetAddr(op, net, addr string) (afnet string, a Addr, err error) {
+func resolveNetAddr(op, net, addr string, deadline time.Time) (afnet string, a Addr, err error) {
 	afnet, _, err = parseDialNetwork(net)
 	if err != nil {
 		return "", nil, &OpError{op, net, nil, err}
@@ -44,25 +45,25 @@ func resolveNetAddr(op, net, addr string) (afnet string, a Addr, err error) {
 	if op == "dial" && addr == "" {
 		return "", nil, &OpError{op, net, nil, errMissingAddress}
 	}
+	a, err = resolveAfnetAddr(afnet, addr, deadline)
+	return
+}
+
+func resolveAfnetAddr(afnet, addr string, deadline time.Time) (Addr, error) {
+	if addr == "" {
+		return nil, nil
+	}
 	switch afnet {
 	case "tcp", "tcp4", "tcp6":
-		if addr != "" {
-			a, err = ResolveTCPAddr(afnet, addr)
-		}
+		return resolveTCPAddr(afnet, addr, deadline)
 	case "udp", "udp4", "udp6":
-		if addr != "" {
-			a, err = ResolveUDPAddr(afnet, addr)
-		}
+		return resolveUDPAddr(afnet, addr, deadline)
 	case "ip", "ip4", "ip6":
-		if addr != "" {
-			a, err = ResolveIPAddr(afnet, addr)
-		}
+		return resolveIPAddr(afnet, addr, deadline)
 	case "unix", "unixgram", "unixpacket":
-		if addr != "" {
-			a, err = ResolveUnixAddr(afnet, addr)
-		}
+		return ResolveUnixAddr(afnet, addr)
 	}
-	return
+	return nil, nil
 }
 
 // Dial connects to the address addr on the network net.
@@ -89,23 +90,23 @@ func resolveNetAddr(op, net, addr string) (afnet string, a Addr, err error) {
 //	Dial("ip6:ospf", "::1")
 //
 func Dial(net, addr string) (Conn, error) {
-	_, addri, err := resolveNetAddr("dial", net, addr)
+	_, addri, err := resolveNetAddr("dial", net, addr, noDeadline)
 	if err != nil {
 		return nil, err
 	}
-	return dialAddr(net, addr, addri)
+	return dialAddr(net, addr, addri, noDeadline)
 }
 
-func dialAddr(net, addr string, addri Addr) (c Conn, err error) {
+func dialAddr(net, addr string, addri Addr, deadline time.Time) (c Conn, err error) {
 	switch ra := addri.(type) {
 	case *TCPAddr:
-		c, err = DialTCP(net, nil, ra)
+		c, err = dialTCP(net, nil, ra, deadline)
 	case *UDPAddr:
-		c, err = DialUDP(net, nil, ra)
+		c, err = dialUDP(net, nil, ra, deadline)
 	case *IPAddr:
-		c, err = DialIP(net, nil, ra)
+		c, err = dialIP(net, nil, ra, deadline)
 	case *UnixAddr:
-		c, err = DialUnix(net, nil, ra)
+		c, err = dialUnix(net, nil, ra, deadline)
 	default:
 		err = &OpError{"dial", net + " " + addr, nil, UnknownNetworkError(net)}
 	}
@@ -115,13 +116,31 @@ func dialAddr(net, addr string, addri Addr) (c Conn, err error) {
 	return
 }
 
+const useDialTimeoutRace = runtime.GOOS == "windows" || runtime.GOOS == "plan9"
+
 // DialTimeout acts like Dial but takes a timeout.
 // The timeout includes name resolution, if required.
 func DialTimeout(net, addr string, timeout time.Duration) (Conn, error) {
-	// TODO(bradfitz): the timeout should be pushed down into the
-	// net package's event loop, so on timeout to dead hosts we
-	// don't have a goroutine sticking around for the default of
-	// ~3 minutes.
+	if useDialTimeoutRace {
+		// On windows and plan9, use the relatively inefficient
+		// goroutine-racing implementation of DialTimeout that
+		// doesn't push down deadlines to the pollster.
+		// TODO: remove this once those are implemented.
+		return dialTimeoutRace(net, addr, timeout)
+	}
+	deadline := time.Now().Add(timeout)
+	_, addri, err := resolveNetAddr("dial", net, addr, deadline)
+	if err != nil {
+		return nil, err
+	}
+	return dialAddr(net, addr, addri, deadline)
+}
+
+// dialTimeoutRace is the old implementation of DialTimeout, still used
+// on operating systems where the deadline hasn't been pushed down
+// into the pollserver.
+// TODO: fix this on Windows and plan9.
+func dialTimeoutRace(net, addr string, timeout time.Duration) (Conn, error) {
 	t := time.NewTimer(timeout)
 	defer t.Stop()
 	type pair struct {
@@ -131,13 +150,13 @@ func DialTimeout(net, addr string, timeout time.Duration) (Conn, error) {
 	ch := make(chan pair, 1)
 	resolvedAddr := make(chan Addr, 1)
 	go func() {
-		_, addri, err := resolveNetAddr("dial", net, addr)
+		_, addri, err := resolveNetAddr("dial", net, addr, noDeadline)
 		if err != nil {
 			ch <- pair{nil, err}
 			return
 		}
 		resolvedAddr <- addri // in case we need it for OpError
-		c, err := dialAddr(net, addr, addri)
+		c, err := dialAddr(net, addr, addri, noDeadline)
 		ch <- pair{c, err}
 	}()
 	select {
@@ -175,7 +194,7 @@ func (a stringAddr) String() string  { return a.addr }
 // The network string net must be a stream-oriented network:
 // "tcp", "tcp4", "tcp6", "unix" or "unixpacket".
 func Listen(net, laddr string) (Listener, error) {
-	afnet, a, err := resolveNetAddr("listen", net, laddr)
+	afnet, a, err := resolveNetAddr("listen", net, laddr, noDeadline)
 	if err != nil {
 		return nil, err
 	}
@@ -200,7 +219,7 @@ func Listen(net, laddr string) (Listener, error) {
 // The network string net must be a packet-oriented network:
 // "udp", "udp4", "udp6", "ip", "ip4", "ip6" or "unixgram".
 func ListenPacket(net, addr string) (PacketConn, error) {
-	afnet, a, err := resolveNetAddr("listen", net, addr)
+	afnet, a, err := resolveNetAddr("listen", net, addr, noDeadline)
 	if err != nil {
 		return nil, err
 	}
diff --git a/src/pkg/net/dial_test.go b/src/pkg/net/dial_test.go
index 869c3cb966e19918f09dd89cc4b26ce55f83747b..34a15f27b1ac3b0d89b053d0243044ffff75d436 100644
--- a/src/pkg/net/dial_test.go
+++ b/src/pkg/net/dial_test.go
@@ -7,6 +7,8 @@ package net
 import (
 	"flag"
 	"fmt"
+	"io"
+	"os"
 	"regexp"
 	"runtime"
 	"testing"
@@ -222,3 +224,79 @@ func TestDialError(t *testing.T) {
 		}
 	}
 }
+
+func TestDialTimeoutFDLeak(t *testing.T) {
+	if runtime.GOOS != "linux" {
+		// TODO(bradfitz): test on other platforms
+		t.Logf("skipping test on %s", runtime.GOOS)
+		return
+	}
+
+	ln := newLocalListener(t)
+	defer ln.Close()
+
+	type connErr struct {
+		conn Conn
+		err  error
+	}
+	dials := listenerBacklog + 100
+	maxGoodConnect := listenerBacklog + 5 // empirically 131 good ones (of 128). who knows?
+	resc := make(chan connErr)
+	for i := 0; i < dials; i++ {
+		go func() {
+			conn, err := DialTimeout("tcp", ln.Addr().String(), 500*time.Millisecond)
+			resc <- connErr{conn, err}
+		}()
+	}
+
+	var firstErr string
+	var ngood int
+	var toClose []io.Closer
+	for i := 0; i < dials; i++ {
+		ce := <-resc
+		if ce.err == nil {
+			ngood++
+			if ngood > maxGoodConnect {
+				t.Errorf("%d good connects; expected at most %d", ngood, maxGoodConnect)
+			}
+			toClose = append(toClose, ce.conn)
+			continue
+		}
+		err := ce.err
+		if firstErr == "" {
+			firstErr = err.Error()
+		} else if err.Error() != firstErr {
+			t.Fatalf("inconsistent error messages: first was %q, then later %q", firstErr, err)
+		}
+	}
+	for _, c := range toClose {
+		c.Close()
+	}
+	for i := 0; i < 100; i++ {
+		if got := numFD(); got < dials {
+			// Test passes.
+			return
+		}
+		time.Sleep(10 * time.Millisecond)
+	}
+	if got := numFD(); got >= dials {
+		t.Errorf("num fds after %d timeouts = %d; want <%d", dials, got, dials)
+	}
+}
+
+func numFD() int {
+	if runtime.GOOS == "linux" {
+		f, err := os.Open("/proc/self/fd")
+		if err != nil {
+			panic(err)
+		}
+		defer f.Close()
+		names, err := f.Readdirnames(0)
+		if err != nil {
+			panic(err)
+		}
+		return len(names)
+	}
+	// All tests using this should be skipped anyway, but:
+	panic("numFDs not implemented on " + runtime.GOOS)
+}
diff --git a/src/pkg/net/fd_unix.go b/src/pkg/net/fd_unix.go
index e1d1256fa1d116397e21eed789a8eb41ad46f6d8..7f82f203e1de189b4e3f00b11e0a30fe6e8522d7 100644
--- a/src/pkg/net/fd_unix.go
+++ b/src/pkg/net/fd_unix.go
@@ -162,7 +162,7 @@ func (s *pollServer) CheckDeadlines() {
 	// TODO(rsc): This will need to be handled more efficiently,
 	// probably with a heap indexed by wakeup time.
 
-	var next_deadline int64
+	var nextDeadline int64
 	for key, fd := range s.pending {
 		var t int64
 		var mode int
@@ -187,12 +187,12 @@ func (s *pollServer) CheckDeadlines() {
 					fd.wdeadline = -1
 				}
 				s.WakeFD(fd, mode, nil)
-			} else if next_deadline == 0 || t < next_deadline {
-				next_deadline = t
+			} else if nextDeadline == 0 || t < nextDeadline {
+				nextDeadline = t
 			}
 		}
 	}
-	s.deadline = next_deadline
+	s.deadline = nextDeadline
 }
 
 func (s *pollServer) Run() {
@@ -332,10 +332,14 @@ func (fd *netFD) name() string {
 
 func (fd *netFD) connect(ra syscall.Sockaddr) error {
 	err := syscall.Connect(fd.sysfd, ra)
+	hadTimeout := fd.wdeadline > 0
 	if err == syscall.EINPROGRESS {
 		if err = fd.pollServer.WaitWrite(fd); err != nil {
 			return err
 		}
+		if hadTimeout && fd.wdeadline < 0 {
+			return errTimeout
+		}
 		var e int
 		e, err = syscall.GetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_ERROR)
 		if err != nil {
diff --git a/src/pkg/net/iprawsock.go b/src/pkg/net/iprawsock.go
index ae21b3c3dde0f551b1b65b5018052ca7626ecec3..d7bffc69e95d37b3944a45302778fc2b41a5fd9c 100644
--- a/src/pkg/net/iprawsock.go
+++ b/src/pkg/net/iprawsock.go
@@ -6,6 +6,10 @@
 
 package net
 
+import (
+	"time"
+)
+
 // IPAddr represents the address of an IP end point.
 type IPAddr struct {
 	IP IP
@@ -26,7 +30,11 @@ func (a *IPAddr) String() string {
 // "ip", "ip4" or "ip6".  A literal IPv6 host address must be
 // enclosed in square brackets, as in "[::]".
 func ResolveIPAddr(net, addr string) (*IPAddr, error) {
-	ip, err := hostToIP(net, addr)
+	return resolveIPAddr(net, addr, noDeadline)
+}
+
+func resolveIPAddr(net, addr string, deadline time.Time) (*IPAddr, error) {
+	ip, err := hostToIP(net, addr, deadline)
 	if err != nil {
 		return nil, err
 	}
@@ -34,7 +42,7 @@ func ResolveIPAddr(net, addr string) (*IPAddr, error) {
 }
 
 // Convert "host" into IP address.
-func hostToIP(net, host string) (ip IP, err error) {
+func hostToIP(net, host string, deadline time.Time) (ip IP, err error) {
 	var addr IP
 	// Try as an IP address.
 	addr = ParseIP(host)
@@ -47,7 +55,7 @@ func hostToIP(net, host string) (ip IP, err error) {
 			filter = ipv6only
 		}
 		// Not an IP address.  Try as a DNS name.
-		addrs, err1 := LookupHost(host)
+		addrs, err1 := lookupHostDeadline(host, deadline)
 		if err1 != nil {
 			err = err1
 			goto Error
diff --git a/src/pkg/net/iprawsock_plan9.go b/src/pkg/net/iprawsock_plan9.go
index 6de2ee33d8460dddeb30da032bf5e7f08ede3087..e77c5476afad6a506c7fb65ed0733a9599f9c096 100644
--- a/src/pkg/net/iprawsock_plan9.go
+++ b/src/pkg/net/iprawsock_plan9.go
@@ -130,6 +130,10 @@ func (c *IPConn) WriteMsgIP(b, oob []byte, addr *IPAddr) (n, oobn int, err error
 // netProto, which must be "ip", "ip4", or "ip6" followed by a colon
 // and a protocol number or name.
 func DialIP(netProto string, laddr, raddr *IPAddr) (*IPConn, error) {
+	return dialIP(netProto, laddr, raddr, noDeadline)
+}
+
+func dialIP(netProto string, laddr, raddr *IPAddr, deadline time.Time) (*IPConn, error) {
 	return nil, syscall.EPLAN9
 }
 
diff --git a/src/pkg/net/iprawsock_posix.go b/src/pkg/net/iprawsock_posix.go
index d0f0b567ac8e409bd7103434047d863e183e942a..4d8b5341d97c82bceb95ad04a22adbca70ebbeb1 100644
--- a/src/pkg/net/iprawsock_posix.go
+++ b/src/pkg/net/iprawsock_posix.go
@@ -10,6 +10,7 @@ package net
 
 import (
 	"syscall"
+	"time"
 )
 
 func sockaddrToIP(sa syscall.Sockaddr) Addr {
@@ -163,6 +164,10 @@ func (c *IPConn) WriteMsgIP(b, oob []byte, addr *IPAddr) (n, oobn int, err error
 // DialIP connects to the remote address raddr on the network protocol netProto,
 // which must be "ip", "ip4", or "ip6" followed by a colon and a protocol number or name.
 func DialIP(netProto string, laddr, raddr *IPAddr) (*IPConn, error) {
+	return dialIP(netProto, laddr, raddr, noDeadline)
+}
+
+func dialIP(netProto string, laddr, raddr *IPAddr, deadline time.Time) (*IPConn, error) {
 	net, proto, err := parseDialNetwork(netProto)
 	if err != nil {
 		return nil, err
@@ -175,7 +180,7 @@ func DialIP(netProto string, laddr, raddr *IPAddr) (*IPConn, error) {
 	if raddr == nil {
 		return nil, &OpError{"dial", netProto, nil, errMissingAddress}
 	}
-	fd, err := internetSocket(net, laddr.toAddr(), raddr.toAddr(), syscall.SOCK_RAW, proto, "dial", sockaddrToIP)
+	fd, err := internetSocket(net, laddr.toAddr(), raddr.toAddr(), deadline, syscall.SOCK_RAW, proto, "dial", sockaddrToIP)
 	if err != nil {
 		return nil, err
 	}
@@ -196,7 +201,7 @@ func ListenIP(netProto string, laddr *IPAddr) (*IPConn, error) {
 	default:
 		return nil, UnknownNetworkError(net)
 	}
-	fd, err := internetSocket(net, laddr.toAddr(), nil, syscall.SOCK_RAW, proto, "listen", sockaddrToIP)
+	fd, err := internetSocket(net, laddr.toAddr(), nil, noDeadline, syscall.SOCK_RAW, proto, "listen", sockaddrToIP)
 	if err != nil {
 		return nil, err
 	}
diff --git a/src/pkg/net/ipsock.go b/src/pkg/net/ipsock.go
index b9b2a9b81ecc54759bb93175321b702f70f42b86..d1fcb4852f7f9fee6660b0d5e96104ecf49751cb 100644
--- a/src/pkg/net/ipsock.go
+++ b/src/pkg/net/ipsock.go
@@ -6,12 +6,9 @@
 
 package net
 
-var supportsIPv6, supportsIPv4map bool
+import "time"
 
-func init() {
-	sysInit()
-	supportsIPv6, supportsIPv4map = probeIPv6Stack()
-}
+var supportsIPv6, supportsIPv4map = probeIPv6Stack()
 
 func firstFavoriteAddr(filter func(IP) IP, addrs []string) (addr IP) {
 	if filter == nil {
@@ -103,7 +100,7 @@ func JoinHostPort(host, port string) string {
 }
 
 // Convert "host:port" into IP address and port.
-func hostPortToIP(net, hostport string) (ip IP, iport int, err error) {
+func hostPortToIP(net, hostport string, deadline time.Time) (ip IP, iport int, err error) {
 	host, port, err := SplitHostPort(hostport)
 	if err != nil {
 		return nil, 0, err
@@ -122,7 +119,7 @@ func hostPortToIP(net, hostport string) (ip IP, iport int, err error) {
 				filter = ipv6only
 			}
 			// Not an IP address.  Try as a DNS name.
-			addrs, err := LookupHost(host)
+			addrs, err := lookupHostDeadline(host, deadline)
 			if err != nil {
 				return nil, 0, err
 			}
diff --git a/src/pkg/net/ipsock_posix.go b/src/pkg/net/ipsock_posix.go
index 171889207d7661b1a0cc4f7ee6f8db95b69b1723..87a2288973b9c1a9cefc67d275a5f1c075b33a07 100644
--- a/src/pkg/net/ipsock_posix.go
+++ b/src/pkg/net/ipsock_posix.go
@@ -6,7 +6,10 @@
 
 package net
 
-import "syscall"
+import (
+	"syscall"
+	"time"
+)
 
 // Should we try to use the IPv4 socket interface if we're
 // only dealing with IPv4 sockets?  As long as the host system
@@ -125,7 +128,7 @@ type sockaddr interface {
 	sockaddr(family int) (syscall.Sockaddr, error)
 }
 
-func internetSocket(net string, laddr, raddr sockaddr, sotype, proto int, mode string, toAddr func(syscall.Sockaddr) Addr) (fd *netFD, err error) {
+func internetSocket(net string, laddr, raddr sockaddr, deadline time.Time, sotype, proto int, mode string, toAddr func(syscall.Sockaddr) Addr) (fd *netFD, err error) {
 	var la, ra syscall.Sockaddr
 	family, ipv6only := favoriteAddrFamily(net, laddr, raddr, mode)
 	if laddr != nil {
@@ -138,7 +141,7 @@ func internetSocket(net string, laddr, raddr sockaddr, sotype, proto int, mode s
 			goto Error
 		}
 	}
-	fd, err = socket(net, family, sotype, proto, ipv6only, la, ra, toAddr)
+	fd, err = socket(net, family, sotype, proto, ipv6only, la, ra, deadline, toAddr)
 	if err != nil {
 		goto Error
 	}
diff --git a/src/pkg/net/lookup.go b/src/pkg/net/lookup.go
index 533b3511a225b009cd85993c874828523a92a556..bec93ec08cd0415219ddcf8d8477ee5acf515b88 100644
--- a/src/pkg/net/lookup.go
+++ b/src/pkg/net/lookup.go
@@ -4,12 +4,53 @@
 
 package net
 
+import (
+	"time"
+)
+
 // 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 error) {
 	return lookupHost(host)
 }
 
+func lookupHostDeadline(host string, deadline time.Time) (addrs []string, err error) {
+	if deadline.IsZero() {
+		return lookupHost(host)
+	}
+
+	// TODO(bradfitz): consider pushing the deadline down into the
+	// name resolution functions. But that involves fixing it for
+	// the native Go resolver, cgo, Windows, etc.
+	//
+	// In the meantime, just use a goroutine. Most users affected
+	// by http://golang.org/issue/2631 are due to TCP connections
+	// to unresponsive hosts, not DNS.
+	timeout := deadline.Sub(time.Now())
+	if timeout <= 0 {
+		err = errTimeout
+		return
+	}
+	t := time.NewTimer(timeout)
+	defer t.Stop()
+	type res struct {
+		addrs []string
+		err   error
+	}
+	resc := make(chan res, 1)
+	go func() {
+		a, err := lookupHost(host)
+		resc <- res{a, err}
+	}()
+	select {
+	case <-t.C:
+		err = errTimeout
+	case r := <-resc:
+		addrs, err = r.addrs, r.err
+	}
+	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 error) {
diff --git a/src/pkg/net/net.go b/src/pkg/net/net.go
index d6563e0a2301b2ea89ed1d0e560b1cf702bb01fa..4f0edd4d29a96f257df6843bc581f0bada77404a 100644
--- a/src/pkg/net/net.go
+++ b/src/pkg/net/net.go
@@ -204,6 +204,8 @@ func (e *OpError) Temporary() bool {
 	return ok && t.Temporary()
 }
 
+var noDeadline = time.Time{}
+
 type timeout interface {
 	Timeout() bool
 }
diff --git a/src/pkg/net/sock_posix.go b/src/pkg/net/sock_posix.go
index dc5247a7f38e813952696e248d2abaac196ce4e2..a3354eacb1b68875abfcca3a63e6bcb4a7947e5c 100644
--- a/src/pkg/net/sock_posix.go
+++ b/src/pkg/net/sock_posix.go
@@ -11,12 +11,13 @@ package net
 import (
 	"io"
 	"syscall"
+	"time"
 )
 
 var listenerBacklog = maxListenerBacklog()
 
 // Generic socket creation.
-func socket(net string, f, t, p int, ipv6only bool, ulsa, ursa syscall.Sockaddr, toAddr func(syscall.Sockaddr) Addr) (fd *netFD, err error) {
+func socket(net string, f, t, p int, ipv6only bool, ulsa, ursa syscall.Sockaddr, deadline time.Time, toAddr func(syscall.Sockaddr) Addr) (fd *netFD, err error) {
 	// See ../syscall/exec_unix.go for description of ForkLock.
 	syscall.ForkLock.RLock()
 	s, err := syscall.Socket(f, t, p)
@@ -50,12 +51,16 @@ func socket(net string, f, t, p int, ipv6only bool, ulsa, ursa syscall.Sockaddr,
 	}
 
 	if ursa != nil {
+		if !deadline.IsZero() {
+			fd.wdeadline = deadline.UnixNano()
+		}
 		if err = fd.connect(ursa); err != nil {
 			closesocket(s)
 			fd.Close()
 			return nil, err
 		}
 		fd.isConnected = true
+		fd.wdeadline = 0
 	}
 
 	lsa, _ := syscall.Getsockname(s)
diff --git a/src/pkg/net/tcpsock.go b/src/pkg/net/tcpsock.go
index 47fbf29198c5bdb8f6700cdf09a7473a01f2f84e..6aba1f89fc82451e93a5d13abca13afcd23879ae 100644
--- a/src/pkg/net/tcpsock.go
+++ b/src/pkg/net/tcpsock.go
@@ -6,6 +6,8 @@
 
 package net
 
+import "time"
+
 // TCPAddr represents the address of a TCP end point.
 type TCPAddr struct {
 	IP   IP
@@ -28,7 +30,11 @@ func (a *TCPAddr) String() string {
 // "tcp4" or "tcp6".  A literal IPv6 host address must be
 // enclosed in square brackets, as in "[::]:80".
 func ResolveTCPAddr(net, addr string) (*TCPAddr, error) {
-	ip, port, err := hostPortToIP(net, addr)
+	return resolveTCPAddr(net, addr, noDeadline)
+}
+
+func resolveTCPAddr(net, addr string, deadline time.Time) (*TCPAddr, error) {
+	ip, port, err := hostPortToIP(net, addr, deadline)
 	if err != nil {
 		return nil, err
 	}
diff --git a/src/pkg/net/tcpsock_plan9.go b/src/pkg/net/tcpsock_plan9.go
index 4121dd89e9a1fb5b9d10bfff97baa1f272fb3168..a77633b355e495a25f556adf3c184da338fd990b 100644
--- a/src/pkg/net/tcpsock_plan9.go
+++ b/src/pkg/net/tcpsock_plan9.go
@@ -6,7 +6,10 @@
 
 package net
 
-import "syscall"
+import (
+	"syscall"
+	"time"
+)
 
 // TCPConn is an implementation of the Conn interface for TCP network
 // connections.
@@ -36,6 +39,13 @@ func (c *TCPConn) CloseWrite() error {
 // 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 error) {
+	return dialTCP(net, laddr, raddr, noDeadline)
+}
+
+func dialTCP(net string, laddr, raddr *TCPAddr, deadline time.Time) (c *TCPConn, err error) {
+	if !deadline.IsZero() {
+		panic("net.dialTCP: deadline not implemented on Plan 9")
+	}
 	switch net {
 	case "tcp", "tcp4", "tcp6":
 	default:
diff --git a/src/pkg/net/tcpsock_posix.go b/src/pkg/net/tcpsock_posix.go
index 2c34d2fda7d847e65554c040aa6ccbef7455b93a..09654a4b580cbb36ceaa9cc4c972f897d90eeb39 100644
--- a/src/pkg/net/tcpsock_posix.go
+++ b/src/pkg/net/tcpsock_posix.go
@@ -143,11 +143,15 @@ func (c *TCPConn) SetNoDelay(noDelay bool) error {
 // 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) (*TCPConn, error) {
+	return dialTCP(net, laddr, raddr, noDeadline)
+}
+
+func dialTCP(net string, laddr, raddr *TCPAddr, deadline time.Time) (*TCPConn, error) {
 	if raddr == nil {
 		return nil, &OpError{"dial", net, nil, errMissingAddress}
 	}
 
-	fd, err := internetSocket(net, laddr.toAddr(), raddr.toAddr(), syscall.SOCK_STREAM, 0, "dial", sockaddrToTCP)
+	fd, err := internetSocket(net, laddr.toAddr(), raddr.toAddr(), deadline, syscall.SOCK_STREAM, 0, "dial", sockaddrToTCP)
 
 	// TCP has a rarely used mechanism called a 'simultaneous connection' in
 	// which Dial("tcp", addr1, addr2) run on the machine at addr1 can
@@ -177,7 +181,7 @@ func DialTCP(net string, laddr, raddr *TCPAddr) (*TCPConn, error) {
 		if err == nil {
 			fd.Close()
 		}
-		fd, err = internetSocket(net, laddr.toAddr(), raddr.toAddr(), syscall.SOCK_STREAM, 0, "dial", sockaddrToTCP)
+		fd, err = internetSocket(net, laddr.toAddr(), raddr.toAddr(), deadline, syscall.SOCK_STREAM, 0, "dial", sockaddrToTCP)
 	}
 
 	if err != nil {
@@ -225,7 +229,7 @@ type TCPListener struct {
 // 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) (*TCPListener, error) {
-	fd, err := internetSocket(net, laddr.toAddr(), nil, syscall.SOCK_STREAM, 0, "listen", sockaddrToTCP)
+	fd, err := internetSocket(net, laddr.toAddr(), nil, noDeadline, syscall.SOCK_STREAM, 0, "listen", sockaddrToTCP)
 	if err != nil {
 		return nil, err
 	}
diff --git a/src/pkg/net/udpsock.go b/src/pkg/net/udpsock.go
index 62b27d95e9c48390b686e27f670e6fcbef2931ed..bf2107b03a22438267ccc8be78ce1127684a2325 100644
--- a/src/pkg/net/udpsock.go
+++ b/src/pkg/net/udpsock.go
@@ -6,7 +6,10 @@
 
 package net
 
-import "errors"
+import (
+	"errors"
+	"time"
+)
 
 var ErrWriteToConnected = errors.New("use of WriteTo with pre-connected UDP")
 
@@ -32,7 +35,11 @@ func (a *UDPAddr) String() string {
 // "udp4" or "udp6".  A literal IPv6 host address must be
 // enclosed in square brackets, as in "[::]:80".
 func ResolveUDPAddr(net, addr string) (*UDPAddr, error) {
-	ip, port, err := hostPortToIP(net, addr)
+	return resolveUDPAddr(net, addr, noDeadline)
+}
+
+func resolveUDPAddr(net, addr string, deadline time.Time) (*UDPAddr, error) {
+	ip, port, err := hostPortToIP(net, addr, deadline)
 	if err != nil {
 		return nil, err
 	}
diff --git a/src/pkg/net/udpsock_plan9.go b/src/pkg/net/udpsock_plan9.go
index aaa7e5b28cb40524584ef7ba381de30bac817a70..c04660baa27536a8fcd4df814b39d61347953654 100644
--- a/src/pkg/net/udpsock_plan9.go
+++ b/src/pkg/net/udpsock_plan9.go
@@ -10,6 +10,7 @@ import (
 	"errors"
 	"os"
 	"syscall"
+	"time"
 )
 
 // UDPConn is the implementation of the Conn and PacketConn
@@ -122,6 +123,13 @@ func (c *UDPConn) WriteMsgUDP(b, oob []byte, addr *UDPAddr) (n, oobn int, err er
 // 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 error) {
+	return dialUDP(net, laddr, raddr, noDeadline)
+}
+
+func dialUDP(net string, laddr, raddr *UDPAddr, deadline time.Time) (c *UDPConn, err error) {
+	if !deadline.IsZero() {
+		panic("net.dialUDP: deadline not implemented on Plan 9")
+	}
 	switch net {
 	case "udp", "udp4", "udp6":
 	default:
diff --git a/src/pkg/net/udpsock_posix.go b/src/pkg/net/udpsock_posix.go
index e075380c8e3e0b385069e1fa00a34a061ff25746..f6e2c17c3cb9543b816a1190befa239f3e882fb3 100644
--- a/src/pkg/net/udpsock_posix.go
+++ b/src/pkg/net/udpsock_posix.go
@@ -8,7 +8,10 @@
 
 package net
 
-import "syscall"
+import (
+	"syscall"
+	"time"
+)
 
 func sockaddrToUDP(sa syscall.Sockaddr) Addr {
 	switch sa := sa.(type) {
@@ -160,6 +163,10 @@ func (c *UDPConn) WriteMsgUDP(b, oob []byte, addr *UDPAddr) (n, oobn int, err er
 // 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) (*UDPConn, error) {
+	return dialUDP(net, laddr, raddr, noDeadline)
+}
+
+func dialUDP(net string, laddr, raddr *UDPAddr, deadline time.Time) (*UDPConn, error) {
 	switch net {
 	case "udp", "udp4", "udp6":
 	default:
@@ -168,7 +175,7 @@ func DialUDP(net string, laddr, raddr *UDPAddr) (*UDPConn, error) {
 	if raddr == nil {
 		return nil, &OpError{"dial", net, nil, errMissingAddress}
 	}
-	fd, err := internetSocket(net, laddr.toAddr(), raddr.toAddr(), syscall.SOCK_DGRAM, 0, "dial", sockaddrToUDP)
+	fd, err := internetSocket(net, laddr.toAddr(), raddr.toAddr(), deadline, syscall.SOCK_DGRAM, 0, "dial", sockaddrToUDP)
 	if err != nil {
 		return nil, err
 	}
@@ -188,7 +195,7 @@ func ListenUDP(net string, laddr *UDPAddr) (*UDPConn, error) {
 	if laddr == nil {
 		return nil, &OpError{"listen", net, nil, errMissingAddress}
 	}
-	fd, err := internetSocket(net, laddr.toAddr(), nil, syscall.SOCK_DGRAM, 0, "listen", sockaddrToUDP)
+	fd, err := internetSocket(net, laddr.toAddr(), nil, noDeadline, syscall.SOCK_DGRAM, 0, "listen", sockaddrToUDP)
 	if err != nil {
 		return nil, err
 	}
@@ -208,7 +215,7 @@ func ListenMulticastUDP(net string, ifi *Interface, gaddr *UDPAddr) (*UDPConn, e
 	if gaddr == nil || gaddr.IP == nil {
 		return nil, &OpError{"listenmulticast", net, nil, errMissingAddress}
 	}
-	fd, err := internetSocket(net, gaddr.toAddr(), nil, syscall.SOCK_DGRAM, 0, "listen", sockaddrToUDP)
+	fd, err := internetSocket(net, gaddr.toAddr(), nil, noDeadline, syscall.SOCK_DGRAM, 0, "listen", sockaddrToUDP)
 	if err != nil {
 		return nil, err
 	}
diff --git a/src/pkg/net/unixsock_plan9.go b/src/pkg/net/unixsock_plan9.go
index 21403754a7ad159f9bc3ef1ab5e39efd48911bbe..342e26fce0239ba8d2533cbffb352c57f22714a3 100644
--- a/src/pkg/net/unixsock_plan9.go
+++ b/src/pkg/net/unixsock_plan9.go
@@ -139,6 +139,10 @@ func (c *UnixConn) CloseWrite() error {
 // 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) (*UnixConn, error) {
+	return dialUnix(net, laddr, raddr, noDeadline)
+}
+
+func dialUnix(net string, laddr, raddr *UnixAddr, deadline time.Time) (*UnixConn, error) {
 	return nil, syscall.EPLAN9
 }
 
diff --git a/src/pkg/net/unixsock_posix.go b/src/pkg/net/unixsock_posix.go
index 2bef5eaaf1272c96f2f5c876696cae7eccececb0..f7cc0746f22c56764802fdd9f2b07e2279914995 100644
--- a/src/pkg/net/unixsock_posix.go
+++ b/src/pkg/net/unixsock_posix.go
@@ -14,7 +14,7 @@ import (
 	"time"
 )
 
-func unixSocket(net string, laddr, raddr *UnixAddr, mode string) (fd *netFD, err error) {
+func unixSocket(net string, laddr, raddr *UnixAddr, mode string, deadline time.Time) (fd *netFD, err error) {
 	var sotype int
 	switch net {
 	default:
@@ -59,7 +59,7 @@ func unixSocket(net string, laddr, raddr *UnixAddr, mode string) (fd *netFD, err
 		f = sockaddrToUnixpacket
 	}
 
-	fd, err = socket(net, syscall.AF_UNIX, sotype, 0, false, la, ra, f)
+	fd, err = socket(net, syscall.AF_UNIX, sotype, 0, false, la, ra, deadline, f)
 	if err != nil {
 		goto Error
 	}
@@ -229,7 +229,11 @@ func (c *UnixConn) CloseWrite() error {
 // 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) (*UnixConn, error) {
-	fd, err := unixSocket(net, laddr, raddr, "dial")
+	return dialUnix(net, laddr, raddr, noDeadline)
+}
+
+func dialUnix(net string, laddr, raddr *UnixAddr, deadline time.Time) (*UnixConn, error) {
+	fd, err := unixSocket(net, laddr, raddr, "dial", deadline)
 	if err != nil {
 		return nil, err
 	}
@@ -253,7 +257,7 @@ func ListenUnix(net string, laddr *UnixAddr) (*UnixListener, error) {
 	if laddr != nil {
 		laddr = &UnixAddr{laddr.Name, net} // make our own copy
 	}
-	fd, err := unixSocket(net, laddr, nil, "listen")
+	fd, err := unixSocket(net, laddr, nil, "listen", noDeadline)
 	if err != nil {
 		return nil, err
 	}
@@ -344,7 +348,7 @@ func ListenUnixgram(net string, laddr *UnixAddr) (*UDPConn, error) {
 	if laddr == nil {
 		return nil, &OpError{"listen", net, nil, errMissingAddress}
 	}
-	fd, err := unixSocket(net, laddr, nil, "listen")
+	fd, err := unixSocket(net, laddr, nil, "listen", noDeadline)
 	if err != nil {
 		return nil, err
 	}