Russ Cox | e8a0223 | 2008-09-16 13:42:47 -0700 | [diff] [blame] | 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 | |
Brad Fitzpatrick | 008e64d | 2012-02-17 13:07:06 +1100 | [diff] [blame] | 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 |
Brad Fitzpatrick | 8729d15 | 2012-02-21 11:11:18 +1100 | [diff] [blame] | 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. |
Brad Fitzpatrick | 008e64d | 2012-02-17 13:07:06 +1100 | [diff] [blame] | 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 | */ |
Russ Cox | e8a0223 | 2008-09-16 13:42:47 -0700 | [diff] [blame] | 40 | package net |
| 41 | |
Russ Cox | 35ace1d | 2009-11-01 11:15:34 -0800 | [diff] [blame] | 42 | // TODO(rsc): |
Russ Cox | 35ace1d | 2009-11-01 11:15:34 -0800 | [diff] [blame] | 43 | // support for raw ethernet sockets |
Russ Cox | e8a0223 | 2008-09-16 13:42:47 -0700 | [diff] [blame] | 44 | |
Brad Fitzpatrick | b71883e | 2012-01-18 16:24:06 -0800 | [diff] [blame] | 45 | import ( |
| 46 | "errors" |
Mikio Hara | 306afc7 | 2012-11-13 16:18:37 +0900 | [diff] [blame^] | 47 | "os" |
| 48 | "syscall" |
Brad Fitzpatrick | b71883e | 2012-01-18 16:24:06 -0800 | [diff] [blame] | 49 | "time" |
| 50 | ) |
Russ Cox | 97bc222 | 2009-05-07 17:36:29 -0700 | [diff] [blame] | 51 | |
Russ Cox | c83b838 | 2009-11-02 18:37:30 -0800 | [diff] [blame] | 52 | // Addr represents a network end point address. |
| 53 | type Addr interface { |
Robert Griesemer | a3d1045 | 2009-12-15 15:35:38 -0800 | [diff] [blame] | 54 | Network() string // name of the network |
| 55 | String() string // string form of address |
Russ Cox | c83b838 | 2009-11-02 18:37:30 -0800 | [diff] [blame] | 56 | } |
| 57 | |
| 58 | // Conn is a generic stream-oriented network connection. |
Russ Cox | babbf94 | 2012-03-07 14:55:09 -0500 | [diff] [blame] | 59 | // |
| 60 | // Multiple goroutines may invoke methods on a Conn simultaneously. |
Russ Cox | cc1d4b7 | 2009-05-13 18:03:41 -0700 | [diff] [blame] | 61 | type Conn interface { |
Russ Cox | c83b838 | 2009-11-02 18:37:30 -0800 | [diff] [blame] | 62 | // Read reads data from the connection. |
Mikio Hara | 3d400db | 2012-01-29 19:11:05 +0900 | [diff] [blame] | 63 | // Read can be made to time out and return a Error with Timeout() == true |
Mikio Hara | 2356e43 | 2012-01-19 12:23:30 +0900 | [diff] [blame] | 64 | // after a fixed time limit; see SetDeadline and SetReadDeadline. |
Russ Cox | eb69292 | 2011-11-01 22:05:34 -0400 | [diff] [blame] | 65 | Read(b []byte) (n int, err error) |
Russ Cox | cc1d4b7 | 2009-05-13 18:03:41 -0700 | [diff] [blame] | 66 | |
Russ Cox | c83b838 | 2009-11-02 18:37:30 -0800 | [diff] [blame] | 67 | // Write writes data to the connection. |
Mikio Hara | 3d400db | 2012-01-29 19:11:05 +0900 | [diff] [blame] | 68 | // Write can be made to time out and return a Error with Timeout() == true |
Mikio Hara | 2356e43 | 2012-01-19 12:23:30 +0900 | [diff] [blame] | 69 | // after a fixed time limit; see SetDeadline and SetWriteDeadline. |
Russ Cox | eb69292 | 2011-11-01 22:05:34 -0400 | [diff] [blame] | 70 | Write(b []byte) (n int, err error) |
Russ Cox | cc1d4b7 | 2009-05-13 18:03:41 -0700 | [diff] [blame] | 71 | |
| 72 | // Close closes the connection. |
Russ Cox | babbf94 | 2012-03-07 14:55:09 -0500 | [diff] [blame] | 73 | // Any blocked Read or Write operations will be unblocked and return errors. |
Russ Cox | eb69292 | 2011-11-01 22:05:34 -0400 | [diff] [blame] | 74 | Close() error |
Russ Cox | cc1d4b7 | 2009-05-13 18:03:41 -0700 | [diff] [blame] | 75 | |
Rob Pike | efc4088 | 2009-06-19 16:03:59 -0700 | [diff] [blame] | 76 | // LocalAddr returns the local network address. |
Robert Griesemer | a3d1045 | 2009-12-15 15:35:38 -0800 | [diff] [blame] | 77 | LocalAddr() Addr |
Rob Pike | efc4088 | 2009-06-19 16:03:59 -0700 | [diff] [blame] | 78 | |
| 79 | // RemoteAddr returns the remote network address. |
Robert Griesemer | a3d1045 | 2009-12-15 15:35:38 -0800 | [diff] [blame] | 80 | RemoteAddr() Addr |
Russ Cox | cc1d4b7 | 2009-05-13 18:03:41 -0700 | [diff] [blame] | 81 | |
Brad Fitzpatrick | b71883e | 2012-01-18 16:24:06 -0800 | [diff] [blame] | 82 | // SetDeadline sets the read and write deadlines associated |
Brad Fitzpatrick | 8729d15 | 2012-02-21 11:11:18 +1100 | [diff] [blame] | 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. |
Brad Fitzpatrick | b71883e | 2012-01-18 16:24:06 -0800 | [diff] [blame] | 95 | SetDeadline(t time.Time) error |
Russ Cox | cc1d4b7 | 2009-05-13 18:03:41 -0700 | [diff] [blame] | 96 | |
Russ Cox | babbf94 | 2012-03-07 14:55:09 -0500 | [diff] [blame] | 97 | // SetReadDeadline sets the deadline for future Read calls. |
Brad Fitzpatrick | b71883e | 2012-01-18 16:24:06 -0800 | [diff] [blame] | 98 | // A zero value for t means Read will not time out. |
| 99 | SetReadDeadline(t time.Time) error |
Russ Cox | cc1d4b7 | 2009-05-13 18:03:41 -0700 | [diff] [blame] | 100 | |
Russ Cox | babbf94 | 2012-03-07 14:55:09 -0500 | [diff] [blame] | 101 | // SetWriteDeadline sets the deadline for future Write calls. |
Russ Cox | cc1d4b7 | 2009-05-13 18:03:41 -0700 | [diff] [blame] | 102 | // Even if write times out, it may return n > 0, indicating that |
| 103 | // some of the data was successfully written. |
Brad Fitzpatrick | 8729d15 | 2012-02-21 11:11:18 +1100 | [diff] [blame] | 104 | // A zero value for t means Write will not time out. |
Brad Fitzpatrick | b71883e | 2012-01-18 16:24:06 -0800 | [diff] [blame] | 105 | SetWriteDeadline(t time.Time) error |
Russ Cox | cc1d4b7 | 2009-05-13 18:03:41 -0700 | [diff] [blame] | 106 | } |
| 107 | |
Mikio Hara | 306afc7 | 2012-11-13 16:18:37 +0900 | [diff] [blame^] | 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 setDeadline(c.fd, 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 setReadDeadline(c.fd, 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 setWriteDeadline(c.fd, 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 returns a copy of the underlying os.File, set to blocking mode. |
| 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 | func (c *conn) File() (f *os.File, err error) { return c.fd.dup() } |
| 202 | |
Russ Cox | 47a0533 | 2010-04-26 22:15:25 -0700 | [diff] [blame] | 203 | // An Error represents a network error. |
| 204 | type Error interface { |
Russ Cox | eb69292 | 2011-11-01 22:05:34 -0400 | [diff] [blame] | 205 | error |
Russ Cox | 47a0533 | 2010-04-26 22:15:25 -0700 | [diff] [blame] | 206 | Timeout() bool // Is the error a timeout? |
| 207 | Temporary() bool // Is the error temporary? |
| 208 | } |
| 209 | |
Russ Cox | c83b838 | 2009-11-02 18:37:30 -0800 | [diff] [blame] | 210 | // PacketConn is a generic packet-oriented network connection. |
Russ Cox | babbf94 | 2012-03-07 14:55:09 -0500 | [diff] [blame] | 211 | // |
| 212 | // Multiple goroutines may invoke methods on a PacketConn simultaneously. |
Russ Cox | c83b838 | 2009-11-02 18:37:30 -0800 | [diff] [blame] | 213 | type PacketConn interface { |
| 214 | // ReadFrom reads a packet from the connection, |
| 215 | // copying the payload into b. It returns the number of |
| 216 | // bytes copied into b and the return address that |
| 217 | // was on the packet. |
Russ Cox | 47a0533 | 2010-04-26 22:15:25 -0700 | [diff] [blame] | 218 | // ReadFrom can be made to time out and return |
| 219 | // an error with Timeout() == true after a fixed time limit; |
Brad Fitzpatrick | b71883e | 2012-01-18 16:24:06 -0800 | [diff] [blame] | 220 | // see SetDeadline and SetReadDeadline. |
Russ Cox | eb69292 | 2011-11-01 22:05:34 -0400 | [diff] [blame] | 221 | ReadFrom(b []byte) (n int, addr Addr, err error) |
Russ Cox | c83b838 | 2009-11-02 18:37:30 -0800 | [diff] [blame] | 222 | |
| 223 | // WriteTo writes a packet with payload b to addr. |
Russ Cox | 47a0533 | 2010-04-26 22:15:25 -0700 | [diff] [blame] | 224 | // WriteTo can be made to time out and return |
| 225 | // an error with Timeout() == true after a fixed time limit; |
Brad Fitzpatrick | b71883e | 2012-01-18 16:24:06 -0800 | [diff] [blame] | 226 | // see SetDeadline and SetWriteDeadline. |
Russ Cox | c83b838 | 2009-11-02 18:37:30 -0800 | [diff] [blame] | 227 | // On packet-oriented connections, write timeouts are rare. |
Russ Cox | eb69292 | 2011-11-01 22:05:34 -0400 | [diff] [blame] | 228 | WriteTo(b []byte, addr Addr) (n int, err error) |
Russ Cox | c83b838 | 2009-11-02 18:37:30 -0800 | [diff] [blame] | 229 | |
| 230 | // Close closes the connection. |
Russ Cox | babbf94 | 2012-03-07 14:55:09 -0500 | [diff] [blame] | 231 | // Any blocked ReadFrom or WriteTo operations will be unblocked and return errors. |
Russ Cox | eb69292 | 2011-11-01 22:05:34 -0400 | [diff] [blame] | 232 | Close() error |
Russ Cox | c83b838 | 2009-11-02 18:37:30 -0800 | [diff] [blame] | 233 | |
| 234 | // LocalAddr returns the local network address. |
Robert Griesemer | a3d1045 | 2009-12-15 15:35:38 -0800 | [diff] [blame] | 235 | LocalAddr() Addr |
Russ Cox | c83b838 | 2009-11-02 18:37:30 -0800 | [diff] [blame] | 236 | |
Brad Fitzpatrick | b71883e | 2012-01-18 16:24:06 -0800 | [diff] [blame] | 237 | // SetDeadline sets the read and write deadlines associated |
Russ Cox | c83b838 | 2009-11-02 18:37:30 -0800 | [diff] [blame] | 238 | // with the connection. |
Brad Fitzpatrick | b71883e | 2012-01-18 16:24:06 -0800 | [diff] [blame] | 239 | SetDeadline(t time.Time) error |
Russ Cox | c83b838 | 2009-11-02 18:37:30 -0800 | [diff] [blame] | 240 | |
Russ Cox | babbf94 | 2012-03-07 14:55:09 -0500 | [diff] [blame] | 241 | // SetReadDeadline sets the deadline for future Read calls. |
Brad Fitzpatrick | b71883e | 2012-01-18 16:24:06 -0800 | [diff] [blame] | 242 | // If the deadline is reached, Read will fail with a timeout |
| 243 | // (see type Error) instead of blocking. |
| 244 | // A zero value for t means Read will not time out. |
| 245 | SetReadDeadline(t time.Time) error |
Russ Cox | c83b838 | 2009-11-02 18:37:30 -0800 | [diff] [blame] | 246 | |
Russ Cox | babbf94 | 2012-03-07 14:55:09 -0500 | [diff] [blame] | 247 | // SetWriteDeadline sets the deadline for future Write calls. |
Brad Fitzpatrick | b71883e | 2012-01-18 16:24:06 -0800 | [diff] [blame] | 248 | // If the deadline is reached, Write will fail with a timeout |
| 249 | // (see type Error) instead of blocking. |
| 250 | // A zero value for t means Write will not time out. |
Russ Cox | c83b838 | 2009-11-02 18:37:30 -0800 | [diff] [blame] | 251 | // Even if write times out, it may return n > 0, indicating that |
| 252 | // some of the data was successfully written. |
Brad Fitzpatrick | b71883e | 2012-01-18 16:24:06 -0800 | [diff] [blame] | 253 | SetWriteDeadline(t time.Time) error |
Russ Cox | c83b838 | 2009-11-02 18:37:30 -0800 | [diff] [blame] | 254 | } |
| 255 | |
| 256 | // A Listener is a generic network listener for stream-oriented protocols. |
Russ Cox | babbf94 | 2012-03-07 14:55:09 -0500 | [diff] [blame] | 257 | // |
| 258 | // Multiple goroutines may invoke methods on a Listener simultaneously. |
Russ Cox | 35ace1d | 2009-11-01 11:15:34 -0800 | [diff] [blame] | 259 | type Listener interface { |
Russ Cox | 47a0533 | 2010-04-26 22:15:25 -0700 | [diff] [blame] | 260 | // Accept waits for and returns the next connection to the listener. |
Russ Cox | eb69292 | 2011-11-01 22:05:34 -0400 | [diff] [blame] | 261 | Accept() (c Conn, err error) |
Russ Cox | 47a0533 | 2010-04-26 22:15:25 -0700 | [diff] [blame] | 262 | |
| 263 | // Close closes the listener. |
Russ Cox | babbf94 | 2012-03-07 14:55:09 -0500 | [diff] [blame] | 264 | // Any blocked Accept operations will be unblocked and return errors. |
Russ Cox | eb69292 | 2011-11-01 22:05:34 -0400 | [diff] [blame] | 265 | Close() error |
Russ Cox | 47a0533 | 2010-04-26 22:15:25 -0700 | [diff] [blame] | 266 | |
| 267 | // Addr returns the listener's network address. |
| 268 | Addr() Addr |
Russ Cox | 5d2ee9d | 2009-06-17 21:44:26 -0700 | [diff] [blame] | 269 | } |
| 270 | |
Russ Cox | eb69292 | 2011-11-01 22:05:34 -0400 | [diff] [blame] | 271 | var errMissingAddress = errors.New("missing address") |
Russ Cox | 35ace1d | 2009-11-01 11:15:34 -0800 | [diff] [blame] | 272 | |
| 273 | type OpError struct { |
Russ Cox | eb69292 | 2011-11-01 22:05:34 -0400 | [diff] [blame] | 274 | Op string |
| 275 | Net string |
| 276 | Addr Addr |
| 277 | Err error |
Russ Cox | 35ace1d | 2009-11-01 11:15:34 -0800 | [diff] [blame] | 278 | } |
| 279 | |
Russ Cox | eb69292 | 2011-11-01 22:05:34 -0400 | [diff] [blame] | 280 | func (e *OpError) Error() string { |
Andrew Gerrand | fc4ba15 | 2010-07-27 17:22:22 +1000 | [diff] [blame] | 281 | if e == nil { |
| 282 | return "<nil>" |
| 283 | } |
Robert Griesemer | a3d1045 | 2009-12-15 15:35:38 -0800 | [diff] [blame] | 284 | s := e.Op |
Russ Cox | 35ace1d | 2009-11-01 11:15:34 -0800 | [diff] [blame] | 285 | if e.Net != "" { |
Robert Griesemer | 40621d5 | 2009-11-09 12:07:39 -0800 | [diff] [blame] | 286 | s += " " + e.Net |
Russ Cox | 35ace1d | 2009-11-01 11:15:34 -0800 | [diff] [blame] | 287 | } |
Russ Cox | c83b838 | 2009-11-02 18:37:30 -0800 | [diff] [blame] | 288 | if e.Addr != nil { |
Robert Griesemer | 40621d5 | 2009-11-09 12:07:39 -0800 | [diff] [blame] | 289 | s += " " + e.Addr.String() |
Russ Cox | 35ace1d | 2009-11-01 11:15:34 -0800 | [diff] [blame] | 290 | } |
Russ Cox | eb69292 | 2011-11-01 22:05:34 -0400 | [diff] [blame] | 291 | s += ": " + e.Err.Error() |
Robert Griesemer | a3d1045 | 2009-12-15 15:35:38 -0800 | [diff] [blame] | 292 | return s |
Russ Cox | 35ace1d | 2009-11-01 11:15:34 -0800 | [diff] [blame] | 293 | } |
| 294 | |
Russ Cox | 47a0533 | 2010-04-26 22:15:25 -0700 | [diff] [blame] | 295 | type temporary interface { |
| 296 | Temporary() bool |
| 297 | } |
| 298 | |
| 299 | func (e *OpError) Temporary() bool { |
Russ Cox | eb69292 | 2011-11-01 22:05:34 -0400 | [diff] [blame] | 300 | t, ok := e.Err.(temporary) |
Russ Cox | 47a0533 | 2010-04-26 22:15:25 -0700 | [diff] [blame] | 301 | return ok && t.Temporary() |
| 302 | } |
| 303 | |
Brad Fitzpatrick | ef6806f | 2012-11-08 10:35:16 -0600 | [diff] [blame] | 304 | var noDeadline = time.Time{} |
| 305 | |
Russ Cox | 47a0533 | 2010-04-26 22:15:25 -0700 | [diff] [blame] | 306 | type timeout interface { |
| 307 | Timeout() bool |
| 308 | } |
| 309 | |
| 310 | func (e *OpError) Timeout() bool { |
Russ Cox | eb69292 | 2011-11-01 22:05:34 -0400 | [diff] [blame] | 311 | t, ok := e.Err.(timeout) |
Russ Cox | 47a0533 | 2010-04-26 22:15:25 -0700 | [diff] [blame] | 312 | return ok && t.Timeout() |
| 313 | } |
| 314 | |
Brad Fitzpatrick | 01507b9 | 2011-12-20 14:32:33 -0800 | [diff] [blame] | 315 | type timeoutError struct{} |
| 316 | |
| 317 | func (e *timeoutError) Error() string { return "i/o timeout" } |
| 318 | func (e *timeoutError) Timeout() bool { return true } |
| 319 | func (e *timeoutError) Temporary() bool { return true } |
| 320 | |
| 321 | var errTimeout error = &timeoutError{} |
| 322 | |
Alex Brainman | 84e2046 | 2012-11-02 11:07:22 +1100 | [diff] [blame] | 323 | var errClosing = errors.New("use of closed network connection") |
| 324 | |
Russ Cox | 35ace1d | 2009-11-01 11:15:34 -0800 | [diff] [blame] | 325 | type AddrError struct { |
Russ Cox | eb69292 | 2011-11-01 22:05:34 -0400 | [diff] [blame] | 326 | Err string |
| 327 | Addr string |
Russ Cox | 35ace1d | 2009-11-01 11:15:34 -0800 | [diff] [blame] | 328 | } |
| 329 | |
Russ Cox | eb69292 | 2011-11-01 22:05:34 -0400 | [diff] [blame] | 330 | func (e *AddrError) Error() string { |
Andrew Gerrand | fc4ba15 | 2010-07-27 17:22:22 +1000 | [diff] [blame] | 331 | if e == nil { |
| 332 | return "<nil>" |
| 333 | } |
Russ Cox | eb69292 | 2011-11-01 22:05:34 -0400 | [diff] [blame] | 334 | s := e.Err |
Russ Cox | 35ace1d | 2009-11-01 11:15:34 -0800 | [diff] [blame] | 335 | if e.Addr != "" { |
Robert Griesemer | 40621d5 | 2009-11-09 12:07:39 -0800 | [diff] [blame] | 336 | s += " " + e.Addr |
Russ Cox | 35ace1d | 2009-11-01 11:15:34 -0800 | [diff] [blame] | 337 | } |
Robert Griesemer | a3d1045 | 2009-12-15 15:35:38 -0800 | [diff] [blame] | 338 | return s |
Russ Cox | 35ace1d | 2009-11-01 11:15:34 -0800 | [diff] [blame] | 339 | } |
| 340 | |
Russ Cox | 47a0533 | 2010-04-26 22:15:25 -0700 | [diff] [blame] | 341 | func (e *AddrError) Temporary() bool { |
| 342 | return false |
| 343 | } |
| 344 | |
| 345 | func (e *AddrError) Timeout() bool { |
| 346 | return false |
| 347 | } |
| 348 | |
Russ Cox | 35ace1d | 2009-11-01 11:15:34 -0800 | [diff] [blame] | 349 | type UnknownNetworkError string |
Robert Griesemer | 5d37705 | 2009-11-04 23:16:46 -0800 | [diff] [blame] | 350 | |
Russ Cox | eb69292 | 2011-11-01 22:05:34 -0400 | [diff] [blame] | 351 | func (e UnknownNetworkError) Error() string { return "unknown network " + string(e) } |
Russ Cox | 47a0533 | 2010-04-26 22:15:25 -0700 | [diff] [blame] | 352 | func (e UnknownNetworkError) Temporary() bool { return false } |
| 353 | func (e UnknownNetworkError) Timeout() bool { return false } |
Brad Fitzpatrick | 549ca93 | 2012-01-31 13:01:34 -0800 | [diff] [blame] | 354 | |
| 355 | // DNSConfigError represents an error reading the machine's DNS configuration. |
| 356 | type DNSConfigError struct { |
| 357 | Err error |
| 358 | } |
| 359 | |
| 360 | func (e *DNSConfigError) Error() string { |
| 361 | return "error reading DNS config: " + e.Err.Error() |
| 362 | } |
| 363 | |
| 364 | func (e *DNSConfigError) Timeout() bool { return false } |
| 365 | func (e *DNSConfigError) Temporary() bool { return false } |