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  On Unix the pure Go resolver is preferred over the cgo resolver, because a blocked DNS
    50  request consumes 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.
    58  
    59  On all systems (except Plan 9), when the cgo resolver is being used
    60  this package applies a concurrent cgo lookup limit to prevent the system
    61  from running out of system threads. Currently, it is limited to 500 concurrent lookups.
    62  
    63  The resolver decision can be overridden by setting the netdns value of the
    64  GODEBUG environment variable (see package runtime) to go or cgo, as in:
    65  
    66  	export GODEBUG=netdns=go    # force pure Go resolver
    67  	export GODEBUG=netdns=cgo   # force native resolver (cgo, win32)
    68  
    69  The decision can also be forced while building the Go source tree
    70  by setting the netgo or netcgo build tag.
    71  The netgo build tag disables entirely the use of the native (CGO) resolver,
    72  meaning the Go resolver is the only one that can be used.
    73  With the netcgo build tag the native and the pure Go resolver are compiled into the binary,
    74  but the native (CGO) resolver is preferred over the Go resolver.
    75  With netcgo, the Go resolver can still be forced at runtime with GODEBUG=netdns=go.
    76  
    77  A numeric netdns setting, as in GODEBUG=netdns=1, causes the resolver
    78  to print debugging information about its decisions.
    79  To force a particular resolver while also printing debugging information,
    80  join the two settings by a plus sign, as in GODEBUG=netdns=go+1.
    81  
    82  The Go resolver will send an EDNS0 additional header with a DNS request,
    83  to signal a willingness to accept a larger DNS packet size.
    84  This can reportedly cause sporadic failures with the DNS server run
    85  by some modems and routers. Setting GODEBUG=netedns0=0 will disable
    86  sending the additional header.
    87  
    88  On macOS, if Go code that uses the net package is built with
    89  -buildmode=c-archive, linking the resulting archive into a C program
    90  requires passing -lresolv when linking the C code.
    91  
    92  On Plan 9, the resolver always accesses /net/cs and /net/dns.
    93  
    94  On Windows, in Go 1.18.x and earlier, the resolver always used C
    95  library functions, such as GetAddrInfo and DnsQuery.
    96  */
    97  package net
    98  
    99  import (
   100  	"context"
   101  	"errors"
   102  	"internal/poll"
   103  	"io"
   104  	"os"
   105  	"sync"
   106  	"syscall"
   107  	"time"
   108  	_ "unsafe" // for linkname
   109  )
   110  
   111  // Addr represents a network end point address.
   112  //
   113  // The two methods [Addr.Network] and [Addr.String] conventionally return strings
   114  // that can be passed as the arguments to [Dial], but the exact form
   115  // and meaning of the strings is up to the implementation.
   116  type Addr interface {
   117  	Network() string // name of the network (for example, "tcp", "udp")
   118  	String() string  // string form of address (for example, "192.0.2.1:25", "[2001:db8::1]:80")
   119  }
   120  
   121  // Conn is a generic stream-oriented network connection.
   122  //
   123  // Multiple goroutines may invoke methods on a Conn simultaneously.
   124  type Conn interface {
   125  	// Read reads data from the connection.
   126  	// Read can be made to time out and return an error after a fixed
   127  	// time limit; see SetDeadline and SetReadDeadline.
   128  	Read(b []byte) (n int, err error)
   129  
   130  	// Write writes data to the connection.
   131  	// Write can be made to time out and return an error after a fixed
   132  	// time limit; see SetDeadline and SetWriteDeadline.
   133  	Write(b []byte) (n int, err error)
   134  
   135  	// Close closes the connection.
   136  	// Any blocked Read or Write operations will be unblocked and return errors.
   137  	// Close may or may not block until any buffered data is sent;
   138  	// for TCP connections see [*TCPConn.SetLinger].
   139  	Close() error
   140  
   141  	// LocalAddr returns the local network address, if known.
   142  	LocalAddr() Addr
   143  
   144  	// RemoteAddr returns the remote network address, if known.
   145  	RemoteAddr() Addr
   146  
   147  	// SetDeadline sets the read and write deadlines associated
   148  	// with the connection. It is equivalent to calling both
   149  	// SetReadDeadline and SetWriteDeadline.
   150  	//
   151  	// A deadline is an absolute time after which I/O operations
   152  	// fail instead of blocking. The deadline applies to all future
   153  	// and pending I/O, not just the immediately following call to
   154  	// Read or Write. After a deadline has been exceeded, the
   155  	// connection can be refreshed by setting a deadline in the future.
   156  	//
   157  	// If the deadline is exceeded a call to Read or Write or to other
   158  	// I/O methods will return an error that wraps os.ErrDeadlineExceeded.
   159  	// This can be tested using errors.Is(err, os.ErrDeadlineExceeded).
   160  	// The error's Timeout method will return true, but note that there
   161  	// are other possible errors for which the Timeout method will
   162  	// return true even if the deadline has not been exceeded.
   163  	//
   164  	// An idle timeout can be implemented by repeatedly extending
   165  	// the deadline after successful Read or Write calls.
   166  	//
   167  	// A zero value for t means I/O operations will not time out.
   168  	SetDeadline(t time.Time) error
   169  
   170  	// SetReadDeadline sets the deadline for future Read calls
   171  	// and any currently-blocked Read call.
   172  	// A zero value for t means Read will not time out.
   173  	SetReadDeadline(t time.Time) error
   174  
   175  	// SetWriteDeadline sets the deadline for future Write calls
   176  	// and any currently-blocked Write call.
   177  	// Even if write times out, it may return n > 0, indicating that
   178  	// some of the data was successfully written.
   179  	// A zero value for t means Write will not time out.
   180  	SetWriteDeadline(t time.Time) error
   181  }
   182  
   183  type conn struct {
   184  	fd *netFD
   185  }
   186  
   187  func (c *conn) ok() bool { return c != nil && c.fd != nil }
   188  
   189  // Implementation of the Conn interface.
   190  
   191  // Read implements the Conn Read method.
   192  func (c *conn) Read(b []byte) (int, error) {
   193  	if !c.ok() {
   194  		return 0, syscall.EINVAL
   195  	}
   196  	n, err := c.fd.Read(b)
   197  	if err != nil && err != io.EOF {
   198  		err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
   199  	}
   200  	return n, err
   201  }
   202  
   203  // Write implements the Conn Write method.
   204  func (c *conn) Write(b []byte) (int, error) {
   205  	if !c.ok() {
   206  		return 0, syscall.EINVAL
   207  	}
   208  	n, err := c.fd.Write(b)
   209  	if err != nil {
   210  		err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
   211  	}
   212  	return n, err
   213  }
   214  
   215  // Close closes the connection.
   216  func (c *conn) Close() error {
   217  	if !c.ok() {
   218  		return syscall.EINVAL
   219  	}
   220  	err := c.fd.Close()
   221  	if err != nil {
   222  		err = &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
   223  	}
   224  	return err
   225  }
   226  
   227  // LocalAddr returns the local network address.
   228  // The Addr returned is shared by all invocations of LocalAddr, so
   229  // do not modify it.
   230  func (c *conn) LocalAddr() Addr {
   231  	if !c.ok() {
   232  		return nil
   233  	}
   234  	return c.fd.laddr
   235  }
   236  
   237  // RemoteAddr returns the remote network address.
   238  // The Addr returned is shared by all invocations of RemoteAddr, so
   239  // do not modify it.
   240  func (c *conn) RemoteAddr() Addr {
   241  	if !c.ok() {
   242  		return nil
   243  	}
   244  	return c.fd.raddr
   245  }
   246  
   247  // SetDeadline implements the Conn SetDeadline method.
   248  func (c *conn) SetDeadline(t time.Time) error {
   249  	if !c.ok() {
   250  		return syscall.EINVAL
   251  	}
   252  	if err := c.fd.SetDeadline(t); err != nil {
   253  		return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
   254  	}
   255  	return nil
   256  }
   257  
   258  // SetReadDeadline implements the Conn SetReadDeadline method.
   259  func (c *conn) SetReadDeadline(t time.Time) error {
   260  	if !c.ok() {
   261  		return syscall.EINVAL
   262  	}
   263  	if err := c.fd.SetReadDeadline(t); err != nil {
   264  		return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
   265  	}
   266  	return nil
   267  }
   268  
   269  // SetWriteDeadline implements the Conn SetWriteDeadline method.
   270  func (c *conn) SetWriteDeadline(t time.Time) error {
   271  	if !c.ok() {
   272  		return syscall.EINVAL
   273  	}
   274  	if err := c.fd.SetWriteDeadline(t); err != nil {
   275  		return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
   276  	}
   277  	return nil
   278  }
   279  
   280  // SetReadBuffer sets the size of the operating system's
   281  // receive buffer associated with the connection.
   282  func (c *conn) SetReadBuffer(bytes int) error {
   283  	if !c.ok() {
   284  		return syscall.EINVAL
   285  	}
   286  	if err := setReadBuffer(c.fd, bytes); err != nil {
   287  		return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
   288  	}
   289  	return nil
   290  }
   291  
   292  // SetWriteBuffer sets the size of the operating system's
   293  // transmit buffer associated with the connection.
   294  func (c *conn) SetWriteBuffer(bytes int) error {
   295  	if !c.ok() {
   296  		return syscall.EINVAL
   297  	}
   298  	if err := setWriteBuffer(c.fd, bytes); err != nil {
   299  		return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
   300  	}
   301  	return nil
   302  }
   303  
   304  // File returns a copy of the underlying [os.File].
   305  // It is the caller's responsibility to close f when finished.
   306  // Closing c does not affect f, and closing f does not affect c.
   307  //
   308  // The returned os.File's file descriptor is different from the connection's.
   309  // Attempting to change properties of the original using this duplicate
   310  // may or may not have the desired effect.
   311  //
   312  // On Windows, the returned os.File's file descriptor is not usable
   313  // on other processes.
   314  func (c *conn) File() (f *os.File, err error) {
   315  	f, err = c.fd.dup()
   316  	if err != nil {
   317  		err = &OpError{Op: "file", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
   318  	}
   319  	return
   320  }
   321  
   322  // PacketConn is a generic packet-oriented network connection.
   323  //
   324  // Multiple goroutines may invoke methods on a PacketConn simultaneously.
   325  type PacketConn interface {
   326  	// ReadFrom reads a packet from the connection,
   327  	// copying the payload into p. It returns the number of
   328  	// bytes copied into p and the return address that
   329  	// was on the packet.
   330  	// It returns the number of bytes read (0 <= n <= len(p))
   331  	// and any error encountered. Callers should always process
   332  	// the n > 0 bytes returned before considering the error err.
   333  	// ReadFrom can be made to time out and return an error after a
   334  	// fixed time limit; see SetDeadline and SetReadDeadline.
   335  	ReadFrom(p []byte) (n int, addr Addr, err error)
   336  
   337  	// WriteTo writes a packet with payload p to addr.
   338  	// WriteTo can be made to time out and return an Error after a
   339  	// fixed time limit; see SetDeadline and SetWriteDeadline.
   340  	// On packet-oriented connections, write timeouts are rare.
   341  	WriteTo(p []byte, addr Addr) (n int, err error)
   342  
   343  	// Close closes the connection.
   344  	// Any blocked ReadFrom or WriteTo operations will be unblocked and return errors.
   345  	Close() error
   346  
   347  	// LocalAddr returns the local network address, if known.
   348  	LocalAddr() Addr
   349  
   350  	// SetDeadline sets the read and write deadlines associated
   351  	// with the connection. It is equivalent to calling both
   352  	// SetReadDeadline and SetWriteDeadline.
   353  	//
   354  	// A deadline is an absolute time after which I/O operations
   355  	// fail instead of blocking. The deadline applies to all future
   356  	// and pending I/O, not just the immediately following call to
   357  	// Read or Write. After a deadline has been exceeded, the
   358  	// connection can be refreshed by setting a deadline in the future.
   359  	//
   360  	// If the deadline is exceeded a call to Read or Write or to other
   361  	// I/O methods will return an error that wraps os.ErrDeadlineExceeded.
   362  	// This can be tested using errors.Is(err, os.ErrDeadlineExceeded).
   363  	// The error's Timeout method will return true, but note that there
   364  	// are other possible errors for which the Timeout method will
   365  	// return true even if the deadline has not been exceeded.
   366  	//
   367  	// An idle timeout can be implemented by repeatedly extending
   368  	// the deadline after successful ReadFrom or WriteTo calls.
   369  	//
   370  	// A zero value for t means I/O operations will not time out.
   371  	SetDeadline(t time.Time) error
   372  
   373  	// SetReadDeadline sets the deadline for future ReadFrom calls
   374  	// and any currently-blocked ReadFrom call.
   375  	// A zero value for t means ReadFrom will not time out.
   376  	SetReadDeadline(t time.Time) error
   377  
   378  	// SetWriteDeadline sets the deadline for future WriteTo calls
   379  	// and any currently-blocked WriteTo call.
   380  	// Even if write times out, it may return n > 0, indicating that
   381  	// some of the data was successfully written.
   382  	// A zero value for t means WriteTo will not time out.
   383  	SetWriteDeadline(t time.Time) error
   384  }
   385  
   386  var listenerBacklogCache struct {
   387  	sync.Once
   388  	val int
   389  }
   390  
   391  // listenerBacklog is a caching wrapper around maxListenerBacklog.
   392  //
   393  // listenerBacklog should be an internal detail,
   394  // but widely used packages access it using linkname.
   395  // Notable members of the hall of shame include:
   396  //   - github.com/database64128/tfo-go/v2
   397  //   - github.com/metacubex/tfo-go
   398  //   - github.com/sagernet/tfo-go
   399  //
   400  // Do not remove or change the type signature.
   401  // See go.dev/issue/67401.
   402  //
   403  //go:linkname listenerBacklog
   404  func listenerBacklog() int {
   405  	listenerBacklogCache.Do(func() { listenerBacklogCache.val = maxListenerBacklog() })
   406  	return listenerBacklogCache.val
   407  }
   408  
   409  // A Listener is a generic network listener for stream-oriented protocols.
   410  //
   411  // Multiple goroutines may invoke methods on a Listener simultaneously.
   412  type Listener interface {
   413  	// Accept waits for and returns the next connection to the listener.
   414  	Accept() (Conn, error)
   415  
   416  	// Close closes the listener.
   417  	// Any blocked Accept operations will be unblocked and return errors.
   418  	Close() error
   419  
   420  	// Addr returns the listener's network address.
   421  	Addr() Addr
   422  }
   423  
   424  // An Error represents a network error.
   425  type Error interface {
   426  	error
   427  	Timeout() bool // Is the error a timeout?
   428  
   429  	// Deprecated: Temporary errors are not well-defined.
   430  	// Most "temporary" errors are timeouts, and the few exceptions are surprising.
   431  	// Do not use this method.
   432  	Temporary() bool
   433  }
   434  
   435  // Various errors contained in OpError.
   436  var (
   437  	// For connection setup operations.
   438  	errNoSuitableAddress = errors.New("no suitable address found")
   439  
   440  	// For connection setup and write operations.
   441  	errMissingAddress = errors.New("missing address")
   442  
   443  	// For both read and write operations.
   444  	errCanceled         = canceledError{}
   445  	ErrWriteToConnected = errors.New("use of WriteTo with pre-connected connection")
   446  )
   447  
   448  // canceledError lets us return the same error string we have always
   449  // returned, while still being Is context.Canceled.
   450  type canceledError struct{}
   451  
   452  func (canceledError) Error() string { return "operation was canceled" }
   453  
   454  func (canceledError) Is(err error) bool { return err == context.Canceled }
   455  
   456  // mapErr maps from the context errors to the historical internal net
   457  // error values.
   458  func mapErr(err error) error {
   459  	switch err {
   460  	case context.Canceled:
   461  		return errCanceled
   462  	case context.DeadlineExceeded:
   463  		return errTimeout
   464  	default:
   465  		return err
   466  	}
   467  }
   468  
   469  // OpError is the error type usually returned by functions in the net
   470  // package. It describes the operation, network type, and address of
   471  // an error.
   472  type OpError struct {
   473  	// Op is the operation which caused the error, such as
   474  	// "read" or "write".
   475  	Op string
   476  
   477  	// Net is the network type on which this error occurred,
   478  	// such as "tcp" or "udp6".
   479  	Net string
   480  
   481  	// For operations involving a remote network connection, like
   482  	// Dial, Read, or Write, Source is the corresponding local
   483  	// network address.
   484  	Source Addr
   485  
   486  	// Addr is the network address for which this error occurred.
   487  	// For local operations, like Listen or SetDeadline, Addr is
   488  	// the address of the local endpoint being manipulated.
   489  	// For operations involving a remote network connection, like
   490  	// Dial, Read, or Write, Addr is the remote address of that
   491  	// connection.
   492  	Addr Addr
   493  
   494  	// Err is the error that occurred during the operation.
   495  	// The Error method panics if the error is nil.
   496  	Err error
   497  }
   498  
   499  func (e *OpError) Unwrap() error { return e.Err }
   500  
   501  func (e *OpError) Error() string {
   502  	if e == nil {
   503  		return "<nil>"
   504  	}
   505  	s := e.Op
   506  	if e.Net != "" {
   507  		s += " " + e.Net
   508  	}
   509  	if e.Source != nil {
   510  		s += " " + e.Source.String()
   511  	}
   512  	if e.Addr != nil {
   513  		if e.Source != nil {
   514  			s += "->"
   515  		} else {
   516  			s += " "
   517  		}
   518  		s += e.Addr.String()
   519  	}
   520  	s += ": " + e.Err.Error()
   521  	return s
   522  }
   523  
   524  var (
   525  	// aLongTimeAgo is a non-zero time, far in the past, used for
   526  	// immediate cancellation of dials.
   527  	aLongTimeAgo = time.Unix(1, 0)
   528  
   529  	// noDeadline and noCancel are just zero values for
   530  	// readability with functions taking too many parameters.
   531  	noDeadline = time.Time{}
   532  	noCancel   = (chan struct{})(nil)
   533  )
   534  
   535  type timeout interface {
   536  	Timeout() bool
   537  }
   538  
   539  func (e *OpError) Timeout() bool {
   540  	if ne, ok := e.Err.(*os.SyscallError); ok {
   541  		t, ok := ne.Err.(timeout)
   542  		return ok && t.Timeout()
   543  	}
   544  	t, ok := e.Err.(timeout)
   545  	return ok && t.Timeout()
   546  }
   547  
   548  type temporary interface {
   549  	Temporary() bool
   550  }
   551  
   552  func (e *OpError) Temporary() bool {
   553  	// Treat ECONNRESET and ECONNABORTED as temporary errors when
   554  	// they come from calling accept. See issue 6163.
   555  	if e.Op == "accept" && isConnError(e.Err) {
   556  		return true
   557  	}
   558  
   559  	if ne, ok := e.Err.(*os.SyscallError); ok {
   560  		t, ok := ne.Err.(temporary)
   561  		return ok && t.Temporary()
   562  	}
   563  	t, ok := e.Err.(temporary)
   564  	return ok && t.Temporary()
   565  }
   566  
   567  // A ParseError is the error type of literal network address parsers.
   568  type ParseError struct {
   569  	// Type is the type of string that was expected, such as
   570  	// "IP address", "CIDR address".
   571  	Type string
   572  
   573  	// Text is the malformed text string.
   574  	Text string
   575  }
   576  
   577  func (e *ParseError) Error() string { return "invalid " + e.Type + ": " + e.Text }
   578  
   579  func (e *ParseError) Timeout() bool   { return false }
   580  func (e *ParseError) Temporary() bool { return false }
   581  
   582  type AddrError struct {
   583  	Err  string
   584  	Addr string
   585  }
   586  
   587  func (e *AddrError) Error() string {
   588  	if e == nil {
   589  		return "<nil>"
   590  	}
   591  	s := e.Err
   592  	if e.Addr != "" {
   593  		s = "address " + e.Addr + ": " + s
   594  	}
   595  	return s
   596  }
   597  
   598  func (e *AddrError) Timeout() bool   { return false }
   599  func (e *AddrError) Temporary() bool { return false }
   600  
   601  type UnknownNetworkError string
   602  
   603  func (e UnknownNetworkError) Error() string   { return "unknown network " + string(e) }
   604  func (e UnknownNetworkError) Timeout() bool   { return false }
   605  func (e UnknownNetworkError) Temporary() bool { return false }
   606  
   607  type InvalidAddrError string
   608  
   609  var _ error = InvalidAddrError("")
   610  
   611  func (e InvalidAddrError) Error() string   { return string(e) }
   612  func (e InvalidAddrError) Timeout() bool   { return false }
   613  func (e InvalidAddrError) Temporary() bool { return false }
   614  
   615  // errTimeout exists to return the historical "i/o timeout" string
   616  // for context.DeadlineExceeded. See mapErr.
   617  // It is also used when Dialer.Deadline is exceeded.
   618  // error.Is(errTimeout, context.DeadlineExceeded) returns true.
   619  //
   620  // TODO(iant): We could consider changing this to os.ErrDeadlineExceeded
   621  // in the future, if we make
   622  //
   623  //	errors.Is(os.ErrDeadlineExceeded, context.DeadlineExceeded)
   624  //
   625  // return true.
   626  var errTimeout error = &timeoutError{}
   627  
   628  type timeoutError struct{}
   629  
   630  func (e *timeoutError) Error() string   { return "i/o timeout" }
   631  func (e *timeoutError) Timeout() bool   { return true }
   632  func (e *timeoutError) Temporary() bool { return true }
   633  
   634  func (e *timeoutError) Is(err error) bool {
   635  	return err == context.DeadlineExceeded
   636  }
   637  
   638  // DNSConfigError represents an error reading the machine's DNS configuration.
   639  // (No longer used; kept for compatibility.)
   640  type DNSConfigError struct {
   641  	Err error
   642  }
   643  
   644  func (e *DNSConfigError) Unwrap() error   { return e.Err }
   645  func (e *DNSConfigError) Error() string   { return "error reading DNS config: " + e.Err.Error() }
   646  func (e *DNSConfigError) Timeout() bool   { return false }
   647  func (e *DNSConfigError) Temporary() bool { return false }
   648  
   649  // Various errors contained in DNSError.
   650  var (
   651  	errNoSuchHost  = &notFoundError{"no such host"}
   652  	errUnknownPort = &notFoundError{"unknown port"}
   653  )
   654  
   655  // notFoundError is a special error understood by the newDNSError function,
   656  // which causes a creation of a DNSError with IsNotFound field set to true.
   657  type notFoundError struct{ s string }
   658  
   659  func (e *notFoundError) Error() string { return e.s }
   660  
   661  // temporaryError is an error type that implements the [Error] interface.
   662  // It returns true from the Temporary method.
   663  type temporaryError struct{ s string }
   664  
   665  func (e *temporaryError) Error() string   { return e.s }
   666  func (e *temporaryError) Temporary() bool { return true }
   667  func (e *temporaryError) Timeout() bool   { return false }
   668  
   669  // DNSError represents a DNS lookup error.
   670  type DNSError struct {
   671  	UnwrapErr   error  // error returned by the [DNSError.Unwrap] method, might be nil
   672  	Err         string // description of the error
   673  	Name        string // name looked for
   674  	Server      string // server used
   675  	IsTimeout   bool   // if true, timed out; not all timeouts set this
   676  	IsTemporary bool   // if true, error is temporary; not all errors set this
   677  
   678  	// IsNotFound is set to true when the requested name does not
   679  	// contain any records of the requested type (data not found),
   680  	// or the name itself was not found (NXDOMAIN).
   681  	IsNotFound bool
   682  }
   683  
   684  // newDNSError creates a new *DNSError.
   685  // Based on the err, it sets the UnwrapErr, IsTimeout, IsTemporary, IsNotFound fields.
   686  func newDNSError(err error, name, server string) *DNSError {
   687  	var (
   688  		isTimeout   bool
   689  		isTemporary bool
   690  		unwrapErr   error
   691  	)
   692  
   693  	if err, ok := err.(Error); ok {
   694  		isTimeout = err.Timeout()
   695  		isTemporary = err.Temporary()
   696  	}
   697  
   698  	// At this time, the only errors we wrap are context errors, to allow
   699  	// users to check for canceled/timed out requests.
   700  	if errors.Is(err, context.DeadlineExceeded) || errors.Is(err, context.Canceled) {
   701  		unwrapErr = err
   702  	}
   703  
   704  	_, isNotFound := err.(*notFoundError)
   705  	return &DNSError{
   706  		UnwrapErr:   unwrapErr,
   707  		Err:         err.Error(),
   708  		Name:        name,
   709  		Server:      server,
   710  		IsTimeout:   isTimeout,
   711  		IsTemporary: isTemporary,
   712  		IsNotFound:  isNotFound,
   713  	}
   714  }
   715  
   716  // Unwrap returns e.UnwrapErr.
   717  func (e *DNSError) Unwrap() error { return e.UnwrapErr }
   718  
   719  func (e *DNSError) Error() string {
   720  	if e == nil {
   721  		return "<nil>"
   722  	}
   723  	s := "lookup " + e.Name
   724  	if e.Server != "" {
   725  		s += " on " + e.Server
   726  	}
   727  	s += ": " + e.Err
   728  	return s
   729  }
   730  
   731  // Timeout reports whether the DNS lookup is known to have timed out.
   732  // This is not always known; a DNS lookup may fail due to a timeout
   733  // and return a [DNSError] for which Timeout returns false.
   734  func (e *DNSError) Timeout() bool { return e.IsTimeout }
   735  
   736  // Temporary reports whether the DNS error is known to be temporary.
   737  // This is not always known; a DNS lookup may fail due to a temporary
   738  // error and return a [DNSError] for which Temporary returns false.
   739  func (e *DNSError) Temporary() bool { return e.IsTimeout || e.IsTemporary }
   740  
   741  // errClosed exists just so that the docs for ErrClosed don't mention
   742  // the internal package poll.
   743  var errClosed = poll.ErrNetClosing
   744  
   745  // ErrClosed is the error returned by an I/O call on a network
   746  // connection that has already been closed, or that is closed by
   747  // another goroutine before the I/O is completed. This may be wrapped
   748  // in another error, and should normally be tested using
   749  // errors.Is(err, net.ErrClosed).
   750  var ErrClosed error = errClosed
   751  
   752  // noReadFrom can be embedded alongside another type to
   753  // hide the ReadFrom method of that other type.
   754  type noReadFrom struct{}
   755  
   756  // ReadFrom hides another ReadFrom method.
   757  // It should never be called.
   758  func (noReadFrom) ReadFrom(io.Reader) (int64, error) {
   759  	panic("can't happen")
   760  }
   761  
   762  // tcpConnWithoutReadFrom implements all the methods of *TCPConn other
   763  // than ReadFrom. This is used to permit ReadFrom to call io.Copy
   764  // without leading to a recursive call to ReadFrom.
   765  type tcpConnWithoutReadFrom struct {
   766  	noReadFrom
   767  	*TCPConn
   768  }
   769  
   770  // Fallback implementation of io.ReaderFrom's ReadFrom, when sendfile isn't
   771  // applicable.
   772  func genericReadFrom(c *TCPConn, r io.Reader) (n int64, err error) {
   773  	// Use wrapper to hide existing r.ReadFrom from io.Copy.
   774  	return io.Copy(tcpConnWithoutReadFrom{TCPConn: c}, r)
   775  }
   776  
   777  // noWriteTo can be embedded alongside another type to
   778  // hide the WriteTo method of that other type.
   779  type noWriteTo struct{}
   780  
   781  // WriteTo hides another WriteTo method.
   782  // It should never be called.
   783  func (noWriteTo) WriteTo(io.Writer) (int64, error) {
   784  	panic("can't happen")
   785  }
   786  
   787  // tcpConnWithoutWriteTo implements all the methods of *TCPConn other
   788  // than WriteTo. This is used to permit WriteTo to call io.Copy
   789  // without leading to a recursive call to WriteTo.
   790  type tcpConnWithoutWriteTo struct {
   791  	noWriteTo
   792  	*TCPConn
   793  }
   794  
   795  // Fallback implementation of io.WriterTo's WriteTo, when zero-copy isn't applicable.
   796  func genericWriteTo(c *TCPConn, w io.Writer) (n int64, err error) {
   797  	// Use wrapper to hide existing w.WriteTo from io.Copy.
   798  	return io.Copy(w, tcpConnWithoutWriteTo{TCPConn: c})
   799  }
   800  
   801  // Limit the number of concurrent cgo-using goroutines, because
   802  // each will block an entire operating system thread. The usual culprit
   803  // is resolving many DNS names in separate goroutines but the DNS
   804  // server is not responding. Then the many lookups each use a different
   805  // thread, and the system or the program runs out of threads.
   806  
   807  var threadLimit chan struct{}
   808  
   809  var threadOnce sync.Once
   810  
   811  func acquireThread(ctx context.Context) error {
   812  	threadOnce.Do(func() {
   813  		threadLimit = make(chan struct{}, concurrentThreadsLimit())
   814  	})
   815  	select {
   816  	case threadLimit <- struct{}{}:
   817  		return nil
   818  	case <-ctx.Done():
   819  		return ctx.Err()
   820  	}
   821  }
   822  
   823  func releaseThread() {
   824  	<-threadLimit
   825  }
   826  
   827  // buffersWriter is the interface implemented by Conns that support a
   828  // "writev"-like batch write optimization.
   829  // writeBuffers should fully consume and write all chunks from the
   830  // provided Buffers, else it should report a non-nil error.
   831  type buffersWriter interface {
   832  	writeBuffers(*Buffers) (int64, error)
   833  }
   834  
   835  // Buffers contains zero or more runs of bytes to write.
   836  //
   837  // On certain machines, for certain types of connections, this is
   838  // optimized into an OS-specific batch write operation (such as
   839  // "writev").
   840  type Buffers [][]byte
   841  
   842  var (
   843  	_ io.WriterTo = (*Buffers)(nil)
   844  	_ io.Reader   = (*Buffers)(nil)
   845  )
   846  
   847  // WriteTo writes contents of the buffers to w.
   848  //
   849  // WriteTo implements [io.WriterTo] for [Buffers].
   850  //
   851  // WriteTo modifies the slice v as well as v[i] for 0 <= i < len(v),
   852  // but does not modify v[i][j] for any i, j.
   853  func (v *Buffers) WriteTo(w io.Writer) (n int64, err error) {
   854  	if wv, ok := w.(buffersWriter); ok {
   855  		return wv.writeBuffers(v)
   856  	}
   857  	for _, b := range *v {
   858  		nb, err := w.Write(b)
   859  		n += int64(nb)
   860  		if err != nil {
   861  			v.consume(n)
   862  			return n, err
   863  		}
   864  	}
   865  	v.consume(n)
   866  	return n, nil
   867  }
   868  
   869  // Read from the buffers.
   870  //
   871  // Read implements [io.Reader] for [Buffers].
   872  //
   873  // Read modifies the slice v as well as v[i] for 0 <= i < len(v),
   874  // but does not modify v[i][j] for any i, j.
   875  func (v *Buffers) Read(p []byte) (n int, err error) {
   876  	for len(p) > 0 && len(*v) > 0 {
   877  		n0 := copy(p, (*v)[0])
   878  		v.consume(int64(n0))
   879  		p = p[n0:]
   880  		n += n0
   881  	}
   882  	if len(*v) == 0 {
   883  		err = io.EOF
   884  	}
   885  	return
   886  }
   887  
   888  func (v *Buffers) consume(n int64) {
   889  	for len(*v) > 0 {
   890  		ln0 := int64(len((*v)[0]))
   891  		if ln0 > n {
   892  			(*v)[0] = (*v)[0][n:]
   893  			return
   894  		}
   895  		n -= ln0
   896  		(*v)[0] = nil
   897  		*v = (*v)[1:]
   898  	}
   899  }
   900  

View as plain text