...
Run Format

Source file src/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			}
    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	}
   426	

View as plain text