pull/40/head
Ryan Tharp 6 years ago
parent 26d4fd068f
commit 67390de0c2

@ -7,7 +7,7 @@ REPO := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
PREFIX ?= /usr/local PREFIX ?= /usr/local
CC ?= cc CC ?= cc
CXX ?= c++ CXX ?= c++
SETCAP ?= which setcap && setcap cap_net_admin=+eip SETCAP ?= which setcap && setcap cap_net_admin=+eip
@ -66,7 +66,7 @@ debug-configure:
$(CONFIG_CMD) -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=$(CC) -DCMAKE_CXX_COMPILER=$(CXX) -DDNS_PORT=$(DNS_PORT) $(CONFIG_CMD) -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=$(CC) -DCMAKE_CXX_COMPILER=$(CXX) -DDNS_PORT=$(DNS_PORT)
release-configure: clean release-configure: clean
mkdir -p '$(BUILD_ROOT)' mkdir -p '$(BUILD_ROOT)'
$(CONFIG_CMD) -DSTATIC_LINK=ON -DCMAKE_BUILD_TYPE=Release -DRELEASE_MOTTO="$(shell cat motto.txt)" -DCMAKE_C_COMPILER=$(CC) -DCMAKE_CXX_COMPILER=$(CXX) $(CONFIG_CMD) -DSTATIC_LINK=ON -DCMAKE_BUILD_TYPE=Release -DRELEASE_MOTTO="$(shell cat motto.txt)" -DCMAKE_C_COMPILER=$(CC) -DCMAKE_CXX_COMPILER=$(CXX)
debug: debug-configure debug: debug-configure
@ -116,7 +116,7 @@ shared-configure: clean
shared: shared-configure shared: shared-configure
$(MAKE) -C $(BUILD_ROOT) $(MAKE) -C $(BUILD_ROOT)
testnet: testnet:
cp $(EXE) $(TESTNET_EXE) cp $(EXE) $(TESTNET_EXE)
mkdir -p $(TESTNET_ROOT) mkdir -p $(TESTNET_ROOT)
python3 contrib/testnet/genconf.py --bin=$(TESTNET_EXE) --svc=$(TESTNET_SERVERS) --clients=$(TESTNET_CLIENTS) --dir=$(TESTNET_ROOT) --out $(TESTNET_CONF) --connect=4 python3 contrib/testnet/genconf.py --bin=$(TESTNET_EXE) --svc=$(TESTNET_SERVERS) --clients=$(TESTNET_CLIENTS) --dir=$(TESTNET_ROOT) --out $(TESTNET_CONF) --connect=4
@ -148,3 +148,13 @@ install:
rm -f $(PREFIX)/bin/lokinet-bootstrap rm -f $(PREFIX)/bin/lokinet-bootstrap
cp $(REPO)/lokinet-bootstrap $(PREFIX)/bin/lokinet-bootstrap cp $(REPO)/lokinet-bootstrap $(PREFIX)/bin/lokinet-bootstrap
chmod 755 $(PREFIX)/bin/lokinet-bootstrap chmod 755 $(PREFIX)/bin/lokinet-bootstrap
setcap cap_net_admin=+eip $(PREFIX)/bin/lokinet
fuzz-configure: clean
cmake -GNinja -DCMAKE_BUILD_TYPE=Fuzz -DCMAKE_C_COMPILER=afl-gcc -DCMAKE_CXX_COMPILER=afl-g++
fuzz-build: fuzz-configure
ninja
fuzz: fuzz-build
$(EXE)

@ -11,7 +11,7 @@
#include <sys/socket.h> #include <sys/socket.h>
#endif #endif
#include <llarp/net.hpp> // for llarp::Addr #include <llarp/net.hpp> // for llarp::Addr , llarp::huint32_t
struct dnsd_context; struct dnsd_context;
@ -85,7 +85,7 @@ struct dns_packet
}; };
std::string std::string
getDNSstring(const char *buffer); 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();
@ -102,10 +102,10 @@ extern "C"
decode_hdr(const char *buffer); decode_hdr(const char *buffer);
dns_msg_question * dns_msg_question *
decode_question(const char *buffer); decode_question(const char *buffer, uint32_t *pos);
dns_msg_answer * dns_msg_answer *
decode_answer(const char *buffer); decode_answer(const char *const buffer, uint32_t *pos);
void void
put16bits(char *&buffer, uint16_t value) throw(); put16bits(char *&buffer, uint16_t value) throw();

@ -11,7 +11,7 @@
// neither, it's a result set row // neither, it's a result set row
struct dns_pointer struct dns_pointer
{ {
llarp::Addr hostResult; llarp::huint32_t hostResult;
llarp::service::Address b32addr; llarp::service::Address b32addr;
// we could store the timeout at which we expect it to be available // we could store the timeout at which we expect it to be available
// or a list of pending requests for it // or a list of pending requests for it
@ -32,16 +32,19 @@ struct dns_iptracker
std::vector< std::unique_ptr< ip_range > > used_ten_ips; std::vector< std::unique_ptr< ip_range > > used_ten_ips;
std::vector< std::unique_ptr< ip_range > > used_seven_ips; std::vector< std::unique_ptr< ip_range > > used_seven_ips;
std::vector< std::unique_ptr< ip_range > > used_nine_ips; std::vector< std::unique_ptr< ip_range > > used_nine_ips;
// make it easier to find a entry
std::vector< std::unique_ptr< dns_pointer > > map;
}; };
void void
dns_iptracker_init(); dns_iptracker_init();
bool bool
dns_iptracker_setup_dotLokiLookup(dotLokiLookup *dll, llarp::Addr tunGatewayIp); dns_iptracker_setup_dotLokiLookup(dotLokiLookup *dll,
llarp::huint32_t tunGatewayIp);
bool bool
dns_iptracker_setup(dns_iptracker *iptracker, llarp::Addr tunGatewayIp); dns_iptracker_setup(dns_iptracker *iptracker, llarp::huint32_t tunGatewayIp);
struct dns_pointer * struct dns_pointer *
dns_iptracker_get_free(); dns_iptracker_get_free();

@ -41,7 +41,7 @@ struct dnsc_answer_request
dnsc_answer_hook_func resolved; dnsc_answer_hook_func resolved;
/// result /// result
bool found; bool found;
llarp::Addr result; llarp::huint32_t result;
std::string revDNS; 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;
@ -81,12 +81,14 @@ struct dnsc_context
/// async resolve a hostname using generic socks /// async 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);
/// async resolve a hostname using llarp platform framework /// async 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,
uint16_t type);
/// cleans up request structure allocations /// cleans up request structure allocations
void void

@ -45,7 +45,7 @@ struct dnsd_query_hook_response
/// turn off recursion /// turn off recursion
bool dontLookUp; bool dontLookUp;
/// potential address /// potential address
sockaddr *returnThis; // FIXME: llarp::Addr llarp::huint32_t *returnThis;
}; };
/// builds and fires a request based based on llarp_udp_io udp event /// builds and fires a request based based on llarp_udp_io udp event
@ -74,7 +74,7 @@ writecname_dnss_response(std::string cname, const struct sockaddr *from,
/// send an A record found response /// send an A record found response
void void
writesend_dnss_response(struct sockaddr *hostRes, const struct sockaddr *from, writesend_dnss_response(llarp::huint32_t *hostRes, const struct sockaddr *from,
dnsd_question_request *request); dnsd_question_request *request);
// FIXME: llarp::Addr // FIXME: llarp::Addr

@ -18,7 +18,7 @@ namespace llarp
} }
EncryptedFrame(const EncryptedFrame& other) EncryptedFrame(const EncryptedFrame& other)
: EncryptedFrame(other.data(), other.size()) : EncryptedFrame(other.data(), other.size())
{ {
} }

@ -43,6 +43,12 @@ namespace llarp
udp_recv_from(llarp_udp_io* udp, const sockaddr* from, const void* buf, udp_recv_from(llarp_udp_io* udp, const sockaddr* from, const void* buf,
const ssize_t sz) const ssize_t sz)
{ {
if(!udp)
{
llarp::LogWarn("no udp set");
return;
}
// maybe chekc from too?
static_cast< ILinkLayer* >(udp->user)->RecvFrom(*from, buf, sz); static_cast< ILinkLayer* >(udp->user)->RecvFrom(*from, buf, sz);
} }

@ -77,6 +77,17 @@ namespace llarp
constexpr bool operator <(huint32_t x) const { return h < x.h; } constexpr bool operator <(huint32_t x) const { return h < x.h; }
constexpr bool operator ==(huint32_t x) const { return h == x.h; } constexpr bool operator ==(huint32_t x) const { return h == x.h; }
friend std::ostream&
operator<<(std::ostream& out, const huint32_t& a)
{
char tmp[INET_ADDRSTRLEN] = {0};
if(inet_ntop(AF_INET, (void*)&a.h, tmp, INET_ADDRSTRLEN))
{
out << tmp;
}
return out;
}
struct Hash struct Hash
{ {
inline size_t inline size_t
@ -107,6 +118,17 @@ namespace llarp
constexpr bool operator <(nuint32_t x) const { return n < x.n; } constexpr bool operator <(nuint32_t x) const { return n < x.n; }
constexpr bool operator ==(nuint32_t x) const { return n == x.n; } constexpr bool operator ==(nuint32_t x) const { return n == x.n; }
friend std::ostream&
operator<<(std::ostream& out, const nuint32_t& a)
{
char tmp[INET_ADDRSTRLEN] = {0};
if(inet_ntop(AF_INET, (void*)&a.n, tmp, INET_ADDRSTRLEN))
{
out << tmp;
}
return out;
}
struct Hash struct Hash
{ {
inline size_t inline size_t
@ -134,6 +156,17 @@ namespace llarp
constexpr bool operator <(huint16_t x) const { return h < x.h; } constexpr bool operator <(huint16_t x) const { return h < x.h; }
constexpr bool operator ==(huint16_t x) const { return h == x.h; } constexpr bool operator ==(huint16_t x) const { return h == x.h; }
friend std::ostream&
operator<<(std::ostream& out, const huint16_t& a)
{
char tmp[INET_ADDRSTRLEN] = {0};
if(inet_ntop(AF_INET, (void*)&a.h, tmp, INET_ADDRSTRLEN))
{
out << tmp;
}
return out;
}
struct Hash struct Hash
{ {
inline size_t inline size_t
@ -161,6 +194,17 @@ namespace llarp
constexpr bool operator <(nuint16_t x) const { return n < x.n; } constexpr bool operator <(nuint16_t x) const { return n < x.n; }
constexpr bool operator ==(nuint16_t x) const { return n == x.n; } constexpr bool operator ==(nuint16_t x) const { return n == x.n; }
friend std::ostream&
operator<<(std::ostream& out, const nuint16_t& a)
{
char tmp[INET_ADDRSTRLEN] = {0};
if(inet_ntop(AF_INET, (void*)&a.n, tmp, INET_ADDRSTRLEN))
{
out << tmp;
}
return out;
}
struct Hash struct Hash
{ {
inline size_t inline size_t
@ -210,14 +254,15 @@ namespace llarp
return (addr & netmask_bits) == (ip & netmask_bits); return (addr & netmask_bits) == (ip & netmask_bits);
} }
std::string friend std::ostream&
ToString() const operator<<(std::ostream& out, const IPRange& a)
{ {
char strbuf[32] = {0}; char strbuf[32] = {0};
char netbuf[32] = {0}; char netbuf[32] = {0};
inet_ntop(AF_INET, &addr, strbuf, sizeof(strbuf)); inet_ntop(AF_INET, &a.addr, strbuf, sizeof(strbuf));
inet_ntop(AF_INET, &netmask_bits, netbuf, sizeof(netbuf)); inet_ntop(AF_INET, &a.netmask_bits, netbuf, sizeof(netbuf));
return std::string(strbuf) + "/" + std::string(netbuf); out << std::string(strbuf) + "/" + std::string(netbuf);
return out;
} }
}; };
@ -268,510 +313,7 @@ namespace llarp
bool bool
IsBogonRange(const in6_addr& host, const in6_addr& mask); IsBogonRange(const in6_addr& host, const in6_addr& mask);
struct Addr struct Addr; // fwd declr
{
// network order
sockaddr_in6 _addr;
sockaddr_in _addr4; // why do we even have this? favor cpu over memory
~Addr(){};
Addr(){};
Addr(const Addr& other)
{
memcpy(&_addr, &other._addr, sizeof(sockaddr_in6));
memcpy(&_addr4, &other._addr4, sizeof(sockaddr_in));
}
void
port(uint16_t port)
{
if(af() == AF_INET)
{
_addr4.sin_port = htons(port);
}
_addr.sin6_port = htons(port);
}
in6_addr*
addr6()
{
return (in6_addr*)&_addr.sin6_addr.s6_addr[0];
}
in_addr*
addr4()
{
return (in_addr*)&_addr.sin6_addr.s6_addr[12];
}
const in6_addr*
addr6() const
{
return (const in6_addr*)&_addr.sin6_addr.s6_addr[0];
}
const in_addr*
addr4() const
{
return (const in_addr*)&_addr.sin6_addr.s6_addr[12];
}
Addr(const std::string str)
{
this->from_char_array(str.c_str());
}
Addr(const std::string str, const uint16_t p_port)
{
this->from_char_array(str.c_str());
this->port(p_port);
}
bool
from_char_array(const char* str)
{
llarp::Zero(&_addr, sizeof(sockaddr_in6));
struct addrinfo hint, *res = NULL;
int ret;
memset(&hint, '\0', sizeof hint);
hint.ai_family = PF_UNSPEC;
hint.ai_flags = AI_NUMERICHOST;
ret = getaddrinfo(str, NULL, &hint, &res);
if(ret)
{
llarp::LogError("failed to determine address family: ", str);
return false;
}
if(res->ai_family == AF_INET6)
{
llarp::LogError("IPv6 address not supported yet", str);
return false;
}
else if(res->ai_family != AF_INET)
{
llarp::LogError("Address family not supported yet", str);
return false;
}
// put it in _addr4
struct in_addr* addr = &_addr4.sin_addr;
if(inet_aton(str, addr) == 0)
{
llarp::LogError("failed to parse ", str);
return false;
}
_addr.sin6_family = res->ai_family;
_addr4.sin_family = res->ai_family;
_addr4.sin_port = 0; // save a call, 0 is 0 no matter how u arrange it
#if((__APPLE__ && __MACH__) || __FreeBSD__)
_addr4.sin_len = sizeof(in_addr);
#endif
// set up SIIT
uint8_t* addrptr = _addr.sin6_addr.s6_addr;
addrptr[11] = 0xff;
addrptr[10] = 0xff;
memcpy(12 + addrptr, &addr->s_addr, sizeof(in_addr));
freeaddrinfo(res);
return true;
}
Addr(const char* str)
{
this->from_char_array(str);
}
bool
from_4int(const uint8_t one, const uint8_t two, const uint8_t three,
const uint8_t four)
{
llarp::Zero(&_addr, sizeof(sockaddr_in6));
struct in_addr* addr = &_addr4.sin_addr;
unsigned char* ip = (unsigned char*)&(addr->s_addr);
_addr.sin6_family = AF_INET; // set ipv4 mode
_addr4.sin_family = AF_INET;
_addr4.sin_port = 0;
#if((__APPLE__ && __MACH__) || __FreeBSD__)
_addr4.sin_len = sizeof(in_addr);
#endif
// FIXME: watch endian
ip[0] = one;
ip[1] = two;
ip[2] = three;
ip[3] = four;
// set up SIIT
uint8_t* addrptr = _addr.sin6_addr.s6_addr;
addrptr[11] = 0xff;
addrptr[10] = 0xff;
memcpy(12 + addrptr, &addr->s_addr, sizeof(in_addr));
// copy ipv6 SIIT into _addr4
memcpy(&_addr4.sin_addr.s_addr, addr4(), sizeof(in_addr));
return true;
}
Addr(const uint8_t one, const uint8_t two, const uint8_t three,
const uint8_t four)
{
this->from_4int(one, two, three, four);
}
Addr(const uint8_t one, const uint8_t two, const uint8_t three,
const uint8_t four, const uint16_t p_port)
{
this->from_4int(one, two, three, four);
this->port(p_port);
}
Addr(const AddressInfo& other)
{
memcpy(addr6(), other.ip.s6_addr, 16);
_addr.sin6_port = htons(other.port);
if(ipv6_is_siit(other.ip))
{
_addr4.sin_family = AF_INET;
_addr4.sin_port = htons(other.port);
_addr.sin6_family = AF_INET;
memcpy(&_addr4.sin_addr.s_addr, addr4(), sizeof(in_addr));
}
else
_addr.sin6_family = AF_INET6;
}
Addr(const sockaddr_in& other)
{
llarp::Zero(&_addr, sizeof(sockaddr_in6));
_addr.sin6_family = AF_INET;
uint8_t* addrptr = _addr.sin6_addr.s6_addr;
uint16_t* port = &_addr.sin6_port;
// SIIT
memcpy(12 + addrptr, &((const sockaddr_in*)(&other))->sin_addr,
sizeof(in_addr));
addrptr[11] = 0xff;
addrptr[10] = 0xff;
*port = ((sockaddr_in*)(&other))->sin_port;
_addr4.sin_family = AF_INET;
_addr4.sin_port = *port;
memcpy(&_addr4.sin_addr.s_addr, addr4(), sizeof(in_addr));
}
Addr(const sockaddr_in6& other)
{
memcpy(addr6(), other.sin6_addr.s6_addr, 16);
_addr.sin6_port = htons(other.sin6_port);
auto ptr = &_addr.sin6_addr.s6_addr[0];
// TODO: detect SIIT better
if(ptr[11] == 0xff && ptr[10] == 0xff && ptr[9] == 0 && ptr[8] == 0
&& ptr[7] == 0 && ptr[6] == 0 && ptr[5] == 0 && ptr[4] == 0
&& ptr[3] == 0 && ptr[2] == 0 && ptr[1] == 0 && ptr[0] == 0)
{
_addr4.sin_family = AF_INET;
_addr4.sin_port = htons(other.sin6_port);
_addr.sin6_family = AF_INET;
memcpy(&_addr4.sin_addr.s_addr, addr4(), sizeof(in_addr));
}
else
_addr.sin6_family = AF_INET6;
}
Addr(const sockaddr& other)
{
llarp::Zero(&_addr, sizeof(sockaddr_in6));
_addr.sin6_family = other.sa_family;
uint8_t* addrptr = _addr.sin6_addr.s6_addr;
uint16_t* port = &_addr.sin6_port;
switch(other.sa_family)
{
case AF_INET:
// SIIT
memcpy(12 + addrptr, &((const sockaddr_in*)(&other))->sin_addr,
sizeof(in_addr));
addrptr[11] = 0xff;
addrptr[10] = 0xff;
*port = ((sockaddr_in*)(&other))->sin_port;
_addr4.sin_family = AF_INET;
_addr4.sin_port = *port;
memcpy(&_addr4.sin_addr.s_addr, addr4(), sizeof(in_addr));
break;
case AF_INET6:
memcpy(addrptr, &((const sockaddr_in6*)(&other))->sin6_addr.s6_addr,
16);
*port = ((sockaddr_in6*)(&other))->sin6_port;
break;
// TODO : sockaddr_ll
default:
break;
}
}
std::string
ToString() const
{
std::stringstream ss;
ss << (*this);
return std::string(ss.str().c_str());
}
friend std::ostream&
operator<<(std::ostream& out, const Addr& a)
{
char tmp[128] = {0};
const void* ptr = nullptr;
if(a.af() == AF_INET6)
{
out << "[";
ptr = a.addr6();
}
else
{
ptr = a.addr4();
}
#ifndef _MSC_VER
if(inet_ntop(a.af(), ptr, tmp, sizeof(tmp)))
#else
if(inet_ntop(a.af(), (void*)ptr, tmp, sizeof(tmp)))
#endif
{
out << tmp;
if(a.af() == AF_INET6)
out << "]";
}
return out << ":" << a.port();
}
operator const sockaddr*() const
{
if(af() == AF_INET)
return (const sockaddr*)&_addr4;
else
return (const sockaddr*)&_addr;
}
operator sockaddr*() const
{
if(af() == AF_INET)
return (sockaddr*)&_addr4;
else
return (sockaddr*)&_addr;
}
void
CopyInto(sockaddr* other) const
{
void *dst, *src;
in_port_t* ptr;
size_t slen;
switch(af())
{
case AF_INET:
{
sockaddr_in* ipv4_dst = (sockaddr_in*)other;
dst = (void*)&ipv4_dst->sin_addr.s_addr;
src = (void*)&_addr4.sin_addr.s_addr;
ptr = &((sockaddr_in*)other)->sin_port;
slen = sizeof(in_addr);
break;
}
case AF_INET6:
{
dst = (void*)((sockaddr_in6*)other)->sin6_addr.s6_addr;
src = (void*)_addr.sin6_addr.s6_addr;
ptr = &((sockaddr_in6*)other)->sin6_port;
slen = sizeof(in6_addr);
break;
}
default:
{
return;
}
}
memcpy(dst, src, slen);
*ptr = htons(port());
other->sa_family = af();
}
int
af() const
{
return _addr.sin6_family;
}
uint16_t
port() const
{
return ntohs(_addr.sin6_port);
}
bool
operator<(const Addr& other) const
{
if(af() == AF_INET && other.af() == AF_INET)
return port() < other.port() || addr4()->s_addr < other.addr4()->s_addr;
else
return port() < other.port() || *addr6() < *other.addr6()
|| af() < other.af();
}
bool
operator==(const Addr& other) const
{
if(af() == AF_INET && other.af() == AF_INET)
return port() == other.port()
&& addr4()->s_addr == other.addr4()->s_addr;
else
return af() == other.af() && memcmp(addr6(), other.addr6(), 16) == 0
&& port() == other.port();
}
Addr&
operator=(const sockaddr& other)
{
llarp::Zero(&_addr, sizeof(sockaddr_in6));
_addr.sin6_family = other.sa_family;
uint8_t* addrptr = _addr.sin6_addr.s6_addr;
uint16_t* port = &_addr.sin6_port;
switch(other.sa_family)
{
case AF_INET:
// SIIT
memcpy(12 + addrptr, &((const sockaddr_in*)(&other))->sin_addr,
sizeof(in_addr));
addrptr[11] = 0xff;
addrptr[10] = 0xff;
*port = ((sockaddr_in*)(&other))->sin_port;
_addr4.sin_family = AF_INET;
_addr4.sin_port = *port;
memcpy(&_addr4.sin_addr.s_addr, addr4(), sizeof(in_addr));
break;
case AF_INET6:
memcpy(addrptr, &((const sockaddr_in6*)(&other))->sin6_addr.s6_addr,
16);
*port = ((sockaddr_in6*)(&other))->sin6_port;
break;
// TODO : sockaddr_ll
default:
break;
}
return *this;
}
inline uint32_t
tohl() const
{
return ntohl(addr4()->s_addr);
}
inline huint32_t
xtohl() const
{
return huint32_t{ntohl(addr4()->s_addr)};
}
inline uint32_t
ton() const
{
return addr4()->s_addr;
}
inline nuint32_t
xtonl() const
{
return nuint32_t{addr4()->s_addr};
}
bool
sameAddr(const Addr& other) const
{
return memcmp(addr6(), other.addr6(), 16) == 0;
}
bool
operator!=(const Addr& other) const
{
return !(*this == other);
}
inline uint32_t
getHostLong()
{
in_addr_t addr = this->addr4()->s_addr;
uint32_t byte = ntohl(addr);
return byte;
};
bool
isTenPrivate(uint32_t byte)
{
uint8_t byte1 = byte >> 24 & 0xff;
return byte1 == 10;
}
bool
isOneSevenPrivate(uint32_t byte)
{
uint8_t byte1 = byte >> 24 & 0xff;
uint8_t byte2 = (0x00ff0000 & byte) >> 16;
return byte1 == 172 && (byte2 >= 16 || byte2 <= 31);
}
bool
isOneNinePrivate(uint32_t byte)
{
uint8_t byte1 = byte >> 24 & 0xff;
uint8_t byte2 = (0x00ff0000 & byte) >> 16;
return byte1 == 192 && byte2 == 168;
}
/// return true if our ipv4 address is a bogon
/// TODO: ipv6
bool
IsBogon() const
{
return IsIPv4Bogon(xtohl());
}
socklen_t
SockLen() const
{
if(af() == AF_INET)
return sizeof(sockaddr_in);
else
return sizeof(sockaddr_in6);
}
bool
isPrivate() const
{
return IsBogon();
}
bool
isLoopback() const
{
return (ntohl(addr4()->s_addr)) >> 24 == 127;
}
struct Hash
{
std::size_t
operator()(Addr const& a) const noexcept
{
if(a.af() == AF_INET)
{
return a.port() ^ a.addr4()->s_addr;
}
static const uint8_t empty[16] = {0};
return (a.af() + memcmp(a.addr6(), empty, 16)) ^ a.port();
}
};
}; // namespace llarp
bool bool
AllInterfaces(int af, Addr& addr); AllInterfaces(int af, Addr& addr);
@ -794,4 +336,7 @@ namespace llarp
} // namespace llarp } // namespace llarp
#include <llarp/net_inaddr.hpp>
#include <llarp/net_addr.hpp>
#endif #endif

@ -40,7 +40,7 @@ namespace llarp
bool firstKey; bool firstKey;
char key; char key;
dict_reader reader; dict_reader reader;
std::unique_ptr<IMessage> msg; std::unique_ptr< IMessage > msg;
}; };
} // namespace routing } // namespace routing
} // namespace llarp } // namespace llarp

