1// Copyright 2020 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//go:build unix || windows
6
7package net
8
9import (
10	"internal/poll"
11	"runtime"
12	"syscall"
13	"time"
14)
15
16// Network file descriptor.
17type netFD struct {
18	pfd poll.FD
19
20	// immutable until Close
21	family      int
22	sotype      int
23	isConnected bool // handshake completed or use of association with peer
24	net         string
25	laddr       Addr
26	raddr       Addr
27}
28
29func (fd *netFD) setAddr(laddr, raddr Addr) {
30	fd.laddr = laddr
31	fd.raddr = raddr
32	runtime.SetFinalizer(fd, (*netFD).Close)
33}
34
35func (fd *netFD) Close() error {
36	runtime.SetFinalizer(fd, nil)
37	return fd.pfd.Close()
38}
39
40func (fd *netFD) shutdown(how int) error {
41	err := fd.pfd.Shutdown(how)
42	runtime.KeepAlive(fd)
43	return wrapSyscallError("shutdown", err)
44}
45
46func (fd *netFD) closeRead() error {
47	return fd.shutdown(syscall.SHUT_RD)
48}
49
50func (fd *netFD) closeWrite() error {
51	return fd.shutdown(syscall.SHUT_WR)
52}
53
54func (fd *netFD) Read(p []byte) (n int, err error) {
55	n, err = fd.pfd.Read(p)
56	runtime.KeepAlive(fd)
57	return n, wrapSyscallError(readSyscallName, err)
58}
59
60func (fd *netFD) readFrom(p []byte) (n int, sa syscall.Sockaddr, err error) {
61	n, sa, err = fd.pfd.ReadFrom(p)
62	runtime.KeepAlive(fd)
63	return n, sa, wrapSyscallError(readFromSyscallName, err)
64}
65func (fd *netFD) readFromInet4(p []byte, from *syscall.SockaddrInet4) (n int, err error) {
66	n, err = fd.pfd.ReadFromInet4(p, from)
67	runtime.KeepAlive(fd)
68	return n, wrapSyscallError(readFromSyscallName, err)
69}
70
71func (fd *netFD) readFromInet6(p []byte, from *syscall.SockaddrInet6) (n int, err error) {
72	n, err = fd.pfd.ReadFromInet6(p, from)
73	runtime.KeepAlive(fd)
74	return n, wrapSyscallError(readFromSyscallName, err)
75}
76
77func (fd *netFD) readMsg(p []byte, oob []byte, flags int) (n, oobn, retflags int, sa syscall.Sockaddr, err error) {
78	n, oobn, retflags, sa, err = fd.pfd.ReadMsg(p, oob, flags)
79	runtime.KeepAlive(fd)
80	return n, oobn, retflags, sa, wrapSyscallError(readMsgSyscallName, err)
81}
82
83func (fd *netFD) readMsgInet4(p []byte, oob []byte, flags int, sa *syscall.SockaddrInet4) (n, oobn, retflags int, err error) {
84	n, oobn, retflags, err = fd.pfd.ReadMsgInet4(p, oob, flags, sa)
85	runtime.KeepAlive(fd)
86	return n, oobn, retflags, wrapSyscallError(readMsgSyscallName, err)
87}
88
89func (fd *netFD) readMsgInet6(p []byte, oob []byte, flags int, sa *syscall.SockaddrInet6) (n, oobn, retflags int, err error) {
90	n, oobn, retflags, err = fd.pfd.ReadMsgInet6(p, oob, flags, sa)
91	runtime.KeepAlive(fd)
92	return n, oobn, retflags, wrapSyscallError(readMsgSyscallName, err)
93}
94
95func (fd *netFD) Write(p []byte) (nn int, err error) {
96	nn, err = fd.pfd.Write(p)
97	runtime.KeepAlive(fd)
98	return nn, wrapSyscallError(writeSyscallName, err)
99}
100
101func (fd *netFD) writeTo(p []byte, sa syscall.Sockaddr) (n int, err error) {
102	n, err = fd.pfd.WriteTo(p, sa)
103	runtime.KeepAlive(fd)
104	return n, wrapSyscallError(writeToSyscallName, err)
105}
106
107func (fd *netFD) writeToInet4(p []byte, sa *syscall.SockaddrInet4) (n int, err error) {
108	n, err = fd.pfd.WriteToInet4(p, sa)
109	runtime.KeepAlive(fd)
110	return n, wrapSyscallError(writeToSyscallName, err)
111}
112
113func (fd *netFD) writeToInet6(p []byte, sa *syscall.SockaddrInet6) (n int, err error) {
114	n, err = fd.pfd.WriteToInet6(p, sa)
115	runtime.KeepAlive(fd)
116	return n, wrapSyscallError(writeToSyscallName, err)
117}
118
119func (fd *netFD) writeMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oobn int, err error) {
120	n, oobn, err = fd.pfd.WriteMsg(p, oob, sa)
121	runtime.KeepAlive(fd)
122	return n, oobn, wrapSyscallError(writeMsgSyscallName, err)
123}
124
125func (fd *netFD) writeMsgInet4(p []byte, oob []byte, sa *syscall.SockaddrInet4) (n int, oobn int, err error) {
126	n, oobn, err = fd.pfd.WriteMsgInet4(p, oob, sa)
127	runtime.KeepAlive(fd)
128	return n, oobn, wrapSyscallError(writeMsgSyscallName, err)
129}
130
131func (fd *netFD) writeMsgInet6(p []byte, oob []byte, sa *syscall.SockaddrInet6) (n int, oobn int, err error) {
132	n, oobn, err = fd.pfd.WriteMsgInet6(p, oob, sa)
133	runtime.KeepAlive(fd)
134	return n, oobn, wrapSyscallError(writeMsgSyscallName, err)
135}
136
137func (fd *netFD) SetDeadline(t time.Time) error {
138	return fd.pfd.SetDeadline(t)
139}
140
141func (fd *netFD) SetReadDeadline(t time.Time) error {
142	return fd.pfd.SetReadDeadline(t)
143}
144
145func (fd *netFD) SetWriteDeadline(t time.Time) error {
146	return fd.pfd.SetWriteDeadline(t)
147}
148