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

View as plain text