10
0
Fork 0
mirror of https://github.com/ZeusWPI/ZNS.git synced 2024-10-29 21:14:27 +01:00

Add wildcard support

This commit is contained in:
Xander Bil 2024-07-08 22:14:35 +02:00
parent e99ba5c97e
commit 32f36e895d
No known key found for this signature in database
GPG key ID: EC9706B54A278598
4 changed files with 60 additions and 25 deletions

View file

@ -35,16 +35,18 @@ impl Record {
pub fn get( pub fn get(
db: &mut PgConnection, db: &mut PgConnection,
name: String, name: String,
_type: i32, _type: Option<i32>,
class: i32, class: i32,
) -> Result<Vec<Record>, diesel::result::Error> { ) -> Result<Vec<Record>, diesel::result::Error> {
records::table let mut query = records::table.into_boxed();
.filter(
records::name query = query.filter(records::name.eq(name).and(records::class.eq(class)));
.eq(name)
.and(records::_type.eq(_type).and(records::class.eq(class))), if let Some(value) = _type {
) query = query.filter(records::_type.eq(value))
.get_results(db) }
query.get_results(db)
} }
pub fn create( pub fn create(
@ -98,16 +100,19 @@ pub fn insert_into_database(rr: &RR, connection: &mut PgConnection) -> Result<()
pub fn get_from_database( pub fn get_from_database(
name: &Vec<String>, name: &Vec<String>,
_type: Type, _type: Option<Type>,
class: Class, class: Class,
connection: &mut PgConnection, connection: &mut PgConnection,
) -> Result<Vec<RR>, ZNSError> { ) -> Result<Vec<RR>, ZNSError> {
let records = let records = Record::get(
Record::get(connection, name.join("."), _type.into(), class.into()).map_err(|e| { connection,
ZNSError::Database { name.join("."),
message: e.to_string(), _type.map(|t| t.into()),
} class.into(),
})?; )
.map_err(|e| ZNSError::Database {
message: e.to_string(),
})?;
Ok(records Ok(records
.into_iter() .into_iter()
@ -154,7 +159,12 @@ mod tests {
let rr = get_rr(); let rr = get_rr();
let f = |connection: &mut PgConnection| { let f = |connection: &mut PgConnection| {
get_from_database(&rr.name, rr._type.clone(), rr.class.clone(), connection) get_from_database(
&rr.name,
Some(rr._type.clone()),
rr.class.clone(),
connection,
)
}; };
assert!(f(&mut connection).unwrap().is_empty()); assert!(f(&mut connection).unwrap().is_empty());

View file

@ -1,11 +1,16 @@
use diesel::PgConnection; use diesel::PgConnection;
use crate::{db::models::get_from_database, errors::ZNSError, structs::Message}; use crate::{
db::models::get_from_database,
errors::ZNSError,
structs::{Message, Question, RR},
};
use super::ResponseHandler; use super::ResponseHandler;
pub struct QueryHandler {} pub struct QueryHandler {}
//TODO: the clones in this file should and could be avoided
impl ResponseHandler for QueryHandler { impl ResponseHandler for QueryHandler {
async fn handle( async fn handle(
message: &Message, message: &Message,
@ -18,17 +23,20 @@ impl ResponseHandler for QueryHandler {
for question in &message.question { for question in &message.question {
let answers = get_from_database( let answers = get_from_database(
&question.qname, &question.qname,
question.qtype.clone(), Some(question.qtype.clone()),
question.qclass.clone(), question.qclass.clone(),
connection, connection,
); );
match answers { match answers {
Ok(rrs) => { Ok(mut rrs) => {
if rrs.len() == 0 { if rrs.len() == 0 {
return Err(ZNSError::NXDomain { rrs.extend(try_wildcard(question, connection)?);
domain: question.qname.join("."), if rrs.len() == 0 {
}); return Err(ZNSError::NXDomain {
domain: question.qname.join("."),
});
}
} }
response.header.ancount += rrs.len() as u16; response.header.ancount += rrs.len() as u16;
response.answer.extend(rrs) response.answer.extend(rrs)
@ -45,6 +53,23 @@ impl ResponseHandler for QueryHandler {
} }
} }
fn try_wildcard(question: &Question, connection: &mut PgConnection) -> Result<Vec<RR>, ZNSError> {
let records = get_from_database(&question.qname, None, question.qclass.clone(), connection)?;
if records.len() > 0 {
Ok(vec![])
} else {
let mut qname = question.qname.clone();
qname[0] = String::from("*");
get_from_database(
&qname,
Some(question.qtype.clone()),
question.qclass.clone(),
connection,
)
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

View file

@ -58,7 +58,7 @@ async fn validate_dnskey(
) -> Result<bool, ZNSError> { ) -> Result<bool, ZNSError> {
Ok(get_from_database( Ok(get_from_database(
zone, zone,
Type::Type(RRType::DNSKEY), Some(Type::Type(RRType::DNSKEY)),
Class::Class(RRClass::IN), Class::Class(RRClass::IN),
connection, connection,
)? )?

View file

@ -66,12 +66,12 @@ impl<'a> Reader<'a> {
} }
pub fn seek(&self, position: usize) -> Result<Self> { pub fn seek(&self, position: usize) -> Result<Self> {
if position >= self.position { if position >= self.position - 2 {
Err(ZNSError::Reader { Err(ZNSError::Reader {
message: String::from("Seeking into the future is not allowed!!"), message: String::from("Seeking into the future is not allowed!!"),
}) })
} else { } else {
let mut reader = Reader::new(&self.buffer[0..self.position]); let mut reader = Reader::new(&self.buffer[..self.position]);
reader.position = position; reader.position = position;
Ok(reader) Ok(reader)
} }