Skip to content

Commit

Permalink
bidirectional header passing, adding question struct
Browse files Browse the repository at this point in the history
  • Loading branch information
Sarsoo committed Jan 29, 2024
1 parent 4051665 commit 985adba
Show file tree
Hide file tree
Showing 10 changed files with 403 additions and 23 deletions.
7 changes: 6 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,9 @@ jobs:
- name: Cargo Build
uses: actions-rs/cargo@v1
with:
command: build
command: build

- name: Cargo Test
uses: actions-rs/cargo@v1
with:
command: test
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/target
**/*.log
**/*.log
.idea
67 changes: 67 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 6 additions & 5 deletions dnstp-client/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
use std::fs::File;
use std::net::{SocketAddr, UdpSocket};
use std::net::SocketAddr;
use std::thread;
use std::time::Duration;
use clap::Parser;
use log::{error, info, LevelFilter};
use log::{info, LevelFilter};
use simplelog::*;
use dnstplib::dns_socket::DNSSocket;
use dnstplib::raw_request::NetworkMessage;
use dnstplib::request_processor::RequestProcesor;
use dnstplib::response_processor::ResponseProcesor;

#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {

/// Addresses to send requests
#[arg(short, long)]
address: String,
}

fn main() {
Expand Down Expand Up @@ -51,7 +52,7 @@ fn main() {

tx_channel.send(Box::from(NetworkMessage {
buffer: Box::from(send_buf),
peer: "127.0.0.1:5000".parse().unwrap()
peer: args.address.parse().unwrap()
}));

thread::sleep(Duration::from_secs(1));
Expand Down
3 changes: 2 additions & 1 deletion dnstp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
log = "0.4.20"
log = "0.4.20"
url = "2.5.0"
58 changes: 54 additions & 4 deletions dnstp/src/dns_header.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,72 @@
use std::convert::TryFrom;

pub const HEADER_SIZE: usize = 12;

#[derive(Ord, PartialOrd, Eq, PartialEq, Debug, Copy, Clone)]
pub enum Direction {
Request, Response
Request = 0,
Response = 1
}

#[derive(Ord, PartialOrd, Eq, PartialEq, Debug, Copy, Clone)]
pub enum Opcode {
Query = 0,
RQuery = 1,
Status = 2,
Reserved = 3
}

impl TryFrom<u16> for Opcode {
type Error = ();

fn try_from(v: u16) -> Result<Self, Self::Error> {
match v {
x if x == Opcode::Query as u16 => Ok(Opcode::Query),
x if x == Opcode::RQuery as u16 => Ok(Opcode::RQuery),
x if x == Opcode::Status as u16 => Ok(Opcode::Status),
x if x == Opcode::Reserved as u16 => Ok(Opcode::Reserved),
_ => Err(()),
}
}
}

#[derive(Ord, PartialOrd, Eq, PartialEq, Debug, Copy, Clone)]
pub enum ResponseCode {
NoError = 0,
FormatSpecError = 1,
FormatError = 1,
ServerFailure = 2,
NameError = 3,
RequestTypeUnsupported = 4,
NotExecuted = 5
NotImplemented = 4,
Refused = 5,
YXDomain = 6,
YXRRSet = 7,
NXRRSet = 8,
NotAuth = 9,
NotZone = 10
}

impl TryFrom<u16> for ResponseCode {
type Error = ();

fn try_from(v: u16) -> Result<Self, Self::Error> {
match v {
x if x == ResponseCode::NoError as u16 => Ok(ResponseCode::NoError),
x if x == ResponseCode::FormatError as u16 => Ok(ResponseCode::FormatError),
x if x == ResponseCode::ServerFailure as u16 => Ok(ResponseCode::ServerFailure),
x if x == ResponseCode::NameError as u16 => Ok(ResponseCode::NameError),
x if x == ResponseCode::NotImplemented as u16 => Ok(ResponseCode::NotImplemented),
x if x == ResponseCode::Refused as u16 => Ok(ResponseCode::Refused),
x if x == ResponseCode::YXDomain as u16 => Ok(ResponseCode::YXDomain),
x if x == ResponseCode::YXRRSet as u16 => Ok(ResponseCode::YXRRSet),
x if x == ResponseCode::NXRRSet as u16 => Ok(ResponseCode::NXRRSet),
x if x == ResponseCode::NotAuth as u16 => Ok(ResponseCode::NotAuth),
x if x == ResponseCode::NotZone as u16 => Ok(ResponseCode::NotZone),
_ => Err(()),
}
}
}

#[derive(Ord, PartialOrd, Eq, PartialEq, Debug)]
pub struct DNSHeader {
pub id: u16,
pub direction: Direction,
Expand All @@ -26,6 +75,7 @@ pub struct DNSHeader {
pub truncation: bool,
pub recursion_desired: bool,
pub recursion_available: bool,
pub valid_zeroes: bool,
pub response: ResponseCode,
pub question_count: u16,
pub answer_record_count: u16,
Expand Down
66 changes: 66 additions & 0 deletions dnstp/src/dns_question.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
use url::form_urlencoded;

#[derive(Ord, PartialOrd, Eq, PartialEq, Debug, Copy, Clone)]
enum QType {
A = 1,

Check warning on line 5 in dnstp/src/dns_question.rs

View workflow job for this annotation

GitHub Actions / build

multiple variants are never constructed

Check warning on line 5 in dnstp/src/dns_question.rs

View workflow job for this annotation

GitHub Actions / build

multiple variants are never constructed
NS = 2,
CNAME = 5,
SOA = 6,
WKS = 11,
PTR = 12,
HINFO = 13,
MINFO = 14,
MX = 15,
TXT = 16,
RP = 17,
AAAA = 28,
SRV = 33
}

#[derive(Ord, PartialOrd, Eq, PartialEq, Debug, Copy, Clone)]
enum QClass {
Internet = 1,

Check warning on line 22 in dnstp/src/dns_question.rs

View workflow job for this annotation

GitHub Actions / build

variants `Internet`, `Chaos`, and `Hesiod` are never constructed

Check warning on line 22 in dnstp/src/dns_question.rs

View workflow job for this annotation

GitHub Actions / build

variants `Internet`, `Chaos`, and `Hesiod` are never constructed
Chaos = 3,
Hesiod = 4,
}

struct DNSQuestion {

Check warning on line 27 in dnstp/src/dns_question.rs

View workflow job for this annotation

GitHub Actions / build

struct `DNSQuestion` is never constructed

Check warning on line 27 in dnstp/src/dns_question.rs

View workflow job for this annotation

GitHub Actions / build

struct `DNSQuestion` is never constructed
qname: String,
qtype: QType,
qclass: QClass
}

impl DNSQuestion {
pub fn new(qname: String, qtype: QType, qclass: QClass) -> DNSQuestion

Check warning on line 34 in dnstp/src/dns_question.rs

View workflow job for this annotation

GitHub Actions / build

associated items `new` and `to_bytes` are never used

Check warning on line 34 in dnstp/src/dns_question.rs

View workflow job for this annotation

GitHub Actions / build

associated items `new` and `to_bytes` are never used
{
DNSQuestion {
qname,
qtype,
qclass
}
}

pub fn to_bytes(&self) -> Vec<u8>
{
let mut ret: Vec<u8> = vec!();

for part in self.qname.split(".")
{
let encoded_string: String = form_urlencoded::byte_serialize(part.as_bytes()).collect();
let count = encoded_string.len();

ret.push(count as u8);
ret.reserve(count);
for x in encoded_string.into_bytes() {
ret.push(x);
};
}

ret.push(0);

ret.push(self.qtype as u8);
ret.push(self.qclass as u8);

ret
}
}
26 changes: 16 additions & 10 deletions dnstp/src/dns_socket.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
use std::net::{SocketAddr, UdpSocket};
use std::ptr::read;

Check warning on line 2 in dnstp/src/dns_socket.rs

View workflow job for this annotation

GitHub Actions / build

unused import: `std::ptr::read`

Check warning on line 2 in dnstp/src/dns_socket.rs

View workflow job for this annotation

GitHub Actions / build

unused import: `std::ptr::read`
use std::thread;
use std::thread::{JoinHandle};
use log::{error, info};
use log::{debug, error, info};

use std::str;
use std::sync::mpsc;
use std::sync::mpsc::{Receiver, Sender, TryRecvError};
use crate::dns_header::HEADER_SIZE;
use crate::raw_request::{NetworkMessage, NetworkMessagePtr};

pub struct DNSSocket {
Expand Down Expand Up @@ -80,16 +82,18 @@ impl DNSSocket {
let res = s.recv_from(&mut (*buf));

match res {
Ok((_, peer)) => {
Ok((read_count, peer)) => {
let res_str = str::from_utf8(&(*buf)).unwrap();
info!("received [{}] from [{}]", res_str, peer);
match message_sender.send(Box::new(NetworkMessage {
buffer: buf,
peer
}))
{
Ok(_) => {}
Err(_) => {}

if read_count > HEADER_SIZE {
message_sender.send(Box::new(NetworkMessage {

Check warning on line 90 in dnstp/src/dns_socket.rs

View workflow job for this annotation

GitHub Actions / build

unused `Result` that must be used

Check warning on line 90 in dnstp/src/dns_socket.rs

View workflow job for this annotation

GitHub Actions / build

unused `Result` that must be used
buffer: buf,
peer
}));
}
else {
debug!("skipping processing message from [{}], message isn't longer than standard header", peer);
}
}
Err(_) => {}
Expand Down Expand Up @@ -129,7 +133,9 @@ impl DNSSocket {

for m in &msg_rx {
info!("sending [{}] to [{}]", str::from_utf8(&(*(*m).buffer)).unwrap(), (*m).peer);
s.send_to(&(*m.buffer), m.peer);
if let Err(e) = s.send_to(&(*m.buffer), m.peer){
error!("error sending response to [{}], {}", m.peer, e);
}
}

cancelled = match rx.try_recv() {
Expand Down
3 changes: 2 additions & 1 deletion dnstp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ pub mod request_parser;
mod dns_header;
pub mod request_processor;
pub mod response_processor;
pub mod raw_request;
pub mod raw_request;
mod dns_question;
Loading

0 comments on commit 985adba

Please sign in to comment.