OXIESEC PANEL
- Current Dir:
/
/
opt
/
golang
/
1.22.0
/
src
/
net
Server IP: 2a02:4780:11:1084:0:327f:3464:10
Upload:
Create Dir:
Name
Size
Modified
Perms
📁
..
-
02/02/2024 06:09:55 PM
rwxr-xr-x
📄
addrselect.go
9.69 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
addrselect_test.go
8.5 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
cgo_aix.go
582 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
cgo_android.go
272 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
cgo_bsd.go
343 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
cgo_darwin.go
298 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
cgo_linux.go
642 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
cgo_netbsd.go
276 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
cgo_openbsd.go
276 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
cgo_resnew.go
580 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
cgo_resold.go
579 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
cgo_socknew.go
753 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
cgo_sockold.go
842 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
cgo_solaris.go
343 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
cgo_stub.go
1.33 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
cgo_unix.go
11.35 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
cgo_unix_cgo.go
2.24 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
cgo_unix_cgo_darwin.go
461 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
cgo_unix_cgo_res.go
911 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
cgo_unix_cgo_resn.go
998 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
cgo_unix_syscall.go
2.99 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
cgo_unix_test.go
1.44 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
conf.go
15.63 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
conf_test.go
12.28 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
conn_test.go
1.82 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
dial.go
25.68 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
dial_test.go
30.14 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
dial_unix_test.go
2.77 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
dnsclient.go
5.65 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
dnsclient_test.go
1.51 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
dnsclient_unix.go
24.26 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
dnsclient_unix_test.go
69.13 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
dnsconfig.go
1.73 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
dnsconfig_unix.go
4.16 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
dnsconfig_unix_test.go
7.07 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
dnsconfig_windows.go
1.6 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
dnsname_test.go
1.96 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
error_plan9.go
224 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
error_plan9_test.go
437 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
error_posix.go
543 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
error_posix_test.go
981 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
error_test.go
20.32 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
error_unix.go
382 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
error_unix_test.go
723 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
error_windows.go
355 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
error_windows_test.go
757 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
example_test.go
8.45 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
external_test.go
4.05 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
fd_fake.go
3.79 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
fd_js.go
627 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
fd_plan9.go
3.56 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
fd_posix.go
4.29 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
fd_unix.go
5.43 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
fd_wasip1.go
496 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
fd_windows.go
6.14 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
file.go
1.69 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
file_plan9.go
2.72 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
file_stub.go
481 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
file_test.go
6.43 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
file_unix.go
2.5 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
file_unix_test.go
2.07 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
file_wasip1.go
2.2 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
file_wasip1_test.go
3.76 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
file_windows.go
521 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
hook.go
894 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
hook_plan9.go
211 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
hook_unix.go
658 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
hook_windows.go
720 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
hosts.go
3.48 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
hosts_test.go
5.6 KB
02/02/2024 06:09:55 PM
rw-r--r--
📁
http
-
02/02/2024 06:09:55 PM
rwxr-xr-x
📄
interface.go
7.26 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
interface_aix.go
4.46 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
interface_bsd.go
2.82 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
interface_bsd_test.go
1.44 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
interface_bsdvar.go
718 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
interface_darwin.go
1.29 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
interface_freebsd.go
1.29 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
interface_linux.go
6.96 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
interface_linux_test.go
3.65 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
interface_plan9.go
4.71 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
interface_solaris.go
2.13 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
interface_stub.go
814 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
interface_test.go
9.76 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
interface_unix_test.go
4.85 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
interface_windows.go
5.43 KB
02/02/2024 06:09:55 PM
rw-r--r--
📁
internal
-
02/02/2024 06:09:55 PM
rwxr-xr-x
📄
ip.go
13.88 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
ip_test.go
25.6 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
iprawsock.go
7.11 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
iprawsock_plan9.go
874 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
iprawsock_posix.go
3.89 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
iprawsock_test.go
5.98 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
ipsock.go
9.05 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
ipsock_plan9.go
7.48 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
ipsock_plan9_test.go
645 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
ipsock_posix.go
7.86 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
ipsock_test.go
6.81 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
listen_test.go
20.5 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
lookup.go
29.04 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
lookup_plan9.go
9.94 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
lookup_test.go
40.62 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
lookup_unix.go
3.35 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
lookup_windows.go
13.8 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
lookup_windows_test.go
8.93 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
mac.go
1.88 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
mac_test.go
3.26 KB
02/02/2024 06:09:55 PM
rw-r--r--
📁
mail
-
02/02/2024 06:09:55 PM
rwxr-xr-x
📄
main_cloexec_test.go
693 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
main_conf_test.go
1.39 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
main_noconf_test.go
467 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
main_plan9_test.go
392 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
main_posix_test.go
1.37 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
main_test.go
7.53 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
main_unix_test.go
1.19 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
main_wasm_test.go
284 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
main_windows_test.go
1 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
mockserver_test.go
10.77 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
mptcpsock_linux.go
3.96 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
mptcpsock_linux_test.go
4.06 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
mptcpsock_stub.go
542 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
net.go
24.56 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
net_fake.go
26.36 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
net_fake_test.go
2.79 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
net_test.go
14 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
net_windows_test.go
16.28 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
netcgo_off.go
222 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
netcgo_on.go
220 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
netgo_netcgo.go
453 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
netgo_off.go
220 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
netgo_on.go
218 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📁
netip
-
02/02/2024 06:09:55 PM
rwxr-xr-x
📄
nss.go
5.48 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
nss_test.go
3.4 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
packetconn_test.go
3.02 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
parse.go
6.04 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
parse_test.go
1.55 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
pipe.go
5.43 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
pipe_test.go
1.2 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
platform_test.go
4.33 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
port.go
1.46 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
port_test.go
1.34 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
port_unix.go
1.24 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
protoconn_test.go
7.44 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
rawconn.go
2.7 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
rawconn_stub_test.go
631 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
rawconn_test.go
4.33 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
rawconn_unix_test.go
2.96 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
rawconn_windows_test.go
3.12 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
resolverdialfunc_test.go
8.25 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
rlimit_js.go
346 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
rlimit_unix.go
1.1 KB
02/02/2024 06:09:55 PM
rw-r--r--
📁
rpc
-
02/02/2024 06:09:55 PM
rwxr-xr-x
📄
sendfile_linux.go
1.12 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
sendfile_linux_test.go
1.93 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
sendfile_stub.go
344 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
sendfile_test.go
8.25 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
sendfile_unix_alt.go
2.04 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
sendfile_windows.go
1.02 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
server_test.go
11.67 KB
02/02/2024 06:09:55 PM
rw-r--r--
📁
smtp
-
02/02/2024 06:09:55 PM
rwxr-xr-x
📄
sock_bsd.go
918 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
sock_cloexec.go
1.38 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
sock_linux.go
993 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
sock_linux_test.go
575 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
sock_plan9.go
262 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
sock_posix.go
6.29 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
sock_stub.go
390 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
sock_windows.go
802 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
sockaddr_posix.go
1.45 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
sockopt_aix.go
1.43 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
sockopt_bsd.go
2.21 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
sockopt_fake.go
955 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
sockopt_linux.go
1.25 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
sockopt_plan9.go
406 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
sockopt_posix.go
2.13 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
sockopt_solaris.go
1.25 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
sockopt_windows.go
1.51 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
sockoptip_bsdvar.go
867 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
sockoptip_linux.go
735 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
sockoptip_posix.go
1.38 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
sockoptip_stub.go
769 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
sockoptip_windows.go
786 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
splice_linux.go
1.69 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
splice_stub.go
376 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
splice_test.go
13.48 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
sys_cloexec.go
962 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
tcpsock.go
11.75 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
tcpsock_plan9.go
2.18 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
tcpsock_posix.go
6.16 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
tcpsock_test.go
17.68 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
tcpsock_unix_test.go
2.34 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
tcpsockopt_darwin.go
770 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
tcpsockopt_dragonfly.go
698 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
tcpsockopt_openbsd.go
365 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
tcpsockopt_plan9.go
525 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
tcpsockopt_posix.go
442 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
tcpsockopt_solaris.go
1.15 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
tcpsockopt_stub.go
399 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
tcpsockopt_unix.go
722 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
tcpsockopt_windows.go
741 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📁
testdata
-
02/02/2024 06:09:55 PM
rwxr-xr-x
📁
textproto
-
02/02/2024 06:09:55 PM
rwxr-xr-x
📄
timeout_test.go
29.11 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
udpsock.go
11.83 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
udpsock_plan9.go
4.64 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
udpsock_plan9_test.go
1.31 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
udpsock_posix.go
7.53 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
udpsock_test.go
17.24 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
unixsock.go
10.12 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
unixsock_linux_test.go
2.29 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
unixsock_plan9.go
1.24 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
unixsock_posix.go
6.64 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
unixsock_readmsg_cloexec.go
654 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
unixsock_readmsg_cmsg_cloexec.go
332 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
unixsock_readmsg_other.go
275 bytes
02/02/2024 06:09:55 PM
rw-r--r--
📄
unixsock_readmsg_test.go
2.51 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
unixsock_test.go
10.64 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
unixsock_windows_test.go
2.03 KB
02/02/2024 06:09:55 PM
rw-r--r--
📁
url
-
02/02/2024 06:09:55 PM
rwxr-xr-x
📄
write_unix_test.go
1.61 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
writev_test.go
5.03 KB
02/02/2024 06:09:55 PM
rw-r--r--
📄
writev_unix.go
666 bytes
02/02/2024 06:09:55 PM
rw-r--r--
Editing: net_fake.go
Close
// Copyright 2018 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Fake networking for js/wasm and wasip1/wasm. // It is intended to allow tests of other package to pass. //go:build js || wasip1 package net import ( "context" "errors" "io" "os" "sync" "sync/atomic" "syscall" "time" ) var ( sockets sync.Map // fakeSockAddr → *netFD fakeSocketIDs sync.Map // fakeNetFD.id → *netFD fakePorts sync.Map // int (port #) → *netFD nextPortCounter atomic.Int32 ) const defaultBuffer = 65535 type fakeSockAddr struct { family int address string } func fakeAddr(sa sockaddr) fakeSockAddr { return fakeSockAddr{ family: sa.family(), address: sa.String(), } } // socket returns a network file descriptor that is ready for // I/O using the fake network. func socket(ctx context.Context, net string, family, sotype, proto int, ipv6only bool, laddr, raddr sockaddr, ctrlCtxFn func(context.Context, string, string, syscall.RawConn) error) (*netFD, error) { if raddr != nil && ctrlCtxFn != nil { return nil, os.NewSyscallError("socket", syscall.ENOTSUP) } switch sotype { case syscall.SOCK_STREAM, syscall.SOCK_SEQPACKET, syscall.SOCK_DGRAM: default: return nil, os.NewSyscallError("socket", syscall.ENOTSUP) } fd := &netFD{ family: family, sotype: sotype, net: net, } fd.fakeNetFD = newFakeNetFD(fd) if raddr == nil { if err := fakeListen(fd, laddr); err != nil { fd.Close() return nil, err } return fd, nil } if err := fakeConnect(ctx, fd, laddr, raddr); err != nil { fd.Close() return nil, err } return fd, nil } func validateResolvedAddr(net string, family int, sa sockaddr) error { validateIP := func(ip IP) error { switch family { case syscall.AF_INET: if len(ip) != 4 { return &AddrError{ Err: "non-IPv4 address", Addr: ip.String(), } } case syscall.AF_INET6: if len(ip) != 16 { return &AddrError{ Err: "non-IPv6 address", Addr: ip.String(), } } default: panic("net: unexpected address family in validateResolvedAddr") } return nil } switch net { case "tcp", "tcp4", "tcp6": sa, ok := sa.(*TCPAddr) if !ok { return &AddrError{ Err: "non-TCP address for " + net + " network", Addr: sa.String(), } } if err := validateIP(sa.IP); err != nil { return err } if sa.Port <= 0 || sa.Port >= 1<<16 { return &AddrError{ Err: "port out of range", Addr: sa.String(), } } return nil case "udp", "udp4", "udp6": sa, ok := sa.(*UDPAddr) if !ok { return &AddrError{ Err: "non-UDP address for " + net + " network", Addr: sa.String(), } } if err := validateIP(sa.IP); err != nil { return err } if sa.Port <= 0 || sa.Port >= 1<<16 { return &AddrError{ Err: "port out of range", Addr: sa.String(), } } return nil case "unix", "unixgram", "unixpacket": sa, ok := sa.(*UnixAddr) if !ok { return &AddrError{ Err: "non-Unix address for " + net + " network", Addr: sa.String(), } } if sa.Name != "" { i := len(sa.Name) - 1 for i > 0 && !os.IsPathSeparator(sa.Name[i]) { i-- } for i > 0 && os.IsPathSeparator(sa.Name[i]) { i-- } if i <= 0 { return &AddrError{ Err: "unix socket name missing path component", Addr: sa.Name, } } if _, err := os.Stat(sa.Name[:i+1]); err != nil { return &AddrError{ Err: err.Error(), Addr: sa.Name, } } } return nil default: return &AddrError{ Err: syscall.EAFNOSUPPORT.Error(), Addr: sa.String(), } } } func matchIPFamily(family int, addr sockaddr) sockaddr { convertIP := func(ip IP) IP { switch family { case syscall.AF_INET: return ip.To4() case syscall.AF_INET6: return ip.To16() default: return ip } } switch addr := addr.(type) { case *TCPAddr: ip := convertIP(addr.IP) if ip == nil || len(ip) == len(addr.IP) { return addr } return &TCPAddr{IP: ip, Port: addr.Port, Zone: addr.Zone} case *UDPAddr: ip := convertIP(addr.IP) if ip == nil || len(ip) == len(addr.IP) { return addr } return &UDPAddr{IP: ip, Port: addr.Port, Zone: addr.Zone} default: return addr } } type fakeNetFD struct { fd *netFD assignedPort int // 0 if no port has been assigned for this socket queue *packetQueue // incoming packets peer *netFD // connected peer (for outgoing packets); nil for listeners and PacketConns readDeadline atomic.Pointer[deadlineTimer] writeDeadline atomic.Pointer[deadlineTimer] fakeAddr fakeSockAddr // cached fakeSockAddr equivalent of fd.laddr // The incoming channels hold incoming connections that have not yet been accepted. // All of these channels are 1-buffered. incoming chan []*netFD // holds the queue when it has >0 but <SOMAXCONN pending connections; closed when the Listener is closed incomingFull chan []*netFD // holds the queue when it has SOMAXCONN pending connections incomingEmpty chan bool // holds true when the incoming queue is empty } func newFakeNetFD(fd *netFD) *fakeNetFD { ffd := &fakeNetFD{fd: fd} ffd.readDeadline.Store(newDeadlineTimer(noDeadline)) ffd.writeDeadline.Store(newDeadlineTimer(noDeadline)) return ffd } func (ffd *fakeNetFD) Read(p []byte) (n int, err error) { n, _, err = ffd.queue.recvfrom(ffd.readDeadline.Load(), p, false, nil) return n, err } func (ffd *fakeNetFD) Write(p []byte) (nn int, err error) { peer := ffd.peer if peer == nil { if ffd.fd.raddr == nil { return 0, os.NewSyscallError("write", syscall.ENOTCONN) } peeri, _ := sockets.Load(fakeAddr(ffd.fd.raddr.(sockaddr))) if peeri == nil { return 0, os.NewSyscallError("write", syscall.ECONNRESET) } peer = peeri.(*netFD) if peer.queue == nil { return 0, os.NewSyscallError("write", syscall.ECONNRESET) } } if peer.fakeNetFD == nil { return 0, os.NewSyscallError("write", syscall.EINVAL) } return peer.queue.write(ffd.writeDeadline.Load(), p, ffd.fd.laddr.(sockaddr)) } func (ffd *fakeNetFD) Close() (err error) { if ffd.fakeAddr != (fakeSockAddr{}) { sockets.CompareAndDelete(ffd.fakeAddr, ffd.fd) } if ffd.queue != nil { if closeErr := ffd.queue.closeRead(); err == nil { err = closeErr } } if ffd.peer != nil { if closeErr := ffd.peer.queue.closeWrite(); err == nil { err = closeErr } } ffd.readDeadline.Load().Reset(noDeadline) ffd.writeDeadline.Load().Reset(noDeadline) if ffd.incoming != nil { var ( incoming []*netFD ok bool ) select { case _, ok = <-ffd.incomingEmpty: case incoming, ok = <-ffd.incoming: case incoming, ok = <-ffd.incomingFull: } if ok { // Sends on ffd.incoming require a receive first. // Since we successfully received, no other goroutine may // send on it at this point, and we may safely close it. close(ffd.incoming) for _, c := range incoming { c.Close() } } } if ffd.assignedPort != 0 { fakePorts.CompareAndDelete(ffd.assignedPort, ffd.fd) } return err } func (ffd *fakeNetFD) closeRead() error { return ffd.queue.closeRead() } func (ffd *fakeNetFD) closeWrite() error { if ffd.peer == nil { return os.NewSyscallError("closeWrite", syscall.ENOTCONN) } return ffd.peer.queue.closeWrite() } func (ffd *fakeNetFD) accept(laddr Addr) (*netFD, error) { if ffd.incoming == nil { return nil, os.NewSyscallError("accept", syscall.EINVAL) } var ( incoming []*netFD ok bool ) select { case <-ffd.readDeadline.Load().expired: return nil, os.ErrDeadlineExceeded case incoming, ok = <-ffd.incoming: if !ok { return nil, ErrClosed } case incoming, ok = <-ffd.incomingFull: } peer := incoming[0] incoming = incoming[1:] if len(incoming) == 0 { ffd.incomingEmpty <- true } else { ffd.incoming <- incoming } return peer, nil } func (ffd *fakeNetFD) SetDeadline(t time.Time) error { err1 := ffd.SetReadDeadline(t) err2 := ffd.SetWriteDeadline(t) if err1 != nil { return err1 } return err2 } func (ffd *fakeNetFD) SetReadDeadline(t time.Time) error { dt := ffd.readDeadline.Load() if !dt.Reset(t) { ffd.readDeadline.Store(newDeadlineTimer(t)) } return nil } func (ffd *fakeNetFD) SetWriteDeadline(t time.Time) error { dt := ffd.writeDeadline.Load() if !dt.Reset(t) { ffd.writeDeadline.Store(newDeadlineTimer(t)) } return nil } const maxPacketSize = 65535 type packet struct { buf []byte bufOffset int next *packet from sockaddr } func (p *packet) clear() { p.buf = p.buf[:0] p.bufOffset = 0 p.next = nil p.from = nil } var packetPool = sync.Pool{ New: func() any { return new(packet) }, } type packetQueueState struct { head, tail *packet // unqueued packets nBytes int // number of bytes enqueued in the packet buffers starting from head readBufferBytes int // soft limit on nbytes; no more packets may be enqueued when the limit is exceeded readClosed bool // true if the reader of the queue has stopped reading writeClosed bool // true if the writer of the queue has stopped writing; the reader sees either io.EOF or syscall.ECONNRESET when they have read all buffered packets noLinger bool // if true, the reader sees ECONNRESET instead of EOF } // A packetQueue is a set of 1-buffered channels implementing a FIFO queue // of packets. type packetQueue struct { empty chan packetQueueState // contains configuration parameters when the queue is empty and not closed ready chan packetQueueState // contains the packets when non-empty or closed full chan packetQueueState // contains the packets when buffer is full and not closed } func newPacketQueue(readBufferBytes int) *packetQueue { pq := &packetQueue{ empty: make(chan packetQueueState, 1), ready: make(chan packetQueueState, 1), full: make(chan packetQueueState, 1), } pq.put(packetQueueState{ readBufferBytes: readBufferBytes, }) return pq } func (pq *packetQueue) get() packetQueueState { var q packetQueueState select { case q = <-pq.empty: case q = <-pq.ready: case q = <-pq.full: } return q } func (pq *packetQueue) put(q packetQueueState) { switch { case q.readClosed || q.writeClosed: pq.ready <- q case q.nBytes >= q.readBufferBytes: pq.full <- q case q.head == nil: if q.nBytes > 0 { defer panic("net: put with nil packet list and nonzero nBytes") } pq.empty <- q default: pq.ready <- q } } func (pq *packetQueue) closeRead() error { q := pq.get() // Discard any unread packets. for q.head != nil { p := q.head q.head = p.next p.clear() packetPool.Put(p) } q.nBytes = 0 q.readClosed = true pq.put(q) return nil } func (pq *packetQueue) closeWrite() error { q := pq.get() q.writeClosed = true pq.put(q) return nil } func (pq *packetQueue) setLinger(linger bool) error { q := pq.get() defer func() { pq.put(q) }() if q.writeClosed { return ErrClosed } q.noLinger = !linger return nil } func (pq *packetQueue) write(dt *deadlineTimer, b []byte, from sockaddr) (n int, err error) { for { dn := len(b) if dn > maxPacketSize { dn = maxPacketSize } dn, err = pq.send(dt, b[:dn], from, true) n += dn if err != nil { return n, err } b = b[dn:] if len(b) == 0 { return n, nil } } } func (pq *packetQueue) send(dt *deadlineTimer, b []byte, from sockaddr, block bool) (n int, err error) { if from == nil { return 0, os.NewSyscallError("send", syscall.EINVAL) } if len(b) > maxPacketSize { return 0, os.NewSyscallError("send", syscall.EMSGSIZE) } var q packetQueueState var full chan packetQueueState if !block { full = pq.full } select { case <-dt.expired: return 0, os.ErrDeadlineExceeded case q = <-full: pq.put(q) return 0, os.NewSyscallError("send", syscall.ENOBUFS) case q = <-pq.empty: case q = <-pq.ready: } defer func() { pq.put(q) }() // Don't allow a packet to be sent if the deadline has expired, // even if the select above chose a different branch. select { case <-dt.expired: return 0, os.ErrDeadlineExceeded default: } if q.writeClosed { return 0, ErrClosed } else if q.readClosed { return 0, os.NewSyscallError("send", syscall.ECONNRESET) } p := packetPool.Get().(*packet) p.buf = append(p.buf[:0], b...) p.from = from if q.head == nil { q.head = p } else { q.tail.next = p } q.tail = p q.nBytes += len(p.buf) return len(b), nil } func (pq *packetQueue) recvfrom(dt *deadlineTimer, b []byte, wholePacket bool, checkFrom func(sockaddr) error) (n int, from sockaddr, err error) { var q packetQueueState var empty chan packetQueueState if len(b) == 0 { // For consistency with the implementation on Unix platforms, // allow a zero-length Read to proceed if the queue is empty. // (Without this, TestZeroByteRead deadlocks.) empty = pq.empty } select { case <-dt.expired: return 0, nil, os.ErrDeadlineExceeded case q = <-empty: case q = <-pq.ready: case q = <-pq.full: } defer func() { pq.put(q) }() p := q.head if p == nil { switch { case q.readClosed: return 0, nil, ErrClosed case q.writeClosed: if q.noLinger { return 0, nil, os.NewSyscallError("recvfrom", syscall.ECONNRESET) } return 0, nil, io.EOF case len(b) == 0: return 0, nil, nil default: // This should be impossible: pq.full should only contain a non-empty list, // pq.ready should either contain a non-empty list or indicate that the // connection is closed, and we should only receive from pq.empty if // len(b) == 0. panic("net: nil packet list from non-closed packetQueue") } } select { case <-dt.expired: return 0, nil, os.ErrDeadlineExceeded default: } if checkFrom != nil { if err := checkFrom(p.from); err != nil { return 0, nil, err } } n = copy(b, p.buf[p.bufOffset:]) from = p.from if wholePacket || p.bufOffset+n == len(p.buf) { q.head = p.next q.nBytes -= len(p.buf) p.clear() packetPool.Put(p) } else { p.bufOffset += n } return n, from, nil } // setReadBuffer sets a soft limit on the number of bytes available to read // from the pipe. func (pq *packetQueue) setReadBuffer(bytes int) error { if bytes <= 0 { return os.NewSyscallError("setReadBuffer", syscall.EINVAL) } q := pq.get() // Use the queue as a lock. q.readBufferBytes = bytes pq.put(q) return nil } type deadlineTimer struct { timer chan *time.Timer expired chan struct{} } func newDeadlineTimer(deadline time.Time) *deadlineTimer { dt := &deadlineTimer{ timer: make(chan *time.Timer, 1), expired: make(chan struct{}), } dt.timer <- nil dt.Reset(deadline) return dt } // Reset attempts to reset the timer. // If the timer has already expired, Reset returns false. func (dt *deadlineTimer) Reset(deadline time.Time) bool { timer := <-dt.timer defer func() { dt.timer <- timer }() if deadline.Equal(noDeadline) { if timer != nil && timer.Stop() { timer = nil } return timer == nil } d := time.Until(deadline) if d < 0 { // Ensure that a deadline in the past takes effect immediately. defer func() { <-dt.expired }() } if timer == nil { timer = time.AfterFunc(d, func() { close(dt.expired) }) return true } if !timer.Stop() { return false } timer.Reset(d) return true } func sysSocket(family, sotype, proto int) (int, error) { return 0, os.NewSyscallError("sysSocket", syscall.ENOSYS) } func fakeListen(fd *netFD, laddr sockaddr) (err error) { wrapErr := func(err error) error { if errno, ok := err.(syscall.Errno); ok { err = os.NewSyscallError("listen", errno) } if errors.Is(err, syscall.EADDRINUSE) { return err } if laddr != nil { if _, ok := err.(*AddrError); !ok { err = &AddrError{ Err: err.Error(), Addr: laddr.String(), } } } return err } ffd := newFakeNetFD(fd) defer func() { if fd.fakeNetFD != ffd { // Failed to register listener; clean up. ffd.Close() } }() if err := ffd.assignFakeAddr(matchIPFamily(fd.family, laddr)); err != nil { return wrapErr(err) } ffd.fakeAddr = fakeAddr(fd.laddr.(sockaddr)) switch fd.sotype { case syscall.SOCK_STREAM, syscall.SOCK_SEQPACKET: ffd.incoming = make(chan []*netFD, 1) ffd.incomingFull = make(chan []*netFD, 1) ffd.incomingEmpty = make(chan bool, 1) ffd.incomingEmpty <- true case syscall.SOCK_DGRAM: ffd.queue = newPacketQueue(defaultBuffer) default: return wrapErr(syscall.EINVAL) } fd.fakeNetFD = ffd if _, dup := sockets.LoadOrStore(ffd.fakeAddr, fd); dup { fd.fakeNetFD = nil return wrapErr(syscall.EADDRINUSE) } return nil } func fakeConnect(ctx context.Context, fd *netFD, laddr, raddr sockaddr) error { wrapErr := func(err error) error { if errno, ok := err.(syscall.Errno); ok { err = os.NewSyscallError("connect", errno) } if errors.Is(err, syscall.EADDRINUSE) { return err } if terr, ok := err.(interface{ Timeout() bool }); !ok || !terr.Timeout() { // For consistency with the net implementation on other platforms, // if we don't need to preserve the Timeout-ness of err we should // wrap it in an AddrError. (Unfortunately we can't wrap errors // that convey structured information, because AddrError reduces // the wrapped Err to a flat string.) if _, ok := err.(*AddrError); !ok { err = &AddrError{ Err: err.Error(), Addr: raddr.String(), } } } return err } if fd.isConnected { return wrapErr(syscall.EISCONN) } if ctx.Err() != nil { return wrapErr(syscall.ETIMEDOUT) } fd.raddr = matchIPFamily(fd.family, raddr) if err := validateResolvedAddr(fd.net, fd.family, fd.raddr.(sockaddr)); err != nil { return wrapErr(err) } if err := fd.fakeNetFD.assignFakeAddr(laddr); err != nil { return wrapErr(err) } fd.fakeNetFD.queue = newPacketQueue(defaultBuffer) switch fd.sotype { case syscall.SOCK_DGRAM: if ua, ok := fd.laddr.(*UnixAddr); !ok || ua.Name != "" { fd.fakeNetFD.fakeAddr = fakeAddr(fd.laddr.(sockaddr)) if _, dup := sockets.LoadOrStore(fd.fakeNetFD.fakeAddr, fd); dup { return wrapErr(syscall.EADDRINUSE) } } fd.isConnected = true return nil case syscall.SOCK_STREAM, syscall.SOCK_SEQPACKET: default: return wrapErr(syscall.EINVAL) } fa := fakeAddr(raddr) lni, ok := sockets.Load(fa) if !ok { return wrapErr(syscall.ECONNREFUSED) } ln := lni.(*netFD) if ln.sotype != fd.sotype { return wrapErr(syscall.EPROTOTYPE) } if ln.incoming == nil { return wrapErr(syscall.ECONNREFUSED) } peer := &netFD{ family: ln.family, sotype: ln.sotype, net: ln.net, laddr: ln.laddr, raddr: fd.laddr, isConnected: true, } peer.fakeNetFD = newFakeNetFD(fd) peer.fakeNetFD.queue = newPacketQueue(defaultBuffer) defer func() { if fd.peer != peer { // Failed to connect; clean up. peer.Close() } }() var incoming []*netFD select { case <-ctx.Done(): return wrapErr(syscall.ETIMEDOUT) case ok = <-ln.incomingEmpty: case incoming, ok = <-ln.incoming: } if !ok { return wrapErr(syscall.ECONNREFUSED) } fd.isConnected = true fd.peer = peer peer.peer = fd incoming = append(incoming, peer) if len(incoming) >= listenerBacklog() { ln.incomingFull <- incoming } else { ln.incoming <- incoming } return nil } func (ffd *fakeNetFD) assignFakeAddr(addr sockaddr) error { validate := func(sa sockaddr) error { if err := validateResolvedAddr(ffd.fd.net, ffd.fd.family, sa); err != nil { return err } ffd.fd.laddr = sa return nil } assignIP := func(addr sockaddr) error { var ( ip IP port int zone string ) switch addr := addr.(type) { case *TCPAddr: if addr != nil { ip = addr.IP port = addr.Port zone = addr.Zone } case *UDPAddr: if addr != nil { ip = addr.IP port = addr.Port zone = addr.Zone } default: return validate(addr) } if ip == nil { ip = IPv4(127, 0, 0, 1) } switch ffd.fd.family { case syscall.AF_INET: if ip4 := ip.To4(); ip4 != nil { ip = ip4 } case syscall.AF_INET6: if ip16 := ip.To16(); ip16 != nil { ip = ip16 } } if ip == nil { return syscall.EINVAL } if port == 0 { var prevPort int32 portWrapped := false nextPort := func() (int, bool) { for { port := nextPortCounter.Add(1) if port <= 0 || port >= 1<<16 { // nextPortCounter ran off the end of the port space. // Bump it back into range. for { if nextPortCounter.CompareAndSwap(port, 0) { break } if port = nextPortCounter.Load(); port >= 0 && port < 1<<16 { break } } if portWrapped { // This is the second wraparound, so we've scanned the whole port space // at least once already and it's time to give up. return 0, false } portWrapped = true prevPort = 0 continue } if port <= prevPort { // nextPortCounter has wrapped around since the last time we read it. if portWrapped { // This is the second wraparound, so we've scanned the whole port space // at least once already and it's time to give up. return 0, false } else { portWrapped = true } } prevPort = port return int(port), true } } for { var ok bool port, ok = nextPort() if !ok { ffd.assignedPort = 0 return syscall.EADDRINUSE } ffd.assignedPort = int(port) if _, dup := fakePorts.LoadOrStore(ffd.assignedPort, ffd.fd); !dup { break } } } switch addr.(type) { case *TCPAddr: return validate(&TCPAddr{IP: ip, Port: port, Zone: zone}) case *UDPAddr: return validate(&UDPAddr{IP: ip, Port: port, Zone: zone}) default: panic("unreachable") } } switch ffd.fd.net { case "tcp", "tcp4", "tcp6": if addr == nil { return assignIP(new(TCPAddr)) } return assignIP(addr) case "udp", "udp4", "udp6": if addr == nil { return assignIP(new(UDPAddr)) } return assignIP(addr) case "unix", "unixgram", "unixpacket": uaddr, ok := addr.(*UnixAddr) if !ok && addr != nil { return &AddrError{ Err: "non-Unix address for " + ffd.fd.net + " network", Addr: addr.String(), } } if uaddr == nil { return validate(&UnixAddr{Net: ffd.fd.net}) } return validate(&UnixAddr{Net: ffd.fd.net, Name: uaddr.Name}) default: return &AddrError{ Err: syscall.EAFNOSUPPORT.Error(), Addr: addr.String(), } } } func (ffd *fakeNetFD) readFrom(p []byte) (n int, sa syscall.Sockaddr, err error) { if ffd.queue == nil { return 0, nil, os.NewSyscallError("readFrom", syscall.EINVAL) } n, from, err := ffd.queue.recvfrom(ffd.readDeadline.Load(), p, true, nil) if from != nil { // Convert the net.sockaddr to a syscall.Sockaddr type. var saErr error sa, saErr = from.sockaddr(ffd.fd.family) if err == nil { err = saErr } } return n, sa, err } func (ffd *fakeNetFD) readFromInet4(p []byte, sa *syscall.SockaddrInet4) (n int, err error) { n, _, err = ffd.queue.recvfrom(ffd.readDeadline.Load(), p, true, func(from sockaddr) error { fromSA, err := from.sockaddr(syscall.AF_INET) if err != nil { return err } if fromSA == nil { return os.NewSyscallError("readFromInet4", syscall.EINVAL) } *sa = *(fromSA.(*syscall.SockaddrInet4)) return nil }) return n, err } func (ffd *fakeNetFD) readFromInet6(p []byte, sa *syscall.SockaddrInet6) (n int, err error) { n, _, err = ffd.queue.recvfrom(ffd.readDeadline.Load(), p, true, func(from sockaddr) error { fromSA, err := from.sockaddr(syscall.AF_INET6) if err != nil { return err } if fromSA == nil { return os.NewSyscallError("readFromInet6", syscall.EINVAL) } *sa = *(fromSA.(*syscall.SockaddrInet6)) return nil }) return n, err } func (ffd *fakeNetFD) readMsg(p []byte, oob []byte, flags int) (n, oobn, retflags int, sa syscall.Sockaddr, err error) { if flags != 0 { return 0, 0, 0, nil, os.NewSyscallError("readMsg", syscall.ENOTSUP) } n, sa, err = ffd.readFrom(p) return n, 0, 0, sa, err } func (ffd *fakeNetFD) readMsgInet4(p []byte, oob []byte, flags int, sa *syscall.SockaddrInet4) (n, oobn, retflags int, err error) { if flags != 0 { return 0, 0, 0, os.NewSyscallError("readMsgInet4", syscall.ENOTSUP) } n, err = ffd.readFromInet4(p, sa) return n, 0, 0, err } func (ffd *fakeNetFD) readMsgInet6(p []byte, oob []byte, flags int, sa *syscall.SockaddrInet6) (n, oobn, retflags int, err error) { if flags != 0 { return 0, 0, 0, os.NewSyscallError("readMsgInet6", syscall.ENOTSUP) } n, err = ffd.readFromInet6(p, sa) return n, 0, 0, err } func (ffd *fakeNetFD) writeMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oobn int, err error) { if len(oob) > 0 { return 0, 0, os.NewSyscallError("writeMsg", syscall.ENOTSUP) } n, err = ffd.writeTo(p, sa) return n, 0, err } func (ffd *fakeNetFD) writeMsgInet4(p []byte, oob []byte, sa *syscall.SockaddrInet4) (n int, oobn int, err error) { return ffd.writeMsg(p, oob, sa) } func (ffd *fakeNetFD) writeMsgInet6(p []byte, oob []byte, sa *syscall.SockaddrInet6) (n int, oobn int, err error) { return ffd.writeMsg(p, oob, sa) } func (ffd *fakeNetFD) writeTo(p []byte, sa syscall.Sockaddr) (n int, err error) { raddr := ffd.fd.raddr if sa != nil { if ffd.fd.isConnected { return 0, os.NewSyscallError("writeTo", syscall.EISCONN) } raddr = ffd.fd.addrFunc()(sa) } if raddr == nil { return 0, os.NewSyscallError("writeTo", syscall.EINVAL) } peeri, _ := sockets.Load(fakeAddr(raddr.(sockaddr))) if peeri == nil { if len(ffd.fd.net) >= 3 && ffd.fd.net[:3] == "udp" { return len(p), nil } return 0, os.NewSyscallError("writeTo", syscall.ECONNRESET) } peer := peeri.(*netFD) if peer.queue == nil { if len(ffd.fd.net) >= 3 && ffd.fd.net[:3] == "udp" { return len(p), nil } return 0, os.NewSyscallError("writeTo", syscall.ECONNRESET) } block := true if len(ffd.fd.net) >= 3 && ffd.fd.net[:3] == "udp" { block = false } return peer.queue.send(ffd.writeDeadline.Load(), p, ffd.fd.laddr.(sockaddr), block) } func (ffd *fakeNetFD) writeToInet4(p []byte, sa *syscall.SockaddrInet4) (n int, err error) { return ffd.writeTo(p, sa) } func (ffd *fakeNetFD) writeToInet6(p []byte, sa *syscall.SockaddrInet6) (n int, err error) { return ffd.writeTo(p, sa) } func (ffd *fakeNetFD) dup() (f *os.File, err error) { return nil, os.NewSyscallError("dup", syscall.ENOSYS) } func (ffd *fakeNetFD) setReadBuffer(bytes int) error { if ffd.queue == nil { return os.NewSyscallError("setReadBuffer", syscall.EINVAL) } ffd.queue.setReadBuffer(bytes) return nil } func (ffd *fakeNetFD) setWriteBuffer(bytes int) error { return os.NewSyscallError("setWriteBuffer", syscall.ENOTSUP) } func (ffd *fakeNetFD) setLinger(sec int) error { if sec < 0 || ffd.peer == nil { return os.NewSyscallError("setLinger", syscall.EINVAL) } ffd.peer.queue.setLinger(sec > 0) return nil }