10
0
Fork 0
mirror of https://github.com/ZeusWPI/ZNS.git synced 2024-10-30 05:24:26 +01:00

Working but not correct answering of A

This commit is contained in:
Xander Bil 2024-02-26 23:29:39 +01:00
parent a0fb2fad7b
commit aa64201d30
No known key found for this signature in database
GPG key ID: EC9706B54A278598
7 changed files with 132 additions and 30 deletions

2
.gitignore vendored
View file

@ -1 +1,3 @@
/target /target
.env
*.sqlite

View file

@ -8,4 +8,3 @@ edition = "2021"
diesel = { version = "2.1.4", features = ["sqlite"] } diesel = { version = "2.1.4", features = ["sqlite"] }
dotenvy = "0.15" dotenvy = "0.15"
tokio = {version = "1.36.0", features = ["full"]} tokio = {version = "1.36.0", features = ["full"]}

9
diesel.toml Normal file
View file

@ -0,0 +1,9 @@
# For documentation on how to configure this file,
# see https://diesel.rs/guides/configuring-diesel-cli
[print_schema]
file = "src/schema.rs"
custom_type_derives = ["diesel::query_builder::QueryId"]
[migrations_directory]
dir = "migrations"

0
migrations/.keep Normal file
View file

View file

@ -4,6 +4,8 @@ use parser::FromBytes;
use structs::Message; use structs::Message;
use tokio::net::UdpSocket; use tokio::net::UdpSocket;
use crate::structs::{Class, Type, RR};
mod errors; mod errors;
mod parser; mod parser;
mod structs; mod structs;
@ -11,8 +13,24 @@ mod worker;
const MAX_DATAGRAM_SIZE: usize = 40_96; const MAX_DATAGRAM_SIZE: usize = 40_96;
async fn create_query(message: Message) { async fn create_query(message: Message) -> Message {
println!("{:?}", message); let mut response = message.clone();
let ip = String::from("93.184.216.34");
let rr = RR {
name: vec![String::from("example"),String::from("org")],
_type: Type::A,
class: Class::IN,
ttl: 4096,
rdlength: ip.len() as u16,
rdata: ip,
};
response.header.flags |= 0b1000010110000000;
response.header.ancount = 1;
response.header.arcount = 0;
response.answer = Some(rr);
response
} }
#[tokio::main] #[tokio::main]
@ -22,13 +40,19 @@ async fn main() -> Result<(), Box<dyn Error>> {
let socket = UdpSocket::bind(local_addr).await?; let socket = UdpSocket::bind(local_addr).await?;
let mut data = vec![0u8; MAX_DATAGRAM_SIZE]; let mut data = vec![0u8; MAX_DATAGRAM_SIZE];
loop { let (len,addr) = socket.recv_from(&mut data).await?;
let len = socket.recv(&mut data).await?;
match Message::from_bytes(&data[..len]) { match Message::from_bytes(&data[..len]) {
Ok(message) => { Ok(message) => {
tokio::spawn(async move { create_query(message).await }); tokio::spawn(async move {
let response = create_query(message).await;
println!("{:?}",response);
let vec = Message::to_bytes(&response);
let decoded = Message::from_bytes(vec.as_slice());
println!("{:?}",decoded);
let _ = socket.send_to(vec.as_slice(),addr).await;
});
} }
Err(err) => println!("{}", err), Err(err) => println!("{}", err),
}; };
} loop {}
} }

View file

@ -1,8 +1,8 @@
use std::mem::size_of; use std::{mem::size_of, vec};
use crate::{ use crate::{
errors::ParseError, errors::ParseError,
structs::{Class, Header, Message, Question, Type}, structs::{Class, Header, Message, Question, Type, RR},
}; };
type Result<T> = std::result::Result<T, ParseError>; type Result<T> = std::result::Result<T, ParseError>;
@ -29,11 +29,13 @@ impl TryFrom<u16> for Class {
} }
} }
// TODO: use Error instead of Option
pub trait FromBytes { pub trait FromBytes {
fn from_bytes(bytes: &[u8]) -> Result<Self> fn from_bytes(bytes: &[u8]) -> Result<Self>
where where
Self: Sized; Self: Sized;
fn to_bytes(s: &Self) -> Vec<u8>
where
Self: Sized;
} }
impl FromBytes for Header { impl FromBytes for Header {
@ -54,9 +56,21 @@ impl FromBytes for Header {
}) })
} }
} }
fn to_bytes(header: &Self) -> Vec<u8> {
let mut result: [u8; size_of::<Header>()] = [0; size_of::<Header>()];
result[0..2].copy_from_slice(&u16::to_be_bytes(header.id));
result[2..4].copy_from_slice(&u16::to_be_bytes(header.flags));
result[4..6].copy_from_slice(&u16::to_be_bytes(header.qdcount));
result[6..8].copy_from_slice(&u16::to_be_bytes(header.ancount));
result[8..10].copy_from_slice(&u16::to_be_bytes(header.nscount));
result[10..12].copy_from_slice(&u16::to_be_bytes(header.arcount));
result.to_vec()
}
} }
//HACK: lots of unsafe unwrap
impl FromBytes for Question { impl FromBytes for Question {
fn from_bytes(bytes: &[u8]) -> Result<Self> { fn from_bytes(bytes: &[u8]) -> Result<Self> {
// 16 for length octet + zero length octet // 16 for length octet + zero length octet
@ -107,6 +121,45 @@ impl FromBytes for Question {
} }
} }
} }
fn to_bytes(question: &Self) -> Vec<u8> {
let mut result: Vec<u8> = vec![];
for label in &question.qname {
result.push(label.len() as u8);
result.extend(label.as_bytes());
}
result.push(0);
result.extend(u16::to_be_bytes(question.qtype.to_owned() as u16));
result.extend(u16::to_be_bytes(question.qclass.to_owned() as u16));
result
}
}
impl FromBytes for RR {
fn from_bytes(bytes: &[u8]) -> Result<Self>
where
Self: Sized,
{
todo!()
}
fn to_bytes(rr: &Self) -> Vec<u8> {
let mut result = vec![];
for label in &rr.name {
result.push(label.len() as u8);
result.extend(label.as_bytes());
}
result.push(0);
result.extend(u16::to_be_bytes(rr._type.to_owned() as u16));
result.extend(u16::to_be_bytes(rr.class.to_owned() as u16));
result.extend(i32::to_be_bytes(rr.ttl.to_owned()));
result.extend(u16::to_be_bytes(4 as u16));
result.push(93);
result.push(184);
result.push(216);
result.push(34);
result
}
} }
impl FromBytes for Message { impl FromBytes for Message {
@ -121,4 +174,20 @@ impl FromBytes for Message {
additional: None, additional: None,
}) })
} }
fn to_bytes(message: &Self) -> Vec<u8> {
let mut result = vec![];
result.extend(Header::to_bytes(&message.header));
result.extend(Question::to_bytes(&message.question));
if message.answer.is_some() {
result.extend(RR::to_bytes(&message.answer.clone().unwrap()));
}
if message.authority.is_some() {
result.extend(RR::to_bytes(&message.authority.clone().unwrap()));
}
if message.additional.is_some() {
result.extend(RR::to_bytes(&message.additional.clone().unwrap()));
}
result
}
} }

View file

@ -1,24 +1,23 @@
#[repr(u16)] #[repr(u16)]
#[derive(Debug)] #[derive(Debug, Clone)]
pub enum Type { pub enum Type {
A = 1, A = 1,
} }
#[repr(u16)] #[repr(u16)]
#[derive(Debug)] #[derive(Debug, Clone)]
pub enum Class { pub enum Class {
IN = 1, IN = 1,
} }
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct Question { pub struct Question {
pub qname: Vec<String>, // TODO: not padded pub qname: Vec<String>, // TODO: not padded
pub qtype: Type, // NOTE: should be QTYPE, right now not really needed pub qtype: Type, // NOTE: should be QTYPE, right now not really needed
pub qclass: Class, pub qclass: Class, //NOTE: should be QCLASS, right now not really needed
} }
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct Header { pub struct Header {
pub id: u16, pub id: u16,
pub flags: u16, // |QR| Opcode |AA|TC|RD|RA| Z | RCODE | ; 1 | 4 | 1 | 1 | 1 | 1 | 3 | 4 pub flags: u16, // |QR| Opcode |AA|TC|RD|RA| Z | RCODE | ; 1 | 4 | 1 | 1 | 1 | 1 | 3 | 4
@ -28,7 +27,7 @@ pub struct Header {
pub arcount: u16, pub arcount: u16,
} }
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct Message { pub struct Message {
pub header: Header, pub header: Header,
pub question: Question, pub question: Question,
@ -37,14 +36,14 @@ pub struct Message {
pub additional: Option<RR>, pub additional: Option<RR>,
} }
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct RR { pub struct RR {
name: String, pub name: Vec<String>,
t: u16, pub _type: Type,
class: u16, pub class: Class,
ttl: u32, pub ttl: i32,
rdlength: u16, pub rdlength: u16,
rdata: String, pub rdata: String,
} }
#[derive(Debug)] #[derive(Debug)]