lokinet/llarp/dns/message.hpp
Jeff 74362149eb
refactor dns subsystem
we want to be able to have multiple locally bound dns sockets in lokinet so
i restructured most of the dns subsystem in order to make this easier.

specifically, we have a new structure to dns subsystem:

* dns::QueryJob_Base

base type for holding a dns query and response with virtual methods
in charge of sending a reply to whoever requested.

* dns::PacketSource_Base

base type for reading and writing dns messages to and from wherever they came from

* dns::Resolver_Base

base type for filtering and handling of dns messages asynchronously.

* dns::Server

contextualized per endpoint dns object, responsible for all dns related isms.

this change hides all impelementation details of all of the dns components.
adds some more helper functions for parsing dns and dealing with OwnedBuffer.

overall dns becomes less of a pain with this new structure. probably.
2022-09-08 14:23:52 -04:00

114 lines
2.5 KiB
C++

#pragma once
#include "serialize.hpp"
#include "rr.hpp"
#include "question.hpp"
namespace llarp
{
namespace dns
{
struct SRVData;
using MsgID_t = uint16_t;
using Fields_t = uint16_t;
using Count_t = uint16_t;
struct MessageHeader : public Serialize
{
static constexpr size_t Size = 12;
MessageHeader() = default;
MsgID_t id;
Fields_t fields;
Count_t qd_count;
Count_t an_count;
Count_t ns_count;
Count_t ar_count;
bool
Encode(llarp_buffer_t* buf) const override;
bool
Decode(llarp_buffer_t* buf) override;
util::StatusObject
ToJSON() const override;
bool
operator==(const MessageHeader& other) const
{
return id == other.id && fields == other.fields && qd_count == other.qd_count
&& an_count == other.an_count && ns_count == other.ns_count
&& ar_count == other.ar_count;
}
};
struct Message : public Serialize
{
explicit Message(const MessageHeader& hdr);
explicit Message(const Question& question);
Message(Message&& other);
Message(const Message& other);
util::StatusObject
ToJSON() const override;
void
AddNXReply(RR_TTL_t ttl = 1);
void
AddServFail(RR_TTL_t ttl = 30);
void
AddMXReply(std::string name, uint16_t priority, RR_TTL_t ttl = 1);
void
AddCNAMEReply(std::string name, RR_TTL_t ttl = 1);
void
AddINReply(llarp::huint128_t addr, bool isV6, RR_TTL_t ttl = 1);
void
AddAReply(std::string name, RR_TTL_t ttl = 1);
void
AddSRVReply(std::vector<SRVData> records, RR_TTL_t ttl = 1);
void
AddNSReply(std::string name, RR_TTL_t ttl = 1);
void
AddTXTReply(std::string value, RR_TTL_t ttl = 1);
bool
Encode(llarp_buffer_t* buf) const override;
bool
Decode(llarp_buffer_t* buf) override;
// Wrapper around Encode that encodes into a new buffer and returns it
[[nodiscard]] OwnedBuffer
ToBuffer() const;
std::string
ToString() const;
MsgID_t hdr_id;
Fields_t hdr_fields;
std::vector<Question> questions;
std::vector<ResourceRecord> answers;
std::vector<ResourceRecord> authorities;
std::vector<ResourceRecord> additional;
};
std::optional<Message>
MaybeParseDNSMessage(llarp_buffer_t buf);
} // namespace dns
template <>
constexpr inline bool IsToStringFormattable<llarp::dns::Message> = true;
} // namespace llarp