Skip to content

Commit fadb8bc

Browse files
committed
Add sock_getaddrinfo syscall
1 parent 0ba7399 commit fadb8bc

File tree

1 file changed

+137
-2
lines changed

1 file changed

+137
-2
lines changed

syscall/net_wasip1.go

Lines changed: 137 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,20 @@
55
package syscall
66

77
import (
8+
"encoding/binary"
89
"runtime"
910
"unsafe"
1011
)
1112

1213
const (
13-
_ = iota
14+
AF_UNSPEC = iota
1415
AF_INET
1516
AF_INET6
1617
AF_UNIX
1718
)
1819

1920
const (
20-
_ = iota
21+
SOCK_ANY = iota
2122
SOCK_DGRAM
2223
SOCK_STREAM
2324
)
@@ -34,6 +35,19 @@ const (
3435
SO_BROADCAST
3536
)
3637

38+
const (
39+
AI_PASSIVE = 1 << iota
40+
_
41+
AI_NUMERICHOST
42+
AI_NUMERICSERV
43+
)
44+
45+
const (
46+
IPPROTO_IP = iota
47+
IPPROTO_TCP
48+
IPPROTO_UDP
49+
)
50+
3751
type Sockaddr interface {
3852
sockaddr() (unsafe.Pointer, error)
3953
sockport() int
@@ -126,6 +140,18 @@ func sock_getlocaladdr(fd int32, addr unsafe.Pointer, port unsafe.Pointer) Errno
126140
//go:wasmimport wasi_snapshot_preview1 sock_getpeeraddr
127141
func sock_getpeeraddr(fd int32, addr unsafe.Pointer, port unsafe.Pointer) Errno
128142

143+
//go:wasmimport wasi_snapshot_preview1 sock_getaddrinfo
144+
func sock_getaddrinfo(
145+
node unsafe.Pointer,
146+
nodeLen uint32,
147+
service unsafe.Pointer,
148+
serviceLen uint32,
149+
hints unsafe.Pointer,
150+
res unsafe.Pointer,
151+
maxResLen uint32,
152+
resLen unsafe.Pointer,
153+
) uint32
154+
129155
func Socket(proto, sotype, unused int) (fd int, err error) {
130156
var newfd int32
131157
errno := sock_open(int32(proto), int32(sotype), unsafe.Pointer(&newfd))
@@ -211,3 +237,112 @@ func anyToSockaddr(rsa *RawSockaddrAny, port int) (Sockaddr, error) {
211237
return nil, ENOTSUP
212238
}
213239
}
240+
241+
// https://github.com/WasmEdge/WasmEdge/blob/434e1fb4690/thirdparty/wasi/api.hpp#L1885
242+
type addrInfo struct {
243+
ai_flags uint16
244+
ai_family uint8
245+
ai_socktype uint8
246+
ai_protocol uint32
247+
ai_addrlen uint32
248+
ai_addr uintptr32 // *sockAddr
249+
ai_canonname uintptr32 // null-terminated string
250+
ai_canonnamelen uint32
251+
ai_next uintptr32 // *addrInfo
252+
}
253+
254+
type sockAddr struct {
255+
sa_family uint32
256+
sa_data_len uint32
257+
sa_data uintptr32
258+
_ [4]byte
259+
}
260+
261+
type AddrInfo struct {
262+
Flags int
263+
Family int
264+
SocketType int
265+
Protocol int
266+
Address Sockaddr
267+
CanonicalName string
268+
269+
addrInfo
270+
sockAddr
271+
sockData [26]byte
272+
cannoname [30]byte
273+
inet4addr SockaddrInet4
274+
inet6addr SockaddrInet6
275+
}
276+
277+
func Getaddrinfo(name, service string, hints AddrInfo, results []AddrInfo) (int, error) {
278+
// For compatibility with WasmEdge, make sure strings are null-terminated.
279+
if len(name) > 0 && name[len(name)-1] != 0 {
280+
name = string(append([]byte(name), 0))
281+
}
282+
if len(service) > 0 && service[len(service)-1] != 0 {
283+
service = string(append([]byte(service), 0))
284+
}
285+
286+
hints.addrInfo = addrInfo{
287+
ai_flags: uint16(hints.Flags),
288+
ai_family: uint8(hints.Family),
289+
ai_socktype: uint8(hints.SocketType),
290+
ai_protocol: uint32(hints.Protocol),
291+
}
292+
for i := range results {
293+
results[i].sockAddr = sockAddr{
294+
sa_family: 0,
295+
sa_data_len: uint32(unsafe.Sizeof(AddrInfo{}.sockData)),
296+
sa_data: uintptr32(uintptr(unsafe.Pointer(&results[i].sockData))),
297+
}
298+
results[i].addrInfo = addrInfo{
299+
ai_flags: 0,
300+
ai_family: 0,
301+
ai_socktype: 0,
302+
ai_protocol: 0,
303+
ai_addrlen: uint32(unsafe.Sizeof(sockAddr{})),
304+
ai_addr: uintptr32(uintptr(unsafe.Pointer(&results[i].sockAddr))),
305+
ai_canonname: uintptr32(uintptr(unsafe.Pointer(&results[i].cannoname))),
306+
ai_canonnamelen: uint32(unsafe.Sizeof(AddrInfo{}.cannoname)),
307+
}
308+
if i > 0 {
309+
results[i-1].addrInfo.ai_next = uintptr32(uintptr(unsafe.Pointer(&results[i-1])))
310+
}
311+
}
312+
313+
resPtr := uintptr32(uintptr(unsafe.Pointer(&results[0].addrInfo)))
314+
315+
var n uint32
316+
errno := sock_getaddrinfo(
317+
unsafe.Pointer(unsafe.StringData(name)),
318+
uint32(len(name)),
319+
unsafe.Pointer(unsafe.StringData(service)),
320+
uint32(len(service)),
321+
unsafe.Pointer(&hints.addrInfo),
322+
unsafe.Pointer(&resPtr),
323+
uint32(len(results)),
324+
unsafe.Pointer(&n),
325+
)
326+
if errno != 0 {
327+
return 0, errnoErr(Errno(errno))
328+
}
329+
330+
for i := range results[:n] {
331+
r := &results[i]
332+
port := binary.BigEndian.Uint16(results[i].sockData[:2])
333+
switch results[i].sockAddr.sa_family {
334+
case AF_INET:
335+
r.inet4addr.Port = int(port)
336+
copy(r.inet4addr.Addr[:], results[i].sockData[2:])
337+
r.Address = &r.inet4addr
338+
case AF_INET6:
339+
r.inet6addr.Port = int(port)
340+
r.Address = &r.inet6addr
341+
copy(r.inet4addr.Addr[:], results[i].sockData[2:])
342+
default:
343+
r.Address = nil
344+
}
345+
// TODO: canonical names
346+
}
347+
return int(n), nil
348+
}

0 commit comments

Comments
 (0)