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

View as plain text