mirror of
https://github.com/ZeusWPI/ZNS.git
synced 2024-10-30 05:24:26 +01:00
Add wildcard support
This commit is contained in:
parent
e99ba5c97e
commit
32f36e895d
4 changed files with 60 additions and 25 deletions
|
@ -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,15 +100,18 @@ 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("."),
|
||||||
|
_type.map(|t| t.into()),
|
||||||
|
class.into(),
|
||||||
|
)
|
||||||
|
.map_err(|e| ZNSError::Database {
|
||||||
message: e.to_string(),
|
message: e.to_string(),
|
||||||
}
|
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok(records
|
Ok(records
|
||||||
|
@ -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());
|
||||||
|
|
|
@ -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,18 +23,21 @@ 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 {
|
||||||
|
rrs.extend(try_wildcard(question, connection)?);
|
||||||
if rrs.len() == 0 {
|
if rrs.len() == 0 {
|
||||||
return Err(ZNSError::NXDomain {
|
return Err(ZNSError::NXDomain {
|
||||||
domain: question.qname.join("."),
|
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::*;
|
||||||
|
|
|
@ -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,
|
||||||
)?
|
)?
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue