1*b315a0a8SYosh use test_programs::sockets::supports_ipv6;
2*b315a0a8SYosh use test_programs::wasi::sockets::network::{
3*b315a0a8SYosh     IpAddress, IpAddressFamily, IpSocketAddress, Ipv4SocketAddress, Ipv6SocketAddress, Network,
4*b315a0a8SYosh };
5*b315a0a8SYosh use test_programs::wasi::sockets::udp::{OutgoingDatagram, UdpSocket};
6*b315a0a8SYosh 
test_udp_sample_application(family: IpAddressFamily, bind_address: IpSocketAddress)7*b315a0a8SYosh fn test_udp_sample_application(family: IpAddressFamily, bind_address: IpSocketAddress) {
8*b315a0a8SYosh     let unspecified_addr = IpSocketAddress::new(IpAddress::new_unspecified(family), 0);
9*b315a0a8SYosh 
10*b315a0a8SYosh     let first_message = &[];
11*b315a0a8SYosh     let second_message = b"Hello, world!";
12*b315a0a8SYosh     let third_message = b"Greetings, planet!";
13*b315a0a8SYosh 
14*b315a0a8SYosh     let net = Network::default();
15*b315a0a8SYosh 
16*b315a0a8SYosh     let server = UdpSocket::new(family).unwrap();
17*b315a0a8SYosh 
18*b315a0a8SYosh     server.blocking_bind(&net, bind_address).unwrap();
19*b315a0a8SYosh     let (server_incoming, _) = server.stream(None).unwrap();
20*b315a0a8SYosh     let addr = server.local_address().unwrap();
21*b315a0a8SYosh 
22*b315a0a8SYosh     let client_addr = {
23*b315a0a8SYosh         let client = UdpSocket::new(family).unwrap();
24*b315a0a8SYosh         client.blocking_bind(&net, unspecified_addr).unwrap();
25*b315a0a8SYosh         let (_, client_outgoing) = client.stream(Some(addr)).unwrap();
26*b315a0a8SYosh 
27*b315a0a8SYosh         let datagrams = [
28*b315a0a8SYosh             OutgoingDatagram {
29*b315a0a8SYosh                 data: first_message.to_vec(),
30*b315a0a8SYosh                 remote_address: None,
31*b315a0a8SYosh             },
32*b315a0a8SYosh             OutgoingDatagram {
33*b315a0a8SYosh                 data: second_message.to_vec(),
34*b315a0a8SYosh                 remote_address: Some(addr),
35*b315a0a8SYosh             },
36*b315a0a8SYosh         ];
37*b315a0a8SYosh         client_outgoing.blocking_send(&datagrams).unwrap();
38*b315a0a8SYosh 
39*b315a0a8SYosh         client.local_address().unwrap()
40*b315a0a8SYosh     };
41*b315a0a8SYosh 
42*b315a0a8SYosh     {
43*b315a0a8SYosh         // Check that we've received our sent messages.
44*b315a0a8SYosh         let datagrams = server_incoming.blocking_receive(2..100).unwrap();
45*b315a0a8SYosh         assert_eq!(datagrams.len(), 2);
46*b315a0a8SYosh 
47*b315a0a8SYosh         assert_eq!(datagrams[0].data, first_message);
48*b315a0a8SYosh         assert_eq!(datagrams[0].remote_address, client_addr);
49*b315a0a8SYosh 
50*b315a0a8SYosh         assert_eq!(datagrams[1].data, second_message);
51*b315a0a8SYosh         assert_eq!(datagrams[1].remote_address, client_addr);
52*b315a0a8SYosh     }
53*b315a0a8SYosh 
54*b315a0a8SYosh     // Another client
55*b315a0a8SYosh     {
56*b315a0a8SYosh         let client = UdpSocket::new(family).unwrap();
57*b315a0a8SYosh         client.blocking_bind(&net, unspecified_addr).unwrap();
58*b315a0a8SYosh         let (_, client_outgoing) = client.stream(None).unwrap();
59*b315a0a8SYosh 
60*b315a0a8SYosh         let datagrams = [OutgoingDatagram {
61*b315a0a8SYosh             data: third_message.to_vec(),
62*b315a0a8SYosh             remote_address: Some(addr),
63*b315a0a8SYosh         }];
64*b315a0a8SYosh         client_outgoing.blocking_send(&datagrams).unwrap();
65*b315a0a8SYosh     }
66*b315a0a8SYosh 
67*b315a0a8SYosh     {
68*b315a0a8SYosh         // Check that we sent and received our message!
69*b315a0a8SYosh         let datagrams = server_incoming.blocking_receive(1..100).unwrap();
70*b315a0a8SYosh         assert_eq!(datagrams.len(), 1);
71*b315a0a8SYosh 
72*b315a0a8SYosh         assert_eq!(datagrams[0].data, third_message);
73*b315a0a8SYosh     }
74*b315a0a8SYosh }
75*b315a0a8SYosh 
main()76*b315a0a8SYosh fn main() {
77*b315a0a8SYosh     test_udp_sample_application(
78*b315a0a8SYosh         IpAddressFamily::Ipv4,
79*b315a0a8SYosh         IpSocketAddress::Ipv4(Ipv4SocketAddress {
80*b315a0a8SYosh             port: 0,                 // use any free port
81*b315a0a8SYosh             address: (127, 0, 0, 1), // localhost
82*b315a0a8SYosh         }),
83*b315a0a8SYosh     );
84*b315a0a8SYosh     if supports_ipv6() {
85*b315a0a8SYosh         test_udp_sample_application(
86*b315a0a8SYosh             IpAddressFamily::Ipv6,
87*b315a0a8SYosh             IpSocketAddress::Ipv6(Ipv6SocketAddress {
88*b315a0a8SYosh                 port: 0,                           // use any free port
89*b315a0a8SYosh                 address: (0, 0, 0, 0, 0, 0, 0, 1), // localhost
90*b315a0a8SYosh                 flow_info: 0,
91*b315a0a8SYosh                 scope_id: 0,
92*b315a0a8SYosh             }),
93*b315a0a8SYosh         );
94*b315a0a8SYosh     }
95*b315a0a8SYosh }
96