net.mx raw

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