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