mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 06:57:44 +00:00
LookupServer: Turn #defines into enum classes and add formatter
This commit is contained in:
parent
6e70888315
commit
7b3bed7910
11 changed files with 120 additions and 49 deletions
|
@ -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() };
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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) {
|
||||
data = { record.data(), record.data_length() };
|
||||
} else {
|
||||
// FIXME: Parse some other record types perhaps?
|
||||
dbgln("data=(unimplemented record type {})", record.type());
|
||||
break;
|
||||
}
|
||||
case DNSRecordType::A:
|
||||
data = { record.data(), record.data_length() };
|
||||
break;
|
||||
default:
|
||||
// FIXME: Parse some other record types perhaps?
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 };
|
||||
};
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue