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/*
6Package net provides a portable interface for network I/O, including
7TCP/IP, UDP, domain name resolution, and Unix domain sockets.
8
9Although the package provides access to low-level networking
10primitives, most clients will need only the basic interface provided
11by the [Dial], [Listen], and Accept functions and the associated
12[Conn] and [Listener] interfaces. The crypto/tls package uses
13the same interfaces and similar Dial and Listen functions.
14
15The 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
25The 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
41The method for resolving domain names, whether indirectly with functions like Dial
42or directly with functions like [LookupHost] and [LookupAddr], varies by operating system.
43
44On Unix systems, the resolver has two options for resolving names.
45It can use a pure Go resolver that sends DNS requests directly to the servers
46listed in /etc/resolv.conf, or it can use a cgo-based resolver that calls C
47library routines such as getaddrinfo and getnameinfo.
48
49On Unix the pure Go resolver is preferred over the cgo resolver, because a blocked DNS
50request consumes only a goroutine, while a blocked C call consumes an operating system thread.
51When cgo is available, the cgo-based resolver is used instead under a variety of
52conditions: on systems that do not let programs make direct DNS requests (OS X),
53when the LOCALDOMAIN environment variable is present (even if empty),
54when the RES_OPTIONS or HOSTALIASES environment variable is non-empty,
55when the ASR_CONFIG environment variable is non-empty (OpenBSD only),
56when /etc/resolv.conf or /etc/nsswitch.conf specify the use of features that the
57Go resolver does not implement.
58
59On all systems (except Plan 9), when the cgo resolver is being used
60this package applies a concurrent cgo lookup limit to prevent the system
61from running out of system threads. Currently, it is limited to 500 concurrent lookups.
62
63The resolver decision can be overridden by setting the netdns value of the
64GODEBUG environment variable (see package runtime) to go or cgo, as in:
65
66	export GODEBUG=netdns=go    # force pure Go resolver
67	export GODEBUG=netdns=cgo   # force native resolver (cgo, win32)
68
69The decision can also be forced while building the Go source tree
70by setting the netgo or netcgo build tag.
71
72A numeric netdns setting, as in GODEBUG=netdns=1, causes the resolver
73to print debugging information about its decisions.
74To force a particular resolver while also printing debugging information,
75join the two settings by a plus sign, as in GODEBUG=netdns=go+1.
76
77The Go resolver will send an EDNS0 additional header with a DNS request,
78to signal a willingness to accept a larger DNS packet size.
79This can reportedly cause sporadic failures with the DNS server run
80by some modems and routers. Setting GODEBUG=netedns0=0 will disable
81sending the additional header.
82
83On macOS, if Go code that uses the net package is built with
84-buildmode=c-archive, linking the resulting archive into a C program
85requires passing -lresolv when linking the C code.
86
87On Plan 9, the resolver always accesses /net/cs and /net/dns.
88
89On Windows, in Go 1.18.x and earlier, the resolver always used C
90library functions, such as GetAddrInfo and DnsQuery.
91*/
92package net
93
94import (
95	"context"
96	"errors"
97	"internal/poll"
98	"io"
99	"os"
100	"sync"
101	"syscall"
102	"time"
103	_ "unsafe" // for linkname
104)
105
106// Addr represents a network end point address.
107//
108// The two methods [Addr.Network] and [Addr.String] conventionally return strings
109// that can be passed as the arguments to [Dial], but the exact form
110// and meaning of the strings is up to the implementation.
111type Addr interface {
112	Network() string // name of the network (for example, "tcp", "udp")
113	String() string  // string form of address (for example, "192.0.2.1:25", "[2001:db8::1]:80")
114}
115
116// Conn is a generic stream-oriented network connection.
117//
118// Multiple goroutines may invoke methods on a Conn simultaneously.
119type Conn interface {
120	// Read reads data from the connection.
121	// Read can be made to time out and return an error after a fixed
122	// time limit; see SetDeadline and SetReadDeadline.
123	Read(b []byte) (n int, err error)
124
125	// Write writes data to the connection.
126	// Write can be made to time out and return an error after a fixed
127	// time limit; see SetDeadline and SetWriteDeadline.
128	Write(b []byte) (n int, err error)
129
130	// Close closes the connection.
131	// Any blocked Read or Write operations will be unblocked and return errors.
132	Close() error
133
134	// LocalAddr returns the local network address, if known.
135	LocalAddr() Addr
136
137	// RemoteAddr returns the remote network address, if known.
138	RemoteAddr() Addr
139
140	// SetDeadline sets the read and write deadlines associated
141	// with the connection. It is equivalent to calling both
142	// SetReadDeadline and SetWriteDeadline.
143	//
144	// A deadline is an absolute time after which I/O operations
145	// fail instead of blocking. The deadline applies to all future
146	// and pending I/O, not just the immediately following call to
147	// Read or Write. After a deadline has been exceeded, the
148	// connection can be refreshed by setting a deadline in the future.
149	//
150	// If the deadline is exceeded a call to Read or Write or to other
151	// I/O methods will return an error that wraps os.ErrDeadlineExceeded.
152	// This can be tested using errors.Is(err, os.ErrDeadlineExceeded).
153	// The error's Timeout method will return true, but note that there
154	// are other possible errors for which the Timeout method will
155	// return true even if the deadline has not been exceeded.
156	//
157	// An idle timeout can be implemented by repeatedly extending
158	// the deadline after successful Read or Write calls.
159	//
160	// A zero value for t means I/O operations will not time out.
161	SetDeadline(t time.Time) error
162
163	// SetReadDeadline sets the deadline for future Read calls
164	// and any currently-blocked Read call.
165	// A zero value for t means Read will not time out.
166	SetReadDeadline(t time.Time) error
167
168	// SetWriteDeadline sets the deadline for future Write calls
169	// and any currently-blocked Write call.
170	// Even if write times out, it may return n > 0, indicating that
171	// some of the data was successfully written.
172	// A zero value for t means Write will not time out.
173	SetWriteDeadline(t time.Time) error
174}
175
176type conn struct {
177	fd *netFD
178}
179
180func (c *conn) ok() bool { return c != nil && c.fd != nil }
181
182// Implementation of the Conn interface.
183
184// Read implements the Conn Read method.
185func (c *conn) Read(b []byte) (int, error) {
186	if !c.ok() {
187		return 0, syscall.EINVAL
188	}
189	n, err := c.fd.Read(b)
190	if err != nil && err != io.EOF {
191		err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
192	}
193	return n, err
194}
195
196// Write implements the Conn Write method.
197func (c *conn) Write(b []byte) (int, error) {
198	if !c.ok() {
199		return 0, syscall.EINVAL
200	}
201	n, err := c.fd.Write(b)
202	if err != nil {
203		err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
204	}
205	return n, err
206}
207
208// Close closes the connection.
209func (c *conn) Close() error {
210	if !c.ok() {
211		return syscall.EINVAL
212	}
213	err := c.fd.Close()
214	if err != nil {
215		err = &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
216	}
217	return err
218}
219
220// LocalAddr returns the local network address.
221// The Addr returned is shared by all invocations of LocalAddr, so
222// do not modify it.
223func (c *conn) LocalAddr() Addr {
224	if !c.ok() {
225		return nil
226	}
227	return c.fd.laddr
228}
229
230// RemoteAddr returns the remote network address.
231// The Addr returned is shared by all invocations of RemoteAddr, so
232// do not modify it.
233func (c *conn) RemoteAddr() Addr {
234	if !c.ok() {
235		return nil
236	}
237	return c.fd.raddr
238}
239
240// SetDeadline implements the Conn SetDeadline method.
241func (c *conn) SetDeadline(t time.Time) error {
242	if !c.ok() {
243		return syscall.EINVAL
244	}
245	if err := c.fd.SetDeadline(t); err != nil {
246		return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
247	}
248	return nil
249}
250
251// SetReadDeadline implements the Conn SetReadDeadline method.
252func (c *conn) SetReadDeadline(t time.Time) error {
253	if !c.ok() {
254		return syscall.EINVAL
255	}
256	if err := c.fd.SetReadDeadline(t); err != nil {
257		return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
258	}
259	return nil
260}
261
262// SetWriteDeadline implements the Conn SetWriteDeadline method.
263func (c *conn) SetWriteDeadline(t time.Time) error {
264	if !c.ok() {
265		return syscall.EINVAL
266	}
267	if err := c.fd.SetWriteDeadline(t); err != nil {
268		return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
269	}
270	return nil
271}
272
273// SetReadBuffer sets the size of the operating system's
274// receive buffer associated with the connection.
275func (c *conn) SetReadBuffer(bytes int) error {
276	if !c.ok() {
277		return syscall.EINVAL
278	}
279	if err := setReadBuffer(c.fd, bytes); err != nil {
280		return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
281	}
282	return nil
283}
284
285// SetWriteBuffer sets the size of the operating system's
286// transmit buffer associated with the connection.
287func (c *conn) SetWriteBuffer(bytes int) error {
288	if !c.ok() {
289		return syscall.EINVAL
290	}
291	if err := setWriteBuffer(c.fd, bytes); err != nil {
292		return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
293	}
294	return nil
295}
296
297// File returns a copy of the underlying [os.File].
298// It is the caller's responsibility to close f when finished.
299// Closing c does not affect f, and closing f does not affect c.
300//
301// The returned os.File's file descriptor is different from the connection's.
302// Attempting to change properties of the original using this duplicate
303// may or may not have the desired effect.
304func (c *conn) File() (f *os.File, err error) {
305	f, err = c.fd.dup()
306	if err != nil {
307		err = &OpError{Op: "file", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
308	}
309	return
310}
311
312// PacketConn is a generic packet-oriented network connection.
313//
314// Multiple goroutines may invoke methods on a PacketConn simultaneously.
315type PacketConn interface {
316	// ReadFrom reads a packet from the connection,
317	// copying the payload into p. It returns the number of
318	// bytes copied into p and the return address that
319	// was on the packet.
320	// It returns the number of bytes read (0 <= n <= len(p))
321	// and any error encountered. Callers should always process
322	// the n > 0 bytes returned before considering the error err.
323	// ReadFrom can be made to time out and return an error after a
324	// fixed time limit; see SetDeadline and SetReadDeadline.
325	ReadFrom(p []byte) (n int, addr Addr, err error)
326
327	// WriteTo writes a packet with payload p to addr.
328	// WriteTo can be made to time out and return an Error after a
329	// fixed time limit; see SetDeadline and SetWriteDeadline.
330	// On packet-oriented connections, write timeouts are rare.
331	WriteTo(p []byte, addr Addr) (n int, err error)
332
333	// Close closes the connection.
334	// Any blocked ReadFrom or WriteTo operations will be unblocked and return errors.
335	Close() error
336
337	// LocalAddr returns the local network address, if known.
338	LocalAddr() Addr
339
340	// SetDeadline sets the read and write deadlines associated
341	// with the connection. It is equivalent to calling both
342	// SetReadDeadline and SetWriteDeadline.
343	//
344	// A deadline is an absolute time after which I/O operations
345	// fail instead of blocking. The deadline applies to all future
346	// and pending I/O, not just the immediately following call to
347	// Read or Write. After a deadline has been exceeded, the
348	// connection can be refreshed by setting a deadline in the future.
349	//
350	// If the deadline is exceeded a call to Read or Write or to other
351	// I/O methods will return an error that wraps os.ErrDeadlineExceeded.
352	// This can be tested using errors.Is(err, os.ErrDeadlineExceeded).
353	// The error's Timeout method will return true, but note that there
354	// are other possible errors for which the Timeout method will
355	// return true even if the deadline has not been exceeded.
356	//
357	// An idle timeout can be implemented by repeatedly extending
358	// the deadline after successful ReadFrom or WriteTo calls.
359	//
360	// A zero value for t means I/O operations will not time out.
361	SetDeadline(t time.Time) error
362
363	// SetReadDeadline sets the deadline for future ReadFrom calls
364	// and any currently-blocked ReadFrom call.
365	// A zero value for t means ReadFrom will not time out.
366	SetReadDeadline(t time.Time) error
367
368	// SetWriteDeadline sets the deadline for future WriteTo calls
369	// and any currently-blocked WriteTo call.
370	// Even if write times out, it may return n > 0, indicating that
371	// some of the data was successfully written.
372	// A zero value for t means WriteTo will not time out.
373	SetWriteDeadline(t time.Time) error
374}
375
376var listenerBacklogCache struct {
377	sync.Once
378	val int
379}
380
381// listenerBacklog is a caching wrapper around maxListenerBacklog.
382//
383// listenerBacklog should be an internal detail,
384// but widely used packages access it using linkname.
385// Notable members of the hall of shame include:
386//   - github.com/database64128/tfo-go/v2
387//   - github.com/metacubex/tfo-go
388//   - github.com/sagernet/tfo-go
389//
390// Do not remove or change the type signature.
391// See go.dev/issue/67401.
392//
393//go:linkname listenerBacklog
394func listenerBacklog() int {
395	listenerBacklogCache.Do(func() { listenerBacklogCache.val = maxListenerBacklog() })
396	return listenerBacklogCache.val
397}
398
399// A Listener is a generic network listener for stream-oriented protocols.
400//
401// Multiple goroutines may invoke methods on a Listener simultaneously.
402type Listener interface {
403	// Accept waits for and returns the next connection to the listener.
404	Accept() (Conn, error)
405
406	// Close closes the listener.
407	// Any blocked Accept operations will be unblocked and return errors.
408	Close() error
409
410	// Addr returns the listener's network address.
411	Addr() Addr
412}
413
414// An Error represents a network error.
415type Error interface {
416	error
417	Timeout() bool // Is the error a timeout?
418
419	// Deprecated: Temporary errors are not well-defined.
420	// Most "temporary" errors are timeouts, and the few exceptions are surprising.
421	// Do not use this method.
422	Temporary() bool
423}
424
425// Various errors contained in OpError.
426var (
427	// For connection setup operations.
428	errNoSuitableAddress = errors.New("no suitable address found")
429
430	// For connection setup and write operations.
431	errMissingAddress = errors.New("missing address")
432
433	// For both read and write operations.
434	errCanceled         = canceledError{}
435	ErrWriteToConnected = errors.New("use of WriteTo with pre-connected connection")
436)
437
438// canceledError lets us return the same error string we have always
439// returned, while still being Is context.Canceled.
440type canceledError struct{}
441
442func (canceledError) Error() string { return "operation was canceled" }
443
444func (canceledError) Is(err error) bool { return err == context.Canceled }
445
446// mapErr maps from the context errors to the historical internal net
447// error values.
448func mapErr(err error) error {
449	switch err {
450	case context.Canceled:
451		return errCanceled
452	case context.DeadlineExceeded:
453		return errTimeout
454	default:
455		return err
456	}
457}
458
459// OpError is the error type usually returned by functions in the net
460// package. It describes the operation, network type, and address of
461// an error.
462type OpError struct {
463	// Op is the operation which caused the error, such as
464	// "read" or "write".
465	Op string
466
467	// Net is the network type on which this error occurred,
468	// such as "tcp" or "udp6".
469	Net string
470
471	// For operations involving a remote network connection, like
472	// Dial, Read, or Write, Source is the corresponding local
473	// network address.
474	Source Addr
475
476	// Addr is the network address for which this error occurred.
477	// For local operations, like Listen or SetDeadline, Addr is
478	// the address of the local endpoint being manipulated.
479	// For operations involving a remote network connection, like
480	// Dial, Read, or Write, Addr is the remote address of that
481	// connection.
482	Addr Addr
483
484	// Err is the error that occurred during the operation.
485	// The Error method panics if the error is nil.
486	Err error
487}
488
489func (e *OpError) Unwrap() error { return e.Err }
490
491func (e *OpError) Error() string {
492	if e == nil {
493		return "<nil>"
494	}
495	s := e.Op
496	if e.Net != "" {
497		s += " " + e.Net
498	}
499	if e.Source != nil {
500		s += " " + e.Source.String()
501	}
502	if e.Addr != nil {
503		if e.Source != nil {
504			s += "->"
505		} else {
506			s += " "
507		}
508		s += e.Addr.String()
509	}
510	s += ": " + e.Err.Error()
511	return s
512}
513
514var (
515	// aLongTimeAgo is a non-zero time, far in the past, used for
516	// immediate cancellation of dials.
517	aLongTimeAgo = time.Unix(1, 0)
518
519	// noDeadline and noCancel are just zero values for
520	// readability with functions taking too many parameters.
521	noDeadline = time.Time{}
522	noCancel   = (chan struct{})(nil)
523)
524
525type timeout interface {
526	Timeout() bool
527}
528
529func (e *OpError) Timeout() bool {
530	if ne, ok := e.Err.(*os.SyscallError); ok {
531		t, ok := ne.Err.(timeout)
532		return ok && t.Timeout()
533	}
534	t, ok := e.Err.(timeout)
535	return ok && t.Timeout()
536}
537
538type temporary interface {
539	Temporary() bool
540}
541
542func (e *OpError) Temporary() bool {
543	// Treat ECONNRESET and ECONNABORTED as temporary errors when
544	// they come from calling accept. See issue 6163.
545	if e.Op == "accept" && isConnError(e.Err) {
546		return true
547	}
548
549	if ne, ok := e.Err.(*os.SyscallError); ok {
550		t, ok := ne.Err.(temporary)
551		return ok && t.Temporary()
552	}
553	t, ok := e.Err.(temporary)
554	return ok && t.Temporary()
555}
556
557// A ParseError is the error type of literal network address parsers.
558type ParseError struct {
559	// Type is the type of string that was expected, such as
560	// "IP address", "CIDR address".
561	Type string
562
563	// Text is the malformed text string.
564	Text string
565}
566
567func (e *ParseError) Error() string { return "invalid " + e.Type + ": " + e.Text }
568
569func (e *ParseError) Timeout() bool   { return false }
570func (e *ParseError) Temporary() bool { return false }
571
572type AddrError struct {
573	Err  string
574	Addr string
575}
576
577func (e *AddrError) Error() string {
578	if e == nil {
579		return "<nil>"
580	}
581	s := e.Err
582	if e.Addr != "" {
583		s = "address " + e.Addr + ": " + s
584	}
585	return s
586}
587
588func (e *AddrError) Timeout() bool   { return false }
589func (e *AddrError) Temporary() bool { return false }
590
591type UnknownNetworkError string
592
593func (e UnknownNetworkError) Error() string   { return "unknown network " + string(e) }
594func (e UnknownNetworkError) Timeout() bool   { return false }
595func (e UnknownNetworkError) Temporary() bool { return false }
596
597type InvalidAddrError string
598
599func (e InvalidAddrError) Error() string   { return string(e) }
600func (e InvalidAddrError) Timeout() bool   { return false }
601func (e InvalidAddrError) Temporary() bool { return false }
602
603// errTimeout exists to return the historical "i/o timeout" string
604// for context.DeadlineExceeded. See mapErr.
605// It is also used when Dialer.Deadline is exceeded.
606// error.Is(errTimeout, context.DeadlineExceeded) returns true.
607//
608// TODO(iant): We could consider changing this to os.ErrDeadlineExceeded
609// in the future, if we make
610//
611//	errors.Is(os.ErrDeadlineExceeded, context.DeadlineExceeded)
612//
613// return true.
614var errTimeout error = &timeoutError{}
615
616type timeoutError struct{}
617
618func (e *timeoutError) Error() string   { return "i/o timeout" }
619func (e *timeoutError) Timeout() bool   { return true }
620func (e *timeoutError) Temporary() bool { return true }
621
622func (e *timeoutError) Is(err error) bool {
623	return err == context.DeadlineExceeded
624}
625
626// DNSConfigError represents an error reading the machine's DNS configuration.
627// (No longer used; kept for compatibility.)
628type DNSConfigError struct {
629	Err error
630}
631
632func (e *DNSConfigError) Unwrap() error   { return e.Err }
633func (e *DNSConfigError) Error() string   { return "error reading DNS config: " + e.Err.Error() }
634func (e *DNSConfigError) Timeout() bool   { return false }
635func (e *DNSConfigError) Temporary() bool { return false }
636
637// Various errors contained in DNSError.
638var (
639	errNoSuchHost  = &notFoundError{"no such host"}
640	errUnknownPort = &notFoundError{"unknown port"}
641)
642
643// notFoundError is a special error understood by the newDNSError function,
644// which causes a creation of a DNSError with IsNotFound field set to true.
645type notFoundError struct{ s string }
646
647func (e *notFoundError) Error() string { return e.s }
648
649// temporaryError is an error type that implements the [Error] interface.
650// It returns true from the Temporary method.
651type temporaryError struct{ s string }
652
653func (e *temporaryError) Error() string   { return e.s }
654func (e *temporaryError) Temporary() bool { return true }
655func (e *temporaryError) Timeout() bool   { return false }
656
657// DNSError represents a DNS lookup error.
658type DNSError struct {
659	UnwrapErr   error  // error returned by the [DNSError.Unwrap] method, might be nil
660	Err         string // description of the error
661	Name        string // name looked for
662	Server      string // server used
663	IsTimeout   bool   // if true, timed out; not all timeouts set this
664	IsTemporary bool   // if true, error is temporary; not all errors set this
665
666	// IsNotFound is set to true when the requested name does not
667	// contain any records of the requested type (data not found),
668	// or the name itself was not found (NXDOMAIN).
669	IsNotFound bool
670}
671
672// newDNSError creates a new *DNSError.
673// Based on the err, it sets the UnwrapErr, IsTimeout, IsTemporary, IsNotFound fields.
674func newDNSError(err error, name, server string) *DNSError {
675	var (
676		isTimeout   bool
677		isTemporary bool
678		unwrapErr   error
679	)
680
681	if err, ok := err.(Error); ok {
682		isTimeout = err.Timeout()
683		isTemporary = err.Temporary()
684	}
685
686	// At this time, the only errors we wrap are context errors, to allow
687	// users to check for canceled/timed out requests.
688	if errors.Is(err, context.DeadlineExceeded) || errors.Is(err, context.Canceled) {
689		unwrapErr = err
690	}
691
692	_, isNotFound := err.(*notFoundError)
693	return &DNSError{
694		UnwrapErr:   unwrapErr,
695		Err:         err.Error(),
696		Name:        name,
697		Server:      server,
698		IsTimeout:   isTimeout,
699		IsTemporary: isTemporary,
700		IsNotFound:  isNotFound,
701	}
702}
703
704// Unwrap returns e.UnwrapErr.
705func (e *DNSError) Unwrap() error { return e.UnwrapErr }
706
707func (e *DNSError) Error() string {
708	if e == nil {
709		return "<nil>"
710	}
711	s := "lookup " + e.Name
712	if e.Server != "" {
713		s += " on " + e.Server
714	}
715	s += ": " + e.Err
716	return s
717}
718
719// Timeout reports whether the DNS lookup is known to have timed out.
720// This is not always known; a DNS lookup may fail due to a timeout
721// and return a [DNSError] for which Timeout returns false.
722func (e *DNSError) Timeout() bool { return e.IsTimeout }
723
724// Temporary reports whether the DNS error is known to be temporary.
725// This is not always known; a DNS lookup may fail due to a temporary
726// error and return a [DNSError] for which Temporary returns false.
727func (e *DNSError) Temporary() bool { return e.IsTimeout || e.IsTemporary }
728
729// errClosed exists just so that the docs for ErrClosed don't mention
730// the internal package poll.
731var errClosed = poll.ErrNetClosing
732
733// ErrClosed is the error returned by an I/O call on a network
734// connection that has already been closed, or that is closed by
735// another goroutine before the I/O is completed. This may be wrapped
736// in another error, and should normally be tested using
737// errors.Is(err, net.ErrClosed).
738var ErrClosed error = errClosed
739
740// noReadFrom can be embedded alongside another type to
741// hide the ReadFrom method of that other type.
742type noReadFrom struct{}
743
744// ReadFrom hides another ReadFrom method.
745// It should never be called.
746func (noReadFrom) ReadFrom(io.Reader) (int64, error) {
747	panic("can't happen")
748}
749
750// tcpConnWithoutReadFrom implements all the methods of *TCPConn other
751// than ReadFrom. This is used to permit ReadFrom to call io.Copy
752// without leading to a recursive call to ReadFrom.
753type tcpConnWithoutReadFrom struct {
754	noReadFrom
755	*TCPConn
756}
757
758// Fallback implementation of io.ReaderFrom's ReadFrom, when sendfile isn't
759// applicable.
760func genericReadFrom(c *TCPConn, r io.Reader) (n int64, err error) {
761	// Use wrapper to hide existing r.ReadFrom from io.Copy.
762	return io.Copy(tcpConnWithoutReadFrom{TCPConn: c}, r)
763}
764
765// noWriteTo can be embedded alongside another type to
766// hide the WriteTo method of that other type.
767type noWriteTo struct{}
768
769// WriteTo hides another WriteTo method.
770// It should never be called.
771func (noWriteTo) WriteTo(io.Writer) (int64, error) {
772	panic("can't happen")
773}
774
775// tcpConnWithoutWriteTo implements all the methods of *TCPConn other
776// than WriteTo. This is used to permit WriteTo to call io.Copy
777// without leading to a recursive call to WriteTo.
778type tcpConnWithoutWriteTo struct {
779	noWriteTo
780	*TCPConn
781}
782
783// Fallback implementation of io.WriterTo's WriteTo, when zero-copy isn't applicable.
784func genericWriteTo(c *TCPConn, w io.Writer) (n int64, err error) {
785	// Use wrapper to hide existing w.WriteTo from io.Copy.
786	return io.Copy(w, tcpConnWithoutWriteTo{TCPConn: c})
787}
788
789// Limit the number of concurrent cgo-using goroutines, because
790// each will block an entire operating system thread. The usual culprit
791// is resolving many DNS names in separate goroutines but the DNS
792// server is not responding. Then the many lookups each use a different
793// thread, and the system or the program runs out of threads.
794
795var threadLimit chan struct{}
796
797var threadOnce sync.Once
798
799func acquireThread(ctx context.Context) error {
800	threadOnce.Do(func() {
801		threadLimit = make(chan struct{}, concurrentThreadsLimit())
802	})
803	select {
804	case threadLimit <- struct{}{}:
805		return nil
806	case <-ctx.Done():
807		return ctx.Err()
808	}
809}
810
811func releaseThread() {
812	<-threadLimit
813}
814
815// buffersWriter is the interface implemented by Conns that support a
816// "writev"-like batch write optimization.
817// writeBuffers should fully consume and write all chunks from the
818// provided Buffers, else it should report a non-nil error.
819type buffersWriter interface {
820	writeBuffers(*Buffers) (int64, error)
821}
822
823// Buffers contains zero or more runs of bytes to write.
824//
825// On certain machines, for certain types of connections, this is
826// optimized into an OS-specific batch write operation (such as
827// "writev").
828type Buffers [][]byte
829
830var (
831	_ io.WriterTo = (*Buffers)(nil)
832	_ io.Reader   = (*Buffers)(nil)
833)
834
835// WriteTo writes contents of the buffers to w.
836//
837// WriteTo implements [io.WriterTo] for [Buffers].
838//
839// WriteTo modifies the slice v as well as v[i] for 0 <= i < len(v),
840// but does not modify v[i][j] for any i, j.
841func (v *Buffers) WriteTo(w io.Writer) (n int64, err error) {
842	if wv, ok := w.(buffersWriter); ok {
843		return wv.writeBuffers(v)
844	}
845	for _, b := range *v {
846		nb, err := w.Write(b)
847		n += int64(nb)
848		if err != nil {
849			v.consume(n)
850			return n, err
851		}
852	}
853	v.consume(n)
854	return n, nil
855}
856
857// Read from the buffers.
858//
859// Read implements [io.Reader] for [Buffers].
860//
861// Read modifies the slice v as well as v[i] for 0 <= i < len(v),
862// but does not modify v[i][j] for any i, j.
863func (v *Buffers) Read(p []byte) (n int, err error) {
864	for len(p) > 0 && len(*v) > 0 {
865		n0 := copy(p, (*v)[0])
866		v.consume(int64(n0))
867		p = p[n0:]
868		n += n0
869	}
870	if len(*v) == 0 {
871		err = io.EOF
872	}
873	return
874}
875
876func (v *Buffers) consume(n int64) {
877	for len(*v) > 0 {
878		ln0 := int64(len((*v)[0]))
879		if ln0 > n {
880			(*v)[0] = (*v)[0][n:]
881			return
882		}
883		n -= ln0
884		(*v)[0] = nil
885		*v = (*v)[1:]
886	}
887}
888