Skip to content

Commit

Permalink
Merge pull request #2 from bitsexplained/prep-for-publish
Browse files Browse the repository at this point in the history
refactor to have lib crate
  • Loading branch information
muathendirangu authored Jan 7, 2024
2 parents c21038b + ca2bf17 commit 608c00b
Show file tree
Hide file tree
Showing 14 changed files with 127 additions and 115 deletions.
21 changes: 19 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,25 @@
[package]
name = "dns"
version = "0.1.0"
name = "micro-dns"
version = "0.1.11"
edition = "2021"
description = "a recursive dns resolver"
homepage = "https://github.com/bitsexplained/dns"
documentation = "https://docs.rs/micro-dns"
repository = "https://github.com/bitsexplained/dns"
readme = "README.md"
license = "MIT"
keywords = ["dns", "resolver", "recursive"]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]


[[bin]]
name = "micro-dns"
path = "src/main.rs"


[lib]
name = "micro_dns"
path = "src/lib/lib.rs"
1 change: 0 additions & 1 deletion src/buffer/mod.rs

This file was deleted.

6 changes: 0 additions & 6 deletions src/dns/mod.rs

This file was deleted.

4 changes: 3 additions & 1 deletion src/buffer/buffer.rs → src/lib/buffer.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use crate::utils::types::Result;

use crate::types::Result;


