Merge remote-tracking branch 'origin/master'

This commit is contained in:
Jeff Becker 2018-11-28 08:30:35 -05:00
commit 53434e28cf
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05
26 changed files with 954 additions and 246 deletions

View File

@ -421,6 +421,7 @@ set(LIB_SRC
llarp/context.cpp llarp/context.cpp
llarp/crypto_libsodium.cpp llarp/crypto_libsodium.cpp
llarp/dht.cpp llarp/dht.cpp
llarp/dns_rectypes.cpp
llarp/dns.cpp llarp/dns.cpp
llarp/dnsc.cpp llarp/dnsc.cpp
llarp/dnsd.cpp llarp/dnsd.cpp
@ -495,6 +496,7 @@ set(DNS_SRC
llarp/dnsd.cpp llarp/dnsd.cpp
llarp/dns_iptracker.cpp llarp/dns_iptracker.cpp
llarp/dns_dotlokilookup.cpp llarp/dns_dotlokilookup.cpp
llarp/dns_rectypes.cpp
llarp/net.cpp llarp/net.cpp
daemon/dns.cpp daemon/dns.cpp
) )

View File

@ -5,6 +5,6 @@ installing deps:
sudo apt install libsodium-dev sudo apt install libsodium-dev
pip3 install --user -r requirements.txt pip3 install --user -r requirements.txt
to generate a nonce with a prefix `^loki` using 8 cpu threads: to generate a nonce with a prefix `^7oki` using 8 cpu threads:
python3 lokinet-vanity.py keyfile.private loki 8 python3 lokinet-vanity.py keyfile.private 7oki 8

View File

@ -95,7 +95,10 @@ main(int argc, char *argv[])
// llarp::SetLogLevel(llarp::eLogDebug); // llarp::SetLogLevel(llarp::eLogDebug);
if(1) bool enableDLL = false;
bool useLlarp = true;
if(enableDLL)
{ {
// libev version w/router context // libev version w/router context
ctx = llarp_main_init(conffname, !TESTNET); ctx = llarp_main_init(conffname, !TESTNET);
@ -163,7 +166,7 @@ main(int argc, char *argv[])
llarp_main_run(ctx); llarp_main_run(ctx);
llarp_main_free(ctx); llarp_main_free(ctx);
} }
else if(0) else if(useLlarp)
{ {
// libev version // libev version
llarp_ev_loop *netloop = nullptr; llarp_ev_loop *netloop = nullptr;
@ -268,8 +271,31 @@ main(int argc, char *argv[])
continue; continue;
llarp::LogInfo("Received Bytes ", nbytes); llarp::LogInfo("Received Bytes ", nbytes);
raw_handle_recvfrom(&m_sockfd, (const struct sockaddr *)&clientAddress, llarp_buffer_t lbuffer;
buffer, nbytes); 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);
} }
} }

View File

@ -19,7 +19,7 @@ extern "C"
} }
namespace llarp namespace llarp
{ {
/// aligned buffer, aligns to the nears Long_t /// aligned buffer that is sz bytes long and aligns to the nears Long_t
template < size_t sz, bool randomize = false, typename Long_t = uint64_t > template < size_t sz, bool randomize = false, typename Long_t = uint64_t >
struct AlignedBuffer struct AlignedBuffer
{ {

View File

@ -1,15 +1,6 @@
#ifndef LLARP_DNS_H_ #ifndef LLARP_DNS_H_
#define 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 #ifdef __cplusplus
extern "C" extern "C"
{ {

View File

@ -12,6 +12,15 @@
#endif #endif
#include <llarp/net.hpp> // for llarp::Addr , llarp::huint32_t #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; struct dnsd_context;
@ -73,6 +82,7 @@ struct dns_msg_answer
uint32_t ttl; uint32_t ttl;
uint16_t rdLen; uint16_t rdLen;
std::vector< byte_t > rData; std::vector< byte_t > rData;
std::unique_ptr< llarp::dns::record > record;
}; };
struct dns_packet struct dns_packet
@ -84,12 +94,24 @@ struct dns_packet
std::vector< std::unique_ptr< dns_msg_answer > > additional_rrs; std::vector< std::unique_ptr< dns_msg_answer > > additional_rrs;
}; };
std::vector< byte_t >
packet2bytes(dns_packet &in);
std::string std::string
getDNSstring(const char *const buffer, uint32_t *pos); getDNSstring(const char *const buffer, uint32_t *pos);
void void
code_domain(char *&buffer, const std::string &domain) throw(); 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" extern "C"
{ {
uint16_t uint16_t
@ -99,7 +121,7 @@ extern "C"
get32bits(const char *&buffer) throw(); get32bits(const char *&buffer) throw();
dns_msg_header * dns_msg_header *
decode_hdr(const char *buffer); decode_hdr(llarp_buffer_t &buffer);
dns_msg_question * dns_msg_question *
decode_question(const char *buffer, uint32_t *pos); decode_question(const char *buffer, uint32_t *pos);

View File

@ -2,10 +2,6 @@
#define LIBLLARP_DNS_DOTLOKILOOKUP_HPP #define LIBLLARP_DNS_DOTLOKILOOKUP_HPP
#include <llarp/service/address.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" #include "dnsd.hpp"
@ -38,7 +34,7 @@ struct dotLokiLookup
}; };
dnsd_query_hook_response * 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); struct dnsd_question_request *const request);
#endif #endif

