Source file src/net/net.go
1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 /* 6 Package net provides a portable interface for network I/O, including 7 TCP/IP, UDP, domain name resolution, and Unix domain sockets. 8 9 Although the package provides access to low-level networking 10 primitives, most clients will need only the basic interface provided 11 by the [Dial], [Listen], and Accept functions and the associated 12 [Conn] and [Listener] interfaces. The crypto/tls package uses 13 the same interfaces and similar Dial and Listen functions. 14 15 The Dial function connects to a server: 16 17 conn, err := net.Dial("tcp", "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() string // 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 = make(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