mirror of
https://github.com/ZeusWPI/ZNS.git
synced 2024-11-21 13:31:11 +01:00
Working but not correct answering of A
This commit is contained in:
parent
a0fb2fad7b
commit
aa64201d30
7 changed files with 132 additions and 30 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1 +1,3 @@
|
|||
/target
|
||||
.env
|
||||
*.sqlite
|
||||
|
|
|
@ -8,4 +8,3 @@ edition = "2021"
|
|||
diesel = { version = "2.1.4", features = ["sqlite"] }
|
||||
dotenvy = "0.15"
|
||||
tokio = {version = "1.36.0", features = ["full"]}
|
||||
|
||||
|
|
9
diesel.toml
Normal file
9
diesel.toml
Normal 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
0
migrations/.keep
Normal file
46
src/main.rs
46
src/main.rs
|
@ -4,6 +4,8 @@ use parser::FromBytes;
|
|||
use structs::Message;
|
||||
use tokio::net::UdpSocket;
|
||||
|
||||
use crate::structs::{Class, Type, RR};
|
||||
|
||||
mod errors;
|
||||
mod parser;
|
||||
mod structs;
|
||||
|
@ -11,8 +13,24 @@ mod worker;
|
|||
|
||||
const MAX_DATAGRAM_SIZE: usize = 40_96;
|
||||
|
||||
async fn create_query(message: Message) {
|
||||
println!("{:?}", message);
|
||||
async fn create_query(message: Message) -> 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]
|
||||
|
@ -22,13 +40,19 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
|||
let socket = UdpSocket::bind(local_addr).await?;
|
||||
|
||||
let mut data = vec![0u8; MAX_DATAGRAM_SIZE];
|
||||
loop {
|
||||
let len = socket.recv(&mut data).await?;
|
||||
match Message::from_bytes(&data[..len]) {
|
||||
Ok(message) => {
|
||||
tokio::spawn(async move { create_query(message).await });
|
||||
}
|
||||
Err(err) => println!("{}", err),
|
||||
};
|
||||
}
|
||||
let (len,addr) = socket.recv_from(&mut data).await?;
|
||||
match Message::from_bytes(&data[..len]) {
|
||||
Ok(message) => {
|
||||
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),
|
||||
};
|
||||
loop {}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use std::mem::size_of;
|
||||
use std::{mem::size_of, vec};
|
||||
|
||||
use crate::{
|
||||
errors::ParseError,
|
||||
structs::{Class, Header, Message, Question, Type},
|
||||
structs::{Class, Header, Message, Question, Type, RR},
|
||||
};
|
||||
|
||||
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 {
|
||||
fn from_bytes(bytes: &[u8]) -> Result<Self>
|
||||
where
|
||||
Self: Sized;
|
||||
fn to_bytes(s: &Self) -> Vec<u8>
|
||||
where
|
||||
Self: Sized;
|
||||
}
|
||||
|
||||
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 {
|
||||
fn from_bytes(bytes: &[u8]) -> Result<Self> {
|
||||
// 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 {
|
||||
|
@ -121,4 +174,20 @@ impl FromBytes for Message {
|
|||
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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,24 +1,23 @@
|
|||
|
||||
#[repr(u16)]
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Type {
|
||||
A = 1,
|
||||
}
|
||||
|
||||
#[repr(u16)]
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Class {
|
||||
IN = 1,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Question {
|
||||
pub qname: Vec<String>, // TODO: not padded
|
||||
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 id: u16,
|
||||
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,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Message {
|
||||
pub header: Header,
|
||||
pub question: Question,
|
||||
|
@ -37,14 +36,14 @@ pub struct Message {
|
|||
pub additional: Option<RR>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct RR {
|
||||
name: String,
|
||||
t: u16,
|
||||
class: u16,
|
||||
ttl: u32,
|
||||
rdlength: u16,
|
||||
rdata: String,
|
||||
pub name: Vec<String>,
|
||||
pub _type: Type,
|
||||
pub class: Class,
|
||||
pub ttl: i32,
|
||||
pub rdlength: u16,
|
||||
pub rdata: String,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
Loading…
Reference in a new issue