EmilHernvall / dnsguide

A guide to writing a DNS Server from scratch in Rust
MIT License
3.92k stars 246 forks source link

help! multithreaded server #20

Open coderboi2001 opened 2 years ago

coderboi2001 commented 2 years ago

I wanted to turn your server to a multithreaded one and I receive this error An error occurred: Either the application has not called WSAStartup, or WSAStartup failed. (os error 10093) handle An error occurred: Either the application has not called WSAStartup, or WSAStartup failed.

I know this is not an issue with your code, help would be much appreciated

coderboi2001 commented 2 years ago

`fn handle_query(socket: &UdpSocket, buffer: &mut BytePacketBuffer) -> Result<()> { // let mut req_buffer = BytePacketBuffer::new();

let mut req_buffer = buffer;
let (_, src) = socket.recv_from(&mut req_buffer.buf)?;

let mut request = DnsPacket::from_buffer(&mut req_buffer)?;

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;

if let Some(question) = request.questions.pop() {
    println!("Received query: {:?}", question);

    if let Ok(result) = recursive_lookup(&question.name, question.qtype) {
        packet.questions.push(question.clone());
        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;
    }
} else {
    packet.header.rescode = ResultCode::FORMERR;
}

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(())

} pub struct UdpServer { socket: UdpSocket, threads: u32 }

impl UdpServer { pub fn new(address: &str, threads: u32) -> UdpServer { let socket = Self::bind_server(address);

    UdpServer {
        socket: socket,
        threads: threads
    }
}

fn bind_server(addr: &str) -> UdpSocket {
    match UdpSocket::bind(&addr) {
        Ok(s) => {
            println!("Server listening: {}", addr);
            return s
        },
        Err(e) => panic!("Bind socket failed: {}", e)
    };
}

pub fn spawn_threads(&self) -> Vec<JoinHandle<()>>{
    (0..self.threads).map(|_|{
        let thread_socket = self.socket.try_clone().unwrap();
        let mut req_buffer = BytePacketBuffer::new();
        thread::spawn(move ||{
            loop {
                match handle_query(&thread_socket, &mut req_buffer){
                    Ok(_) => {}
                    Err(e) => eprintln!("An error occurred: {}", e),
                }
            }
        })
    }).collect()
}

}

fn main() {

let udpserver = UdpServer::new("0.0.0.0:2053",1);
let _ = udpserver.spawn_threads();
// let socket = UdpSocket::bind(("0.0.0.0", 2053))?;

// loop {
//     match handle_query(&socket) {
//         Ok(_) => {}
//         Err(e) => eprintln!("An error occurred: {}", e),
//     }
// }

}`

JeninSutradhar commented 3 months ago

https://github.com/JeninSutradhar/fortifynet_proxy/