Source file src/net/net.go

     1  // 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  
     5  /*
     6  Package net provides a portable interface for network I/O, including
     7  TCP/IP, UDP, domain name resolution, and Unix domain sockets.
     8  
     9  Although the package provides access to low-level networking
    10  primitives, most clients will need only the basic interface provided
    11  by the Dial, Listen, and Accept functions and the associated
    12  Conn and Listener interfaces. The crypto/tls package uses
    13  the same interfaces and similar Dial and Listen functions.
    14  
    15  The Dial function connects to a server:
    16  
    17  	conn, err := net.Dial("tcp", "golang.org:80")
    18  	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  
    25  The 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
    35  		}
    36  		go handleConnection(conn)
    37  	}
    38  
    39  Name Resolution
    40  
    41  The method for resolving domain names, whether indirectly with functions like Dial
    42  or directly with functions like LookupHost and LookupAddr, varies by operating system.
    43  
    44  On Unix systems, the resolver has two options for resolving names.
    45  It can use a pure Go resolver that sends DNS requests directly to the servers
    46  listed in /etc/resolv.conf, or it can use a cgo-based resolver that calls C
    47  library routines such as getaddrinfo and getnameinfo.
    48  
    49  By default the pure Go resolver is used, because a blocked DNS request consumes
    50  only a goroutine, while a blocked C call consumes an operating system thread.
    51  When cgo is available, the cgo-based resolver is used instead under a variety of
    52  conditions: on systems that do not let programs make direct DNS requests (OS X),
    53  when the LOCALDOMAIN environment variable is present (even if empty),
    54  when the RES_OPTIONS or HOSTALIASES environment variable is non-empty,
    55  when the ASR_CONFIG environment variable is non-empty (OpenBSD only),
    56  when /etc/resolv.conf or /etc/nsswitch.conf specify the use of features that the
    57  Go resolver does not implement, and when the name being looked up ends in .local
    58  or is an mDNS name.
    59  
    60  The resolver decision can be overridden by setting the netdns value of the
    61  GODEBUG 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  
    66  The decision can also be forced while building the Go source tree
    67  by setting the netgo or netcgo build tag.
    68  
    69  A numeric netdns setting, as in GODEBUG=netdns=1, causes the resolver
    70  to print debugging information about its decisions.
    71  To force a particular resolver while also printing debugging information,
    72  join the two settings by a plus sign, as in GODEBUG=netdns=go+1.
    73  
    74  On Plan 9, the resolver always accesses /net/cs and /net/dns.
    75  
    76  On Windows, the resolver always uses C library functions, such as GetAddrInfo and DnsQuery.
    77  
    78  */
    79  package net
    80  
    81  import (
    82  	"context"
    83  	"errors"
    84  	"internal/poll"
    85  	"io"
    86  	"os"
    87  	"sync"
    88  	"syscall"
    89  	"time"
    90  )
    91  
    92  // netGo and netCgo contain the state of the build tags used
    93  // to build this binary, and whether cgo is available.
    94  // conf.go mirrors these into conf for easier testing.
    95  var (
    96  	netGo  bool // set true in cgo_stub.go for build tag "netgo" (or no cgo)
    97  	netCgo bool // set true in conf_netcgo.go for build tag "netcgo"
    98  )
    99  
   100  // Addr represents a network end point address.
   101  //
   102  // The two methods Network and String conventionally return strings
   103  // that can be passed as the arguments to Dial, but the exact form
   104  // and meaning of the strings is up to the implementation.
   105  type Addr interface {
   106  	Network() string // name of the network (for example, "tcp", "udp")
   107  	String() string  // string form of address (for example, "192.0.2.1:25", "[2001:db8::1]:80")
   108  }
   109  
   110  // Conn is a generic stream-oriented network connection.
   111  //
   112  // Multiple goroutines may invoke methods on a Conn simultaneously.
   113  type Conn interface {
   114  	// Read reads data from the connection.
   115  	// Read can be made to time out and return an error after a fixed
   116  	// time limit; see SetDeadline and SetReadDeadline.
   117  	Read(b []byte) (n int, err error)
   118  
   119  	// Write writes data to the connection.
   120  	// Write can be made to time out and return an error after a fixed
   121  	// time limit; see SetDeadline and SetWriteDeadline.
   122  	Write(b []byte) (n int, err error)
   123  
   124  	// Close closes the connection.
   125  	// Any blocked Read or Write operations will be unblocked and return errors.
   126  	Close() error
   127  
   128  	// LocalAddr returns the local network address, if known.
   129  	LocalAddr() Addr
   130  
   131  	// RemoteAddr returns the remote network address, if known.
   132  	RemoteAddr() Addr
   133  
   134  	// SetDeadline sets the read and write deadlines associated
   135  	// 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 instead of blocking. The deadline applies to all future
   140  	// and pending I/O, not just the immediately following call to
   141  	// Read or Write. After a deadline has been exceeded, the
   142  	// connection can be refreshed by setting a deadline in the future.
   143  	//
   144  	// If the deadline is exceeded a call to Read or Write or to other
   145  	// I/O methods will return an error that wraps os.ErrDeadlineExceeded.
   146  	// This can be tested using errors.Is(err, os.ErrDeadlineExceeded).
   147  	// The error's Timeout method will return true, but note that there
   148  	// are other possible errors for which the Timeout method will
   149  	// return true even if the deadline has not been exceeded.
   150  	//
   151  	// An idle timeout can be implemented by repeatedly extending
   152  	// the deadline after successful Read or Write calls.
   153  	//
   154  	// A zero value for t means I/O operations will not time out.
   155  	SetDeadline(t time.Time) error
   156  
   157  	// SetReadDeadline sets the deadline for future Read calls
   158  	// and any currently-blocked Read call.
   159  	// A zero value for t means Read will not time out.
   160  	SetReadDeadline(t time.Time) error
   161  
   162  	// SetWriteDeadline sets the deadline for future Write calls
   163  	// and any currently-blocked Write call.
   164  	// Even if write times out, it may return n > 0, indicating that
   165  	// some of the data was successfully written.
   166  	// A zero value for t means Write will not time out.
   167  	SetWriteDeadline(t time.Time) error
   168  }
   169  
   170  type conn struct {
   171  	fd *netFD
   172  }
   173  
   174  func (c *conn) ok() bool { return c != nil && c.fd != nil }
   175  
   176  // Implementation of the Conn interface.
   177  
   178  // Read implements the Conn Read method.
   179  func (c *conn) Read(b []byte) (int, error) {
   180  	if !c.ok() {
   181  		return 0, syscall.EINVAL
   182  	}
   183  	n, err := c.fd.Read(b)
   184  	if err != nil && err != io.EOF {
   185  		err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
   186  	}
   187  	return n, err
   188  }
   189  
   190  // Write implements the Conn Write method.
   191  func (c *conn) Write(b []byte) (int, error) {
   192  	if !c.ok() {
   193  		return 0, syscall.EINVAL
   194  	}
   195  	n, err := c.fd.Write(b)
   196  	if err != nil {
   197  		err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
   198  	}
   199  	return n, err
   200  }
   201  
   202  // Close closes the connection.
   203  func (c *conn) Close() error {
   204  	if !c.ok() {
   205  		return syscall.EINVAL
   206  	}
   207  	err := c.fd.Close()
   208  	if err != nil {
   209  		err = &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
   210  	}
   211  	return err
   212  }
   213  
   214  // LocalAddr returns the local network address.
   215  // The Addr returned is shared by all invocations of LocalAddr, so
   216  // do not modify it.
   217  func (c *conn) LocalAddr() Addr {
   218  	if !c.ok() {
   219  		return nil
   220  	}
   221  	return c.fd.laddr
   222  }
   223  
   224  // RemoteAddr returns the remote network address.
   225  // The Addr returned is shared by all invocations of RemoteAddr, so
   226  // do not modify it.
   227  func (c *conn) RemoteAddr() Addr {
   228  	if !c.ok() {
   229  		return nil
   230  	}
   231  	return c.fd.raddr
   232  }
   233  
   234  // SetDeadline implements the Conn SetDeadline method.
   235  func (c *conn) SetDeadline(t time.Time) error {
   236  	if !c.ok() {
   237  		return syscall.EINVAL
   238  	}
   239  	if err := c.fd.SetDeadline(t); err != nil {
   240  		return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
   241  	}
   242  	return nil
   243  }
   244  
   245  // SetReadDeadline implements the Conn SetReadDeadline method.
   246  func (c *conn) SetReadDeadline(t time.Time) error {
   247  	if !c.ok() {
   248  		return syscall.EINVAL
   249  	}
   250  	if err := c.fd.SetReadDeadline(t); err != nil {
   251  		return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
   252  	}
   253  	return nil
   254  }
   255  
   256  // SetWriteDeadline implements the Conn SetWriteDeadline method.
   257  func (c *conn) SetWriteDeadline(t time.Time) error {
   258  	if !c.ok() {
   259  		return syscall.EINVAL
   260  	}
   261  	if err := c.fd.SetWriteDeadline(t); err != nil {
   262  		return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
   263  	}
   264  	return nil
   265  }
   266  
   267  // SetReadBuffer sets the size of the operating system's
   268  // receive buffer associated with the connection.
   269  func (c *conn) SetReadBuffer(bytes int) error {
   270  	if !c.ok() {
   271  		return syscall.EINVAL
   272  	}
   273  	if err := setReadBuffer(c.fd, bytes); err != nil {
   274  		return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
   275  	}
   276  	return nil
   277  }
   278  
   279  // SetWriteBuffer sets the size of the operating system's
   280  // transmit buffer associated with the connection.
   281  func (c *conn) SetWriteBuffer(bytes int) error {
   282  	if !c.ok() {
   283  		return syscall.EINVAL
   284  	}
   285  	if err := setWriteBuffer(c.fd, bytes); err != nil {
   286  		return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
   287  	}
   288  	return nil
   289  }
   290  
   291  // File returns a copy of the underlying os.File.
   292  // It is the caller's responsibility to close f when finished.
   293  // Closing c does not affect f, and closing f does not affect c.
   294  //
   295  // The returned os.File's file descriptor is different from the connection's.
   296  // Attempting to change properties of the original using this duplicate
   297  // may or may not have the desired effect.
   298  func (c *conn) File() (f *os.File, err error) {
   299  	f, err = c.fd.dup()
   300  	if err != nil {
   301  		err = &OpError{Op: "file", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
   302  	}
   303  	return
   304  }
   305  
   306  // PacketConn is a generic packet-oriented network connection.
   307  //
   308  // Multiple goroutines may invoke methods on a PacketConn simultaneously.
   309  type PacketConn interface {
   310  	// ReadFrom reads a packet from the connection,
   311  	// copying the payload into p. It returns the number of
   312  	// bytes copied into p and the return address that
   313  	// was on the packet.
   314  	// It returns the number of bytes read (0 <= n <= len(p))
   315  	// and any error encountered. Callers should always process
   316  	// the n > 0 bytes returned before considering the error err.
   317  	// ReadFrom can be made to time out and return an error after a
   318  	// fixed time limit; see SetDeadline and SetReadDeadline.
   319  	ReadFrom(p []byte) (n int, addr Addr, err error)
   320  
   321  	// WriteTo writes a packet with payload p to addr.
   322  	// WriteTo can be made to time out and return an Error after a
   323  	// fixed time limit; see SetDeadline and SetWriteDeadline.
   324  	// On packet-oriented connections, write timeouts are rare.
   325  	WriteTo(p []byte, addr Addr) (n int, err error)
   326  
   327  	// Close closes the connection.
   328  	// Any blocked ReadFrom or WriteTo operations will be unblocked and return errors.
   329  	Close() error
   330  
   331  	// LocalAddr returns the local network address, if known.
   332  	LocalAddr() Addr
   333  
   334  	// SetDeadline sets the read and write deadlines associated
   335  	// with the connection. It is equivalent to calling both
   336  	// SetReadDeadline and SetWriteDeadline.
   337  	//
   338  	// A deadline is an absolute time after which I/O operations
   339  	// fail instead of blocking. The deadline applies to all future
   340  	// and pending I/O, not just the immediately following call to
   341  	// Read or Write. After a deadline has been exceeded, the
   342  	// connection can be refreshed by setting a deadline in the future.
   343  	//
   344  	// If the deadline is exceeded a call to Read or Write or to other
   345  	// I/O methods will return an error that wraps os.ErrDeadlineExceeded.
   346  	// This can be tested using errors.Is(err, os.ErrDeadlineExceeded).
   347  	// The error's Timeout method will return true, but note that there
   348  	// are other possible errors for which the Timeout method will
   349  	// return true even if the deadline has not been exceeded.
   350  	//
   351  	// An idle timeout can be implemented by repeatedly extending
   352  	// the deadline after successful ReadFrom or WriteTo calls.
   353  	//
   354  	// A zero value for t means I/O operations will not time out.
   355  	SetDeadline(t time.Time) error
   356  
   357  	// SetReadDeadline sets the deadline for future ReadFrom calls
   358  	// and any currently-blocked ReadFrom call.
   359  	// A zero value for t means ReadFrom will not time out.
   360  	SetReadDeadline(t time.Time) error
   361  
   362  	// SetWriteDeadline sets the deadline for future WriteTo calls
   363  	// and any currently-blocked WriteTo call.
   364  	// Even if write times out, it may return n > 0, indicating that
   365  	// some of the data was successfully written.
   366  	// A zero value for t means WriteTo will not time out.
   367  	SetWriteDeadline(t time.Time) error
   368  }
   369  
   370  var listenerBacklogCache struct {
   371  	sync.Once
   372  	val int
   373  }
   374  
   375  // listenerBacklog is a caching wrapper around maxListenerBacklog.
   376  func listenerBacklog() int {
   377  	listenerBacklogCache.Do(func() { listenerBacklogCache.val = maxListenerBacklog() })
   378  	return listenerBacklogCache.val
   379  }
   380  
   381  // A Listener is a generic network listener for stream-oriented protocols.
   382  //
   383  // Multiple goroutines may invoke methods on a Listener simultaneously.
   384  type Listener interface {
   385  	// Accept waits for and returns the next connection to the listener.
   386  	Accept() (Conn, error)
   387  
   388  	// Close closes the listener.
   389  	// Any blocked Accept operations will be unblocked and return errors.
   390  	Close() error
   391  
   392  	// Addr returns the listener's network address.
   393  	Addr() Addr
   394  }
   395  
   396  // An Error represents a network error.
   397  type Error interface {
   398  	error
   399  	Timeout() bool // Is the error a timeout?
   400  
   401  	// Deprecated: Temporary errors are not well-defined.
   402  	// Most "temporary" errors are timeouts, and the few exceptions are surprising.
   403  	// Do not use this method.
   404  	Temporary() bool
   405  }
   406  
   407  // Various errors contained in OpError.
   408  var (
   409  	// For connection setup operations.
   410  	errNoSuitableAddress = errors.New("no suitable address found")
   411  
   412  	// For connection setup and write operations.
   413  	errMissingAddress = errors.New("missing address")
   414  
   415  	// For both read and write operations.
   416  	errCanceled         = errors.New("operation was canceled")
   417  	ErrWriteToConnected = errors.New("use of WriteTo with pre-connected connection")
   418  )
   419  
   420  // mapErr maps from the context errors to the historical internal net
   421  // error values.
   422  //
   423  // TODO(bradfitz): get rid of this after adjusting tests and making
   424  // context.DeadlineExceeded implement net.Error?
   425  func mapErr(err error) error {
   426  	switch err {
   427  	case context.Canceled:
   428  		return errCanceled
   429  	case context.DeadlineExceeded:
   430  		return errTimeout
   431  	default:
   432  		return err
   433  	}
   434  }
   435  
   436  // OpError is the error type usually returned by functions in the net
   437  // package. It describes the operation, network type, and address of
   438  // an error.
   439  type OpError struct {
   440  	// Op is the operation which caused the error, such as
   441  	// "read" or "write".
   442  	Op string
   443  
   444  	// Net is the network type on which this error occurred,
   445  	// such as "tcp" or "udp6".
   446  	Net string
   447  
   448  	// For operations involving a remote network connection, like
   449  	// Dial, Read, or Write, Source is the corresponding local
   450  	// network address.
   451  	Source Addr
   452  
   453  	// Addr is the network address for which this error occurred.
   454  	// For local operations, like Listen or SetDeadline, Addr is
   455  	// the address of the local endpoint being manipulated.
   456  	// For operations involving a remote network connection, like
   457  	// Dial, Read, or Write, Addr is the remote address of that
   458  	// connection.
   459  	Addr Addr
   460  
   461  	// Err is the error that occurred during the operation.
   462  	// The Error method panics if the error is nil.
   463  	Err error
   464  }
   465  
   466  func (e *OpError) Unwrap() error { return e.Err }
   467  
   468  func (e *OpError) Error() string {
   469  	if e == nil {
   470  		return "<nil>"
   471  	}
   472  	s := e.Op
   473  	if e.Net != "" {
   474  		s += " " + e.Net
   475  	}
   476  	if e.Source != nil {
   477  		s += " " + e.Source.String()
   478  	}
   479  	if e.Addr != nil {
   480  		if e.Source != nil {
   481  			s += "->"
   482  		} else {
   483  			s += " "
   484  		}
   485  		s += e.Addr.String()
   486  	}
   487  	s += ": " + e.Err.Error()
   488  	return s
   489  }
   490  
   491  var (
   492  	// aLongTimeAgo is a non-zero time, far in the past, used for
   493  	// immediate cancellation of dials.
   494  	aLongTimeAgo = time.Unix(1, 0)
   495  
   496  	// nonDeadline and noCancel are just zero values for
   497  	// readability with functions taking too many parameters.
   498  	noDeadline = time.Time{}
   499  	noCancel   = (chan struct{})(nil)
   500  )
   501  
   502  type timeout interface {
   503  	Timeout() bool
   504  }
   505  
   506  func (e *OpError) Timeout() bool {
   507  	if ne, ok := e.Err.(*os.SyscallError); ok {
   508  		t, ok := ne.Err.(timeout)
   509  		return ok && t.Timeout()
   510  	}
   511  	t, ok := e.Err.(timeout)
   512  	return ok && t.Timeout()
   513  }
   514  
   515  type temporary interface {
   516  	Temporary() bool
   517  }
   518  
   519  func (e *OpError) Temporary() bool {
   520  	// Treat ECONNRESET and ECONNABORTED as temporary errors when
   521  	// they come from calling accept. See issue 6163.
   522  	if e.Op == "accept" && isConnError(e.Err) {
   523  		return true
   524  	}
   525  
   526  	if ne, ok := e.Err.(*os.SyscallError); ok {
   527  		t, ok := ne.Err.(temporary)
   528  		return ok && t.Temporary()
   529  	}
   530  	t, ok := e.Err.(temporary)
   531  	return ok && t.Temporary()
   532  }
   533  
   534  // A ParseError is the error type of literal network address parsers.
   535  type ParseError struct {
   536  	// Type is the type of string that was expected, such as
   537  	// "IP address", "CIDR address".
   538  	Type string
   539  
   540  	// Text is the malformed text string.
   541  	Text string
   542  }
   543  
   544  func (e *ParseError) Error() string { return "invalid " + e.Type + ": " + e.Text }
   545  
   546  func (e *ParseError) Timeout() bool   { return false }
   547  func (e *ParseError) Temporary() bool { return false }
   548  
   549  type AddrError struct {
   550  	Err  string
   551  	Addr string
   552  }
   553  
   554  func (e *AddrError) Error() string {
   555  	if e == nil {
   556  		return "<nil>"
   557  	}
   558  	s := e.Err
   559  	if e.Addr != "" {
   560  		s = "address " + e.Addr + ": " + s
   561  	}
   562  	return s
   563  }
   564  
   565  func (e *AddrError) Timeout() bool   { return false }
   566  func (e *AddrError) Temporary() bool { return false }
   567  
   568  type UnknownNetworkError string
   569  
   570  func (e UnknownNetworkError) Error() string   { return "unknown network " + string(e) }
   571  func (e UnknownNetworkError) Timeout() bool   { return false }
   572  func (e UnknownNetworkError) Temporary() bool { return false }
   573  
   574  type InvalidAddrError string
   575  
   576  func (e InvalidAddrError) Error() string   { return string(e) }
   577  func (e InvalidAddrError) Timeout() bool   { return false }
   578  func (e InvalidAddrError) Temporary() bool { return false }
   579  
   580  // errTimeout exists to return the historical "i/o timeout" string
   581  // for context.DeadlineExceeded. See mapErr.
   582  // It is also used when Dialer.Deadline is exceeded.
   583  //
   584  // TODO(iant): We could consider changing this to os.ErrDeadlineExceeded
   585  // in the future, but note that that would conflict with the TODO
   586  // at mapErr that suggests changing it to context.DeadlineExceeded.
   587  var errTimeout error = &timeoutError{}
   588  
   589  type timeoutError struct{}
   590  
   591  func (e *timeoutError) Error() string   { return "i/o timeout" }
   592  func (e *timeoutError) Timeout() bool   { return true }
   593  func (e *timeoutError) Temporary() bool { return true }
   594  
   595  // DNSConfigError represents an error reading the machine's DNS configuration.
   596  // (No longer used; kept for compatibility.)
   597  type DNSConfigError struct {
   598  	Err error
   599  }
   600  
   601  func (e *DNSConfigError) Unwrap() error   { return e.Err }
   602  func (e *DNSConfigError) Error() string   { return "error reading DNS config: " + e.Err.Error() }
   603  func (e *DNSConfigError) Timeout() bool   { return false }
   604  func (e *DNSConfigError) Temporary() bool { return false }
   605  
   606  // Various errors contained in DNSError.
   607  var (
   608  	errNoSuchHost = errors.New("no such host")
   609  )
   610  
   611  // DNSError represents a DNS lookup error.
   612  type DNSError struct {
   613  	Err         string // description of the error
   614  	Name        string // name looked for
   615  	Server      string // server used
   616  	IsTimeout   bool   // if true, timed out; not all timeouts set this
   617  	IsTemporary bool   // if true, error is temporary; not all errors set this
   618  	IsNotFound  bool   // if true, host could not be found
   619  }
   620  
   621  func (e *DNSError) Error() string {
   622  	if e == nil {
   623  		return "<nil>"
   624  	}
   625  	s := "lookup " + e.Name
   626  	if e.Server != "" {
   627  		s += " on " + e.Server
   628  	}
   629  	s += ": " + e.Err
   630  	return s
   631  }
   632  
   633  // Timeout reports whether the DNS lookup is known to have timed out.
   634  // This is not always known; a DNS lookup may fail due to a timeout
   635  // and return a DNSError for which Timeout returns false.
   636  func (e *DNSError) Timeout() bool { return e.IsTimeout }
   637  
   638  // Temporary reports whether the DNS error is known to be temporary.
   639  // This is not always known; a DNS lookup may fail due to a temporary
   640  // error and return a DNSError for which Temporary returns false.
   641  func (e *DNSError) Temporary() bool { return e.IsTimeout || e.IsTemporary }
   642  
   643  // errClosed exists just so that the docs for ErrClosed don't mention
   644  // the internal package poll.
   645  var errClosed = poll.ErrNetClosing
   646  
   647  // ErrClosed is the error returned by an I/O call on a network
   648  // connection that has already been closed, or that is closed by
   649  // another goroutine before the I/O is completed. This may be wrapped
   650  // in another error, and should normally be tested using
   651  // errors.Is(err, net.ErrClosed).
   652  var ErrClosed error = errClosed
   653  
   654  type writerOnly struct {
   655  	io.Writer
   656  }
   657  
   658  // Fallback implementation of io.ReaderFrom's ReadFrom, when sendfile isn't
   659  // applicable.
   660  func genericReadFrom(w io.Writer, r io.Reader) (n int64, err error) {
   661  	// Use wrapper to hide existing r.ReadFrom from io.Copy.
   662  	return io.Copy(writerOnly{w}, r)
   663  }
   664  
   665  // Limit the number of concurrent cgo-using goroutines, because
   666  // each will block an entire operating system thread. The usual culprit
   667  // is resolving many DNS names in separate goroutines but the DNS
   668  // server is not responding. Then the many lookups each use a different
   669  // thread, and the system or the program runs out of threads.
   670  
   671  var threadLimit chan struct{}
   672  
   673  var threadOnce sync.Once
   674  
   675  func acquireThread() {
   676  	threadOnce.Do(func() {
   677  		threadLimit = make(chan struct{}, concurrentThreadsLimit())
   678  	})
   679  	threadLimit <- struct{}{}
   680  }
   681  
   682  func releaseThread() {
   683  	<-threadLimit
   684  }
   685  
   686  // buffersWriter is the interface implemented by Conns that support a
   687  // "writev"-like batch write optimization.
   688  // writeBuffers should fully consume and write all chunks from the
   689  // provided Buffers, else it should report a non-nil error.
   690  type buffersWriter interface {
   691  	writeBuffers(*Buffers) (int64, error)
   692  }
   693  
   694  // Buffers contains zero or more runs of bytes to write.
   695  //
   696  // On certain machines, for certain types of connections, this is
   697  // optimized into an OS-specific batch write operation (such as
   698  // "writev").
   699  type Buffers [][]byte
   700  
   701  var (
   702  	_ io.WriterTo = (*Buffers)(nil)
   703  	_ io.Reader   = (*Buffers)(nil)
   704  )
   705  
   706  // WriteTo writes contents of the buffers to w.
   707  //
   708  // WriteTo implements io.WriterTo for Buffers.
   709  //
   710  // WriteTo modifies the slice v as well as v[i] for 0 <= i < len(v),
   711  // but does not modify v[i][j] for any i, j.
   712  func (v *Buffers) WriteTo(w io.Writer) (n int64, err error) {
   713  	if wv, ok := w.(buffersWriter); ok {
   714  		return wv.writeBuffers(v)
   715  	}
   716  	for _, b := range *v {
   717  		nb, err := w.Write(b)
   718  		n += int64(nb)
   719  		if err != nil {
   720  			v.consume(n)
   721  			return n, err
   722  		}
   723  	}
   724  	v.consume(n)
   725  	return n, nil
   726  }
   727  
   728  // Read from the buffers.
   729  //
   730  // Read implements io.Reader for Buffers.
   731  //
   732  // Read modifies the slice v as well as v[i] for 0 <= i < len(v),
   733  // but does not modify v[i][j] for any i, j.
   734  func (v *Buffers) Read(p []byte) (n int, err error) {
   735  	for len(p) > 0 && len(*v) > 0 {
   736  		n0 := copy(p, (*v)[0])
   737  		v.consume(int64(n0))
   738  		p = p[n0:]
   739  		n += n0
   740  	}
   741  	if len(*v) == 0 {
   742  		err = io.EOF
   743  	}
   744  	return
   745  }
   746  
   747  func (v *Buffers) consume(n int64) {
   748  	for len(*v) > 0 {
   749  		ln0 := int64(len((*v)[0]))
   750  		if ln0 > n {
   751  			(*v)[0] = (*v)[0][n:]
   752  			return
   753  		}
   754  		n -= ln0
   755  		(*v)[0] = nil
   756  		*v = (*v)[1:]
   757  	}
   758  }
   759  

View as plain text