diff options
-rw-r--r-- | Userland/Services/LookupServer/ClientConnection.cpp | 4 | ||||
-rw-r--r-- | Userland/Services/LookupServer/DNSAnswer.cpp | 42 | ||||
-rw-r--r-- | Userland/Services/LookupServer/DNSAnswer.h | 47 | ||||
-rw-r--r-- | Userland/Services/LookupServer/DNSPacket.cpp | 23 | ||||
-rw-r--r-- | Userland/Services/LookupServer/DNSPacket.h | 9 | ||||
-rw-r--r-- | Userland/Services/LookupServer/DNSQuestion.h | 10 | ||||
-rw-r--r-- | Userland/Services/LookupServer/DNSServer.cpp | 2 | ||||
-rw-r--r-- | Userland/Services/LookupServer/LookupServer.cpp | 14 | ||||
-rw-r--r-- | Userland/Services/LookupServer/LookupServer.h | 4 | ||||
-rw-r--r-- | Userland/Services/LookupServer/MulticastDNS.cpp | 8 | ||||
-rw-r--r-- | Userland/Services/LookupServer/MulticastDNS.h | 2 |
11 files changed, 118 insertions, 47 deletions
diff --git a/Userland/Services/LookupServer/ClientConnection.cpp b/Userland/Services/LookupServer/ClientConnection.cpp index 98f5e3fb18..5d937b2537 100644 --- a/Userland/Services/LookupServer/ClientConnection.cpp +++ b/Userland/Services/LookupServer/ClientConnection.cpp @@ -30,7 +30,7 @@ void ClientConnection::die() Messages::LookupServer::LookupNameResponse ClientConnection::lookup_name(String const& name) { - auto answers = LookupServer::the().lookup(name, T_A); + auto answers = LookupServer::the().lookup(name, DNSRecordType::A); if (answers.is_empty()) return { 1, Vector<String>() }; Vector<String> addresses; @@ -50,7 +50,7 @@ Messages::LookupServer::LookupAddressResponse ClientConnection::lookup_address(S ip_address[2], ip_address[1], ip_address[0]); - auto answers = LookupServer::the().lookup(name, T_PTR); + auto answers = LookupServer::the().lookup(name, DNSRecordType::PTR); if (answers.is_empty()) return { 1, String() }; return { 0, answers[0].record_data() }; diff --git a/Userland/Services/LookupServer/DNSAnswer.cpp b/Userland/Services/LookupServer/DNSAnswer.cpp index 167361ac3e..edb7e8234d 100644 --- a/Userland/Services/LookupServer/DNSAnswer.cpp +++ b/Userland/Services/LookupServer/DNSAnswer.cpp @@ -5,11 +5,12 @@ */ #include "DNSAnswer.h" +#include <AK/Stream.h> #include <time.h> namespace LookupServer { -DNSAnswer::DNSAnswer(const DNSName& name, u16 type, u16 class_code, u32 ttl, const String& record_data, bool mdns_cache_flush) +DNSAnswer::DNSAnswer(const DNSName& name, DNSRecordType type, DNSRecordClass class_code, u32 ttl, const String& record_data, bool mdns_cache_flush) : m_name(name) , m_type(type) , m_class_code(class_code) @@ -29,3 +30,42 @@ bool DNSAnswer::has_expired() const } } + +void AK::Formatter<LookupServer::DNSRecordType>::format(AK::FormatBuilder& builder, LookupServer::DNSRecordType value) +{ + switch (value) { + case LookupServer::DNSRecordType::A: + builder.put_string("A"); + return; + case LookupServer::DNSRecordType::NS: + builder.put_string("NS"); + return; + case LookupServer::DNSRecordType::CNAME: + builder.put_string("CNAME"); + return; + case LookupServer::DNSRecordType::SOA: + builder.put_string("SOA"); + return; + case LookupServer::DNSRecordType::PTR: + builder.put_string("PTR"); + return; + case LookupServer::DNSRecordType::MX: + builder.put_string("MX"); + return; + } + + builder.put_string("DNS record type "); + builder.put_u64((u16)value); +} + +void AK::Formatter<LookupServer::DNSRecordClass>::format(AK::FormatBuilder& builder, LookupServer::DNSRecordClass value) +{ + switch (value) { + case LookupServer::DNSRecordClass::IN: + builder.put_string("IN"); + return; + } + + builder.put_string("DNS record class "); + builder.put_u64((u16)value); +} diff --git a/Userland/Services/LookupServer/DNSAnswer.h b/Userland/Services/LookupServer/DNSAnswer.h index d5dffe597c..a015a050d8 100644 --- a/Userland/Services/LookupServer/DNSAnswer.h +++ b/Userland/Services/LookupServer/DNSAnswer.h @@ -7,21 +7,35 @@ #pragma once #include "DNSName.h" +#include <AK/Format.h> #include <AK/String.h> #include <AK/Types.h> namespace LookupServer { +enum class DNSRecordType : u16 { + A = 1, + NS = 2, + CNAME = 5, + SOA = 6, + PTR = 12, + MX = 15, +}; + +enum class DNSRecordClass : u16 { + IN = 1 +}; + #define MDNS_CACHE_FLUSH 0x8000 class DNSAnswer { public: - DNSAnswer(const DNSName& name, u16 type, u16 class_code, u32 ttl, const String& record_data, bool mdns_cache_flush); + DNSAnswer(const DNSName& name, DNSRecordType type, DNSRecordClass class_code, u32 ttl, const String& record_data, bool mdns_cache_flush); const DNSName& name() const { return m_name; } - u16 type() const { return m_type; } - u16 class_code() const { return m_class_code; } - u16 raw_class_code() const { return m_class_code | (m_mdns_cache_flush ? MDNS_CACHE_FLUSH : 0); } + DNSRecordType type() const { return m_type; } + DNSRecordClass class_code() const { return m_class_code; } + u16 raw_class_code() const { return (u16)m_class_code | (m_mdns_cache_flush ? MDNS_CACHE_FLUSH : 0); } u32 ttl() const { return m_ttl; } const String& record_data() const { return m_record_data; } bool mdns_cache_flush() const { return m_mdns_cache_flush; } @@ -30,8 +44,8 @@ public: private: DNSName m_name; - u16 m_type { 0 }; - u16 m_class_code { 0 }; + DNSRecordType m_type { 0 }; + DNSRecordClass m_class_code { 0 }; u32 m_ttl { 0 }; time_t m_expiration_time { 0 }; String m_record_data; @@ -39,3 +53,24 @@ private: }; } +template<> +struct AK::Formatter<LookupServer::DNSRecordType> : StandardFormatter { + Formatter() = default; + explicit Formatter(StandardFormatter formatter) + : StandardFormatter(formatter) + { + } + + void format(AK::FormatBuilder&, LookupServer::DNSRecordType); +}; + +template<> +struct AK::Formatter<LookupServer::DNSRecordClass> : StandardFormatter { + Formatter() = default; + explicit Formatter(StandardFormatter formatter) + : StandardFormatter(formatter) + { + } + + void format(AK::FormatBuilder&, LookupServer::DNSRecordClass); +}; diff --git a/Userland/Services/LookupServer/DNSPacket.cpp b/Userland/Services/LookupServer/DNSPacket.cpp index 8cec959856..f76bbf9772 100644 --- a/Userland/Services/LookupServer/DNSPacket.cpp +++ b/Userland/Services/LookupServer/DNSPacket.cpp @@ -55,15 +55,15 @@ ByteBuffer DNSPacket::to_byte_buffer() const stream << ReadonlyBytes { &header, sizeof(header) }; for (auto& question : m_questions) { stream << question.name(); - stream << htons(question.record_type()); + stream << htons((u16)question.record_type()); stream << htons(question.raw_class_code()); } for (auto& answer : m_answers) { stream << answer.name(); - stream << htons(answer.type()); + stream << htons((u16)answer.type()); stream << htons(answer.raw_class_code()); stream << htonl(answer.ttl()); - if (answer.type() == T_PTR) { + if (answer.type() == DNSRecordType::PTR) { DNSName name { answer.record_data() }; stream << htons(name.serialized_size()); stream << name; @@ -131,7 +131,7 @@ Optional<DNSPacket> DNSPacket::from_raw_packet(const u8* raw_data, size_t raw_si auto& record_and_class = *(const RawDNSAnswerQuestion*)&raw_data[offset]; u16 class_code = record_and_class.class_code & ~MDNS_WANTS_UNICAST_RESPONSE; bool mdns_wants_unicast_response = record_and_class.class_code & MDNS_WANTS_UNICAST_RESPONSE; - packet.m_questions.empend(name, record_and_class.record_type, class_code, mdns_wants_unicast_response); + packet.m_questions.empend(name, (DNSRecordType)(u16)record_and_class.record_type, (DNSRecordClass)class_code, mdns_wants_unicast_response); offset += 4; auto& question = packet.m_questions.last(); dbgln_if(LOOKUPSERVER_DEBUG, "Question #{}: name=_{}_, type={}, class={}", i, question.name(), question.record_type(), question.class_code()); @@ -146,19 +146,24 @@ Optional<DNSPacket> DNSPacket::from_raw_packet(const u8* raw_data, size_t raw_si offset += sizeof(DNSRecordWithoutName); - if (record.type() == T_PTR) { + switch ((DNSRecordType)record.type()) { + case DNSRecordType::PTR: { size_t dummy_offset = offset; data = DNSName::parse(raw_data, dummy_offset, raw_size).as_string(); - } else if (record.type() == T_A) { + break; + } + case DNSRecordType::A: data = { record.data(), record.data_length() }; - } else { + break; + default: // FIXME: Parse some other record types perhaps? - dbgln("data=(unimplemented record type {})", record.type()); + dbgln("data=(unimplemented record type {})", (u16)record.type()); } + dbgln_if(LOOKUPSERVER_DEBUG, "Answer #{}: name=_{}_, type={}, ttl={}, length={}, data=_{}_", i, name, record.type(), record.ttl(), record.data_length(), data); u16 class_code = record.record_class() & ~MDNS_CACHE_FLUSH; bool mdns_cache_flush = record.record_class() & MDNS_CACHE_FLUSH; - packet.m_answers.empend(name, record.type(), class_code, record.ttl(), data, mdns_cache_flush); + packet.m_answers.empend(name, (DNSRecordType)record.type(), (DNSRecordClass)class_code, record.ttl(), data, mdns_cache_flush); offset += record.data_length(); } diff --git a/Userland/Services/LookupServer/DNSPacket.h b/Userland/Services/LookupServer/DNSPacket.h index 2db3539678..0927f94e4f 100644 --- a/Userland/Services/LookupServer/DNSPacket.h +++ b/Userland/Services/LookupServer/DNSPacket.h @@ -13,15 +13,6 @@ #include <AK/Types.h> #include <AK/Vector.h> -#define T_A 1 -#define T_NS 2 -#define T_CNAME 5 -#define T_SOA 6 -#define T_PTR 12 -#define T_MX 15 - -#define C_IN 1 - namespace LookupServer { enum class ShouldRandomizeCase { diff --git a/Userland/Services/LookupServer/DNSQuestion.h b/Userland/Services/LookupServer/DNSQuestion.h index dfe5826b55..89d5c76ff8 100644 --- a/Userland/Services/LookupServer/DNSQuestion.h +++ b/Userland/Services/LookupServer/DNSQuestion.h @@ -15,7 +15,7 @@ namespace LookupServer { class DNSQuestion { public: - DNSQuestion(const DNSName& name, u16 record_type, u16 class_code, bool mdns_wants_unicast_response) + DNSQuestion(const DNSName& name, DNSRecordType record_type, DNSRecordClass class_code, bool mdns_wants_unicast_response) : m_name(name) , m_record_type(record_type) , m_class_code(class_code) @@ -23,16 +23,16 @@ public: { } - u16 record_type() const { return m_record_type; } - u16 class_code() const { return m_class_code; } + DNSRecordType record_type() const { return m_record_type; } + DNSRecordClass class_code() const { return m_class_code; } u16 raw_class_code() const { return (u16)m_class_code | (m_mdns_wants_unicast_response ? MDNS_WANTS_UNICAST_RESPONSE : 0); } const DNSName& name() const { return m_name; } bool mdns_wants_unicast_response() const { return m_mdns_wants_unicast_response; } private: DNSName m_name; - u16 m_record_type { 0 }; - u16 m_class_code { 0 }; + DNSRecordType m_record_type { 0 }; + DNSRecordClass m_class_code { 0 }; bool m_mdns_wants_unicast_response { false }; }; diff --git a/Userland/Services/LookupServer/DNSServer.cpp b/Userland/Services/LookupServer/DNSServer.cpp index 3bce7a275b..08f199da69 100644 --- a/Userland/Services/LookupServer/DNSServer.cpp +++ b/Userland/Services/LookupServer/DNSServer.cpp @@ -43,7 +43,7 @@ void DNSServer::handle_client() response.set_id(request.id()); for (auto& question : request.questions()) { - if (question.class_code() != C_IN) + if (question.class_code() != DNSRecordClass::IN) continue; response.add_question(question); auto answers = lookup_server.lookup(question.name(), question.record_type()); diff --git a/Userland/Services/LookupServer/LookupServer.cpp b/Userland/Services/LookupServer/LookupServer.cpp index e20e775a36..46eec69369 100644 --- a/Userland/Services/LookupServer/LookupServer.cpp +++ b/Userland/Services/LookupServer/LookupServer.cpp @@ -69,13 +69,13 @@ void LookupServer::load_etc_hosts() // The value here is 1 day. static constexpr u32 static_ttl = 86400; - auto add_answer = [this](const DNSName& name, unsigned short record_type, String data) { + auto add_answer = [this](const DNSName& name, DNSRecordType record_type, String data) { auto it = m_etc_hosts.find(name); if (it == m_etc_hosts.end()) { m_etc_hosts.set(name, {}); it = m_etc_hosts.find(name); } - it->value.empend(name, record_type, (u16)C_IN, static_ttl, data, false); + it->value.empend(name, record_type, DNSRecordClass::IN, static_ttl, data, false); }; auto file = Core::File::construct("/etc/hosts"); @@ -97,7 +97,7 @@ void LookupServer::load_etc_hosts() auto raw_addr = addr.to_in_addr_t(); DNSName name = fields[1]; - add_answer(name, T_A, String { (const char*)&raw_addr, sizeof(raw_addr) }); + add_answer(name, DNSRecordType::A, String { (const char*)&raw_addr, sizeof(raw_addr) }); IPv4Address reverse_addr { (u8)atoi(sections[3].characters()), @@ -108,11 +108,11 @@ void LookupServer::load_etc_hosts() StringBuilder builder; builder.append(reverse_addr.to_string()); builder.append(".in-addr.arpa"); - add_answer(builder.to_string(), T_PTR, name.as_string()); + add_answer(builder.to_string(), DNSRecordType::PTR, name.as_string()); } } -Vector<DNSAnswer> LookupServer::lookup(const DNSName& name, unsigned short record_type) +Vector<DNSAnswer> LookupServer::lookup(const DNSName& name, DNSRecordType record_type) { dbgln_if(LOOKUPSERVER_DEBUG, "Got request for '{}'", name.as_string()); @@ -190,7 +190,7 @@ Vector<DNSAnswer> LookupServer::lookup(const DNSName& name, unsigned short recor return answers; } -Vector<DNSAnswer> LookupServer::lookup(const DNSName& name, const String& nameserver, bool& did_get_response, unsigned short record_type, ShouldRandomizeCase should_randomize_case) +Vector<DNSAnswer> LookupServer::lookup(const DNSName& name, const String& nameserver, bool& did_get_response, DNSRecordType record_type, ShouldRandomizeCase should_randomize_case) { DNSPacket request; request.set_is_query(); @@ -198,7 +198,7 @@ Vector<DNSAnswer> LookupServer::lookup(const DNSName& name, const String& namese DNSName name_in_question = name; if (should_randomize_case == ShouldRandomizeCase::Yes) name_in_question.randomize_case(); - request.add_question({ name_in_question, record_type, C_IN, false }); + request.add_question({ name_in_question, record_type, DNSRecordClass::IN, false }); auto buffer = request.to_byte_buffer(); diff --git a/Userland/Services/LookupServer/LookupServer.h b/Userland/Services/LookupServer/LookupServer.h index a46ebffc54..c948f2aa07 100644 --- a/Userland/Services/LookupServer/LookupServer.h +++ b/Userland/Services/LookupServer/LookupServer.h @@ -21,7 +21,7 @@ class LookupServer final : public Core::Object { public: static LookupServer& the(); - Vector<DNSAnswer> lookup(const DNSName& name, unsigned short record_type); + Vector<DNSAnswer> lookup(const DNSName& name, DNSRecordType record_type); private: LookupServer(); @@ -29,7 +29,7 @@ private: void load_etc_hosts(); void put_in_cache(const DNSAnswer&); - Vector<DNSAnswer> lookup(const DNSName& hostname, const String& nameserver, bool& did_get_response, unsigned short record_type, ShouldRandomizeCase = ShouldRandomizeCase::Yes); + Vector<DNSAnswer> lookup(const DNSName& hostname, const String& nameserver, bool& did_get_response, DNSRecordType record_type, ShouldRandomizeCase = ShouldRandomizeCase::Yes); RefPtr<Core::LocalServer> m_local_server; RefPtr<DNSServer> m_dns_server; diff --git a/Userland/Services/LookupServer/MulticastDNS.cpp b/Userland/Services/LookupServer/MulticastDNS.cpp index 4e903c74ed..2eebfbf1f4 100644 --- a/Userland/Services/LookupServer/MulticastDNS.cpp +++ b/Userland/Services/LookupServer/MulticastDNS.cpp @@ -87,8 +87,8 @@ void MulticastDNS::announce() auto raw_addr = address.to_in_addr_t(); DNSAnswer answer { m_hostname, - T_A, - C_IN, + DNSRecordType::A, + DNSRecordClass::IN, 120, String { (const char*)&raw_addr, sizeof(raw_addr) }, true, @@ -138,11 +138,11 @@ Vector<IPv4Address> MulticastDNS::local_addresses() const return addresses; } -Vector<DNSAnswer> MulticastDNS::lookup(const DNSName& name, unsigned short record_type) +Vector<DNSAnswer> MulticastDNS::lookup(const DNSName& name, DNSRecordType record_type) { DNSPacket request; request.set_is_query(); - request.add_question({ name, record_type, C_IN, false }); + request.add_question({ name, record_type, DNSRecordClass::IN, false }); if (emit_packet(request) < 0) { perror("failed to emit request packet"); diff --git a/Userland/Services/LookupServer/MulticastDNS.h b/Userland/Services/LookupServer/MulticastDNS.h index 49a73c1b34..0f7131e64f 100644 --- a/Userland/Services/LookupServer/MulticastDNS.h +++ b/Userland/Services/LookupServer/MulticastDNS.h @@ -18,7 +18,7 @@ namespace LookupServer { class MulticastDNS : public Core::UDPServer { C_OBJECT(MulticastDNS) public: - Vector<DNSAnswer> lookup(const DNSName&, unsigned short record_type); + Vector<DNSAnswer> lookup(const DNSName&, DNSRecordType record_type); private: explicit MulticastDNS(Object* parent = nullptr); |