@ -55,6 +55,9 @@ namespace llarp
bool bool
iterate(struct endpoint_iter &i); iterate(struct endpoint_iter &i);
huint32_t
GetIpForAddr(const llarp::service::Address &addr);
/// hint at possible path usage and trigger building early /// hint at possible path usage and trigger building early
bool bool
Prefetch(const llarp::service::Address &addr); Prefetch(const llarp::service::Address &addr);

@ -76,6 +76,7 @@ namespace llarp
auto pathset = ctx->impl.router->paths.GetLocalPathSet(pathID); auto pathset = ctx->impl.router->paths.GetLocalPathSet(pathID);
return pathset && pathset->HandleGotRouterMessage(this); return pathset && pathset->HandleGotRouterMessage(this);
} }
// not relayed
TXOwner owner(From, txid); TXOwner owner(From, txid);
if(dht.pendingExploreLookups.HasPendingLookupFrom(owner)) if(dht.pendingExploreLookups.HasPendingLookupFrom(owner))
@ -88,12 +89,16 @@ namespace llarp
} }
return true; return true;
} }
// not explore lookup
if(!dht.pendingRouterLookups.HasPendingLookupFrom(owner)) if(!dht.pendingRouterLookups.HasPendingLookupFrom(owner))
{ {
llarp::LogWarn("Unwarrented GRM from ", From, " txid=", txid); llarp::LogWarn("Unwarrented GRM from ", From, " txid=", txid);
return false; return false;
} }
// no pending lookup
llarp::LogInfo("DHT no pending lookup");
if(R.size() == 1) if(R.size() == 1)
dht.pendingRouterLookups.Found(owner, R[0].pubkey, {R[0]}); dht.pendingRouterLookups.Found(owner, R[0].pubkey, {R[0]});
else else

