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