github.com/c0deoo1/golang1.5@v0.0.0-20220525150107-c87c805d4593/src/net/net.go (about)

     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", "google.com: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  package net
    40  
    41  import (
    42  	"errors"
    43  	"io"
    44  	"os"
    45  	"syscall"
    46  	"time"
    47  )
    48  
    49  // netGo and netCgo contain the state of the build tags used
    50  // to build this binary, and whether cgo is available.
    51  // conf.go mirrors these into conf for easier testing.
    52  var (
    53  	netGo  bool // set true in cgo_stub.go for build tag "netgo" (or no cgo)
    54  	netCgo bool // set true in conf_netcgo.go for build tag "netcgo"
    55  )
    56  
    57  func init() {
    58  	sysInit()
    59  	supportsIPv4 = probeIPv4Stack()
    60  	supportsIPv6, supportsIPv4map = probeIPv6Stack()
    61  }
    62  
    63  // Addr represents a network end point address.
    64  type Addr interface {
    65  	Network() string // name of the network
    66  	String() string  // string form of address
    67  }
    68  
    69  // Conn is a generic stream-oriented network connection.
    70  //
    71  // Multiple goroutines may invoke methods on a Conn simultaneously.
    72  type Conn interface {
    73  	// Read reads data from the connection.
    74  	// Read can be made to time out and return a Error with Timeout() == true
    75  	// after a fixed time limit; see SetDeadline and SetReadDeadline.
    76  	Read(b []byte) (n int, err error)
    77  
    78  	// Write writes data to the connection.
    79  	// Write can be made to time out and return a Error with Timeout() == true
    80  	// after a fixed time limit; see SetDeadline and SetWriteDeadline.
    81  	Write(b []byte) (n int, err error)
    82  
    83  	// Close closes the connection.
    84  	// Any blocked Read or Write operations will be unblocked and return errors.
    85  	Close() error
    86  
    87  	// LocalAddr returns the local network address.
    88  	LocalAddr() Addr
    89  
    90  	// RemoteAddr returns the remote network address.
    91  	RemoteAddr() Addr
    92  
    93  	// SetDeadline sets the read and write deadlines associated
    94  	// with the connection. It is equivalent to calling both
    95  	// SetReadDeadline and SetWriteDeadline.
    96  	//
    97  	// A deadline is an absolute time after which I/O operations
    98  	// fail with a timeout (see type Error) instead of
    99  	// blocking. The deadline applies to all future I/O, not just
   100  	// the immediately following call to Read or Write.
   101  	//
   102  	// An idle timeout can be implemented by repeatedly extending
   103  	// the deadline after successful Read or Write calls.
   104  	//
   105  	// A zero value for t means I/O operations will not time out.
   106  	SetDeadline(t time.Time) error
   107  
   108  	// SetReadDeadline sets the deadline for future Read calls.
   109  	// A zero value for t means Read will not time out.
   110  	SetReadDeadline(t time.Time) error
   111  
   112  	// SetWriteDeadline sets the deadline for future Write calls.
   113  	// Even if write times out, it may return n > 0, indicating that
   114  	// some of the data was successfully written.
   115  	// A zero value for t means Write will not time out.
   116  	SetWriteDeadline(t time.Time) error
   117  }
   118  
   119  type conn struct {
   120  	fd *netFD
   121  }
   122  
   123  func (c *conn) ok() bool { return c != nil && c.fd != nil }
   124  
   125  // Implementation of the Conn interface.
   126  
   127  // Read implements the Conn Read method.
   128  func (c *conn) Read(b []byte) (int, error) {
   129  	if !c.ok() {
   130  		return 0, syscall.EINVAL
   131  	}
   132  	n, err := c.fd.Read(b)
   133  	if err != nil && err != io.EOF {
   134  		err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
   135  	}
   136  	return n, err
   137  }
   138  
   139  // Write implements the Conn Write method.
   140  func (c *conn) Write(b []byte) (int, error) {
   141  	if !c.ok() {
   142  		return 0, syscall.EINVAL
   143  	}
   144  	n, err := c.fd.Write(b)
   145  	if err != nil {
   146  		err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
   147  	}
   148  	return n, err
   149  }
   150  
   151  // Close closes the connection.
   152  func (c *conn) Close() error {
   153  	if !c.ok() {
   154  		return syscall.EINVAL
   155  	}
   156  	err := c.fd.Close()
   157  	if err != nil {
   158  		err = &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
   159  	}
   160  	return err
   161  }
   162  
   163  // LocalAddr returns the local network address.
   164  // The Addr returned is shared by all invocations of LocalAddr, so
   165  // do not modify it.
   166  func (c *conn) LocalAddr() Addr {
   167  	if !c.ok() {
   168  		return nil
   169  	}
   170  	return c.fd.laddr
   171  }
   172  
   173  // RemoteAddr returns the remote network address.
   174  // The Addr returned is shared by all invocations of RemoteAddr, so
   175  // do not modify it.
   176  func (c *conn) RemoteAddr() Addr {
   177  	if !c.ok() {
   178  		return nil
   179  	}
   180  	return c.fd.raddr
   181  }
   182  
   183  // SetDeadline implements the Conn SetDeadline method.
   184  func (c *conn) SetDeadline(t time.Time) error {
   185  	if !c.ok() {
   186  		return syscall.EINVAL
   187  	}
   188  	if err := c.fd.setDeadline(t); err != nil {
   189  		return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
   190  	}
   191  	return nil
   192  }
   193  
   194  // SetReadDeadline implements the Conn SetReadDeadline method.
   195  func (c *conn) SetReadDeadline(t time.Time) error {
   196  	if !c.ok() {
   197  		return syscall.EINVAL
   198  	}
   199  	if err := c.fd.setReadDeadline(t); err != nil {
   200  		return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
   201  	}
   202  	return nil
   203  }
   204  
   205  // SetWriteDeadline implements the Conn SetWriteDeadline method.
   206  func (c *conn) SetWriteDeadline(t time.Time) error {
   207  	if !c.ok() {
   208  		return syscall.EINVAL
   209  	}
   210  	if err := c.fd.setWriteDeadline(t); err != nil {
   211  		return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
   212  	}
   213  	return nil
   214  }
   215  
   216  // SetReadBuffer sets the size of the operating system's
   217  // receive buffer associated with the connection.
   218  func (c *conn) SetReadBuffer(bytes int) error {
   219  	if !c.ok() {
   220  		return syscall.EINVAL
   221  	}
   222  	if err := setReadBuffer(c.fd, bytes); err != nil {
   223  		return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
   224  	}
   225  	return nil
   226  }
   227  
   228  // SetWriteBuffer sets the size of the operating system's
   229  // transmit buffer associated with the connection.
   230  func (c *conn) SetWriteBuffer(bytes int) error {
   231  	if !c.ok() {
   232  		return syscall.EINVAL
   233  	}
   234  	if err := setWriteBuffer(c.fd, bytes); err != nil {
   235  		return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
   236  	}
   237  	return nil
   238  }
   239  
   240  // File sets the underlying os.File to blocking mode and returns a copy.
   241  // It is the caller's responsibility to close f when finished.
   242  // Closing c does not affect f, and closing f does not affect c.
   243  //
   244  // The returned os.File's file descriptor is different from the connection's.
   245  // Attempting to change properties of the original using this duplicate
   246  // may or may not have the desired effect.
   247  func (c *conn) File() (f *os.File, err error) {
   248  	f, err = c.fd.dup()
   249  	if err != nil {
   250  		err = &OpError{Op: "file", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
   251  	}
   252  	return
   253  }
   254  
   255  // PacketConn is a generic packet-oriented network connection.
   256  //
   257  // Multiple goroutines may invoke methods on a PacketConn simultaneously.
   258  type PacketConn interface {
   259  	// ReadFrom reads a packet from the connection,
   260  	// copying the payload into b.  It returns the number of
   261  	// bytes copied into b and the return address that
   262  	// was on the packet.
   263  	// ReadFrom can be made to time out and return
   264  	// an error with Timeout() == true after a fixed time limit;
   265  	// see SetDeadline and SetReadDeadline.
   266  	ReadFrom(b []byte) (n int, addr Addr, err error)
   267  
   268  	// WriteTo writes a packet with payload b to addr.
   269  	// WriteTo can be made to time out and return
   270  	// an error with Timeout() == true after a fixed time limit;
   271  	// see SetDeadline and SetWriteDeadline.
   272  	// On packet-oriented connections, write timeouts are rare.
   273  	WriteTo(b []byte, addr Addr) (n int, err error)
   274  
   275  	// Close closes the connection.
   276  	// Any blocked ReadFrom or WriteTo operations will be unblocked and return errors.
   277  	Close() error
   278  
   279  	// LocalAddr returns the local network address.
   280  	LocalAddr() Addr
   281  
   282  	// SetDeadline sets the read and write deadlines associated
   283  	// with the connection.
   284  	SetDeadline(t time.Time) error
   285  
   286  	// SetReadDeadline sets the deadline for future Read calls.
   287  	// If the deadline is reached, Read will fail with a timeout
   288  	// (see type Error) instead of blocking.
   289  	// A zero value for t means Read will not time out.
   290  	SetReadDeadline(t time.Time) error
   291  
   292  	// SetWriteDeadline sets the deadline for future Write calls.
   293  	// If the deadline is reached, Write will fail with a timeout
   294  	// (see type Error) instead of blocking.
   295  	// A zero value for t means Write will not time out.
   296  	// Even if write times out, it may return n > 0, indicating that
   297  	// some of the data was successfully written.
   298  	SetWriteDeadline(t time.Time) error
   299  }
   300  
   301  var listenerBacklog = maxListenerBacklog()
   302  
   303  // A Listener is a generic network listener for stream-oriented protocols.
   304  //
   305  // Multiple goroutines may invoke methods on a Listener simultaneously.
   306  type Listener interface {
   307  	// Accept waits for and returns the next connection to the listener.
   308  	Accept() (c Conn, err error)
   309  
   310  	// Close closes the listener.
   311  	// Any blocked Accept operations will be unblocked and return errors.
   312  	Close() error
   313  
   314  	// Addr returns the listener's network address.
   315  	Addr() Addr
   316  }
   317  
   318  // An Error represents a network error.
   319  type Error interface {
   320  	error
   321  	Timeout() bool   // Is the error a timeout?
   322  	Temporary() bool // Is the error temporary?
   323  }
   324  
   325  // Various errors contained in OpError.
   326  var (
   327  	// For connection setup and write operations.
   328  	errMissingAddress = errors.New("missing address")
   329  
   330  	// For both read and write operations.
   331  	errTimeout          error = &timeoutError{}
   332  	errCanceled               = errors.New("operation was canceled")
   333  	errClosing                = errors.New("use of closed network connection")
   334  	ErrWriteToConnected       = errors.New("use of WriteTo with pre-connected connection")
   335  )
   336  
   337  // OpError is the error type usually returned by functions in the net
   338  // package. It describes the operation, network type, and address of
   339  // an error.
   340  type OpError struct {
   341  	// Op is the operation which caused the error, such as
   342  	// "read" or "write".
   343  	Op string
   344  
   345  	// Net is the network type on which this error occurred,
   346  	// such as "tcp" or "udp6".
   347  	Net string
   348  
   349  	// For operations involving a remote network connection, like
   350  	// Dial, Read, or Write, Source is the corresponding local
   351  	// network address.
   352  	Source Addr
   353  
   354  	// Addr is the network address for which this error occurred.
   355  	// For local operations, like Listen or SetDeadline, Addr is
   356  	// the address of the local endpoint being manipulated.
   357  	// For operations involving a remote network connection, like
   358  	// Dial, Read, or Write, Addr is the remote address of that
   359  	// connection.
   360  	Addr Addr
   361  
   362  	// Err is the error that occurred during the operation.
   363  	Err error
   364  }
   365  
   366  func (e *OpError) Error() string {
   367  	if e == nil {
   368  		return "<nil>"
   369  	}
   370  	s := e.Op
   371  	if e.Net != "" {
   372  		s += " " + e.Net
   373  	}
   374  	if e.Source != nil {
   375  		s += " " + e.Source.String()
   376  	}
   377  	if e.Addr != nil {
   378  		if e.Source != nil {
   379  			s += "->"
   380  		} else {
   381  			s += " "
   382  		}
   383  		s += e.Addr.String()
   384  	}
   385  	s += ": " + e.Err.Error()
   386  	return s
   387  }
   388  
   389  var noDeadline = time.Time{}
   390  
   391  type timeout interface {
   392  	Timeout() bool
   393  }
   394  
   395  func (e *OpError) Timeout() bool {
   396  	if ne, ok := e.Err.(*os.SyscallError); ok {
   397  		t, ok := ne.Err.(timeout)
   398  		return ok && t.Timeout()
   399  	}
   400  	t, ok := e.Err.(timeout)
   401  	return ok && t.Timeout()
   402  }
   403  
   404  type temporary interface {
   405  	Temporary() bool
   406  }
   407  
   408  func (e *OpError) Temporary() bool {
   409  	if ne, ok := e.Err.(*os.SyscallError); ok {
   410  		t, ok := ne.Err.(temporary)
   411  		return ok && t.Temporary()
   412  	}
   413  	t, ok := e.Err.(temporary)
   414  	return ok && t.Temporary()
   415  }
   416  
   417  type timeoutError struct{}
   418  
   419  func (e *timeoutError) Error() string   { return "i/o timeout" }
   420  func (e *timeoutError) Timeout() bool   { return true }
   421  func (e *timeoutError) Temporary() bool { return true }
   422  
   423  // A ParseError is the error type of literal network address parsers.
   424  type ParseError struct {
   425  	// Type is the type of string that was expected, such as
   426  	// "IP address", "CIDR address".
   427  	Type string
   428  
   429  	// Text is the malformed text string.
   430  	Text string
   431  }
   432  
   433  func (e *ParseError) Error() string { return "invalid " + e.Type + ": " + e.Text }
   434  
   435  type AddrError struct {
   436  	Err  string
   437  	Addr string
   438  }
   439  
   440  func (e *AddrError) Error() string {
   441  	if e == nil {
   442  		return "<nil>"
   443  	}
   444  	s := e.Err
   445  	if e.Addr != "" {
   446  		s += " " + e.Addr
   447  	}
   448  	return s
   449  }
   450  
   451  func (e *AddrError) Timeout() bool   { return false }
   452  func (e *AddrError) Temporary() bool { return false }
   453  
   454  type UnknownNetworkError string
   455  
   456  func (e UnknownNetworkError) Error() string   { return "unknown network " + string(e) }
   457  func (e UnknownNetworkError) Timeout() bool   { return false }
   458  func (e UnknownNetworkError) Temporary() bool { return false }
   459  
   460  type InvalidAddrError string
   461  
   462  func (e InvalidAddrError) Error() string   { return string(e) }
   463  func (e InvalidAddrError) Timeout() bool   { return false }
   464  func (e InvalidAddrError) Temporary() bool { return false }
   465  
   466  // DNSConfigError represents an error reading the machine's DNS configuration.
   467  // (No longer used; kept for compatibility.)
   468  type DNSConfigError struct {
   469  	Err error
   470  }
   471  
   472  func (e *DNSConfigError) Error() string   { return "error reading DNS config: " + e.Err.Error() }
   473  func (e *DNSConfigError) Timeout() bool   { return false }
   474  func (e *DNSConfigError) Temporary() bool { return false }
   475  
   476  // Various errors contained in DNSError.
   477  var (
   478  	errNoSuchHost = errors.New("no such host")
   479  )
   480  
   481  // DNSError represents a DNS lookup error.
   482  type DNSError struct {
   483  	Err       string // description of the error
   484  	Name      string // name looked for
   485  	Server    string // server used
   486  	IsTimeout bool   // if true, timed out; not all timeouts set this
   487  }
   488  
   489  func (e *DNSError) Error() string {
   490  	if e == nil {
   491  		return "<nil>"
   492  	}
   493  	s := "lookup " + e.Name
   494  	if e.Server != "" {
   495  		s += " on " + e.Server
   496  	}
   497  	s += ": " + e.Err
   498  	return s
   499  }
   500  
   501  // Timeout reports whether the DNS lookup is known to have timed out.
   502  // This is not always known; a DNS lookup may fail due to a timeout
   503  // and return a DNSError for which Timeout returns false.
   504  func (e *DNSError) Timeout() bool { return e.IsTimeout }
   505  
   506  // Temporary reports whether the DNS error is known to be temporary.
   507  // This is not always known; a DNS lookup may fail due to a temporary
   508  // error and return a DNSError for which Temporary returns false.
   509  func (e *DNSError) Temporary() bool { return e.IsTimeout }
   510  
   511  type writerOnly struct {
   512  	io.Writer
   513  }
   514  
   515  // Fallback implementation of io.ReaderFrom's ReadFrom, when sendfile isn't
   516  // applicable.
   517  func genericReadFrom(w io.Writer, r io.Reader) (n int64, err error) {
   518  	// Use wrapper to hide existing r.ReadFrom from io.Copy.
   519  	return io.Copy(writerOnly{w}, r)
   520  }
   521  
   522  // Limit the number of concurrent cgo-using goroutines, because
   523  // each will block an entire operating system thread. The usual culprit
   524  // is resolving many DNS names in separate goroutines but the DNS
   525  // server is not responding. Then the many lookups each use a different
   526  // thread, and the system or the program runs out of threads.
   527  
   528  var threadLimit = make(chan struct{}, 500)
   529  
   530  func acquireThread() {
   531  	threadLimit <- struct{}{}
   532  }
   533  
   534  func releaseThread() {
   535  	<-threadLimit
   536  }