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 // +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows 6 7 package net 8 9 import ( 10 "io" 11 "os" 12 "syscall" 13 "time" 14 ) 15 16 func sockaddrToTCP(sa syscall.Sockaddr) Addr { 17 switch sa := sa.(type) { 18 case *syscall.SockaddrInet4: 19 return &TCPAddr{IP: sa.Addr[0:], Port: sa.Port} 20 case *syscall.SockaddrInet6: 21 return &TCPAddr{IP: sa.Addr[0:], Port: sa.Port, Zone: zoneToString(int(sa.ZoneId))} 22 } 23 return nil 24 } 25 26 func (a *TCPAddr) family() int { 27 if a == nil || len(a.IP) <= IPv4len { 28 return syscall.AF_INET 29 } 30 if a.IP.To4() != nil { 31 return syscall.AF_INET 32 } 33 return syscall.AF_INET6 34 } 35 36 func (a *TCPAddr) sockaddr(family int) (syscall.Sockaddr, error) { 37 if a == nil { 38 return nil, nil 39 } 40 return ipToSockaddr(family, a.IP, a.Port, a.Zone) 41 } 42 43 // TCPConn is an implementation of the Conn interface for TCP network 44 // connections. 45 type TCPConn struct { 46 conn 47 } 48 49 func newTCPConn(fd *netFD) *TCPConn { 50 c := &TCPConn{conn{fd}} 51 setNoDelay(c.fd, true) 52 return c 53 } 54 55 // ReadFrom implements the io.ReaderFrom ReadFrom method. 56 func (c *TCPConn) ReadFrom(r io.Reader) (int64, error) { 57 if n, err, handled := sendFile(c.fd, r); handled { 58 if err != nil && err != io.EOF { 59 err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err} 60 } 61 return n, err 62 } 63 n, err := genericReadFrom(c, r) 64 if err != nil && err != io.EOF { 65 err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err} 66 } 67 return n, err 68 } 69 70 // CloseRead shuts down the reading side of the TCP connection. 71 // Most callers should just use Close. 72 func (c *TCPConn) CloseRead() error { 73 if !c.ok() { 74 return syscall.EINVAL 75 } 76 err := c.fd.closeRead() 77 if err != nil { 78 err = &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err} 79 } 80 return err 81 } 82 83 // CloseWrite shuts down the writing side of the TCP connection. 84 // Most callers should just use Close. 85 func (c *TCPConn) CloseWrite() error { 86 if !c.ok() { 87 return syscall.EINVAL 88 } 89 err := c.fd.closeWrite() 90 if err != nil { 91 err = &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err} 92 } 93 return err 94 } 95 96 // SetLinger sets the behavior of Close on a connection which still 97 // has data waiting to be sent or to be acknowledged. 98 // 99 // If sec < 0 (the default), the operating system finishes sending the 100 // data in the background. 101 // 102 // If sec == 0, the operating system discards any unsent or 103 // unacknowledged data. 104 // 105 // If sec > 0, the data is sent in the background as with sec < 0. On 106 // some operating systems after sec seconds have elapsed any remaining 107 // unsent data may be discarded. 108 func (c *TCPConn) SetLinger(sec int) error { 109 if !c.ok() { 110 return syscall.EINVAL 111 } 112 if err := setLinger(c.fd, sec); err != nil { 113 return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err} 114 } 115 return nil 116 } 117 118 // SetKeepAlive sets whether the operating system should send 119 // keepalive messages on the connection. 120 func (c *TCPConn) SetKeepAlive(keepalive bool) error { 121 if !c.ok() { 122 return syscall.EINVAL 123 } 124 if err := setKeepAlive(c.fd, keepalive); err != nil { 125 return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err} 126 } 127 return nil 128 } 129 130 // SetKeepAlivePeriod sets period between keep alives. 131 func (c *TCPConn) SetKeepAlivePeriod(d time.Duration) error { 132 if !c.ok() { 133 return syscall.EINVAL 134 } 135 if err := setKeepAlivePeriod(c.fd, d); err != nil { 136 return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err} 137 } 138 return nil 139 } 140 141 // SetNoDelay controls whether the operating system should delay 142 // packet transmission in hopes of sending fewer packets (Nagle's 143 // algorithm). The default is true (no delay), meaning that data is 144 // sent as soon as possible after a Write. 145 func (c *TCPConn) SetNoDelay(noDelay bool) error { 146 if !c.ok() { 147 return syscall.EINVAL 148 } 149 if err := setNoDelay(c.fd, noDelay); err != nil { 150 return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err} 151 } 152 return nil 153 } 154 155 // DialTCP connects to the remote address raddr on the network net, 156 // which must be "tcp", "tcp4", or "tcp6". If laddr is not nil, it is 157 // used as the local address for the connection. 158 func DialTCP(net string, laddr, raddr *TCPAddr) (*TCPConn, error) { 159 switch net { 160 case "tcp", "tcp4", "tcp6": 161 default: 162 return nil, &OpError{Op: "dial", Net: net, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: UnknownNetworkError(net)} 163 } 164 if raddr == nil { 165 return nil, &OpError{Op: "dial", Net: net, Source: laddr.opAddr(), Addr: nil, Err: errMissingAddress} 166 } 167 return dialTCP(net, laddr, raddr, noDeadline) 168 } 169 170 func dialTCP(net string, laddr, raddr *TCPAddr, deadline time.Time) (*TCPConn, error) { 171 fd, err := internetSocket(net, laddr, raddr, deadline, syscall.SOCK_STREAM, 0, "dial") 172 173 // TCP has a rarely used mechanism called a 'simultaneous connection' in 174 // which Dial("tcp", addr1, addr2) run on the machine at addr1 can 175 // connect to a simultaneous Dial("tcp", addr2, addr1) run on the machine 176 // at addr2, without either machine executing Listen. If laddr == nil, 177 // it means we want the kernel to pick an appropriate originating local 178 // address. Some Linux kernels cycle blindly through a fixed range of 179 // local ports, regardless of destination port. If a kernel happens to 180 // pick local port 50001 as the source for a Dial("tcp", "", "localhost:50001"), 181 // then the Dial will succeed, having simultaneously connected to itself. 182 // This can only happen when we are letting the kernel pick a port (laddr == nil) 183 // and when there is no listener for the destination address. 184 // It's hard to argue this is anything other than a kernel bug. If we 185 // see this happen, rather than expose the buggy effect to users, we 186 // close the fd and try again. If it happens twice more, we relent and 187 // use the result. See also: 188 // https://golang.org/issue/2690 189 // http://stackoverflow.com/questions/4949858/ 190 // 191 // The opposite can also happen: if we ask the kernel to pick an appropriate 192 // originating local address, sometimes it picks one that is already in use. 193 // So if the error is EADDRNOTAVAIL, we have to try again too, just for 194 // a different reason. 195 // 196 // The kernel socket code is no doubt enjoying watching us squirm. 197 for i := 0; i < 2 && (laddr == nil || laddr.Port == 0) && (selfConnect(fd, err) || spuriousENOTAVAIL(err)); i++ { 198 if err == nil { 199 fd.Close() 200 } 201 fd, err = internetSocket(net, laddr, raddr, deadline, syscall.SOCK_STREAM, 0, "dial") 202 } 203 204 if err != nil { 205 return nil, &OpError{Op: "dial", Net: net, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: err} 206 } 207 return newTCPConn(fd), nil 208 } 209 210 func selfConnect(fd *netFD, err error) bool { 211 // If the connect failed, we clearly didn't connect to ourselves. 212 if err != nil { 213 return false 214 } 215 216 // The socket constructor can return an fd with raddr nil under certain 217 // unknown conditions. The errors in the calls there to Getpeername 218 // are discarded, but we can't catch the problem there because those 219 // calls are sometimes legally erroneous with a "socket not connected". 220 // Since this code (selfConnect) is already trying to work around 221 // a problem, we make sure if this happens we recognize trouble and 222 // ask the DialTCP routine to try again. 223 // TODO: try to understand what's really going on. 224 if fd.laddr == nil || fd.raddr == nil { 225 return true 226 } 227 l := fd.laddr.(*TCPAddr) 228 r := fd.raddr.(*TCPAddr) 229 return l.Port == r.Port && l.IP.Equal(r.IP) 230 } 231 232 func spuriousENOTAVAIL(err error) bool { 233 if op, ok := err.(*OpError); ok { 234 err = op.Err 235 } 236 if sys, ok := err.(*os.SyscallError); ok { 237 err = sys.Err 238 } 239 return err == syscall.EADDRNOTAVAIL 240 } 241 242 // TCPListener is a TCP network listener. Clients should typically 243 // use variables of type Listener instead of assuming TCP. 244 type TCPListener struct { 245 fd *netFD 246 } 247 248 // AcceptTCP accepts the next incoming call and returns the new 249 // connection. 250 func (l *TCPListener) AcceptTCP() (*TCPConn, error) { 251 if l == nil || l.fd == nil { 252 return nil, syscall.EINVAL 253 } 254 fd, err := l.fd.accept() 255 if err != nil { 256 return nil, &OpError{Op: "accept", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err} 257 } 258 return newTCPConn(fd), nil 259 } 260 261 // Accept implements the Accept method in the Listener interface; it 262 // waits for the next call and returns a generic Conn. 263 func (l *TCPListener) Accept() (Conn, error) { 264 c, err := l.AcceptTCP() 265 if err != nil { 266 return nil, err 267 } 268 return c, nil 269 } 270 271 // Close stops listening on the TCP address. 272 // Already Accepted connections are not closed. 273 func (l *TCPListener) Close() error { 274 if l == nil || l.fd == nil { 275 return syscall.EINVAL 276 } 277 err := l.fd.Close() 278 if err != nil { 279 err = &OpError{Op: "close", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err} 280 } 281 return err 282 } 283 284 // Addr returns the listener's network address, a *TCPAddr. 285 // The Addr returned is shared by all invocations of Addr, so 286 // do not modify it. 287 func (l *TCPListener) Addr() Addr { return l.fd.laddr } 288 289 // SetDeadline sets the deadline associated with the listener. 290 // A zero time value disables the deadline. 291 func (l *TCPListener) SetDeadline(t time.Time) error { 292 if l == nil || l.fd == nil { 293 return syscall.EINVAL 294 } 295 if err := l.fd.setDeadline(t); err != nil { 296 return &OpError{Op: "set", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err} 297 } 298 return nil 299 } 300 301 // File returns a copy of the underlying os.File, set to blocking 302 // mode. It is the caller's responsibility to close f when finished. 303 // Closing l does not affect f, and closing f does not affect l. 304 // 305 // The returned os.File's file descriptor is different from the 306 // connection's. Attempting to change properties of the original 307 // using this duplicate may or may not have the desired effect. 308 func (l *TCPListener) File() (f *os.File, err error) { 309 f, err = l.fd.dup() 310 if err != nil { 311 err = &OpError{Op: "file", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err} 312 } 313 return 314 } 315 316 // ListenTCP announces on the TCP address laddr and returns a TCP 317 // listener. Net must be "tcp", "tcp4", or "tcp6". If laddr has a 318 // port of 0, ListenTCP will choose an available port. The caller can 319 // use the Addr method of TCPListener to retrieve the chosen address. 320 func ListenTCP(net string, laddr *TCPAddr) (*TCPListener, error) { 321 switch net { 322 case "tcp", "tcp4", "tcp6": 323 default: 324 return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr.opAddr(), Err: UnknownNetworkError(net)} 325 } 326 if laddr == nil { 327 laddr = &TCPAddr{} 328 } 329 fd, err := internetSocket(net, laddr, nil, noDeadline, syscall.SOCK_STREAM, 0, "listen") 330 if err != nil { 331 return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: err} 332 } 333 return &TCPListener{fd}, nil 334 } 335