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