Skip to content

Commit 14e345c

Browse files
Merge pull request #2 from stealthrocket/wasip1
net/wasip1
2 parents 8ba0c2a + a37e2ea commit 14e345c

File tree

8 files changed

+151
-74
lines changed

8 files changed

+151
-74
lines changed

syscall/errno_wasip1.go renamed to internal/syscall/errno_wasip1.go

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,17 @@
44

55
package syscall
66

7-
import (
8-
"syscall"
9-
)
7+
import "syscall"
108

119
type Errno = syscall.Errno
1210

1311
const (
14-
EAGAIN Errno = 6
15-
EINPROGRESS Errno = 26
16-
EINTR Errno = 27
17-
EISCONN Errno = 30
18-
ENOSYS Errno = 52
19-
ENOTSUP Errno = 58
12+
EAGAIN = syscall.EAGAIN
13+
EINPROGRESS = syscall.EINPROGRESS
14+
EINTR = syscall.EINTR
15+
EISCONN = syscall.EISCONN
16+
ENOSYS = syscall.ENOSYS
17+
ENOTSUP = syscall.ENOTSUP
2018
)
2119

2220
// Do the interface allocations only once for common
File renamed without changes.
File renamed without changes.

dial_wasip1.go renamed to wasip1/dial_wasip1.go

Lines changed: 46 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,76 @@
1-
package net
1+
package wasip1
22

33
import (
44
"context"
5-
"fmt"
65
"net"
7-
"net/http"
86
"os"
97

10-
"github.com/stealthrocket/net/syscall"
8+
"github.com/stealthrocket/net/internal/syscall"
119
)
1210

13-
func init() {
14-
if t, ok := http.DefaultTransport.(*http.Transport); ok {
15-
t.DialContext = DialContext
16-
}
17-
}
18-
19-
// Conn is a generic stream-oriented network connection.
20-
type Conn = net.Conn
21-
2211
// Dial connects to the address on the named network.
23-
func Dial(network, address string) (Conn, error) {
12+
func Dial(network, address string) (net.Conn, error) {
2413
addr, err := lookupAddr("dial", network, address)
2514
if err != nil {
26-
return nil, err
15+
addr := &netAddr{network, address}
16+
return nil, dialErr(addr, err)
2717
}
28-
return dialAddr(addr)
18+
conn, err := dialAddr(addr)
19+
if err != nil {
20+
return nil, dialErr(addr, err)
21+
}
22+
return conn, nil
2923
}
3024

3125
// DialContext is a variant of Dial that accepts a context.
32-
func DialContext(ctx context.Context, network, address string) (Conn, error) {
33-
_ = ctx // TODO
34-
return Dial(network, address)
26+
func DialContext(ctx context.Context, network, address string) (net.Conn, error) {
27+
select {
28+
case <-ctx.Done():
29+
addr := &netAddr{network, address}
30+
return nil, dialErr(addr, context.Cause(ctx))
31+
default:
32+
return Dial(network, address)
33+
}
34+
}
35+
36+
func dialErr(addr net.Addr, err error) error {
37+
return newOpError("dial", addr, err)
3538
}
3639

37-
func dialAddr(addr net.Addr) (Conn, error) {
40+
func dialAddr(addr net.Addr) (net.Conn, error) {
3841
proto := family(addr)
3942
sotype := socketType(addr)
4043

4144
fd, err := syscall.Socket(proto, sotype, 0)
4245
if err != nil {
43-
return nil, err
46+
return nil, os.NewSyscallError("socket", err)
4447
}
4548

4649
if err := syscall.SetNonblock(fd, true); err != nil {
4750
syscall.Close(fd)
48-
return nil, fmt.Errorf("SetNonblock: %w", err)
51+
return nil, os.NewSyscallError("setnonblock", err)
4952
}
5053

5154
if sotype == syscall.SOCK_DGRAM && proto != syscall.AF_UNIX {
5255
if err := syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1); err != nil {
5356
syscall.Close(fd)
54-
return nil, err
57+
return nil, os.NewSyscallError("setsockopt", err)
5558
}
5659
}
5760

61+
connectAddr, err := socketAddress(addr)
62+
if err != nil {
63+
return nil, os.NewSyscallError("connect", err)
64+
}
65+
5866
var inProgress bool
59-
switch err := syscall.Connect(fd, socketAddress(addr)); err {
67+
switch err := syscall.Connect(fd, connectAddr); err {
6068
case nil:
6169
case syscall.EINPROGRESS:
6270
inProgress = true
6371
default:
6472
syscall.Close(fd)
65-
return nil, fmt.Errorf("Connect: %w", err)
73+
return nil, os.NewSyscallError("connect", err)
6674
}
6775

6876
f := os.NewFile(uintptr(fd), "")
@@ -94,10 +102,11 @@ func dialAddr(addr net.Addr) (Conn, error) {
94102
return true
95103
}
96104
})
105+
if err == nil {
106+
err = rawConnErr
107+
}
97108
if err != nil {
98-
return nil, err
99-
} else if rawConnErr != nil {
100-
return nil, err
109+
return nil, os.NewSyscallError("connect", err)
101110
}
102111
}
103112

@@ -107,7 +116,6 @@ func dialAddr(addr net.Addr) (Conn, error) {
107116
}
108117

109118
// TODO: get local+peer address; wrap FileConn to implement LocalAddr() and RemoteAddr()
110-
111119
return c, nil
112120
}
113121

