use futures_util::stream::Stream;
#[cfg(any(feature = "std", feature = "no-std-rand"))]
use tracing::debug;
use crate::error::*;
use crate::op::Query;
use crate::xfer::{DnsRequest, DnsRequestOptions, DnsResponse, SerialMessage};
#[cfg(any(feature = "std", feature = "no-std-rand"))]
use crate::{
op::{Edns, Message, MessageType, OpCode},
random,
};
#[cfg(any(feature = "std", feature = "no-std-rand"))]
const MAX_PAYLOAD_LEN: u16 = 1232;
pub trait DnsStreamHandle: 'static + Send {
fn send(&mut self, buffer: SerialMessage) -> Result<(), ProtoError>;
}
pub trait DnsHandle: 'static + Clone + Send + Sync + Unpin {
type Response: Stream<Item = Result<DnsResponse, ProtoError>> + Send + Unpin + 'static;
fn is_verifying_dnssec(&self) -> bool {
false
}
fn is_using_edns(&self) -> bool {
true
}
fn send<R: Into<DnsRequest> + Unpin + Send + 'static>(&self, request: R) -> Self::Response;
#[cfg(any(feature = "std", feature = "no-std-rand"))]
fn lookup(&self, query: Query, options: DnsRequestOptions) -> Self::Response {
debug!("querying: {} {:?}", query.name(), query.query_type());
self.send(build_request(query, options))
}
#[cfg(not(any(feature = "std", feature = "no-std-rand")))]
fn lookup(&self, query: Query, options: DnsRequestOptions) -> Self::Response;
}
#[cfg_attr(not(any(feature = "std", feature = "no-std-rand")), expect(unused_mut))]
#[cfg(any(feature = "std", feature = "no-std-rand"))]
fn build_request(mut query: Query, options: DnsRequestOptions) -> DnsRequest {
let mut message: Message = Message::new();
let id: u16 = random();
let mut original_query = None;
#[cfg(feature = "std")]
if options.case_randomization {
original_query = Some(query.clone());
query.name.randomize_label_case();
}
message
.add_query(query)
.set_id(id)
.set_message_type(MessageType::Query)
.set_op_code(OpCode::Query)
.set_recursion_desired(options.recursion_desired);
if options.use_edns {
message
.extensions_mut()
.get_or_insert_with(Edns::new)
.set_max_payload(MAX_PAYLOAD_LEN)
.set_version(0)
.set_dnssec_ok(options.edns_set_dnssec_ok);
}
DnsRequest::new(message, options).with_original_query(original_query)
}