23
21
func sockaddrToTCP(sa syscall.Sockaddr) Addr {
24
22
switch sa := sa.(type) {
25
23
case *syscall.SockaddrInet4:
26
return &TCPAddr{sa.Addr[0:], sa.Port}
24
return &TCPAddr{IP: sa.Addr[0:], Port: sa.Port}
27
25
case *syscall.SockaddrInet6:
28
return &TCPAddr{sa.Addr[0:], sa.Port}
31
// Diagnose when we will turn a non-nil sockaddr into a nil.
32
panic("unexpected type in sockaddrToTCP")
26
return &TCPAddr{IP: sa.Addr[0:], Port: sa.Port, Zone: zoneToString(int(sa.ZoneId))}
55
48
func (a *TCPAddr) sockaddr(family int) (syscall.Sockaddr, error) {
56
return ipToSockaddr(family, a.IP, a.Port)
49
return ipToSockaddr(family, a.IP, a.Port, a.Zone)
59
52
func (a *TCPAddr) toAddr() sockaddr {
66
// TCPConn is an implementation of the Conn interface
67
// for TCP network connections.
59
// TCPConn is an implementation of the Conn interface for TCP network
68
61
type TCPConn struct {
72
65
func newTCPConn(fd *netFD) *TCPConn {
66
c := &TCPConn{conn{fd}}
78
func (c *TCPConn) ok() bool { return c != nil && c.fd != nil }
80
// Implementation of the Conn interface - see Conn for documentation.
82
// Read implements the Conn Read method.
83
func (c *TCPConn) Read(b []byte) (n int, err error) {
85
return 0, syscall.EINVAL
90
71
// ReadFrom implements the io.ReaderFrom ReadFrom method.
91
72
func (c *TCPConn) ReadFrom(r io.Reader) (int64, error) {
92
73
if n, err, handled := sendFile(c.fd, r); handled {
95
76
return genericReadFrom(c, r)
98
// Write implements the Conn Write method.
99
func (c *TCPConn) Write(b []byte) (n int, err error) {
101
return 0, syscall.EINVAL
106
// Close closes the TCP connection.
107
func (c *TCPConn) Close() error {
109
return syscall.EINVAL
114
79
// CloseRead shuts down the reading side of the TCP connection.
115
80
// Most callers should just use Close.
116
81
func (c *TCPConn) CloseRead() error {
129
94
return c.fd.CloseWrite()
132
// LocalAddr returns the local network address, a *TCPAddr.
133
func (c *TCPConn) LocalAddr() Addr {
140
// RemoteAddr returns the remote network address, a *TCPAddr.
141
func (c *TCPConn) RemoteAddr() Addr {
148
// SetDeadline implements the Conn SetDeadline method.
149
func (c *TCPConn) SetDeadline(t time.Time) error {
151
return syscall.EINVAL
153
return setDeadline(c.fd, t)
156
// SetReadDeadline implements the Conn SetReadDeadline method.
157
func (c *TCPConn) SetReadDeadline(t time.Time) error {
159
return syscall.EINVAL
161
return setReadDeadline(c.fd, t)
164
// SetWriteDeadline implements the Conn SetWriteDeadline method.
165
func (c *TCPConn) SetWriteDeadline(t time.Time) error {
167
return syscall.EINVAL
169
return setWriteDeadline(c.fd, t)
172
// SetReadBuffer sets the size of the operating system's
173
// receive buffer associated with the connection.
174
func (c *TCPConn) SetReadBuffer(bytes int) error {
176
return syscall.EINVAL
178
return setReadBuffer(c.fd, bytes)
181
// SetWriteBuffer sets the size of the operating system's
182
// transmit buffer associated with the connection.
183
func (c *TCPConn) SetWriteBuffer(bytes int) error {
185
return syscall.EINVAL
187
return setWriteBuffer(c.fd, bytes)
190
// SetLinger sets the behavior of Close() on a connection
191
// which still has data waiting to be sent or to be acknowledged.
97
// SetLinger sets the behavior of Close() on a connection which still
98
// has data waiting to be sent or to be acknowledged.
193
// If sec < 0 (the default), Close returns immediately and
194
// the operating system finishes sending the data in the background.
100
// If sec < 0 (the default), Close returns immediately and the
101
// operating system finishes sending the data in the background.
196
103
// If sec == 0, Close returns immediately and the operating system
197
104
// discards any unsent or unacknowledged data.
199
// If sec > 0, Close blocks for at most sec seconds waiting for
200
// data to be sent and acknowledged.
106
// If sec > 0, Close blocks for at most sec seconds waiting for data
107
// to be sent and acknowledged.
201
108
func (c *TCPConn) SetLinger(sec int) error {
203
110
return syscall.EINVAL
217
124
// SetNoDelay controls whether the operating system should delay
218
// packet transmission in hopes of sending fewer packets
219
// (Nagle's algorithm). The default is true (no delay), meaning
220
// that data is sent as soon as possible after a Write.
125
// packet transmission in hopes of sending fewer packets (Nagle's
126
// algorithm). The default is true (no delay), meaning that data is
127
// sent as soon as possible after a Write.
221
128
func (c *TCPConn) SetNoDelay(noDelay bool) error {
223
130
return syscall.EINVAL
225
132
return setNoDelay(c.fd, noDelay)
228
// File returns a copy of the underlying os.File, set to blocking mode.
229
// It is the caller's responsibility to close f when finished.
230
// Closing c does not affect f, and closing f does not affect c.
231
func (c *TCPConn) File() (f *os.File, err error) { return c.fd.dup() }
233
135
// DialTCP connects to the remote address raddr on the network net,
234
// which must be "tcp", "tcp4", or "tcp6". If laddr is not nil, it is used
235
// as the local address for the connection.
136
// which must be "tcp", "tcp4", or "tcp6". If laddr is not nil, it is
137
// used as the local address for the connection.
236
138
func DialTCP(net string, laddr, raddr *TCPAddr) (*TCPConn, error) {
140
case "tcp", "tcp4", "tcp6":
142
return nil, UnknownNetworkError(net)
237
144
if raddr == nil {
238
145
return nil, &OpError{"dial", net, nil, errMissingAddress}
147
return dialTCP(net, laddr, raddr, noDeadline)
241
fd, err := internetSocket(net, laddr.toAddr(), raddr.toAddr(), syscall.SOCK_STREAM, 0, "dial", sockaddrToTCP)
150
func dialTCP(net string, laddr, raddr *TCPAddr, deadline time.Time) (*TCPConn, error) {
151
fd, err := internetSocket(net, laddr.toAddr(), raddr.toAddr(), deadline, syscall.SOCK_STREAM, 0, "dial", sockaddrToTCP)
243
153
// TCP has a rarely used mechanism called a 'simultaneous connection' in
244
154
// which Dial("tcp", addr1, addr2) run on the machine at addr1 can
257
167
// use the result. See also:
258
168
// http://golang.org/issue/2690
259
169
// http://stackoverflow.com/questions/4949858/
260
for i := 0; i < 2 && err == nil && laddr == nil && selfConnect(fd); i++ {
262
fd, err = internetSocket(net, laddr.toAddr(), raddr.toAddr(), syscall.SOCK_STREAM, 0, "dial", sockaddrToTCP)
171
// The opposite can also happen: if we ask the kernel to pick an appropriate
172
// originating local address, sometimes it picks one that is already in use.
173
// So if the error is EADDRNOTAVAIL, we have to try again too, just for
174
// a different reason.
176
// The kernel socket code is no doubt enjoying watching us squirm.
177
for i := 0; i < 2 && (laddr == nil || laddr.Port == 0) && (selfConnect(fd, err) || spuriousENOTAVAIL(err)); i++ {
181
fd, err = internetSocket(net, laddr.toAddr(), raddr.toAddr(), deadline, syscall.SOCK_STREAM, 0, "dial", sockaddrToTCP)
268
187
return newTCPConn(fd), nil
271
func selfConnect(fd *netFD) bool {
190
func selfConnect(fd *netFD, err error) bool {
191
// If the connect failed, we clearly didn't connect to ourselves.
272
196
// The socket constructor can return an fd with raddr nil under certain
273
197
// unknown conditions. The errors in the calls there to Getpeername
274
198
// are discarded, but we can't catch the problem there because those
285
209
return l.Port == r.Port && l.IP.Equal(r.IP)
288
// TCPListener is a TCP network listener.
289
// Clients should typically use variables of type Listener
290
// instead of assuming TCP.
212
func spuriousENOTAVAIL(err error) bool {
213
e, ok := err.(*OpError)
214
return ok && e.Err == syscall.EADDRNOTAVAIL
217
// TCPListener is a TCP network listener. Clients should typically
218
// use variables of type Listener instead of assuming TCP.
291
219
type TCPListener struct {
295
// ListenTCP announces on the TCP address laddr and returns a TCP listener.
296
// Net must be "tcp", "tcp4", or "tcp6".
297
// If laddr has a port of 0, it means to listen on some available port.
298
// The caller can use l.Addr() to retrieve the chosen address.
299
func ListenTCP(net string, laddr *TCPAddr) (*TCPListener, error) {
300
fd, err := internetSocket(net, laddr.toAddr(), nil, syscall.SOCK_STREAM, 0, "listen", sockaddrToTCP)
304
err = syscall.Listen(fd.sysfd, listenerBacklog)
306
closesocket(fd.sysfd)
307
return nil, &OpError{"listen", net, laddr, err}
309
l := new(TCPListener)
314
// AcceptTCP accepts the next incoming call and returns the new connection
315
// and the remote address.
316
func (l *TCPListener) AcceptTCP() (c *TCPConn, err error) {
317
if l == nil || l.fd == nil || l.fd.sysfd < 0 {
223
// AcceptTCP accepts the next incoming call and returns the new
224
// connection and the remote address.
225
func (l *TCPListener) AcceptTCP() (*TCPConn, error) {
226
if l == nil || l.fd == nil {
318
227
return nil, syscall.EINVAL
320
229
fd, err := l.fd.accept(sockaddrToTCP)
324
233
return newTCPConn(fd), nil
327
// Accept implements the Accept method in the Listener interface;
328
// it waits for the next call and returns a generic Conn.
329
func (l *TCPListener) Accept() (c Conn, err error) {
330
c1, err := l.AcceptTCP()
236
// Accept implements the Accept method in the Listener interface; it
237
// waits for the next call and returns a generic Conn.
238
func (l *TCPListener) Accept() (Conn, error) {
239
c, err := l.AcceptTCP()
337
246
// Close stops listening on the TCP address.
355
264
return setDeadline(l.fd, t)
358
// File returns a copy of the underlying os.File, set to blocking mode.
359
// It is the caller's responsibility to close f when finished.
267
// File returns a copy of the underlying os.File, set to blocking
268
// mode. It is the caller's responsibility to close f when finished.
360
269
// Closing l does not affect f, and closing f does not affect l.
271
// The returned os.File's file descriptor is different from the
272
// connection's. Attempting to change properties of the original
273
// using this duplicate may or may not have the desired effect.
361
274
func (l *TCPListener) File() (f *os.File, err error) { return l.fd.dup() }
276
// ListenTCP announces on the TCP address laddr and returns a TCP
277
// listener. Net must be "tcp", "tcp4", or "tcp6". If laddr has a
278
// port of 0, ListenTCP will choose an available port. The caller can
279
// use the Addr method of TCPListener to retrieve the chosen address.
280
func ListenTCP(net string, laddr *TCPAddr) (*TCPListener, error) {
282
case "tcp", "tcp4", "tcp6":
284
return nil, UnknownNetworkError(net)
289
fd, err := internetSocket(net, laddr.toAddr(), nil, noDeadline, syscall.SOCK_STREAM, 0, "listen", sockaddrToTCP)
293
err = syscall.Listen(fd.sysfd, listenerBacklog)
296
return nil, &OpError{"listen", net, laddr, err}
298
return &TCPListener{fd}, nil