pub struct BytePacketBuffer{
pub buf: [u8; 512],
Expand Down
4 changes: 2 additions & 2 deletions src/dns/dns_header.rs → src/lib/dns_header.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::buffer::buffer::BytePacketBuffer;
use crate::utils::types::Result;
use crate::buffer::BytePacketBuffer;
use crate::types::Result;


// ResultCode
Expand Down
14 changes: 6 additions & 8 deletions src/dns/dns_lookup.rs → src/lib/dns_lookup.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
use std::net::{Ipv4Addr,UdpSocket};


use crate::buffer::buffer::BytePacketBuffer;
use crate::utils::types::Result;

use super::query_type::QueryType;
use super::dns_packet::DnsPacket;
use super::dns_header::ResultCode;
use super::dns_question::DnsQuestion;

use crate::buffer::BytePacketBuffer;
use crate::types::Result;
use crate::dns_packet::DnsPacket;
use crate::dns_header::ResultCode;
use crate::dns_question::DnsQuestion;
use crate::query_type::QueryType;

// Add lookup method to lookup DNS records
fn lookup(query_name: &str, query_type: QueryType, server: (Ipv4Addr, u16)) -> Result<DnsPacket> {
Expand Down
4 changes: 2 additions & 2 deletions src/dns/dns_packet.rs → src/lib/dns_packet.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::net::Ipv4Addr;


use crate::buffer::buffer::BytePacketBuffer;
use crate::utils::types::Result;
use crate::buffer::BytePacketBuffer;
use crate::types::Result;

use super::query_type::QueryType;
use super::dns_header::DnsHeader;
Expand Down
6 changes: 2 additions & 4 deletions src/dns/dns_question.rs → src/lib/dns_question.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use crate::utils::types::Result;
use crate::types::Result;
use crate::buffer::buffer::BytePacketBuffer;


use super::query_type::QueryType;
use crate::query_type::QueryType;


//DnsQuestion allows adding of more records later on
Expand Down
8 changes: 3 additions & 5 deletions src/dns/dns_record.rs → src/lib/dns_record.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
use std::net::{Ipv4Addr, Ipv6Addr};

use crate::utils::types::Result;
use crate::buffer::buffer::BytePacketBuffer;

use super::query_type::QueryType;
use crate::types::Result;
use crate::buffer::BytePacketBuffer;
use crate::query_type::QueryType;

//DnsRecord represents the actual dns record
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
Expand Down
89 changes: 89 additions & 0 deletions src/lib/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@

use std::net::UdpSocket;


pub mod buffer;
pub mod dns_header;
pub mod dns_packet;
pub mod dns_lookup;
pub mod types;


use crate::types::Result;
use crate::buffer::BytePacketBuffer;
use crate::dns_header::ResultCode;
use crate::dns_packet::DnsPacket;
use crate::dns_lookup::recursive_lookup;



/// Handle a single incoming packet
pub fn handle_query(socket: &UdpSocket) -> Result<()> {
// With a socket ready, we can go ahead and read a packet. This will
// block until one is received.
let mut req_buffer = BytePacketBuffer::new();

// The `recv_from` function will write the data into the provided buffer,
// and return the length of the data read as well as the source address.
// We're not interested in the length, but we need to keep track of the
// source in order to send our reply later on.
let (_, src) = socket.recv_from(&mut req_buffer.buf)?;

// Next, `DnsPacket::from_buffer` is used to parse the raw bytes into
// a `DnsPacket`.
let mut request = DnsPacket::from_buffer(&mut req_buffer)?;

// Create and initialize the response packet
let mut packet = DnsPacket::new();
packet.header.id = request.header.id;
packet.header.recursion_desired = true;
packet.header.recursion_available = true;
packet.header.response = true;

// In the normal case, exactly one question is present
if let Some(question) = request.questions.pop() {
println!("Received query: {:?}", question);

// Since all is set up and as expected, the query can be forwarded to the
// target server. There's always the possibility that the query will
// fail, in which case the `SERVFAIL` response code is set to indicate
// as much to the client. If rather everything goes as planned, the
// question and response records as copied into our response packet.
if let Ok(result) = recursive_lookup(&question.name, question.question_type) {
packet.questions.push(question);
packet.header.rescode = result.header.rescode;

for rec in result.answers {
println!("Answer: {:?}", rec);
packet.answers.push(rec);
}
for rec in result.authorities {
println!("Authority: {:?}", rec);
packet.authorities.push(rec);
}
for rec in result.resources {
println!("Resource: {:?}", rec);
packet.resources.push(rec);
}
} else {
packet.header.rescode = ResultCode::SERVFAIL;
}
}
// Being mindful of how unreliable input data from arbitrary senders can be, we
// need make sure that a question is actually present. If not, we return `FORMERR`
// to indicate that the sender made something wrong.
else {
packet.header.rescode = ResultCode::FORMERR;
}

// encode our response and send it back
let mut res_buffer = BytePacketBuffer::new();
packet.write(&mut res_buffer)?;

let len = res_buffer.pos();
let data = res_buffer.get_range(0, len)?;

socket.send_to(data, src)?;

Ok(())
}
File renamed without changes.
File renamed without changes.
84 changes: 1 addition & 83 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,88 +1,6 @@
use std::net::UdpSocket;

pub mod utils;
pub mod buffer;
pub mod dns;


use lib::handle_query;
use utils::types::Result;
use buffer::buffer::BytePacketBuffer;
use dns::dns_header::ResultCode;
use dns::dns_packet::DnsPacket;
use dns::dns_lookup::recursive_lookup;



/// Handle a single incoming packet
fn handle_query(socket: &UdpSocket) -> Result<()> {
// With a socket ready, we can go ahead and read a packet. This will
// block until one is received.
let mut req_buffer = BytePacketBuffer::new();

// The `recv_from` function will write the data into the provided buffer,
// and return the length of the data read as well as the source address.
// We're not interested in the length, but we need to keep track of the
// source in order to send our reply later on.
let (_, src) = socket.recv_from(&mut req_buffer.buf)?;

// Next, `DnsPacket::from_buffer` is used to parse the raw bytes into
// a `DnsPacket`.
let mut request = DnsPacket::from_buffer(&mut req_buffer)?;

// Create and initialize the response packet
let mut packet = DnsPacket::new();
packet.header.id = request.header.id;
packet.header.recursion_desired = true;
packet.header.recursion_available = true;
packet.header.response = true;

// In the normal case, exactly one question is present
if let Some(question) = request.questions.pop() {
println!("Received query: {:?}", question);

// Since all is set up and as expected, the query can be forwarded to the
// target server. There's always the possibility that the query will
// fail, in which case the `SERVFAIL` response code is set to indicate
// as much to the client. If rather everything goes as planned, the
// question and response records as copied into our response packet.
if let Ok(result) = recursive_lookup(&question.name, question.question_type) {
packet.questions.push(question);
packet.header.rescode = result.header.rescode;

for rec in result.answers {
println!("Answer: {:?}", rec);
packet.answers.push(rec);
}
for rec in result.authorities {
println!("Authority: {:?}", rec);
packet.authorities.push(rec);
}
for rec in result.resources {
println!("Resource: {:?}", rec);
packet.resources.push(rec);
}
} else {
packet.header.rescode = ResultCode::SERVFAIL;
}
}
// Being mindful of how unreliable input data from arbitrary senders can be, we
// need make sure that a question is actually present. If not, we return `FORMERR`
// to indicate that the sender made something wrong.
else {
packet.header.rescode = ResultCode::FORMERR;
}

// encode our response and send it back
let mut res_buffer = BytePacketBuffer::new();
packet.write(&mut res_buffer)?;

let len = res_buffer.pos();
let data = res_buffer.get_range(0, len)?;

socket.send_to(data, src)?;

Ok(())
}

fn main() -> Result<()> {
// Bind an UDP socket on port 2053
Expand Down
1 change: 0 additions & 1 deletion src/utils/mod.rs

This file was deleted.

0 comments on commit 608c00b

Please sign in to comment.