github.com/dara-project/godist@v0.0.0-20200823115410-e0c80c8f0c78/src/net/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 := 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 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 net 80 81 import ( 82 "context" 83 "dara" 84 "errors" 85 "internal/poll" 86 "io" 87 "os" 88 "runtime" 89 "syscall" 90 "time" 91 ) 92 93 // netGo and netCgo contain the state of the build tags used 94 // to build this binary, and whether cgo is available. 95 // conf.go mirrors these into conf for easier testing. 96 var ( 97 netGo bool // set true in cgo_stub.go for build tag "netgo" (or no cgo) 98 netCgo bool // set true in conf_netcgo.go for build tag "netcgo" 99 ) 100 101 // Addr represents a network end point address. 102 // 103 // The two methods Network and String conventionally return strings 104 // that can be passed as the arguments to Dial, but the exact form 105 // and meaning of the strings is up to the implementation. 106 type Addr interface { 107 Network() string // name of the network (for example, "tcp", "udp") 108 String() string // string form of address (for example, "192.0.2.1:25", "[2001:db8::1]:80") 109 } 110 111 // Conn is a generic stream-oriented network connection. 112 // 113 // Multiple goroutines may invoke methods on a Conn simultaneously. 114 type Conn interface { 115 // Read reads data from the connection. 116 // Read can be made to time out and return an Error with Timeout() == true 117 // after a fixed time limit; see SetDeadline and SetReadDeadline. 118 Read(b []byte) (n int, err error) 119 120 // Write writes data to the connection. 121 // Write can be made to time out and return an Error with Timeout() == true 122 // after a fixed time limit; see SetDeadline and SetWriteDeadline. 123 Write(b []byte) (n int, err error) 124 125 // Close closes the connection. 126 // Any blocked Read or Write operations will be unblocked and return errors. 127 Close() error 128 129 // LocalAddr returns the local network address. 130 LocalAddr() Addr 131 132 // RemoteAddr returns the remote network address. 133 RemoteAddr() Addr 134 135 // SetDeadline sets the read and write deadlines associated 136 // with the connection. It is equivalent to calling both 137 // SetReadDeadline and SetWriteDeadline. 138 // 139 // A deadline is an absolute time after which I/O operations 140 // fail with a timeout (see type Error) instead of 141 // blocking. The deadline applies to all future and pending 142 // I/O, not just the immediately following call to Read or 143 // Write. After a deadline has been exceeded, the connection 144 // can be refreshed by setting a deadline in the future. 145 // 146 // An idle timeout can be implemented by repeatedly extending 147 // the deadline after successful Read or Write calls. 148 // 149 // A zero value for t means I/O operations will not time out. 150 SetDeadline(t time.Time) error 151 152 // SetReadDeadline sets the deadline for future Read calls 153 // and any currently-blocked Read call. 154 // A zero value for t means Read will not time out. 155 SetReadDeadline(t time.Time) error 156 157 // SetWriteDeadline sets the deadline for future Write calls 158 // and any currently-blocked Write call. 159 // Even if write times out, it may return n > 0, indicating that 160 // some of the data was successfully written. 161 // A zero value for t means Write will not time out. 162 SetWriteDeadline(t time.Time) error 163 } 164 165 type conn struct { 166 fd *netFD 167 } 168 169 func (c *conn) ok() bool { return c != nil && c.fd != nil } 170 171 // Implementation of the Conn interface. 172 173 // Read implements the Conn Read method. 174 func (c *conn) Read(b []byte) (int, error) { 175 if !c.ok() { 176 // DARA Instrumentation 177 if runtime.Is_dara_profiling_on() { 178 runtime.Dara_Debug_Print(func() { 179 print("[NET.READ] : ") 180 print(c.fd.laddr.String()) 181 print(" ") 182 println(c.fd.raddr.String()) 183 }) 184 str := c.fd.laddr.String() + c.fd.raddr.String() 185 argInfo1 := dara.GeneralType{Type: dara.CONNECTION, Integer: len(str)} 186 copy(argInfo1.String[:], str) 187 argInfo2 := dara.GeneralType{Type: dara.ARRAY, Integer: len(b)} 188 retInfo1 := dara.GeneralType{Type: dara.INTEGER, Integer: 0} 189 retInfo2 := dara.GeneralType{Type: dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL} 190 syscallInfo := dara.GeneralSyscall{dara.DSYS_NET_READ, 2, 2, [10]dara.GeneralType{argInfo1, argInfo2}, [10]dara.GeneralType{retInfo1, retInfo2}} 191 runtime.Report_Syscall_To_Scheduler(dara.DSYS_NET_READ, syscallInfo) 192 } 193 return 0, syscall.EINVAL 194 } 195 n, err := c.fd.Read(b) 196 if err != nil && err != io.EOF { 197 err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err} 198 } 199 // DARA Instrumentation 200 if runtime.Is_dara_profiling_on() { 201 runtime.Dara_Debug_Print(func() { 202 print("[NET.READ] : ") 203 print(c.fd.laddr.String()) 204 print(" ") 205 println(c.fd.raddr.String()) 206 }) 207 str := c.fd.laddr.String() + c.fd.raddr.String() 208 argInfo1 := dara.GeneralType{Type: dara.CONNECTION, Integer: len(str)} 209 copy(argInfo1.String[:], str) 210 argInfo2 := dara.GeneralType{Type: dara.ARRAY, Integer: len(b)} 211 retInfo1 := dara.GeneralType{Type: dara.INTEGER, Integer: n} 212 retInfo2 := dara.GeneralType{Type: dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL} 213 syscallInfo := dara.GeneralSyscall{dara.DSYS_NET_READ, 2, 2, [10]dara.GeneralType{argInfo1, argInfo2}, [10]dara.GeneralType{retInfo1, retInfo2}} 214 runtime.Report_Syscall_To_Scheduler(dara.DSYS_NET_READ, syscallInfo) 215 } 216 return n, err 217 } 218 219 // Write implements the Conn Write method. 220 func (c *conn) Write(b []byte) (int, error) { 221 if !c.ok() { 222 // DARA Instrumentation 223 if runtime.Is_dara_profiling_on() { 224 runtime.Dara_Debug_Print(func() { 225 print("[NET.WRITE] : ") 226 print(c.fd.laddr.String()) 227 print(" ") 228 print(c.fd.raddr.String()) 229 print(" ") 230 println(string(b[:])) 231 }) 232 str := c.fd.laddr.String() + c.fd.raddr.String() 233 argInfo1 := dara.GeneralType{Type: dara.CONNECTION, Integer: len(str)} 234 copy(argInfo1.String[:], str) 235 argInfo2 := dara.GeneralType{Type: dara.ARRAY, Integer: len(str)} 236 retInfo1 := dara.GeneralType{Type: dara.INTEGER, Integer: 0} 237 retInfo2 := dara.GeneralType{Type: dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL} 238 syscallInfo := dara.GeneralSyscall{dara.DSYS_NET_WRITE, 2, 2, [10]dara.GeneralType{argInfo1, argInfo2}, [10]dara.GeneralType{retInfo1, retInfo2}} 239 runtime.Report_Syscall_To_Scheduler(dara.DSYS_NET_WRITE, syscallInfo) 240 } 241 return 0, syscall.EINVAL 242 } 243 n, err := c.fd.Write(b) 244 if err != nil { 245 err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err} 246 } 247 // DARA Instrumentation 248 if runtime.Is_dara_profiling_on() { 249 runtime.Dara_Debug_Print(func() { 250 print("[NET.WRITE] : ") 251 print(c.fd.laddr.String()) 252 print(" ") 253 print(c.fd.raddr.String()) 254 print(" ") 255 println(string(b[:])) 256 }) 257 str := c.fd.laddr.String() + c.fd.raddr.String() 258 argInfo1 := dara.GeneralType{Type: dara.CONNECTION, Integer: len(str)} 259 copy(argInfo1.String[:], str) 260 argInfo2 := dara.GeneralType{Type: dara.ARRAY, Integer: len(str)} 261 retInfo1 := dara.GeneralType{Type: dara.INTEGER, Integer: 0} 262 retInfo2 := dara.GeneralType{Type: dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL} 263 syscallInfo := dara.GeneralSyscall{dara.DSYS_NET_WRITE, 2, 2, [10]dara.GeneralType{argInfo1, argInfo2}, [10]dara.GeneralType{retInfo1, retInfo2}} 264 runtime.Report_Syscall_To_Scheduler(dara.DSYS_NET_WRITE, syscallInfo) 265 } 266 return n, err 267 } 268 269 // Close closes the connection. 270 func (c *conn) Close() error { 271 // DARA Instrumentation 272 if runtime.Is_dara_profiling_on() { 273 runtime.Dara_Debug_Print(func() { 274 print("[NET.CLOSE] : ") 275 print(c.fd.laddr.String()) 276 print(" ") 277 println(c.fd.raddr.String()) 278 }) 279 str := c.fd.laddr.String() + c.fd.raddr.String() 280 argInfo1 := dara.GeneralType{Type: dara.CONNECTION, Integer: len(str)} 281 copy(argInfo1.String[:], str) 282 retInfo1 := dara.GeneralType{Type: dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL} 283 syscallInfo := dara.GeneralSyscall{dara.DSYS_NET_CLOSE, 1, 1, [10]dara.GeneralType{argInfo1}, [10]dara.GeneralType{retInfo1}} 284 runtime.Report_Syscall_To_Scheduler(dara.DSYS_NET_CLOSE, syscallInfo) 285 } 286 if !c.ok() { 287 return syscall.EINVAL 288 } 289 err := c.fd.Close() 290 if err != nil { 291 err = &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err} 292 } 293 return err 294 } 295 296 // LocalAddr returns the local network address. 297 // The Addr returned is shared by all invocations of LocalAddr, so 298 // do not modify it. 299 func (c *conn) LocalAddr() Addr { 300 if !c.ok() { 301 return nil 302 } 303 return c.fd.laddr 304 } 305 306 // RemoteAddr returns the remote network address. 307 // The Addr returned is shared by all invocations of RemoteAddr, so 308 // do not modify it. 309 func (c *conn) RemoteAddr() Addr { 310 if !c.ok() { 311 return nil 312 } 313 return c.fd.raddr 314 } 315 316 // SetDeadline implements the Conn SetDeadline method. 317 func (c *conn) SetDeadline(t time.Time) error { 318 // DARA Instrumentation 319 if runtime.Is_dara_profiling_on() { 320 runtime.Dara_Debug_Print(func() { 321 print("[NET.SETDEADLINE] : ") 322 print(c.fd.laddr.String()) 323 print(" ") 324 print(c.fd.raddr.String()) 325 print(" ") 326 println(t.String()) 327 }) 328 str := c.fd.laddr.String() + c.fd.raddr.String() 329 argInfo1 := dara.GeneralType{Type: dara.CONNECTION, Integer: len(str)} 330 copy(argInfo1.String[:], str) 331 argInfo2 := dara.GeneralType{Type: dara.TIME} 332 copy(argInfo2.String[:], t.String()) 333 retInfo1 := dara.GeneralType{Type: dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL} 334 syscallInfo := dara.GeneralSyscall{dara.DSYS_NET_SETDEADLINE, 1, 1, [10]dara.GeneralType{argInfo1, argInfo2}, [10]dara.GeneralType{retInfo1}} 335 runtime.Report_Syscall_To_Scheduler(dara.DSYS_NET_SETDEADLINE, syscallInfo) 336 } 337 if !c.ok() { 338 return syscall.EINVAL 339 } 340 if err := c.fd.pfd.SetDeadline(t); err != nil { 341 return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err} 342 } 343 return nil 344 } 345 346 // SetReadDeadline implements the Conn SetReadDeadline method. 347 func (c *conn) SetReadDeadline(t time.Time) error { 348 // DARA Instrumentation 349 if runtime.Is_dara_profiling_on() { 350 runtime.Dara_Debug_Print(func() { 351 print("[NET.SETREADDEADLINE] : ") 352 print(c.fd.laddr.String()) 353 print(" ") 354 print(c.fd.raddr.String()) 355 print(" ") 356 println(t.String()) 357 }) 358 str := c.fd.laddr.String() + c.fd.raddr.String() 359 argInfo1 := dara.GeneralType{Type: dara.CONNECTION, Integer: len(str)} 360 copy(argInfo1.String[:], str) 361 argInfo2 := dara.GeneralType{Type: dara.TIME} 362 copy(argInfo2.String[:], t.String()) 363 retInfo1 := dara.GeneralType{Type: dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL} 364 syscallInfo := dara.GeneralSyscall{dara.DSYS_NET_SETREADDEADLINE, 1, 1, [10]dara.GeneralType{argInfo1, argInfo2}, [10]dara.GeneralType{retInfo1}} 365 runtime.Report_Syscall_To_Scheduler(dara.DSYS_NET_SETREADDEADLINE, syscallInfo) 366 } 367 if !c.ok() { 368 return syscall.EINVAL 369 } 370 if err := c.fd.pfd.SetReadDeadline(t); err != nil { 371 return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err} 372 } 373 return nil 374 } 375 376 // SetWriteDeadline implements the Conn SetWriteDeadline method. 377 func (c *conn) SetWriteDeadline(t time.Time) error { 378 // DARA Instrumentation 379 if runtime.Is_dara_profiling_on() { 380 runtime.Dara_Debug_Print(func() { 381 print("[NET.SETWRITEDEADLINE] : ") 382 print(c.fd.laddr.String()) 383 print(" ") 384 print(c.fd.raddr.String()) 385 print(" ") 386 println(t.String()) 387 }) 388 str := c.fd.laddr.String() + c.fd.raddr.String() 389 argInfo1 := dara.GeneralType{Type: dara.CONNECTION, Integer: len(str)} 390 copy(argInfo1.String[:], str) 391 argInfo2 := dara.GeneralType{Type: dara.TIME} 392 copy(argInfo2.String[:], t.String()) 393 retInfo1 := dara.GeneralType{Type: dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL} 394 syscallInfo := dara.GeneralSyscall{dara.DSYS_NET_SETWRITEDEADLINE, 1, 1, [10]dara.GeneralType{argInfo1, argInfo2}, [10]dara.GeneralType{retInfo1}} 395 runtime.Report_Syscall_To_Scheduler(dara.DSYS_NET_SETWRITEDEADLINE, syscallInfo) 396 } 397 if !c.ok() { 398 return syscall.EINVAL 399 } 400 if err := c.fd.pfd.SetWriteDeadline(t); err != nil { 401 return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err} 402 } 403 return nil 404 } 405 406 // SetReadBuffer sets the size of the operating system's 407 // receive buffer associated with the connection. 408 func (c *conn) SetReadBuffer(bytes int) error { 409 // DARA Instrumentation 410 if runtime.Is_dara_profiling_on() { 411 runtime.Dara_Debug_Print(func() { 412 print("[NET.SETREADBUFFER] : ") 413 print(c.fd.raddr.String()) 414 print(" ") 415 println(bytes) 416 }) 417 str := c.fd.laddr.String() + c.fd.raddr.String() 418 argInfo1 := dara.GeneralType{Type: dara.CONNECTION, Integer: len(str)} 419 copy(argInfo1.String[:], str) 420 argInfo2 := dara.GeneralType{Type: dara.INTEGER, Integer: bytes} 421 retInfo1 := dara.GeneralType{Type: dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL} 422 syscallInfo := dara.GeneralSyscall{dara.DSYS_NET_SETREADBUFFER, 2, 1, [10]dara.GeneralType{argInfo1, argInfo2}, [10]dara.GeneralType{retInfo1}} 423 runtime.Report_Syscall_To_Scheduler(dara.DSYS_NET_SETREADBUFFER, syscallInfo) 424 } 425 if !c.ok() { 426 return syscall.EINVAL 427 } 428 if err := setReadBuffer(c.fd, bytes); err != nil { 429 return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err} 430 } 431 return nil 432 } 433 434 // SetWriteBuffer sets the size of the operating system's 435 // transmit buffer associated with the connection. 436 func (c *conn) SetWriteBuffer(bytes int) error { 437 // DARA Instrumentation 438 if runtime.Is_dara_profiling_on() { 439 runtime.Dara_Debug_Print(func() { 440 print("[NET.SETWRITEBUFFER] : ") 441 print(c.fd.raddr.String()) 442 print(" ") 443 println(bytes) 444 }) 445 str := c.fd.laddr.String() + c.fd.raddr.String() 446 argInfo1 := dara.GeneralType{Type: dara.CONNECTION, Integer: len(str)} 447 copy(argInfo1.String[:], str) 448 argInfo2 := dara.GeneralType{Type: dara.INTEGER, Integer: bytes} 449 retInfo1 := dara.GeneralType{Type: dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL} 450 syscallInfo := dara.GeneralSyscall{dara.DSYS_NET_SETWRITEBUFFER, 2, 1, [10]dara.GeneralType{argInfo1, argInfo2}, [10]dara.GeneralType{retInfo1}} 451 runtime.Report_Syscall_To_Scheduler(dara.DSYS_NET_SETWRITEBUFFER, syscallInfo) 452 } 453 if !c.ok() { 454 return syscall.EINVAL 455 } 456 if err := setWriteBuffer(c.fd, bytes); err != nil { 457 return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err} 458 } 459 return nil 460 } 461 462 // File sets the underlying os.File to blocking mode and returns a copy. 463 // It is the caller's responsibility to close f when finished. 464 // Closing c does not affect f, and closing f does not affect c. 465 // 466 // The returned os.File's file descriptor is different from the connection's. 467 // Attempting to change properties of the original using this duplicate 468 // may or may not have the desired effect. 469 // 470 // On Unix systems this will cause the SetDeadline methods to stop working. 471 func (c *conn) File() (f *os.File, err error) { 472 f, err = c.fd.dup() 473 if err != nil { 474 err = &OpError{Op: "file", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err} 475 } 476 return 477 } 478 479 // PacketConn is a generic packet-oriented network connection. 480 // 481 // Multiple goroutines may invoke methods on a PacketConn simultaneously. 482 type PacketConn interface { 483 // ReadFrom reads a packet from the connection, 484 // copying the payload into b. It returns the number of 485 // bytes copied into b and the return address that 486 // was on the packet. 487 // ReadFrom can be made to time out and return 488 // an Error with Timeout() == true after a fixed time limit; 489 // see SetDeadline and SetReadDeadline. 490 ReadFrom(b []byte) (n int, addr Addr, err error) 491 492 // WriteTo writes a packet with payload b to addr. 493 // WriteTo can be made to time out and return 494 // an Error with Timeout() == true after a fixed time limit; 495 // see SetDeadline and SetWriteDeadline. 496 // On packet-oriented connections, write timeouts are rare. 497 WriteTo(b []byte, addr Addr) (n int, err error) 498 499 // Close closes the connection. 500 // Any blocked ReadFrom or WriteTo operations will be unblocked and return errors. 501 Close() error 502 503 // LocalAddr returns the local network address. 504 LocalAddr() Addr 505 506 // SetDeadline sets the read and write deadlines associated 507 // with the connection. It is equivalent to calling both 508 // SetReadDeadline and SetWriteDeadline. 509 // 510 // A deadline is an absolute time after which I/O operations 511 // fail with a timeout (see type Error) instead of 512 // blocking. The deadline applies to all future and pending 513 // I/O, not just the immediately following call to ReadFrom or 514 // WriteTo. After a deadline has been exceeded, the connection 515 // can be refreshed by setting a deadline in the future. 516 // 517 // An idle timeout can be implemented by repeatedly extending 518 // the deadline after successful ReadFrom or WriteTo calls. 519 // 520 // A zero value for t means I/O operations will not time out. 521 SetDeadline(t time.Time) error 522 523 // SetReadDeadline sets the deadline for future ReadFrom calls 524 // and any currently-blocked ReadFrom call. 525 // A zero value for t means ReadFrom will not time out. 526 SetReadDeadline(t time.Time) error 527 528 // SetWriteDeadline sets the deadline for future WriteTo calls 529 // and any currently-blocked WriteTo call. 530 // Even if write times out, it may return n > 0, indicating that 531 // some of the data was successfully written. 532 // A zero value for t means WriteTo will not time out. 533 SetWriteDeadline(t time.Time) error 534 } 535 536 var listenerBacklog = maxListenerBacklog() 537 538 // A Listener is a generic network listener for stream-oriented protocols. 539 // 540 // Multiple goroutines may invoke methods on a Listener simultaneously. 541 type Listener interface { 542 // Accept waits for and returns the next connection to the listener. 543 Accept() (Conn, error) 544 545 // Close closes the listener. 546 // Any blocked Accept operations will be unblocked and return errors. 547 Close() error 548 549 // Addr returns the listener's network address. 550 Addr() Addr 551 } 552 553 // An Error represents a network error. 554 type Error interface { 555 error 556 Timeout() bool // Is the error a timeout? 557 Temporary() bool // Is the error temporary? 558 } 559 560 // Various errors contained in OpError. 561 var ( 562 // For connection setup operations. 563 errNoSuitableAddress = errors.New("no suitable address found") 564 565 // For connection setup and write operations. 566 errMissingAddress = errors.New("missing address") 567 568 // For both read and write operations. 569 errCanceled = errors.New("operation was canceled") 570 ErrWriteToConnected = errors.New("use of WriteTo with pre-connected connection") 571 ) 572 573 // mapErr maps from the context errors to the historical internal net 574 // error values. 575 // 576 // TODO(bradfitz): get rid of this after adjusting tests and making 577 // context.DeadlineExceeded implement net.Error? 578 func mapErr(err error) error { 579 switch err { 580 case context.Canceled: 581 return errCanceled 582 case context.DeadlineExceeded: 583 return poll.ErrTimeout 584 default: 585 return err 586 } 587 } 588 589 // OpError is the error type usually returned by functions in the net 590 // package. It describes the operation, network type, and address of 591 // an error. 592 type OpError struct { 593 // Op is the operation which caused the error, such as 594 // "read" or "write". 595 Op string 596 597 // Net is the network type on which this error occurred, 598 // such as "tcp" or "udp6". 599 Net string 600 601 // For operations involving a remote network connection, like 602 // Dial, Read, or Write, Source is the corresponding local 603 // network address. 604 Source Addr 605 606 // Addr is the network address for which this error occurred. 607 // For local operations, like Listen or SetDeadline, Addr is 608 // the address of the local endpoint being manipulated. 609 // For operations involving a remote network connection, like 610 // Dial, Read, or Write, Addr is the remote address of that 611 // connection. 612 Addr Addr 613 614 // Err is the error that occurred during the operation. 615 Err error 616 } 617 618 func (e *OpError) Error() string { 619 if e == nil { 620 return "<nil>" 621 } 622 s := e.Op 623 if e.Net != "" { 624 s += " " + e.Net 625 } 626 if e.Source != nil { 627 s += " " + e.Source.String() 628 } 629 if e.Addr != nil { 630 if e.Source != nil { 631 s += "->" 632 } else { 633 s += " " 634 } 635 s += e.Addr.String() 636 } 637 s += ": " + e.Err.Error() 638 return s 639 } 640 641 var ( 642 // aLongTimeAgo is a non-zero time, far in the past, used for 643 // immediate cancelation of dials. 644 aLongTimeAgo = time.Unix(1, 0) 645 646 // nonDeadline and noCancel are just zero values for 647 // readability with functions taking too many parameters. 648 noDeadline = time.Time{} 649 noCancel = (chan struct{})(nil) 650 ) 651 652 type timeout interface { 653 Timeout() bool 654 } 655 656 func (e *OpError) Timeout() bool { 657 if ne, ok := e.Err.(*os.SyscallError); ok { 658 t, ok := ne.Err.(timeout) 659 return ok && t.Timeout() 660 } 661 t, ok := e.Err.(timeout) 662 return ok && t.Timeout() 663 } 664 665 type temporary interface { 666 Temporary() bool 667 } 668 669 func (e *OpError) Temporary() bool { 670 if ne, ok := e.Err.(*os.SyscallError); ok { 671 t, ok := ne.Err.(temporary) 672 return ok && t.Temporary() 673 } 674 t, ok := e.Err.(temporary) 675 return ok && t.Temporary() 676 } 677 678 // A ParseError is the error type of literal network address parsers. 679 type ParseError struct { 680 // Type is the type of string that was expected, such as 681 // "IP address", "CIDR address". 682 Type string 683 684 // Text is the malformed text string. 685 Text string 686 } 687 688 func (e *ParseError) Error() string { return "invalid " + e.Type + ": " + e.Text } 689 690 type AddrError struct { 691 Err string 692 Addr string 693 } 694 695 func (e *AddrError) Error() string { 696 if e == nil { 697 return "<nil>" 698 } 699 s := e.Err 700 if e.Addr != "" { 701 s = "address " + e.Addr + ": " + s 702 } 703 return s 704 } 705 706 func (e *AddrError) Timeout() bool { return false } 707 func (e *AddrError) Temporary() bool { return false } 708 709 type UnknownNetworkError string 710 711 func (e UnknownNetworkError) Error() string { return "unknown network " + string(e) } 712 func (e UnknownNetworkError) Timeout() bool { return false } 713 func (e UnknownNetworkError) Temporary() bool { return false } 714 715 type InvalidAddrError string 716 717 func (e InvalidAddrError) Error() string { return string(e) } 718 func (e InvalidAddrError) Timeout() bool { return false } 719 func (e InvalidAddrError) Temporary() bool { return false } 720 721 // DNSConfigError represents an error reading the machine's DNS configuration. 722 // (No longer used; kept for compatibility.) 723 type DNSConfigError struct { 724 Err error 725 } 726 727 func (e *DNSConfigError) Error() string { return "error reading DNS config: " + e.Err.Error() } 728 func (e *DNSConfigError) Timeout() bool { return false } 729 func (e *DNSConfigError) Temporary() bool { return false } 730 731 // Various errors contained in DNSError. 732 var ( 733 errNoSuchHost = errors.New("no such host") 734 ) 735 736 // DNSError represents a DNS lookup error. 737 type DNSError struct { 738 Err string // description of the error 739 Name string // name looked for 740 Server string // server used 741 IsTimeout bool // if true, timed out; not all timeouts set this 742 IsTemporary bool // if true, error is temporary; not all errors set this 743 } 744 745 func (e *DNSError) Error() string { 746 if e == nil { 747 return "<nil>" 748 } 749 s := "lookup " + e.Name 750 if e.Server != "" { 751 s += " on " + e.Server 752 } 753 s += ": " + e.Err 754 return s 755 } 756 757 // Timeout reports whether the DNS lookup is known to have timed out. 758 // This is not always known; a DNS lookup may fail due to a timeout 759 // and return a DNSError for which Timeout returns false. 760 func (e *DNSError) Timeout() bool { return e.IsTimeout } 761 762 // Temporary reports whether the DNS error is known to be temporary. 763 // This is not always known; a DNS lookup may fail due to a temporary 764 // error and return a DNSError for which Temporary returns false. 765 func (e *DNSError) Temporary() bool { return e.IsTimeout || e.IsTemporary } 766 767 type writerOnly struct { 768 io.Writer 769 } 770 771 // Fallback implementation of io.ReaderFrom's ReadFrom, when sendfile isn't 772 // applicable. 773 func genericReadFrom(w io.Writer, r io.Reader) (n int64, err error) { 774 // Use wrapper to hide existing r.ReadFrom from io.Copy. 775 return io.Copy(writerOnly{w}, r) 776 } 777 778 // Limit the number of concurrent cgo-using goroutines, because 779 // each will block an entire operating system thread. The usual culprit 780 // is resolving many DNS names in separate goroutines but the DNS 781 // server is not responding. Then the many lookups each use a different 782 // thread, and the system or the program runs out of threads. 783 784 var threadLimit = make(chan struct{}, 500) 785 786 func acquireThread() { 787 threadLimit <- struct{}{} 788 } 789 790 func releaseThread() { 791 <-threadLimit 792 } 793 794 // buffersWriter is the interface implemented by Conns that support a 795 // "writev"-like batch write optimization. 796 // writeBuffers should fully consume and write all chunks from the 797 // provided Buffers, else it should report a non-nil error. 798 type buffersWriter interface { 799 writeBuffers(*Buffers) (int64, error) 800 } 801 802 // Buffers contains zero or more runs of bytes to write. 803 // 804 // On certain machines, for certain types of connections, this is 805 // optimized into an OS-specific batch write operation (such as 806 // "writev"). 807 type Buffers [][]byte 808 809 var ( 810 _ io.WriterTo = (*Buffers)(nil) 811 _ io.Reader = (*Buffers)(nil) 812 ) 813 814 func (v *Buffers) WriteTo(w io.Writer) (n int64, err error) { 815 if wv, ok := w.(buffersWriter); ok { 816 return wv.writeBuffers(v) 817 } 818 for _, b := range *v { 819 nb, err := w.Write(b) 820 n += int64(nb) 821 if err != nil { 822 v.consume(n) 823 return n, err 824 } 825 } 826 v.consume(n) 827 return n, nil 828 } 829 830 func (v *Buffers) Read(p []byte) (n int, err error) { 831 for len(p) > 0 && len(*v) > 0 { 832 n0 := copy(p, (*v)[0]) 833 v.consume(int64(n0)) 834 p = p[n0:] 835 n += n0 836 } 837 if len(*v) == 0 { 838 err = io.EOF 839 } 840 return 841 } 842 843 func (v *Buffers) consume(n int64) { 844 for len(*v) > 0 { 845 ln0 := int64(len((*v)[0])) 846 if ln0 > n { 847 (*v)[0] = (*v)[0][n:] 848 return 849 } 850 n -= ln0 851 *v = (*v)[1:] 852 } 853 }