...

Source file src/net/net.go

Documentation: net

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

View as plain text