Merge pull request #58 from neuroscr/master

Major DNS refactor
pull/89/head
Jeff 6 years ago committed by GitHub
commit 387d05282b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -419,6 +419,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
@ -493,6 +494,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
)

@ -95,7 +95,10 @@ main(int argc, char *argv[])
// llarp::SetLogLevel(llarp::eLogDebug);
if(1)
bool enableDLL = false;
bool useLlarp = true;
if(enableDLL)
{
// libev version w/router context
ctx = llarp_main_init(conffname, !TESTNET);
@ -163,7 +166,7 @@ main(int argc, char *argv[])
llarp_main_run(ctx);
llarp_main_free(ctx);
}
else if(0)
else if(useLlarp)
{
// libev version
llarp_ev_loop *netloop = nullptr;
@ -268,8 +271,31 @@ main(int argc, char *argv[])
continue;
llarp::LogInfo("Received Bytes ", nbytes);
raw_handle_recvfrom(&m_sockfd, (const struct sockaddr *)&clientAddress,
buffer, nbytes);
llarp_buffer_t lbuffer;
lbuffer.base = (byte_t *)buffer;
lbuffer.cur = lbuffer.base;
lbuffer.sz = nbytes;
dns_msg_header *hdr = decode_hdr(lbuffer);
// if we sent this out, then there's an id
struct dns_tracker *tracker = (struct dns_tracker *)dnsd.client.tracker;
struct dnsc_answer_request *request =
tracker->client_request[hdr->id].get();
if(request)
{
request->packet.header = hdr;
generic_handle_dnsc_recvfrom(tracker->client_request[hdr->id].get(),
lbuffer, hdr);
}
else
{
llarp::LogWarn("Ignoring multiple responses on ID #", hdr->id);
}
// raw_handle_recvfrom(&m_sockfd, (const struct sockaddr *)&clientAddress,
// buffer, nbytes);
}
}

