Skip to content

Commit 043bd3f

Browse files
committed
net: wasip2: UDP client
1 parent 71c5c4f commit 043bd3f

File tree

2 files changed

+140
-0
lines changed

2 files changed

+140
-0
lines changed

netdev_wasip2.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,11 @@ func (n *wasip2Netdev) Socket(domain int, stype int, protocol int) (sockfd int,
134134
if err != nil {
135135
return -1, err
136136
}
137+
case _SOCK_DGRAM:
138+
sock, err = createUDPSocket(af)
139+
if err != nil {
140+
return -1, err
141+
}
137142
default:
138143
return -1, fmt.Errorf("wasip2: unsupported socket type %d", stype)
139144
}

udp_wasip2.go

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
//go:build wasip2
2+
3+
// WASI preview 2 UDP
4+
5+
package net
6+
7+
import (
8+
"fmt"
9+
"time"
10+
11+
"internal/cm"
12+
instancenetwork "internal/wasi/sockets/v0.2.0/instance-network"
13+
"internal/wasi/sockets/v0.2.0/network"
14+
"internal/wasi/sockets/v0.2.0/udp"
15+
udpcreatesocket "internal/wasi/sockets/v0.2.0/udp-create-socket"
16+
)
17+
18+
type wasip2UdpSocket struct {
19+
udpcreatesocket.UDPSocket
20+
udp.Pollable
21+
*udp.IncomingDatagramStream
22+
*udp.OutgoingDatagramStream
23+
}
24+
25+
func createUDPSocket(af network.IPAddressFamily) (wasip2Socket, error) {
26+
res := udpcreatesocket.CreateUDPSocket(af)
27+
if res.IsErr() {
28+
return nil, fmt.Errorf("failed to create UDP socket: %s", res.Err().String())
29+
}
30+
31+
sock := res.OK()
32+
return &wasip2UdpSocket{
33+
UDPSocket: *sock,
34+
Pollable: sock.Subscribe(),
35+
}, nil
36+
}
37+
38+
func (s *wasip2UdpSocket) Bind(globalNetwork instancenetwork.Network, addr network.IPSocketAddress) error {
39+
res := s.StartBind(globalNetwork, addr)
40+
if res.IsErr() {
41+
return fmt.Errorf("failed to start binding socket: %s", res.Err().String())
42+
}
43+
44+
res = s.FinishBind()
45+
if res.IsErr() {
46+
return fmt.Errorf("failed to finish binding socket: %s", res.Err().String())
47+
}
48+
49+
return nil
50+
}
51+
52+
func (s *wasip2UdpSocket) Listen(backlog int) error {
53+
fmt.Println("wasip2 UDP listen TODO:", backlog) ///
54+
return nil
55+
}
56+
57+
func (s *wasip2UdpSocket) Accept() (wasip2Socket, *network.IPSocketAddress, error) {
58+
return nil, nil, fmt.Errorf("wasip2 UDP sockets do not support Accept")
59+
}
60+
61+
func (s *wasip2UdpSocket) Connect(globalNetwork instancenetwork.Network, host string, ip network.IPSocketAddress) error {
62+
res := s.UDPSocket.Stream(cm.Some(ip))
63+
64+
if res.IsErr() {
65+
return fmt.Errorf("failed to connect UDP socket: %s", res.Err().String())
66+
}
67+
68+
s.IncomingDatagramStream, s.OutgoingDatagramStream = &res.OK().F0, &res.OK().F1
69+
70+
return nil
71+
}
72+
73+
func (c wasip2UdpSocket) Send(buf []byte, flags int, deadline time.Time) (int, error) {
74+
if flags != 0 {
75+
fmt.Println("wasip2 UDP send flags TODO:", flags) ///
76+
}
77+
78+
if c.OutgoingDatagramStream == nil {
79+
return -1, fmt.Errorf("send called on a socket without open streams")
80+
}
81+
82+
res := c.OutgoingDatagramStream.CheckSend()
83+
if res.IsErr() {
84+
return -1, fmt.Errorf("failed to write to output stream: %s", res.Err().String())
85+
}
86+
87+
if *res.OK() == 0 {
88+
c.Block()
89+
}
90+
91+
a := []udp.OutgoingDatagram{
92+
{
93+
Data: cm.NewList(&buf[0], len(buf)),
94+
// RemoteAddress: cm.Some(c.raddr),
95+
},
96+
}
97+
98+
c.OutgoingDatagramStream.Send(cm.NewList(&a[0], 1))
99+
100+
return len(buf), nil
101+
}
102+
103+
func (c wasip2UdpSocket) Recv(buf []byte, flags int, deadline time.Time) (int, error) {
104+
if flags != 0 {
105+
fmt.Println("wasip2 UDP recv flags TODO:", flags) ///
106+
}
107+
108+
if c.IncomingDatagramStream == nil {
109+
return -1, fmt.Errorf("recv called on a socket without open streams")
110+
}
111+
112+
res := c.Receive(1)
113+
if res.IsErr() {
114+
return -1, fmt.Errorf("failed to read from input stream: %s", res.Err().String())
115+
}
116+
117+
if res.OK().Len() != 1 {
118+
return -1, fmt.Errorf("expected 1 datagram, got %d", res.OK().Len())
119+
}
120+
121+
return copy(buf, res.OK().Data().Data.Slice()), nil
122+
}
123+
124+
func (c wasip2UdpSocket) Close() error {
125+
if c.IncomingDatagramStream != nil {
126+
c.IncomingDatagramStream.ResourceDrop()
127+
}
128+
if c.OutgoingDatagramStream != nil {
129+
c.OutgoingDatagramStream.ResourceDrop()
130+
}
131+
c.Pollable.ResourceDrop()
132+
c.UDPSocket.ResourceDrop()
133+
134+
return nil
135+
}

0 commit comments

Comments
 (0)