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

Convert errors using thiserror crate

This commit is contained in:
Xander Bil 2024-06-26 00:22:41 +02:00
parent 6ac9f2f36e
commit aa94dc21bb
No known key found for this signature in database
GPG key ID: EC9706B54A278598
16 changed files with 143 additions and 212 deletions

21
Cargo.lock generated
View file

@ -943,6 +943,26 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "thiserror"
version = "1.0.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tinyvec"
version = "1.6.0"
@ -1361,5 +1381,6 @@ dependencies = [
"int-enum",
"reqwest",
"ring",
"thiserror",
"tokio",
]

View file

@ -12,3 +12,4 @@ base64 = "0.22.0"
reqwest = {version = "0.12.4", features = ["json","default"]}
asn1 = "0.16.2"
int-enum = "1.1"
thiserror = "1.0"

View file

@ -1,5 +1,5 @@
use crate::{
errors::DatabaseError,
errors::ZNSError,
structs::{Class, Type, RR},
};
use diesel::prelude::*;
@ -81,7 +81,7 @@ impl Record {
}
}
pub async fn insert_into_database(rr: &RR) -> Result<(), DatabaseError> {
pub async fn insert_into_database(rr: &RR) -> Result<(), ZNSError> {
let db_connection = &mut establish_connection();
let record = Record {
name: rr.name.join("."),
@ -92,7 +92,7 @@ pub async fn insert_into_database(rr: &RR) -> Result<(), DatabaseError> {
rdata: rr.rdata.clone(),
};
Record::create(db_connection, record).map_err(|e| DatabaseError {
Record::create(db_connection, record).map_err(|e| ZNSError::Database {
message: e.to_string(),
})?;
@ -103,11 +103,11 @@ pub async fn get_from_database(
name: &Vec<String>,
_type: Type,
class: Class,
) -> Result<Vec<RR>, DatabaseError> {
) -> Result<Vec<RR>, ZNSError> {
let db_connection = &mut establish_connection();
let records =
Record::get(db_connection, name.join("."), _type.into(), class.into()).map_err(|e| {
DatabaseError {
ZNSError::Database {
message: e.to_string(),
}
})?;

View file

@ -1,100 +1,44 @@
use core::fmt;
use thiserror::Error;
use crate::structs::RCODE;
pub struct DNSError {
pub message: String,
pub rcode: RCODE,
#[derive(Error, Debug)]
pub enum ZNSError {
#[error("Parse Error for {object:?}: {message:?}")]
Parse { object: String, message: String },
#[error("Database Error: {message:?}")]
Database { message: String },
#[error("Reader Error: {message:?}")]
Reader { message: String },
#[error("PublicKey Error: {message:?}")]
PublicKey { message: String },
#[error("Reqwest error")]
Reqwest(#[from] reqwest::Error),
#[error("DNS Query Format Error: {message:?}")]
Formerr { message: String },
#[error("Domain name does not exist")]
NXDomain { domain: String },
#[error("NotImplemented Error for {object:?}: {message:?}")]
NotImp { object: String, message: String },
#[error("Authentication Error: {message:?}")]
NotAuth { message: String },
#[error("I refuse to answer the query: {message:?}")]
Refused { message: String },
}
impl fmt::Display for DNSError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Error: {}", self.message)
}
impl ZNSError {
pub fn rcode(&self) -> RCODE {
match self {
ZNSError::Formerr { .. } | ZNSError::Parse { .. } | ZNSError::Reader { .. } => {
RCODE::FORMERR
}
ZNSError::Database { .. } | ZNSError::Reqwest(_) => RCODE::SERVFAIL,
#[derive(Debug)]
pub struct ParseError {
pub object: String,
pub message: String,
}
impl fmt::Display for ParseError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Parse Error for {}: {}", self.object, self.message)
}
}
#[derive(Debug)]
pub struct DatabaseError {
pub message: String,
}
impl fmt::Display for DatabaseError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Database Error: {}", self.message)
}
}
#[derive(Debug)]
pub struct AuthenticationError {
pub message: String,
}
impl fmt::Display for AuthenticationError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Authentication Error: {}", self.message)
}
}
#[derive(Debug)]
pub struct ReaderError {
pub message: String,
}
impl fmt::Display for ReaderError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Reader Error: {}", self.message)
}
}
impl<E> From<E> for ParseError
where
E: Into<ReaderError>,
{
fn from(value: E) -> Self {
ParseError {
object: String::from("Reader"),
message: value.into().to_string(),
}
}
}
impl<E> From<E> for DNSError
where
E: Into<ParseError>,
{
fn from(value: E) -> Self {
DNSError {
message: value.into().to_string(),
rcode: RCODE::FORMERR,
}
}
}
trait Supported {}
impl Supported for reqwest::Error {}
impl Supported for DatabaseError {}
impl<E> From<E> for AuthenticationError
where
E: Supported,
E: std::fmt::Display,
{
fn from(value: E) -> Self {
AuthenticationError {
message: value.to_string(),
ZNSError::NotAuth { .. } | ZNSError::PublicKey { .. } => RCODE::NOTAUTH,
ZNSError::NXDomain { .. } => RCODE::NXDOMAIN,
ZNSError::NotImp { .. } => RCODE::NOTIMP,
ZNSError::Refused { .. } => RCODE::REFUSED,
}
}
}

View file

@ -1,6 +1,6 @@
use crate::{
errors::DNSError,
structs::{Message, Opcode, RCODE},
errors::ZNSError,
structs::{Message, Opcode},
};
use self::{query::QueryHandler, update::UpdateHandler};
@ -9,21 +9,20 @@ mod query;
mod update;
pub trait ResponseHandler {
async fn handle(message: &Message, raw: &[u8]) -> Result<Message, DNSError>;
async fn handle(message: &Message, raw: &[u8]) -> Result<Message, ZNSError>;
}
pub struct Handler {}
impl ResponseHandler for Handler {
async fn handle(message: &Message, raw: &[u8]) -> Result<Message, DNSError> {
async fn handle(message: &Message, raw: &[u8]) -> Result<Message, ZNSError> {
match message.get_opcode() {
Ok(opcode) => match opcode {
Opcode::QUERY => QueryHandler::handle(&message, raw).await,
Opcode::UPDATE => UpdateHandler::handle(&message, raw).await,
},
Err(e) => Err(DNSError {
Err(e) => Err(ZNSError::Formerr {
message: e.to_string(),
rcode: RCODE::FORMERR,
}),
}
}

View file

@ -1,15 +1,11 @@
use crate::{
db::models::get_from_database,
errors::DNSError,
structs::{Message, RCODE},
};
use crate::{db::models::get_from_database, errors::ZNSError, structs::Message};
use super::ResponseHandler;
pub struct QueryHandler {}
impl ResponseHandler for QueryHandler {
async fn handle(message: &Message, _raw: &[u8]) -> Result<Message, DNSError> {
async fn handle(message: &Message, _raw: &[u8]) -> Result<Message, ZNSError> {
let mut response = message.clone();
response.header.arcount = 0; //TODO: fix this, handle unknown class values
@ -23,12 +19,16 @@ impl ResponseHandler for QueryHandler {
match answers {
Ok(rrs) => {
if rrs.len() == 0 {
return Err(ZNSError::NXDomain {
domain: question.qname.join("."),
});
}
response.header.ancount = rrs.len() as u16;
response.answer.extend(rrs)
}
Err(e) => {
return Err(DNSError {
rcode: RCODE::NXDOMAIN,
return Err(ZNSError::Database {
message: e.to_string(),
})
}

View file

@ -1,15 +1,15 @@
use crate::{
config::Config,
db::models::get_from_database,
errors::{AuthenticationError, DatabaseError},
errors::ZNSError,
parser::FromBytes,
reader::Reader,
structs::{Class, RRClass, RRType, Type},
};
use super::{dnskey::DNSKeyRData, pubkeys::PublicKeyError, sig::Sig};
use super::{dnskey::DNSKeyRData, sig::Sig};
pub async fn authenticate(sig: &Sig, zone: &Vec<String>) -> Result<bool, AuthenticationError> {
pub async fn authenticate(sig: &Sig, zone: &Vec<String>) -> Result<bool, ZNSError> {
if zone.len() >= 4 {
let username = &zone[zone.len() - 4]; // Should match: username.users.zeus.gent
@ -21,7 +21,7 @@ pub async fn authenticate(sig: &Sig, zone: &Vec<String>) -> Result<bool, Authent
Ok(validate_dnskey(zone, sig).await?)
}
} else {
Err(AuthenticationError {
Err(ZNSError::NotAuth {
message: String::from("Invalid zone"),
})
}
@ -40,7 +40,7 @@ async fn validate_ssh(username: &String, sig: &Sig) -> Result<bool, reqwest::Err
.any(|key| sig.verify_ssh(&key).is_ok_and(|b| b)))
}
async fn validate_dnskey(zone: &Vec<String>, sig: &Sig) -> Result<bool, DatabaseError> {
async fn validate_dnskey(zone: &Vec<String>, sig: &Sig) -> Result<bool, ZNSError> {
Ok(
get_from_database(zone, Type::Type(RRType::DNSKEY), Class::Class(RRClass::IN))
.await?
@ -52,11 +52,3 @@ async fn validate_dnskey(zone: &Vec<String>, sig: &Sig) -> Result<bool, Database
}),
)
}
impl From<PublicKeyError> for AuthenticationError {
fn from(value: PublicKeyError) -> Self {
AuthenticationError {
message: value.to_string(),
}
}
}

View file

@ -1,4 +1,4 @@
use crate::{errors::ParseError, parser::FromBytes, reader::Reader};
use crate::{errors::ZNSError, parser::FromBytes, reader::Reader};
use super::sig::Algorithm;
@ -13,7 +13,7 @@ pub struct DNSKeyRData {
//TODO: validate values
impl FromBytes for DNSKeyRData {
fn from_bytes(reader: &mut Reader) -> Result<Self, ParseError> {
fn from_bytes(reader: &mut Reader) -> Result<Self, ZNSError> {
Ok(DNSKeyRData {
flags: reader.read_u16()?,
protocol: reader.read_u8()?,

View file

@ -1,7 +1,7 @@
use crate::{
db::models::{delete_from_database, insert_into_database},
errors::DNSError,
structs::{Class, Message, RRClass, RRType, Type, RCODE},
errors::ZNSError,
structs::{Class, Message, RRClass, RRType, Type},
utils::vec_equal,
};
@ -17,15 +17,14 @@ mod sig;
pub struct UpdateHandler {}
impl ResponseHandler for UpdateHandler {
async fn handle(message: &Message, raw: &[u8]) -> Result<Message, crate::errors::DNSError> {
async fn handle(message: &Message, raw: &[u8]) -> Result<Message, ZNSError> {
let response = message.clone();
// Zone section (question) processing
if (message.header.qdcount != 1)
|| !matches!(message.question[0].qtype, Type::Type(RRType::SOA))
{
return Err(DNSError {
return Err(ZNSError::Formerr {
message: "Qdcount not one".to_string(),
rcode: RCODE::FORMERR,
});
}
@ -33,9 +32,8 @@ impl ResponseHandler for UpdateHandler {
let zone = &message.question[0];
let zlen = zone.qname.len();
if !(zlen >= 2 && zone.qname[zlen - 1] == "gent" && zone.qname[zlen - 2] == "zeus") {
return Err(DNSError {
return Err(ZNSError::Formerr {
message: "Invalid zone".to_string(),
rcode: RCODE::NOTAUTH,
});
}
@ -50,15 +48,13 @@ impl ResponseHandler for UpdateHandler {
.await
.is_ok_and(|x| x)
{
return Err(DNSError {
return Err(ZNSError::NotAuth {
message: "Unable to verify authentication".to_string(),
rcode: RCODE::NOTAUTH,
});
}
} else {
return Err(DNSError {
return Err(ZNSError::NotAuth {
message: "No KEY record at the end of request found".to_string(),
rcode: RCODE::NOTAUTH,
});
}
@ -68,9 +64,8 @@ impl ResponseHandler for UpdateHandler {
// Check if rr has same zone
if rlen < zlen || !(vec_equal(&zone.qname, &rr.name[rlen - zlen..])) {
return Err(DNSError {
return Err(ZNSError::Refused {
message: "RR has different zone from Question".to_string(),
rcode: RCODE::NOTZONE,
});
}
@ -84,9 +79,8 @@ impl ResponseHandler for UpdateHandler {
.contains(&rr.class)
{
true => {
return Err(DNSError {
return Err(ZNSError::Formerr {
message: "RR has invalid rr,ttl or class".to_string(),
rcode: RCODE::FORMERR,
});
}
false => (),
@ -99,9 +93,9 @@ impl ResponseHandler for UpdateHandler {
} else if rr.class == Class::Class(RRClass::ANY) {
if rr._type == Type::Type(RRType::ANY) {
if rr.name == zone.qname {
return Err(DNSError {
message: "Not yet implemented".to_string(),
rcode: RCODE::NOTIMP,
return Err(ZNSError::NotImp {
object: String::from("Update Handler"),
message: "rr.name == zone.qname".to_string(),
});
} else {
delete_from_database(&rr.name, None, Class::Class(RRClass::IN), None).await;

View file

@ -1,15 +1,15 @@
use ring::signature;
use crate::{handlers::update::sig::Algorithm, reader::Reader};
use crate::{errors::ZNSError, handlers::update::sig::Algorithm, reader::Reader};
use super::{PublicKey, PublicKeyError, SSH_ED25519};
use super::{PublicKey, SSH_ED25519};
pub struct Ed25519PublicKey {
data: Vec<u8>,
}
impl PublicKey for Ed25519PublicKey {
fn from_openssh(key: &[u8]) -> Result<Self, PublicKeyError>
fn from_openssh(key: &[u8]) -> Result<Self, ZNSError>
where
Self: Sized,
{
@ -21,7 +21,7 @@ impl PublicKey for Ed25519PublicKey {
})
}
fn from_dnskey(key: &[u8]) -> Result<Self, PublicKeyError>
fn from_dnskey(key: &[u8]) -> Result<Self, ZNSError>
where
Self: Sized,
{
@ -33,7 +33,7 @@ impl PublicKey for Ed25519PublicKey {
data: &[u8],
signature: &[u8],
_algorithm: &Algorithm,
) -> Result<bool, PublicKeyError> {
) -> Result<bool, ZNSError> {
let pkey = ring::signature::UnparsedPublicKey::new(&signature::ED25519, &self.data);
Ok(pkey.verify(data, signature).is_ok())

View file

@ -1,42 +1,23 @@
mod ed25519;
mod rsa;
use core::fmt;
use std::str::from_utf8;
use crate::{errors::ReaderError, reader::Reader};
use crate::errors::ZNSError;
use crate::reader::Reader;
pub use self::ed25519::Ed25519PublicKey;
pub use self::rsa::RsaPublicKey;
use super::sig::Algorithm;
#[derive(Debug)]
pub struct PublicKeyError {
pub message: String,
}
impl fmt::Display for PublicKeyError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Public Key Error: {}", self.message)
}
}
impl From<ReaderError> for PublicKeyError {
fn from(value: ReaderError) -> Self {
PublicKeyError {
message: value.to_string(),
}
}
}
pub const SSH_ED25519: &str = "ssh-ed25519";
pub const SSH_RSA: &str = "ssh-rsa";
pub trait PublicKey {
fn verify_ssh_type(reader: &mut Reader, key_type: &str) -> Result<(), PublicKeyError> {
fn verify_ssh_type(reader: &mut Reader, key_type: &str) -> Result<(), ZNSError> {
let type_size = reader.read_i32()?;
let read = reader.read(type_size as usize)?;
let algo_type = from_utf8(&read).map_err(|e| PublicKeyError {
let algo_type = from_utf8(&read).map_err(|e| ZNSError::PublicKey {
message: format!(
"Could not convert type name bytes to string: {}",
e.to_string()
@ -46,17 +27,17 @@ pub trait PublicKey {
if algo_type == key_type {
Ok(())
} else {
Err(PublicKeyError {
Err(ZNSError::PublicKey {
message: String::from("ssh key type does not match identifier"),
})
}
}
fn from_openssh(key: &[u8]) -> Result<Self, PublicKeyError>
fn from_openssh(key: &[u8]) -> Result<Self, ZNSError>
where
Self: Sized;
fn from_dnskey(key: &[u8]) -> Result<Self, PublicKeyError>
fn from_dnskey(key: &[u8]) -> Result<Self, ZNSError>
where
Self: Sized;
@ -65,5 +46,5 @@ pub trait PublicKey {
data: &[u8],
signature: &[u8],
algorithm: &Algorithm,
) -> Result<bool, PublicKeyError>;
) -> Result<bool, ZNSError>;
}

View file

@ -1,8 +1,8 @@
use ring::signature;
use crate::{handlers::update::sig::Algorithm, reader::Reader};
use crate::{errors::ZNSError, handlers::update::sig::Algorithm, reader::Reader};
use super::{PublicKey, PublicKeyError, SSH_RSA};
use super::{PublicKey, SSH_RSA};
pub struct RsaPublicKey {
e: Vec<u8>,
@ -16,7 +16,7 @@ struct RsaAsn1<'a> {
}
impl PublicKey for RsaPublicKey {
fn from_openssh(key: &[u8]) -> Result<Self, PublicKeyError>
fn from_openssh(key: &[u8]) -> Result<Self, ZNSError>
where
Self: Sized,
{
@ -34,19 +34,19 @@ impl PublicKey for RsaPublicKey {
data: &[u8],
signature: &[u8],
algorithm: &Algorithm,
) -> Result<bool, PublicKeyError> {
) -> Result<bool, ZNSError> {
let result = asn1::write_single(&RsaAsn1 {
n: asn1::BigInt::new(&self.n),
e: asn1::BigInt::new(&self.e),
})
.map_err(|e| PublicKeyError {
.map_err(|e| ZNSError::PublicKey {
message: format!("Verify Error: {}", e),
})?;
let signature_type = match algorithm {
Algorithm::RSASHA512 => Ok(&signature::RSA_PKCS1_2048_8192_SHA512),
Algorithm::RSASHA256 => Ok(&signature::RSA_PKCS1_2048_8192_SHA256),
_ => Err(PublicKeyError {
_ => Err(ZNSError::PublicKey {
message: format!("RsaPublicKey: invalid verify algorithm",),
}),
}?;
@ -56,7 +56,7 @@ impl PublicKey for RsaPublicKey {
Ok(pkey.verify(data, signature).is_ok())
}
fn from_dnskey(key: &[u8]) -> Result<Self, PublicKeyError>
fn from_dnskey(key: &[u8]) -> Result<Self, ZNSError>
where
Self: Sized,
{

View file

@ -2,7 +2,7 @@ use base64::prelude::*;
use int_enum::IntEnum;
use crate::{
errors::ParseError,
errors::ZNSError,
parser::FromBytes,
reader::Reader,
structs::{LabelString, RR},
@ -10,7 +10,7 @@ use crate::{
use super::{
dnskey::DNSKeyRData,
pubkeys::{Ed25519PublicKey, PublicKey, PublicKeyError, RsaPublicKey, SSH_ED25519, SSH_RSA},
pubkeys::{Ed25519PublicKey, PublicKey, RsaPublicKey, SSH_ED25519, SSH_RSA},
};
pub struct Sig {
@ -41,9 +41,8 @@ pub enum Algorithm {
}
impl Algorithm {
pub fn from(value: u8) -> Result<Self, ParseError> {
Algorithm::try_from(value).map_err(|a| ParseError {
// TODO: Should respond with error code refused or notimpl
pub fn from(value: u8) -> Result<Self, ZNSError> {
Algorithm::try_from(value).map_err(|a| ZNSError::NotImp {
object: String::from("Algorithm"),
message: format!("Usupported algorithm: {}", a),
})
@ -51,9 +50,9 @@ impl Algorithm {
}
impl FromBytes for SigRData {
fn from_bytes(reader: &mut Reader) -> Result<Self, ParseError> {
fn from_bytes(reader: &mut Reader) -> Result<Self, ZNSError> {
if reader.unread_bytes() < 18 {
Err(ParseError {
Err(ZNSError::Parse {
object: String::from("KeyRData"),
message: String::from("invalid rdata"),
})
@ -74,7 +73,7 @@ impl FromBytes for SigRData {
}
impl Sig {
pub fn new(rr: &RR, datagram: &[u8]) -> Result<Self, ParseError> {
pub fn new(rr: &RR, datagram: &[u8]) -> Result<Self, ZNSError> {
let mut request = datagram[0..datagram.len() - 11 - rr.rdlength as usize].to_vec();
request[11] -= 1; // Decrease arcount
@ -90,7 +89,7 @@ impl Sig {
})
}
fn verify(&self, key: impl PublicKey) -> Result<bool, PublicKeyError> {
fn verify(&self, key: impl PublicKey) -> Result<bool, ZNSError> {
key.verify(
&self.raw_data,
&self.key_rdata.signature,
@ -98,7 +97,7 @@ impl Sig {
)
}
pub fn verify_ssh(&self, key: &str) -> Result<bool, PublicKeyError> {
pub fn verify_ssh(&self, key: &str) -> Result<bool, ZNSError> {
let key_split: Vec<&str> = key.split_ascii_whitespace().collect();
let bin = BASE64_STANDARD.decode(key_split[1]).unwrap();
@ -111,7 +110,7 @@ impl Sig {
}
}
pub fn verify_dnskey(&self, key: DNSKeyRData) -> Result<bool, PublicKeyError> {
pub fn verify_dnskey(&self, key: DNSKeyRData) -> Result<bool, ZNSError> {
if self.key_rdata.algo != key.algorithm {
Ok(false)
} else {

View file

@ -1,12 +1,12 @@
use std::{mem::size_of, vec};
use std::mem::size_of;
use crate::{
errors::ParseError,
errors::ZNSError,
reader::Reader,
structs::{Class, Header, LabelString, Message, Opcode, Question, RRClass, RRType, Type, RR},
};
type Result<T> = std::result::Result<T, ParseError>;
type Result<T> = std::result::Result<T, ZNSError>;
impl From<Type> for u16 {
fn from(value: Type) -> Self {
@ -83,7 +83,7 @@ pub trait ToBytes {
impl FromBytes for Header {
fn from_bytes(reader: &mut Reader) -> Result<Self> {
if reader.unread_bytes() < size_of::<Header>() {
Err(ParseError {
Err(ZNSError::Parse {
object: String::from("Header"),
message: String::from("Size of Header does not match"),
})
@ -124,7 +124,7 @@ impl FromBytes for LabelString {
while code != 0 && (code & 0b11000000 == 0) && reader.unread_bytes() > code as usize {
out.push(
String::from_utf8(reader.read(code as usize)?.to_vec()).map_err(|e| {
ParseError {
ZNSError::Parse {
object: String::from("Label"),
message: e.to_string(),
}
@ -159,7 +159,7 @@ impl FromBytes for Question {
fn from_bytes(reader: &mut Reader) -> Result<Self> {
// 16 for length octet + zero length octet
if reader.unread_bytes() < 2 + size_of::<Class>() + size_of::<Type>() {
Err(ParseError {
Err(ZNSError::Parse {
object: String::from("Question"),
message: String::from("len of bytes smaller then minimum size"),
})
@ -167,7 +167,7 @@ impl FromBytes for Question {
let qname = LabelString::from_bytes(reader)?;
if reader.unread_bytes() < 4 {
Err(ParseError {
Err(ZNSError::Parse {
object: String::from("Question"),
message: String::from("len of rest bytes smaller then minimum size"),
})
@ -201,7 +201,7 @@ impl FromBytes for RR {
fn from_bytes(reader: &mut Reader) -> Result<Self> {
let name = LabelString::from_bytes(reader)?;
if reader.unread_bytes() < size_of::<Type>() + size_of::<Class>() + 6 {
Err(ParseError {
Err(ZNSError::Parse {
object: String::from("RR"),
message: String::from("len of rest of bytes smaller then minimum size"),
})
@ -211,7 +211,7 @@ impl FromBytes for RR {
let ttl = reader.read_i32()?;
let rdlength = reader.read_u16()?;
if reader.unread_bytes() < rdlength as usize {
Err(ParseError {
Err(ZNSError::Parse {
object: String::from("RR"),
message: String::from("len of rest of bytes not equal to rdlength"),
})

View file

@ -1,13 +1,13 @@
use std::array::TryFromSliceError;
use crate::errors::ReaderError;
use crate::errors::ZNSError;
pub struct Reader<'a> {
buffer: &'a [u8],
position: usize,
}
type Result<T> = std::result::Result<T, ReaderError>;
type Result<T> = std::result::Result<T, ZNSError>;
impl<'a> Reader<'a> {
pub fn new(buffer: &[u8]) -> Reader {
@ -23,7 +23,7 @@ impl<'a> Reader<'a> {
pub fn read(&mut self, size: usize) -> Result<Vec<u8>> {
if size > self.unread_bytes() {
Err(ReaderError {
Err(ZNSError::Reader {
message: String::from("cannot read enough bytes"),
})
} else {
@ -41,7 +41,7 @@ impl<'a> Reader<'a> {
let result = u16::from_be_bytes(
self.buffer[self.position..self.position + 2]
.try_into()
.map_err(|e: TryFromSliceError| ReaderError {
.map_err(|e: TryFromSliceError| ZNSError::Reader {
message: e.to_string(),
})?,
);
@ -53,7 +53,7 @@ impl<'a> Reader<'a> {
let result = i32::from_be_bytes(
self.buffer[self.position..self.position + 4]
.try_into()
.map_err(|e: TryFromSliceError| ReaderError {
.map_err(|e: TryFromSliceError| ZNSError::Reader {
message: e.to_string(),
})?,
);
@ -65,7 +65,7 @@ impl<'a> Reader<'a> {
let result = u32::from_be_bytes(
self.buffer[self.position..self.position + 4]
.try_into()
.map_err(|e: TryFromSliceError| ReaderError {
.map_err(|e: TryFromSliceError| ZNSError::Reader {
message: e.to_string(),
})?,
);
@ -75,7 +75,7 @@ impl<'a> Reader<'a> {
pub fn seek(&self, position: usize) -> Result<Self> {
if position >= self.position {
Err(ReaderError {
Err(ZNSError::Reader {
message: String::from("Seeking into the future is not allowed!!"),
})
} else {

View file

@ -4,7 +4,7 @@ use std::sync::Arc;
use tokio::net::UdpSocket;
use crate::errors::ParseError;
use crate::errors::ZNSError;
use crate::handlers::{Handler, ResponseHandler};
use crate::parser::{FromBytes, ToBytes};
use crate::reader::Reader;
@ -12,7 +12,7 @@ use crate::structs::{Header, Message, RCODE};
const MAX_DATAGRAM_SIZE: usize = 4096;
fn handle_parse_error(bytes: &[u8], err: ParseError) -> Message {
fn handle_parse_error(bytes: &[u8], err: ZNSError) -> Message {
eprintln!("{}", err);
let mut reader = Reader::new(bytes);
let mut header = Header::from_bytes(&mut reader).unwrap_or(Header {
@ -50,7 +50,7 @@ async fn get_response(bytes: &[u8]) -> Message {
}
Err(e) => {
eprintln!("{}", e.to_string());
message.set_response(e.rcode);
message.set_response(e.rcode());
message
}
},