hickory_proto/multicast/
mdns_client_stream.rs1use alloc::boxed::Box;
9use core::fmt::{self, Display};
10use core::future::Future;
11use core::pin::Pin;
12use core::task::{Context, Poll};
13use std::net::{Ipv4Addr, SocketAddr};
14
15use futures_util::future::{FutureExt, TryFutureExt};
16use futures_util::stream::{Stream, StreamExt, TryStreamExt};
17
18use crate::BufDnsStreamHandle;
19use crate::error::ProtoError;
20use crate::multicast::mdns_stream::{MDNS_IPV4, MDNS_IPV6};
21use crate::multicast::{MdnsQueryType, MdnsStream};
22use crate::runtime::TokioTime;
23use crate::xfer::{DnsClientStream, SerialMessage};
24
25#[must_use = "futures do nothing unless polled"]
27pub struct MdnsClientStream {
28 mdns_stream: MdnsStream,
29}
30
31impl MdnsClientStream {
32 pub fn new_ipv4(
34 mdns_query_type: MdnsQueryType,
35 packet_ttl: Option<u32>,
36 ipv4_if: Option<Ipv4Addr>,
37 ) -> (MdnsClientConnect, BufDnsStreamHandle) {
38 Self::new(*MDNS_IPV4, mdns_query_type, packet_ttl, ipv4_if, None)
39 }
40
41 pub fn new_ipv6(
43 mdns_query_type: MdnsQueryType,
44 packet_ttl: Option<u32>,
45 ipv6_if: Option<u32>,
46 ) -> (MdnsClientConnect, BufDnsStreamHandle) {
47 Self::new(*MDNS_IPV6, mdns_query_type, packet_ttl, None, ipv6_if)
48 }
49
50 #[allow(clippy::new_ret_no_self)]
59 pub fn new(
60 mdns_addr: SocketAddr,
61 mdns_query_type: MdnsQueryType,
62 packet_ttl: Option<u32>,
63 ipv4_if: Option<Ipv4Addr>,
64 ipv6_if: Option<u32>,
65 ) -> (MdnsClientConnect, BufDnsStreamHandle) {
66 let (stream_future, sender) =
67 MdnsStream::new(mdns_addr, mdns_query_type, packet_ttl, ipv4_if, ipv6_if);
68
69 let stream_future = stream_future
70 .map_ok(move |mdns_stream| Self { mdns_stream })
71 .map_err(ProtoError::from);
72
73 let new_future = Box::new(stream_future);
74 let new_future = MdnsClientConnect(new_future);
75
76 (new_future, sender)
77 }
78}
79
80impl Display for MdnsClientStream {
81 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
82 write!(formatter, "mDNS({})", self.mdns_stream.multicast_addr())
83 }
84}
85
86impl DnsClientStream for MdnsClientStream {
87 type Time = TokioTime;
88
89 fn name_server_addr(&self) -> SocketAddr {
90 self.mdns_stream.multicast_addr()
91 }
92}
93
94impl Stream for MdnsClientStream {
95 type Item = Result<SerialMessage, ProtoError>;
96
97 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
98 let mdns_stream = &mut self.as_mut().mdns_stream;
99 mdns_stream.map_err(ProtoError::from).poll_next_unpin(cx)
100 }
109}
110
111pub struct MdnsClientConnect(
113 Box<dyn Future<Output = Result<MdnsClientStream, ProtoError>> + Send + Unpin>,
114);
115
116impl Future for MdnsClientConnect {
117 type Output = Result<MdnsClientStream, ProtoError>;
118
119 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
120 self.0.as_mut().poll_unpin(cx)
121 }
122}