@ -1,15 +1,6 @@
#ifndef LLARP_DNS_H_
#define LLARP_DNS_H_
//#include <llarp/ev.h> // for sockaadr
//#include <sys/types.h> // for uint & ssize_t
// all uint should have been removed in favor of uint_16t
/* non-cygnus does not have this type */
//#ifdef _WIN32
//#define uint UINT
//#endif
#ifdef __cplusplus
extern "C"
{

@ -12,6 +12,15 @@
#endif
#include <llarp/net.hpp> // for llarp::Addr , llarp::huint32_t
#include <llarp/dns_rectypes.hpp>
#define LLARP_DNS_RECTYPE_A 1
#define LLARP_DNS_RECTYPE_NS 2
#define LLARP_DNS_RECTYPE_CNAME 5
#define LLARP_DNS_RECTYPE_SOA 6
#define LLARP_DNS_RECTYPE_PTR 12
#define LLARP_DNS_RECTYPE_MX 15
#define LLARP_DNS_RECTYPE_TXT 16
struct dnsd_context;
@ -73,6 +82,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 +94,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
@ -99,7 +121,7 @@ extern "C"
get32bits(const char *&buffer) throw();
dns_msg_header *
decode_hdr(const char *buffer);
decode_hdr(llarp_buffer_t &buffer);
dns_msg_question *
decode_question(const char *buffer, uint32_t *pos);

@ -2,10 +2,6 @@
#define LIBLLARP_DNS_DOTLOKILOOKUP_HPP
#include <llarp/service/address.hpp>
//#include <llarp/service.hpp>
//#include <llarp/service/endpoint.hpp>
//#include <llarp/handlers/tun.hpp>
//#include <llarp/handlers/tun.hpp>
#include "dnsd.hpp"
@ -38,7 +34,7 @@ struct dotLokiLookup
};
dnsd_query_hook_response *
llarp_dotlokilookup_handler(std::string name, const struct sockaddr *from,
llarp_dotlokilookup_handler(std::string name,
struct dnsd_question_request *const request);
#endif

@ -0,0 +1,134 @@
#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() = 0;
record()
{
}
virtual bool
parse(std::vector< byte_t > bytes) = 0;
virtual std::vector< byte_t >
to_bytes() = 0;
};
struct type_1a : public record
{
huint32_t ipaddr;
virtual ~type_1a(){};
type_1a();
bool
parse(std::vector< byte_t > bytes) override;
std::vector< byte_t >
to_bytes() override;
};
struct type_2ns : public record
{
std::string ns;
virtual ~type_2ns(){};
type_2ns();
bool
parse(std::vector< byte_t > bytes) override;
std::vector< byte_t >
to_bytes() override;
};
struct type_6soa : public record
{
std::string mname;
std::string rname;
uint32_t serial;
uint32_t refresh;
uint32_t retry;
uint32_t expire;
uint32_t minimum;
virtual ~type_6soa(){};
type_6soa();
bool
parse(std::vector< byte_t > bytes) override;
std::vector< byte_t >
to_bytes() override;
};
struct type_5cname : public record
{
std::string cname;
virtual ~type_5cname(){};
type_5cname();
bool
parse(std::vector< byte_t > bytes) override;
std::vector< byte_t >
to_bytes() override;
};
struct type_12ptr : public record
{
std::string revname;
virtual ~type_12ptr(){};
type_12ptr();
bool
parse(std::vector< byte_t > bytes) override;
std::vector< byte_t >
to_bytes() override;
};
struct type_15mx : public record
{
std::string mx;
uint16_t priority;
virtual ~type_15mx(){};
type_15mx();
bool
parse(std::vector< byte_t > bytes) override;
std::vector< byte_t >
to_bytes() override;
};
struct type_16txt : public record
{
std::string txt;
virtual ~type_16txt(){};
type_16txt();
bool
parse(std::vector< byte_t > bytes) override;
std::vector< byte_t >
to_bytes() override;
};
} // 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,17 +32,21 @@ 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;
// llarp::huint32_t result;
// std::string revDNS;
// a reference to dnsc_context incase of multiple contexts
struct dnsc_context *context;
};
@ -59,9 +63,16 @@ llarp_handle_dnsc_recvfrom(struct llarp_udp_io *const udp,
/// because we don't need a callback like recvfrom
/// because we're not evented
/// however daemon/dns expects this
/*
void
raw_handle_recvfrom(int *sockfd, const struct sockaddr *addr, const void *buf,
const ssize_t sz);
*/
// removed saddr, if needed get through request
void
generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
llarp_buffer_t buffer, dns_msg_header *hdr);
/// DNS client context (one needed per upstream DNS server)
struct dnsc_context
@ -78,13 +89,14 @@ struct dnsc_context
struct llarp_logic *logic;
};
/// async resolve a hostname using generic socks
/// async (blocking w/callback) resolve a hostname using generic socks
void
raw_resolve_host(struct dnsc_context *const dnsc, const char *url,
dnsc_answer_hook_func resolved, void *const user,
uint16_t type);
/// async resolve a hostname using llarp platform framework
/// async (non blocking w/callback) resolve a hostname using llarp platform
/// framework
bool
llarp_resolve_host(struct dnsc_context *const dns, const char *url,
dnsc_answer_hook_func resolved, void *const user,

@ -62,27 +62,26 @@ 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,
dnsd_question_request *request);
write404_dnss_response(dnsd_question_request *request);
/// for hook functions to use
void
writecname_dnss_response(std::string cname, const struct sockaddr *from,
dnsd_question_request *request);
writecname_dnss_response(std::string cname, dnsd_question_request *request);
// FIXME: llarp::Addr
/// send an A record found response
void
writesend_dnss_response(llarp::huint32_t *hostRes, const struct sockaddr *from,
writesend_dnss_response(llarp::huint32_t *hostRes,
dnsd_question_request *request);
// FIXME: llarp::Addr
/// send an PTR record found response
void
writesend_dnss_revresponse(std::string reverse, const struct sockaddr *from,
dnsd_question_request *request);
writesend_dnss_revresponse(std::string reverse, dnsd_question_request *request);
// FIXME: llarp::Addr
//
@ -91,8 +90,7 @@ writesend_dnss_revresponse(std::string reverse, const struct sockaddr *from,
/// intercept query hook functor
using intercept_query_hook = std::function< dnsd_query_hook_response *(
std::string name, const struct sockaddr *from,
struct dnsd_question_request *request) >;
std::string name, struct dnsd_question_request *request) >;
// FIXME: llarp::Addr
/// DNS Server context

@ -108,7 +108,7 @@ namespace tl
/// \exclude
#define TL_OPTIONAL_11_CONSTEXPR
#else
/// \exclude
/// \exclude
#define TL_OPTIONAL_11_CONSTEXPR constexpr
#endif

@ -1233,6 +1233,7 @@ UTPSocket::write_outgoing_packet(size_t payload, uint flags,
last_rcv_win = get_rcv_window();
PacketFormatV1 *p1 = (PacketFormatV1 *)pkt->data;
// p1->ver_type; needs to be set!!
p1->set_version(1);
p1->set_type(flags);
p1->ext = 0;

@ -124,10 +124,171 @@ 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)
vput16bits(write_buffer, in.auth_rrs.size()); // NS (number of auth RRs)
vput16bits(write_buffer,
in.additional_rrs.size()); // AR (number of Additional RRs)
for(auto &it : in.questions)
{
// code question
vcode_domain(write_buffer, it->name);
vput16bits(write_buffer, it->type);
vput16bits(write_buffer, it->qClass);
}
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());
}
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"
{
@ -148,13 +309,24 @@ extern "C"
}
dns_msg_header *
decode_hdr(const char *buffer)
decode_hdr(llarp_buffer_t &buffer)
{
dns_msg_header *hdr = new dns_msg_header;
hdr->id = get16bits(buffer);
uint16_t fields = get16bits(buffer);
uint8_t lFields = (fields & 0x00FF) >> 0;
uint8_t hFields = (fields & 0xFF00) >> 8;
uint16_t fields;
// reads as network byte order
llarp_buffer_read_uint16(&buffer, &hdr->id);
llarp_buffer_read_uint16(&buffer, &fields);
llarp_buffer_read_uint16(&buffer, &hdr->qdCount);
llarp_buffer_read_uint16(&buffer, &hdr->anCount);
llarp_buffer_read_uint16(&buffer, &hdr->nsCount);
llarp_buffer_read_uint16(&buffer, &hdr->arCount);
// decode fields into hdr
uint8_t lFields = (fields & 0x00FF) >> 0;
uint8_t hFields = (fields & 0xFF00) >> 8;
// process high byte
// hdr->qr = fields & 0x8000;
hdr->qr = (hFields >> 7) & 0x1;
hdr->opcode = fields & 0x7800;
@ -162,68 +334,32 @@ extern "C"
hdr->tc = fields & 0x0200;
hdr->rd = fields & 0x0100;
// process low byte
hdr->ra = (lFields >> 7) & 0x1;
hdr->z = (lFields >> 6) & 0x1;
hdr->ad = (lFields >> 5) & 0x1;
hdr->cd = (lFields >> 4) & 0x1;
hdr->rcode = lFields & 0xf;
hdr->qdCount = get16bits(buffer);
hdr->anCount = get16bits(buffer);
hdr->nsCount = get16bits(buffer);
hdr->arCount = get16bits(buffer);
return hdr;
}
dns_msg_question *
decode_question(const char *buffer, uint32_t *pos)
{
// char *start = (char *)buffer;
dns_msg_question *question = new dns_msg_question;
// uint32_t start = *pos;
std::string m_qName = getDNSstring(buffer, pos);
llarp::LogDebug("Got question name: ", m_qName);
// llarp::LogInfo("Started at ", std::to_string(start), " ended at: ",
// std::to_string(*pos)); llarp::LogInfo("Advancing question buffer by ",
// std::to_string(*pos)); buffer += (*pos) - start; buffer +=
// m_qName.length() + 2; // + length byte & ending terminator
const char *moveable = buffer;
moveable += *pos; // advance to position
// hexDump(moveable, 4);
// printf("Now0 at [%d]\n", buffer - start);
// buffer += m_qName.size() + 1;
/*
std::string m_qName = "";
int length = *buffer++;
// llarp::LogInfo("qNamLen", length);
while(length != 0)
{
for(int i = 0; i < length; i++)
{
char c = *buffer++;
m_qName.append(1, c);
}
length = *buffer++;
if(length != 0)
m_qName.append(1, '.');
}
*/
question->name = m_qName;
question->type = get16bits(moveable);
(*pos) += 2;
// printf("Now1 at [%d]\n", buffer - start);
question->qClass = get16bits(moveable);
(*pos) += 2;
// printf("Now2 at [%d]\n", buffer - start);
/*
llarp::LogDebug("Type ", std::to_string(question->type), " Class ",
std::to_string(question->qClass));
*/
// hexDump(moveable, 4);
return question;
}
@ -323,6 +459,9 @@ extern "C"
*/
moveable += answer->rdLen;
(*pos) += answer->rdLen; // advance the length
answer->record = std::make_unique< llarp::dns::type_1a >();
answer->record->parse(answer->rData);
}
else
{
@ -330,16 +469,36 @@ extern "C"
// FIXME: move this out of here, this shouldn't be responsible for decode
switch(answer->type)
{
case 2: // NS
case LLARP_DNS_RECTYPE_NS: // 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
break;
case 5:
//(*pos) += answer->rdLen; // advance the length
answer->record = std::make_unique< llarp::dns::type_2ns >();
answer->record->parse(answer->rData);
}
break;
case LLARP_DNS_RECTYPE_CNAME: // 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;
case 6: // type 6 = SOA
//(*pos) += answer->rdLen; // advance the length
answer->record = std::make_unique< llarp::dns::type_5cname >();
answer->record->parse(answer->rData);
}
break;
case LLARP_DNS_RECTYPE_SOA: // type 6 = SOA
{
// 2 names, then 4x 32bit
// why risk any crashes
@ -367,19 +526,22 @@ extern "C"
(*pos) += answer->rdLen; // advance the length
}
break;
case 12:
case LLARP_DNS_RECTYPE_PTR:
{
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.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 = std::make_unique< llarp::dns::type_12ptr >();
answer->record->parse(answer->rData);
}
break;
case 15:
case LLARP_DNS_RECTYPE_MX:
{
uint16_t priority = get16bits(moveable);
(*pos) += 2;
@ -393,9 +555,12 @@ extern "C"
// llarp::LogInfo("leaving at ", std::to_string(*pos));
// hexDumpAt(buffer, *pos, 5);
// hexDump(moveable, 5);
answer->record = std::make_unique< llarp::dns::type_15mx >();
answer->record->parse(answer->rData);
}
break;
case 16:
case LLARP_DNS_RECTYPE_TXT:
{
// hexDump(buffer, 5);
// std::string revname = getDNSstring((char *)buffer);
@ -404,6 +569,9 @@ extern "C"
memcpy(answer->rData.data(), moveable + 1, answer->rdLen);
moveable += answer->rdLen;
(*pos) += answer->rdLen; // advance the length
answer->record = std::make_unique< llarp::dns::type_16txt >();
answer->record->parse(answer->rData);
}
break;
// type 28 AAAA
@ -436,10 +604,14 @@ extern "C"
const struct sockaddr *addr, const void *buf,
ssize_t sz)
{
unsigned char *castBuf = (unsigned char *)buf;
// auto buffer = llarp::StackBuffer< decltype(castBuf) >(castBuf);
dns_msg_header *hdr = decode_hdr((const char *)castBuf);
// castBuf += 12;
// auto abuffer = llarp::StackBuffer< decltype(buf) >(buf);
llarp_buffer_t buffer;
buffer.base = (byte_t *)buf;
buffer.cur = buffer.base;
buffer.sz = sz;
dns_msg_header *hdr = decode_hdr(buffer);
llarp::LogDebug("msg id ", hdr->id);
llarp::LogDebug("msg qr ", (uint8_t)hdr->qr);
if(!udp)
@ -461,23 +633,5 @@ extern "C"
llarp_handle_dnsd_recvfrom(udp, addr, buf, sz);
}
delete hdr;
/*
llarp::LogInfo("msg op ", hdr->opcode);
llarp::LogInfo("msg rc ", hdr->rcode);
for(uint8_t i = 0; i < hdr->qdCount; i++)
{
dns_msg_question *question = decode_question((const char*)castBuf);
llarp::LogInfo("Read a question");
castBuf += question->name.length() + 8;
}
for(uint8_t i = 0; i < hdr->anCount; i++)
{
dns_msg_answer *answer = decode_answer((const char*)castBuf);
llarp::LogInfo("Read an answer");
castBuf += answer->name.length() + 4 + 4 + 4 + answer->rdLen;
}
*/
}
}

