aboutsummaryrefslogtreecommitdiff
path: root/src/syscall
diff options
context:
space:
mode:
authorChris O'Hara <cohara87@gmail.com>2023-05-08 17:08:20 +1000
committerGopher Robot <gobot@golang.org>2023-05-25 00:12:41 +0000
commita17de43ef12250cd9a0ffdd8ff2d05fb18fcf322 (patch)
tree1a092d125865530314bfa393625262302029330e /src/syscall
parentc5c2184538411c8cf7abc4e536fbe7af8b0307f5 (diff)
downloadgo-a17de43ef12250cd9a0ffdd8ff2d05fb18fcf322.tar.xz
net: implement wasip1 FileListener and FileConn
Implements net.FileListener and net.FileConn for wasip1. net.FileListener can be used with a pre-opened socket. If the WASM module knows the file descriptor, a listener can be constructed with: l, err := net.FileListener(os.NewFile(fd, "")) If the WASM module does not know the file descriptor, but knows that at least one of the preopens is a socket, it can find the file descriptor and construct a listener like so: func findListener() (net.Listener, error) { // We start looking for pre-opened sockets at fd=3 because 0, 1, // and 2 are reserved for stdio. Pre-opened directories also // start at fd=3, so we skip fds that aren't sockets. Once we // reach EBADF we know there are no more pre-opens. for preopenFd := uintptr(3); ; preopenFd++ { l, err := net.FileListener(os.NewFile(preopenFd, "")) var se syscall.Errno switch errors.As(err, &se); se { case syscall.ENOTSOCK: continue case syscall.EBADF: err = nil } return l, err } } A similar strategy can be used with net.FileConn and pre-opened connection sockets. The wasmtime runtime supports pre-opening listener sockets: $ wasmtime --tcplisten 127.0.0.1:8080 module.wasm Change-Id: Iec6ae4ffa84b3753cce4f56a2817e150445db643 Reviewed-on: https://go-review.googlesource.com/c/go/+/493358 Reviewed-by: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Ian Lance Taylor <iant@golang.org> Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org> TryBot-Bypass: Dmitri Shuralyov <dmitshur@google.com> Reviewed-by: Johan Brandhorst-Satzkorn <johan.brandhorst@gmail.com> Auto-Submit: Johan Brandhorst-Satzkorn <johan.brandhorst@gmail.com> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Diffstat (limited to 'src/syscall')
-rw-r--r--src/syscall/fs_wasip1.go12
-rw-r--r--src/syscall/net_fake.go63
-rw-r--r--src/syscall/net_js.go56
-rw-r--r--src/syscall/net_wasip1.go70
4 files changed, 89 insertions, 112 deletions
diff --git a/src/syscall/fs_wasip1.go b/src/syscall/fs_wasip1.go
index 25cabf8234..d60ab0b53e 100644
--- a/src/syscall/fs_wasip1.go
+++ b/src/syscall/fs_wasip1.go
@@ -279,6 +279,12 @@ func fd_fdstat_get_flags(fd int) (uint32, error) {
return uint32(stat.fdflags), errnoErr(errno)
}
+func fd_fdstat_get_type(fd int) (uint8, error) {
+ var stat fdstat
+ errno := fd_fdstat_get(int32(fd), unsafe.Pointer(&stat))
+ return stat.filetype, errnoErr(errno)
+}
+
type preopentype = uint8
const (
@@ -331,12 +337,12 @@ func init() {
if errno == EBADF {
break
}
+ if errno == ENOTDIR || prestat.typ != preopentypeDir {
+ continue
+ }
if errno != 0 {
panic("fd_prestat: " + errno.Error())
}
- if prestat.typ != preopentypeDir {
- continue
- }
if int(prestat.dir.prNameLen) > len(dirNameBuf) {
dirNameBuf = make([]byte, prestat.dir.prNameLen)
}
diff --git a/src/syscall/net_fake.go b/src/syscall/net_fake.go
new file mode 100644
index 0000000000..689f6f8812
--- /dev/null
+++ b/src/syscall/net_fake.go
@@ -0,0 +1,63 @@
+// Copyright 2023 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.
+// This file only exists to make the compiler happy.
+
+//go:build (js && wasm) || wasip1
+
+package syscall
+
+const (
+ AF_UNSPEC = iota
+ AF_UNIX
+ AF_INET
+ AF_INET6
+)
+
+const (
+ SOCK_STREAM = 1 + iota
+ SOCK_DGRAM
+ SOCK_RAW
+ SOCK_SEQPACKET
+)
+
+const (
+ IPPROTO_IP = 0
+ IPPROTO_IPV4 = 4
+ IPPROTO_IPV6 = 0x29
+ IPPROTO_TCP = 6
+ IPPROTO_UDP = 0x11
+)
+
+const (
+ _ = iota
+ IPV6_V6ONLY
+ SOMAXCONN
+ SO_ERROR
+)
+
+// Misc constants expected by package net but not supported.
+const (
+ _ = iota
+ F_DUPFD_CLOEXEC
+ SYS_FCNTL = 500 // unsupported
+)
+
+type Sockaddr any
+
+type SockaddrInet4 struct {
+ Port int
+ Addr [4]byte
+}
+
+type SockaddrInet6 struct {
+ Port int
+ ZoneId uint32
+ Addr [16]byte
+}
+
+type SockaddrUnix struct {
+ Name string
+}
diff --git a/src/syscall/net_js.go b/src/syscall/net_js.go
index 2ed4e191bd..cba33dfd2e 100644
--- a/src/syscall/net_js.go
+++ b/src/syscall/net_js.go
@@ -2,66 +2,10 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// js/wasm uses fake networking directly implemented in the net package.
-// This file only exists to make the compiler happy.
-
//go:build js && wasm
package syscall
-const (
- AF_UNSPEC = iota
- AF_UNIX
- AF_INET
- AF_INET6
-)
-
-const (
- SOCK_STREAM = 1 + iota
- SOCK_DGRAM
- SOCK_RAW
- SOCK_SEQPACKET
-)
-
-const (
- IPPROTO_IP = 0
- IPPROTO_IPV4 = 4
- IPPROTO_IPV6 = 0x29
- IPPROTO_TCP = 6
- IPPROTO_UDP = 0x11
-)
-
-const (
- _ = iota
- IPV6_V6ONLY
- SOMAXCONN
- SO_ERROR
-)
-
-// Misc constants expected by package net but not supported.
-const (
- _ = iota
- F_DUPFD_CLOEXEC
- SYS_FCNTL = 500 // unsupported
-)
-
-type Sockaddr any
-
-type SockaddrInet4 struct {
- Port int
- Addr [4]byte
-}
-
-type SockaddrInet6 struct {
- Port int
- ZoneId uint32
- Addr [16]byte
-}
-
-type SockaddrUnix struct {
- Name string
-}
-
func Socket(proto, sotype, unused int) (fd int, err error) {
return 0, ENOSYS
}
diff --git a/src/syscall/net_wasip1.go b/src/syscall/net_wasip1.go
index 896dd3e770..3918840a7e 100644
--- a/src/syscall/net_wasip1.go
+++ b/src/syscall/net_wasip1.go
@@ -2,66 +2,27 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// wasip1/wasm uses fake networking directly implemented in the net package.
-// This file only exists to make the compiler happy.
-
//go:build wasip1
package syscall
-const (
- AF_UNSPEC = iota
- AF_UNIX
- AF_INET
- AF_INET6
-)
+import "unsafe"
const (
- SOCK_STREAM = 1 + iota
- SOCK_DGRAM
- SOCK_RAW
- SOCK_SEQPACKET
+ SHUT_RD = 0x1
+ SHUT_WR = 0x2
+ SHUT_RDWR = SHUT_RD | SHUT_WR
)
-const (
- IPPROTO_IP = 0
- IPPROTO_IPV4 = 4
- IPPROTO_IPV6 = 0x29
- IPPROTO_TCP = 6
- IPPROTO_UDP = 0x11
-)
+type sdflags = uint32
-const (
- _ = iota
- IPV6_V6ONLY
- SOMAXCONN
- SO_ERROR
-)
+//go:wasmimport wasi_snapshot_preview1 sock_accept
+//go:noescape
+func sock_accept(fd int32, flags fdflags, newfd unsafe.Pointer) Errno
-// Misc constants expected by package net but not supported.
-const (
- _ = iota
- F_DUPFD_CLOEXEC
- SYS_FCNTL = 500 // unsupported; same value as net_nacl.go
-)
-
-type Sockaddr interface {
-}
-
-type SockaddrInet4 struct {
- Port int
- Addr [4]byte
-}
-
-type SockaddrInet6 struct {
- Port int
- ZoneId uint32
- Addr [16]byte
-}
-
-type SockaddrUnix struct {
- Name string
-}
+//go:wasmimport wasi_snapshot_preview1 sock_shutdown
+//go:noescape
+func sock_shutdown(fd int32, flags sdflags) Errno
func Socket(proto, sotype, unused int) (fd int, err error) {
return 0, ENOSYS
@@ -79,8 +40,10 @@ func Listen(fd int, backlog int) error {
return ENOSYS
}
-func Accept(fd int) (newfd int, sa Sockaddr, err error) {
- return 0, nil, ENOSYS
+func Accept(fd int) (int, Sockaddr, error) {
+ var newfd int32
+ errno := sock_accept(int32(fd), 0, unsafe.Pointer(&newfd))
+ return int(newfd), nil, errnoErr(errno)
}
func Connect(fd int, sa Sockaddr) error {
@@ -120,5 +83,6 @@ func SetWriteDeadline(fd int, t int64) error {
}
func Shutdown(fd int, how int) error {
- return ENOSYS
+ errno := sock_shutdown(int32(fd), sdflags(how))
+ return errnoErr(errno)
}