mirror of
https://github.com/oxen-io/lokinet
synced 2023-12-14 06:53:00 +01:00
internal refactor
- created various structs for each record type - changed DNSd to return most of the recieved packet (allowing for multiple answers) - favor vector<byte_t> over c-style buffers - support NS records a little better - fixed output on cname, ptr, txt
This commit is contained in:
parent
373a14b44b
commit
969865c499
9 changed files with 629 additions and 59 deletions
|
@ -422,6 +422,7 @@ set(LIB_SRC
|
|||
llarp/context.cpp
|
||||
llarp/crypto_libsodium.cpp
|
||||
llarp/dht.cpp
|
||||
llarp/dns_rectypes.cpp
|
||||
llarp/dns.cpp
|
||||
llarp/dnsc.cpp
|
||||
llarp/dnsd.cpp
|
||||
|
@ -485,6 +486,7 @@ set(DNS_SRC
|
|||
llarp/dnsd.cpp
|
||||
llarp/dns_iptracker.cpp
|
||||
llarp/dns_dotlokilookup.cpp
|
||||
llarp/dns_rectypes.cpp
|
||||
llarp/net.cpp
|
||||
daemon/dns.cpp
|
||||
)
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#endif
|
||||
|
||||
#include <llarp/net.hpp> // for llarp::Addr , llarp::huint32_t
|
||||
#include <llarp/dns_rectypes.hpp>
|
||||
|
||||
struct dnsd_context;
|
||||
|
||||
|
@ -73,6 +74,7 @@ struct dns_msg_answer
|
|||
uint32_t ttl;
|
||||
uint16_t rdLen;
|
||||
std::vector< byte_t > rData;
|
||||
std::unique_ptr< llarp::dns::record > record;
|
||||
};
|
||||
|
||||
struct dns_packet
|
||||
|
@ -84,12 +86,24 @@ struct dns_packet
|
|||
std::vector< std::unique_ptr< dns_msg_answer > > additional_rrs;
|
||||
};
|
||||
|
||||
std::vector< byte_t >
|
||||
packet2bytes(dns_packet &in);
|
||||
|
||||
std::string
|
||||
getDNSstring(const char *const buffer, uint32_t *pos);
|
||||
|
||||
void
|
||||
code_domain(char *&buffer, const std::string &domain) throw();
|
||||
|
||||
void
|
||||
vcode_domain(std::vector< byte_t > &bytes, const std::string &domain) throw();
|
||||
|
||||
void
|
||||
vput16bits(std::vector< byte_t > &bytes, uint16_t value) throw();
|
||||
|
||||
void
|
||||
vput32bits(std::vector< byte_t > &bytes, uint32_t value) throw();
|
||||
|
||||
extern "C"
|
||||
{
|
||||
uint16_t
|
||||
|
|
114
include/llarp/dns_rectypes.hpp
Normal file
114
include/llarp/dns_rectypes.hpp
Normal file
|
@ -0,0 +1,114 @@
|
|||
#ifndef LIBLLARP_DNS_REC_TYPES_HPP
|
||||
#define LIBLLARP_DNS_REC_TYPES_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <llarp/buffer.h> // for byte_t
|
||||
#include <llarp/net.hpp> // for llarp::Addr , llarp::huint32_t
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace dns
|
||||
{
|
||||
struct record
|
||||
{
|
||||
virtual ~record(){};
|
||||
record()
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool
|
||||
parse(std::vector< byte_t > bytes);
|
||||
|
||||
virtual std::vector< byte_t >
|
||||
to_bytes();
|
||||
};
|
||||
|
||||
struct type_1a : public record
|
||||
{
|
||||
huint32_t ipaddr;
|
||||
|
||||
virtual ~type_1a(){};
|
||||
type_1a();
|
||||
|
||||
bool
|
||||
parse(std::vector< byte_t > bytes);
|
||||
|
||||
std::vector< byte_t >
|
||||
to_bytes();
|
||||
};
|
||||
|
||||
struct type_2ns : public record
|
||||
{
|
||||
std::string ns;
|
||||
|
||||
virtual ~type_2ns(){};
|
||||
type_2ns();
|
||||
|
||||
bool
|
||||
parse(std::vector< byte_t > bytes);
|
||||
|
||||
std::vector< byte_t >
|
||||
to_bytes();
|
||||
};
|
||||
|
||||
struct type_5cname : public record
|
||||
{
|
||||
std::string cname;
|
||||
|
||||
virtual ~type_5cname(){};
|
||||
type_5cname();
|
||||
|
||||
bool
|
||||
parse(std::vector< byte_t > bytes);
|
||||
|
||||
std::vector< byte_t >
|
||||
to_bytes();
|
||||
};
|
||||
|
||||
struct type_12ptr : public record
|
||||
{
|
||||
std::string revname;
|
||||
|
||||
virtual ~type_12ptr(){};
|
||||
type_12ptr();
|
||||
|
||||
bool
|
||||
parse(std::vector< byte_t > bytes);
|
||||
|
||||
std::vector< byte_t >
|
||||
to_bytes();
|
||||
};
|
||||
|
||||
struct type_15mx : public record
|
||||
{
|
||||
std::string mx;
|
||||
uint16_t priority;
|
||||
|
||||
virtual ~type_15mx(){};
|
||||
type_15mx();
|
||||
|
||||
bool
|
||||
parse(std::vector< byte_t > bytes);
|
||||
|
||||
std::vector< byte_t >
|
||||
to_bytes();
|
||||
};
|
||||
|
||||
struct type_16txt : public record
|
||||
{
|
||||
std::string txt;
|
||||
|
||||
virtual ~type_16txt(){};
|
||||
type_16txt();
|
||||
|
||||
bool
|
||||
parse(std::vector< byte_t > bytes);
|
||||
|
||||
std::vector< byte_t >
|
||||
to_bytes();
|
||||
};
|
||||
|
||||
} // namespace dns
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
|
@ -15,8 +15,8 @@ struct dnsc_answer_request;
|
|||
struct dns_query
|
||||
{
|
||||
uint16_t length;
|
||||
// char *url;
|
||||
unsigned char request[DNC_BUF_SIZE];
|
||||
// char *url;
|
||||
// uint16_t reqType;
|
||||
};
|
||||
|
||||
|
@ -32,15 +32,18 @@ typedef void (*dnsc_answer_hook_func)(dnsc_answer_request *request);
|
|||
struct dnsc_answer_request
|
||||
{
|
||||
/// sock type
|
||||
void *sock; // pts to udp...
|
||||
void *sock; // points to udp that sent the request to DNSc...
|
||||
/// customizable (used for hook (outer request))
|
||||
void *user;
|
||||
/// storage
|
||||
/// request storage
|
||||
dns_msg_question question;
|
||||
/// response storage
|
||||
dns_packet packet;
|
||||
/// hook
|
||||
dnsc_answer_hook_func resolved;
|
||||
/// result
|
||||
bool found;
|
||||
|
||||
llarp::huint32_t result;
|
||||
std::string revDNS;
|
||||
// a reference to dnsc_context incase of multiple contexts
|
||||
|
|
|
@ -61,6 +61,8 @@ llarp_handle_dnsd_recvfrom(struct llarp_udp_io *udp,
|
|||
// we may want to pass dnsd_question_request to these,
|
||||
// incase we need to send an error back up through the pipeline
|
||||
|
||||
// FIXME: just use the from in the request
|
||||
|
||||
/// NXDOMAIN not found
|
||||
void
|
||||
write404_dnss_response(const struct sockaddr *from,
|
||||
|
|
242
llarp/dns.cpp
242
llarp/dns.cpp
|
@ -124,10 +124,180 @@ code_domain(char *&buffer, const std::string &domain) throw()
|
|||
*buffer++ = 0;
|
||||
}
|
||||
|
||||
// lets just remove uint
|
||||
#ifdef _WIN32
|
||||
#define uint UINT
|
||||
#endif
|
||||
void
|
||||
vcode_domain(std::vector< byte_t > &bytes, const std::string &domain) throw()
|
||||
{
|
||||
std::string::size_type start(0);
|
||||
std::string::size_type end; // indexes
|
||||
// llarp::LogInfo("domain [", domain, "]");
|
||||
while((end = domain.find('.', start)) != std::string::npos)
|
||||
{
|
||||
bytes.push_back(end - start); // label length octet
|
||||
for(std::string::size_type i = start; i < end; i++)
|
||||
{
|
||||
bytes.push_back(domain[i]); // label octets
|
||||
// llarp::LogInfo("Writing ", domain[i], " at ", i);
|
||||
}
|
||||
start = end + 1; // Skip '.'
|
||||
}
|
||||
|
||||
// llarp::LogInfo("start ", start, " domain size ", domain.size());
|
||||
|
||||
bytes.push_back(domain.size() - start); // last label length octet
|
||||
for(size_t i = start; i < domain.size(); i++)
|
||||
{
|
||||
bytes.push_back(domain[i]); // last label octets
|
||||
// llarp::LogInfo("Writing ", domain[i], " at ", i);
|
||||
}
|
||||
bytes.push_back(0); // end it
|
||||
}
|
||||
|
||||
// expects host order
|
||||
void
|
||||
vput16bits(std::vector< byte_t > &bytes, uint16_t value) throw()
|
||||
{
|
||||
char buf[2] = {0};
|
||||
char *write_buffer = buf;
|
||||
htobe16buf(write_buffer, value);
|
||||
bytes.push_back(buf[0]);
|
||||
bytes.push_back(buf[1]);
|
||||
}
|
||||
|
||||
// expects host order
|
||||
void
|
||||
vput32bits(std::vector< byte_t > &bytes, uint32_t value) throw()
|
||||
{
|
||||
char buf[4] = {0};
|
||||
char *write_buffer = buf;
|
||||
htobe32buf(write_buffer, value);
|
||||
bytes.push_back(buf[0]);
|
||||
bytes.push_back(buf[1]);
|
||||
bytes.push_back(buf[2]);
|
||||
bytes.push_back(buf[3]);
|
||||
}
|
||||
|
||||
void
|
||||
dns_writeType(std::vector< byte_t > &bytes, llarp::dns::record *record)
|
||||
{
|
||||
llarp::dns::type_1a *type1a = dynamic_cast< llarp::dns::type_1a * >(record);
|
||||
if(type1a)
|
||||
{
|
||||
std::vector< byte_t > more_bytes = type1a->to_bytes();
|
||||
llarp::LogDebug("[1]Adding ", more_bytes.size());
|
||||
bytes.insert(bytes.end(), more_bytes.begin(), more_bytes.end());
|
||||
}
|
||||
|
||||
llarp::dns::type_2ns *type2ns =
|
||||
dynamic_cast< llarp::dns::type_2ns * >(record);
|
||||
if(type2ns)
|
||||
{
|
||||
std::vector< byte_t > more_bytes = type2ns->to_bytes();
|
||||
llarp::LogDebug("[2]Adding ", more_bytes.size());
|
||||
bytes.insert(bytes.end(), more_bytes.begin(), more_bytes.end());
|
||||
}
|
||||
|
||||
llarp::dns::type_5cname *type5cname =
|
||||
dynamic_cast< llarp::dns::type_5cname * >(record);
|
||||
if(type5cname)
|
||||
{
|
||||
std::vector< byte_t > more_bytes = type5cname->to_bytes();
|
||||
llarp::LogDebug("[5]Adding ", more_bytes.size());
|
||||
bytes.insert(bytes.end(), more_bytes.begin(), more_bytes.end());
|
||||
}
|
||||
|
||||
llarp::dns::type_12ptr *type12ptr =
|
||||
dynamic_cast< llarp::dns::type_12ptr * >(record);
|
||||
if(type12ptr)
|
||||
{
|
||||
std::vector< byte_t > more_bytes = type12ptr->to_bytes();
|
||||
llarp::LogDebug("[12]Adding ", more_bytes.size());
|
||||
bytes.insert(bytes.end(), more_bytes.begin(), more_bytes.end());
|
||||
}
|
||||
llarp::dns::type_15mx *type15mx =
|
||||
dynamic_cast< llarp::dns::type_15mx * >(record);
|
||||
if(type15mx)
|
||||
{
|
||||
std::vector< byte_t > more_bytes = type15mx->to_bytes();
|
||||
llarp::LogDebug("[15]Adding ", more_bytes.size());
|
||||
bytes.insert(bytes.end(), more_bytes.begin(), more_bytes.end());
|
||||
}
|
||||
llarp::dns::type_16txt *type16txt =
|
||||
dynamic_cast< llarp::dns::type_16txt * >(record);
|
||||
if(type16txt)
|
||||
{
|
||||
std::vector< byte_t > more_bytes = type16txt->to_bytes();
|
||||
llarp::LogDebug("[15]Adding ", more_bytes.size());
|
||||
bytes.insert(bytes.end(), more_bytes.begin(), more_bytes.end());
|
||||
}
|
||||
}
|
||||
|
||||
std::vector< byte_t >
|
||||
packet2bytes(dns_packet &in)
|
||||
{
|
||||
std::vector< byte_t > write_buffer;
|
||||
vput16bits(write_buffer, in.header->id);
|
||||
|
||||
int fields = (in.header->qr << 15); // QR => message type, 1 = response
|
||||
fields += (in.header->opcode << 14); // I think opcode is always 0
|
||||
fields += in.header->rcode; // response code (3 => not found, 0 = Ok)
|
||||
vput16bits(write_buffer, fields);
|
||||
|
||||
// don't pull these from the header, trust what we actually have more
|
||||
vput16bits(write_buffer, in.questions.size()); // QD (number of questions)
|
||||
vput16bits(write_buffer, in.answers.size()); // AN (number of answers)
|
||||
// be lazy for now
|
||||
// vput16bits(write_buffer, 0); // NS (number of auth RRs)
|
||||
// vput16bits(write_buffer, 0); // AR (number of Additional
|
||||
vput16bits(write_buffer, in.auth_rrs.size()); // NS (number of auth RRs)
|
||||
vput16bits(write_buffer,
|
||||
in.additional_rrs.size()); // AR (number of Additional RRs)
|
||||
|
||||
// llarp::LogInfo("Header took ", write_buffer.size());
|
||||
|
||||
for(auto &it : in.questions)
|
||||
{
|
||||
// code question
|
||||
vcode_domain(write_buffer, it->name);
|
||||
vput16bits(write_buffer, it->type);
|
||||
vput16bits(write_buffer, it->qClass);
|
||||
}
|
||||
// llarp::LogInfo("Questions finished at ", write_buffer.size());
|
||||
|
||||
// llarp::LogDebug("Starting answers for ", in.questions[0]->name);
|
||||
for(auto &it : in.answers)
|
||||
{
|
||||
// code answers
|
||||
vcode_domain(write_buffer, it->name);
|
||||
vput16bits(write_buffer, it->type);
|
||||
vput16bits(write_buffer, it->aClass);
|
||||
vput32bits(write_buffer, 1); // ttl
|
||||
dns_writeType(write_buffer, it->record.get());
|
||||
}
|
||||
// llarp::LogDebug("Done with answers");
|
||||
// llarp::LogInfo("Answers finished at ", write_buffer.size());
|
||||
|
||||
for(auto &it : in.auth_rrs)
|
||||
{
|
||||
// code answers
|
||||
vcode_domain(write_buffer, it->name);
|
||||
vput16bits(write_buffer, it->type);
|
||||
vput16bits(write_buffer, it->aClass);
|
||||
vput32bits(write_buffer, 1); // ttl
|
||||
dns_writeType(write_buffer, it->record.get());
|
||||
}
|
||||
|
||||
for(auto &it : in.additional_rrs)
|
||||
{
|
||||
// code answers
|
||||
vcode_domain(write_buffer, it->name);
|
||||
vput16bits(write_buffer, it->type);
|
||||
vput16bits(write_buffer, it->aClass);
|
||||
vput32bits(write_buffer, 1); // ttl
|
||||
dns_writeType(write_buffer, it->record.get());
|
||||
}
|
||||
|
||||
return write_buffer;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
@ -212,7 +382,7 @@ extern "C"
|
|||
}
|
||||
*/
|
||||
question->name = m_qName;
|
||||
|
||||
|
||||
question->type = get16bits(moveable);
|
||||
(*pos) += 2;
|
||||
// printf("Now1 at [%d]\n", buffer - start);
|
||||
|
@ -242,9 +412,9 @@ extern "C"
|
|||
// llarp::LogDebug("Advancing to pos ", std::to_string(*pos));
|
||||
moveable += (*pos); // advance to position
|
||||
|
||||
//hexDump(moveable, 12);
|
||||
//hexDumpAt(buffer, *pos, 12);
|
||||
|
||||
// hexDump(moveable, 12);
|
||||
// hexDumpAt(buffer, *pos, 12);
|
||||
|
||||
if(*moveable == '\xc0')
|
||||
{
|
||||
// hexDump(moveable, 2);
|
||||
|
@ -267,10 +437,10 @@ extern "C"
|
|||
/*
|
||||
uint32_t readAt32 = *pos;
|
||||
answer->name = getDNSstring(buffer, &readAt32);
|
||||
llarp::LogInfo("Parsed string ", answer->name, " read ", std::to_string(readAt32));
|
||||
moveable += readAt32; (*pos) += readAt32;
|
||||
llarp::LogInfo("Parsed string ", answer->name, " read ",
|
||||
std::to_string(readAt32)); moveable += readAt32; (*pos) += readAt32;
|
||||
*/
|
||||
//moveable++; (*pos)++;
|
||||
// moveable++; (*pos)++;
|
||||
}
|
||||
/*
|
||||
hexDump(moveable, 10);
|
||||
|
@ -323,6 +493,9 @@ extern "C"
|
|||
*/
|
||||
moveable += answer->rdLen;
|
||||
(*pos) += answer->rdLen; // advance the length
|
||||
|
||||
answer->record.reset(new llarp::dns::type_1a());
|
||||
answer->record->parse(answer->rData);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -330,15 +503,35 @@ extern "C"
|
|||
// FIXME: move this out of here, this shouldn't be responsible for decode
|
||||
switch(answer->type)
|
||||
{
|
||||
case 2: // NS
|
||||
case 2: // NS
|
||||
{
|
||||
std::string ns = getDNSstring(buffer, pos);
|
||||
answer->rData.resize(ns.size());
|
||||
memcpy(answer->rData.data(), ns.c_str(),
|
||||
ns.size()); // raw copy rData
|
||||
|
||||
// don't really need to do anything here
|
||||
moveable += answer->rdLen;
|
||||
(*pos) += answer->rdLen; // advance the length
|
||||
//(*pos) += answer->rdLen; // advance the length
|
||||
|
||||
answer->record.reset(new llarp::dns::type_2ns());
|
||||
answer->record->parse(answer->rData);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
case 5: // CNAME
|
||||
{
|
||||
std::string cname = getDNSstring(buffer, pos);
|
||||
llarp::LogDebug("CNAME ", cname);
|
||||
answer->rData.resize(cname.size());
|
||||
memcpy(answer->rData.data(), cname.c_str(), cname.size());
|
||||
|
||||
moveable += answer->rdLen;
|
||||
(*pos) += answer->rdLen; // advance the length
|
||||
break;
|
||||
//(*pos) += answer->rdLen; // advance the length
|
||||
|
||||
answer->record.reset(new llarp::dns::type_5cname());
|
||||
answer->record->parse(answer->rData);
|
||||
}
|
||||
break;
|
||||
case 6: // type 6 = SOA
|
||||
{
|
||||
// 2 names, then 4x 32bit
|
||||
|
@ -371,12 +564,15 @@ extern "C"
|
|||
{
|
||||
std::string revname = getDNSstring(buffer, pos);
|
||||
llarp::LogInfo("revDNSname: ", revname);
|
||||
//answer->rData = new uint8_t[answer->rdLen + 1];
|
||||
answer->rData.resize(answer->rdLen);
|
||||
memcpy(answer->rData.data(), revname.c_str(), answer->rdLen);
|
||||
//answer->rData = (uint8_t *)strdup(revname.c_str()); // safer? nope
|
||||
// answer->rData = new uint8_t[answer->rdLen + 1];
|
||||
answer->rData.resize(revname.size());
|
||||
memcpy(answer->rData.data(), revname.c_str(), revname.size());
|
||||
// answer->rData = (uint8_t *)strdup(revname.c_str()); // safer? nope
|
||||
moveable += answer->rdLen;
|
||||
//(*pos) += answer->rdLen; // advance the length
|
||||
|
||||
answer->record.reset(new llarp::dns::type_12ptr());
|
||||
answer->record->parse(answer->rData);
|
||||
}
|
||||
break;
|
||||
case 15:
|
||||
|
@ -393,6 +589,9 @@ extern "C"
|
|||
// llarp::LogInfo("leaving at ", std::to_string(*pos));
|
||||
// hexDumpAt(buffer, *pos, 5);
|
||||
// hexDump(moveable, 5);
|
||||
|
||||
answer->record.reset(new llarp::dns::type_15mx());
|
||||
answer->record->parse(answer->rData);
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
|
@ -404,6 +603,9 @@ extern "C"
|
|||
memcpy(answer->rData.data(), moveable + 1, answer->rdLen);
|
||||
moveable += answer->rdLen;
|
||||
(*pos) += answer->rdLen; // advance the length
|
||||
|
||||
answer->record.reset(new llarp::dns::type_16txt());
|
||||
answer->record->parse(answer->rData);
|
||||
}
|
||||
break;
|
||||
// type 28 AAAA
|
||||
|
|
175
llarp/dns_rectypes.cpp
Normal file
175
llarp/dns_rectypes.cpp
Normal file
|
@ -0,0 +1,175 @@
|
|||
#include <llarp/dns_rectypes.hpp>
|
||||
#include <llarp/dns.hpp> // for vput16bits()
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace dns
|
||||
{
|
||||
bool
|
||||
record::parse(std::vector< byte_t > bytes)
|
||||
{
|
||||
return bytes.size() ? true : false;
|
||||
};
|
||||
|
||||
std::vector< byte_t >
|
||||
record::to_bytes()
|
||||
{
|
||||
std::vector< byte_t > retval;
|
||||
return retval;
|
||||
};
|
||||
|
||||
type_1a::type_1a() : record()
|
||||
{
|
||||
this->ipaddr.h = 0;
|
||||
}
|
||||
|
||||
bool
|
||||
type_1a::parse(std::vector< byte_t > bytes)
|
||||
{
|
||||
if(bytes.size() < 4)
|
||||
{
|
||||
LogWarn("Less than 4 bytes passed in");
|
||||
return false;
|
||||
}
|
||||
// endian problems? no, it should come in, in network order
|
||||
/*
|
||||
LogDebug("Read ", std::to_string(bytes[0]), ".",
|
||||
std::to_string(bytes[1]), ".",
|
||||
std::to_string(bytes[2]), ".",
|
||||
std::to_string(bytes[3]));
|
||||
*/
|
||||
this->ipaddr = ipaddr_ipv4_bits(bytes[3], bytes[2], bytes[1], bytes[0]);
|
||||
// LogDebug("Test ", this->ipaddr);
|
||||
return bytes.size() ? true : false;
|
||||
};
|
||||
|
||||
std::vector< byte_t >
|
||||
type_1a::to_bytes()
|
||||
{
|
||||
std::vector< byte_t > retval;
|
||||
vput16bits(retval, 4); // rdLength
|
||||
vput32bits(retval, this->ipaddr.h); // write IP
|
||||
return retval;
|
||||
};
|
||||
|
||||
type_2ns::type_2ns() : record()
|
||||
{
|
||||
this->ns = "";
|
||||
}
|
||||
bool
|
||||
type_2ns::parse(std::vector< byte_t > bytes)
|
||||
{
|
||||
// trim last 2 bytes... probably the size
|
||||
this->ns = std::string((char *)bytes.data(), bytes.size() - 2);
|
||||
return true;
|
||||
};
|
||||
|
||||
std::vector< byte_t >
|
||||
type_2ns::to_bytes()
|
||||
{
|
||||
std::vector< byte_t > retval;
|
||||
vput16bits(retval, 2 + this->ns.length()); // rdLength
|
||||
vcode_domain(retval, this->ns);
|
||||
return retval;
|
||||
};
|
||||
|
||||
type_5cname::type_5cname() : record()
|
||||
{
|
||||
this->cname = "";
|
||||
}
|
||||
|
||||
bool
|
||||
type_5cname::parse(std::vector< byte_t > bytes)
|
||||
{
|
||||
// trim last 2 bytes... probably the size
|
||||
this->cname = std::string((char *)bytes.data(), bytes.size());
|
||||
// LogDebug("type5 parsed ", this->cname);
|
||||
return true;
|
||||
};
|
||||
|
||||
std::vector< byte_t >
|
||||
type_5cname::to_bytes()
|
||||
{
|
||||
std::vector< byte_t > retval;
|
||||
vput16bits(retval, 2 + this->cname.length()); // rdLength
|
||||
vcode_domain(retval, this->cname);
|
||||
return retval;
|
||||
};
|
||||
|
||||
type_12ptr::type_12ptr() : record()
|
||||
{
|
||||
this->revname = "";
|
||||
}
|
||||
|
||||
bool
|
||||
type_12ptr::parse(std::vector< byte_t > bytes)
|
||||
{
|
||||
// trim last 2 bytes... probably the size
|
||||
this->revname = std::string((char *)bytes.data(), bytes.size() - 2);
|
||||
return bytes.size() ? true : false;
|
||||
};
|
||||
|
||||
std::vector< byte_t >
|
||||
type_12ptr::to_bytes()
|
||||
{
|
||||
std::vector< byte_t > retval;
|
||||
// revname has 2 extra bytes at the end we don't want or need
|
||||
vput16bits(retval, 2 + this->revname.length()); // rdLength
|
||||
vcode_domain(retval, this->revname);
|
||||
// vput16bits(retval, this->revname.length()); // rdLength
|
||||
// vcode_domain(retval, this->revname.substr(0, this->revname.size() -
|
||||
// 2));
|
||||
return retval;
|
||||
};
|
||||
|
||||
type_15mx::type_15mx() : record()
|
||||
{
|
||||
this->priority = 99;
|
||||
this->mx = "";
|
||||
}
|
||||
|
||||
bool
|
||||
type_15mx::parse(std::vector< byte_t > bytes)
|
||||
{
|
||||
this->mx = std::string((char *)bytes.data(), bytes.size());
|
||||
// LogInfo("parsed ", this->mx);
|
||||
return true;
|
||||
};
|
||||
|
||||
std::vector< byte_t >
|
||||
type_15mx::to_bytes()
|
||||
{
|
||||
std::vector< byte_t > retval;
|
||||
vput16bits(retval, 2 + (2 + this->mx.length())); // rdLength
|
||||
vput16bits(retval, this->priority); // priority
|
||||
vcode_domain(retval, this->mx);
|
||||
return retval;
|
||||
};
|
||||
|
||||
type_16txt::type_16txt() : record()
|
||||
{
|
||||
this->txt = "";
|
||||
}
|
||||
|
||||
bool
|
||||
type_16txt::parse(std::vector< byte_t > bytes)
|
||||
{
|
||||
this->txt = std::string((char *)bytes.data(), bytes.size() - 1);
|
||||
return true;
|
||||
};
|
||||
|
||||
std::vector< byte_t >
|
||||
type_16txt::to_bytes()
|
||||
{
|
||||
std::vector< byte_t > retval;
|
||||
vput16bits(retval, 1 + this->txt.length()); // rdLength
|
||||
retval.push_back(this->txt.length()); // length
|
||||
for(auto it : this->txt)
|
||||
{
|
||||
retval.push_back(it);
|
||||
}
|
||||
return retval;
|
||||
};
|
||||
|
||||
} // namespace dns
|
||||
} // namespace llarp
|
113
llarp/dnsc.cpp
113
llarp/dnsc.cpp
|
@ -124,6 +124,8 @@ answer_request_alloc(struct dnsc_context *dnsc, void *sock, const char *url,
|
|||
request->question.type = type;
|
||||
request->question.qClass = 1;
|
||||
|
||||
request->packet.header = nullptr;
|
||||
|
||||
// register our self with the tracker
|
||||
dns_tracker *tracker = request->context->tracker;
|
||||
if(!tracker)
|
||||
|
@ -155,14 +157,6 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
|
|||
const struct sockaddr *saddr,
|
||||
const void *buf, ssize_t sz)
|
||||
{
|
||||
// llarp::LogInfo("got a response, udp user is ", udp->user);
|
||||
|
||||
unsigned char *castBuf = (unsigned char *)buf;
|
||||
const char *const castBufc = (const char *)buf;
|
||||
// auto buffer = llarp::StackBuffer< decltype(castBuf) >(castBuf);
|
||||
dns_msg_header *hdr = decode_hdr((const char *)castBuf);
|
||||
|
||||
llarp::LogDebug("Header got client responses for id: ", hdr->id);
|
||||
if(!request)
|
||||
{
|
||||
llarp::LogError(
|
||||
|
@ -170,6 +164,15 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
|
|||
// we can't call back the hook
|
||||
return;
|
||||
}
|
||||
// llarp::LogInfo("got a response, udp user is ", udp->user);
|
||||
|
||||
unsigned char *castBuf = (unsigned char *)buf;
|
||||
const char *const castBufc = (const char *)buf;
|
||||
// auto buffer = llarp::StackBuffer< decltype(castBuf) >(castBuf);
|
||||
dns_msg_header *hdr = decode_hdr((const char *)castBuf);
|
||||
request->packet.header = hdr;
|
||||
|
||||
llarp::LogDebug("Header got client responses for id: ", hdr->id);
|
||||
// llarp_dnsc_unbind(request);
|
||||
|
||||
if(sz < 0)
|
||||
|
@ -224,13 +227,16 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
|
|||
for(uint32_t i = 0; i < hdr->qdCount; i++)
|
||||
{
|
||||
question = decode_question(castBufc, &pos);
|
||||
//llarp::LogDebug("Read a question, now at ", std::to_string(pos));
|
||||
std::unique_ptr< dns_msg_question > unique(question);
|
||||
request->packet.questions.push_back(std::move(unique));
|
||||
// llarp::LogDebug("Read a question, now at ", std::to_string(pos));
|
||||
// 1 dot: 1 byte for length + length
|
||||
// 4 bytes for class/type
|
||||
// castBuf += question->name.length() + 1 + 4;
|
||||
// castBuf += 2; // skip answer label
|
||||
}
|
||||
llarp::LogDebug("Question ", std::to_string(question->type), " ", question->name);
|
||||
llarp::LogDebug("Question ", std::to_string(question->type), " ",
|
||||
question->name);
|
||||
|
||||
// FIXME: only handling one atm
|
||||
std::vector< dns_msg_answer * > answers;
|
||||
|
@ -240,6 +246,8 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
|
|||
// pos = 0; // reset pos
|
||||
answer = decode_answer(castBufc, &pos);
|
||||
answers.push_back(answer);
|
||||
std::unique_ptr< dns_msg_answer > unique(answer);
|
||||
request->packet.answers.push_back(std::move(unique));
|
||||
/*
|
||||
llarp::LogDebug("Read an answer ", answer->type, " for ",
|
||||
request->question.name, ", now at ", std::to_string(pos));
|
||||
|
@ -295,16 +303,31 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
|
|||
{
|
||||
// pos = 0; // reset pos
|
||||
answer = decode_answer(castBufc, &pos);
|
||||
std::unique_ptr< dns_msg_answer > unique(answer);
|
||||
request->packet.auth_rrs.push_back(std::move(unique));
|
||||
// answers.push_back(answer);
|
||||
/*
|
||||
llarp::LogDebug("Read an authority for ",
|
||||
request->question.name, " at ", std::to_string(pos));
|
||||
*/
|
||||
// castBuf += answer->name.length() + 4 + 4 + 4 + answer->rdLen;
|
||||
if(pos > sz)
|
||||
{
|
||||
llarp::LogWarn("Would read past end of dns packet. for ",
|
||||
request->question.name);
|
||||
break;
|
||||
}
|
||||
if(pos > sz)
|
||||
{
|
||||
llarp::LogWarn("Would read past end of dns packet. for ",
|
||||
request->question.name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for(uint32_t i = 0; i < hdr->arCount; i++)
|
||||
{
|
||||
answer = decode_answer(castBufc, &pos);
|
||||
std::unique_ptr< dns_msg_answer > unique(answer);
|
||||
request->packet.additional_rrs.push_back(std::move(unique));
|
||||
/*
|
||||
llarp::LogDebug("Read an addl RR for ",
|
||||
request->question.name, " at ", std::to_string(pos));
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -393,21 +416,35 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
|
|||
|
||||
int ip = 0;
|
||||
|
||||
// if no answer, just bail now
|
||||
if (!answer)
|
||||
{
|
||||
request->found = false;
|
||||
request->resolved(request);
|
||||
return;
|
||||
}
|
||||
|
||||
// if no answer, just bail now
|
||||
if(!answer)
|
||||
{
|
||||
request->found = false;
|
||||
request->resolved(request);
|
||||
return;
|
||||
}
|
||||
|
||||
/* search for and print IPv4 addresses */
|
||||
// if(dnsQuery->reqType == 0x01)
|
||||
/*
|
||||
llarp::LogDebug("request question type: ",
|
||||
std::to_string(request->question.type));
|
||||
*/
|
||||
if(request->question.type == 1)
|
||||
// lets detect this for a bit
|
||||
if(answer->type != question->type)
|
||||
{
|
||||
llarp::LogWarn("Answer type [", std::to_string(answer->type),
|
||||
"] doesn't match question type[",
|
||||
std::to_string(question->type), "]");
|
||||
}
|
||||
// check this assumption
|
||||
if(request->question.type != question->type)
|
||||
{
|
||||
llarp::LogWarn("Request qtype [", std::to_string(request->question.type),
|
||||
"] doesn't match response qtype[",
|
||||
std::to_string(question->type), "]");
|
||||
}
|
||||
if(answer->type == 1)
|
||||
{
|
||||
// llarp::LogInfo("DNS server's answer is: (type#=", ATYPE, "):");
|
||||
llarp::LogDebug("IPv4 address(es) for ", request->question.name, ":");
|
||||
|
@ -460,23 +497,29 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
|
|||
else if(answer->type == 12)
|
||||
{
|
||||
llarp::LogDebug("Resolving PTR");
|
||||
llarp::dns::type_12ptr *record =
|
||||
dynamic_cast< llarp::dns::type_12ptr * >(answer->record.get());
|
||||
request->found = true;
|
||||
request->revDNS =
|
||||
std::string((char *)answer->rData.data(), answer->rData.size());
|
||||
// request->revDNS = std::string((char *)answer->rData.data(),
|
||||
// answer->rData.size());
|
||||
request->revDNS = record->revname;
|
||||
request->resolved(request);
|
||||
return;
|
||||
}
|
||||
else if(request->question.type == 15)
|
||||
else if(answer->type == 15)
|
||||
{
|
||||
llarp::LogDebug("Resolving MX");
|
||||
llarp::dns::type_15mx *record =
|
||||
dynamic_cast< llarp::dns::type_15mx * >(answer->record.get());
|
||||
llarp::LogDebug("Resolving MX ", record->mx, "@", record->priority);
|
||||
request->found = true;
|
||||
request->result.h = 99;
|
||||
request->revDNS =
|
||||
std::string((char *)answer->rData.data(), answer->rData.size());
|
||||
request->result.h = record->priority;
|
||||
// request->revDNS = std::string((char *)answer->rData.data(),
|
||||
// answer->rData.size());
|
||||
request->revDNS = record->mx;
|
||||
request->resolved(request);
|
||||
return;
|
||||
}
|
||||
else if(request->question.type == 16)
|
||||
else if(answer->type == 16)
|
||||
{
|
||||
llarp::LogDebug("Resolving TXT");
|
||||
request->found = true;
|
||||
|
@ -485,12 +528,14 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
|
|||
request->resolved(request);
|
||||
return;
|
||||
}
|
||||
else if(request->question.type == 28)
|
||||
else if(answer->type == 28)
|
||||
{
|
||||
llarp::LogDebug("Resolving AAAA");
|
||||
return;
|
||||
}
|
||||
llarp::LogWarn("Unhandled question type ", request->question.type);
|
||||
// should we let it timeout? lets try sending 404 asap
|
||||
request->resolved(request);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -113,7 +113,7 @@ writecname_dnss_response(std::string cname, const struct sockaddr *from,
|
|||
put32bits(write_buffer, 1); // ttl
|
||||
|
||||
put16bits(write_buffer, cname.length() + 2); // rdLength
|
||||
code_domain(write_buffer, cname); // com, type=6, ttl=0
|
||||
code_domain(write_buffer, cname); //
|
||||
// location of cname
|
||||
//*write_buffer++ = ip[0];
|
||||
//*write_buffer++ = ip[1];
|
||||
|
@ -248,7 +248,7 @@ writesend_dnss_response(llarp::huint32_t *hostRes, const struct sockaddr *from,
|
|||
*/
|
||||
|
||||
uint32_t out_bytes = write_buffer - bufferBegin;
|
||||
llarp::LogDebug("Sending found, ", out_bytes, " bytes");
|
||||
llarp::LogInfo("Sending found, ", out_bytes, " bytes");
|
||||
// struct llarp_udp_io *udp = (struct llarp_udp_io *)request->user;
|
||||
request->sendto_hook(request->user, from, buf, out_bytes);
|
||||
}
|
||||
|
@ -349,6 +349,18 @@ handle_dnsc_result(dnsc_answer_request *client_request)
|
|||
llarp::LogError("Couldn't map client requser user to a server request");
|
||||
return;
|
||||
}
|
||||
|
||||
client_request->packet.header->id = server_request->id;
|
||||
std::vector< byte_t > test = packet2bytes(client_request->packet);
|
||||
// llarp::LogInfo("packet2bytes figures we should send ", test.size(), "
|
||||
// bytes");
|
||||
|
||||
server_request->sendto_hook(server_request->user, server_request->from,
|
||||
test.data(), test.size());
|
||||
|
||||
llarp_host_resolved(client_request);
|
||||
return;
|
||||
|
||||
// llarp::LogDebug("handle_dnsc_result - client request question type",
|
||||
// std::to_string(client_request->question.type));
|
||||
if(client_request->question.type == 12)
|
||||
|
@ -487,6 +499,7 @@ handle_recvfrom(const char *buffer, __attribute__((unused)) ssize_t nbytes,
|
|||
}
|
||||
*/
|
||||
delete fromCopy;
|
||||
// call DNSc
|
||||
if(request->llarp)
|
||||
{
|
||||
// make async request
|
||||
|
|
Loading…
Reference in a new issue