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