@ -2,6 +2,28 @@
#include <llarp/dnsd.hpp> // for llarp_handle_dnsd_recvfrom, dnsc #include <llarp/dnsd.hpp> // for llarp_handle_dnsd_recvfrom, dnsc
#include <llarp/logger.hpp> #include <llarp/logger.hpp>
void
hexDump(const char *buffer, uint16_t size)
{
char hex_buffer[size * 3 + 1];
hex_buffer[size * 3] = 0;
for(unsigned int j = 0; j < size; j++)
sprintf(&hex_buffer[3 * j], "%02X ", buffer[j]);
std::string str(hex_buffer);
llarp::LogInfo("First ", size, " bytes: ", str);
}
void
hexDumpAt(const char *const buffer, uint32_t pos, uint16_t size)
{
char hex_buffer[size * 3 + 1];
hex_buffer[size * 3] = 0;
for(unsigned int j = 0; j < size; j++)
sprintf(&hex_buffer[3 * j], "%02X ", buffer[pos + j]);
std::string str(hex_buffer);
llarp::LogInfo(pos, " ", size, " bytes: ", str);
}
/* /*
<domain-name> is a domain name represented as a series of labels, and <domain-name> is a domain name represented as a series of labels, and
terminated by a label with zero length. <character-string> is a single terminated by a label with zero length. <character-string> is a single
@ -10,25 +32,62 @@
length (including the length octet). length (including the length octet).
*/ */
std::string std::string
getDNSstring(const char *buffer) getDNSstring(const char *const buffer, uint32_t *pos)
{ {
std::string str = ""; std::string str = "";
uint8_t length = *buffer++; const char *moveable = buffer;
moveable += *pos;
uint8_t length = *moveable++;
(*pos)++;
if(length == 0xc0)
{
uint8_t cPos = *moveable++;
(*pos)++;
uint32_t cPos32 = cPos;
// llarp::LogInfo("Found reference at ", std::to_string(cPos));
return getDNSstring(buffer, &cPos32);
}
// hexDump(moveable, length);
// hexDump(buffer, length);
// printf("dnsStringLen[%d]\n", length); // printf("dnsStringLen[%d]\n", length);
// llarp::LogInfo("dnsStringLen ", length); // llarp::LogInfo("dnsStringLen ", std::to_string(length));
if(!length) if(!length)
return str; return str;
while(length != 0) while(length != 0)
{ {
// llarp::LogInfo("Reading ", std::to_string(length));
for(int i = 0; i < length; i++) for(int i = 0; i < length; i++)
{ {
char c = *buffer++; char c = *moveable++;
(*pos)++;
str.append(1, c); str.append(1, c);
} }
length = *buffer++; if(*moveable == '\xc0')
{
moveable++;
(*pos)++; // forward one char
uint8_t cPos = *moveable; // read char
uint32_t cPos32 = cPos;
// llarp::LogInfo("Remaining [", str, "] is an reference at ", (int)cPos);
std::string addl = getDNSstring(buffer, &cPos32);
// llarp::LogInfo("Addl str [", addl, "]");
str += "." + addl;
// llarp::LogInfo("Final str [", str, "]");
(*pos)++; // move past reference
return str;
}
length = *moveable++;
(*pos)++;
if(length > 64)
llarp::LogError("bug detected");
// else
// hexDump(buffer, length);
// llarp::LogInfo("NextLen ", std::to_string(length));
if(length != 0) if(length != 0)
str.append(1, '.'); str.append(1, '.');
} }
// llarp::LogInfo("Returning ", str);
return str; return str;
} }
@ -113,12 +172,23 @@ extern "C"
} }
dns_msg_question * dns_msg_question *
decode_question(const char *buffer) decode_question(const char *buffer, uint32_t *pos)
{ {
// char *start = (char *)buffer; // char *start = (char *)buffer;
dns_msg_question *question = new dns_msg_question; dns_msg_question *question = new dns_msg_question;
std::string m_qName = getDNSstring(buffer);
buffer += m_qName.length() + 2; // + length byte & ending terminator // uint32_t start = *pos;
std::string m_qName = getDNSstring(buffer, pos);
llarp::LogInfo("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); // printf("Now0 at [%d]\n", buffer - start);
// buffer += m_qName.size() + 1; // buffer += m_qName.size() + 1;
/* /*
@ -138,15 +208,20 @@ extern "C"
} }
*/ */
question->name = m_qName; question->name = m_qName;
question->type = get16bits(buffer); question->type = get16bits(moveable);
(*pos) += 2;
// printf("Now1 at [%d]\n", buffer - start); // printf("Now1 at [%d]\n", buffer - start);
question->qClass = get16bits(buffer); question->qClass = get16bits(moveable);
(*pos) += 2;
// printf("Now2 at [%d]\n", buffer - start); // printf("Now2 at [%d]\n", buffer - start);
llarp::LogInfo("Type ", std::to_string(question->type), " Class ",
std::to_string(question->qClass));
// hexDump(moveable, 4);
return question; return question;
} }
dns_msg_answer * dns_msg_answer *
decode_answer(const char *buffer) decode_answer(const char *const buffer, uint32_t *pos)
{ {
dns_msg_answer *answer = new dns_msg_answer; dns_msg_answer *answer = new dns_msg_answer;
// skip for now until we can handle compressed labels // skip for now until we can handle compressed labels
@ -162,42 +237,95 @@ extern "C"
llarp::DumpBuffer(bob); llarp::DumpBuffer(bob);
*/ */
char hex_buffer[12 * 3 + 1]; // hexDump(buffer, 10);
hex_buffer[12 * 3] = 0;
for(unsigned int j = 0; j < 10; j++)
sprintf(&hex_buffer[3 * j], "%02X ", buffer[j]);
llarp::LogDebug("First 12 bytes: ", hex_buffer);
uint8_t first = *buffer++; const char *moveable = buffer;
// llarp::LogInfo("decode - first", std::to_string(first)); // llarp::LogDebug("Advancing to pos ", std::to_string(*pos));
moveable += (*pos); // advance to position
// hexDumpAt(buffer, (*pos) - 2, 12);
// hexDump(moveable, 12);
if(*moveable == '\xc0')
{
// hexDump(moveable, 12);
// hexDumpAt(buffer, *pos, 12);
// hexDump(moveable, 2);
moveable++;
(*pos)++;
uint8_t readAt = *moveable;
uint32_t readAt32 = readAt;
llarp::LogInfo("Ref, skip. Read ", readAt32);
// hexDumpAt(buffer, readAt, 2);
answer->name = getDNSstring(buffer, &readAt32);
moveable++;
(*pos)++;
// hexDump(moveable, 10);
// hexDumpAt(buffer, *pos, 10);
}
else
{
// get DNSString?
llarp::LogWarn("Need to parse string");
}
/*
hexDump(moveable, 10);
uint8_t first = *moveable++; (*pos)++;
llarp::LogInfo("decode - first", std::to_string(first));
// SOA hack // SOA hack
if(first != 12 && first != 14) // 0x0c (c0 0c) 0 if(first != 12 && first != 14) // 0x0c (c0 0c) 0
{ {
llarp::LogDebug("decode - first isnt 12, stepping back"); llarp::LogDebug("decode - first isnt 12, stepping back");
buffer--; // rewind buffer one byte moveable--; (*pos)--; // rewind buffer one byte
} }
answer->type = get16bits(buffer); */
// hexDump(moveable, 10);
answer->type = get16bits(moveable);
(*pos) += 2;
llarp::LogDebug("Answer Type: ", answer->type);
// assert(answer->type < 259); // assert(answer->type < 259);
if(answer->type > 259) if(answer->type > 259)
{ {
llarp::LogWarn("Answer type is off the charts"); llarp::LogWarn("Answer type is off the charts");
} }
answer->aClass = get16bits(buffer); answer->aClass = get16bits(moveable);
answer->ttl = get32bits(buffer); (*pos) += 2;
answer->rdLen = get16bits(buffer); llarp::LogDebug("Answer Class: ", answer->aClass);
answer->ttl = get32bits(moveable);
(*pos) += 4;
llarp::LogDebug("Answer TTL: ", answer->ttl);
answer->rdLen = get16bits(moveable);
(*pos) += 2;
llarp::LogDebug("Answer rdL: ", answer->rdLen, " at ",
std::to_string(*pos));
// uint32_t cPos = moveable - buffer;
// llarp::LogInfo("pos at ", std::to_string(*pos), " calculated: ",
// std::to_string(cPos));
// hexDump(moveable, answer->rdLen);
// hexDumpAt(buffer, *pos, answer->rdLen);
if(answer->rdLen == 4) if(answer->rdLen == 4)
{ {
answer->rData = new uint8_t[answer->rdLen]; answer->rData = new uint8_t[answer->rdLen];
memcpy(answer->rData, buffer, answer->rdLen); memcpy(answer->rData, moveable, answer->rdLen);
buffer += answer->rdLen; // advance the length llarp::LogDebug("Read ", std::to_string(answer->rData[0]), ".",
std::to_string(answer->rData[1]), ".",
std::to_string(answer->rData[2]), ".",
std::to_string(answer->rData[3]));
moveable += answer->rdLen;
(*pos) += answer->rdLen; // advance the length
} }
else else
{ {
llarp::LogDebug("Got type ", answer->type); llarp::LogDebug("Got type ", answer->type);
// FIXME: move this out of here, this shouldn't be responsible for decode
switch(answer->type) switch(answer->type)
{ {
case 5: case 5:
buffer += answer->rdLen; // advance the length moveable += answer->rdLen;
(*pos) += answer->rdLen; // advance the length
break; break;
case 6: // type 6 = SOA case 6: // type 6 = SOA
{ {
@ -223,18 +351,51 @@ extern "C"
llarp::LogDebug("expire : ", expire); llarp::LogDebug("expire : ", expire);
llarp::LogDebug("minimum : ", minimum); llarp::LogDebug("minimum : ", minimum);
*/ */
moveable += answer->rdLen;
(*pos) += answer->rdLen; // advance the length
} }
break; break;
case 12: case 12:
{ {
std::string revname = getDNSstring((char *)buffer); 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];
memcpy(answer->rData, revname.c_str(), answer->rdLen); memcpy(answer->rData, revname.c_str(), answer->rdLen);
moveable += answer->rdLen;
(*pos) += answer->rdLen; // advance the length
}
break;
case 15:
{
uint16_t priority = get16bits(moveable);
(*pos) += 2;
std::string revname = getDNSstring(buffer, pos);
llarp::LogInfo("MX: ", revname, " @ ", priority);
// answer->rData = new uint8_t[revname.length() + 1];
// memcpy(answer->rData, revname.c_str(), answer->rdLen);
answer->rData = (uint8_t *)strdup(revname.c_str());
moveable += answer->rdLen - 2; // advance the length
// llarp::LogInfo("leaving at ", std::to_string(*pos));
// hexDumpAt(buffer, *pos, 5);
// hexDump(moveable, 5);
}
break;
case 16:
{
// hexDump(buffer, 5);
// std::string revname = getDNSstring((char *)buffer);
llarp::LogInfo("TXT: size: ", answer->rdLen);
answer->rData = new uint8_t[answer->rdLen + 1];
memcpy(answer->rData, moveable + 1, answer->rdLen - 1);
answer->rData[answer->rdLen - 1] = 0; // terminate string
moveable += answer->rdLen;
(*pos) += answer->rdLen; // advance the length
} }
break; break;
// type 28 AAAA
default: default:
buffer += answer->rdLen; // advance the length moveable += answer->rdLen;
(*pos) += answer->rdLen; // advance the length
llarp::LogWarn("Unknown Type ", answer->type); llarp::LogWarn("Unknown Type ", answer->type);
break; break;
} }

@ -79,6 +79,50 @@ llarp_dotlokilookup_checkQuery(void *u, uint64_t orig, uint64_t left)
// in_addr ip_address = ((sockaddr_in *)free_private->hostResult)->sin_addr; // in_addr ip_address = ((sockaddr_in *)free_private->hostResult)->sin_addr;
llarp::service::Context *routerHiddenServiceContext =
(llarp::service::Context *)dll->user;
if(!routerHiddenServiceContext)
{
llarp::LogWarn("dotLokiLookup user isnt a service::Context: ", dll->user);
write404_dnss_response(qr->from, qr->request);
delete qr;
return;
}
llarp::huint32_t *tunIp =
new llarp::huint32_t(routerHiddenServiceContext->GetIpForAddr(addr));
if(!tunIp->h)
{
llarp::LogWarn("dotLokiLookup failed to map address");
write404_dnss_response(qr->from, qr->request);
delete qr;
return;
}
/*
bool mapResult = routerHiddenServiceContext->MapAddressAll(
addr, free_private->hostResult);
if(!mapResult)
{
llarp::LogWarn("dotLokiLookup failed to map address");
write404_dnss_response(qr->from, qr->request);
delete qr;
return;
}
*/
// make a dnsd_query_hook_response for the cache
dnsd_query_hook_response *response = new dnsd_query_hook_response;
response->dontLookUp = true;
response->dontSendResponse = false;
// llarp::Addr test(*free_private->hostResult.getSockAddr());
// llarp::LogInfo("IP Test: ", test);
// response->returnThis = &free_private->hostResult;
response->returnThis = tunIp;
llarp::LogInfo("Saving ", qr->request->question.name);
loki_tld_lookup_cache[qr->request->question.name] = response;
// we can't delete response now...
/* /*
llarp::handlers::TunEndpoint *tunEndpoint = llarp::handlers::TunEndpoint *tunEndpoint =
(llarp::handlers::TunEndpoint *)dll->user; (llarp::handlers::TunEndpoint *)dll->user;
@ -186,21 +230,19 @@ ReverseHandlerIter(struct llarp::service::Context::endpoint_iter *endpointCfg)
stoi(tokensSearch[searchTokens - 6]), stoi(tokensSearch[searchTokens - 6]),
stoi(tokensSearch[searchTokens - 5]), stoi(tokensSearch[searchTokens - 5]),
stoi(tokensSearch[searchTokens - 4]), stoi(tokensSearch[searchTokens - 4]),
stoi(tokensSearch[searchTokens stoi(tokensSearch[searchTokens - 3])); // create ip
- 3])); // create ip (llarp::Addr is untrustworthy atm)
llarp::huint32_t searchIPv4_search = llarp::ipaddr_ipv4_bits( llarp::huint32_t searchIPv4_search = llarp::ipaddr_ipv4_bits(
stoi(tokensSearch[searchTokens - 3]), stoi(tokensSearch[searchTokens - 3]),
stoi(tokensSearch[searchTokens - 4]), stoi(tokensSearch[searchTokens - 4]),
stoi(tokensSearch[searchTokens - 5]), stoi(tokensSearch[searchTokens - 5]),
stoi(tokensSearch[searchTokens stoi(tokensSearch[searchTokens - 6])); // create ip
- 6])); // create ip (llarp::Addr is untrustworthy atm)
// bool inRange = range.Contains(searchAddr.xtohl()); // bool inRange = range.Contains(searchAddr.xtohl());
bool inRange = range.Contains(searchIPv4_search); bool inRange = range.Contains(searchIPv4_search);
llarp::Addr searchAddr(searchIp); llarp::Addr searchAddr(searchIp);
llarp::Addr checkAddr(checkIp); llarp::Addr checkAddr(checkIp);
llarp::LogDebug(searchAddr, " vs ", range.ToString(), " = ", llarp::LogDebug(searchAddr, " vs ", range, " = ",
inRange ? "inRange" : "not match"); inRange ? "inRange" : "not match");
if(inRange) if(inRange)
@ -214,6 +256,7 @@ ReverseHandlerIter(struct llarp::service::Context::endpoint_iter *endpointCfg)
} }
else else
{ {
// llarp::LogInfo("Returning [", addr.ToString(), "]");
writesend_dnss_revresponse(addr.ToString(), context->from, writesend_dnss_revresponse(addr.ToString(), context->from,
(dnsd_question_request *)context->request); (dnsd_question_request *)context->request);
} }
@ -262,7 +305,7 @@ llarp_dotlokilookup_handler(std::string name, const struct sockaddr *from,
bool res = routerHiddenServiceContext->iterate(i); bool res = routerHiddenServiceContext->iterate(i);
if(!res) if(!res)
{ {
llarp::LogInfo("Reverse is ours"); llarp::LogDebug("Reverse is ours");
response->dontSendResponse = true; // should have already sent it response->dontSendResponse = true; // should have already sent it
} }
else else

@ -23,7 +23,8 @@ dns_iptracker_init()
// not sure we want tunGatewayIP... we'll know when we get further // not sure we want tunGatewayIP... we'll know when we get further
bool bool
dns_iptracker_setup_dotLokiLookup(dotLokiLookup *dll, llarp::Addr tunGatewayIp) dns_iptracker_setup_dotLokiLookup(dotLokiLookup *dll,
llarp::huint32_t tunGatewayIp)
{ {
dll->ip_tracker = &g_dns_iptracker; dll->ip_tracker = &g_dns_iptracker;
return true; return true;
@ -31,12 +32,13 @@ dns_iptracker_setup_dotLokiLookup(dotLokiLookup *dll, llarp::Addr tunGatewayIp)
// FIXME: pass in b32addr of client // FIXME: pass in b32addr of client
bool bool
dns_iptracker_setup(dns_iptracker *iptracker, llarp::Addr tunGatewayIp) dns_iptracker_setup(dns_iptracker *iptracker, llarp::huint32_t tunGatewayIp)
{ {
if(!iptracker) if(!iptracker)
iptracker = &g_dns_iptracker; // FIXME: god forgive I'm tired iptracker = &g_dns_iptracker; // FIXME: god forgive I'm tired
struct in_addr *addr = tunGatewayIp.addr4(); // struct in_addr *addr = tunGatewayIp.addr4();
unsigned char *ip = (unsigned char *)&(addr->s_addr); // unsigned char *ip = (unsigned char *)&(addr->s_addr);
unsigned char *ip = (unsigned char *)&(tunGatewayIp.h);
llarp::LogInfo("iptracker setup: (", std::to_string(ip[0]), ").[", llarp::LogInfo("iptracker setup: (", std::to_string(ip[0]), ").[",
std::to_string(ip[1]), '.', std::to_string(ip[2]), "].", std::to_string(ip[1]), '.', std::to_string(ip[2]), "].",
@ -90,7 +92,7 @@ dns_iptracker_allocate_range(std::unique_ptr< ip_range > &range, uint8_t first)
llarp::LogDebug("Allocated ", ip); llarp::LogDebug("Allocated ", ip);
// result->hostResult = new sockaddr; // result->hostResult = new sockaddr;
// ip.CopyInto(result->hostResult); // ip.CopyInto(result->hostResult);
result->hostResult = ip; result->hostResult = ip.xtohl();
// make an address and place into this sockaddr // make an address and place into this sockaddr
range->used[range->left + 2] = result; range->used[range->left + 2] = result;

@ -95,7 +95,7 @@ build_dns_packet(char *url, uint16_t id, uint16_t reqType)
dns_query * dns_query *
answer_request_alloc(struct dnsc_context *dnsc, void *sock, const char *url, answer_request_alloc(struct dnsc_context *dnsc, void *sock, const char *url,
dnsc_answer_hook_func resolved, void *user) dnsc_answer_hook_func resolved, void *user, uint16_t type)
{ {
std::unique_ptr< dnsc_answer_request > request(new dnsc_answer_request); std::unique_ptr< dnsc_answer_request > request(new dnsc_answer_request);
if(!request) if(!request)
@ -123,7 +123,7 @@ answer_request_alloc(struct dnsc_context *dnsc, void *sock, const char *url,
llarp::LogWarn("dnsc request question too long"); llarp::LogWarn("dnsc request question too long");
return nullptr; return nullptr;
} }
request->question.type = strstr(url, "in-addr.arpa") != nullptr ? 12 : 1; request->question.type = type;
request->question.qClass = 1; request->question.qClass = 1;
// register our self with the tracker // register our self with the tracker
@ -159,6 +159,7 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
// llarp::LogInfo("got a response, udp user is ", udp->user); // llarp::LogInfo("got a response, udp user is ", udp->user);
unsigned char *castBuf = (unsigned char *)buf; unsigned char *castBuf = (unsigned char *)buf;
char *const castBufc = (char *const)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((const char *)castBuf);
@ -230,15 +231,16 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
*/ */
// FIXME: only handling one atm // FIXME: only handling one atm
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((const char *)castBuf); question = decode_question(castBufc, &pos);
llarp::LogDebug("Read a question"); llarp::LogInfo("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
} }
// FIXME: only handling one atm // FIXME: only handling one atm
@ -246,16 +248,18 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
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++)
{ {
answer = decode_answer((const char *)castBuf); // pos = 0; // reset pos
answer = decode_answer(castBufc, &pos);
answers.push_back(answer); answers.push_back(answer);
llarp::LogDebug("Read an answer ", answer->type, " for ", llarp::LogInfo("Read an answer ", answer->type, " for ",
request->question.name); request->question.name, ", now at ", std::to_string(pos));
// llarp::LogInfo("Read an answer. Label Len: ", answer->name.length(), " // llarp::LogInfo("Read an answer. Label Len: ", answer->name.length(), "
// rdLen: ", answer->rdLen); // rdLen: ", answer->rdLen);
// name + Type (2) + Class (2) + TTL (4) + rdLen (2) + rdData + skip next // name + Type (2) + Class (2) + TTL (4) + rdLen (2) + rdData + skip next
// answer label (1) first 2 was answer->name.length() if lbl is ref and type // answer label (1) first 2 was answer->name.length() if lbl is ref and type
// 1: it should be 16 bytes long l0 + t2 + c2 + t4 + l2 + rd4 (14) + l2 // 1: it should be 16 bytes long l0 + t2 + c2 + t4 + l2 + rd4 (14) + l2
// (2) // (2)
/*
castBuf += 0 + 2 + 2 + 4 + 2 + answer->rdLen; castBuf += 0 + 2 + 2 + 4 + 2 + answer->rdLen;
castBuf += 2; // skip answer label castBuf += 2; // skip answer label
uint8_t first = *castBuf; uint8_t first = *castBuf;
@ -265,7 +269,9 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
std::to_string(first)); std::to_string(first));
castBuf++; castBuf++;
} }
*/
// prevent reading past the end of the packet // prevent reading past the end of the packet
/*
auto diff = castBuf - (unsigned char *)buf; auto diff = castBuf - (unsigned char *)buf;
llarp::LogDebug("Read answer, bytes left ", diff); llarp::LogDebug("Read answer, bytes left ", diff);
if(diff > sz) if(diff > sz)
@ -274,16 +280,33 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
// request->question.name); // request->question.name);
break; break;
} }
*/
if(pos > sz)
{
llarp::LogWarn("Would read past end of dns packet. for ",
request->question.name);
break;
}
/*
uint8_t first = castBufc[pos];
if(first != 0)
{
llarp::LogInfo("next byte isnt 12, skipping ahead one byte. ",
std::to_string(first));
pos++;
}
*/
} }
// handle authority records (usually no answers with these, so we'll just // handle authority records (usually no answers with these, so we'll just
// stomp) usually NS records tho // stomp) usually NS records tho
for(uint32_t i = 0; i < hdr->nsCount; i++) for(uint32_t i = 0; i < hdr->nsCount; i++)
{ {
answer = decode_answer((const char *)castBuf); // pos = 0; // reset pos
answer = decode_answer(castBufc, &pos);
// answers.push_back(answer); // answers.push_back(answer);
llarp::LogDebug("Read an authority"); llarp::LogDebug("Read an authority");
castBuf += answer->name.length() + 4 + 4 + 4 + answer->rdLen; // castBuf += answer->name.length() + 4 + 4 + 4 + answer->rdLen;
} }
/* /*
@ -336,6 +359,8 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
answer = answers.front(); answer = answers.front();
} }
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);
llarp::LogDebug("ans ttl ", answer->ttl); llarp::LogDebug("ans ttl ", answer->ttl);
@ -348,6 +373,7 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
llarp::LogInfo("ans2 rdlen ", answer2->rdLen); llarp::LogInfo("ans2 rdlen ", answer2->rdLen);
*/ */
llarp::LogDebug("rcode ", std::to_string(rcode));
if(rcode == 2) if(rcode == 2)
{ {
llarp::LogWarn("nameserver ", upstreamAddr, " returned SERVFAIL:"); llarp::LogWarn("nameserver ", upstreamAddr, " returned SERVFAIL:");
@ -370,11 +396,14 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
/* search for and print IPv4 addresses */ /* search for and print IPv4 addresses */
// if(dnsQuery->reqType == 0x01) // if(dnsQuery->reqType == 0x01)
llarp::LogDebug("request question type: ",
std::to_string(request->question.type));
if(request->question.type == 1) if(request->question.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, ":");
// llarp::LogDebug("Answer rdLen ", std::to_string(answer->rdLen));
if(answer->rdLen == 4) if(answer->rdLen == 4)
{ {
/* /*
@ -391,8 +420,18 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
ip[2] = answer->rData[2]; ip[2] = answer->rData[2];
ip[3] = answer->rData[3]; ip[3] = answer->rData[3];
*/ */
/*
request->result.from_4int(answer->rData[0], answer->rData[1], request->result.from_4int(answer->rData[0], answer->rData[1],
answer->rData[2], answer->rData[3]); answer->rData[2], answer->rData[3]);
*/
// llarp::LogDebug("Passing back IPv4: ",
// std::to_string(answer->rData[3]), ".", 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::Addr test(request->result);
// llarp::LogDebug(request->result); // llarp::LogDebug(request->result);
@ -416,14 +455,43 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
request->resolved(request); request->resolved(request);
return; return;
} }
else if(request->question.type == 15)
{
llarp::LogDebug("Resolving MX");
request->found = true;
request->result.h = 99;
request->revDNS = std::string((char *)answer->rData);
delete answer->rData;
request->resolved(request);
return;
}
else if(request->question.type == 16)
{
llarp::LogDebug("Resolving TXT");
request->found = true;
request->revDNS = std::string((char *)answer->rData);
request->resolved(request);
return;
}
else if(request->question.type == 28)
{
llarp::LogDebug("Resolving AAAA");
return;
}
llarp::LogWarn("Unhandled question type ", request->question.type);
} }
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)
{ {
if(strstr(url, "in-addr.arpa") != nullptr)
{
type = 12;
}
dns_query *dns_packet = dns_query *dns_packet =
answer_request_alloc(dnsc, nullptr, url, resolved, user); answer_request_alloc(dnsc, nullptr, url, resolved, user, type);
if(!dns_packet) if(!dns_packet)
{ {
llarp::LogError("Couldn't make dnsc packet"); llarp::LogError("Couldn't make dnsc packet");
@ -512,6 +580,10 @@ llarp_handle_dnsc_recvfrom(struct llarp_udp_io *const udp,
const struct sockaddr *saddr, const void *buf, const struct sockaddr *saddr, const void *buf,
const ssize_t sz) const ssize_t sz)
{ {
if(!saddr)
{
llarp::LogWarn("saddr isnt set");
}
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);
dns_msg_header *hdr = decode_hdr((const char *)castBuf); dns_msg_header *hdr = decode_hdr((const char *)castBuf);
@ -535,11 +607,18 @@ llarp_handle_dnsc_recvfrom(struct llarp_udp_io *const udp,
bool bool
llarp_resolve_host(struct dnsc_context *const dnsc, const char *url, llarp_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)
{ {
// FIXME: probably can be stack allocated // FIXME: probably can be stack allocated
/*
if (strstr(url, "in-addr.arpa") != nullptr)
{
type = 12;
}
*/
dns_query *dns_packet = dns_query *dns_packet =
answer_request_alloc(dnsc, &dnsc->udp, url, resolved, user); answer_request_alloc(dnsc, &dnsc->udp, url, resolved, user, type);
if(!dns_packet) if(!dns_packet)
{ {
llarp::LogError("Couldn't make dnsc packet"); llarp::LogError("Couldn't make dnsc packet");
@ -605,8 +684,9 @@ llarp_host_resolved(dnsc_answer_request *const request)
dns_tracker *tracker = (dns_tracker *)request->context->tracker; dns_tracker *tracker = (dns_tracker *)request->context->tracker;
auto val = std::find_if( auto val = std::find_if(
tracker->client_request.begin(), tracker->client_request.end(), tracker->client_request.begin(), tracker->client_request.end(),
[request](std::pair< const uint32_t, std::unique_ptr< dnsc_answer_request > > [request](
&element) { return element.second.get() == request; }); std::pair< const uint32_t, std::unique_ptr< dnsc_answer_request > >
&element) { return element.second.get() == request; });
if(val != tracker->client_request.end()) if(val != tracker->client_request.end())
{ {
tracker->client_request[val->first].reset(); tracker->client_request[val->first].reset();

@ -188,7 +188,7 @@ writesend_dnss_revresponse(std::string reverse, const struct sockaddr *from,
// 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(struct sockaddr *hostRes, const struct sockaddr *from, writesend_dnss_response(llarp::huint32_t *hostRes, const struct sockaddr *from,
dnsd_question_request *request) dnsd_question_request *request)
{ {
// llarp::Addr test(*from); // llarp::Addr test(*from);
@ -229,7 +229,12 @@ writesend_dnss_response(struct sockaddr *hostRes, const struct sockaddr *from,
put16bits(write_buffer, request->question.qClass); put16bits(write_buffer, request->question.qClass);
put32bits(write_buffer, 1); // ttl put32bits(write_buffer, 1); // ttl
put16bits(write_buffer, 4); // rdLength
// put32bits(write_buffer, xhtonl(*hostRes).n);
put32bits(write_buffer, hostRes->h);
// has to be a string of 4 bytes // has to be a string of 4 bytes
/*
struct sockaddr_in *sin = (struct sockaddr_in *)hostRes; struct sockaddr_in *sin = (struct sockaddr_in *)hostRes;
unsigned char *ip = (unsigned char *)&sin->sin_addr.s_addr; unsigned char *ip = (unsigned char *)&sin->sin_addr.s_addr;
@ -241,6 +246,95 @@ writesend_dnss_response(struct sockaddr *hostRes, const struct sockaddr *from,
*write_buffer++ = ip[1]; *write_buffer++ = ip[1];
*write_buffer++ = ip[2]; *write_buffer++ = ip[2];
*write_buffer++ = ip[3]; *write_buffer++ = ip[3];
*/
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);
}
void
writesend_dnss_mxresponse(uint16_t priority, std::string mx,
const struct sockaddr *from,
dnsd_question_request *request)
{
const size_t BUFFER_SIZE = 1024 + (request->question.name.size() * 2);
char buf[BUFFER_SIZE];
memset(buf, 0, BUFFER_SIZE);
char *write_buffer = buf;
char *bufferBegin = buf;
// build header
put16bits(write_buffer, request->id);
int fields = (1 << 15); // QR => message type, 1 = response
fields += (0 << 14); // I think opcode is always 0
fields += 0; // response code (3 => not found, 0 = Ok)
put16bits(write_buffer, fields);
put16bits(write_buffer, 1); // QD (number of questions)
put16bits(write_buffer, 1); // AN (number of answers)
put16bits(write_buffer, 0); // NS (number of auth RRs)
put16bits(write_buffer, 0); // AR (number of Additional RRs)
// code question
code_domain(write_buffer, request->question.name);
put16bits(write_buffer, request->question.type);
put16bits(write_buffer, request->question.qClass);
// code answer
llarp::LogDebug("Sending question name: ", request->question.name);
code_domain(write_buffer, request->question.name); // com, type=6, ttl=0
put16bits(write_buffer, request->question.type);
put16bits(write_buffer, request->question.qClass);
put32bits(write_buffer, 1); // ttl
put16bits(write_buffer, 2 + (mx.size() + 2)); // rdLength
put16bits(write_buffer, priority); // priority
code_domain(write_buffer, mx); //
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);
}
void
writesend_dnss_txtresponse(std::string txt, const struct sockaddr *from,
dnsd_question_request *request)
{
const size_t BUFFER_SIZE = 1024 + (request->question.name.size() * 2);
char buf[BUFFER_SIZE];
memset(buf, 0, BUFFER_SIZE);
char *write_buffer = buf;
char *bufferBegin = buf;
// build header
put16bits(write_buffer, request->id);
int fields = (1 << 15); // QR => message type, 1 = response
fields += (0 << 14); // I think opcode is always 0
fields += 0; // response code (3 => not found, 0 = Ok)
put16bits(write_buffer, fields);
put16bits(write_buffer, 1); // QD (number of questions)
put16bits(write_buffer, 1); // AN (number of answers)
put16bits(write_buffer, 0); // NS (number of auth RRs)
put16bits(write_buffer, 0); // AR (number of Additional RRs)
// code question
code_domain(write_buffer, request->question.name);
put16bits(write_buffer, request->question.type);
put16bits(write_buffer, request->question.qClass);
// code answer
llarp::LogDebug("Sending question name: ", request->question.name);
code_domain(write_buffer, request->question.name); // com, type=6, ttl=0
put16bits(write_buffer, request->question.type);
put16bits(write_buffer, request->question.qClass);
put32bits(write_buffer, 1); // ttl
put16bits(write_buffer, txt.size() + 2); // rdLength
*write_buffer = txt.size(); // write size
write_buffer++;
code_domain(write_buffer, txt); //
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");
@ -265,11 +359,27 @@ handle_dnsc_result(dnsc_answer_request *client_request)
writesend_dnss_revresponse(client_request->revDNS, server_request->from, writesend_dnss_revresponse(client_request->revDNS, server_request->from,
server_request); server_request);
} }
else if(client_request->question.type == 15)
{
writesend_dnss_mxresponse(client_request->result.h, client_request->revDNS,
server_request->from, server_request);
}
else if(client_request->question.type == 16)
{
llarp::LogInfo("Writing TXT ", client_request->revDNS);
writesend_dnss_txtresponse(client_request->revDNS, server_request->from,
server_request);
}
else else
{ {
struct sockaddr *useHostRes = nullptr; if(client_request->question.type != 1)
{
llarp::LogInfo("Returning type ", client_request->question.type,
" as standard");
}
llarp::huint32_t *useHostRes = nullptr;
if(client_request->found) if(client_request->found)
useHostRes = client_request->result; useHostRes = &client_request->result;
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);
@ -384,13 +494,15 @@ handle_recvfrom(const char *buffer, ssize_t nbytes, const struct sockaddr *from,
{ {
// make async request // make async request
llarp_resolve_host(&request->context->client, m_qName.c_str(), llarp_resolve_host(&request->context->client, m_qName.c_str(),
&handle_dnsc_result, (void *)request); &handle_dnsc_result, (void *)request,
request->question.type);
} }
else else
{ {
// make raw/sync request // make raw/sync request
raw_resolve_host(&request->context->client, m_qName.c_str(), raw_resolve_host(&request->context->client, m_qName.c_str(),
&handle_dnsc_result, (void *)request); &handle_dnsc_result, (void *)request,
request->question.type);
} }
} }

@ -11,7 +11,7 @@ namespace llarp
} }
Encrypted::Encrypted(const Encrypted& other) Encrypted::Encrypted(const Encrypted& other)
: Encrypted(other.data(), other.size()) : Encrypted(other.data(), other.size())
{ {
} }

@ -57,7 +57,14 @@ namespace llarp
return -1; return -1;
} }
if(ret > sz) if(ret > sz)
{
llarp::LogWarn("ret > sz");
return -1; return -1;
}
if(!addr)
{
llarp::LogWarn("no source addr");
}
// Addr is the source // Addr is the source
udp->recvfrom(udp, addr, buf, ret); udp->recvfrom(udp, addr, buf, ret);
return 0; return 0;

@ -51,7 +51,7 @@ namespace llarp
if(pos == std::string::npos) if(pos == std::string::npos)
{ {
llarp::LogError("Cannot map address ", v, llarp::LogError("Cannot map address ", v,
" invalid format, expects " " invalid format, missing colon (:), expects "
"address.loki:ip.address.goes.here"); "address.loki:ip.address.goes.here");
return false; return false;
} }
@ -105,31 +105,29 @@ namespace llarp
strncpy(tunif.ifaddr, addr.c_str(), sizeof(tunif.ifaddr) - 1); strncpy(tunif.ifaddr, addr.c_str(), sizeof(tunif.ifaddr) - 1);
// set up address in dotLokiLookup // set up address in dotLokiLookup
llarp::Addr tunIp(tunif.ifaddr); //llarp::Addr tunIp(tunif.ifaddr);
llarp::huint32_t tunIpV4;
tunIpV4.h = inet_addr(tunif.ifaddr);
// related to dns_iptracker_setup_dotLokiLookup(&this->dll, tunIp); // related to dns_iptracker_setup_dotLokiLookup(&this->dll, tunIp);
dns_iptracker_setup(this->dll.ip_tracker, dns_iptracker_setup(
tunIp); // claim GW IP to make sure it's not inuse this->dll.ip_tracker,
tunIpV4); // claim GW IP to make sure it's not inuse
return true; return true;
} }
return Endpoint::SetOption(k, v); return Endpoint::SetOption(k, v);
} }
/// ip should be in host byte order
bool bool
TunEndpoint::MapAddress(const service::Address &addr, huint32_t ip) TunEndpoint::MapAddress(const service::Address &addr, huint32_t ip)
{ {
nuint32_t nip = xhtonl(ip);
auto itr = m_IPToAddr.find(ip); auto itr = m_IPToAddr.find(ip);
if(itr != m_IPToAddr.end()) if(itr != m_IPToAddr.end())
{ {
// XXX is calling inet_ntoa safe in this context? it's MP-unsafe // XXX is calling inet_ntoa safe in this context? it's MP-unsafe
llarp::LogWarn(inet_ntoa({nip.n}), " already mapped to ", llarp::LogWarn(ip, " already mapped to ", itr->second.ToString());
itr->second.ToString());
return false; return false;
} }
llarp::LogInfo(Name() + " map ", addr.ToString(), " to ", llarp::LogInfo(Name() + " map ", addr.ToString(), " to ", ip);
inet_ntoa({nip.n}));
m_IPToAddr.insert(std::make_pair(ip, addr)); m_IPToAddr.insert(std::make_pair(ip, addr));
m_AddrToIP.insert(std::make_pair(addr, ip)); m_AddrToIP.insert(std::make_pair(addr, ip));
@ -149,11 +147,13 @@ namespace llarp
if(!NetworkIsIsolated()) if(!NetworkIsIsolated())
{ {
llarp::LogInfo("Setting up global DNS IP tracker"); llarp::LogInfo("Setting up global DNS IP tracker");
llarp::Addr tunIp(tunif.ifaddr); llarp::huint32_t tunIpV4;
tunIpV4.h = inet_addr(tunif.ifaddr);
dns_iptracker_setup_dotLokiLookup( dns_iptracker_setup_dotLokiLookup(
&this->dll, tunIp); // just set ups dll to use global iptracker &this->dll, tunIpV4); // just set ups dll to use global iptracker
dns_iptracker_setup(this->dll.ip_tracker, dns_iptracker_setup(
tunIp); // claim GW IP to make sure it's not inuse this->dll.ip_tracker,
tunIpV4); // claim GW IP to make sure it's not inuse
// set up networking in currrent thread if we are not isolated // set up networking in currrent thread if we are not isolated
if(!SetupNetworking()) if(!SetupNetworking())
@ -162,12 +162,15 @@ namespace llarp
else else
{ {
llarp::LogInfo("Setting up per netns DNS IP tracker"); llarp::LogInfo("Setting up per netns DNS IP tracker");
llarp::huint32_t tunIpV4;
tunIpV4.h = inet_addr(tunif.ifaddr);
llarp::Addr tunIp(tunif.ifaddr); llarp::Addr tunIp(tunif.ifaddr);
this->dll.ip_tracker = new dns_iptracker; this->dll.ip_tracker = new dns_iptracker;
dns_iptracker_setup_dotLokiLookup( dns_iptracker_setup_dotLokiLookup(
&this->dll, tunIp); // just set ups dll to use global iptracker &this->dll, tunIpV4); // just set ups dll to use global iptracker
dns_iptracker_setup(this->dll.ip_tracker, dns_iptracker_setup(
tunIp); // claim GW IP to make sure it's not inuse this->dll.ip_tracker,
tunIpV4); // claim GW IP to make sure it's not inuse
} }
// wait for result for network setup // wait for result for network setup
llarp::LogInfo("waiting for tun interface..."); llarp::LogInfo("waiting for tun interface...");
@ -237,11 +240,9 @@ namespace llarp
auto baseaddr = m_OurIP & xmask; auto baseaddr = m_OurIP & xmask;
m_MaxIP = baseaddr | ~xmask; m_MaxIP = baseaddr | ~xmask;
char buf[128] = {0};
llarp::LogInfo(Name(), " set ", tunif.ifname, " to have address ", lAddr); llarp::LogInfo(Name(), " set ", tunif.ifname, " to have address ", lAddr);
llarp::LogInfo(Name(), " allocated up to ", llarp::LogInfo(Name(), " allocated up to ", m_MaxIP);
inet_ntop(AF_INET, &m_MaxIP, buf, sizeof(buf)));
return true; return true;
} }
@ -298,8 +299,7 @@ namespace llarp
auto itr = m_IPToAddr.find(pkt.dst()); auto itr = m_IPToAddr.find(pkt.dst());
if(itr == m_IPToAddr.end()) if(itr == m_IPToAddr.end())
{ {
llarp::LogWarn(Name(), " has no endpoint for ", llarp::LogWarn(Name(), " has no endpoint for ", pkt.dst());
inet_ntoa({xhtonl(pkt.dst()).n}));
return true; return true;
} }
@ -318,9 +318,11 @@ namespace llarp
bool bool
TunEndpoint::ProcessDataMessage(service::ProtocolMessage *msg) TunEndpoint::ProcessDataMessage(service::ProtocolMessage *msg)
{ {
// llarp::LogInfo("got packet from ", msg->sender.Addr());
auto themIP = ObtainIPForAddr(msg->sender.Addr()); auto themIP = ObtainIPForAddr(msg->sender.Addr());
auto usIP = m_OurIP; // llarp::LogInfo("themIP ", themIP);
auto buf = llarp::Buffer(msg->payload); auto usIP = m_OurIP;
auto buf = llarp::Buffer(msg->payload);
if(m_NetworkToUserPktQueue.EmplaceIf( if(m_NetworkToUserPktQueue.EmplaceIf(
[buf, themIP, usIP](net::IPv4Packet &pkt) -> bool { [buf, themIP, usIP](net::IPv4Packet &pkt) -> bool {
// load // load
@ -346,7 +348,7 @@ namespace llarp
})) }))
llarp::LogDebug(Name(), " handle data message ", msg->payload.size(), llarp::LogDebug(Name(), " handle data message ", msg->payload.size(),
" bytes from ", inet_ntoa({xhtonl(themIP).n})); " bytes from ", themIP);
return true; return true;
} }
@ -357,9 +359,8 @@ namespace llarp
if(itr == m_IPToAddr.end()) if(itr == m_IPToAddr.end())
{ {
// not found // not found
// llarp::Addr test(ip); // "/", test,
service::Address addr; service::Address addr;
llarp::LogWarn(" not found in tun map. Sending ", addr.ToString()); llarp::LogWarn(ip, " not found in tun map. Sending ", addr.ToString());
return addr; return addr;
} }
// found // found
@ -394,8 +395,7 @@ namespace llarp
{ {
m_AddrToIP.insert(std::make_pair(addr, nextIP)); m_AddrToIP.insert(std::make_pair(addr, nextIP));
m_IPToAddr.insert(std::make_pair(nextIP, addr)); m_IPToAddr.insert(std::make_pair(nextIP, addr));
llarp::LogInfo(Name(), " mapped ", addr, " to ", llarp::LogInfo(Name(), " mapped ", addr, " to ", nextIP);
inet_ntoa({xhtonl(nextIP).n}));
MarkIPActive(nextIP); MarkIPActive(nextIP);
return nextIP; return nextIP;
} }

@ -94,6 +94,11 @@ namespace llarp
bool bool
InboundMessageParser::ProcessFrom(ILinkSession* src, llarp_buffer_t buf) InboundMessageParser::ProcessFrom(ILinkSession* src, llarp_buffer_t buf)
{ {
if(!src)
{
llarp::LogWarn("no link session");
return false;
}
reader.user = this; reader.user = this;
reader.on_key = &OnKey; reader.on_key = &OnKey;
from = src; from = src;

@ -11,6 +11,9 @@
#include <cstdio> #include <cstdio>
#include "logger.hpp" #include "logger.hpp"
//#include <llarp/net_inaddr.hpp>
#include <llarp/net_addr.hpp>
bool bool
operator==(const sockaddr& a, const sockaddr& b) operator==(const sockaddr& a, const sockaddr& b)
{ {

@ -138,6 +138,11 @@ namespace llarp
{ {
RouterID remote = ctx->path->Upstream(); RouterID remote = ctx->path->Upstream();
auto router = ctx->user->router; auto router = ctx->user->router;
if(!router)
{
llarp::LogError("null router");
return;
}
if(!router->SendToOrQueue(remote, &ctx->LRCM)) if(!router->SendToOrQueue(remote, &ctx->LRCM))
{ {
llarp::LogError("failed to send LRCM"); llarp::LogError("failed to send LRCM");

@ -139,8 +139,9 @@ namespace llarp
void void
PathSet::AddPath(Path* path) PathSet::AddPath(Path* path)
{ {
m_Paths.insert( auto upstream = path->Upstream(); // RouterID
std::make_pair(std::make_pair(path->Upstream(), path->RXID()), path)); auto RXID = path->RXID(); // PathID
m_Paths.insert(std::make_pair(std::make_pair(upstream, RXID), path));
} }
void void

@ -138,6 +138,20 @@ namespace llarp
addr, [](Address addr, void *ctx) {}, 10000); addr, [](Address addr, void *ctx) {}, 10000);
} }
huint32_t
Context::GetIpForAddr(const llarp::service::Address &addr)
{
llarp::handlers::TunEndpoint *tunEndpoint = this->getFirstTun();
if(!tunEndpoint)
{
huint32_t zero;
zero.h = 0;
llarp::LogError("No tunnel endpoint found");
return zero;
}
return tunEndpoint->ObtainIPForAddr(addr);
}
bool bool
Context::MapAddress(const llarp::service::Address &addr, huint32_t ip) Context::MapAddress(const llarp::service::Address &addr, huint32_t ip)
{ {

@ -1,10 +1,107 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <llarp/net.hpp> #include <llarp/net.hpp>
#include <llarp/net_inaddr.hpp>
struct NetTest : public ::testing::Test struct NetTest : public ::testing::Test
{ {
}; };
TEST_F(NetTest, TestinAddrFrom4Int)
{
llarp::inAddr test;
test.from4int(127, 0, 0, 1);
char str[INET6_ADDRSTRLEN];
if (inet_ntop(AF_INET, &test._addr, str, INET6_ADDRSTRLEN) == NULL) {
ASSERT_TRUE(false);
}
ASSERT_TRUE(strcmp("127.0.0.1", str) == 0);
}
TEST_F(NetTest, TestinAddrFromStr)
{
llarp::inAddr test;
test.from_char_array("127.0.0.1");
char str[INET6_ADDRSTRLEN];
if (inet_ntop(AF_INET, &test._addr, str, INET6_ADDRSTRLEN) == NULL) {
ASSERT_TRUE(false);
}
ASSERT_TRUE(strcmp("127.0.0.1", str) == 0);
}
TEST_F(NetTest, TestinAddrReset)
{
llarp::inAddr test;
test.from_char_array("127.0.0.1");
test.reset();
char str[INET6_ADDRSTRLEN];
if (inet_ntop(AF_INET, &test._addr, str, INET6_ADDRSTRLEN) == NULL) {
ASSERT_TRUE(false);
}
ASSERT_TRUE(strcmp("0.0.0.0", str) == 0);
}
TEST_F(NetTest, TestinAddrModeSet)
{
llarp::inAddr test;
test.from_char_array("127.0.0.1");
//test.hexDebug();
ASSERT_TRUE(test.isIPv4Mode());
// corrupt it
test._addr.s6_addr[10] = 0xfe;
test._addr.s6_addr[11] = 0xfe;
test.setIPv4Mode();
//test.hexDebug();
ASSERT_TRUE(test.isIPv4Mode());
}
TEST_F(NetTest, TestinAddrSIIT)
{
llarp::inAddr test;
test.from_char_array("127.0.0.1");
test.toSIIT();
//test.hexDebug();
ASSERT_TRUE(llarp::ipv6_is_siit(test._addr));
test.fromSIIT();
//test.hexDebug();
ASSERT_TRUE(!llarp::ipv6_is_siit(test._addr));
}
TEST_F(NetTest, TestinAddrN32)
{
llarp::inAddr test;
test.from_char_array("127.0.0.1");
llarp::nuint32_t netOrder = test.toN32();
llarp::inAddr test2;
test2.fromN32(netOrder);
char str[INET6_ADDRSTRLEN];
if (inet_ntop(AF_INET, &test2._addr, str, INET6_ADDRSTRLEN) == NULL) {
ASSERT_TRUE(false);
}
//printf("[%s]\n", str);
ASSERT_TRUE(strcmp("127.0.0.1", str) == 0);
}
TEST_F(NetTest, TestinAddrH32)
{
llarp::inAddr test;
test.from_char_array("127.0.0.1");
llarp::huint32_t netOrder = test.toH32();
llarp::inAddr test2;
test2.fromH32(netOrder);
char str[INET6_ADDRSTRLEN];
if (inet_ntop(AF_INET, &test2._addr, str, INET6_ADDRSTRLEN) == NULL) {
ASSERT_TRUE(false);
}
//printf("[%s]\n", str);
ASSERT_TRUE(strcmp("127.0.0.1", str) == 0);
}
TEST_F(NetTest, TestRangeContains8) TEST_F(NetTest, TestRangeContains8)
{ {
ASSERT_TRUE(llarp::iprange_ipv4(10, 0, 0, 0, 8) ASSERT_TRUE(llarp::iprange_ipv4(10, 0, 0, 0, 8)

@ -61,7 +61,8 @@ TEST_F(DNSTest, TestDecodeDNSstring)
{ {
char *buffer = (char *)this->buf; char *buffer = (char *)this->buf;
buffer += 12; // skip header buffer += 12; // skip header
std::string res = getDNSstring(buffer); uint32_t pos = 0;
std::string res = getDNSstring(buffer, &pos);
ASSERT_TRUE(res == "loki.network"); ASSERT_TRUE(res == "loki.network");
} }
@ -125,7 +126,8 @@ TEST_F(DNSTest, TestDecodeQuestion)
{ {
char *buffer = (char *)this->buf; char *buffer = (char *)this->buf;
buffer += 12; // skip header buffer += 12; // skip header
dns_msg_question *question = decode_question(buffer); uint32_t pos = 0;
dns_msg_question *question = decode_question(buffer, &pos);
//printf("name[%s]", question->name.c_str()); //printf("name[%s]", question->name.c_str());
//printf("type[%d]", question->type); //printf("type[%d]", question->type);
//printf("qClass[%d]", question->qClass); //printf("qClass[%d]", question->qClass);
@ -137,19 +139,20 @@ TEST_F(DNSTest, TestDecodeQuestion)
TEST_F(DNSTest, TestDecodeAnswer) TEST_F(DNSTest, TestDecodeAnswer)
{ {
char *buffer = (char *)this->buf; const char * const buffer = (const char * const)this->buf;
buffer += 12; // skip header uint32_t pos = 12;
std::string url = "loki.network"; std::string url = "loki.network";
buffer += url.length() + 1 + 4; pos += url.length() + 2 + 4; // skip question (string + 2 shorts)
buffer += 2; // FIXME: skip answer label
dns_msg_answer *answer = decode_answer(buffer); dns_msg_answer *answer = decode_answer(buffer, &pos);
/* /*
printf("type[%d]", answer->type); printf("type[%d]", answer->type);
printf("aClass[%d]", answer->aClass); printf("aClass[%d]", answer->aClass);
printf("ttl[%d]", answer->ttl); printf("ttl[%d]", answer->ttl);
printf("rdLen[%d]", answer->rdLen); printf("rdLen[%d]", answer->rdLen);
printf("[%zu].[%zu].[%zu].[%zu]", answer->rData[0], answer->rData[1], answer->rData[2], answer->rData[3]); printf("[%hhu].[%hhu].[%hhu].[%hhu]", answer->rData[0], answer->rData[1], answer->rData[2], answer->rData[3]);
*/ */
ASSERT_TRUE(answer->name == url);
ASSERT_TRUE(answer->type == 1); ASSERT_TRUE(answer->type == 1);
ASSERT_TRUE(answer->aClass == 1); ASSERT_TRUE(answer->aClass == 1);
ASSERT_TRUE(answer->ttl == 2123); ASSERT_TRUE(answer->ttl == 2123);

@ -55,8 +55,10 @@ TEST_F(llarpDNSdTest, TestNxDomain)
TEST_F(llarpDNSdTest, TestAResponse) TEST_F(llarpDNSdTest, TestAResponse)
{ {
sockaddr hostRes; llarp::huint32_t hostRes;
llarp::Zero(&hostRes, sizeof(sockaddr)); 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, nullptr, &test_request);
ASSERT_TRUE(g_length == 58); 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 6B 00 00 01 00 01 04 6C 6F 6B 69 07 6E 65 74 77 6F 72 6B 00 00 01 00 01 00 00 00 01 00 04 00 00 00 00 "; 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 6B 00 00 01 00 01 04 6C 6F 6B 69 07 6E 65 74 77 6F 72 6B 00 00 01 00 01 00 00 00 01 00 04 00 00 00 00 ";

Loading…
Cancel
Save