...
Run Format

Source file src/pkg/net/net.go

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

View as plain text