@ -23,7 +23,8 @@ random_string(size_t len = 15, std::string const &allowed_chars = default_chars)
struct check_query_simple_request
{
const struct sockaddr *from; // source
// already inside request
// const struct sockaddr *from; // source
dnsd_question_request *request;
};
@ -44,7 +45,7 @@ llarp_dotlokilookup_checkQuery(void *u, __attribute__((unused)) uint64_t orig,
if(!dll)
{
llarp::LogError("DNSd dotLokiLookup is not configured");
write404_dnss_response(qr->from, qr->request);
write404_dnss_response(qr->request);
delete qr;
return;
}
@ -58,7 +59,7 @@ llarp_dotlokilookup_checkQuery(void *u, __attribute__((unused)) uint64_t orig,
{
llarp::LogWarn("Could not base32 decode address: ",
qr->request->question.name);
write404_dnss_response(qr->from, qr->request);
write404_dnss_response(qr->request);
delete qr;
return;
}
@ -85,7 +86,7 @@ llarp_dotlokilookup_checkQuery(void *u, __attribute__((unused)) uint64_t orig,
if(!routerHiddenServiceContext)
{
llarp::LogWarn("dotLokiLookup user isnt a service::Context: ", dll->user);
write404_dnss_response(qr->from, qr->request);
write404_dnss_response(qr->request);
delete qr;
return;
}
@ -95,7 +96,7 @@ llarp_dotlokilookup_checkQuery(void *u, __attribute__((unused)) uint64_t orig,
if(!tunIp->h)
{
llarp::LogWarn("dotLokiLookup failed to map address");
write404_dnss_response(qr->from, qr->request);
write404_dnss_response(qr->request);
delete qr;
return;
}
@ -142,7 +143,7 @@ llarp_dotlokilookup_checkQuery(void *u, __attribute__((unused)) uint64_t orig,
llarp::huint32_t foundAddr;
if(!routerHiddenServiceContext->FindBestAddressFor(addr, foundAddr))
{
write404_dnss_response(qr->from, qr->request);
write404_dnss_response(qr->request);
delete qr;
return;
}
@ -160,7 +161,7 @@ llarp_dotlokilookup_checkQuery(void *u, __attribute__((unused)) uint64_t orig,
// saddr.sin_addr.s_addr = llarp::xhtonl(foundAddr).n;
// FIXME: flush cache to disk
// on crash we'll need to bring up all the same IPs we assigned before...
writesend_dnss_response(&foundAddr, qr->from, qr->request);
writesend_dnss_response(&foundAddr, qr->request);
delete qr;
return;
}
@ -188,7 +189,7 @@ split(std::string str)
struct reverse_handler_iter_context
{
std::string lName;
const struct sockaddr *from;
// const struct sockaddr *from; // aready inside dnsd_question_request
const struct dnsd_question_request *request;
};
@ -260,13 +261,12 @@ ReverseHandlerIter(struct llarp::service::Context::endpoint_iter *endpointCfg)
searchIPv4_fixed);
if(addr.IsZero())
{
write404_dnss_response(context->from,
(dnsd_question_request *)context->request);
write404_dnss_response((dnsd_question_request *)context->request);
}
else
{
// llarp::LogInfo("Returning [", addr.ToString(), "]");
writesend_dnss_revresponse(addr.ToString(), context->from,
writesend_dnss_revresponse(addr.ToString(),
(dnsd_question_request *)context->request);
}
return false;
@ -275,7 +275,7 @@ ReverseHandlerIter(struct llarp::service::Context::endpoint_iter *endpointCfg)
}
dnsd_query_hook_response *
llarp_dotlokilookup_handler(std::string name, const struct sockaddr *from,
llarp_dotlokilookup_handler(std::string name,
struct dnsd_question_request *const request)
{
dnsd_query_hook_response *response = new dnsd_query_hook_response;
@ -303,8 +303,8 @@ llarp_dotlokilookup_handler(std::string name, const struct sockaddr *from,
// which range?
// for each tun interface
struct reverse_handler_iter_context context;
context.lName = lName;
context.from = from;
context.lName = lName;
// context.from = request->from;
context.request = request;
struct llarp::service::Context::endpoint_iter i;
@ -362,8 +362,8 @@ llarp_dotlokilookup_handler(std::string name, const struct sockaddr *from,
// schedule future response
check_query_simple_request *qr = new check_query_simple_request;
qr->from = from;
qr->request = request;
// qr->from = request->from;
qr->request = request;
auto tun = routerHiddenServiceContext->getFirstTun();
if(tun->HasPathToService(addr))

@ -0,0 +1,207 @@
#include <llarp/dns_rectypes.hpp>
#include <llarp/dns.hpp> // for vput16bits()
namespace llarp
{
namespace dns
{
record::~record(){
};
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(){};
bool
type_2ns::parse(std::vector< byte_t > bytes)
{
// trim last 2 bytes... probably the size
this->ns = std::string(reinterpret_cast< 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(){};
bool
type_5cname::parse(std::vector< byte_t > bytes)
{
// trim last 2 bytes... probably the size
this->cname =
std::string(reinterpret_cast< 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_6soa::type_6soa() : record()
{
this->serial = 0;
this->refresh = 0;
this->retry = 0;
this->expire = 0;
this->minimum = 0;
}
bool
type_6soa::parse(std::vector< byte_t > bytes)
{
// FIXME: implmement me
// this->cname = std::string(reinterpret_cast<char *>(bytes.data()),
// bytes.size());
return bytes.size() ? true : false;
};
std::vector< byte_t >
type_6soa::to_bytes()
{
std::vector< byte_t > retval;
vput16bits(
retval,
4 + this->mname.length() + this->rname.length() + 20); // rdLength
vcode_domain(retval, this->mname);
vcode_domain(retval, this->rname);
vput32bits(retval, this->serial);
vput32bits(retval, this->refresh);
vput32bits(retval, this->retry);
vput32bits(retval, this->expire);
vput32bits(retval, this->minimum);
return retval;
};
type_12ptr::type_12ptr() : record(){};
bool
type_12ptr::parse(std::vector< byte_t > bytes)
{
this->revname =
std::string(reinterpret_cast< char* >(bytes.data()), bytes.size());
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;
}
bool
type_15mx::parse(std::vector< byte_t > bytes)
{
this->mx =
std::string(reinterpret_cast< 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(){};
bool
type_16txt::parse(std::vector< byte_t > bytes)
{
this->txt = std::string(reinterpret_cast< 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

@ -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)
@ -151,18 +153,8 @@ answer_request_alloc(struct dnsc_context *dnsc, void *sock, const char *url,
/// generic dnsc handler
void
generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
__attribute__((unused))
const struct sockaddr *saddr,
const void *buf, ssize_t sz)
llarp_buffer_t buffer, dns_msg_header *hdr)
{
// 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,14 +162,15 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
// we can't call back the hook
return;
}
// llarp_dnsc_unbind(request);
// llarp::LogInfo("got a response, udp user is ", udp->user);
if(sz < 0)
{
llarp::LogWarn("Error Receiving DNS Client Response");
request->resolved(request);
return;
}
// unsigned char *castBuf = (unsigned char *)buf;
// const char *const castBufc = (const char *)buf;
// auto buffer = llarp::StackBuffer< decltype(castBuf) >(castBuf);
size_t sz = buffer.sz;
llarp::LogDebug("Header got client responses for id: ", hdr->id);
// llarp_dnsc_unbind(request);
// unsigned char *castBuf = (unsigned char *)buf;
// auto buffer = llarp::StackBuffer< decltype(castBuf) >(castBuf);
@ -203,44 +196,49 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
// rcode = (buffer[3] & 0x0F);
// llarp::LogInfo("dnsc rcode ", rcode);
dns_msg_header *msg = decode_hdr((const char *)castBuf);
castBuf += 12;
llarp::LogDebug("msg id ", msg->id);
uint8_t qr = msg->qr;
// dns_msg_header *msg = decode_hdr((const char *)castBuf);
// dns_msg_header *msg = hdr;
// castBuf += 12;
llarp::LogDebug("msg id ", hdr->id);
uint8_t qr = hdr->qr;
llarp::LogDebug("msg qr ", qr);
uint8_t opcode = msg->opcode;
uint8_t opcode = hdr->opcode;
llarp::LogDebug("msg op ", opcode);
rcode = msg->rcode;
rcode = hdr->rcode;
llarp::LogDebug("msg rc ", rcode);
llarp::LogDebug("msg qdc ", msg->qdCount);
llarp::LogDebug("msg anc ", msg->anCount);
llarp::LogDebug("msg nsc ", msg->nsCount);
llarp::LogDebug("msg arc ", msg->arCount);
llarp::LogDebug("msg qdc ", hdr->qdCount);
llarp::LogDebug("msg anc ", hdr->anCount);
llarp::LogDebug("msg nsc ", hdr->nsCount);
llarp::LogDebug("msg arc ", hdr->arCount);
// FIXME: only handling one atm
uint32_t pos = 12; // just set after header
dns_msg_question *question = nullptr;
for(uint32_t i = 0; i < hdr->qdCount; i++)
{
question = decode_question(castBufc, &pos);
question = decode_question((char *)buffer.base, &pos);
request->packet.questions.emplace_back(question);
// 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);
if(question)
{
llarp::LogDebug("Question ", std::to_string(question->type), " ",
question->name);
}
// FIXME: only handling one atm
std::vector< dns_msg_answer * > answers;
dns_msg_answer *answer = nullptr;
for(uint32_t i = 0; i < hdr->anCount; i++)
{
// pos = 0; // reset pos
answer = decode_answer(castBufc, &pos);
answer = decode_answer((char *)buffer.base, &pos);
answers.push_back(answer);
request->packet.answers.emplace_back(answer);
/*
llarp::LogDebug("Read an answer ", answer->type, " for ",
request->question.name, ", now at ", std::to_string(pos));
@ -295,12 +293,32 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
for(uint32_t i = 0; i < hdr->nsCount; i++)
{
// pos = 0; // reset pos
answer = decode_answer(castBufc, &pos);
answer = decode_answer((char *)buffer.base, &pos);
request->packet.answers.emplace_back(answer);
// answers.push_back(answer);
llarp::LogDebug("Read an authority for ", request->question.name, " at ",
std::to_string(pos));
/*
llarp::LogDebug("Read an authority for ",
request->question.name, " at ", std::to_string(pos));
*/
// castBuf += answer->name.length() + 4 + 4 + 4 + answer->rdLen;
if((size_t)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((char *)buffer.base, &pos);
request->packet.answers.emplace_back(answer);
/*
llarp::LogDebug("Read an addl RR for ",
request->question.name, " at ", std::to_string(pos));
*/
// castBuf += answer->name.length() + 4 + 4 + 4 + answer->rdLen;
if((ssize_t)pos > sz)
if((size_t)pos > sz)
{
llarp::LogWarn("Would read past end of dns packet. for ",
request->question.name);
@ -359,7 +377,10 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
answer = answers.front();
}
llarp::LogDebug("qus type ", question->type);
if(question)
{
llarp::LogDebug("qus type ", question->type);
}
llarp::LogDebug("ans class ", answer->aClass);
llarp::LogDebug("ans type ", answer->type);
@ -408,7 +429,21 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
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, ":");
@ -440,9 +475,11 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
// std::to_string(answer->rData[2]),
// ".", std::to_string(answer->rData[1]), ".",
// std::to_string(answer->rData[0]));
/*
request->result =
llarp::ipaddr_ipv4_bits(answer->rData[3], answer->rData[2],
answer->rData[1], answer->rData[0]);
*/
// llarp::Addr test(request->result);
// llarp::LogDebug(request->result);
@ -461,37 +498,45 @@ 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");
request->found = true;
request->result.h = 99;
request->revDNS =
std::string((char *)answer->rData.data(), answer->rData.size());
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 = 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;
request->revDNS =
std::string((char *)answer->rData.data(), answer->rData.size());
// request->revDNS = std::string((char *)answer->rData.data(),
// answer->rData.size());
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
@ -530,6 +575,7 @@ raw_resolve_host(struct dnsc_context *const dnsc, const char *url,
if(!(sockfd > 0))
{
llarp::LogWarn("Error creating socket!\n");
delete dns_packet;
return;
}
// socket = sockfd;
@ -567,7 +613,11 @@ raw_resolve_host(struct dnsc_context *const dnsc, const char *url,
return;
}
llarp::LogInfo("closing new socket\n");
if(!size)
{
llarp::LogWarn("Error Receiving DNS Client Response");
return;
}
// hexdump("received packet", &buffer, ret);
#ifndef _WIN32
@ -576,15 +626,30 @@ raw_resolve_host(struct dnsc_context *const dnsc, const char *url,
closesocket(sockfd);
#endif
unsigned char *castBuf = (unsigned char *)buffer;
llarp_buffer_t lbuffer;
lbuffer.base = (byte_t *)buffer;
lbuffer.cur = lbuffer.base;
lbuffer.sz = size;
// unsigned char *castBuf = (unsigned char *)buffer;
// auto buffer = llarp::StackBuffer< decltype(castBuf) >(castBuf);
dns_msg_header *hdr = decode_hdr((const char *)castBuf);
dns_msg_header *hdr = decode_hdr(lbuffer);
llarp::LogInfo("response header says it belongs to id #", hdr->id);
// if we sent this out, then there's an id
struct dns_tracker *tracker = (struct dns_tracker *)dnsc->tracker;
generic_handle_dnsc_recvfrom(tracker->client_request[hdr->id].get(), nullptr,
castBuf, size);
struct dns_tracker *tracker = (struct dns_tracker *)dnsc->tracker;
struct dnsc_answer_request *request = tracker->client_request[hdr->id].get();
if(request)
{
request->packet.header = hdr;
generic_handle_dnsc_recvfrom(tracker->client_request[hdr->id].get(),
lbuffer, hdr);
}
else
{
llarp::LogWarn("Ignoring multiple responses on ID #", hdr->id);
}
}
/// intermediate udp_io handler
@ -597,9 +662,21 @@ llarp_handle_dnsc_recvfrom(struct llarp_udp_io *const udp,
{
llarp::LogWarn("saddr isnt set");
}
unsigned char *castBuf = (unsigned char *)buf;
if(sz < 0)
{
llarp::LogWarn("Error Receiving DNS Client Response");
return;
}
llarp_buffer_t buffer;
buffer.base = (byte_t *)buf;
buffer.cur = buffer.base;
buffer.sz = sz;
// unsigned char *castBuf = (unsigned char *)buf;
// auto buffer = llarp::StackBuffer< decltype(castBuf) >(castBuf);
dns_msg_header *hdr = decode_hdr((const char *)castBuf);
dns_msg_header *hdr = decode_hdr(buffer);
buffer.cur = buffer.base; // reset cursor to beginning
llarp::LogDebug("Header got client responses for id: ", hdr->id);
@ -610,7 +687,8 @@ llarp_handle_dnsc_recvfrom(struct llarp_udp_io *const udp,
// sometimes we'll get double responses
if(request)
{
generic_handle_dnsc_recvfrom(request, saddr, buf, sz);
request->packet.header = hdr;
generic_handle_dnsc_recvfrom(request, buffer, hdr);
}
else
{

@ -39,8 +39,7 @@ llarp_sendto_dns_hook_func(void *sock, const struct sockaddr *from,
}
void
write404_dnss_response(const struct sockaddr *from,
dnsd_question_request *request)
write404_dnss_response(dnsd_question_request *request)
{
char buf[BUFFER_SIZE] = {0};
@ -75,12 +74,11 @@ write404_dnss_response(const struct sockaddr *from,
uint32_t out_bytes = write_buffer - bufferBegin;
llarp::LogDebug("Sending 404, ", out_bytes, " bytes");
// struct llarp_udp_io *udp = (struct llarp_udp_io *)request->user;
request->sendto_hook(request->user, from, buf, out_bytes);
request->sendto_hook(request->user, request->from, buf, out_bytes);
}
void
writecname_dnss_response(std::string cname, const struct sockaddr *from,
dnsd_question_request *request)
writecname_dnss_response(std::string cname, dnsd_question_request *request)
{
char buf[BUFFER_SIZE] = {0};
@ -113,7 +111,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];
@ -143,12 +141,11 @@ writecname_dnss_response(std::string cname, const struct sockaddr *from,
uint32_t out_bytes = write_buffer - bufferBegin;
llarp::LogDebug("Sending cname, ", out_bytes, " bytes");
// struct llarp_udp_io *udp = (struct llarp_udp_io *)request->user;
request->sendto_hook(request->user, from, buf, out_bytes);
request->sendto_hook(request->user, request->from, buf, out_bytes);
}
void
writesend_dnss_revresponse(std::string reverse, const struct sockaddr *from,
dnsd_question_request *request)
writesend_dnss_revresponse(std::string reverse, dnsd_question_request *request)
{
char buf[BUFFER_SIZE] = {0};
@ -182,13 +179,13 @@ writesend_dnss_revresponse(std::string reverse, const struct sockaddr *from,
uint32_t out_bytes = write_buffer - bufferBegin;
llarp::LogDebug("Sending reverse: ", reverse, " ", out_bytes, " bytes");
// struct llarp_udp_io *udp = (struct llarp_udp_io *)request->user;
request->sendto_hook(request->user, from, buf, out_bytes);
request->sendto_hook(request->user, request->from, buf, out_bytes);
}
// FIXME: we need an DNS answer not a sockaddr
// otherwise ttl, type and class can't be relayed correctly
void
writesend_dnss_response(llarp::huint32_t *hostRes, const struct sockaddr *from,
writesend_dnss_response(llarp::huint32_t *hostRes,
dnsd_question_request *request)
{
// llarp::Addr test(*from);
@ -196,7 +193,7 @@ writesend_dnss_response(llarp::huint32_t *hostRes, const struct sockaddr *from,
if(!hostRes)
{
llarp::LogWarn("Failed to resolve ", request->question.name);
write404_dnss_response(from, request);
write404_dnss_response(request);
return;
}
@ -250,7 +247,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");
// struct llarp_udp_io *udp = (struct llarp_udp_io *)request->user;
request->sendto_hook(request->user, from, buf, out_bytes);
request->sendto_hook(request->user, request->from, buf, out_bytes);
}
void
@ -349,8 +346,22 @@ 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; // stomp 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)
{
writesend_dnss_revresponse(client_request->revDNS, server_request->from,
@ -380,20 +391,20 @@ handle_dnsc_result(dnsc_answer_request *client_request)
writesend_dnss_response(useHostRes, server_request->from, server_request);
}
llarp_host_resolved(client_request);
*/
}
// our generic version
void
handle_recvfrom(const char *buffer, __attribute__((unused)) ssize_t nbytes,
const struct sockaddr *from, dnsd_question_request *request)
handle_recvfrom(llarp_buffer_t buffer, dnsd_question_request *request)
{
const size_t HDR_OFFSET = 12;
const char *p_buffer = buffer;
const char *p_buffer = (const char *)buffer.base;
int rcode = (buffer[3] & 0x0F);
llarp::LogDebug("dnsd rcode ", rcode);
dns_msg_header *msg = decode_hdr(p_buffer);
dns_msg_header *msg = decode_hdr(buffer);
p_buffer += HDR_OFFSET;
request->id = msg->id;
std::string m_qName = "";
@ -424,8 +435,8 @@ handle_recvfrom(const char *buffer, __attribute__((unused)) ssize_t nbytes,
llarp::LogInfo("DNS request from ", test2);
*/
sockaddr *fromCopy =
new sockaddr(*from); // make our own sockaddr that won't get cleaned up
// sockaddr *fromCopy = new sockaddr(*from); // make our own sockaddr that
// won't get cleaned up
if(!request)
{
llarp::LogError("request is not configured");
@ -441,7 +452,7 @@ handle_recvfrom(const char *buffer, __attribute__((unused)) ssize_t nbytes,
// llarp::Addr test(*from);
// llarp::LogInfo("from ", test);
dnsd_query_hook_response *intercept =
request->context->intercept(request->question.name, fromCopy, request);
request->context->intercept(request->question.name, request);
// if(!forward_dns_request(m_qName))
if(intercept != nullptr)
{
@ -455,7 +466,7 @@ handle_recvfrom(const char *buffer, __attribute__((unused)) ssize_t nbytes,
{
llarp::LogDebug("HOOKED: sending an immediate override");
// told that hook will handle overrides
writesend_dnss_response(intercept->returnThis, fromCopy, request);
writesend_dnss_response(intercept->returnThis, request);
return;
}
}
@ -465,7 +476,7 @@ handle_recvfrom(const char *buffer, __attribute__((unused)) ssize_t nbytes,
if(!request->context)
{
llarp::LogError("dnsd request context was not a dnsd context");
writesend_dnss_response(nullptr, fromCopy, request);
writesend_dnss_response(nullptr, request);
return;
}
/*
@ -486,7 +497,8 @@ handle_recvfrom(const char *buffer, __attribute__((unused)) ssize_t nbytes,
return;
}
*/
delete fromCopy;
// delete fromCopy;
// call DNSc
if(request->llarp)
{
// make async request
@ -524,12 +536,17 @@ llarp_handle_dnsd_recvfrom(struct llarp_udp_io *udp,
&llarp_sendto_dns_hook_func; // set sock hook
// llarp::LogInfo("Server request's UDP ", llarp_dns_request->user);
handle_recvfrom((char *)buf, sz, llarp_dns_request->from, llarp_dns_request);
llarp_buffer_t buffer;
buffer.base = (byte_t *)buf;
buffer.cur = buffer.base;
buffer.sz = sz;
handle_recvfrom(buffer, llarp_dns_request);
}
void
raw_handle_recvfrom(int *sockfd, const struct sockaddr *saddr, const void *buf,
ssize_t sz)
raw_handle_recvfrom(int *sockfd, const struct sockaddr *saddr,
llarp_buffer_t buffer)
{
if(!dns_udp_tracker.dnsd)
{
@ -543,7 +560,8 @@ raw_handle_recvfrom(int *sockfd, const struct sockaddr *saddr, const void *buf,
llarp_dns_request->user = (void *)sockfd;
llarp_dns_request->llarp = false;
llarp_dns_request->sendto_hook = &raw_sendto_dns_hook_func;
handle_recvfrom((char *)buf, sz, llarp_dns_request->from, llarp_dns_request);
handle_recvfrom(buffer, llarp_dns_request);
}
bool

@ -309,10 +309,10 @@ namespace llarp
if(wantInternet && !m_PermitExit)
return false;
huint32_t ip = GetIPForIdent(pk);
m_ActiveExits.insert(std::make_pair(
pk,
std::unique_ptr< llarp::exit::Endpoint >(
new llarp::exit::Endpoint(pk, path, !wantInternet, ip, this))));
m_ActiveExits.insert(
std::make_pair(pk,
std::make_unique< llarp::exit::Endpoint >(
pk, path, !wantInternet, ip, this)));
m_Paths[path] = pk;
return HasLocalMappedAddrFor(pk);
}
@ -364,4 +364,4 @@ namespace llarp
}
}
} // namespace handlers
} // namespace llarp
} // namespace llarp

@ -114,8 +114,26 @@ namespace llarp
}
bool
Addr::from_char_array(const char* str)
Addr::from_char_array(const char* in)
{
char* str = (char*)in;
char* pPosition = strchr(str, ':');
bool freeStr = false;
if(pPosition)
{
// parse port
char buf[6];
snprintf(buf, 6, "%s", pPosition + 1);
uint16_t port = std::atoi(buf);
llarp::LogDebug("Setting port ", std::to_string(port));
this->port(port);
// trim str
// can't VLA
str = strdup(in); // copy it
str[pPosition - in] = '\0'; // nul terminate it early
llarp::LogDebug("Truncating to ", str);
freeStr = true;
}
llarp::Zero(&_addr, sizeof(sockaddr_in6));
struct addrinfo hint, *res = NULL;
int ret;
@ -129,17 +147,23 @@ namespace llarp
if(ret)
{
llarp::LogError("failed to determine address family: ", str);
if(freeStr)
free(str);
return false;
}
if(res->ai_family == AF_INET6)
{
llarp::LogError("IPv6 address not supported yet", str);
if(freeStr)
free(str);
return false;
}
else if(res->ai_family != AF_INET)
{
llarp::LogError("Address family not supported yet", str);
if(freeStr)
free(str);
return false;
}
@ -148,8 +172,12 @@ namespace llarp
if(inet_aton(str, addr) == 0)
{
llarp::LogError("failed to parse ", str);
if(freeStr)
free(str);
return false;
}
if(freeStr)
free(str);
_addr.sin6_family = res->ai_family;
_addr4.sin_family = res->ai_family;

@ -28,9 +28,13 @@ struct DNSTest : public ::testing::Test
// extra
0x00 // null terminator (probably don't need this, just added it)
};
llarp_buffer_t buffer_t;
DNSTest()
{
this->buffer_t.base = (byte_t *)this->buf;
this->buffer_t.cur = buffer_t.base;
this->buffer_t.sz = 47;
}
void
@ -87,7 +91,8 @@ TEST_F(DNSTest, TestCodeDomain)
// test decoders
TEST_F(DNSTest, TestDecodeHdr)
{
dns_msg_header *hdr = decode_hdr((char *)this->buf);
dns_msg_header *hdr = decode_hdr(this->buffer_t);
/*
printf("id[%d]", hdr->id);
printf("qr[%d]", hdr->qr);

@ -50,7 +50,7 @@ struct llarpDNSdTest : public ::testing::Test
TEST_F(llarpDNSdTest, TestNxDomain)
{
write404_dnss_response(nullptr, &test_request);
write404_dnss_response(&test_request);
ASSERT_TRUE(g_length == 55);
std::string expected_output =
"00 00 FFF03 00 01 00 01 00 00 00 00 04 6C 6F 6B 69 07 6E 65 74 77 6F 72 "
@ -65,7 +65,7 @@ TEST_F(llarpDNSdTest, TestAResponse)
llarp::Zero(&hostRes.h, sizeof(uint32_t));
// sockaddr hostRes;
// llarp::Zero(&hostRes, sizeof(sockaddr));
writesend_dnss_response(&hostRes, nullptr, &test_request);
writesend_dnss_response(&hostRes, &test_request);
ASSERT_TRUE(g_length == 58);
std::string expected_output =
"00 00 FFF00 00 01 00 01 00 00 00 00 04 6C 6F 6B 69 07 6E 65 74 77 6F 72 "
@ -76,7 +76,7 @@ TEST_F(llarpDNSdTest, TestAResponse)
TEST_F(llarpDNSdTest, TestPTRResponse)
{
writesend_dnss_revresponse("loki.network", nullptr, &test_request);
writesend_dnss_revresponse("loki.network", &test_request);
ASSERT_TRUE(g_length == 68);
std::string expected_output =
"00 00 FFF00 00 01 00 01 00 00 00 00 04 6C 6F 6B 69 07 6E 65 74 77 6F 72 "
@ -87,7 +87,7 @@ TEST_F(llarpDNSdTest, TestPTRResponse)
TEST_F(llarpDNSdTest, TestCname)
{
writecname_dnss_response("test.cname", nullptr, &test_request);
writecname_dnss_response("test.cname", &test_request);
ASSERT_TRUE(g_length == 122);
std::string expected_output =
"00 00 FFF00 00 01 00 01 00 01 00 01 04 6C 6F 6B 69 07 6E 65 74 77 6F 72 "

Loading…
Cancel
Save