@@ -142,12 +150,12 @@ func socketType(addr net.Addr) int {
142150
}
143151
}
144152

145-
func socketAddress(addr net.Addr) syscall.Sockaddr {
153+
func socketAddress(addr net.Addr) (syscall.Sockaddr, error) {
146154
var ip net.IP
147155
var port int
148156
switch a := addr.(type) {
149157
case *net.UnixAddr:
150-
return &syscall.SockaddrUnix{Name: a.Name}
158+
return &syscall.SockaddrUnix{Name: a.Name}, nil
151159
case *net.TCPAddr:
152160
ip, port = a.IP, a.Port
153161
case *net.UDPAddr:
@@ -156,9 +164,13 @@ func socketAddress(addr net.Addr) syscall.Sockaddr {
156164
ip = a.IP
157165
}
158166
if ipv4 := ip.To4(); ipv4 != nil {
159-
return &syscall.SockaddrInet4{Addr: ([4]byte)(ipv4), Port: port}
167+
return &syscall.SockaddrInet4{Addr: ([4]byte)(ipv4), Port: port}, nil
160168
} else if len(ip) == net.IPv6len {
161-
return &syscall.SockaddrInet6{Addr: ([16]byte)(ip), Port: port}
169+
return &syscall.SockaddrInet6{Addr: ([16]byte)(ip), Port: port}, nil
170+
} else {
171+
return nil, &net.AddrError{
172+
Err: "unsupported address type",
173+
Addr: addr.String(),
174+
}
162175
}
163-
panic("not implemented")
164176
}

listen_wasip1.go renamed to wasip1/listen_wasip1.go

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,59 @@
1-
package net
1+
package wasip1
22

33
import (
4-
"fmt"
54
"net"
65
"os"
76

8-
"github.com/stealthrocket/net/syscall"
7+
"github.com/stealthrocket/net/internal/syscall"
98
)
109

11-
// A Listener is a generic network listener for stream-oriented protocols.
12-
type Listener = net.Listener
13-
1410
// Listen announces on the local network address.
15-
func Listen(network, address string) (Listener, error) {
11+
func Listen(network, address string) (net.Listener, error) {
1612
addr, err := lookupAddr("listen", network, address)
1713
if err != nil {
18-
return nil, err
14+
addr := &netAddr{network, address}
15+
return nil, listenErr(addr, err)
1916
}
20-
return listenAddr(addr)
17+
lstn, err := listenAddr(addr)
18+
if err != nil {
19+
return nil, listenErr(addr, err)
20+
}
21+
return lstn, nil
22+
}
23+
24+
func listenErr(addr net.Addr, err error) error {
25+
return newOpError("listen", addr, err)
2126
}
2227

23-
func listenAddr(addr net.Addr) (Listener, error) {
28+
func listenAddr(addr net.Addr) (net.Listener, error) {
2429
fd, err := syscall.Socket(family(addr), socketType(addr), 0)
2530
if err != nil {
26-
return nil, fmt.Errorf("Socket: %w", err)
31+
return nil, os.NewSyscallError("socket", err)
2732
}
2833

2934
if err := syscall.SetNonblock(fd, true); err != nil {
3035
syscall.Close(fd)
31-
return nil, fmt.Errorf("SetNonBlock: %w", err)
36+
return nil, os.NewSyscallError("setnonblock", err)
3237
}
3338
if err := syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1); err != nil {
3439
syscall.Close(fd)
35-
return nil, err
40+
return nil, os.NewSyscallError("setsockopt", err)
41+
}
42+
43+
listenAddr, err := socketAddress(addr)
44+
if err != nil {
45+
return nil, os.NewSyscallError("bind", err)
3646
}
3747

38-
if err := syscall.Bind(fd, socketAddress(addr)); err != nil {
48+
if err := syscall.Bind(fd, listenAddr); err != nil {
3949
syscall.Close(fd)
40-
return nil, fmt.Errorf("Bind: %w", err)
50+
return nil, os.NewSyscallError("bind", err)
4151
}
4252

4353
const backlog = 64 // TODO: configurable?
4454
if err := syscall.Listen(fd, backlog); err != nil {
4555
syscall.Close(fd)
46-
return nil, fmt.Errorf("Listen: %w", err)
56+
return nil, os.NewSyscallError("listen", err)
4757
}
4858

4959
f := os.NewFile(uintptr(fd), "")
@@ -53,11 +63,11 @@ func listenAddr(addr net.Addr) (Listener, error) {
5363
if err != nil {
5464
return nil, err
5565
}
56-
return &listener{l, addr}, err
66+
return &listener{l, addr}, nil
5767
}
5868

5969
type listener struct {
60-
Listener
70+
net.Listener
6171
addr net.Addr
6272
}
6373

lookup_wasip1.go renamed to wasip1/lookup_wasip1.go

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
package net
1+
//go:build wasip1 && !purego
2+
3+
package wasip1
24

35
import (
4-
"fmt"
56
"net"
7+
"os"
68

7-
"github.com/stealthrocket/net/syscall"
9+
"github.com/stealthrocket/net/internal/syscall"
810
)
911

10-
func lookupAddr(context, network, address string) (net.Addr, error) {
12+
func lookupAddr(op, network, address string) (net.Addr, error) {
1113
var hints syscall.AddrInfo
1214
switch network {
1315
case "tcp", "tcp4", "tcp6":
@@ -19,7 +21,7 @@ func lookupAddr(context, network, address string) (net.Addr, error) {
1921
case "unix", "unixgram":
2022
return &net.UnixAddr{Name: address, Net: network}, nil
2123
default:
22-
return nil, fmt.Errorf("not implemented: %s", network)
24+
return nil, net.UnknownNetworkError(network)
2325
}
2426
switch network {
2527
case "tcp", "udp":
@@ -31,16 +33,17 @@ func lookupAddr(context, network, address string) (net.Addr, error) {
3133
}
3234
hostname, service, err := net.SplitHostPort(address)
3335
if err != nil {
34-
return nil, err
36+
return nil, net.InvalidAddrError(address)
3537
}
36-
if context == "listen" && hostname == "" {
38+
if op == "listen" && hostname == "" {
3739
hints.Flags |= syscall.AI_PASSIVE
3840
}
3941

4042
results := make([]syscall.AddrInfo, 16)
4143
n, err := syscall.Getaddrinfo(hostname, service, hints, results)
4244
if err != nil {
43-
return nil, err
45+
addr := &netAddr{network, address}
46+
return nil, newOpError(op, addr, os.NewSyscallError("getaddrinfo", err))
4447
}
4548
results = results[:n]
4649
for _, r := range results {
@@ -61,5 +64,9 @@ func lookupAddr(context, network, address string) (net.Addr, error) {
6164
return &net.UDPAddr{IP: ip, Port: port}, nil
6265
}
6366
}
64-
return nil, &net.DNSError{Err: "lookup failed", Name: hostname, IsNotFound: true}
67+
return nil, &net.DNSError{
68+
Err: "lookup failed",
69+
Name: hostname,
70+
IsNotFound: true,
71+
}
6572
}

lookup_wasip1_purego.go renamed to wasip1/lookup_wasip1_purego.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//go:build wasip1 && purego
22

3-
package net
3+
package wasip1
44

55
import (
66
"fmt"
@@ -18,11 +18,11 @@ func lookupAddr(context, network, address string) (net.Addr, error) {
1818
case "unix", "unixgram":
1919
return &net.UnixAddr{Name: address, Net: network}, nil
2020
default:
21-
return nil, fmt.Errorf("not implemented: %s", network)
21+
return nil, net.UnknownNetworkError(network)
2222
}
2323
hostname, service, err := net.SplitHostPort(address)
2424
if err != nil {
25-
return nil, err
25+
return nil, net.InvalidAddrError(address)
2626
}
2727
port, err := net.LookupPort(network, service)
2828
if err != nil {
@@ -71,5 +71,9 @@ func lookupAddr(context, network, address string) (net.Addr, error) {
7171
}
7272
}
7373
}
74-
return nil, &net.DNSError{Err: "lookup failed", Name: hostname, IsNotFound: true}
74+
return nil, &net.DNSError{
75+
Err: "lookup failed",
76+
Name: hostname,
77+
IsNotFound: true,
78+
}
7579
}

0 commit comments

Comments
 (0)