Source file
src/net/tcpsock.go
Documentation: net
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), nil
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 func (c *TCPConn) WriteTo(w io.Writer) (int64, error) {
139 if !c.ok() {
140 return 0, syscall.EINVAL
141 }
142 n, err := c.writeTo(w)
143 if err != nil && err != io.EOF {
144 err = &OpError{Op: "writeto", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
145 }
146 return n, err
147 }
148
149
150
151 func (c *TCPConn) CloseRead() error {
152 if !c.ok() {
153 return syscall.EINVAL
154 }
155 if err := c.fd.closeRead(); 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 func (c *TCPConn) CloseWrite() error {
164 if !c.ok() {
165 return syscall.EINVAL
166 }
167 if err := c.fd.closeWrite(); err != nil {
168 return &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
169 }
170 return nil
171 }
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187 func (c *TCPConn) SetLinger(sec int) error {
188 if !c.ok() {
189 return syscall.EINVAL
190 }
191 if err := setLinger(c.fd, sec); err != nil {
192 return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
193 }
194 return nil
195 }
196
197
198
199 func (c *TCPConn) SetKeepAlive(keepalive bool) error {
200 if !c.ok() {
201 return syscall.EINVAL
202 }
203 if err := setKeepAlive(c.fd, keepalive); err != nil {
204 return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
205 }
206 return nil
207 }
208
209
210 func (c *TCPConn) SetKeepAlivePeriod(d time.Duration) error {
211 if !c.ok() {
212 return syscall.EINVAL
213 }
214 if err := setKeepAlivePeriod(c.fd, d); 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
221
222
223
224 func (c *TCPConn) SetNoDelay(noDelay bool) error {
225 if !c.ok() {
226 return syscall.EINVAL
227 }
228 if err := setNoDelay(c.fd, noDelay); err != nil {
229 return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
230 }
231 return nil
232 }
233
234
235
236
237
238
239
240
241
242
243 func (c *TCPConn) MultipathTCP() (bool, error) {
244 if !c.ok() {
245 return false, syscall.EINVAL
246 }
247 return isUsingMultipathTCP(c.fd), nil
248 }
249
250 func newTCPConn(fd *netFD, keepAlive time.Duration, keepAliveHook func(time.Duration)) *TCPConn {
251 setNoDelay(fd, true)
252 if keepAlive == 0 {
253 keepAlive = defaultTCPKeepAlive
254 }
255 if keepAlive > 0 {
256 setKeepAlive(fd, true)
257 setKeepAlivePeriod(fd, keepAlive)
258 if keepAliveHook != nil {
259 keepAliveHook(keepAlive)
260 }
261 }
262 return &TCPConn{conn{fd}}
263 }
264
265
266
267
268
269
270
271
272 func DialTCP(network string, laddr, raddr *TCPAddr) (*TCPConn, error) {
273 switch network {
274 case "tcp", "tcp4", "tcp6":
275 default:
276 return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: UnknownNetworkError(network)}
277 }
278 if raddr == nil {
279 return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: nil, Err: errMissingAddress}
280 }
281 sd := &sysDialer{network: network, address: raddr.String()}
282 c, err := sd.dialTCP(context.Background(), laddr, raddr)
283 if err != nil {
284 return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: err}
285 }
286 return c, nil
287 }
288
289
290
291 type TCPListener struct {
292 fd *netFD
293 lc ListenConfig
294 }
295
296
297
298
299
300
301 func (l *TCPListener) SyscallConn() (syscall.RawConn, error) {
302 if !l.ok() {
303 return nil, syscall.EINVAL
304 }
305 return newRawListener(l.fd), nil
306 }
307
308
309
310 func (l *TCPListener) AcceptTCP() (*TCPConn, error) {
311 if !l.ok() {
312 return nil, syscall.EINVAL
313 }
314 c, err := l.accept()
315 if err != nil {
316 return nil, &OpError{Op: "accept", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
317 }
318 return c, nil
319 }
320
321
322
323 func (l *TCPListener) Accept() (Conn, error) {
324 if !l.ok() {
325 return nil, syscall.EINVAL
326 }
327 c, err := l.accept()
328 if err != nil {
329 return nil, &OpError{Op: "accept", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
330 }
331 return c, nil
332 }
333
334
335
336 func (l *TCPListener) Close() error {
337 if !l.ok() {
338 return syscall.EINVAL
339 }
340 if err := l.close(); err != nil {
341 return &OpError{Op: "close", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
342 }
343 return nil
344 }
345
346
347
348
349 func (l *TCPListener) Addr() Addr { return l.fd.laddr }
350
351
352
353 func (l *TCPListener) SetDeadline(t time.Time) error {
354 if !l.ok() {
355 return syscall.EINVAL
356 }
357 return l.fd.SetDeadline(t)
358 }
359
360
361
362
363
364
365
366
367 func (l *TCPListener) File() (f *os.File, err error) {
368 if !l.ok() {
369 return nil, syscall.EINVAL
370 }
371 f, err = l.file()
372 if err != nil {
373 return nil, &OpError{Op: "file", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
374 }
375 return
376 }
377
378
379
380
381
382
383
384
385
386
387 func ListenTCP(network string, laddr *TCPAddr) (*TCPListener, error) {
388 switch network {
389 case "tcp", "tcp4", "tcp6":
390 default:
391 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: UnknownNetworkError(network)}
392 }
393 if laddr == nil {
394 laddr = &TCPAddr{}
395 }
396 sl := &sysListener{network: network, address: laddr.String()}
397 ln, err := sl.listenTCP(context.Background(), laddr)
398 if err != nil {
399 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: err}
400 }
401 return ln, nil
402 }
403
404
405 func roundDurationUp(d time.Duration, to time.Duration) time.Duration {
406 return (d + to - 1) / to
407 }
408
View as plain text