moving server socket to new thread, adding dns structs

This commit is contained in:
Andy Pack 2024-01-28 22:48:35 +00:00
parent 81907a3fa8
commit d3aefea3cd
Signed by: sarsoo
GPG Key ID: A55BA3536A5E0ED7
11 changed files with 160 additions and 21 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
/target /target
**/*.log

4
Cargo.lock generated
View File

@ -122,11 +122,15 @@ dependencies = [
"clap", "clap",
"dnstplib", "dnstplib",
"log", "log",
"simplelog",
] ]
[[package]] [[package]]
name = "dnstplib" name = "dnstplib"
version = "0.1.0" version = "0.1.0"
dependencies = [
"log",
]
[[package]] [[package]]
name = "heck" name = "heck"

View File

@ -9,3 +9,4 @@ edition = "2021"
dnstplib = { path = "../dnstp" } dnstplib = { path = "../dnstp" }
clap = { version = "4.4.18", features = ["derive"] } clap = { version = "4.4.18", features = ["derive"] }
log = "0.4.20" log = "0.4.20"
simplelog = "0.12.1"

View File

@ -1,6 +1,10 @@
use std::fs::File;
use std::net::{SocketAddr, UdpSocket}; use std::net::{SocketAddr, UdpSocket};
use std::thread;
use std::time::Duration;
use clap::Parser; use clap::Parser;
use log::error; use log::{error, info, LevelFilter};
use simplelog::*;
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)] #[command(author, version, about, long_about = None)]
@ -9,6 +13,13 @@ struct Args {
} }
fn main() { fn main() {
CombinedLogger::init(
vec![
TermLogger::new(LevelFilter::Info, Config::default(), TerminalMode::Mixed, ColorChoice::Auto),
WriteLogger::new(LevelFilter::Info, Config::default(), File::create("dnstp.log").unwrap()),
]
).unwrap();
let args = Args::parse(); let args = Args::parse();
let address = SocketAddr::from(([127, 0, 0, 1], 0)); let address = SocketAddr::from(([127, 0, 0, 1], 0));
@ -17,9 +28,12 @@ fn main() {
Ok(s) => { Ok(s) => {
loop { loop {
info!("sending...");
let send_buf = "hello world"; let send_buf = "hello world";
let send_res = s.send_to(send_buf.as_bytes(), "127.0.0.1:5000"); let send_res = s.send_to(send_buf.as_bytes(), "127.0.0.1:5000");
thread::sleep(Duration::from_secs(1));
} }
} }
Err(e) => error!("couldn't bind to address {}", e) Err(e) => error!("couldn't bind to address {}", e)

Binary file not shown.

View File

@ -1,11 +1,13 @@
use clap::Parser; use clap::Parser;
use std::str; use std::{thread};
use log::{error, info, warn}; use log::{error, info, warn};
use simplelog::*; use simplelog::*;
use std::fs::File; use std::fs::File;
use std::net::{SocketAddr, UdpSocket}; use std::net::{SocketAddr, UdpSocket};
use dnstplib::dns_socket::DNSSocket;
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)] #[command(author, version, about, long_about = None)]
struct Args { struct Args {
@ -37,22 +39,8 @@ fn main() {
.map(|x| x.parse().expect("Couldn't parse address")) .map(|x| x.parse().expect("Couldn't parse address"))
.collect(); .collect();
match UdpSocket::bind(&addresses[..]) { let mut socket = DNSSocket::new(addresses);
Ok(s) => { socket.run();
loop {
let mut buf = [0; 512];
let res = s.recv_from(&mut buf);
match res {
Ok(r) => {
let res_str = str::from_utf8(&buf).unwrap();
info!("{}", res_str);
}
Err(_) => {}
}
}
}
Err(e) => error!("couldn't bind to address {}", e)
}
thread::park();
} }

View File

@ -6,3 +6,4 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
log = "0.4.20"

35
dnstp/src/dns_header.rs Normal file
View File

@ -0,0 +1,35 @@
pub enum Direction {
Request, Response
}
pub enum Opcode {
Query = 0,
RQuery = 1,
Status = 2,
Reserved = 3
}
pub enum ResponseCode {
NoError = 0,
FormatSpecError = 1,
ServerFailure = 2,
NameError = 3,
RequestTypeUnsupported = 4,
NotExecuted = 5
}
pub struct DNSHeader {
pub id: u16,
pub direction: Direction,
pub opcode: Opcode,
pub authoritative: bool,
pub truncation: bool,
pub recursion_desired: bool,
pub recursion_available: bool,
pub response: ResponseCode,
pub question_count: u16,
pub answer_record_count: u16,
pub authority_record_count: u16,
pub additional_record_count: u16,
}

92
dnstp/src/dns_socket.rs Normal file
View File

@ -0,0 +1,92 @@
use std::net::{SocketAddr, UdpSocket};
use std::thread;
use std::thread::{JoinHandle};
use log::{error, info};
use std::str;
use std::sync::mpsc;
use std::sync::mpsc::{Receiver, Sender, TryRecvError};
pub struct DNSSocket {
addresses: Vec<SocketAddr>,
thread: Option<JoinHandle<()>>,
thread_killer: Option<Sender<()>>
}
impl DNSSocket {
pub fn new(addresses: Vec<SocketAddr>) -> DNSSocket
{
DNSSocket {
addresses,
thread: None,
thread_killer: None
}
}
// pub fn new<T, U: ToSocketAddrs>(addr: T) -> DNSSocket
// where
// T: Iterator<Item = U>,
// {
// DNSSocket {
// addresses: addr
// .map(|x| x.parse().expect("Couldn't parse address"))
// .collect()
// }
// }
fn bind(&mut self) -> Option<UdpSocket>
{
match UdpSocket::bind(&self.addresses[..]) {
Ok(s) => Option::from(s),
Err(e) => None
}
}
pub fn run(&mut self)
{
let (tx, rx): (Sender<()>, Receiver<()>) = mpsc::channel();
self.thread_killer = Some(tx);
let socket = self.bind();
self.thread = Some(thread::spawn(move || {
match socket {
None => {
error!("no socket created, failed to bind to address")
}
Some(s) => {
let mut cancelled = false;
while !cancelled {
let mut buf = [0; 512];
let res = s.recv_from(&mut buf);
match res {
Ok(r) => {
let res_str = str::from_utf8(&buf).unwrap();
info!("received: {}", res_str);
}
Err(_) => {}
}
cancelled = match rx.try_recv() {
Ok(_) | Err(TryRecvError::Disconnected) => true,
_ => false
}
}
}
};
info!("socket thread finishing")
}));
}
pub fn stop(&mut self)
{
// if let Some(t) = &mut self.thread {
if let Some(k) = &self.thread_killer {
k.send(());
// t.join();
}
// }
}
}

View File

@ -0,0 +1,3 @@
pub mod dns_socket;
pub mod request_parser;
mod dns_header;

View File