1 package wasi_snapshot_preview1
2
3 import (
4 "context"
5
6 "github.com/tetratelabs/wazero/api"
7 "github.com/tetratelabs/wazero/experimental/sys"
8 socketapi "github.com/tetratelabs/wazero/internal/sock"
9 "github.com/tetratelabs/wazero/internal/sysfs"
10 "github.com/tetratelabs/wazero/internal/wasip1"
11 "github.com/tetratelabs/wazero/internal/wasm"
12 )
13
14
15
16
17
18
19 var sockAccept = newHostFunc(
20 wasip1.SockAcceptName,
21 sockAcceptFn,
22 []wasm.ValueType{i32, i32, i32},
23 "fd", "flags", "result.fd",
24 )
25
26 func sockAcceptFn(_ context.Context, mod api.Module, params []uint64) (errno sys.Errno) {
27 mem := mod.Memory()
28 fsc := mod.(*wasm.ModuleInstance).Sys.FS()
29
30 fd := int32(params[0])
31 flags := uint32(params[1])
32 resultFd := uint32(params[2])
33 nonblock := flags&uint32(wasip1.FD_NONBLOCK) != 0
34
35 var connFD int32
36 if connFD, errno = fsc.SockAccept(fd, nonblock); errno == 0 {
37 mem.WriteUint32Le(resultFd, uint32(connFD))
38 }
39 return
40 }
41
42
43
44
45
46 var sockRecv = newHostFunc(
47 wasip1.SockRecvName,
48 sockRecvFn,
49 []wasm.ValueType{i32, i32, i32, i32, i32, i32},
50 "fd", "ri_data", "ri_data_len", "ri_flags", "result.ro_datalen", "result.ro_flags",
51 )
52
53 func sockRecvFn(_ context.Context, mod api.Module, params []uint64) sys.Errno {
54 mem := mod.Memory()
55 fsc := mod.(*wasm.ModuleInstance).Sys.FS()
56
57 fd := int32(params[0])
58 riData := uint32(params[1])
59 riDataCount := uint32(params[2])
60 riFlags := uint8(params[3])
61 resultRoDatalen := uint32(params[4])
62 resultRoFlags := uint32(params[5])
63
64 var conn socketapi.TCPConn
65 if e, ok := fsc.LookupFile(fd); !ok {
66 return sys.EBADF
67 } else if conn, ok = e.File.(socketapi.TCPConn); !ok {
68 return sys.EBADF
69 }
70
71 if riFlags & ^(wasip1.RI_RECV_PEEK|wasip1.RI_RECV_WAITALL) != 0 {
72 return sys.ENOTSUP
73 }
74
75 if riFlags&wasip1.RI_RECV_PEEK != 0 {
76
77
78
79 firstIovecBufAddr, ok := mem.ReadUint32Le(riData)
80 if !ok {
81 return sys.EINVAL
82 }
83
84 firstIovecBufLen, ok := mem.ReadUint32Le(riData + 4)
85 if !ok {
86 return sys.EINVAL
87 }
88 firstIovecBuf, ok := mem.Read(firstIovecBufAddr, firstIovecBufLen)
89 if !ok {
90 return sys.EINVAL
91 }
92 n, err := conn.Recvfrom(firstIovecBuf, sysfs.MSG_PEEK)
93 if err != 0 {
94 return err
95 }
96 mem.WriteUint32Le(resultRoDatalen, uint32(n))
97 mem.WriteUint16Le(resultRoFlags, 0)
98 return 0
99 }
100
101
102
103
104
105 bufSize, errno := readv(mem, riData, riDataCount, conn.Read)
106 if errno != 0 {
107 return errno
108 }
109 mem.WriteUint32Le(resultRoDatalen, bufSize)
110 mem.WriteUint16Le(resultRoFlags, 0)
111 return 0
112 }
113
114
115
116
117
118 var sockSend = newHostFunc(
119 wasip1.SockSendName,
120 sockSendFn,
121 []wasm.ValueType{i32, i32, i32, i32, i32},
122 "fd", "si_data", "si_data_len", "si_flags", "result.so_datalen",
123 )
124
125 func sockSendFn(_ context.Context, mod api.Module, params []uint64) sys.Errno {
126 mem := mod.Memory()
127 fsc := mod.(*wasm.ModuleInstance).Sys.FS()
128
129 fd := int32(params[0])
130 siData := uint32(params[1])
131 siDataCount := uint32(params[2])
132 siFlags := uint32(params[3])
133 resultSoDatalen := uint32(params[4])
134
135 if siFlags != 0 {
136 return sys.ENOTSUP
137 }
138
139 var conn socketapi.TCPConn
140 if e, ok := fsc.LookupFile(fd); !ok {
141 return sys.EBADF
142 } else if conn, ok = e.File.(socketapi.TCPConn); !ok {
143 return sys.EBADF
144 }
145
146 bufSize, errno := writev(mem, siData, siDataCount, conn.Write)
147 if errno != 0 {
148 return errno
149 }
150 mem.WriteUint32Le(resultSoDatalen, bufSize)
151 return 0
152 }
153
154
155
156
157
158 var sockShutdown = newHostFunc(wasip1.SockShutdownName, sockShutdownFn, []wasm.ValueType{i32, i32}, "fd", "how")
159
160 func sockShutdownFn(_ context.Context, mod api.Module, params []uint64) sys.Errno {
161 fsc := mod.(*wasm.ModuleInstance).Sys.FS()
162
163 fd := int32(params[0])
164 how := uint8(params[1])
165
166 var conn socketapi.TCPConn
167 if e, ok := fsc.LookupFile(fd); !ok {
168 return sys.EBADF
169 } else if conn, ok = e.File.(socketapi.TCPConn); !ok {
170 return sys.EBADF
171 }
172
173 sysHow := 0
174
175 switch how {
176 case wasip1.SD_RD | wasip1.SD_WR:
177 sysHow = socketapi.SHUT_RD | socketapi.SHUT_WR
178 case wasip1.SD_RD:
179 sysHow = socketapi.SHUT_RD
180 case wasip1.SD_WR:
181 sysHow = socketapi.SHUT_WR
182 default:
183 return sys.EINVAL
184 }
185
186
187 return conn.Shutdown(sysHow)
188 }
189
View as plain text