pharos-plugins 0.1.0

CoreDNS-compatible Plugins for the Pharos DNS server
Documentation
#![forbid(unsafe_code)]
#![cfg(all(feature = "plugin-cache", feature = "plugin-whoami"))]
#![recursion_limit = "512"]

use std::alloc::System;

use pharos_corefile::{configure, parse};
use pharos_plugins::{Chain, directives, servers};
use pharos_proto::{Message, Rdata};
use pharos_server::{Action, Handler, Protocol};
use stats_alloc::{INSTRUMENTED_SYSTEM, StatsAlloc};

#[global_allocator]
static GLOBAL: &StatsAlloc<System> = &INSTRUMENTED_SYSTEM;

#[tokio::test(flavor = "current_thread")]
async fn warmed_routed_cache_hit_has_no_allocations() {
    let blocks = parse(
        "Corefile",
        ".:0 {\n cache {\n success 1024 3600 3600\n }\n whoami\n}",
    )
    .unwrap();
    let (mut servers, _) = servers(configure::<Chain>(&blocks, directives()).unwrap()).unwrap();
    let (_, server) = servers.drain().next().unwrap();
    let query = b"\x12\x34\x01\0\0\x01\0\0\0\0\0\0\x03www\x07example\x03com\0\0\x01\0\x01";
    let first = "127.0.0.1:1001".parse().unwrap();
    let second = "127.0.0.1:1002".parse().unwrap();
    let mut response = Vec::with_capacity(65535);
    assert_eq!(
        server
            .handle(query, first, Protocol::Udp, &mut response)
            .await,
        Action::Respond
    );
    let before = GLOBAL.stats();
    for _ in 0..100 {
        assert_eq!(
            server
                .handle(query, second, Protocol::Udp, &mut response)
                .await,
            Action::Respond
        );
    }
    let after = GLOBAL.stats();
    assert_eq!(after.allocations - before.allocations, 0);
    assert_eq!(after.reallocations - before.reallocations, 0);
    let answer = Message::parse(&response).unwrap();
    let port = answer.additionals().find_map(|rr| match rr.data().ok()? {
        Rdata::Srv { port, .. } => Some(port),
        _ => None,
    });
    assert_eq!(port, Some(1001), "response must come from the warmed cache");
}