View File

@ -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

View File

@ -15,8 +15,8 @@ struct dnsc_answer_request;
struct dns_query struct dns_query
{ {
uint16_t length; uint16_t length;
// char *url;
unsigned char request[DNC_BUF_SIZE]; unsigned char request[DNC_BUF_SIZE];
// char *url;
// uint16_t reqType; // uint16_t reqType;
}; };
@ -32,17 +32,21 @@ typedef void (*dnsc_answer_hook_func)(dnsc_answer_request *request);
struct dnsc_answer_request struct dnsc_answer_request
{ {
/// sock type /// sock type
void *sock; // pts to udp... void *sock; // points to udp that sent the request to DNSc...
/// customizable (used for hook (outer request)) /// customizable (used for hook (outer request))
void *user; void *user;
/// storage /// request storage
dns_msg_question question; dns_msg_question question;
/// response storage
dns_packet packet;
/// hook /// hook
dnsc_answer_hook_func resolved; dnsc_answer_hook_func resolved;
/// result /// result
bool found; 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 // a reference to dnsc_context incase of multiple contexts
struct dnsc_context *context; 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 don't need a callback like recvfrom
/// because we're not evented /// because we're not evented
/// however daemon/dns expects this /// however daemon/dns expects this
/*
void void
raw_handle_recvfrom(int *sockfd, const struct sockaddr *addr, const void *buf, raw_handle_recvfrom(int *sockfd, const struct sockaddr *addr, const void *buf,
const ssize_t sz); 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) /// DNS client context (one needed per upstream DNS server)
struct dnsc_context struct dnsc_context
@ -78,13 +89,14 @@ struct dnsc_context
struct llarp_logic *logic; struct llarp_logic *logic;
}; };
/// async resolve a hostname using generic socks /// async (blocking w/callback) resolve a hostname using generic socks
void void
raw_resolve_host(struct dnsc_context *const dnsc, const char *url, raw_resolve_host(struct dnsc_context *const dnsc, const char *url,
dnsc_answer_hook_func resolved, void *const user, dnsc_answer_hook_func resolved, void *const user,
uint16_t type); uint16_t type);
/// async resolve a hostname using llarp platform framework /// async (non blocking w/callback) resolve a hostname using llarp platform
/// framework
bool bool
llarp_resolve_host(struct dnsc_context *const dns, const char *url, llarp_resolve_host(struct dnsc_context *const dns, const char *url,
dnsc_answer_hook_func resolved, void *const user, dnsc_answer_hook_func resolved, void *const user,

View File

@ -62,27 +62,26 @@ llarp_handle_dnsd_recvfrom(struct llarp_udp_io *udp,
// we may want to pass dnsd_question_request to these, // we may want to pass dnsd_question_request to these,
// incase we need to send an error back up through the pipeline // incase we need to send an error back up through the pipeline
// FIXME: just use the from in the request
/// NXDOMAIN not found /// NXDOMAIN not found
void void
write404_dnss_response(const struct sockaddr *from, write404_dnss_response(dnsd_question_request *request);
dnsd_question_request *request);
/// for hook functions to use /// for hook functions to use
void void
writecname_dnss_response(std::string cname, const struct sockaddr *from, writecname_dnss_response(std::string cname, dnsd_question_request *request);
dnsd_question_request *request);
// FIXME: llarp::Addr // FIXME: llarp::Addr
/// send an A record found response /// send an A record found response
void void
writesend_dnss_response(llarp::huint32_t *hostRes, const struct sockaddr *from, writesend_dnss_response(llarp::huint32_t *hostRes,
dnsd_question_request *request); dnsd_question_request *request);
// FIXME: llarp::Addr // FIXME: llarp::Addr
/// send an PTR record found response /// send an PTR record found response
void void
writesend_dnss_revresponse(std::string reverse, const struct sockaddr *from, writesend_dnss_revresponse(std::string reverse, dnsd_question_request *request);
dnsd_question_request *request);
// FIXME: llarp::Addr // FIXME: llarp::Addr
// //
@ -91,8 +90,7 @@ writesend_dnss_revresponse(std::string reverse, const struct sockaddr *from,
/// intercept query hook functor /// intercept query hook functor
using intercept_query_hook = std::function< dnsd_query_hook_response *( using intercept_query_hook = std::function< dnsd_query_hook_response *(
std::string name, const struct sockaddr *from, std::string name, struct dnsd_question_request *request) >;
struct dnsd_question_request *request) >;
// FIXME: llarp::Addr // FIXME: llarp::Addr
/// DNS Server context /// DNS Server context

View File

@ -35,6 +35,10 @@ namespace llarp
bool bool
ExpiresSoon(llarp_time_t now, llarp_time_t dlt = 5000) const; ExpiresSoon(llarp_time_t now, llarp_time_t dlt = 5000) const;
/// return true if this endpoint looks dead right now
bool
LooksDead(llarp_time_t now, llarp_time_t timeout = 10000) const;
/// tick ourself, reset tx/rx rates /// tick ourself, reset tx/rx rates
void void
Tick(llarp_time_t now); Tick(llarp_time_t now);
@ -92,6 +96,7 @@ namespace llarp
llarp::PathID_t m_CurrentPath; llarp::PathID_t m_CurrentPath;
llarp::huint32_t m_IP; llarp::huint32_t m_IP;
uint64_t m_TxRate, m_RxRate; uint64_t m_TxRate, m_RxRate;
llarp_time_t m_LastActive;
bool m_RewriteSource; bool m_RewriteSource;
}; };
} // namespace exit } // namespace exit

View File

@ -44,6 +44,9 @@ namespace llarp
llarp_router* llarp_router*
Router(); Router();
llarp_time_t
Now() const;
llarp_crypto* llarp_crypto*
Crypto(); Crypto();

View File

@ -13,9 +13,10 @@ namespace llarp
private: private:
llarp::PubKey enckey; llarp::PubKey enckey;
llarp::PubKey signkey; llarp::PubKey signkey;
VanityNonce vanity;
public: public:
VanityNonce vanity;
ServiceInfo() = default; ServiceInfo() = default;
ServiceInfo(ServiceInfo&& other) ServiceInfo(ServiceInfo&& other)
@ -57,10 +58,12 @@ namespace llarp
} }
bool bool
Update(const byte_t* enc, const byte_t* sign) Update(const byte_t* enc, const byte_t* sign, const byte_t * nonce=nullptr)
{ {
enckey = enc; enckey = enc;
signkey = sign; signkey = sign;
if(nonce)
vanity = nonce;
return UpdateAddr(); return UpdateAddr();
} }

View File

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

View File

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

View File

@ -124,10 +124,171 @@ code_domain(char *&buffer, const std::string &domain) throw()
*buffer++ = 0; *buffer++ = 0;
} }
// lets just remove uint void
#ifdef _WIN32 vcode_domain(std::vector< byte_t > &bytes, const std::string &domain) throw()
#define uint UINT {
#endif 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" extern "C"
{ {
@ -148,13 +309,24 @@ extern "C"
} }
dns_msg_header * dns_msg_header *
decode_hdr(const char *buffer) decode_hdr(llarp_buffer_t &buffer)
{ {
dns_msg_header *hdr = new dns_msg_header; dns_msg_header *hdr = new dns_msg_header;
hdr->id = get16bits(buffer); uint16_t fields;
uint16_t fields = get16bits(buffer);
uint8_t lFields = (fields & 0x00FF) >> 0; // reads as network byte order
uint8_t hFields = (fields & 0xFF00) >> 8; 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 = fields & 0x8000;
hdr->qr = (hFields >> 7) & 0x1; hdr->qr = (hFields >> 7) & 0x1;
hdr->opcode = fields & 0x7800; hdr->opcode = fields & 0x7800;
@ -162,68 +334,32 @@ extern "C"
hdr->tc = fields & 0x0200; hdr->tc = fields & 0x0200;
hdr->rd = fields & 0x0100; hdr->rd = fields & 0x0100;
// process low byte
hdr->ra = (lFields >> 7) & 0x1; hdr->ra = (lFields >> 7) & 0x1;
hdr->z = (lFields >> 6) & 0x1; hdr->z = (lFields >> 6) & 0x1;
hdr->ad = (lFields >> 5) & 0x1; hdr->ad = (lFields >> 5) & 0x1;
hdr->cd = (lFields >> 4) & 0x1; hdr->cd = (lFields >> 4) & 0x1;
hdr->rcode = lFields & 0xf; hdr->rcode = lFields & 0xf;
hdr->qdCount = get16bits(buffer);
hdr->anCount = get16bits(buffer);
hdr->nsCount = get16bits(buffer);
hdr->arCount = get16bits(buffer);
return hdr; return hdr;
} }
dns_msg_question * dns_msg_question *
decode_question(const char *buffer, uint32_t *pos) decode_question(const char *buffer, uint32_t *pos)
{ {
// char *start = (char *)buffer;
dns_msg_question *question = new dns_msg_question; dns_msg_question *question = new dns_msg_question;
// uint32_t start = *pos;
std::string m_qName = getDNSstring(buffer, pos); std::string m_qName = getDNSstring(buffer, pos);
llarp::LogDebug("Got question name: ", m_qName); 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; const char *moveable = buffer;
moveable += *pos; // advance to position 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->name = m_qName;
question->type = get16bits(moveable); question->type = get16bits(moveable);
(*pos) += 2; (*pos) += 2;
// printf("Now1 at [%d]\n", buffer - start);
question->qClass = get16bits(moveable); question->qClass = get16bits(moveable);
(*pos) += 2; (*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; return question;
} }
@ -323,6 +459,9 @@ extern "C"
*/ */
moveable += answer->rdLen; moveable += answer->rdLen;
(*pos) += answer->rdLen; // advance the length (*pos) += answer->rdLen; // advance the length
answer->record = std::make_unique< llarp::dns::type_1a >();
answer->record->parse(answer->rData);
} }
else else
{ {
@ -330,16 +469,36 @@ extern "C"
// FIXME: move this out of here, this shouldn't be responsible for decode // FIXME: move this out of here, this shouldn't be responsible for decode
switch(answer->type) 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 // don't really need to do anything here
moveable += answer->rdLen; moveable += answer->rdLen;
(*pos) += answer->rdLen; // advance the length //(*pos) += answer->rdLen; // advance the length
break;
case 5: 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; moveable += answer->rdLen;
(*pos) += answer->rdLen; // advance the length //(*pos) += answer->rdLen; // advance the length
break;
case 6: // type 6 = SOA 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 // 2 names, then 4x 32bit
// why risk any crashes // why risk any crashes
@ -367,19 +526,22 @@ extern "C"
(*pos) += answer->rdLen; // advance the length (*pos) += answer->rdLen; // advance the length
} }
break; break;
case 12: case LLARP_DNS_RECTYPE_PTR:
{ {
std::string revname = getDNSstring(buffer, pos); std::string revname = getDNSstring(buffer, pos);
llarp::LogInfo("revDNSname: ", revname); llarp::LogInfo("revDNSname: ", revname);
// answer->rData = new uint8_t[answer->rdLen + 1]; // answer->rData = new uint8_t[answer->rdLen + 1];
answer->rData.resize(answer->rdLen); answer->rData.resize(revname.size());
memcpy(answer->rData.data(), revname.c_str(), answer->rdLen); memcpy(answer->rData.data(), revname.c_str(), revname.size());
// answer->rData = (uint8_t *)strdup(revname.c_str()); // safer? nope // answer->rData = (uint8_t *)strdup(revname.c_str()); // safer? nope
moveable += answer->rdLen; moveable += answer->rdLen;
//(*pos) += answer->rdLen; // advance the length //(*pos) += answer->rdLen; // advance the length
answer->record = std::make_unique< llarp::dns::type_12ptr >();
answer->record->parse(answer->rData);
} }
break; break;
case 15: case LLARP_DNS_RECTYPE_MX:
{ {
uint16_t priority = get16bits(moveable); uint16_t priority = get16bits(moveable);
(*pos) += 2; (*pos) += 2;
@ -393,9 +555,12 @@ extern "C"
// llarp::LogInfo("leaving at ", std::to_string(*pos)); // llarp::LogInfo("leaving at ", std::to_string(*pos));
// hexDumpAt(buffer, *pos, 5); // hexDumpAt(buffer, *pos, 5);
// hexDump(moveable, 5); // hexDump(moveable, 5);
answer->record = std::make_unique< llarp::dns::type_15mx >();
answer->record->parse(answer->rData);
} }
break; break;
case 16: case LLARP_DNS_RECTYPE_TXT:
{ {
// hexDump(buffer, 5); // hexDump(buffer, 5);
// std::string revname = getDNSstring((char *)buffer); // std::string revname = getDNSstring((char *)buffer);
@ -404,6 +569,9 @@ extern "C"
memcpy(answer->rData.data(), moveable + 1, answer->rdLen); memcpy(answer->rData.data(), moveable + 1, answer->rdLen);
moveable += answer->rdLen; moveable += answer->rdLen;
(*pos) += answer->rdLen; // advance the length (*pos) += answer->rdLen; // advance the length
answer->record = std::make_unique< llarp::dns::type_16txt >();
answer->record->parse(answer->rData);
} }
break; break;
// type 28 AAAA // type 28 AAAA
@ -436,10 +604,14 @@ extern "C"
const struct sockaddr *addr, const void *buf, const struct sockaddr *addr, const void *buf,
ssize_t sz) ssize_t sz)
{ {
unsigned char *castBuf = (unsigned char *)buf; // auto abuffer = llarp::StackBuffer< decltype(buf) >(buf);
// auto buffer = llarp::StackBuffer< decltype(castBuf) >(castBuf);
dns_msg_header *hdr = decode_hdr((const char *)castBuf); llarp_buffer_t buffer;
// castBuf += 12; 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 id ", hdr->id);
llarp::LogDebug("msg qr ", (uint8_t)hdr->qr); llarp::LogDebug("msg qr ", (uint8_t)hdr->qr);
if(!udp) if(!udp)
@ -461,23 +633,5 @@ extern "C"
llarp_handle_dnsd_recvfrom(udp, addr, buf, sz); llarp_handle_dnsd_recvfrom(udp, addr, buf, sz);
} }
delete hdr; 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;
}
*/
} }
} }

View File

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

207
llarp/dns_rectypes.cpp Normal file
View File

@ -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

View File

@ -124,6 +124,8 @@ answer_request_alloc(struct dnsc_context *dnsc, void *sock, const char *url,
request->question.type = type; request->question.type = type;
request->question.qClass = 1; request->question.qClass = 1;
request->packet.header = nullptr;
// register our self with the tracker // register our self with the tracker
dns_tracker *tracker = request->context->tracker; dns_tracker *tracker = request->context->tracker;
if(!tracker) if(!tracker)
@ -151,18 +153,8 @@ answer_request_alloc(struct dnsc_context *dnsc, void *sock, const char *url,
/// generic dnsc handler /// generic dnsc handler
void void
generic_handle_dnsc_recvfrom(dnsc_answer_request *request, generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
__attribute__((unused)) llarp_buffer_t buffer, dns_msg_header *hdr)
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) if(!request)
{ {
llarp::LogError( llarp::LogError(
@ -170,14 +162,15 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
// we can't call back the hook // we can't call back the hook
return; return;
} }
// llarp_dnsc_unbind(request); // llarp::LogInfo("got a response, udp user is ", udp->user);
if(sz < 0) // unsigned char *castBuf = (unsigned char *)buf;
{ // const char *const castBufc = (const char *)buf;
llarp::LogWarn("Error Receiving DNS Client Response"); // auto buffer = llarp::StackBuffer< decltype(castBuf) >(castBuf);
request->resolved(request); size_t sz = buffer.sz;
return;
} llarp::LogDebug("Header got client responses for id: ", hdr->id);
// llarp_dnsc_unbind(request);
// unsigned char *castBuf = (unsigned char *)buf; // unsigned char *castBuf = (unsigned char *)buf;
// auto buffer = llarp::StackBuffer< decltype(castBuf) >(castBuf); // auto buffer = llarp::StackBuffer< decltype(castBuf) >(castBuf);
@ -203,44 +196,49 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
// rcode = (buffer[3] & 0x0F); // rcode = (buffer[3] & 0x0F);
// llarp::LogInfo("dnsc rcode ", rcode); // llarp::LogInfo("dnsc rcode ", rcode);
dns_msg_header *msg = decode_hdr((const char *)castBuf); // dns_msg_header *msg = decode_hdr((const char *)castBuf);
castBuf += 12; // dns_msg_header *msg = hdr;
llarp::LogDebug("msg id ", msg->id); // castBuf += 12;
uint8_t qr = msg->qr; llarp::LogDebug("msg id ", hdr->id);
uint8_t qr = hdr->qr;
llarp::LogDebug("msg qr ", qr); llarp::LogDebug("msg qr ", qr);
uint8_t opcode = msg->opcode; uint8_t opcode = hdr->opcode;
llarp::LogDebug("msg op ", opcode); llarp::LogDebug("msg op ", opcode);
rcode = msg->rcode; rcode = hdr->rcode;
llarp::LogDebug("msg rc ", rcode); llarp::LogDebug("msg rc ", rcode);
llarp::LogDebug("msg qdc ", msg->qdCount); llarp::LogDebug("msg qdc ", hdr->qdCount);
llarp::LogDebug("msg anc ", msg->anCount); llarp::LogDebug("msg anc ", hdr->anCount);
llarp::LogDebug("msg nsc ", msg->nsCount); llarp::LogDebug("msg nsc ", hdr->nsCount);
llarp::LogDebug("msg arc ", msg->arCount); llarp::LogDebug("msg arc ", hdr->arCount);
// FIXME: only handling one atm // FIXME: only handling one atm
uint32_t pos = 12; // just set after header uint32_t pos = 12; // just set after header
dns_msg_question *question = nullptr; dns_msg_question *question = nullptr;
for(uint32_t i = 0; i < hdr->qdCount; i++) 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)); // llarp::LogDebug("Read a question, now at ", std::to_string(pos));
// 1 dot: 1 byte for length + length // 1 dot: 1 byte for length + length
// 4 bytes for class/type // 4 bytes for class/type
// castBuf += question->name.length() + 1 + 4; // castBuf += question->name.length() + 1 + 4;
// castBuf += 2; // skip answer label // castBuf += 2; // skip answer label
} }
llarp::LogDebug("Question ", std::to_string(question->type), " ", if(question)
question->name); {
llarp::LogDebug("Question ", std::to_string(question->type), " ",
question->name);
}
// FIXME: only handling one atm // FIXME: only handling one atm
std::vector< dns_msg_answer * > answers; std::vector< dns_msg_answer * > answers;
dns_msg_answer *answer = nullptr; dns_msg_answer *answer = nullptr;
for(uint32_t i = 0; i < hdr->anCount; i++) for(uint32_t i = 0; i < hdr->anCount; i++)
{ {
// pos = 0; // reset pos // pos = 0; // reset pos
answer = decode_answer(castBufc, &pos); answer = decode_answer((char *)buffer.base, &pos);
answers.push_back(answer); answers.push_back(answer);
request->packet.answers.emplace_back(answer);
/* /*
llarp::LogDebug("Read an answer ", answer->type, " for ", llarp::LogDebug("Read an answer ", answer->type, " for ",
request->question.name, ", now at ", std::to_string(pos)); 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++) for(uint32_t i = 0; i < hdr->nsCount; i++)
{ {
// pos = 0; // reset pos // 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); // 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; // 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);
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((size_t)pos > sz)
{ {
llarp::LogWarn("Would read past end of dns packet. for ", llarp::LogWarn("Would read past end of dns packet. for ",
request->question.name); request->question.name);
@ -359,7 +377,10 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
answer = answers.front(); 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 class ", answer->aClass);
llarp::LogDebug("ans type ", answer->type); llarp::LogDebug("ans type ", answer->type);
@ -408,7 +429,21 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
llarp::LogDebug("request question type: ", llarp::LogDebug("request question type: ",
std::to_string(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::LogInfo("DNS server's answer is: (type#=", ATYPE, "):");
llarp::LogDebug("IPv4 address(es) for ", request->question.name, ":"); 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[2]),
// ".", std::to_string(answer->rData[1]), ".", // ".", std::to_string(answer->rData[1]), ".",
// std::to_string(answer->rData[0])); // std::to_string(answer->rData[0]));
/*
request->result = request->result =
llarp::ipaddr_ipv4_bits(answer->rData[3], answer->rData[2], llarp::ipaddr_ipv4_bits(answer->rData[3], answer->rData[2],
answer->rData[1], answer->rData[0]); answer->rData[1], answer->rData[0]);
*/
// llarp::Addr test(request->result); // llarp::Addr test(request->result);
// llarp::LogDebug(request->result); // llarp::LogDebug(request->result);
@ -461,37 +498,45 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
else if(answer->type == 12) else if(answer->type == 12)
{ {
llarp::LogDebug("Resolving PTR"); llarp::LogDebug("Resolving PTR");
// llarp::dns::type_12ptr *record = dynamic_cast< llarp::dns::type_12ptr *
// >(answer->record.get());
request->found = true; request->found = true;
request->revDNS = // request->revDNS = std::string((char *)answer->rData.data(),
std::string((char *)answer->rData.data(), answer->rData.size()); // answer->rData.size());
// request->revDNS = record->revname;
request->resolved(request); request->resolved(request);
return; return;
} }
else if(request->question.type == 15) else if(answer->type == 15)
{ {
llarp::LogDebug("Resolving MX"); llarp::dns::type_15mx *record =
request->found = true; dynamic_cast< llarp::dns::type_15mx * >(answer->record.get());
request->result.h = 99; llarp::LogDebug("Resolving MX ", record->mx, "@", record->priority);
request->revDNS = request->found = true;
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); request->resolved(request);
return; return;
} }
else if(request->question.type == 16) else if(answer->type == 16)
{ {
llarp::LogDebug("Resolving TXT"); llarp::LogDebug("Resolving TXT");
request->found = true; request->found = true;
request->revDNS = // request->revDNS = std::string((char *)answer->rData.data(),
std::string((char *)answer->rData.data(), answer->rData.size()); // answer->rData.size());
request->resolved(request); request->resolved(request);
return; return;
} }
else if(request->question.type == 28) else if(answer->type == 28)
{ {
llarp::LogDebug("Resolving AAAA"); llarp::LogDebug("Resolving AAAA");
return; return;
} }
llarp::LogWarn("Unhandled question type ", request->question.type); llarp::LogWarn("Unhandled question type ", request->question.type);
// should we let it timeout? lets try sending 404 asap
request->resolved(request);
} }
void void
@ -530,6 +575,7 @@ raw_resolve_host(struct dnsc_context *const dnsc, const char *url,
if(!(sockfd > 0)) if(!(sockfd > 0))
{ {
llarp::LogWarn("Error creating socket!\n"); llarp::LogWarn("Error creating socket!\n");
delete dns_packet;
return; return;
} }
// socket = sockfd; // socket = sockfd;
@ -567,7 +613,11 @@ raw_resolve_host(struct dnsc_context *const dnsc, const char *url,
return; return;
} }
llarp::LogInfo("closing new socket\n"); llarp::LogInfo("closing new socket\n");
if(!size)
{
llarp::LogWarn("Error Receiving DNS Client Response");
return;
}
// hexdump("received packet", &buffer, ret); // hexdump("received packet", &buffer, ret);
#ifndef _WIN32 #ifndef _WIN32
@ -576,15 +626,30 @@ raw_resolve_host(struct dnsc_context *const dnsc, const char *url,
closesocket(sockfd); closesocket(sockfd);
#endif #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); // 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); llarp::LogInfo("response header says it belongs to id #", hdr->id);
// if we sent this out, then there's an id // if we sent this out, then there's an id
struct dns_tracker *tracker = (struct dns_tracker *)dnsc->tracker; struct dns_tracker *tracker = (struct dns_tracker *)dnsc->tracker;
generic_handle_dnsc_recvfrom(tracker->client_request[hdr->id].get(), nullptr, struct dnsc_answer_request *request = tracker->client_request[hdr->id].get();
castBuf, size);
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 /// intermediate udp_io handler
@ -597,9 +662,21 @@ llarp_handle_dnsc_recvfrom(struct llarp_udp_io *const udp,
{ {
llarp::LogWarn("saddr isnt set"); 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); // 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); 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 // sometimes we'll get double responses
if(request) if(request)
{ {
generic_handle_dnsc_recvfrom(request, saddr, buf, sz); request->packet.header = hdr;
generic_handle_dnsc_recvfrom(request, buffer, hdr);
} }
else else
{ {

View File

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

View File

@ -14,6 +14,7 @@ namespace llarp
, m_IP(ip) , m_IP(ip)
, m_RewriteSource(rewriteIP) , m_RewriteSource(rewriteIP)
{ {
m_LastActive = parent->Now();
} }
Endpoint::~Endpoint() Endpoint::~Endpoint()
@ -65,6 +66,15 @@ namespace llarp
return true; return true;
} }
bool Endpoint::LooksDead(llarp_time_t now, llarp_time_t timeout) const
{
if(ExpiresSoon(now, timeout))
return true;
if (now > m_LastActive)
return now - m_LastActive > timeout;
return true;
}
bool bool
Endpoint::SendOutboundTraffic(llarp_buffer_t buf) Endpoint::SendOutboundTraffic(llarp_buffer_t buf)
{ {
@ -83,6 +93,7 @@ namespace llarp
return false; return false;
} }
m_TxRate += buf.sz; m_TxRate += buf.sz;
m_LastActive = m_Parent->Now();
return true; return true;
} }

View File

@ -37,10 +37,16 @@ namespace llarp
{ {
} }
llarp_time_t
ExitEndpoint::Now() const
{
return m_Router->Now();
}
void void
ExitEndpoint::FlushInbound() ExitEndpoint::FlushInbound()
{ {
auto now = Router()->Now(); auto now = Now();
m_InetToNetwork.Process([&](Pkt_t &pkt) { m_InetToNetwork.Process([&](Pkt_t &pkt) {
llarp::PubKey pk; llarp::PubKey pk;
{ {
@ -58,23 +64,27 @@ namespace llarp
auto range = m_ActiveExits.equal_range(pk); auto range = m_ActiveExits.equal_range(pk);
auto itr = range.first; auto itr = range.first;
uint64_t min = std::numeric_limits< uint64_t >::max(); uint64_t min = std::numeric_limits< uint64_t >::max();
/// pick path with lowest tx rate /// pick non dead looking path with lowest tx rate
while(itr != range.second) while(itr != range.second)
{ {
if(ep == nullptr) if(itr->second->TxRate() < min && !itr->second->LooksDead(now))
ep = itr->second.get();
else if(itr->second->RxRate() < min && !itr->second->ExpiresSoon(now))
{ {
min = ep->TxRate();
ep = itr->second.get(); ep = itr->second.get();
min = ep->TxRate();
} }
++itr; ++itr;
} }
if(ep)
if(ep == nullptr)
{
// we may have all dead sessions, wtf now?
llarp::LogWarn(Name(), " dropped inbound traffic for session ", pk, " as we have no working endpoints");
}
else
{ {
if(!ep->SendInboundTraffic(pkt.Buffer())) if(!ep->SendInboundTraffic(pkt.Buffer()))
{ {
llarp::LogWarn(Name(), " dropped inbound traffic for session ", pk); llarp::LogWarn(Name(), " dropped inbound traffic for session ", pk, " as we are overloaded (probably)");
} }
} }
}); });
@ -299,10 +309,10 @@ namespace llarp
if(wantInternet && !m_PermitExit) if(wantInternet && !m_PermitExit)
return false; return false;
huint32_t ip = GetIPForIdent(pk); huint32_t ip = GetIPForIdent(pk);
m_ActiveExits.insert(std::make_pair( m_ActiveExits.insert(
pk, std::make_pair(pk,
std::unique_ptr< llarp::exit::Endpoint >( std::make_unique< llarp::exit::Endpoint >(
new llarp::exit::Endpoint(pk, path, !wantInternet, ip, this)))); pk, path, !wantInternet, ip, this)));
m_Paths[path] = pk; m_Paths[path] = pk;
return HasLocalMappedAddrFor(pk); return HasLocalMappedAddrFor(pk);
} }
@ -354,4 +364,4 @@ namespace llarp
} }
} }
} // namespace handlers } // namespace handlers
} // namespace llarp } // namespace llarp

