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) *TCPConn {
221 c := &TCPConn{conn{fd}}
222 setNoDelay(c.fd, true)
223 return c
224 }
225
226
227
228
229
230
231
232
233 func DialTCP(network string, laddr, raddr *TCPAddr) (*TCPConn, error) {
234 switch network {
235 case "tcp", "tcp4", "tcp6":
236 default:
237 return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: UnknownNetworkError(network)}
238 }
239 if raddr == nil {
240 return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: nil, Err: errMissingAddress}
241 }
242 sd := &sysDialer{network: network, address: raddr.String()}
243 c, err := sd.dialTCP(context.Background(), laddr, raddr)
244 if err != nil {
245 return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: err}
246 }
247 return c, nil
248 }
249
250
251
252 type TCPListener struct {
253 fd *netFD
254 lc ListenConfig
255 }
256
257
258
259
260
261
262 func (l *TCPListener) SyscallConn() (syscall.RawConn, error) {
263 if !l.ok() {
264 return nil, syscall.EINVAL
265 }
266 return newRawListener(l.fd)
267 }
268
269
270
271 func (l *TCPListener) AcceptTCP() (*TCPConn, error) {
272 if !l.ok() {
273 return nil, syscall.EINVAL
274 }
275 c, err := l.accept()
276 if err != nil {
277 return nil, &OpError{Op: "accept", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
278 }
279 return c, nil
280 }
281
282
283
284 func (l *TCPListener) Accept() (Conn, error) {
285 if !l.ok() {
286 return nil, syscall.EINVAL
287 }
288 c, err := l.accept()
289 if err != nil {
290 return nil, &OpError{Op: "accept", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
291 }
292 return c, nil
293 }
294
295
296
297 func (l *TCPListener) Close() error {
298 if !l.ok() {
299 return syscall.EINVAL
300 }
301 if err := l.close(); err != nil {
302 return &OpError{Op: "close", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
303 }
304 return nil
305 }
306
307
308
309
310 func (l *TCPListener) Addr() Addr { return l.fd.laddr }
311
312
313
314 func (l *TCPListener) SetDeadline(t time.Time) error {
315 if !l.ok() {
316 return syscall.EINVAL
317 }
318 if err := l.fd.pfd.SetDeadline(t); err != nil {
319 return &OpError{Op: "set", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
320 }
321 return nil
322 }
323
324
325
326
327
328
329
330
331 func (l *TCPListener) File() (f *os.File, err error) {
332 if !l.ok() {
333 return nil, syscall.EINVAL
334 }
335 f, err = l.file()
336 if err != nil {
337 return nil, &OpError{Op: "file", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
338 }
339 return
340 }
341
342
343
344
345
346
347
348
349
350
351 func ListenTCP(network string, laddr *TCPAddr) (*TCPListener, error) {
352 switch network {
353 case "tcp", "tcp4", "tcp6":
354 default:
355 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: UnknownNetworkError(network)}
356 }
357 if laddr == nil {
358 laddr = &TCPAddr{}
359 }
360 sl := &sysListener{network: network, address: laddr.String()}
361 ln, err := sl.listenTCP(context.Background(), laddr)
362 if err != nil {
363 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: err}
364 }
365 return ln, nil
366 }
367
368
369 func roundDurationUp(d time.Duration, to time.Duration) time.Duration {
370 return (d + to - 1) / to
371 }
372
View as plain text