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