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