use crate::Context; use std::sync::{Mutex, Arc}; use crate::dns::filter::DnsFilter; use crate::dns::protocol::{DnsPacket, QueryType, DnsRecord, DnsQuestion}; use log::{trace, debug, info, warn, error}; pub struct BlockchainFilter { context: Arc> } impl BlockchainFilter { pub fn new(context: Arc>) -> Self { BlockchainFilter { context } } } impl DnsFilter for BlockchainFilter { fn lookup(&self, qname: &str, qtype: QueryType) -> Option { let data = self.context.lock().unwrap().blockchain.get_domain_info(qname); match data { None => { debug!("Not found data for domain {}", &qname); } Some(data) => { info!("Found data for domain {}", &qname); let records: Vec = match serde_json::from_str(&data) { Err(_) => { return None; } Ok(records) => { records } }; let mut answers: Vec = Vec::new(); for mut record in records { if record.get_querytype() == qtype { match &mut record { // TODO make it for all types of records DnsRecord::A { domain, .. } | DnsRecord::AAAA { domain, .. } if domain == "@" => { *domain = String::from(qname); } _ => () } answers.push(record); } } if !answers.is_empty() { // Create DnsPacket let mut packet = DnsPacket::new(); packet.questions.push(DnsQuestion::new(String::from(qname), qtype)); for answer in answers { packet.answers.push(answer); } return Some(packet); } } } None } }