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	var errMissingAddress = errors.New("missing address")
   279	
   280	// OpError is the error type usually returned by functions in the net
   281	// package. It describes the operation, network type, and address of
   282	// an error.
   283	type OpError struct {
   284		// Op is the operation which caused the error, such as
   285		// "read" or "write".
   286		Op string
   287	
   288		// Net is the network type on which this error occurred,
   289		// such as "tcp" or "udp6".
   290		Net string
   291	
   292		// Addr is the network address on which this error occurred.
   293		Addr Addr
   294	
   295		// Err is the error that occurred during the operation.
   296		Err error
   297	}
   298	
   299	func (e *OpError) Error() string {
   300		if e == nil {
   301			return "<nil>"
   302		}
   303		s := e.Op
   304		if e.Net != "" {
   305			s += " " + e.Net
   306		}
   307		if e.Addr != nil {
   308			s += " " + e.Addr.String()
   309		}
   310		s += ": " + e.Err.Error()
   311		return s
   312	}
   313	
   314	type temporary interface {
   315		Temporary() bool
   316	}
   317	
   318	func (e *OpError) Temporary() bool {
   319		t, ok := e.Err.(temporary)
   320		return ok && t.Temporary()
   321	}
   322	
   323	var noDeadline = time.Time{}
   324	
   325	type timeout interface {
   326		Timeout() bool
   327	}
   328	
   329	func (e *OpError) Timeout() bool {
   330		t, ok := e.Err.(timeout)
   331		return ok && t.Timeout()
   332	}
   333	
   334	type timeoutError struct{}
   335	
   336	func (e *timeoutError) Error() string   { return "i/o timeout" }
   337	func (e *timeoutError) Timeout() bool   { return true }
   338	func (e *timeoutError) Temporary() bool { return true }
   339	
   340	var errTimeout error = &timeoutError{}
   341	
   342	var errClosing = errors.New("use of closed network connection")
   343	
   344	type AddrError struct {
   345		Err  string
   346		Addr string
   347	}
   348	
   349	func (e *AddrError) Error() string {
   350		if e == nil {
   351			return "<nil>"
   352		}
   353		s := e.Err
   354		if e.Addr != "" {
   355			s += " " + e.Addr
   356		}
   357		return s
   358	}
   359	
   360	func (e *AddrError) Temporary() bool {
   361		return false
   362	}
   363	
   364	func (e *AddrError) Timeout() bool {
   365		return false
   366	}
   367	
   368	type UnknownNetworkError string
   369	
   370	func (e UnknownNetworkError) Error() string   { return "unknown network " + string(e) }
   371	func (e UnknownNetworkError) Temporary() bool { return false }
   372	func (e UnknownNetworkError) Timeout() bool   { return false }
   373	
   374	type InvalidAddrError string
   375	
   376	func (e InvalidAddrError) Error() string   { return string(e) }
   377	func (e InvalidAddrError) Timeout() bool   { return false }
   378	func (e InvalidAddrError) Temporary() bool { return false }
   379	
   380	// DNSConfigError represents an error reading the machine's DNS configuration.
   381	type DNSConfigError struct {
   382		Err error
   383	}
   384	
   385	func (e *DNSConfigError) Error() string {
   386		return "error reading DNS config: " + e.Err.Error()
   387	}
   388	
   389	func (e *DNSConfigError) Timeout() bool   { return false }
   390	func (e *DNSConfigError) Temporary() bool { return false }
   391	
   392	type writerOnly struct {
   393		io.Writer
   394	}
   395	
   396	// Fallback implementation of io.ReaderFrom's ReadFrom, when sendfile isn't
   397	// applicable.
   398	func genericReadFrom(w io.Writer, r io.Reader) (n int64, err error) {
   399		// Use wrapper to hide existing r.ReadFrom from io.Copy.
   400		return io.Copy(writerOnly{w}, r)
   401	}
   402	
   403	// Limit the number of concurrent cgo-using goroutines, because
   404	// each will block an entire operating system thread. The usual culprit
   405	// is resolving many DNS names in separate goroutines but the DNS
   406	// server is not responding. Then the many lookups each use a different
   407	// thread, and the system or the program runs out of threads.
   408	
   409	var threadLimit = make(chan struct{}, 500)
   410	
   411	// Using send for acquire is fine here because we are not using this
   412	// to protect any memory. All we care about is the number of goroutines
   413	// making calls at a time.
   414	
   415	func acquireThread() {
   416		threadLimit <- struct{}{}
   417	}
   418	
   419	func releaseThread() {
   420		<-threadLimit
   421	}

View as plain text