Source file
src/net/tcpsock.go
1
2
3
4
5 package net
6
7 import (
8 "context"
9 "internal/itoa"
10 "io"
11 "net/netip"
12 "os"
13 "syscall"
14 "time"
15 )
16
17
18
19
20
21 type TCPAddr struct {
22 IP IP
23 Port int
24 Zone string
25 }
26
27
28
29
30
31
32 func (a *TCPAddr) AddrPort() netip.AddrPort {
33 if a == nil {
34 return netip.AddrPort{}
35 }
36 na, _ := netip.AddrFromSlice(a.IP)
37 na = na.WithZone(a.Zone)
38 return netip.AddrPortFrom(na, uint16(a.Port))
39 }
40
41
42 func (a *TCPAddr) Network() string { return "tcp" }
43
44 func (a *TCPAddr) String() string {
45 if a == nil {
46 return "<nil>"
47 }
48 ip := ipEmptyString(a.IP)
49 if a.Zone != "" {
50 return JoinHostPort(ip+"%"+a.Zone, itoa.Itoa(a.Port))
51 }
52 return JoinHostPort(ip, itoa.Itoa(a.Port))
53 }
54
55 func (a *TCPAddr) isWildcard() bool {
56 if a == nil || a.IP == nil {
57 return true
58 }
59 return a.IP.IsUnspecified()
60 }
61
62 func (a *TCPAddr) opAddr() Addr {
63 if a == nil {
64 return nil
65 }
66 return a
67 }
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84 func ResolveTCPAddr(network, address string) (*TCPAddr, error) {
85 switch network {
86 case "tcp", "tcp4", "tcp6":
87 case "":
88 network = "tcp"
89 default:
90 return nil, UnknownNetworkError(network)
91 }
92 addrs, err := DefaultResolver.internetAddrList(context.Background(), network, address)
93 if err != nil {
94 return nil, err
95 }
96 return addrs.forResolve(network, address).(*TCPAddr), nil
97 }
98
99
100
101
102 func TCPAddrFromAddrPort(addr netip.AddrPort) *TCPAddr {
103 return &TCPAddr{
104 IP: addr.Addr().AsSlice(),
105 Zone: addr.Addr().Zone(),
106 Port: int(addr.Port()),
107 }
108 }
109
110
111
112 type TCPConn struct {
113 conn
114 }
115
116
117
118 func (c *TCPConn) SyscallConn() (syscall.RawConn, error) {
119 if !c.ok() {
120 return nil, syscall.EINVAL
121 }
122 return newRawConn(c.fd)
123 }
124
125
126 func (c *TCPConn) ReadFrom(r io.Reader) (int64, error) {
127 if !c.ok() {
128 return 0, syscall.EINVAL
129 }
130 n, err := c.readFrom(r)
131 if err != nil && err != io.EOF {
132 err = &OpError{Op: "readfrom", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
133 }
134 return n, err
135 }
136
137
138
139 func (c *TCPConn) CloseRead() error {
140 if !c.ok() {
141 return syscall.EINVAL
142 }
143 if err := c.fd.closeRead(); err != nil {
144 return &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
145 }
146 return nil
147 }
148
149
150
151 func (c *TCPConn) CloseWrite() error {
152 if !c.ok() {
153 return syscall.EINVAL
154 }
155 if err := c.fd.closeWrite(); err != nil {
156 return &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
157 }
158 return nil
159 }
160
161
162
163
164
165
166
167
168
169
170
171
172
173 func (c *TCPConn) SetLinger(sec int) error {
174 if !c.ok() {
175 return syscall.EINVAL
176 }
177 if err := setLinger(c.fd, sec); err != nil {
178 return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
179 }
180 return nil
181 }
182
183
184
185 func (c *TCPConn) SetKeepAlive(keepalive bool) error {
186 if !c.ok() {
187 return syscall.EINVAL
188 }
189 if err := setKeepAlive(c.fd, keepalive); err != nil {
190 return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
191 }
192 return nil
193 }
194
195
196 func (c *TCPConn) SetKeepAlivePeriod(d time.Duration) error {
197 if !c.ok() {
198 return syscall.EINVAL
199 }
200 if err := setKeepAlivePeriod(c.fd, d); err != nil {
201 return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
202 }
203 return nil
204 }
205
206
207
208
209
210 func (c *TCPConn) SetNoDelay(noDelay bool) error {
211 if !c.ok() {
212 return syscall.EINVAL
213 }
214 if err := setNoDelay(c.fd, noDelay); err != nil {
215 return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
216 }
217 return nil
218 }
219
220 func newTCPConn(fd *netFD, keepAlive time.Duration, keepAliveHook func(time.Duration)) *TCPConn {
221 setNoDelay(fd, true)
222 if keepAlive == 0 {
223 keepAlive = defaultTCPKeepAlive
224 }
225 if keepAlive > 0 {
226 setKeepAlive(fd, true)
227 setKeepAlivePeriod(fd, keepAlive)
228 if keepAliveHook != nil {
229 keepAliveHook(keepAlive)
230 }
231 }
232 return &TCPConn{conn{fd}}
233 }
234
235
236
237
238
239
240
241
242 func DialTCP(network string, laddr, raddr *TCPAddr) (*TCPConn, error) {
243 switch network {
244 case "tcp", "tcp4", "tcp6":
245 default:
246 return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: UnknownNetworkError(network)}
247 }
248 if raddr == nil {
249 return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: nil, Err: errMissingAddress}
250 }
251 sd := &sysDialer{network: network, address: raddr.String()}
252 c, err := sd.dialTCP(context.Background(), laddr, raddr)
253 if err != nil {
254 return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: err}
255 }
256 return c, nil
257 }
258
259
260
261 type TCPListener struct {
262 fd *netFD
263 lc ListenConfig
264 }
265
266
267
268
269
270
271 func (l *TCPListener) SyscallConn() (syscall.RawConn, error) {
272 if !l.ok() {
273 return nil, syscall.EINVAL
274 }
275 return newRawListener(l.fd)
276 }
277
278
279
280 func (l *TCPListener) AcceptTCP() (*TCPConn, error) {
281 if !l.ok() {
282 return nil, syscall.EINVAL
283 }
284 c, err := l.accept()
285 if err != nil {
286 return nil, &OpError{Op: "accept", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
287 }
288 return c, nil
289 }
290
291
292
293 func (l *TCPListener) Accept() (Conn, error) {
294 if !l.ok() {
295 return nil, syscall.EINVAL
296 }
297 c, err := l.accept()
298 if err != nil {
299 return nil, &OpError{Op: "accept", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
300 }
301 return c, nil
302 }
303
304
305
306 func (l *TCPListener) Close() error {
307 if !l.ok() {
308 return syscall.EINVAL
309 }
310 if err := l.close(); err != nil {
311 return &OpError{Op: "close", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
312 }
313 return nil
314 }
315
316
317
318
319 func (l *TCPListener) Addr() Addr { return l.fd.laddr }
320
321
322
323 func (l *TCPListener) SetDeadline(t time.Time) error {
324 if !l.ok() {
325 return syscall.EINVAL
326 }
327 if err := l.fd.pfd.SetDeadline(t); err != nil {
328 return &OpError{Op: "set", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
329 }
330 return nil
331 }
332
333
334
335
336
337
338
339
340 func (l *TCPListener) File() (f *os.File, err error) {
341 if !l.ok() {
342 return nil, syscall.EINVAL
343 }
344 f, err = l.file()
345 if err != nil {
346 return nil, &OpError{Op: "file", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
347 }
348 return
349 }
350
351
352
353
354
355
356
357
358
359
360 func ListenTCP(network string, laddr *TCPAddr) (*TCPListener, error) {
361 switch network {
362 case "tcp", "tcp4", "tcp6":
363 default:
364 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: UnknownNetworkError(network)}
365 }
366 if laddr == nil {
367 laddr = &TCPAddr{}
368 }
369 sl := &sysListener{network: network, address: laddr.String()}
370 ln, err := sl.listenTCP(context.Background(), laddr)
371 if err != nil {
372 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: err}
373 }
374 return ln, nil
375 }
376
377
378 func roundDurationUp(d time.Duration, to time.Duration) time.Duration {
379 return (d + to - 1) / to
380 }
381
View as plain text