github.com/roboticscm/goman@v0.0.0-20210203095141-87c07b4a0a55/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", "google.com: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 package net 40 41 // TODO(rsc): 42 // support for raw ethernet sockets 43 44 import ( 45 "errors" 46 "io" 47 "os" 48 "syscall" 49 "time" 50 ) 51 52 // Addr represents a network end point address. 53 type Addr interface { 54 Network() string // name of the network 55 String() string // string form of address 56 } 57 58 // Conn is a generic stream-oriented network connection. 59 // 60 // Multiple goroutines may invoke methods on a Conn simultaneously. 61 type Conn interface { 62 // Read reads data from the connection. 63 // Read can be made to time out and return a Error with Timeout() == true 64 // after a fixed time limit; see SetDeadline and SetReadDeadline. 65 Read(b []byte) (n int, err error) 66 67 // Write writes data to the connection. 68 // Write can be made to time out and return a Error with Timeout() == true 69 // after a fixed time limit; see SetDeadline and SetWriteDeadline. 70 Write(b []byte) (n int, err error) 71 72 // Close closes the connection. 73 // Any blocked Read or Write operations will be unblocked and return errors. 74 Close() error 75 76 // LocalAddr returns the local network address. 77 LocalAddr() Addr 78 79 // RemoteAddr returns the remote network address. 80 RemoteAddr() Addr 81 82 // SetDeadline sets the read and write deadlines associated 83 // with the connection. It is equivalent to calling both 84 // SetReadDeadline and SetWriteDeadline. 85 // 86 // A deadline is an absolute time after which I/O operations 87 // fail with a timeout (see type Error) instead of 88 // blocking. The deadline applies to all future I/O, not just 89 // the immediately following call to Read or Write. 90 // 91 // An idle timeout can be implemented by repeatedly extending 92 // the deadline after successful Read or Write calls. 93 // 94 // A zero value for t means I/O operations will not time out. 95 SetDeadline(t time.Time) error 96 97 // SetReadDeadline sets the deadline for future Read calls. 98 // A zero value for t means Read will not time out. 99 SetReadDeadline(t time.Time) error 100 101 // SetWriteDeadline sets the deadline for future Write calls. 102 // Even if write times out, it may return n > 0, indicating that 103 // some of the data was successfully written. 104 // A zero value for t means Write will not time out. 105 SetWriteDeadline(t time.Time) error 106 } 107 108 type conn struct { 109 fd *netFD 110 } 111 112 func (c *conn) ok() bool { return c != nil && c.fd != nil } 113 114 // Implementation of the Conn interface. 115 116 // Read implements the Conn Read method. 117 func (c *conn) Read(b []byte) (int, error) { 118 if !c.ok() { 119 return 0, syscall.EINVAL 120 } 121 return c.fd.Read(b) 122 } 123 124 // Write implements the Conn Write method. 125 func (c *conn) Write(b []byte) (int, error) { 126 if !c.ok() { 127 return 0, syscall.EINVAL 128 } 129 return c.fd.Write(b) 130 } 131 132 // Close closes the connection. 133 func (c *conn) Close() error { 134 if !c.ok() { 135 return syscall.EINVAL 136 } 137 return c.fd.Close() 138 } 139 140 // LocalAddr returns the local network address. 141 func (c *conn) LocalAddr() Addr { 142 if !c.ok() { 143 return nil 144 } 145 return c.fd.laddr 146 } 147 148 // RemoteAddr returns the remote network address. 149 func (c *conn) RemoteAddr() Addr { 150 if !c.ok() { 151 return nil 152 } 153 return c.fd.raddr 154 } 155 156 // SetDeadline implements the Conn SetDeadline method. 157 func (c *conn) SetDeadline(t time.Time) error { 158 if !c.ok() { 159 return syscall.EINVAL 160 } 161 return c.fd.setDeadline(t) 162 } 163 164 // SetReadDeadline implements the Conn SetReadDeadline method. 165 func (c *conn) SetReadDeadline(t time.Time) error { 166 if !c.ok() { 167 return syscall.EINVAL 168 } 169 return c.fd.setReadDeadline(t) 170 } 171 172 // SetWriteDeadline implements the Conn SetWriteDeadline method. 173 func (c *conn) SetWriteDeadline(t time.Time) error { 174 if !c.ok() { 175 return syscall.EINVAL 176 } 177 return c.fd.setWriteDeadline(t) 178 } 179 180 // SetReadBuffer sets the size of the operating system's 181 // receive buffer associated with the connection. 182 func (c *conn) SetReadBuffer(bytes int) error { 183 if !c.ok() { 184 return syscall.EINVAL 185 } 186 return setReadBuffer(c.fd, bytes) 187 } 188 189 // SetWriteBuffer sets the size of the operating system's 190 // transmit buffer associated with the connection. 191 func (c *conn) SetWriteBuffer(bytes int) error { 192 if !c.ok() { 193 return syscall.EINVAL 194 } 195 return setWriteBuffer(c.fd, bytes) 196 } 197 198 // File sets the underlying os.File to blocking mode and returns a copy. 199 // It is the caller's responsibility to close f when finished. 200 // Closing c does not affect f, and closing f does not affect c. 201 // 202 // The returned os.File's file descriptor is different from the connection's. 203 // Attempting to change properties of the original using this duplicate 204 // may or may not have the desired effect. 205 func (c *conn) File() (f *os.File, err error) { return c.fd.dup() } 206 207 // An Error represents a network error. 208 type Error interface { 209 error 210 Timeout() bool // Is the error a timeout? 211 Temporary() bool // Is the error temporary? 212 } 213 214 // PacketConn is a generic packet-oriented network connection. 215 // 216 // Multiple goroutines may invoke methods on a PacketConn simultaneously. 217 type PacketConn interface { 218 // ReadFrom reads a packet from the connection, 219 // copying the payload into b. It returns the number of 220 // bytes copied into b and the return address that 221 // was on the packet. 222 // ReadFrom can be made to time out and return 223 // an error with Timeout() == true after a fixed time limit; 224 // see SetDeadline and SetReadDeadline. 225 ReadFrom(b []byte) (n int, addr Addr, err error) 226 227 // WriteTo writes a packet with payload b to addr. 228 // WriteTo can be made to time out and return 229 // an error with Timeout() == true after a fixed time limit; 230 // see SetDeadline and SetWriteDeadline. 231 // On packet-oriented connections, write timeouts are rare. 232 WriteTo(b []byte, addr Addr) (n int, err error) 233 234 // Close closes the connection. 235 // Any blocked ReadFrom or WriteTo operations will be unblocked and return errors. 236 Close() error 237 238 // LocalAddr returns the local network address. 239 LocalAddr() Addr 240 241 // SetDeadline sets the read and write deadlines associated 242 // with the connection. 243 SetDeadline(t time.Time) error 244 245 // SetReadDeadline sets the deadline for future Read calls. 246 // If the deadline is reached, Read will fail with a timeout 247 // (see type Error) instead of blocking. 248 // A zero value for t means Read will not time out. 249 SetReadDeadline(t time.Time) error 250 251 // SetWriteDeadline sets the deadline for future Write calls. 252 // If the deadline is reached, Write will fail with a timeout 253 // (see type Error) instead of blocking. 254 // A zero value for t means Write will not time out. 255 // Even if write times out, it may return n > 0, indicating that 256 // some of the data was successfully written. 257 SetWriteDeadline(t time.Time) error 258 } 259 260 var listenerBacklog = maxListenerBacklog() 261 262 // A Listener is a generic network listener for stream-oriented protocols. 263 // 264 // Multiple goroutines may invoke methods on a Listener simultaneously. 265 type Listener interface { 266 // Accept waits for and returns the next connection to the listener. 267 Accept() (c Conn, err error) 268 269 // Close closes the listener. 270 // Any blocked Accept operations will be unblocked and return errors. 271 Close() error 272 273 // Addr returns the listener's network address. 274 Addr() Addr 275 } 276 277 // Various errors contained in OpError. 278 var ( 279 // For connection setup and write operations. 280 errMissingAddress = errors.New("missing address") 281 282 // For both read and write operations. 283 errTimeout error = &timeoutError{} 284 errClosing = errors.New("use of closed network connection") 285 ErrWriteToConnected = errors.New("use of WriteTo with pre-connected connection") 286 ) 287 288 // OpError is the error type usually returned by functions in the net 289 // package. It describes the operation, network type, and address of 290 // an error. 291 type OpError struct { 292 // Op is the operation which caused the error, such as 293 // "read" or "write". 294 Op string 295 296 // Net is the network type on which this error occurred, 297 // such as "tcp" or "udp6". 298 Net string 299 300 // Addr is the network address on which this error occurred. 301 Addr Addr 302 303 // Err is the error that occurred during the operation. 304 Err error 305 } 306 307 func (e *OpError) Error() string { 308 if e == nil { 309 return "<nil>" 310 } 311 s := e.Op 312 if e.Net != "" { 313 s += " " + e.Net 314 } 315 if e.Addr != nil { 316 s += " " + e.Addr.String() 317 } 318 s += ": " + e.Err.Error() 319 return s 320 } 321 322 type temporary interface { 323 Temporary() bool 324 } 325 326 func (e *OpError) Temporary() bool { 327 t, ok := e.Err.(temporary) 328 return ok && t.Temporary() 329 } 330 331 var noDeadline = time.Time{} 332 333 type timeout interface { 334 Timeout() bool 335 } 336 337 func (e *OpError) Timeout() bool { 338 t, ok := e.Err.(timeout) 339 return ok && t.Timeout() 340 } 341 342 type timeoutError struct{} 343 344 func (e *timeoutError) Error() string { return "i/o timeout" } 345 func (e *timeoutError) Timeout() bool { return true } 346 func (e *timeoutError) Temporary() bool { return true } 347 348 type AddrError struct { 349 Err string 350 Addr string 351 } 352 353 func (e *AddrError) Error() string { 354 if e == nil { 355 return "<nil>" 356 } 357 s := e.Err 358 if e.Addr != "" { 359 s += " " + e.Addr 360 } 361 return s 362 } 363 364 func (e *AddrError) Temporary() bool { 365 return false 366 } 367 368 func (e *AddrError) Timeout() bool { 369 return false 370 } 371 372 type UnknownNetworkError string 373 374 func (e UnknownNetworkError) Error() string { return "unknown network " + string(e) } 375 func (e UnknownNetworkError) Temporary() bool { return false } 376 func (e UnknownNetworkError) Timeout() bool { return false } 377 378 type InvalidAddrError string 379 380 func (e InvalidAddrError) Error() string { return string(e) } 381 func (e InvalidAddrError) Timeout() bool { return false } 382 func (e InvalidAddrError) Temporary() bool { return false } 383 384 // DNSConfigError represents an error reading the machine's DNS configuration. 385 type DNSConfigError struct { 386 Err error 387 } 388 389 func (e *DNSConfigError) Error() string { 390 return "error reading DNS config: " + e.Err.Error() 391 } 392 393 func (e *DNSConfigError) Timeout() bool { return false } 394 func (e *DNSConfigError) Temporary() bool { return false } 395 396 type writerOnly struct { 397 io.Writer 398 } 399 400 // Fallback implementation of io.ReaderFrom's ReadFrom, when sendfile isn't 401 // applicable. 402 func genericReadFrom(w io.Writer, r io.Reader) (n int64, err error) { 403 // Use wrapper to hide existing r.ReadFrom from io.Copy. 404 return io.Copy(writerOnly{w}, r) 405 } 406 407 // Limit the number of concurrent cgo-using goroutines, because 408 // each will block an entire operating system thread. The usual culprit 409 // is resolving many DNS names in separate goroutines but the DNS 410 // server is not responding. Then the many lookups each use a different 411 // thread, and the system or the program runs out of threads. 412 413 var threadLimit = make(chan struct{}, 500) 414 415 // Using send for acquire is fine here because we are not using this 416 // to protect any memory. All we care about is the number of goroutines 417 // making calls at a time. 418 419 func acquireThread() { 420 threadLimit <- struct{}{} 421 } 422 423 func releaseThread() { 424 <-threadLimit 425 }