github.com/dara-project/godist@v0.0.0-20200823115410-e0c80c8f0c78/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", "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  	"dara"
    84  	"errors"
    85  	"internal/poll"
    86  	"io"
    87  	"os"
    88  	"runtime"
    89  	"syscall"
    90  	"time"
    91  )
    92  
    93  // netGo and netCgo contain the state of the build tags used
    94  // to build this binary, and whether cgo is available.
    95  // conf.go mirrors these into conf for easier testing.
    96  var (
    97  	netGo  bool // set true in cgo_stub.go for build tag "netgo" (or no cgo)
    98  	netCgo bool // set true in conf_netcgo.go for build tag "netcgo"
    99  )
   100  
   101  // Addr represents a network end point address.
   102  //
   103  // The two methods Network and String conventionally return strings
   104  // that can be passed as the arguments to Dial, but the exact form
   105  // and meaning of the strings is up to the implementation.
   106  type Addr interface {
   107  	Network() string // name of the network (for example, "tcp", "udp")
   108  	String() string  // string form of address (for example, "192.0.2.1:25", "[2001:db8::1]:80")
   109  }
   110  
   111  // Conn is a generic stream-oriented network connection.
   112  //
   113  // Multiple goroutines may invoke methods on a Conn simultaneously.
   114  type Conn interface {
   115  	// Read reads data from the connection.
   116  	// Read can be made to time out and return an Error with Timeout() == true
   117  	// after a fixed time limit; see SetDeadline and SetReadDeadline.
   118  	Read(b []byte) (n int, err error)
   119  
   120  	// Write writes data to the connection.
   121  	// Write can be made to time out and return an Error with Timeout() == true
   122  	// after a fixed time limit; see SetDeadline and SetWriteDeadline.
   123  	Write(b []byte) (n int, err error)
   124  
   125  	// Close closes the connection.
   126  	// Any blocked Read or Write operations will be unblocked and return errors.
   127  	Close() error
   128  
   129  	// LocalAddr returns the local network address.
   130  	LocalAddr() Addr
   131  
   132  	// RemoteAddr returns the remote network address.
   133  	RemoteAddr() Addr
   134  
   135  	// SetDeadline sets the read and write deadlines associated
   136  	// with the connection. It is equivalent to calling both
   137  	// SetReadDeadline and SetWriteDeadline.
   138  	//
   139  	// A deadline is an absolute time after which I/O operations
   140  	// fail with a timeout (see type Error) instead of
   141  	// blocking. The deadline applies to all future and pending
   142  	// I/O, not just the immediately following call to Read or
   143  	// Write. After a deadline has been exceeded, the connection
   144  	// can be refreshed by setting a deadline in the future.
   145  	//
   146  	// An idle timeout can be implemented by repeatedly extending
   147  	// the deadline after successful Read or Write calls.
   148  	//
   149  	// A zero value for t means I/O operations will not time out.
   150  	SetDeadline(t time.Time) error
   151  
   152  	// SetReadDeadline sets the deadline for future Read calls
   153  	// and any currently-blocked Read call.
   154  	// A zero value for t means Read will not time out.
   155  	SetReadDeadline(t time.Time) error
   156  
   157  	// SetWriteDeadline sets the deadline for future Write calls
   158  	// and any currently-blocked Write call.
   159  	// Even if write times out, it may return n > 0, indicating that
   160  	// some of the data was successfully written.
   161  	// A zero value for t means Write will not time out.
   162  	SetWriteDeadline(t time.Time) error
   163  }
   164  
   165  type conn struct {
   166  	fd *netFD
   167  }
   168  
   169  func (c *conn) ok() bool { return c != nil && c.fd != nil }
   170  
   171  // Implementation of the Conn interface.
   172  
   173  // Read implements the Conn Read method.
   174  func (c *conn) Read(b []byte) (int, error) {
   175  	if !c.ok() {
   176  		// DARA Instrumentation
   177  		if runtime.Is_dara_profiling_on() {
   178              runtime.Dara_Debug_Print(func() {
   179  			    print("[NET.READ] : ")
   180  			    print(c.fd.laddr.String())
   181  			    print(" ")
   182  			    println(c.fd.raddr.String())
   183              })
   184  			str := c.fd.laddr.String() + c.fd.raddr.String()
   185  			argInfo1 := dara.GeneralType{Type: dara.CONNECTION, Integer: len(str)}
   186              copy(argInfo1.String[:], str)
   187  			argInfo2 := dara.GeneralType{Type: dara.ARRAY, Integer: len(b)}
   188  			retInfo1 := dara.GeneralType{Type: dara.INTEGER, Integer: 0}
   189  			retInfo2 := dara.GeneralType{Type: dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL}
   190  			syscallInfo := dara.GeneralSyscall{dara.DSYS_NET_READ, 2, 2, [10]dara.GeneralType{argInfo1, argInfo2}, [10]dara.GeneralType{retInfo1, retInfo2}}
   191  			runtime.Report_Syscall_To_Scheduler(dara.DSYS_NET_READ, syscallInfo)
   192  		}
   193  		return 0, syscall.EINVAL
   194  	}
   195  	n, err := c.fd.Read(b)
   196  	if err != nil && err != io.EOF {
   197  		err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
   198  	}
   199  	// DARA Instrumentation
   200  	if runtime.Is_dara_profiling_on() {
   201          runtime.Dara_Debug_Print(func() {
   202  		    print("[NET.READ] : ")
   203  		    print(c.fd.laddr.String())
   204  		    print(" ")
   205  		    println(c.fd.raddr.String())
   206          })
   207  		str := c.fd.laddr.String() + c.fd.raddr.String()
   208  		argInfo1 := dara.GeneralType{Type: dara.CONNECTION, Integer: len(str)}
   209          copy(argInfo1.String[:], str)
   210  		argInfo2 := dara.GeneralType{Type: dara.ARRAY, Integer: len(b)}
   211  		retInfo1 := dara.GeneralType{Type: dara.INTEGER, Integer: n}
   212  		retInfo2 := dara.GeneralType{Type: dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL}
   213  		syscallInfo := dara.GeneralSyscall{dara.DSYS_NET_READ, 2, 2, [10]dara.GeneralType{argInfo1, argInfo2}, [10]dara.GeneralType{retInfo1, retInfo2}}
   214  		runtime.Report_Syscall_To_Scheduler(dara.DSYS_NET_READ, syscallInfo)
   215  	}
   216  	return n, err
   217  }
   218  
   219  // Write implements the Conn Write method.
   220  func (c *conn) Write(b []byte) (int, error) {
   221  	if !c.ok() {
   222  		// DARA Instrumentation
   223  		if runtime.Is_dara_profiling_on() {
   224              runtime.Dara_Debug_Print(func() {
   225  			    print("[NET.WRITE] : ")
   226  			    print(c.fd.laddr.String())
   227  			    print(" ")
   228  			    print(c.fd.raddr.String())
   229  			    print(" ")
   230  			    println(string(b[:]))
   231              })
   232  			str := c.fd.laddr.String() + c.fd.raddr.String()
   233  			argInfo1 := dara.GeneralType{Type: dara.CONNECTION, Integer: len(str)}
   234              copy(argInfo1.String[:], str)
   235  			argInfo2 := dara.GeneralType{Type: dara.ARRAY, Integer: len(str)}
   236  			retInfo1 := dara.GeneralType{Type: dara.INTEGER, Integer: 0}
   237  			retInfo2 := dara.GeneralType{Type: dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL}
   238  			syscallInfo := dara.GeneralSyscall{dara.DSYS_NET_WRITE, 2, 2, [10]dara.GeneralType{argInfo1, argInfo2}, [10]dara.GeneralType{retInfo1, retInfo2}}
   239  			runtime.Report_Syscall_To_Scheduler(dara.DSYS_NET_WRITE, syscallInfo)
   240  		}
   241  		return 0, syscall.EINVAL
   242  	}
   243  	n, err := c.fd.Write(b)
   244  	if err != nil {
   245  		err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
   246  	}
   247  	// DARA Instrumentation
   248  	if runtime.Is_dara_profiling_on() {
   249          runtime.Dara_Debug_Print(func() {
   250  		    print("[NET.WRITE] : ")
   251  		    print(c.fd.laddr.String())
   252  		    print(" ")
   253  		    print(c.fd.raddr.String())
   254  		    print(" ")
   255  		    println(string(b[:]))
   256          })
   257  		str := c.fd.laddr.String() + c.fd.raddr.String()
   258  		argInfo1 := dara.GeneralType{Type: dara.CONNECTION, Integer: len(str)}
   259          copy(argInfo1.String[:], str)
   260  		argInfo2 := dara.GeneralType{Type: dara.ARRAY, Integer: len(str)}
   261  		retInfo1 := dara.GeneralType{Type: dara.INTEGER, Integer: 0}
   262  		retInfo2 := dara.GeneralType{Type: dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL}
   263  		syscallInfo := dara.GeneralSyscall{dara.DSYS_NET_WRITE, 2, 2, [10]dara.GeneralType{argInfo1, argInfo2}, [10]dara.GeneralType{retInfo1, retInfo2}}
   264  		runtime.Report_Syscall_To_Scheduler(dara.DSYS_NET_WRITE, syscallInfo)
   265  	}
   266  	return n, err
   267  }
   268  
   269  // Close closes the connection.
   270  func (c *conn) Close() error {
   271  	// DARA Instrumentation
   272  	if runtime.Is_dara_profiling_on() {
   273          runtime.Dara_Debug_Print(func() {
   274  		    print("[NET.CLOSE] : ")
   275  		    print(c.fd.laddr.String())
   276  		    print(" ")
   277  		    println(c.fd.raddr.String())
   278          })
   279  		str := c.fd.laddr.String() + c.fd.raddr.String()
   280  		argInfo1 := dara.GeneralType{Type: dara.CONNECTION, Integer: len(str)}
   281          copy(argInfo1.String[:], str)
   282  		retInfo1 := dara.GeneralType{Type: dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL}
   283  		syscallInfo := dara.GeneralSyscall{dara.DSYS_NET_CLOSE, 1, 1, [10]dara.GeneralType{argInfo1}, [10]dara.GeneralType{retInfo1}}
   284  		runtime.Report_Syscall_To_Scheduler(dara.DSYS_NET_CLOSE, syscallInfo)
   285  	}
   286  	if !c.ok() {
   287  		return syscall.EINVAL
   288  	}
   289  	err := c.fd.Close()
   290  	if err != nil {
   291  		err = &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
   292  	}
   293  	return err
   294  }
   295  
   296  // LocalAddr returns the local network address.
   297  // The Addr returned is shared by all invocations of LocalAddr, so
   298  // do not modify it.
   299  func (c *conn) LocalAddr() Addr {
   300  	if !c.ok() {
   301  		return nil
   302  	}
   303  	return c.fd.laddr
   304  }
   305  
   306  // RemoteAddr returns the remote network address.
   307  // The Addr returned is shared by all invocations of RemoteAddr, so
   308  // do not modify it.
   309  func (c *conn) RemoteAddr() Addr {
   310  	if !c.ok() {
   311  		return nil
   312  	}
   313  	return c.fd.raddr
   314  }
   315  
   316  // SetDeadline implements the Conn SetDeadline method.
   317  func (c *conn) SetDeadline(t time.Time) error {
   318  	// DARA Instrumentation
   319  	if runtime.Is_dara_profiling_on() {
   320          runtime.Dara_Debug_Print(func() {
   321  		    print("[NET.SETDEADLINE] : ")
   322  		    print(c.fd.laddr.String())
   323  		    print(" ")
   324  		    print(c.fd.raddr.String())
   325  		    print(" ")
   326  		    println(t.String())
   327          })
   328  		str := c.fd.laddr.String() + c.fd.raddr.String()
   329  		argInfo1 := dara.GeneralType{Type: dara.CONNECTION, Integer: len(str)}
   330          copy(argInfo1.String[:], str)
   331  		argInfo2 := dara.GeneralType{Type: dara.TIME}
   332          copy(argInfo2.String[:], t.String())
   333  		retInfo1 := dara.GeneralType{Type: dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL}
   334  		syscallInfo := dara.GeneralSyscall{dara.DSYS_NET_SETDEADLINE, 1, 1, [10]dara.GeneralType{argInfo1, argInfo2}, [10]dara.GeneralType{retInfo1}}
   335  		runtime.Report_Syscall_To_Scheduler(dara.DSYS_NET_SETDEADLINE, syscallInfo)
   336  	}
   337  	if !c.ok() {
   338  		return syscall.EINVAL
   339  	}
   340  	if err := c.fd.pfd.SetDeadline(t); err != nil {
   341  		return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
   342  	}
   343  	return nil
   344  }
   345  
   346  // SetReadDeadline implements the Conn SetReadDeadline method.
   347  func (c *conn) SetReadDeadline(t time.Time) error {
   348  	// DARA Instrumentation
   349  	if runtime.Is_dara_profiling_on() {
   350          runtime.Dara_Debug_Print(func() {
   351  		    print("[NET.SETREADDEADLINE] : ")
   352  		    print(c.fd.laddr.String())
   353  		    print(" ")
   354  		    print(c.fd.raddr.String())
   355  		    print(" ")
   356  		    println(t.String())
   357          })
   358  		str := c.fd.laddr.String() + c.fd.raddr.String()
   359  		argInfo1 := dara.GeneralType{Type: dara.CONNECTION, Integer: len(str)}
   360          copy(argInfo1.String[:], str)
   361  		argInfo2 := dara.GeneralType{Type: dara.TIME}
   362          copy(argInfo2.String[:], t.String())
   363  		retInfo1 := dara.GeneralType{Type: dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL}
   364  		syscallInfo := dara.GeneralSyscall{dara.DSYS_NET_SETREADDEADLINE, 1, 1, [10]dara.GeneralType{argInfo1, argInfo2}, [10]dara.GeneralType{retInfo1}}
   365  		runtime.Report_Syscall_To_Scheduler(dara.DSYS_NET_SETREADDEADLINE, syscallInfo)
   366  	}
   367  	if !c.ok() {
   368  		return syscall.EINVAL
   369  	}
   370  	if err := c.fd.pfd.SetReadDeadline(t); err != nil {
   371  		return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
   372  	}
   373  	return nil
   374  }
   375  
   376  // SetWriteDeadline implements the Conn SetWriteDeadline method.
   377  func (c *conn) SetWriteDeadline(t time.Time) error {
   378  	// DARA Instrumentation
   379  	if runtime.Is_dara_profiling_on() {
   380          runtime.Dara_Debug_Print(func() {
   381  		    print("[NET.SETWRITEDEADLINE] : ")
   382  		    print(c.fd.laddr.String())
   383  		    print(" ")
   384  		    print(c.fd.raddr.String())
   385  		    print(" ")
   386  		    println(t.String())
   387          })
   388  		str := c.fd.laddr.String() + c.fd.raddr.String()
   389  		argInfo1 := dara.GeneralType{Type: dara.CONNECTION, Integer: len(str)}
   390          copy(argInfo1.String[:], str)
   391  		argInfo2 := dara.GeneralType{Type: dara.TIME}
   392          copy(argInfo2.String[:], t.String())
   393  		retInfo1 := dara.GeneralType{Type: dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL}
   394  		syscallInfo := dara.GeneralSyscall{dara.DSYS_NET_SETWRITEDEADLINE, 1, 1, [10]dara.GeneralType{argInfo1, argInfo2}, [10]dara.GeneralType{retInfo1}}
   395  		runtime.Report_Syscall_To_Scheduler(dara.DSYS_NET_SETWRITEDEADLINE, syscallInfo)
   396  	}
   397  	if !c.ok() {
   398  		return syscall.EINVAL
   399  	}
   400  	if err := c.fd.pfd.SetWriteDeadline(t); err != nil {
   401  		return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
   402  	}
   403  	return nil
   404  }
   405  
   406  // SetReadBuffer sets the size of the operating system's
   407  // receive buffer associated with the connection.
   408  func (c *conn) SetReadBuffer(bytes int) error {
   409  	// DARA Instrumentation
   410  	if runtime.Is_dara_profiling_on() {
   411          runtime.Dara_Debug_Print(func() {
   412  		    print("[NET.SETREADBUFFER] : ")
   413  		    print(c.fd.raddr.String())
   414  		    print(" ")
   415  		    println(bytes)
   416          })
   417  		str := c.fd.laddr.String() + c.fd.raddr.String()
   418  		argInfo1 := dara.GeneralType{Type: dara.CONNECTION, Integer: len(str)}
   419          copy(argInfo1.String[:], str)
   420  		argInfo2 := dara.GeneralType{Type: dara.INTEGER, Integer: bytes}
   421  		retInfo1 := dara.GeneralType{Type: dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL}
   422  		syscallInfo := dara.GeneralSyscall{dara.DSYS_NET_SETREADBUFFER, 2, 1, [10]dara.GeneralType{argInfo1, argInfo2}, [10]dara.GeneralType{retInfo1}}
   423  		runtime.Report_Syscall_To_Scheduler(dara.DSYS_NET_SETREADBUFFER, syscallInfo)
   424  	}
   425  	if !c.ok() {
   426  		return syscall.EINVAL
   427  	}
   428  	if err := setReadBuffer(c.fd, bytes); err != nil {
   429  		return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
   430  	}
   431  	return nil
   432  }
   433  
   434  // SetWriteBuffer sets the size of the operating system's
   435  // transmit buffer associated with the connection.
   436  func (c *conn) SetWriteBuffer(bytes int) error {
   437  	// DARA Instrumentation
   438  	if runtime.Is_dara_profiling_on() {
   439          runtime.Dara_Debug_Print(func() {
   440  		    print("[NET.SETWRITEBUFFER] : ")
   441  		    print(c.fd.raddr.String())
   442  		    print(" ")
   443  		    println(bytes)
   444          })
   445  		str := c.fd.laddr.String() + c.fd.raddr.String()
   446  		argInfo1 := dara.GeneralType{Type: dara.CONNECTION, Integer: len(str)}
   447          copy(argInfo1.String[:], str)
   448  		argInfo2 := dara.GeneralType{Type: dara.INTEGER, Integer: bytes}
   449  		retInfo1 := dara.GeneralType{Type: dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL}
   450  		syscallInfo := dara.GeneralSyscall{dara.DSYS_NET_SETWRITEBUFFER, 2, 1, [10]dara.GeneralType{argInfo1, argInfo2}, [10]dara.GeneralType{retInfo1}}
   451  		runtime.Report_Syscall_To_Scheduler(dara.DSYS_NET_SETWRITEBUFFER, syscallInfo)
   452  	}
   453  	if !c.ok() {
   454  		return syscall.EINVAL
   455  	}
   456  	if err := setWriteBuffer(c.fd, bytes); err != nil {
   457  		return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
   458  	}
   459  	return nil
   460  }
   461  
   462  // File sets the underlying os.File to blocking mode and returns a copy.
   463  // It is the caller's responsibility to close f when finished.
   464  // Closing c does not affect f, and closing f does not affect c.
   465  //
   466  // The returned os.File's file descriptor is different from the connection's.
   467  // Attempting to change properties of the original using this duplicate
   468  // may or may not have the desired effect.
   469  //
   470  // On Unix systems this will cause the SetDeadline methods to stop working.
   471  func (c *conn) File() (f *os.File, err error) {
   472  	f, err = c.fd.dup()
   473  	if err != nil {
   474  		err = &OpError{Op: "file", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
   475  	}
   476  	return
   477  }
   478  
   479  // PacketConn is a generic packet-oriented network connection.
   480  //
   481  // Multiple goroutines may invoke methods on a PacketConn simultaneously.
   482  type PacketConn interface {
   483  	// ReadFrom reads a packet from the connection,
   484  	// copying the payload into b. It returns the number of
   485  	// bytes copied into b and the return address that
   486  	// was on the packet.
   487  	// ReadFrom can be made to time out and return
   488  	// an Error with Timeout() == true after a fixed time limit;
   489  	// see SetDeadline and SetReadDeadline.
   490  	ReadFrom(b []byte) (n int, addr Addr, err error)
   491  
   492  	// WriteTo writes a packet with payload b to addr.
   493  	// WriteTo can be made to time out and return
   494  	// an Error with Timeout() == true after a fixed time limit;
   495  	// see SetDeadline and SetWriteDeadline.
   496  	// On packet-oriented connections, write timeouts are rare.
   497  	WriteTo(b []byte, addr Addr) (n int, err error)
   498  
   499  	// Close closes the connection.
   500  	// Any blocked ReadFrom or WriteTo operations will be unblocked and return errors.
   501  	Close() error
   502  
   503  	// LocalAddr returns the local network address.
   504  	LocalAddr() Addr
   505  
   506  	// SetDeadline sets the read and write deadlines associated
   507  	// with the connection. It is equivalent to calling both
   508  	// SetReadDeadline and SetWriteDeadline.
   509  	//
   510  	// A deadline is an absolute time after which I/O operations
   511  	// fail with a timeout (see type Error) instead of
   512  	// blocking. The deadline applies to all future and pending
   513  	// I/O, not just the immediately following call to ReadFrom or
   514  	// WriteTo. After a deadline has been exceeded, the connection
   515  	// can be refreshed by setting a deadline in the future.
   516  	//
   517  	// An idle timeout can be implemented by repeatedly extending
   518  	// the deadline after successful ReadFrom or WriteTo calls.
   519  	//
   520  	// A zero value for t means I/O operations will not time out.
   521  	SetDeadline(t time.Time) error
   522  
   523  	// SetReadDeadline sets the deadline for future ReadFrom calls
   524  	// and any currently-blocked ReadFrom call.
   525  	// A zero value for t means ReadFrom will not time out.
   526  	SetReadDeadline(t time.Time) error
   527  
   528  	// SetWriteDeadline sets the deadline for future WriteTo calls
   529  	// and any currently-blocked WriteTo call.
   530  	// Even if write times out, it may return n > 0, indicating that
   531  	// some of the data was successfully written.
   532  	// A zero value for t means WriteTo will not time out.
   533  	SetWriteDeadline(t time.Time) error
   534  }
   535  
   536  var listenerBacklog = maxListenerBacklog()
   537  
   538  // A Listener is a generic network listener for stream-oriented protocols.
   539  //
   540  // Multiple goroutines may invoke methods on a Listener simultaneously.
   541  type Listener interface {
   542  	// Accept waits for and returns the next connection to the listener.
   543  	Accept() (Conn, error)
   544  
   545  	// Close closes the listener.
   546  	// Any blocked Accept operations will be unblocked and return errors.
   547  	Close() error
   548  
   549  	// Addr returns the listener's network address.
   550  	Addr() Addr
   551  }
   552  
   553  // An Error represents a network error.
   554  type Error interface {
   555  	error
   556  	Timeout() bool   // Is the error a timeout?
   557  	Temporary() bool // Is the error temporary?
   558  }
   559  
   560  // Various errors contained in OpError.
   561  var (
   562  	// For connection setup operations.
   563  	errNoSuitableAddress = errors.New("no suitable address found")
   564  
   565  	// For connection setup and write operations.
   566  	errMissingAddress = errors.New("missing address")
   567  
   568  	// For both read and write operations.
   569  	errCanceled         = errors.New("operation was canceled")
   570  	ErrWriteToConnected = errors.New("use of WriteTo with pre-connected connection")
   571  )
   572  
   573  // mapErr maps from the context errors to the historical internal net
   574  // error values.
   575  //
   576  // TODO(bradfitz): get rid of this after adjusting tests and making
   577  // context.DeadlineExceeded implement net.Error?
   578  func mapErr(err error) error {
   579  	switch err {
   580  	case context.Canceled:
   581  		return errCanceled
   582  	case context.DeadlineExceeded:
   583  		return poll.ErrTimeout
   584  	default:
   585  		return err
   586  	}
   587  }
   588  
   589  // OpError is the error type usually returned by functions in the net
   590  // package. It describes the operation, network type, and address of
   591  // an error.
   592  type OpError struct {
   593  	// Op is the operation which caused the error, such as
   594  	// "read" or "write".
   595  	Op string
   596  
   597  	// Net is the network type on which this error occurred,
   598  	// such as "tcp" or "udp6".
   599  	Net string
   600  
   601  	// For operations involving a remote network connection, like
   602  	// Dial, Read, or Write, Source is the corresponding local
   603  	// network address.
   604  	Source Addr
   605  
   606  	// Addr is the network address for which this error occurred.
   607  	// For local operations, like Listen or SetDeadline, Addr is
   608  	// the address of the local endpoint being manipulated.
   609  	// For operations involving a remote network connection, like
   610  	// Dial, Read, or Write, Addr is the remote address of that
   611  	// connection.
   612  	Addr Addr
   613  
   614  	// Err is the error that occurred during the operation.
   615  	Err error
   616  }
   617  
   618  func (e *OpError) Error() string {
   619  	if e == nil {
   620  		return "<nil>"
   621  	}
   622  	s := e.Op
   623  	if e.Net != "" {
   624  		s += " " + e.Net
   625  	}
   626  	if e.Source != nil {
   627  		s += " " + e.Source.String()
   628  	}
   629  	if e.Addr != nil {
   630  		if e.Source != nil {
   631  			s += "->"
   632  		} else {
   633  			s += " "
   634  		}
   635  		s += e.Addr.String()
   636  	}
   637  	s += ": " + e.Err.Error()
   638  	return s
   639  }
   640  
   641  var (
   642  	// aLongTimeAgo is a non-zero time, far in the past, used for
   643  	// immediate cancelation of dials.
   644  	aLongTimeAgo = time.Unix(1, 0)
   645  
   646  	// nonDeadline and noCancel are just zero values for
   647  	// readability with functions taking too many parameters.
   648  	noDeadline = time.Time{}
   649  	noCancel   = (chan struct{})(nil)
   650  )
   651  
   652  type timeout interface {
   653  	Timeout() bool
   654  }
   655  
   656  func (e *OpError) Timeout() bool {
   657  	if ne, ok := e.Err.(*os.SyscallError); ok {
   658  		t, ok := ne.Err.(timeout)
   659  		return ok && t.Timeout()
   660  	}
   661  	t, ok := e.Err.(timeout)
   662  	return ok && t.Timeout()
   663  }
   664  
   665  type temporary interface {
   666  	Temporary() bool
   667  }
   668  
   669  func (e *OpError) Temporary() bool {
   670  	if ne, ok := e.Err.(*os.SyscallError); ok {
   671  		t, ok := ne.Err.(temporary)
   672  		return ok && t.Temporary()
   673  	}
   674  	t, ok := e.Err.(temporary)
   675  	return ok && t.Temporary()
   676  }
   677  
   678  // A ParseError is the error type of literal network address parsers.
   679  type ParseError struct {
   680  	// Type is the type of string that was expected, such as
   681  	// "IP address", "CIDR address".
   682  	Type string
   683  
   684  	// Text is the malformed text string.
   685  	Text string
   686  }
   687  
   688  func (e *ParseError) Error() string { return "invalid " + e.Type + ": " + e.Text }
   689  
   690  type AddrError struct {
   691  	Err  string
   692  	Addr string
   693  }
   694  
   695  func (e *AddrError) Error() string {
   696  	if e == nil {
   697  		return "<nil>"
   698  	}
   699  	s := e.Err
   700  	if e.Addr != "" {
   701  		s = "address " + e.Addr + ": " + s
   702  	}
   703  	return s
   704  }
   705  
   706  func (e *AddrError) Timeout() bool   { return false }
   707  func (e *AddrError) Temporary() bool { return false }
   708  
   709  type UnknownNetworkError string
   710  
   711  func (e UnknownNetworkError) Error() string   { return "unknown network " + string(e) }
   712  func (e UnknownNetworkError) Timeout() bool   { return false }
   713  func (e UnknownNetworkError) Temporary() bool { return false }
   714  
   715  type InvalidAddrError string
   716  
   717  func (e InvalidAddrError) Error() string   { return string(e) }
   718  func (e InvalidAddrError) Timeout() bool   { return false }
   719  func (e InvalidAddrError) Temporary() bool { return false }
   720  
   721  // DNSConfigError represents an error reading the machine's DNS configuration.
   722  // (No longer used; kept for compatibility.)
   723  type DNSConfigError struct {
   724  	Err error
   725  }
   726  
   727  func (e *DNSConfigError) Error() string   { return "error reading DNS config: " + e.Err.Error() }
   728  func (e *DNSConfigError) Timeout() bool   { return false }
   729  func (e *DNSConfigError) Temporary() bool { return false }
   730  
   731  // Various errors contained in DNSError.
   732  var (
   733  	errNoSuchHost = errors.New("no such host")
   734  )
   735  
   736  // DNSError represents a DNS lookup error.
   737  type DNSError struct {
   738  	Err         string // description of the error
   739  	Name        string // name looked for
   740  	Server      string // server used
   741  	IsTimeout   bool   // if true, timed out; not all timeouts set this
   742  	IsTemporary bool   // if true, error is temporary; not all errors set this
   743  }
   744  
   745  func (e *DNSError) Error() string {
   746  	if e == nil {
   747  		return "<nil>"
   748  	}
   749  	s := "lookup " + e.Name
   750  	if e.Server != "" {
   751  		s += " on " + e.Server
   752  	}
   753  	s += ": " + e.Err
   754  	return s
   755  }
   756  
   757  // Timeout reports whether the DNS lookup is known to have timed out.
   758  // This is not always known; a DNS lookup may fail due to a timeout
   759  // and return a DNSError for which Timeout returns false.
   760  func (e *DNSError) Timeout() bool { return e.IsTimeout }
   761  
   762  // Temporary reports whether the DNS error is known to be temporary.
   763  // This is not always known; a DNS lookup may fail due to a temporary
   764  // error and return a DNSError for which Temporary returns false.
   765  func (e *DNSError) Temporary() bool { return e.IsTimeout || e.IsTemporary }
   766  
   767  type writerOnly struct {
   768  	io.Writer
   769  }
   770  
   771  // Fallback implementation of io.ReaderFrom's ReadFrom, when sendfile isn't
   772  // applicable.
   773  func genericReadFrom(w io.Writer, r io.Reader) (n int64, err error) {
   774  	// Use wrapper to hide existing r.ReadFrom from io.Copy.
   775  	return io.Copy(writerOnly{w}, r)
   776  }
   777  
   778  // Limit the number of concurrent cgo-using goroutines, because
   779  // each will block an entire operating system thread. The usual culprit
   780  // is resolving many DNS names in separate goroutines but the DNS
   781  // server is not responding. Then the many lookups each use a different
   782  // thread, and the system or the program runs out of threads.
   783  
   784  var threadLimit = make(chan struct{}, 500)
   785  
   786  func acquireThread() {
   787  	threadLimit <- struct{}{}
   788  }
   789  
   790  func releaseThread() {
   791  	<-threadLimit
   792  }
   793  
   794  // buffersWriter is the interface implemented by Conns that support a
   795  // "writev"-like batch write optimization.
   796  // writeBuffers should fully consume and write all chunks from the
   797  // provided Buffers, else it should report a non-nil error.
   798  type buffersWriter interface {
   799  	writeBuffers(*Buffers) (int64, error)
   800  }
   801  
   802  // Buffers contains zero or more runs of bytes to write.
   803  //
   804  // On certain machines, for certain types of connections, this is
   805  // optimized into an OS-specific batch write operation (such as
   806  // "writev").
   807  type Buffers [][]byte
   808  
   809  var (
   810  	_ io.WriterTo = (*Buffers)(nil)
   811  	_ io.Reader   = (*Buffers)(nil)
   812  )
   813  
   814  func (v *Buffers) WriteTo(w io.Writer) (n int64, err error) {
   815  	if wv, ok := w.(buffersWriter); ok {
   816  		return wv.writeBuffers(v)
   817  	}
   818  	for _, b := range *v {
   819  		nb, err := w.Write(b)
   820  		n += int64(nb)
   821  		if err != nil {
   822  			v.consume(n)
   823  			return n, err
   824  		}
   825  	}
   826  	v.consume(n)
   827  	return n, nil
   828  }
   829  
   830  func (v *Buffers) Read(p []byte) (n int, err error) {
   831  	for len(p) > 0 && len(*v) > 0 {
   832  		n0 := copy(p, (*v)[0])
   833  		v.consume(int64(n0))
   834  		p = p[n0:]
   835  		n += n0
   836  	}
   837  	if len(*v) == 0 {
   838  		err = io.EOF
   839  	}
   840  	return
   841  }
   842  
   843  func (v *Buffers) consume(n int64) {
   844  	for len(*v) > 0 {
   845  		ln0 := int64(len((*v)[0]))
   846  		if ln0 > n {
   847  			(*v)[0] = (*v)[0][n:]
   848  			return
   849  		}
   850  		n -= ln0
   851  		*v = (*v)[1:]
   852  	}
   853  }