blob: d6812d1ef054dc03e57b9f53fa7689da924c46dd [file] [log] [blame]
Russ Coxe8a02232008-09-16 13:42:47 -07001// Copyright 2009 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
Brad Fitzpatrick008e64d2012-02-17 13:07:06 +11005/*
6Package net provides a portable interface for network I/O, including
7TCP/IP, UDP, domain name resolution, and Unix domain sockets.
8
9Although the package provides access to low-level networking
Brad Fitzpatrick8729d152012-02-21 11:11:18 +110010primitives, most clients will need only the basic interface provided
11by the Dial, Listen, and Accept functions and the associated
12Conn and Listener interfaces. The crypto/tls package uses
13the same interfaces and similar Dial and Listen functions.
Brad Fitzpatrick008e64d2012-02-17 13:07:06 +110014
15The Dial function connects to a server:
16
Mikio Hara495e3c62016-05-17 12:20:16 +090017 conn, err := net.Dial("tcp", "golang.org:80")
Brad Fitzpatrick008e64d2012-02-17 13:07:06 +110018 if err != nil {
19 // handle error
20 }
21 fmt.Fprintf(conn, "GET / HTTP/1.0\r\n\r\n")
22 status, err := bufio.NewReader(conn).ReadString('\n')
23 // ...
24
25The Listen function creates servers:
26
27 ln, err := net.Listen("tcp", ":8080")
28 if err != nil {
29 // handle error
30 }
31 for {
32 conn, err := ln.Accept()
33 if err != nil {
34 // handle error
Brad Fitzpatrick008e64d2012-02-17 13:07:06 +110035 }
36 go handleConnection(conn)
37 }
Russ Coxb711f5a2015-08-18 23:19:41 -040038
39Name Resolution
40
41The method for resolving domain names, whether indirectly with functions like Dial
42or directly with functions like LookupHost and LookupAddr, varies by operating system.
43
44On Unix systems, the resolver has two options for resolving names.
45It can use a pure Go resolver that sends DNS requests directly to the servers
46listed in /etc/resolv.conf, or it can use a cgo-based resolver that calls C
47library routines such as getaddrinfo and getnameinfo.
48
49By default the pure Go resolver is used, because a blocked DNS request consumes
50only a goroutine, while a blocked C call consumes an operating system thread.
51When cgo is available, the cgo-based resolver is used instead under a variety of
52conditions: on systems that do not let programs make direct DNS requests (OS X),
53when the LOCALDOMAIN environment variable is present (even if empty),
54when the RES_OPTIONS or HOSTALIASES environment variable is non-empty,
55when the ASR_CONFIG environment variable is non-empty (OpenBSD only),
56when /etc/resolv.conf or /etc/nsswitch.conf specify the use of features that the
57Go resolver does not implement, and when the name being looked up ends in .local
58or is an mDNS name.
59
60The resolver decision can be overridden by setting the netdns value of the
61GODEBUG environment variable (see package runtime) to go or cgo, as in:
62
63 export GODEBUG=netdns=go # force pure Go resolver
64 export GODEBUG=netdns=cgo # force cgo resolver
65
66The decision can also be forced while building the Go source tree
67by setting the netgo or netcgo build tag.
68
69A numeric netdns setting, as in GODEBUG=netdns=1, causes the resolver
70to print debugging information about its decisions.
71To force a particular resolver while also printing debugging information,
72join the two settings by a plus sign, as in GODEBUG=netdns=go+1.
73
74On Plan 9, the resolver always accesses /net/cs and /net/dns.
75
76On Windows, the resolver always uses C library functions, such as GetAddrInfo and DnsQuery.
77
Brad Fitzpatrick008e64d2012-02-17 13:07:06 +110078*/
Russ Coxe8a02232008-09-16 13:42:47 -070079package net
80
Brad Fitzpatrickb71883e2012-01-18 16:24:06 -080081import (
Brad Fitzpatrickb6b40042016-04-14 17:47:25 -070082 "context"
Brad Fitzpatrickb71883e2012-01-18 16:24:06 -080083 "errors"
Anthony Martin253ed022012-11-30 11:41:50 -080084 "io"
Mikio Hara306afc72012-11-13 16:18:37 +090085 "os"
86 "syscall"
Brad Fitzpatrickb71883e2012-01-18 16:24:06 -080087 "time"
88)
Russ Cox97bc2222009-05-07 17:36:29 -070089
Brad Fitzpatrickb615ad82015-06-25 12:52:54 +020090// netGo and netCgo contain the state of the build tags used
91// to build this binary, and whether cgo is available.
92// conf.go mirrors these into conf for easier testing.
93var (
94 netGo bool // set true in cgo_stub.go for build tag "netgo" (or no cgo)
95 netCgo bool // set true in conf_netcgo.go for build tag "netcgo"
96)
97
Mikio Hara3a9024b2015-04-01 22:46:12 +090098func init() {
99 sysInit()
100 supportsIPv4 = probeIPv4Stack()
101 supportsIPv6, supportsIPv4map = probeIPv6Stack()
102}
103
Russ Coxc83b8382009-11-02 18:37:30 -0800104// Addr represents a network end point address.
105type Addr interface {
Robert Griesemera3d10452009-12-15 15:35:38 -0800106 Network() string // name of the network
107 String() string // string form of address
Russ Coxc83b8382009-11-02 18:37:30 -0800108}
109
110// Conn is a generic stream-oriented network connection.
Russ Coxbabbf942012-03-07 14:55:09 -0500111//
112// Multiple goroutines may invoke methods on a Conn simultaneously.
Russ Coxcc1d4b72009-05-13 18:03:41 -0700113type Conn interface {
Russ Coxc83b8382009-11-02 18:37:30 -0800114 // Read reads data from the connection.
Mikio Hara3d400db2012-01-29 19:11:05 +0900115 // Read can be made to time out and return a Error with Timeout() == true
Mikio Hara2356e432012-01-19 12:23:30 +0900116 // after a fixed time limit; see SetDeadline and SetReadDeadline.
Russ Coxeb692922011-11-01 22:05:34 -0400117 Read(b []byte) (n int, err error)
Russ Coxcc1d4b72009-05-13 18:03:41 -0700118
Russ Coxc83b8382009-11-02 18:37:30 -0800119 // Write writes data to the connection.
Mikio Hara3d400db2012-01-29 19:11:05 +0900120 // Write can be made to time out and return a Error with Timeout() == true
Mikio Hara2356e432012-01-19 12:23:30 +0900121 // after a fixed time limit; see SetDeadline and SetWriteDeadline.
Russ Coxeb692922011-11-01 22:05:34 -0400122 Write(b []byte) (n int, err error)
Russ Coxcc1d4b72009-05-13 18:03:41 -0700123
124 // Close closes the connection.
Russ Coxbabbf942012-03-07 14:55:09 -0500125 // Any blocked Read or Write operations will be unblocked and return errors.
Russ Coxeb692922011-11-01 22:05:34 -0400126 Close() error
Russ Coxcc1d4b72009-05-13 18:03:41 -0700127
Rob Pikeefc40882009-06-19 16:03:59 -0700128 // LocalAddr returns the local network address.
Robert Griesemera3d10452009-12-15 15:35:38 -0800129 LocalAddr() Addr
Rob Pikeefc40882009-06-19 16:03:59 -0700130
131 // RemoteAddr returns the remote network address.
Robert Griesemera3d10452009-12-15 15:35:38 -0800132 RemoteAddr() Addr
Russ Coxcc1d4b72009-05-13 18:03:41 -0700133
Brad Fitzpatrickb71883e2012-01-18 16:24:06 -0800134 // SetDeadline sets the read and write deadlines associated
Brad Fitzpatrick8729d152012-02-21 11:11:18 +1100135 // with the connection. It is equivalent to calling both
136 // SetReadDeadline and SetWriteDeadline.
137 //
138 // A deadline is an absolute time after which I/O operations
139 // fail with a timeout (see type Error) instead of
140 // blocking. The deadline applies to all future I/O, not just
141 // the immediately following call to Read or Write.
142 //
143 // An idle timeout can be implemented by repeatedly extending
144 // the deadline after successful Read or Write calls.
145 //
146 // A zero value for t means I/O operations will not time out.
Brad Fitzpatrickb71883e2012-01-18 16:24:06 -0800147 SetDeadline(t time.Time) error
Russ Coxcc1d4b72009-05-13 18:03:41 -0700148
Russ Coxbabbf942012-03-07 14:55:09 -0500149 // SetReadDeadline sets the deadline for future Read calls.
Brad Fitzpatrickb71883e2012-01-18 16:24:06 -0800150 // A zero value for t means Read will not time out.
151 SetReadDeadline(t time.Time) error
Russ Coxcc1d4b72009-05-13 18:03:41 -0700152
Russ Coxbabbf942012-03-07 14:55:09 -0500153 // SetWriteDeadline sets the deadline for future Write calls.
Russ Coxcc1d4b72009-05-13 18:03:41 -0700154 // Even if write times out, it may return n > 0, indicating that
155 // some of the data was successfully written.
Brad Fitzpatrick8729d152012-02-21 11:11:18 +1100156 // A zero value for t means Write will not time out.
Brad Fitzpatrickb71883e2012-01-18 16:24:06 -0800157 SetWriteDeadline(t time.Time) error
Russ Coxcc1d4b72009-05-13 18:03:41 -0700158}
159
Mikio Hara306afc72012-11-13 16:18:37 +0900160type conn struct {
161 fd *netFD
162}
163
164func (c *conn) ok() bool { return c != nil && c.fd != nil }
165
166// Implementation of the Conn interface.
167
168// Read implements the Conn Read method.
169func (c *conn) Read(b []byte) (int, error) {
170 if !c.ok() {
171 return 0, syscall.EINVAL
172 }
Mikio Haraec114442015-04-16 23:10:56 +0900173 n, err := c.fd.Read(b)
174 if err != nil && err != io.EOF {
Mikio Haraafd2d2b2015-04-21 22:53:47 +0900175 err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
Mikio Haraec114442015-04-16 23:10:56 +0900176 }
177 return n, err
Mikio Hara306afc72012-11-13 16:18:37 +0900178}
179
180// Write implements the Conn Write method.
181func (c *conn) Write(b []byte) (int, error) {
182 if !c.ok() {
183 return 0, syscall.EINVAL
184 }
Mikio Hara11b5f982015-04-16 11:26:44 +0900185 n, err := c.fd.Write(b)
186 if err != nil {
Mikio Haraafd2d2b2015-04-21 22:53:47 +0900187 err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
Mikio Hara11b5f982015-04-16 11:26:44 +0900188 }
189 return n, err
Mikio Hara306afc72012-11-13 16:18:37 +0900190}
191
192// Close closes the connection.
193func (c *conn) Close() error {
194 if !c.ok() {
195 return syscall.EINVAL
196 }
Mikio Hara310db632015-04-17 12:24:42 +0900197 err := c.fd.Close()
198 if err != nil {
Mikio Haraafd2d2b2015-04-21 22:53:47 +0900199 err = &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
Mikio Hara310db632015-04-17 12:24:42 +0900200 }
201 return err
Mikio Hara306afc72012-11-13 16:18:37 +0900202}
203
204// LocalAddr returns the local network address.
Shenghou Ma7e43aee2015-02-03 12:59:40 -0500205// The Addr returned is shared by all invocations of LocalAddr, so
206// do not modify it.
Mikio Hara306afc72012-11-13 16:18:37 +0900207func (c *conn) LocalAddr() Addr {
208 if !c.ok() {
209 return nil
210 }
211 return c.fd.laddr
212}
213
214// RemoteAddr returns the remote network address.
Shenghou Ma7e43aee2015-02-03 12:59:40 -0500215// The Addr returned is shared by all invocations of RemoteAddr, so
216// do not modify it.
Mikio Hara306afc72012-11-13 16:18:37 +0900217func (c *conn) RemoteAddr() Addr {
218 if !c.ok() {
219 return nil
220 }
221 return c.fd.raddr
222}
223
224// SetDeadline implements the Conn SetDeadline method.
225func (c *conn) SetDeadline(t time.Time) error {
226 if !c.ok() {
227 return syscall.EINVAL
228 }
Mikio Hara2173a272015-04-19 19:01:49 +0900229 if err := c.fd.setDeadline(t); err != nil {
Mikio Haraafd2d2b2015-04-21 22:53:47 +0900230 return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
Mikio Hara2173a272015-04-19 19:01:49 +0900231 }
232 return nil
Mikio Hara306afc72012-11-13 16:18:37 +0900233}
234
235// SetReadDeadline implements the Conn SetReadDeadline method.
236func (c *conn) SetReadDeadline(t time.Time) error {
237 if !c.ok() {
238 return syscall.EINVAL
239 }
Mikio Hara2173a272015-04-19 19:01:49 +0900240 if err := c.fd.setReadDeadline(t); err != nil {
Mikio Haraafd2d2b2015-04-21 22:53:47 +0900241 return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
Mikio Hara2173a272015-04-19 19:01:49 +0900242 }
243 return nil
Mikio Hara306afc72012-11-13 16:18:37 +0900244}
245
246// SetWriteDeadline implements the Conn SetWriteDeadline method.
247func (c *conn) SetWriteDeadline(t time.Time) error {
248 if !c.ok() {
249 return syscall.EINVAL
250 }
Mikio Hara2173a272015-04-19 19:01:49 +0900251 if err := c.fd.setWriteDeadline(t); err != nil {
Mikio Haraafd2d2b2015-04-21 22:53:47 +0900252 return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
Mikio Hara2173a272015-04-19 19:01:49 +0900253 }
254 return nil
Mikio Hara306afc72012-11-13 16:18:37 +0900255}
256
257// SetReadBuffer sets the size of the operating system's
258// receive buffer associated with the connection.
259func (c *conn) SetReadBuffer(bytes int) error {
260 if !c.ok() {
261 return syscall.EINVAL
262 }
Mikio Hara2173a272015-04-19 19:01:49 +0900263 if err := setReadBuffer(c.fd, bytes); err != nil {
Mikio Haraafd2d2b2015-04-21 22:53:47 +0900264 return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
Mikio Hara2173a272015-04-19 19:01:49 +0900265 }
266 return nil
Mikio Hara306afc72012-11-13 16:18:37 +0900267}
268
269// SetWriteBuffer sets the size of the operating system's
270// transmit buffer associated with the connection.
271func (c *conn) SetWriteBuffer(bytes int) error {
272 if !c.ok() {
273 return syscall.EINVAL
274 }
Mikio Hara2173a272015-04-19 19:01:49 +0900275 if err := setWriteBuffer(c.fd, bytes); err != nil {
Mikio Haraafd2d2b2015-04-21 22:53:47 +0900276 return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
Mikio Hara2173a272015-04-19 19:01:49 +0900277 }
278 return nil
Mikio Hara306afc72012-11-13 16:18:37 +0900279}
280
Rick Arnold5416e6e2012-12-05 23:31:35 -0500281// File sets the underlying os.File to blocking mode and returns a copy.
Mikio Hara306afc72012-11-13 16:18:37 +0900282// It is the caller's responsibility to close f when finished.
283// Closing c does not affect f, and closing f does not affect c.
Rick Arnold5416e6e2012-12-05 23:31:35 -0500284//
285// The returned os.File's file descriptor is different from the connection's.
286// Attempting to change properties of the original using this duplicate
287// may or may not have the desired effect.
Mikio Hara88511132015-04-18 16:53:55 +0900288func (c *conn) File() (f *os.File, err error) {
289 f, err = c.fd.dup()
290 if err != nil {
Mikio Haraafd2d2b2015-04-21 22:53:47 +0900291 err = &OpError{Op: "file", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
Mikio Hara88511132015-04-18 16:53:55 +0900292 }
293 return
294}
Mikio Hara306afc72012-11-13 16:18:37 +0900295
Russ Coxc83b8382009-11-02 18:37:30 -0800296// PacketConn is a generic packet-oriented network connection.
Russ Coxbabbf942012-03-07 14:55:09 -0500297//
298// Multiple goroutines may invoke methods on a PacketConn simultaneously.
Russ Coxc83b8382009-11-02 18:37:30 -0800299type PacketConn interface {
300 // ReadFrom reads a packet from the connection,
Brad Fitzpatrick5fea2cc2016-03-01 23:21:55 +0000301 // copying the payload into b. It returns the number of
Russ Coxc83b8382009-11-02 18:37:30 -0800302 // bytes copied into b and the return address that
303 // was on the packet.
Russ Cox47a05332010-04-26 22:15:25 -0700304 // ReadFrom can be made to time out and return
305 // an error with Timeout() == true after a fixed time limit;
Brad Fitzpatrickb71883e2012-01-18 16:24:06 -0800306 // see SetDeadline and SetReadDeadline.
Russ Coxeb692922011-11-01 22:05:34 -0400307 ReadFrom(b []byte) (n int, addr Addr, err error)
Russ Coxc83b8382009-11-02 18:37:30 -0800308
309 // WriteTo writes a packet with payload b to addr.
Russ Cox47a05332010-04-26 22:15:25 -0700310 // WriteTo can be made to time out and return
311 // an error with Timeout() == true after a fixed time limit;
Brad Fitzpatrickb71883e2012-01-18 16:24:06 -0800312 // see SetDeadline and SetWriteDeadline.
Russ Coxc83b8382009-11-02 18:37:30 -0800313 // On packet-oriented connections, write timeouts are rare.
Russ Coxeb692922011-11-01 22:05:34 -0400314 WriteTo(b []byte, addr Addr) (n int, err error)
Russ Coxc83b8382009-11-02 18:37:30 -0800315
316 // Close closes the connection.
Russ Coxbabbf942012-03-07 14:55:09 -0500317 // Any blocked ReadFrom or WriteTo operations will be unblocked and return errors.
Russ Coxeb692922011-11-01 22:05:34 -0400318 Close() error
Russ Coxc83b8382009-11-02 18:37:30 -0800319
320 // LocalAddr returns the local network address.
Robert Griesemera3d10452009-12-15 15:35:38 -0800321 LocalAddr() Addr
Russ Coxc83b8382009-11-02 18:37:30 -0800322
Brad Fitzpatrickb71883e2012-01-18 16:24:06 -0800323 // SetDeadline sets the read and write deadlines associated
Russ Coxc83b8382009-11-02 18:37:30 -0800324 // with the connection.
Brad Fitzpatrickb71883e2012-01-18 16:24:06 -0800325 SetDeadline(t time.Time) error
Russ Coxc83b8382009-11-02 18:37:30 -0800326
Russ Coxbabbf942012-03-07 14:55:09 -0500327 // SetReadDeadline sets the deadline for future Read calls.
Brad Fitzpatrickb71883e2012-01-18 16:24:06 -0800328 // If the deadline is reached, Read will fail with a timeout
329 // (see type Error) instead of blocking.
330 // A zero value for t means Read will not time out.
331 SetReadDeadline(t time.Time) error
Russ Coxc83b8382009-11-02 18:37:30 -0800332
Russ Coxbabbf942012-03-07 14:55:09 -0500333 // SetWriteDeadline sets the deadline for future Write calls.
Brad Fitzpatrickb71883e2012-01-18 16:24:06 -0800334 // If the deadline is reached, Write will fail with a timeout
335 // (see type Error) instead of blocking.
336 // A zero value for t means Write will not time out.
Russ Coxc83b8382009-11-02 18:37:30 -0800337 // Even if write times out, it may return n > 0, indicating that
338 // some of the data was successfully written.
Brad Fitzpatrickb71883e2012-01-18 16:24:06 -0800339 SetWriteDeadline(t time.Time) error
Russ Coxc83b8382009-11-02 18:37:30 -0800340}
341
Mikio Haraa0a45bb2013-07-24 08:43:08 +0900342var listenerBacklog = maxListenerBacklog()
343
Russ Coxc83b8382009-11-02 18:37:30 -0800344// A Listener is a generic network listener for stream-oriented protocols.
Russ Coxbabbf942012-03-07 14:55:09 -0500345//
346// Multiple goroutines may invoke methods on a Listener simultaneously.
Russ Cox35ace1d2009-11-01 11:15:34 -0800347type Listener interface {
Russ Cox47a05332010-04-26 22:15:25 -0700348 // Accept waits for and returns the next connection to the listener.
Brad Fitzpatrick19d262f2015-09-14 20:58:21 -0700349 Accept() (Conn, error)
Russ Cox47a05332010-04-26 22:15:25 -0700350
351 // Close closes the listener.
Russ Coxbabbf942012-03-07 14:55:09 -0500352 // Any blocked Accept operations will be unblocked and return errors.
Russ Coxeb692922011-11-01 22:05:34 -0400353 Close() error
Russ Cox47a05332010-04-26 22:15:25 -0700354
355 // Addr returns the listener's network address.
356 Addr() Addr
Russ Cox5d2ee9d2009-06-17 21:44:26 -0700357}
358
Mikio Hara055ecb72015-04-21 21:20:15 +0900359// An Error represents a network error.
360type Error interface {
361 error
362 Timeout() bool // Is the error a timeout?
363 Temporary() bool // Is the error temporary?
364}
365
Mikio Haraa2a35142014-04-08 06:14:49 +0900366// Various errors contained in OpError.
367var (
Mikio Hara790053b2016-03-15 10:00:12 +0900368 // For connection setup operations.
369 errNoSuitableAddress = errors.New("no suitable address found")
370
Mikio Haraa2a35142014-04-08 06:14:49 +0900371 // For connection setup and write operations.
372 errMissingAddress = errors.New("missing address")
373
374 // For both read and write operations.
375 errTimeout error = &timeoutError{}
Paul Marks0d8366e2015-04-10 14:15:54 -0700376 errCanceled = errors.New("operation was canceled")
Mikio Haraa2a35142014-04-08 06:14:49 +0900377 errClosing = errors.New("use of closed network connection")
378 ErrWriteToConnected = errors.New("use of WriteTo with pre-connected connection")
379)
Russ Cox35ace1d2009-11-01 11:15:34 -0800380
Brad Fitzpatrickb6b40042016-04-14 17:47:25 -0700381// mapErr maps from the context errors to the historical internal net
382// error values.
383//
384// TODO(bradfitz): get rid of this after adjusting tests and making
385// context.DeadlineExceeded implement net.Error?
386func mapErr(err error) error {
387 switch err {
388 case context.Canceled:
389 return errCanceled
390 case context.DeadlineExceeded:
391 return errTimeout
392 default:
393 return err
394 }
395}
396
Brad Fitzpatrick158a0352013-02-14 09:29:34 -0800397// OpError is the error type usually returned by functions in the net
398// package. It describes the operation, network type, and address of
399// an error.
Russ Cox35ace1d2009-11-01 11:15:34 -0800400type OpError struct {
Brad Fitzpatrick158a0352013-02-14 09:29:34 -0800401 // Op is the operation which caused the error, such as
402 // "read" or "write".
403 Op string
404
405 // Net is the network type on which this error occurred,
406 // such as "tcp" or "udp6".
407 Net string
408
Mikio Haraafd2d2b2015-04-21 22:53:47 +0900409 // For operations involving a remote network connection, like
410 // Dial, Read, or Write, Source is the corresponding local
411 // network address.
412 Source Addr
413
414 // Addr is the network address for which this error occurred.
415 // For local operations, like Listen or SetDeadline, Addr is
416 // the address of the local endpoint being manipulated.
417 // For operations involving a remote network connection, like
418 // Dial, Read, or Write, Addr is the remote address of that
419 // connection.
Russ Coxeb692922011-11-01 22:05:34 -0400420 Addr Addr
Brad Fitzpatrick158a0352013-02-14 09:29:34 -0800421
422 // Err is the error that occurred during the operation.
423 Err error
Russ Cox35ace1d2009-11-01 11:15:34 -0800424}
425
Russ Coxeb692922011-11-01 22:05:34 -0400426func (e *OpError) Error() string {
Andrew Gerrandfc4ba152010-07-27 17:22:22 +1000427 if e == nil {
428 return "<nil>"
429 }
Robert Griesemera3d10452009-12-15 15:35:38 -0800430 s := e.Op
Russ Cox35ace1d2009-11-01 11:15:34 -0800431 if e.Net != "" {
Robert Griesemer40621d52009-11-09 12:07:39 -0800432 s += " " + e.Net
Russ Cox35ace1d2009-11-01 11:15:34 -0800433 }
Mikio Haraafd2d2b2015-04-21 22:53:47 +0900434 if e.Source != nil {
435 s += " " + e.Source.String()
436 }
Russ Coxc83b8382009-11-02 18:37:30 -0800437 if e.Addr != nil {
Mikio Haraafd2d2b2015-04-21 22:53:47 +0900438 if e.Source != nil {
439 s += "->"
440 } else {
441 s += " "
442 }
443 s += e.Addr.String()
Russ Cox35ace1d2009-11-01 11:15:34 -0800444 }
Russ Coxeb692922011-11-01 22:05:34 -0400445 s += ": " + e.Err.Error()
Robert Griesemera3d10452009-12-15 15:35:38 -0800446 return s
Russ Cox35ace1d2009-11-01 11:15:34 -0800447}
448
Brad Fitzpatrick24a83d32015-12-14 22:21:48 +0000449var (
450 // aLongTimeAgo is a non-zero time, far in the past, used for
451 // immediate cancelation of dials.
452 aLongTimeAgo = time.Unix(233431200, 0)
453
454 // nonDeadline and noCancel are just zero values for
455 // readability with functions taking too many parameters.
456 noDeadline = time.Time{}
457 noCancel = (chan struct{})(nil)
458)
Brad Fitzpatrickef6806f2012-11-08 10:35:16 -0600459
Russ Cox47a05332010-04-26 22:15:25 -0700460type timeout interface {
461 Timeout() bool
462}
463
464func (e *OpError) Timeout() bool {
Mikio Hara055ecb72015-04-21 21:20:15 +0900465 if ne, ok := e.Err.(*os.SyscallError); ok {
466 t, ok := ne.Err.(timeout)
467 return ok && t.Timeout()
468 }
Russ Coxeb692922011-11-01 22:05:34 -0400469 t, ok := e.Err.(timeout)
Russ Cox47a05332010-04-26 22:15:25 -0700470 return ok && t.Timeout()
471}
472
Mikio Hara055ecb72015-04-21 21:20:15 +0900473type temporary interface {
474 Temporary() bool
475}
476
477func (e *OpError) Temporary() bool {
478 if ne, ok := e.Err.(*os.SyscallError); ok {
479 t, ok := ne.Err.(temporary)
480 return ok && t.Temporary()
481 }
482 t, ok := e.Err.(temporary)
483 return ok && t.Temporary()
484}
485
Brad Fitzpatrick01507b92011-12-20 14:32:33 -0800486type timeoutError struct{}
487
488func (e *timeoutError) Error() string { return "i/o timeout" }
489func (e *timeoutError) Timeout() bool { return true }
490func (e *timeoutError) Temporary() bool { return true }
491
Mikio Hara055ecb72015-04-21 21:20:15 +0900492// A ParseError is the error type of literal network address parsers.
493type ParseError struct {
494 // Type is the type of string that was expected, such as
495 // "IP address", "CIDR address".
496 Type string
497
498 // Text is the malformed text string.
499 Text string
500}
501
502func (e *ParseError) Error() string { return "invalid " + e.Type + ": " + e.Text }
503
Russ Cox35ace1d2009-11-01 11:15:34 -0800504type AddrError struct {
Russ Coxeb692922011-11-01 22:05:34 -0400505 Err string
506 Addr string
Russ Cox35ace1d2009-11-01 11:15:34 -0800507}
508
Russ Coxeb692922011-11-01 22:05:34 -0400509func (e *AddrError) Error() string {
Andrew Gerrandfc4ba152010-07-27 17:22:22 +1000510 if e == nil {
511 return "<nil>"
512 }
Russ Coxeb692922011-11-01 22:05:34 -0400513 s := e.Err
Russ Cox35ace1d2009-11-01 11:15:34 -0800514 if e.Addr != "" {
Robert Griesemer40621d52009-11-09 12:07:39 -0800515 s += " " + e.Addr
Russ Cox35ace1d2009-11-01 11:15:34 -0800516 }
Robert Griesemera3d10452009-12-15 15:35:38 -0800517 return s
Russ Cox35ace1d2009-11-01 11:15:34 -0800518}
519
Mikio Hara0fc582e82015-04-19 20:54:01 +0900520func (e *AddrError) Timeout() bool { return false }
Mikio Hara055ecb72015-04-21 21:20:15 +0900521func (e *AddrError) Temporary() bool { return false }
Russ Cox47a05332010-04-26 22:15:25 -0700522
Russ Cox35ace1d2009-11-01 11:15:34 -0800523type UnknownNetworkError string
Robert Griesemer5d377052009-11-04 23:16:46 -0800524
Russ Coxeb692922011-11-01 22:05:34 -0400525func (e UnknownNetworkError) Error() string { return "unknown network " + string(e) }
Russ Cox47a05332010-04-26 22:15:25 -0700526func (e UnknownNetworkError) Timeout() bool { return false }
Mikio Hara055ecb72015-04-21 21:20:15 +0900527func (e UnknownNetworkError) Temporary() bool { return false }
Brad Fitzpatrick549ca932012-01-31 13:01:34 -0800528
Mikio Haradb84a452013-08-10 09:46:22 +0900529type InvalidAddrError string
530
531func (e InvalidAddrError) Error() string { return string(e) }
532func (e InvalidAddrError) Timeout() bool { return false }
533func (e InvalidAddrError) Temporary() bool { return false }
534
Brad Fitzpatrick549ca932012-01-31 13:01:34 -0800535// DNSConfigError represents an error reading the machine's DNS configuration.
Alex A Skinnerf3901352015-04-25 20:50:21 -0400536// (No longer used; kept for compatibility.)
Brad Fitzpatrick549ca932012-01-31 13:01:34 -0800537type DNSConfigError struct {
538 Err error
539}
540
Mikio Hara0fc582e82015-04-19 20:54:01 +0900541func (e *DNSConfigError) Error() string { return "error reading DNS config: " + e.Err.Error() }
Brad Fitzpatrick549ca932012-01-31 13:01:34 -0800542func (e *DNSConfigError) Timeout() bool { return false }
543func (e *DNSConfigError) Temporary() bool { return false }
Anthony Martin253ed022012-11-30 11:41:50 -0800544
Mikio Hara0fc582e82015-04-19 20:54:01 +0900545// Various errors contained in DNSError.
546var (
547 errNoSuchHost = errors.New("no such host")
548)
549
550// DNSError represents a DNS lookup error.
551type DNSError struct {
Dan Petersonced06462015-09-01 22:53:46 -0300552 Err string // description of the error
553 Name string // name looked for
554 Server string // server used
555 IsTimeout bool // if true, timed out; not all timeouts set this
556 IsTemporary bool // if true, error is temporary; not all errors set this
Mikio Hara0fc582e82015-04-19 20:54:01 +0900557}
558
559func (e *DNSError) Error() string {
560 if e == nil {
561 return "<nil>"
562 }
563 s := "lookup " + e.Name
564 if e.Server != "" {
565 s += " on " + e.Server
566 }
567 s += ": " + e.Err
568 return s
569}
570
571// Timeout reports whether the DNS lookup is known to have timed out.
572// This is not always known; a DNS lookup may fail due to a timeout
573// and return a DNSError for which Timeout returns false.
574func (e *DNSError) Timeout() bool { return e.IsTimeout }
575
576// Temporary reports whether the DNS error is known to be temporary.
577// This is not always known; a DNS lookup may fail due to a temporary
578// error and return a DNSError for which Temporary returns false.
Dan Petersonced06462015-09-01 22:53:46 -0300579func (e *DNSError) Temporary() bool { return e.IsTimeout || e.IsTemporary }
Mikio Hara0fc582e82015-04-19 20:54:01 +0900580
Anthony Martin253ed022012-11-30 11:41:50 -0800581type writerOnly struct {
582 io.Writer
583}
584
585// Fallback implementation of io.ReaderFrom's ReadFrom, when sendfile isn't
586// applicable.
587func genericReadFrom(w io.Writer, r io.Reader) (n int64, err error) {
588 // Use wrapper to hide existing r.ReadFrom from io.Copy.
589 return io.Copy(writerOnly{w}, r)
590}
Dave Cheney9fb96992012-12-05 15:59:01 +1100591
Russ Cox1d3efd62013-08-16 22:43:05 -0400592// Limit the number of concurrent cgo-using goroutines, because
593// each will block an entire operating system thread. The usual culprit
594// is resolving many DNS names in separate goroutines but the DNS
595// server is not responding. Then the many lookups each use a different
596// thread, and the system or the program runs out of threads.
597
598var threadLimit = make(chan struct{}, 500)
599
600func acquireThread() {
Russ Coxbab302d2013-09-11 20:29:22 -0400601 threadLimit <- struct{}{}
Russ Cox1d3efd62013-08-16 22:43:05 -0400602}
603
604func releaseThread() {
Russ Coxbab302d2013-09-11 20:29:22 -0400605 <-threadLimit
Russ Cox1d3efd62013-08-16 22:43:05 -0400606}