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