github.com/epfl-dcsl/gotee@v0.0.0-20200909122901-014b35f5e5e9/src/gnet/net.go (about) 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 := gnet.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 := gnet.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 By default the pure Go resolver is used, because a blocked DNS request consumes 50 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, and when the name being looked up ends in .local 58 or is an mDNS name. 59 60 The resolver decision can be overridden by setting the netdns value of the 61 GODEBUG environment variable (see package runtime) to go or cgo, as in: 62 63 export GODEBUG=netdns=go # force pure Go resolver 64 export GODEBUG=netdns=cgo # force cgo resolver 65 66 The decision can also be forced while building the Go source tree 67 by setting the netgo or netcgo build tag. 68 69 A numeric netdns setting, as in GODEBUG=netdns=1, causes the resolver 70 to print debugging information about its decisions. 71 To force a particular resolver while also printing debugging information, 72 join the two settings by a plus sign, as in GODEBUG=netdns=go+1. 73 74 On Plan 9, the resolver always accesses /net/cs and /net/dns. 75 76 On Windows, the resolver always uses C library functions, such as GetAddrInfo and DnsQuery. 77 78 */ 79 package gnet 80 81 import ( 82 "context" 83 "errors" 84 "internal/poll" 85 "io" 86 "os" 87 "syscall" 88 "time" 89 ) 90 91 // netGo and netCgo contain the state of the build tags used 92 // to build this binary, and whether cgo is available. 93 // conf.go mirrors these into conf for easier testing. 94 var ( 95 netGo bool // set true in cgo_stub.go for build tag "gnetgo" (or no cgo) 96 netCgo bool // set true in conf_netcgo.go for build tag "gnetcgo" 97 ) 98 99 // Addr represents a network end point address. 100 // 101 // The two methods Network and String conventionally return strings 102 // that can be passed as the arguments to Dial, but the exact form 103 // and meaning of the strings is up to the implementation. 104 type Addr interface { 105 Network() string // name of the network (for example, "tcp", "udp") 106 String() string // string form of address (for example, "192.0.2.1:25", "[2001:db8::1]:80") 107 } 108 109 // Conn is a generic stream-oriented network connection. 110 // 111 // Multiple goroutines may invoke methods on a Conn simultaneously. 112 type Conn interface { 113 // Read reads data from the connection. 114 // Read can be made to time out and return an Error with Timeout() == true 115 // after a fixed time limit; see SetDeadline and SetReadDeadline. 116 Read(b []byte) (n int, err error) 117 118 // Write writes data to the connection. 119 // Write can be made to time out and return an Error with Timeout() == true 120 // after a fixed time limit; see SetDeadline and SetWriteDeadline. 121 Write(b []byte) (n int, err error) 122 123 // Close closes the connection. 124 // Any blocked Read or Write operations will be unblocked and return errors. 125 Close() error 126 127 // LocalAddr returns the local network address. 128 LocalAddr() Addr 129 130 // RemoteAddr returns the remote network address. 131 RemoteAddr() Addr 132 133 // SetDeadline sets the read and write deadlines associated 134 // with the connection. It is equivalent to calling both 135 // SetReadDeadline and SetWriteDeadline. 136 // 137 // A deadline is an absolute time after which I/O operations 138 // fail with a timeout (see type Error) instead of 139 // blocking. The deadline applies to all future and pending 140 // I/O, not just the immediately following call to Read or 141 // Write. After a deadline has been exceeded, the connection 142 // can be refreshed by setting a deadline in the future. 143 // 144 // An idle timeout can be implemented by repeatedly extending 145 // the deadline after successful Read or Write calls. 146 // 147 // A zero value for t means I/O operations will not time out. 148 SetDeadline(t time.Time) error 149 150 // SetReadDeadline sets the deadline for future Read calls 151 // and any currently-blocked Read call. 152 // A zero value for t means Read will not time out. 153 SetReadDeadline(t time.Time) error 154 155 // SetWriteDeadline sets the deadline for future Write calls 156 // and any currently-blocked Write call. 157 // Even if write times out, it may return n > 0, indicating that 158 // some of the data was successfully written. 159 // A zero value for t means Write will not time out. 160 SetWriteDeadline(t time.Time) error 161 } 162 163 type conn struct { 164 fd *netFD 165 } 166 167 func (c *conn) ok() bool { return c != nil && c.fd != nil } 168 169 // Implementation of the Conn interface. 170 171 // Read implements the Conn Read method. 172 func (c *conn) Read(b []byte) (int, error) { 173 if !c.ok() { 174 return 0, syscall.EINVAL 175 } 176 n, err := c.fd.Read(b) 177 if err != nil && err != io.EOF { 178 err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err} 179 } 180 return n, err 181 } 182 183 // Write implements the Conn Write method. 184 func (c *conn) Write(b []byte) (int, error) { 185 if !c.ok() { 186 return 0, syscall.EINVAL 187 } 188 n, err := c.fd.Write(b) 189 if err != nil { 190 err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err} 191 } 192 return n, err 193 } 194 195 // Close closes the connection. 196 func (c *conn) Close() error { 197 if !c.ok() { 198 return syscall.EINVAL 199 } 200 err := c.fd.Close() 201 if err != nil { 202 err = &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err} 203 } 204 return err 205 } 206 207 // LocalAddr returns the local network address. 208 // The Addr returned is shared by all invocations of LocalAddr, so 209 // do not modify it. 210 func (c *conn) LocalAddr() Addr { 211 if !c.ok() { 212 return nil 213 } 214 return c.fd.laddr 215 } 216 217 // RemoteAddr returns the remote network address. 218 // The Addr returned is shared by all invocations of RemoteAddr, so 219 // do not modify it. 220 func (c *conn) RemoteAddr() Addr { 221 if !c.ok() { 222 return nil 223 } 224 return c.fd.raddr 225 } 226 227 // SetDeadline implements the Conn SetDeadline method. 228 func (c *conn) SetDeadline(t time.Time) error { 229 if !c.ok() { 230 return syscall.EINVAL 231 } 232 if err := c.fd.pfd.SetDeadline(t); err != nil { 233 return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err} 234 } 235 return nil 236 } 237 238 // SetReadDeadline implements the Conn SetReadDeadline method. 239 func (c *conn) SetReadDeadline(t time.Time) error { 240 if !c.ok() { 241 return syscall.EINVAL 242 } 243 if err := c.fd.pfd.SetReadDeadline(t); err != nil { 244 return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err} 245 } 246 return nil 247 } 248 249 // SetWriteDeadline implements the Conn SetWriteDeadline method. 250 func (c *conn) SetWriteDeadline(t time.Time) error { 251 if !c.ok() { 252 return syscall.EINVAL 253 } 254 if err := c.fd.pfd.SetWriteDeadline(t); err != nil { 255 return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err} 256 } 257 return nil 258 } 259 260 // SetReadBuffer sets the size of the operating system's 261 // receive buffer associated with the connection. 262 func (c *conn) SetReadBuffer(bytes int) error { 263 if !c.ok() { 264 return syscall.EINVAL 265 } 266 if err := setReadBuffer(c.fd, bytes); err != nil { 267 return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err} 268 } 269 return nil 270 } 271 272 // SetWriteBuffer sets the size of the operating system's 273 // transmit buffer associated with the connection. 274 func (c *conn) SetWriteBuffer(bytes int) error { 275 if !c.ok() { 276 return syscall.EINVAL 277 } 278 if err := setWriteBuffer(c.fd, bytes); err != nil { 279 return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err} 280 } 281 return nil 282 } 283 284 // File sets the underlying os.File to blocking mode and returns a copy. 285 // It is the caller's responsibility to close f when finished. 286 // Closing c does not affect f, and closing f does not affect c. 287 // 288 // The returned os.File's file descriptor is different from the connection's. 289 // Attempting to change properties of the original using this duplicate 290 // may or may not have the desired effect. 291 // 292 // On Unix systems this will cause the SetDeadline methods to stop working. 293 func (c *conn) File() (f *os.File, err error) { 294 f, err = c.fd.dup() 295 if err != nil { 296 err = &OpError{Op: "file", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err} 297 } 298 return 299 } 300 301 // PacketConn is a generic packet-oriented network connection. 302 // 303 // Multiple goroutines may invoke methods on a PacketConn simultaneously. 304 type PacketConn interface { 305 // ReadFrom reads a packet from the connection, 306 // copying the payload into b. It returns the number of 307 // bytes copied into b and the return address that 308 // was on the packet. 309 // ReadFrom can be made to time out and return 310 // an Error with Timeout() == true after a fixed time limit; 311 // see SetDeadline and SetReadDeadline. 312 ReadFrom(b []byte) (n int, addr Addr, err error) 313 314 // WriteTo writes a packet with payload b to addr. 315 // WriteTo can be made to time out and return 316 // an Error with Timeout() == true after a fixed time limit; 317 // see SetDeadline and SetWriteDeadline. 318 // On packet-oriented connections, write timeouts are rare. 319 WriteTo(b []byte, addr Addr) (n int, err error) 320 321 // Close closes the connection. 322 // Any blocked ReadFrom or WriteTo operations will be unblocked and return errors. 323 Close() error 324 325 // LocalAddr returns the local network address. 326 LocalAddr() Addr 327 328 // SetDeadline sets the read and write deadlines associated 329 // with the connection. It is equivalent to calling both 330 // SetReadDeadline and SetWriteDeadline. 331 // 332 // A deadline is an absolute time after which I/O operations 333 // fail with a timeout (see type Error) instead of 334 // blocking. The deadline applies to all future and pending 335 // I/O, not just the immediately following call to ReadFrom or 336 // WriteTo. After a deadline has been exceeded, the connection 337 // can be refreshed by setting a deadline in the future. 338 // 339 // An idle timeout can be implemented by repeatedly extending 340 // the deadline after successful ReadFrom or WriteTo calls. 341 // 342 // A zero value for t means I/O operations will not time out. 343 SetDeadline(t time.Time) error 344 345 // SetReadDeadline sets the deadline for future ReadFrom calls 346 // and any currently-blocked ReadFrom call. 347 // A zero value for t means ReadFrom will not time out. 348 SetReadDeadline(t time.Time) error 349 350 // SetWriteDeadline sets the deadline for future WriteTo calls 351 // and any currently-blocked WriteTo call. 352 // Even if write times out, it may return n > 0, indicating that 353 // some of the data was successfully written. 354 // A zero value for t means WriteTo will not time out. 355 SetWriteDeadline(t time.Time) error 356 } 357 358 var listenerBacklog = maxListenerBacklog() 359 360 // A Listener is a generic network listener for stream-oriented protocols. 361 // 362 // Multiple goroutines may invoke methods on a Listener simultaneously. 363 type Listener interface { 364 // Accept waits for and returns the next connection to the listener. 365 Accept() (Conn, error) 366 367 // Close closes the listener. 368 // Any blocked Accept operations will be unblocked and return errors. 369 Close() error 370 371 // Addr returns the listener's network address. 372 Addr() Addr 373 } 374 375 // An Error represents a network error. 376 type Error interface { 377 error 378 Timeout() bool // Is the error a timeout? 379 Temporary() bool // Is the error temporary? 380 } 381 382 // Various errors contained in OpError. 383 var ( 384 // For connection setup operations. 385 errNoSuitableAddress = errors.New("no suitable address found") 386 387 // For connection setup and write operations. 388 errMissingAddress = errors.New("missing address") 389 390 // For both read and write operations. 391 errCanceled = errors.New("operation was canceled") 392 ErrWriteToConnected = errors.New("use of WriteTo with pre-connected connection") 393 ) 394 395 // mapErr maps from the context errors to the historical internal net 396 // error values. 397 // 398 // TODO(bradfitz): get rid of this after adjusting tests and making 399 // context.DeadlineExceeded implement gnet.Error? 400 func mapErr(err error) error { 401 switch err { 402 case context.Canceled: 403 return errCanceled 404 case context.DeadlineExceeded: 405 return poll.ErrTimeout 406 default: 407 return err 408 } 409 } 410 411 // OpError is the error type usually returned by functions in the net 412 // package. It describes the operation, network type, and address of 413 // an error. 414 type OpError struct { 415 // Op is the operation which caused the error, such as 416 // "read" or "write". 417 Op string 418 419 // Net is the network type on which this error occurred, 420 // such as "tcp" or "udp6". 421 Net string 422 423 // For operations involving a remote network connection, like 424 // Dial, Read, or Write, Source is the corresponding local 425 // network address. 426 Source Addr 427 428 // Addr is the network address for which this error occurred. 429 // For local operations, like Listen or SetDeadline, Addr is 430 // the address of the local endpoint being manipulated. 431 // For operations involving a remote network connection, like 432 // Dial, Read, or Write, Addr is the remote address of that 433 // connection. 434 Addr Addr 435 436 // Err is the error that occurred during the operation. 437 Err error 438 } 439 440 func (e *OpError) Error() string { 441 if e == nil { 442 return "<nil>" 443 } 444 s := e.Op 445 if e.Net != "" { 446 s += " " + e.Net 447 } 448 if e.Source != nil { 449 s += " " + e.Source.String() 450 } 451 if e.Addr != nil { 452 if e.Source != nil { 453 s += "->" 454 } else { 455 s += " " 456 } 457 s += e.Addr.String() 458 } 459 s += ": " + e.Err.Error() 460 return s 461 } 462 463 var ( 464 // aLongTimeAgo is a non-zero time, far in the past, used for 465 // immediate cancelation of dials. 466 aLongTimeAgo = time.Unix(1, 0) 467 468 // nonDeadline and noCancel are just zero values for 469 // readability with functions taking too many parameters. 470 noDeadline = time.Time{} 471 noCancel = (chan struct{})(nil) 472 ) 473 474 type timeout interface { 475 Timeout() bool 476 } 477 478 func (e *OpError) Timeout() bool { 479 if ne, ok := e.Err.(*os.SyscallError); ok { 480 t, ok := ne.Err.(timeout) 481 return ok && t.Timeout() 482 } 483 t, ok := e.Err.(timeout) 484 return ok && t.Timeout() 485 } 486 487 type temporary interface { 488 Temporary() bool 489 } 490 491 func (e *OpError) Temporary() bool { 492 if ne, ok := e.Err.(*os.SyscallError); ok { 493 t, ok := ne.Err.(temporary) 494 return ok && t.Temporary() 495 } 496 t, ok := e.Err.(temporary) 497 return ok && t.Temporary() 498 } 499 500 // A ParseError is the error type of literal network address parsers. 501 type ParseError struct { 502 // Type is the type of string that was expected, such as 503 // "IP address", "CIDR address". 504 Type string 505 506 // Text is the malformed text string. 507 Text string 508 } 509 510 func (e *ParseError) Error() string { return "invalid " + e.Type + ": " + e.Text } 511 512 type AddrError struct { 513 Err string 514 Addr string 515 } 516 517 func (e *AddrError) Error() string { 518 if e == nil { 519 return "<nil>" 520 } 521 s := e.Err 522 if e.Addr != "" { 523 s = "address " + e.Addr + ": " + s 524 } 525 return s 526 } 527 528 func (e *AddrError) Timeout() bool { return false } 529 func (e *AddrError) Temporary() bool { return false } 530 531 type UnknownNetworkError string 532 533 func (e UnknownNetworkError) Error() string { return "unknown network " + string(e) } 534 func (e UnknownNetworkError) Timeout() bool { return false } 535 func (e UnknownNetworkError) Temporary() bool { return false } 536 537 type InvalidAddrError string 538 539 func (e InvalidAddrError) Error() string { return string(e) } 540 func (e InvalidAddrError) Timeout() bool { return false } 541 func (e InvalidAddrError) Temporary() bool { return false } 542 543 // DNSConfigError represents an error reading the machine's DNS configuration. 544 // (No longer used; kept for compatibility.) 545 type DNSConfigError struct { 546 Err error 547 } 548 549 func (e *DNSConfigError) Error() string { return "error reading DNS config: " + e.Err.Error() } 550 func (e *DNSConfigError) Timeout() bool { return false } 551 func (e *DNSConfigError) Temporary() bool { return false } 552 553 // Various errors contained in DNSError. 554 var ( 555 errNoSuchHost = errors.New("no such host") 556 ) 557 558 // DNSError represents a DNS lookup error. 559 type DNSError struct { 560 Err string // description of the error 561 Name string // name looked for 562 Server string // server used 563 IsTimeout bool // if true, timed out; not all timeouts set this 564 IsTemporary bool // if true, error is temporary; not all errors set this 565 } 566 567 func (e *DNSError) Error() string { 568 if e == nil { 569 return "<nil>" 570 } 571 s := "lookup " + e.Name 572 if e.Server != "" { 573 s += " on " + e.Server 574 } 575 s += ": " + e.Err 576 return s 577 } 578 579 // Timeout reports whether the DNS lookup is known to have timed out. 580 // This is not always known; a DNS lookup may fail due to a timeout 581 // and return a DNSError for which Timeout returns false. 582 func (e *DNSError) Timeout() bool { return e.IsTimeout } 583 584 // Temporary reports whether the DNS error is known to be temporary. 585 // This is not always known; a DNS lookup may fail due to a temporary 586 // error and return a DNSError for which Temporary returns false. 587 func (e *DNSError) Temporary() bool { return e.IsTimeout || e.IsTemporary } 588 589 type writerOnly struct { 590 io.Writer 591 } 592 593 // Fallback implementation of io.ReaderFrom's ReadFrom, when sendfile isn't 594 // applicable. 595 func genericReadFrom(w io.Writer, r io.Reader) (n int64, err error) { 596 // Use wrapper to hide existing r.ReadFrom from io.Copy. 597 return io.Copy(writerOnly{w}, r) 598 } 599 600 // Limit the number of concurrent cgo-using goroutines, because 601 // each will block an entire operating system thread. The usual culprit 602 // is resolving many DNS names in separate goroutines but the DNS 603 // server is not responding. Then the many lookups each use a different 604 // thread, and the system or the program runs out of threads. 605 606 var threadLimit = make(chan struct{}, 500) 607 608 func acquireThread() { 609 threadLimit <- struct{}{} 610 } 611 612 func releaseThread() { 613 <-threadLimit 614 } 615 616 // buffersWriter is the interface implemented by Conns that support a 617 // "writev"-like batch write optimization. 618 // writeBuffers should fully consume and write all chunks from the 619 // provided Buffers, else it should report a non-nil error. 620 type buffersWriter interface { 621 writeBuffers(*Buffers) (int64, error) 622 } 623 624 // Buffers contains zero or more runs of bytes to write. 625 // 626 // On certain machines, for certain types of connections, this is 627 // optimized into an OS-specific batch write operation (such as 628 // "writev"). 629 type Buffers [][]byte 630 631 var ( 632 _ io.WriterTo = (*Buffers)(nil) 633 _ io.Reader = (*Buffers)(nil) 634 ) 635 636 func (v *Buffers) WriteTo(w io.Writer) (n int64, err error) { 637 if wv, ok := w.(buffersWriter); ok { 638 return wv.writeBuffers(v) 639 } 640 for _, b := range *v { 641 nb, err := w.Write(b) 642 n += int64(nb) 643 if err != nil { 644 v.consume(n) 645 return n, err 646 } 647 } 648 v.consume(n) 649 return n, nil 650 } 651 652 func (v *Buffers) Read(p []byte) (n int, err error) { 653 for len(p) > 0 && len(*v) > 0 { 654 n0 := copy(p, (*v)[0]) 655 v.consume(int64(n0)) 656 p = p[n0:] 657 n += n0 658 } 659 if len(*v) == 0 { 660 err = io.EOF 661 } 662 return 663 } 664 665 func (v *Buffers) consume(n int64) { 666 for len(*v) > 0 { 667 ln0 := int64(len((*v)[0])) 668 if ln0 > n { 669 (*v)[0] = (*v)[0][n:] 670 return 671 } 672 n -= ln0 673 *v = (*v)[1:] 674 } 675 }