...

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 cgo resolver
		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, the resolver always uses C library functions, such as GetAddrInfo and DnsQuery.
		77  
		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.
	 129  	LocalAddr() Addr
	 130  
	 131  	// RemoteAddr returns the remote network address.
	 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.
	 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  	Temporary() bool // Is the error temporary?
	 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				 = errors.New("operation was canceled")
	 413  	ErrWriteToConnected = errors.New("use of WriteTo with pre-connected connection")
	 414  )
	 415  
	 416  // mapErr maps from the context errors to the historical internal net
	 417  // error values.
	 418  //
	 419  // TODO(bradfitz): get rid of this after adjusting tests and making
	 420  // context.DeadlineExceeded implement net.Error?
	 421  func mapErr(err error) error {
	 422  	switch err {
	 423  	case context.Canceled:
	 424  		return errCanceled
	 425  	case context.DeadlineExceeded:
	 426  		return errTimeout
	 427  	default:
	 428  		return err
	 429  	}
	 430  }
	 431  
	 432  // OpError is the error type usually returned by functions in the net
	 433  // package. It describes the operation, network type, and address of
	 434  // an error.
	 435  type OpError struct {
	 436  	// Op is the operation which caused the error, such as
	 437  	// "read" or "write".
	 438  	Op string
	 439  
	 440  	// Net is the network type on which this error occurred,
	 441  	// such as "tcp" or "udp6".
	 442  	Net string
	 443  
	 444  	// For operations involving a remote network connection, like
	 445  	// Dial, Read, or Write, Source is the corresponding local
	 446  	// network address.
	 447  	Source Addr
	 448  
	 449  	// Addr is the network address for which this error occurred.
	 450  	// For local operations, like Listen or SetDeadline, Addr is
	 451  	// the address of the local endpoint being manipulated.
	 452  	// For operations involving a remote network connection, like
	 453  	// Dial, Read, or Write, Addr is the remote address of that
	 454  	// connection.
	 455  	Addr Addr
	 456  
	 457  	// Err is the error that occurred during the operation.
	 458  	// The Error method panics if the error is nil.
	 459  	Err error
	 460  }
	 461  
	 462  func (e *OpError) Unwrap() error { return e.Err }
	 463  
	 464  func (e *OpError) Error() string {
	 465  	if e == nil {
	 466  		return "<nil>"
	 467  	}
	 468  	s := e.Op
	 469  	if e.Net != "" {
	 470  		s += " " + e.Net
	 471  	}
	 472  	if e.Source != nil {
	 473  		s += " " + e.Source.String()
	 474  	}
	 475  	if e.Addr != nil {
	 476  		if e.Source != nil {
	 477  			s += "->"
	 478  		} else {
	 479  			s += " "
	 480  		}
	 481  		s += e.Addr.String()
	 482  	}
	 483  	s += ": " + e.Err.Error()
	 484  	return s
	 485  }
	 486  
	 487  var (
	 488  	// aLongTimeAgo is a non-zero time, far in the past, used for
	 489  	// immediate cancellation of dials.
	 490  	aLongTimeAgo = time.Unix(1, 0)
	 491  
	 492  	// nonDeadline and noCancel are just zero values for
	 493  	// readability with functions taking too many parameters.
	 494  	noDeadline = time.Time{}
	 495  	noCancel	 = (chan struct{})(nil)
	 496  )
	 497  
	 498  type timeout interface {
	 499  	Timeout() bool
	 500  }
	 501  
	 502  func (e *OpError) Timeout() bool {
	 503  	if ne, ok := e.Err.(*os.SyscallError); ok {
	 504  		t, ok := ne.Err.(timeout)
	 505  		return ok && t.Timeout()
	 506  	}
	 507  	t, ok := e.Err.(timeout)
	 508  	return ok && t.Timeout()
	 509  }
	 510  
	 511  type temporary interface {
	 512  	Temporary() bool
	 513  }
	 514  
	 515  func (e *OpError) Temporary() bool {
	 516  	// Treat ECONNRESET and ECONNABORTED as temporary errors when
	 517  	// they come from calling accept. See issue 6163.
	 518  	if e.Op == "accept" && isConnError(e.Err) {
	 519  		return true
	 520  	}
	 521  
	 522  	if ne, ok := e.Err.(*os.SyscallError); ok {
	 523  		t, ok := ne.Err.(temporary)
	 524  		return ok && t.Temporary()
	 525  	}
	 526  	t, ok := e.Err.(temporary)
	 527  	return ok && t.Temporary()
	 528  }
	 529  
	 530  // A ParseError is the error type of literal network address parsers.
	 531  type ParseError struct {
	 532  	// Type is the type of string that was expected, such as
	 533  	// "IP address", "CIDR address".
	 534  	Type string
	 535  
	 536  	// Text is the malformed text string.
	 537  	Text string
	 538  }
	 539  
	 540  func (e *ParseError) Error() string { return "invalid " + e.Type + ": " + e.Text }
	 541  
	 542  func (e *ParseError) Timeout() bool	 { return false }
	 543  func (e *ParseError) Temporary() bool { return false }
	 544  
	 545  type AddrError struct {
	 546  	Err	string
	 547  	Addr string
	 548  }
	 549  
	 550  func (e *AddrError) Error() string {
	 551  	if e == nil {
	 552  		return "<nil>"
	 553  	}
	 554  	s := e.Err
	 555  	if e.Addr != "" {
	 556  		s = "address " + e.Addr + ": " + s
	 557  	}
	 558  	return s
	 559  }
	 560  
	 561  func (e *AddrError) Timeout() bool	 { return false }
	 562  func (e *AddrError) Temporary() bool { return false }
	 563  
	 564  type UnknownNetworkError string
	 565  
	 566  func (e UnknownNetworkError) Error() string	 { return "unknown network " + string(e) }
	 567  func (e UnknownNetworkError) Timeout() bool	 { return false }
	 568  func (e UnknownNetworkError) Temporary() bool { return false }
	 569  
	 570  type InvalidAddrError string
	 571  
	 572  func (e InvalidAddrError) Error() string	 { return string(e) }
	 573  func (e InvalidAddrError) Timeout() bool	 { return false }
	 574  func (e InvalidAddrError) Temporary() bool { return false }
	 575  
	 576  // errTimeout exists to return the historical "i/o timeout" string
	 577  // for context.DeadlineExceeded. See mapErr.
	 578  // It is also used when Dialer.Deadline is exceeded.
	 579  //
	 580  // TODO(iant): We could consider changing this to os.ErrDeadlineExceeded
	 581  // in the future, but note that that would conflict with the TODO
	 582  // at mapErr that suggests changing it to context.DeadlineExceeded.
	 583  var errTimeout error = &timeoutError{}
	 584  
	 585  type timeoutError struct{}
	 586  
	 587  func (e *timeoutError) Error() string	 { return "i/o timeout" }
	 588  func (e *timeoutError) Timeout() bool	 { return true }
	 589  func (e *timeoutError) Temporary() bool { return true }
	 590  
	 591  // DNSConfigError represents an error reading the machine's DNS configuration.
	 592  // (No longer used; kept for compatibility.)
	 593  type DNSConfigError struct {
	 594  	Err error
	 595  }
	 596  
	 597  func (e *DNSConfigError) Unwrap() error	 { return e.Err }
	 598  func (e *DNSConfigError) Error() string	 { return "error reading DNS config: " + e.Err.Error() }
	 599  func (e *DNSConfigError) Timeout() bool	 { return false }
	 600  func (e *DNSConfigError) Temporary() bool { return false }
	 601  
	 602  // Various errors contained in DNSError.
	 603  var (
	 604  	errNoSuchHost = errors.New("no such host")
	 605  )
	 606  
	 607  // DNSError represents a DNS lookup error.
	 608  type DNSError struct {
	 609  	Err				 string // description of the error
	 610  	Name				string // name looked for
	 611  	Server			string // server used
	 612  	IsTimeout	 bool	 // if true, timed out; not all timeouts set this
	 613  	IsTemporary bool	 // if true, error is temporary; not all errors set this
	 614  	IsNotFound	bool	 // if true, host could not be found
	 615  }
	 616  
	 617  func (e *DNSError) Error() string {
	 618  	if e == nil {
	 619  		return "<nil>"
	 620  	}
	 621  	s := "lookup " + e.Name
	 622  	if e.Server != "" {
	 623  		s += " on " + e.Server
	 624  	}
	 625  	s += ": " + e.Err
	 626  	return s
	 627  }
	 628  
	 629  // Timeout reports whether the DNS lookup is known to have timed out.
	 630  // This is not always known; a DNS lookup may fail due to a timeout
	 631  // and return a DNSError for which Timeout returns false.
	 632  func (e *DNSError) Timeout() bool { return e.IsTimeout }
	 633  
	 634  // Temporary reports whether the DNS error is known to be temporary.
	 635  // This is not always known; a DNS lookup may fail due to a temporary
	 636  // error and return a DNSError for which Temporary returns false.
	 637  func (e *DNSError) Temporary() bool { return e.IsTimeout || e.IsTemporary }
	 638  
	 639  // errClosed exists just so that the docs for ErrClosed don't mention
	 640  // the internal package poll.
	 641  var errClosed = poll.ErrNetClosing
	 642  
	 643  // ErrClosed is the error returned by an I/O call on a network
	 644  // connection that has already been closed, or that is closed by
	 645  // another goroutine before the I/O is completed. This may be wrapped
	 646  // in another error, and should normally be tested using
	 647  // errors.Is(err, net.ErrClosed).
	 648  var ErrClosed error = errClosed
	 649  
	 650  type writerOnly struct {
	 651  	io.Writer
	 652  }
	 653  
	 654  // Fallback implementation of io.ReaderFrom's ReadFrom, when sendfile isn't
	 655  // applicable.
	 656  func genericReadFrom(w io.Writer, r io.Reader) (n int64, err error) {
	 657  	// Use wrapper to hide existing r.ReadFrom from io.Copy.
	 658  	return io.Copy(writerOnly{w}, r)
	 659  }
	 660  
	 661  // Limit the number of concurrent cgo-using goroutines, because
	 662  // each will block an entire operating system thread. The usual culprit
	 663  // is resolving many DNS names in separate goroutines but the DNS
	 664  // server is not responding. Then the many lookups each use a different
	 665  // thread, and the system or the program runs out of threads.
	 666  
	 667  var threadLimit chan struct{}
	 668  
	 669  var threadOnce sync.Once
	 670  
	 671  func acquireThread() {
	 672  	threadOnce.Do(func() {
	 673  		threadLimit = make(chan struct{}, concurrentThreadsLimit())
	 674  	})
	 675  	threadLimit <- struct{}{}
	 676  }
	 677  
	 678  func releaseThread() {
	 679  	<-threadLimit
	 680  }
	 681  
	 682  // buffersWriter is the interface implemented by Conns that support a
	 683  // "writev"-like batch write optimization.
	 684  // writeBuffers should fully consume and write all chunks from the
	 685  // provided Buffers, else it should report a non-nil error.
	 686  type buffersWriter interface {
	 687  	writeBuffers(*Buffers) (int64, error)
	 688  }
	 689  
	 690  // Buffers contains zero or more runs of bytes to write.
	 691  //
	 692  // On certain machines, for certain types of connections, this is
	 693  // optimized into an OS-specific batch write operation (such as
	 694  // "writev").
	 695  type Buffers [][]byte
	 696  
	 697  var (
	 698  	_ io.WriterTo = (*Buffers)(nil)
	 699  	_ io.Reader	 = (*Buffers)(nil)
	 700  )
	 701  
	 702  func (v *Buffers) WriteTo(w io.Writer) (n int64, err error) {
	 703  	if wv, ok := w.(buffersWriter); ok {
	 704  		return wv.writeBuffers(v)
	 705  	}
	 706  	for _, b := range *v {
	 707  		nb, err := w.Write(b)
	 708  		n += int64(nb)
	 709  		if err != nil {
	 710  			v.consume(n)
	 711  			return n, err
	 712  		}
	 713  	}
	 714  	v.consume(n)
	 715  	return n, nil
	 716  }
	 717  
	 718  func (v *Buffers) Read(p []byte) (n int, err error) {
	 719  	for len(p) > 0 && len(*v) > 0 {
	 720  		n0 := copy(p, (*v)[0])
	 721  		v.consume(int64(n0))
	 722  		p = p[n0:]
	 723  		n += n0
	 724  	}
	 725  	if len(*v) == 0 {
	 726  		err = io.EOF
	 727  	}
	 728  	return
	 729  }
	 730  
	 731  func (v *Buffers) consume(n int64) {
	 732  	for len(*v) > 0 {
	 733  		ln0 := int64(len((*v)[0]))
	 734  		if ln0 > n {
	 735  			(*v)[0] = (*v)[0][n:]
	 736  			return
	 737  		}
	 738  		n -= ln0
	 739  		(*v)[0] = nil
	 740  		*v = (*v)[1:]
	 741  	}
	 742  }
	 743  

View as plain text