Serenity Operating System
at master 71 lines 1.8 kB view raw
1/* 2 * Copyright (c) 2021, Sergey Bugaev <bugaevc@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include "DNSServer.h" 8#include "LookupServer.h" 9#include <AK/IPv4Address.h> 10#include <LibDNS/Packet.h> 11 12namespace LookupServer { 13 14using namespace DNS; 15 16DNSServer::DNSServer(Object* parent) 17 : Core::UDPServer(parent) 18{ 19 bind(IPv4Address(), 53); 20 on_ready_to_receive = [this]() { 21 auto result = handle_client(); 22 if (result.is_error()) { 23 dbgln("DNSServer: Failed to handle client: {}", result.error()); 24 } 25 }; 26} 27 28ErrorOr<void> DNSServer::handle_client() 29{ 30 sockaddr_in client_address; 31 auto buffer = TRY(receive(1024, client_address)); 32 auto optional_request = Packet::from_raw_packet(buffer.data(), buffer.size()); 33 if (!optional_request.has_value()) { 34 dbgln("Got an invalid DNS packet"); 35 return {}; 36 } 37 auto& request = optional_request.value(); 38 39 if (!request.is_query()) { 40 dbgln("It's not a request"); 41 return {}; 42 } 43 44 LookupServer& lookup_server = LookupServer::the(); 45 46 Packet response; 47 response.set_is_response(); 48 response.set_id(request.id()); 49 50 for (auto& question : request.questions()) { 51 if (question.class_code() != RecordClass::IN) 52 continue; 53 response.add_question(question); 54 auto answers = TRY(lookup_server.lookup(question.name(), question.record_type())); 55 for (auto& answer : answers) { 56 response.add_answer(answer); 57 } 58 } 59 60 if (response.answer_count() == 0) 61 response.set_code(Packet::Code::NXDOMAIN); 62 else 63 response.set_code(Packet::Code::NOERROR); 64 65 buffer = TRY(response.to_byte_buffer()); 66 67 TRY(send(buffer, client_address)); 68 return {}; 69} 70 71}