Skip to main content

hickory_server/server/
response_handler.rs

1// Copyright 2015-2021 Benjamin Fry <benjaminfry@me.com>
2//
3// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4// https://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5// https://opensource.org/licenses/MIT>, at your option. This file may not be
6// copied, modified, or distributed except according to those terms.
7
8use std::net::SocketAddr;
9
10use crate::{
11    net::{BufDnsStreamHandle, DnsStreamHandle, NetError, xfer::Protocol},
12    proto::{op::SerialMessage, rr::Record},
13    server::ResponseInfo,
14    zone_handler::MessageResponse,
15};
16
17/// A handler for send a response to a client
18#[async_trait::async_trait]
19pub trait ResponseHandler: Clone + Send + Sync + Unpin + 'static {
20    // TODO: add associated error type
21    //type Error;
22
23    /// Serializes and sends a message to the wrapped handle
24    async fn send_response<'a>(
25        &mut self,
26        response: MessageResponse<
27            '_,
28            'a,
29            impl Iterator<Item = &'a Record> + Send + 'a,
30            impl Iterator<Item = &'a Record> + Send + 'a,
31            impl Iterator<Item = &'a Record> + Send + 'a,
32            impl Iterator<Item = &'a Record> + Send + 'a,
33        >,
34    ) -> Result<ResponseInfo, NetError>;
35}
36
37/// A handler for wrapping a [`BufDnsStreamHandle`], which will properly serialize the message and add the
38///  associated destination.
39#[derive(Clone)]
40pub struct ResponseHandle {
41    dst: SocketAddr,
42    stream_handle: BufDnsStreamHandle,
43    protocol: Protocol,
44}
45
46impl ResponseHandle {
47    /// Returns a new `ResponseHandle` for sending a response message
48    pub fn new(dst: SocketAddr, stream_handle: BufDnsStreamHandle, protocol: Protocol) -> Self {
49        Self {
50            dst,
51            stream_handle,
52            protocol,
53        }
54    }
55}
56
57#[async_trait::async_trait]
58impl ResponseHandler for ResponseHandle {
59    /// Serializes and sends a message to the wrapped handle
60    async fn send_response<'a>(
61        &mut self,
62        response: MessageResponse<
63            '_,
64            'a,
65            impl Iterator<Item = &'a Record> + Send + 'a,
66            impl Iterator<Item = &'a Record> + Send + 'a,
67            impl Iterator<Item = &'a Record> + Send + 'a,
68            impl Iterator<Item = &'a Record> + Send + 'a,
69        >,
70    ) -> Result<ResponseInfo, NetError> {
71        let (info, buffer) = response.encode(self.protocol)?;
72        self.stream_handle
73            .send(SerialMessage::new(buffer, self.dst))?;
74
75        Ok(info)
76    }
77}