17074afb6SRoman Volosatovs use futures::join;
27074afb6SRoman Volosatovs use test_programs::p3::wasi::sockets::types::{
37074afb6SRoman Volosatovs     IpAddress, IpAddressFamily, IpSocketAddress, Ipv4SocketAddress, Ipv6SocketAddress, UdpSocket,
47074afb6SRoman Volosatovs };
5*62d9b187SAlex Crichton use test_programs::sockets::supports_ipv6;
67074afb6SRoman Volosatovs 
77074afb6SRoman Volosatovs struct Component;
87074afb6SRoman Volosatovs 
97074afb6SRoman Volosatovs test_programs::p3::export!(Component);
107074afb6SRoman Volosatovs 
test_udp_sample_application(family: IpAddressFamily, bind_address: IpSocketAddress)117074afb6SRoman Volosatovs async fn test_udp_sample_application(family: IpAddressFamily, bind_address: IpSocketAddress) {
127074afb6SRoman Volosatovs     let unspecified_addr = IpSocketAddress::new(IpAddress::new_unspecified(family), 0);
137074afb6SRoman Volosatovs 
147074afb6SRoman Volosatovs     let first_message = &[];
157074afb6SRoman Volosatovs     let second_message = b"Hello, world!";
167074afb6SRoman Volosatovs     let third_message = b"Greetings, planet!";
177074afb6SRoman Volosatovs 
187c9f88daSAlex Crichton     let server = UdpSocket::create(family).unwrap();
197074afb6SRoman Volosatovs 
207074afb6SRoman Volosatovs     server.bind(bind_address).unwrap();
217c9f88daSAlex Crichton     let addr = server.get_local_address().unwrap();
227074afb6SRoman Volosatovs 
237c9f88daSAlex Crichton     let client = UdpSocket::create(family).unwrap();
247074afb6SRoman Volosatovs     client.bind(unspecified_addr).unwrap();
257074afb6SRoman Volosatovs     client.connect(addr).unwrap();
267c9f88daSAlex Crichton     let client_addr = client.get_local_address().unwrap();
277074afb6SRoman Volosatovs     join!(
287074afb6SRoman Volosatovs         async {
297074afb6SRoman Volosatovs             client.send(first_message.to_vec(), None).await.unwrap();
307074afb6SRoman Volosatovs             client
317074afb6SRoman Volosatovs                 .send(second_message.to_vec(), Some(addr))
327074afb6SRoman Volosatovs                 .await
337074afb6SRoman Volosatovs                 .unwrap();
347074afb6SRoman Volosatovs         },
357074afb6SRoman Volosatovs         async {
367074afb6SRoman Volosatovs             // Check that we've received our sent messages.
377074afb6SRoman Volosatovs             let (buf, addr) = server.receive().await.unwrap();
387074afb6SRoman Volosatovs             assert_eq!(buf, first_message);
397074afb6SRoman Volosatovs             assert_eq!(addr, client_addr);
407074afb6SRoman Volosatovs 
417074afb6SRoman Volosatovs             let (buf, addr) = server.receive().await.unwrap();
427074afb6SRoman Volosatovs             assert_eq!(buf, second_message);
437074afb6SRoman Volosatovs             assert_eq!(addr, client_addr);
447074afb6SRoman Volosatovs         }
457074afb6SRoman Volosatovs     );
467074afb6SRoman Volosatovs     join!(
477074afb6SRoman Volosatovs         async {
487074afb6SRoman Volosatovs             // Another client
497c9f88daSAlex Crichton             let client = UdpSocket::create(family).unwrap();
507074afb6SRoman Volosatovs             client.bind(unspecified_addr).unwrap();
517074afb6SRoman Volosatovs             client
527074afb6SRoman Volosatovs                 .send(third_message.to_vec(), Some(addr))
537074afb6SRoman Volosatovs                 .await
547074afb6SRoman Volosatovs                 .unwrap();
557074afb6SRoman Volosatovs         },
567074afb6SRoman Volosatovs         async {
577074afb6SRoman Volosatovs             // Check that we sent and received our message!
587074afb6SRoman Volosatovs             let (buf, _) = server.receive().await.unwrap();
597074afb6SRoman Volosatovs             assert_eq!(buf, third_message);
607074afb6SRoman Volosatovs         },
617074afb6SRoman Volosatovs     );
627074afb6SRoman Volosatovs }
637074afb6SRoman Volosatovs 
647074afb6SRoman Volosatovs impl test_programs::p3::exports::wasi::cli::run::Guest for Component {
run() -> Result<(), ()>657074afb6SRoman Volosatovs     async fn run() -> Result<(), ()> {
667074afb6SRoman Volosatovs         test_udp_sample_application(
677074afb6SRoman Volosatovs             IpAddressFamily::Ipv4,
687074afb6SRoman Volosatovs             IpSocketAddress::Ipv4(Ipv4SocketAddress {
697074afb6SRoman Volosatovs                 port: 0,                 // use any free port
707074afb6SRoman Volosatovs                 address: (127, 0, 0, 1), // localhost
717074afb6SRoman Volosatovs             }),
727074afb6SRoman Volosatovs         )
737074afb6SRoman Volosatovs         .await;
74*62d9b187SAlex Crichton         if supports_ipv6() {
757074afb6SRoman Volosatovs             test_udp_sample_application(
767074afb6SRoman Volosatovs                 IpAddressFamily::Ipv6,
777074afb6SRoman Volosatovs                 IpSocketAddress::Ipv6(Ipv6SocketAddress {
787074afb6SRoman Volosatovs                     port: 0,                           // use any free port
797074afb6SRoman Volosatovs                     address: (0, 0, 0, 0, 0, 0, 0, 1), // localhost
807074afb6SRoman Volosatovs                     flow_info: 0,
817074afb6SRoman Volosatovs                     scope_id: 0,
827074afb6SRoman Volosatovs                 }),
837074afb6SRoman Volosatovs             )
847074afb6SRoman Volosatovs             .await;
85*62d9b187SAlex Crichton         }
867074afb6SRoman Volosatovs         Ok(())
877074afb6SRoman Volosatovs     }
887074afb6SRoman Volosatovs }
897074afb6SRoman Volosatovs 
main()907074afb6SRoman Volosatovs fn main() {}
91