github.com/roboticscm/goman@v0.0.0-20210203095141-87c07b4a0a55/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  // TODO(rsc):
    42  //	support for raw ethernet sockets
    43  
    44  import (
    45  	"errors"
    46  	"io"
    47  	"os"
    48  	"syscall"
    49  	"time"
    50  )
    51  
    52  // Addr represents a network end point address.
    53  type Addr interface {
    54  	Network() string // name of the network
    55  	String() string  // string form of address
    56  }
    57  
    58  // Conn is a generic stream-oriented network connection.
    59  //
    60  // Multiple goroutines may invoke methods on a Conn simultaneously.
    61  type Conn interface {
    62  	// Read reads data from the connection.
    63  	// Read can be made to time out and return a Error with Timeout() == true
    64  	// after a fixed time limit; see SetDeadline and SetReadDeadline.
    65  	Read(b []byte) (n int, err error)
    66  
    67  	// Write writes data to the connection.
    68  	// Write can be made to time out and return a Error with Timeout() == true
    69  	// after a fixed time limit; see SetDeadline and SetWriteDeadline.
    70  	Write(b []byte) (n int, err error)
    71  
    72  	// Close closes the connection.
    73  	// Any blocked Read or Write operations will be unblocked and return errors.
    74  	Close() error
    75  
    76  	// LocalAddr returns the local network address.
    77  	LocalAddr() Addr
    78  
    79  	// RemoteAddr returns the remote network address.
    80  	RemoteAddr() Addr
    81  
    82  	// SetDeadline sets the read and write deadlines associated
    83  	// with the connection. It is equivalent to calling both
    84  	// SetReadDeadline and SetWriteDeadline.
    85  	//
    86  	// A deadline is an absolute time after which I/O operations
    87  	// fail with a timeout (see type Error) instead of
    88  	// blocking. The deadline applies to all future I/O, not just
    89  	// the immediately following call to Read or Write.
    90  	//
    91  	// An idle timeout can be implemented by repeatedly extending
    92  	// the deadline after successful Read or Write calls.
    93  	//
    94  	// A zero value for t means I/O operations will not time out.
    95  	SetDeadline(t time.Time) error
    96  
    97  	// SetReadDeadline sets the deadline for future Read calls.
    98  	// A zero value for t means Read will not time out.
    99  	SetReadDeadline(t time.Time) error
   100  
   101  	// SetWriteDeadline sets the deadline for future Write calls.
   102  	// Even if write times out, it may return n > 0, indicating that
   103  	// some of the data was successfully written.
   104  	// A zero value for t means Write will not time out.
   105  	SetWriteDeadline(t time.Time) error
   106  }
   107  
   108  type conn struct {
   109  	fd *netFD
   110  }
   111  
   112  func (c *conn) ok() bool { return c != nil && c.fd != nil }
   113  
   114  // Implementation of the Conn interface.
   115  
   116  // Read implements the Conn Read method.
   117  func (c *conn) Read(b []byte) (int, error) {
   118  	if !c.ok() {
   119  		return 0, syscall.EINVAL
   120  	}
   121  	return c.fd.Read(b)
   122  }
   123  
   124  // Write implements the Conn Write method.
   125  func (c *conn) Write(b []byte) (int, error) {
   126  	if !c.ok() {
   127  		return 0, syscall.EINVAL
   128  	}
   129  	return c.fd.Write(b)
   130  }
   131  
   132  // Close closes the connection.
   133  func (c *conn) Close() error {
   134  	if !c.ok() {
   135  		return syscall.EINVAL
   136  	}
   137  	return c.fd.Close()
   138  }
   139  
   140  // LocalAddr returns the local network address.
   141  func (c *conn) LocalAddr() Addr {
   142  	if !c.ok() {
   143  		return nil
   144  	}
   145  	return c.fd.laddr
   146  }
   147  
   148  // RemoteAddr returns the remote network address.
   149  func (c *conn) RemoteAddr() Addr {
   150  	if !c.ok() {
   151  		return nil
   152  	}
   153  	return c.fd.raddr
   154  }
   155  
   156  // SetDeadline implements the Conn SetDeadline method.
   157  func (c *conn) SetDeadline(t time.Time) error {
   158  	if !c.ok() {
   159  		return syscall.EINVAL
   160  	}
   161  	return c.fd.setDeadline(t)
   162  }
   163  
   164  // SetReadDeadline implements the Conn SetReadDeadline method.
   165  func (c *conn) SetReadDeadline(t time.Time) error {
   166  	if !c.ok() {
   167  		return syscall.EINVAL
   168  	}
   169  	return c.fd.setReadDeadline(t)
   170  }
   171  
   172  // SetWriteDeadline implements the Conn SetWriteDeadline method.
   173  func (c *conn) SetWriteDeadline(t time.Time) error {
   174  	if !c.ok() {
   175  		return syscall.EINVAL
   176  	}
   177  	return c.fd.setWriteDeadline(t)
   178  }
   179  
   180  // SetReadBuffer sets the size of the operating system's
   181  // receive buffer associated with the connection.
   182  func (c *conn) SetReadBuffer(bytes int) error {
   183  	if !c.ok() {
   184  		return syscall.EINVAL
   185  	}
   186  	return setReadBuffer(c.fd, bytes)
   187  }
   188  
   189  // SetWriteBuffer sets the size of the operating system's
   190  // transmit buffer associated with the connection.
   191  func (c *conn) SetWriteBuffer(bytes int) error {
   192  	if !c.ok() {
   193  		return syscall.EINVAL
   194  	}
   195  	return setWriteBuffer(c.fd, bytes)
   196  }
   197  
   198  // File sets the underlying os.File to blocking mode and returns a copy.
   199  // It is the caller's responsibility to close f when finished.
   200  // Closing c does not affect f, and closing f does not affect c.
   201  //
   202  // The returned os.File's file descriptor is different from the connection's.
   203  // Attempting to change properties of the original using this duplicate
   204  // may or may not have the desired effect.
   205  func (c *conn) File() (f *os.File, err error) { return c.fd.dup() }
   206  
   207  // An Error represents a network error.
   208  type Error interface {
   209  	error
   210  	Timeout() bool   // Is the error a timeout?
   211  	Temporary() bool // Is the error temporary?
   212  }
   213  
   214  // PacketConn is a generic packet-oriented network connection.
   215  //
   216  // Multiple goroutines may invoke methods on a PacketConn simultaneously.
   217  type PacketConn interface {
   218  	// ReadFrom reads a packet from the connection,
   219  	// copying the payload into b.  It returns the number of
   220  	// bytes copied into b and the return address that
   221  	// was on the packet.
   222  	// ReadFrom can be made to time out and return
   223  	// an error with Timeout() == true after a fixed time limit;
   224  	// see SetDeadline and SetReadDeadline.
   225  	ReadFrom(b []byte) (n int, addr Addr, err error)
   226  
   227  	// WriteTo writes a packet with payload b to addr.
   228  	// WriteTo can be made to time out and return
   229  	// an error with Timeout() == true after a fixed time limit;
   230  	// see SetDeadline and SetWriteDeadline.
   231  	// On packet-oriented connections, write timeouts are rare.
   232  	WriteTo(b []byte, addr Addr) (n int, err error)
   233  
   234  	// Close closes the connection.
   235  	// Any blocked ReadFrom or WriteTo operations will be unblocked and return errors.
   236  	Close() error
   237  
   238  	// LocalAddr returns the local network address.
   239  	LocalAddr() Addr
   240  
   241  	// SetDeadline sets the read and write deadlines associated
   242  	// with the connection.
   243  	SetDeadline(t time.Time) error
   244  
   245  	// SetReadDeadline sets the deadline for future Read calls.
   246  	// If the deadline is reached, Read will fail with a timeout
   247  	// (see type Error) instead of blocking.
   248  	// A zero value for t means Read will not time out.
   249  	SetReadDeadline(t time.Time) error
   250  
   251  	// SetWriteDeadline sets the deadline for future Write calls.
   252  	// If the deadline is reached, Write will fail with a timeout
   253  	// (see type Error) instead of blocking.
   254  	// A zero value for t means Write will not time out.
   255  	// Even if write times out, it may return n > 0, indicating that
   256  	// some of the data was successfully written.
   257  	SetWriteDeadline(t time.Time) error
   258  }
   259  
   260  var listenerBacklog = maxListenerBacklog()
   261  
   262  // A Listener is a generic network listener for stream-oriented protocols.
   263  //
   264  // Multiple goroutines may invoke methods on a Listener simultaneously.
   265  type Listener interface {
   266  	// Accept waits for and returns the next connection to the listener.
   267  	Accept() (c Conn, err error)
   268  
   269  	// Close closes the listener.
   270  	// Any blocked Accept operations will be unblocked and return errors.
   271  	Close() error
   272  
   273  	// Addr returns the listener's network address.
   274  	Addr() Addr
   275  }
   276  
   277  // Various errors contained in OpError.
   278  var (
   279  	// For connection setup and write operations.
   280  	errMissingAddress = errors.New("missing address")
   281  
   282  	// For both read and write operations.
   283  	errTimeout          error = &timeoutError{}
   284  	errClosing                = errors.New("use of closed network connection")
   285  	ErrWriteToConnected       = errors.New("use of WriteTo with pre-connected connection")
   286  )
   287  
   288  // OpError is the error type usually returned by functions in the net
   289  // package. It describes the operation, network type, and address of
   290  // an error.
   291  type OpError struct {
   292  	// Op is the operation which caused the error, such as
   293  	// "read" or "write".
   294  	Op string
   295  
   296  	// Net is the network type on which this error occurred,
   297  	// such as "tcp" or "udp6".
   298  	Net string
   299  
   300  	// Addr is the network address on which this error occurred.
   301  	Addr Addr
   302  
   303  	// Err is the error that occurred during the operation.
   304  	Err error
   305  }
   306  
   307  func (e *OpError) Error() string {
   308  	if e == nil {
   309  		return "<nil>"
   310  	}
   311  	s := e.Op
   312  	if e.Net != "" {
   313  		s += " " + e.Net
   314  	}
   315  	if e.Addr != nil {
   316  		s += " " + e.Addr.String()
   317  	}
   318  	s += ": " + e.Err.Error()
   319  	return s
   320  }
   321  
   322  type temporary interface {
   323  	Temporary() bool
   324  }
   325  
   326  func (e *OpError) Temporary() bool {
   327  	t, ok := e.Err.(temporary)
   328  	return ok && t.Temporary()
   329  }
   330  
   331  var noDeadline = time.Time{}
   332  
   333  type timeout interface {
   334  	Timeout() bool
   335  }
   336  
   337  func (e *OpError) Timeout() bool {
   338  	t, ok := e.Err.(timeout)
   339  	return ok && t.Timeout()
   340  }
   341  
   342  type timeoutError struct{}
   343  
   344  func (e *timeoutError) Error() string   { return "i/o timeout" }
   345  func (e *timeoutError) Timeout() bool   { return true }
   346  func (e *timeoutError) Temporary() bool { return true }
   347  
   348  type AddrError struct {
   349  	Err  string
   350  	Addr string
   351  }
   352  
   353  func (e *AddrError) Error() string {
   354  	if e == nil {
   355  		return "<nil>"
   356  	}
   357  	s := e.Err
   358  	if e.Addr != "" {
   359  		s += " " + e.Addr
   360  	}
   361  	return s
   362  }
   363  
   364  func (e *AddrError) Temporary() bool {
   365  	return false
   366  }
   367  
   368  func (e *AddrError) Timeout() bool {
   369  	return false
   370  }
   371  
   372  type UnknownNetworkError string
   373  
   374  func (e UnknownNetworkError) Error() string   { return "unknown network " + string(e) }
   375  func (e UnknownNetworkError) Temporary() bool { return false }
   376  func (e UnknownNetworkError) Timeout() bool   { return false }
   377  
   378  type InvalidAddrError string
   379  
   380  func (e InvalidAddrError) Error() string   { return string(e) }
   381  func (e InvalidAddrError) Timeout() bool   { return false }
   382  func (e InvalidAddrError) Temporary() bool { return false }
   383  
   384  // DNSConfigError represents an error reading the machine's DNS configuration.
   385  type DNSConfigError struct {
   386  	Err error
   387  }
   388  
   389  func (e *DNSConfigError) Error() string {
   390  	return "error reading DNS config: " + e.Err.Error()
   391  }
   392  
   393  func (e *DNSConfigError) Timeout() bool   { return false }
   394  func (e *DNSConfigError) Temporary() bool { return false }
   395  
   396  type writerOnly struct {
   397  	io.Writer
   398  }
   399  
   400  // Fallback implementation of io.ReaderFrom's ReadFrom, when sendfile isn't
   401  // applicable.
   402  func genericReadFrom(w io.Writer, r io.Reader) (n int64, err error) {
   403  	// Use wrapper to hide existing r.ReadFrom from io.Copy.
   404  	return io.Copy(writerOnly{w}, r)
   405  }
   406  
   407  // Limit the number of concurrent cgo-using goroutines, because
   408  // each will block an entire operating system thread. The usual culprit
   409  // is resolving many DNS names in separate goroutines but the DNS
   410  // server is not responding. Then the many lookups each use a different
   411  // thread, and the system or the program runs out of threads.
   412  
   413  var threadLimit = make(chan struct{}, 500)
   414  
   415  // Using send for acquire is fine here because we are not using this
   416  // to protect any memory. All we care about is the number of goroutines
   417  // making calls at a time.
   418  
   419  func acquireThread() {
   420  	threadLimit <- struct{}{}
   421  }
   422  
   423  func releaseThread() {
   424  	<-threadLimit
   425  }