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 func (c *conn) File() (f *os.File, err error) { 312 f, err = c.fd.dup() 313 if err != nil { 314 err = &OpError{Op: "file", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err} 315 } 316 return 317 } 318 319 // PacketConn is a generic packet-oriented network connection. 320 // 321 // Multiple goroutines may invoke methods on a PacketConn simultaneously. 322 type PacketConn interface { 323 // ReadFrom reads a packet from the connection, 324 // copying the payload into p. It returns the number of 325 // bytes copied into p and the return address that 326 // was on the packet. 327 // It returns the number of bytes read (0 <= n <= len(p)) 328 // and any error encountered. Callers should always process 329 // the n > 0 bytes returned before considering the error err. 330 // ReadFrom can be made to time out and return an error after a 331 // fixed time limit; see SetDeadline and SetReadDeadline. 332 ReadFrom(p []byte) (n int, addr Addr, err error) 333 334 // WriteTo writes a packet with payload p to addr. 335 // WriteTo can be made to time out and return an Error after a 336 // fixed time limit; see SetDeadline and SetWriteDeadline. 337 // On packet-oriented connections, write timeouts are rare. 338 WriteTo(p []byte, addr Addr) (n int, err error) 339 340 // Close closes the connection. 341 // Any blocked ReadFrom or WriteTo operations will be unblocked and return errors. 342 Close() error 343 344 // LocalAddr returns the local network address, if known. 345 LocalAddr() Addr 346 347 // SetDeadline sets the read and write deadlines associated 348 // with the connection. It is equivalent to calling both 349 // SetReadDeadline and SetWriteDeadline. 350 // 351 // A deadline is an absolute time after which I/O operations 352 // fail instead of blocking. The deadline applies to all future 353 // and pending I/O, not just the immediately following call to 354 // Read or Write. After a deadline has been exceeded, the 355 // connection can be refreshed by setting a deadline in the future. 356 // 357 // If the deadline is exceeded a call to Read or Write or to other 358 // I/O methods will return an error that wraps os.ErrDeadlineExceeded. 359 // This can be tested using errors.Is(err, os.ErrDeadlineExceeded). 360 // The error's Timeout method will return true, but note that there 361 // are other possible errors for which the Timeout method will 362 // return true even if the deadline has not been exceeded. 363 // 364 // An idle timeout can be implemented by repeatedly extending 365 // the deadline after successful ReadFrom or WriteTo calls. 366 // 367 // A zero value for t means I/O operations will not time out. 368 SetDeadline(t time.Time) error 369 370 // SetReadDeadline sets the deadline for future ReadFrom calls 371 // and any currently-blocked ReadFrom call. 372 // A zero value for t means ReadFrom will not time out. 373 SetReadDeadline(t time.Time) error 374 375 // SetWriteDeadline sets the deadline for future WriteTo calls 376 // and any currently-blocked WriteTo call. 377 // Even if write times out, it may return n > 0, indicating that 378 // some of the data was successfully written. 379 // A zero value for t means WriteTo will not time out. 380 SetWriteDeadline(t time.Time) error 381 } 382 383 var listenerBacklogCache struct { 384 sync.Once 385 val int 386 } 387 388 // listenerBacklog is a caching wrapper around maxListenerBacklog. 389 // 390 // listenerBacklog should be an internal detail, 391 // but widely used packages access it using linkname. 392 // Notable members of the hall of shame include: 393 // - github.com/database64128/tfo-go/v2 394 // - github.com/metacubex/tfo-go 395 // - github.com/sagernet/tfo-go 396 // 397 // Do not remove or change the type signature. 398 // See go.dev/issue/67401. 399 // 400 //go:linkname listenerBacklog 401 func listenerBacklog() int { 402 listenerBacklogCache.Do(func() { listenerBacklogCache.val = maxListenerBacklog() }) 403 return listenerBacklogCache.val 404 } 405 406 // A Listener is a generic network listener for stream-oriented protocols. 407 // 408 // Multiple goroutines may invoke methods on a Listener simultaneously. 409 type Listener interface { 410 // Accept waits for and returns the next connection to the listener. 411 Accept() (Conn, error) 412 413 // Close closes the listener. 414 // Any blocked Accept operations will be unblocked and return errors. 415 Close() error 416 417 // Addr returns the listener's network address. 418 Addr() Addr 419 } 420 421 // An Error represents a network error. 422 type Error interface { 423 error 424 Timeout() bool // Is the error a timeout? 425 426 // Deprecated: Temporary errors are not well-defined. 427 // Most "temporary" errors are timeouts, and the few exceptions are surprising. 428 // Do not use this method. 429 Temporary() bool 430 } 431 432 // Various errors contained in OpError. 433 var ( 434 // For connection setup operations. 435 errNoSuitableAddress = errors.New("no suitable address found") 436 437 // For connection setup and write operations. 438 errMissingAddress = errors.New("missing address") 439 440 // For both read and write operations. 441 errCanceled = canceledError{} 442 ErrWriteToConnected = errors.New("use of WriteTo with pre-connected connection") 443 ) 444 445 // canceledError lets us return the same error string we have always 446 // returned, while still being Is context.Canceled. 447 type canceledError struct{} 448 449 func (canceledError) Error() string { return "operation was canceled" } 450 451 func (canceledError) Is(err error) bool { return err == context.Canceled } 452 453 // mapErr maps from the context errors to the historical internal net 454 // error values. 455 func mapErr(err error) error { 456 switch err { 457 case context.Canceled: 458 return errCanceled 459 case context.DeadlineExceeded: 460 return errTimeout 461 default: 462 return err 463 } 464 } 465 466 // OpError is the error type usually returned by functions in the net 467 // package. It describes the operation, network type, and address of 468 // an error. 469 type OpError struct { 470 // Op is the operation which caused the error, such as 471 // "read" or "write". 472 Op string 473 474 // Net is the network type on which this error occurred, 475 // such as "tcp" or "udp6". 476 Net string 477 478 // For operations involving a remote network connection, like 479 // Dial, Read, or Write, Source is the corresponding local 480 // network address. 481 Source Addr 482 483 // Addr is the network address for which this error occurred. 484 // For local operations, like Listen or SetDeadline, Addr is 485 // the address of the local endpoint being manipulated. 486 // For operations involving a remote network connection, like 487 // Dial, Read, or Write, Addr is the remote address of that 488 // connection. 489 Addr Addr 490 491 // Err is the error that occurred during the operation. 492 // The Error method panics if the error is nil. 493 Err error 494 } 495 496 func (e *OpError) Unwrap() error { return e.Err } 497 498 func (e *OpError) Error() string { 499 if e == nil { 500 return "<nil>" 501 } 502 s := e.Op 503 if e.Net != "" { 504 s += " " + e.Net 505 } 506 if e.Source != nil { 507 s += " " + e.Source.String() 508 } 509 if e.Addr != nil { 510 if e.Source != nil { 511 s += "->" 512 } else { 513 s += " " 514 } 515 s += e.Addr.String() 516 } 517 s += ": " + e.Err.Error() 518 return s 519 } 520 521 var ( 522 // aLongTimeAgo is a non-zero time, far in the past, used for 523 // immediate cancellation of dials. 524 aLongTimeAgo = time.Unix(1, 0) 525 526 // noDeadline and noCancel are just zero values for 527 // readability with functions taking too many parameters. 528 noDeadline = time.Time{} 529 noCancel = (chan struct{})(nil) 530 ) 531 532 type timeout interface { 533 Timeout() bool 534 } 535 536 func (e *OpError) Timeout() bool { 537 if ne, ok := e.Err.(*os.SyscallError); ok { 538 t, ok := ne.Err.(timeout) 539 return ok && t.Timeout() 540 } 541 t, ok := e.Err.(timeout) 542 return ok && t.Timeout() 543 } 544 545 type temporary interface { 546 Temporary() bool 547 } 548 549 func (e *OpError) Temporary() bool { 550 // Treat ECONNRESET and ECONNABORTED as temporary errors when 551 // they come from calling accept. See issue 6163. 552 if e.Op == "accept" && isConnError(e.Err) { 553 return true 554 } 555 556 if ne, ok := e.Err.(*os.SyscallError); ok { 557 t, ok := ne.Err.(temporary) 558 return ok && t.Temporary() 559 } 560 t, ok := e.Err.(temporary) 561 return ok && t.Temporary() 562 } 563 564 // A ParseError is the error type of literal network address parsers. 565 type ParseError struct { 566 // Type is the type of string that was expected, such as 567 // "IP address", "CIDR address". 568 Type string 569 570 // Text is the malformed text string. 571 Text string 572 } 573 574 func (e *ParseError) Error() string { return "invalid " + e.Type + ": " + e.Text } 575 576 func (e *ParseError) Timeout() bool { return false } 577 func (e *ParseError) Temporary() bool { return false } 578 579 type AddrError struct { 580 Err string 581 Addr string 582 } 583 584 func (e *AddrError) Error() string { 585 if e == nil { 586 return "<nil>" 587 } 588 s := e.Err 589 if e.Addr != "" { 590 s = "address " + e.Addr + ": " + s 591 } 592 return s 593 } 594 595 func (e *AddrError) Timeout() bool { return false } 596 func (e *AddrError) Temporary() bool { return false } 597 598 type UnknownNetworkError string 599 600 func (e UnknownNetworkError) Error() string { return "unknown network " + string(e) } 601 func (e UnknownNetworkError) Timeout() bool { return false } 602 func (e UnknownNetworkError) Temporary() bool { return false } 603 604 type InvalidAddrError string 605 606 func (e InvalidAddrError) Error() string { return string(e) } 607 func (e InvalidAddrError) Timeout() bool { return false } 608 func (e InvalidAddrError) Temporary() bool { return false } 609 610 // errTimeout exists to return the historical "i/o timeout" string 611 // for context.DeadlineExceeded. See mapErr. 612 // It is also used when Dialer.Deadline is exceeded. 613 // error.Is(errTimeout, context.DeadlineExceeded) returns true. 614 // 615 // TODO(iant): We could consider changing this to os.ErrDeadlineExceeded 616 // in the future, if we make 617 // 618 // errors.Is(os.ErrDeadlineExceeded, context.DeadlineExceeded) 619 // 620 // return true. 621 var errTimeout error = &timeoutError{} 622 623 type timeoutError struct{} 624 625 func (e *timeoutError) Error() string { return "i/o timeout" } 626 func (e *timeoutError) Timeout() bool { return true } 627 func (e *timeoutError) Temporary() bool { return true } 628 629 func (e *timeoutError) Is(err error) bool { 630 return err == context.DeadlineExceeded 631 } 632 633 // DNSConfigError represents an error reading the machine's DNS configuration. 634 // (No longer used; kept for compatibility.) 635 type DNSConfigError struct { 636 Err error 637 } 638 639 func (e *DNSConfigError) Unwrap() error { return e.Err } 640 func (e *DNSConfigError) Error() string { return "error reading DNS config: " + e.Err.Error() } 641 func (e *DNSConfigError) Timeout() bool { return false } 642 func (e *DNSConfigError) Temporary() bool { return false } 643 644 // Various errors contained in DNSError. 645 var ( 646 errNoSuchHost = ¬FoundError{"no such host"} 647 errUnknownPort = ¬FoundError{"unknown port"} 648 ) 649 650 // notFoundError is a special error understood by the newDNSError function, 651 // which causes a creation of a DNSError with IsNotFound field set to true. 652 type notFoundError struct{ s string } 653 654 func (e *notFoundError) Error() string { return e.s } 655 656 // temporaryError is an error type that implements the [Error] interface. 657 // It returns true from the Temporary method. 658 type temporaryError struct{ s string } 659 660 func (e *temporaryError) Error() string { return e.s } 661 func (e *temporaryError) Temporary() bool { return true } 662 func (e *temporaryError) Timeout() bool { return false } 663 664 // DNSError represents a DNS lookup error. 665 type DNSError struct { 666 UnwrapErr error // error returned by the [DNSError.Unwrap] method, might be nil 667 Err string // description of the error 668 Name string // name looked for 669 Server string // server used 670 IsTimeout bool // if true, timed out; not all timeouts set this 671 IsTemporary bool // if true, error is temporary; not all errors set this 672 673 // IsNotFound is set to true when the requested name does not 674 // contain any records of the requested type (data not found), 675 // or the name itself was not found (NXDOMAIN). 676 IsNotFound bool 677 } 678 679 // newDNSError creates a new *DNSError. 680 // Based on the err, it sets the UnwrapErr, IsTimeout, IsTemporary, IsNotFound fields. 681 func newDNSError(err error, name, server string) *DNSError { 682 var ( 683 isTimeout bool 684 isTemporary bool 685 unwrapErr error 686 ) 687 688 if err, ok := err.(Error); ok { 689 isTimeout = err.Timeout() 690 isTemporary = err.Temporary() 691 } 692 693 // At this time, the only errors we wrap are context errors, to allow 694 // users to check for canceled/timed out requests. 695 if errors.Is(err, context.DeadlineExceeded) || errors.Is(err, context.Canceled) { 696 unwrapErr = err 697 } 698 699 _, isNotFound := err.(*notFoundError) 700 return &DNSError{ 701 UnwrapErr: unwrapErr, 702 Err: err.Error(), 703 Name: name, 704 Server: server, 705 IsTimeout: isTimeout, 706 IsTemporary: isTemporary, 707 IsNotFound: isNotFound, 708 } 709 } 710 711 // Unwrap returns e.UnwrapErr. 712 func (e *DNSError) Unwrap() error { return e.UnwrapErr } 713 714 func (e *DNSError) Error() string { 715 if e == nil { 716 return "<nil>" 717 } 718 s := "lookup " + e.Name 719 if e.Server != "" { 720 s += " on " + e.Server 721 } 722 s += ": " + e.Err 723 return s 724 } 725 726 // Timeout reports whether the DNS lookup is known to have timed out. 727 // This is not always known; a DNS lookup may fail due to a timeout 728 // and return a [DNSError] for which Timeout returns false. 729 func (e *DNSError) Timeout() bool { return e.IsTimeout } 730 731 // Temporary reports whether the DNS error is known to be temporary. 732 // This is not always known; a DNS lookup may fail due to a temporary 733 // error and return a [DNSError] for which Temporary returns false. 734 func (e *DNSError) Temporary() bool { return e.IsTimeout || e.IsTemporary } 735 736 // errClosed exists just so that the docs for ErrClosed don't mention 737 // the internal package poll. 738 var errClosed = poll.ErrNetClosing 739 740 // ErrClosed is the error returned by an I/O call on a network 741 // connection that has already been closed, or that is closed by 742 // another goroutine before the I/O is completed. This may be wrapped 743 // in another error, and should normally be tested using 744 // errors.Is(err, net.ErrClosed). 745 var ErrClosed error = errClosed 746 747 // noReadFrom can be embedded alongside another type to 748 // hide the ReadFrom method of that other type. 749 type noReadFrom struct{} 750 751 // ReadFrom hides another ReadFrom method. 752 // It should never be called. 753 func (noReadFrom) ReadFrom(io.Reader) (int64, error) { 754 panic("can't happen") 755 } 756 757 // tcpConnWithoutReadFrom implements all the methods of *TCPConn other 758 // than ReadFrom. This is used to permit ReadFrom to call io.Copy 759 // without leading to a recursive call to ReadFrom. 760 type tcpConnWithoutReadFrom struct { 761 noReadFrom 762 *TCPConn 763 } 764 765 // Fallback implementation of io.ReaderFrom's ReadFrom, when sendfile isn't 766 // applicable. 767 func genericReadFrom(c *TCPConn, r io.Reader) (n int64, err error) { 768 // Use wrapper to hide existing r.ReadFrom from io.Copy. 769 return io.Copy(tcpConnWithoutReadFrom{TCPConn: c}, r) 770 } 771 772 // noWriteTo can be embedded alongside another type to 773 // hide the WriteTo method of that other type. 774 type noWriteTo struct{} 775 776 // WriteTo hides another WriteTo method. 777 // It should never be called. 778 func (noWriteTo) WriteTo(io.Writer) (int64, error) { 779 panic("can't happen") 780 } 781 782 // tcpConnWithoutWriteTo implements all the methods of *TCPConn other 783 // than WriteTo. This is used to permit WriteTo to call io.Copy 784 // without leading to a recursive call to WriteTo. 785 type tcpConnWithoutWriteTo struct { 786 noWriteTo 787 *TCPConn 788 } 789 790 // Fallback implementation of io.WriterTo's WriteTo, when zero-copy isn't applicable. 791 func genericWriteTo(c *TCPConn, w io.Writer) (n int64, err error) { 792 // Use wrapper to hide existing w.WriteTo from io.Copy. 793 return io.Copy(w, tcpConnWithoutWriteTo{TCPConn: c}) 794 } 795 796 // Limit the number of concurrent cgo-using goroutines, because 797 // each will block an entire operating system thread. The usual culprit 798 // is resolving many DNS names in separate goroutines but the DNS 799 // server is not responding. Then the many lookups each use a different 800 // thread, and the system or the program runs out of threads. 801 802 var threadLimit chan struct{} 803 804 var threadOnce sync.Once 805 806 func acquireThread(ctx context.Context) error { 807 threadOnce.Do(func() { 808 threadLimit = make(chan struct{}, concurrentThreadsLimit()) 809 }) 810 select { 811 case threadLimit <- struct{}{}: 812 return nil 813 case <-ctx.Done(): 814 return ctx.Err() 815 } 816 } 817 818 func releaseThread() { 819 <-threadLimit 820 } 821 822 // buffersWriter is the interface implemented by Conns that support a 823 // "writev"-like batch write optimization. 824 // writeBuffers should fully consume and write all chunks from the 825 // provided Buffers, else it should report a non-nil error. 826 type buffersWriter interface { 827 writeBuffers(*Buffers) (int64, error) 828 } 829 830 // Buffers contains zero or more runs of bytes to write. 831 // 832 // On certain machines, for certain types of connections, this is 833 // optimized into an OS-specific batch write operation (such as 834 // "writev"). 835 type Buffers [][]byte 836 837 var ( 838 _ io.WriterTo = (*Buffers)(nil) 839 _ io.Reader = (*Buffers)(nil) 840 ) 841 842 // WriteTo writes contents of the buffers to w. 843 // 844 // WriteTo implements [io.WriterTo] for [Buffers]. 845 // 846 // WriteTo modifies the slice v as well as v[i] for 0 <= i < len(v), 847 // but does not modify v[i][j] for any i, j. 848 func (v *Buffers) WriteTo(w io.Writer) (n int64, err error) { 849 if wv, ok := w.(buffersWriter); ok { 850 return wv.writeBuffers(v) 851 } 852 for _, b := range *v { 853 nb, err := w.Write(b) 854 n += int64(nb) 855 if err != nil { 856 v.consume(n) 857 return n, err 858 } 859 } 860 v.consume(n) 861 return n, nil 862 } 863 864 // Read from the buffers. 865 // 866 // Read implements [io.Reader] for [Buffers]. 867 // 868 // Read modifies the slice v as well as v[i] for 0 <= i < len(v), 869 // but does not modify v[i][j] for any i, j. 870 func (v *Buffers) Read(p []byte) (n int, err error) { 871 for len(p) > 0 && len(*v) > 0 { 872 n0 := copy(p, (*v)[0]) 873 v.consume(int64(n0)) 874 p = p[n0:] 875 n += n0 876 } 877 if len(*v) == 0 { 878 err = io.EOF 879 } 880 return 881 } 882 883 func (v *Buffers) consume(n int64) { 884 for len(*v) > 0 { 885 ln0 := int64(len((*v)[0])) 886 if ln0 > n { 887 (*v)[0] = (*v)[0][n:] 888 return 889 } 890 n -= ln0 891 (*v)[0] = nil 892 *v = (*v)[1:] 893 } 894 } 895