1use crate::FuchsiaTime;
6use async_trait::async_trait;
7use fuchsia_async::net::UdpSocket;
8use futures::FutureExt as _;
9use std::io;
10use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr};
11use std::pin::pin;
12use std::task::{Context, Poll};
13use trust_dns_proto::udp;
14
15pub struct DnsUdpSocket(UdpSocket);
18
19#[async_trait]
20impl udp::UdpSocket for DnsUdpSocket {
21 type Time = FuchsiaTime;
22
23 async fn connect_with_bind(_addr: SocketAddr, bind_addr: SocketAddr) -> io::Result<Self> {
24 let socket = Self::bind(bind_addr).await?;
25
26 Ok(socket)
33 }
34
35 async fn connect(addr: SocketAddr) -> io::Result<Self> {
36 let bind_addr = match addr {
37 SocketAddr::V4(_addr) => (Ipv4Addr::UNSPECIFIED, 0).into(),
38 SocketAddr::V6(_addr) => (Ipv6Addr::UNSPECIFIED, 0).into(),
39 };
40
41 Self::connect_with_bind(addr, bind_addr).await
42 }
43
44 async fn bind(addr: SocketAddr) -> io::Result<Self> {
45 UdpSocket::bind(&addr).map(Self)
46 }
47
48 fn poll_recv_from(
49 &self,
50 cx: &mut Context<'_>,
51 buf: &mut [u8],
52 ) -> Poll<io::Result<(usize, SocketAddr)>> {
53 let fut = self.recv_from(buf);
54 let mut fut = pin!(fut);
55 fut.poll_unpin(cx)
56 }
57
58 async fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
59 let Self(socket) = self;
60 socket.recv_from(buf).await
61 }
62
63 fn poll_send_to(
64 &self,
65 cx: &mut Context<'_>,
66 buf: &[u8],
67 target: SocketAddr,
68 ) -> Poll<io::Result<usize>> {
69 let fut = self.send_to(buf, target);
70 let mut fut = pin!(fut);
71 fut.poll_unpin(cx)
72 }
73
74 async fn send_to(&self, buf: &[u8], target: SocketAddr) -> io::Result<usize> {
75 let Self(socket) = self;
76 socket.send_to(buf, target).await
77 }
78}
79
80#[cfg(test)]
81mod test {
82 use super::*;
83 use crate::FuchsiaExec;
84
85 use net_declare::std::ip;
86
87 #[test]
88 fn test_next_random_socket() {
89 use trust_dns_proto::tests::next_random_socket_test;
90 let exec = FuchsiaExec::new().expect("failed to create fuchsia executor");
91 next_random_socket_test::<DnsUdpSocket, FuchsiaExec>(exec)
92 }
93
94 #[fuchsia_async::run_singlethreaded(test)]
95 async fn test_udp_stream_ipv4() {
96 use trust_dns_proto::tests::udp_stream_test;
97 udp_stream_test::<DnsUdpSocket>(ip!("127.0.0.1")).await
98 }
99
100 #[fuchsia_async::run_singlethreaded(test)]
101 async fn test_udp_stream_ipv6() {
102 use trust_dns_proto::tests::udp_stream_test;
103 udp_stream_test::<DnsUdpSocket>(ip!("::1")).await
104 }
105
106 #[test]
107 fn test_udp_client_stream_ipv4() {
108 use trust_dns_proto::tests::udp_client_stream_test;
109 let exec = FuchsiaExec::new().expect("failed to create fuchsia executor");
110 udp_client_stream_test::<DnsUdpSocket, FuchsiaExec, FuchsiaTime>(ip!("127.0.0.1"), exec)
111 }
112
113 #[test]
114 fn test_udp_client_stream_ipv6() {
115 use trust_dns_proto::tests::udp_client_stream_test;
116 let exec = FuchsiaExec::new().expect("failed to create fuchsia executor");
117 udp_client_stream_test::<DnsUdpSocket, FuchsiaExec, FuchsiaTime>(ip!("::1"), exec)
118 }
119}