View File

@ -114,8 +114,26 @@ namespace llarp
} }
bool 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)); llarp::Zero(&_addr, sizeof(sockaddr_in6));
struct addrinfo hint, *res = NULL; struct addrinfo hint, *res = NULL;
int ret; int ret;
@ -129,17 +147,23 @@ namespace llarp
if(ret) if(ret)
{ {
llarp::LogError("failed to determine address family: ", str); llarp::LogError("failed to determine address family: ", str);
if(freeStr)
free(str);
return false; return false;
} }
if(res->ai_family == AF_INET6) if(res->ai_family == AF_INET6)
{ {
llarp::LogError("IPv6 address not supported yet", str); llarp::LogError("IPv6 address not supported yet", str);
if(freeStr)
free(str);
return false; return false;
} }
else if(res->ai_family != AF_INET) else if(res->ai_family != AF_INET)
{ {
llarp::LogError("Address family not supported yet", str); llarp::LogError("Address family not supported yet", str);
if(freeStr)
free(str);
return false; return false;
} }
@ -148,8 +172,12 @@ namespace llarp
if(inet_aton(str, addr) == 0) if(inet_aton(str, addr) == 0)
{ {
llarp::LogError("failed to parse ", str); llarp::LogError("failed to parse ", str);
if(freeStr)
free(str);
return false; return false;
} }
if(freeStr)
free(str);
_addr.sin6_family = res->ai_family; _addr.sin6_family = res->ai_family;
_addr4.sin_family = res->ai_family; _addr4.sin_family = res->ai_family;

View File

@ -262,9 +262,13 @@ namespace llarp
inf.read((char*)buf.base, sz); inf.read((char*)buf.base, sz);
if(!BDecode(&buf)) if(!BDecode(&buf))
return false; return false;
// update pubkey
const byte_t * ptr = nullptr;
if(!vanity.IsZero())
ptr = vanity.data();
// update pubkeys
pub.Update(llarp::seckey_topublic(enckey), pub.Update(llarp::seckey_topublic(enckey),
llarp::seckey_topublic(signkey)); llarp::seckey_topublic(signkey), ptr);
return true; return true;
} }

View File

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

View File

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