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
CC ?= cc
CC ?= cc
CXX ?= c++
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)
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)
debug: debug-configure
@ -116,7 +116,7 @@ shared-configure: clean
shared: shared-configure
$(MAKE) -C $(BUILD_ROOT)
testnet:
testnet:
cp $(EXE) $(TESTNET_EXE)
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
@ -148,3 +148,13 @@ install:
rm -f $(PREFIX)/bin/lokinet-bootstrap
cp $(REPO)/lokinet-bootstrap $(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>
#endif
#include <llarp/net.hpp> // for llarp::Addr
#include <llarp/net.hpp> // for llarp::Addr , llarp::huint32_t
struct dnsd_context;
@ -85,7 +85,7 @@ struct dns_packet
};
std::string
getDNSstring(const char *buffer);
getDNSstring(const char *const buffer, uint32_t *pos);
void
code_domain(char *&buffer, const std::string &domain) throw();
@ -102,10 +102,10 @@ extern "C"
decode_hdr(const char *buffer);
dns_msg_question *
decode_question(const char *buffer);
decode_question(const char *buffer, uint32_t *pos);
dns_msg_answer *
decode_answer(const char *buffer);
decode_answer(const char *const buffer, uint32_t *pos);
void
put16bits(char *&buffer, uint16_t value) throw();

@ -11,7 +11,7 @@
// neither, it's a result set row
struct dns_pointer
{
llarp::Addr hostResult;
llarp::huint32_t hostResult;
llarp::service::Address b32addr;
// we could store the timeout at which we expect it to be available
// 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_seven_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
dns_iptracker_init();
bool
dns_iptracker_setup_dotLokiLookup(dotLokiLookup *dll, llarp::Addr tunGatewayIp);
dns_iptracker_setup_dotLokiLookup(dotLokiLookup *dll,
llarp::huint32_t tunGatewayIp);
bool
dns_iptracker_setup(dns_iptracker *iptracker, llarp::Addr tunGatewayIp);
dns_iptracker_setup(dns_iptracker *iptracker, llarp::huint32_t tunGatewayIp);
struct dns_pointer *
dns_iptracker_get_free();

@ -41,7 +41,7 @@ struct dnsc_answer_request
dnsc_answer_hook_func resolved;
/// result
bool found;
llarp::Addr result;
llarp::huint32_t result;
std::string revDNS;
// a reference to dnsc_context incase of multiple contexts
struct dnsc_context *context;
@ -81,12 +81,14 @@ struct dnsc_context
/// async resolve a hostname using generic socks
void
raw_resolve_host(struct dnsc_context *const dnsc, const char *url,
dnsc_answer_hook_func resolved, void *const user);
dnsc_answer_hook_func resolved, void *const user,
uint16_t type);
/// async resolve a hostname using llarp platform framework
bool
llarp_resolve_host(struct dnsc_context *const dns, const char *url,
dnsc_answer_hook_func resolved, void *const user);
dnsc_answer_hook_func resolved, void *const user,
uint16_t type);
/// cleans up request structure allocations
void

@ -45,7 +45,7 @@ struct dnsd_query_hook_response
/// turn off recursion
bool dontLookUp;
/// potential address
sockaddr *returnThis; // FIXME: llarp::Addr
llarp::huint32_t *returnThis;
};
/// 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
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);
// FIXME: llarp::Addr

@ -18,7 +18,7 @@ namespace llarp
}
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,
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);
}

@ -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; }
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
{
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; }
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
{
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; }
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
{
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; }
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
{
inline size_t
@ -210,14 +254,15 @@ namespace llarp
return (addr & netmask_bits) == (ip & netmask_bits);
}
std::string
ToString() const
friend std::ostream&
operator<<(std::ostream& out, const IPRange& a)
{
char strbuf[32] = {0};
char netbuf[32] = {0};
inet_ntop(AF_INET, &addr, strbuf, sizeof(strbuf));
inet_ntop(AF_INET, &netmask_bits, netbuf, sizeof(netbuf));
return std::string(strbuf) + "/" + std::string(netbuf);
inet_ntop(AF_INET, &a.addr, strbuf, sizeof(strbuf));
inet_ntop(AF_INET, &a.netmask_bits, netbuf, sizeof(netbuf));
out << std::string(strbuf) + "/" + std::string(netbuf);
return out;
}
};
@ -268,510 +313,7 @@ namespace llarp
bool
IsBogonRange(const in6_addr& host, const in6_addr& mask);
struct Addr
{
// 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
struct Addr; // fwd declr
bool
AllInterfaces(int af, Addr& addr);
@ -794,4 +336,7 @@ namespace llarp
} // namespace llarp
#include <llarp/net_inaddr.hpp>
#include <llarp/net_addr.hpp>
#endif

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

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

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

@ -2,6 +2,28 @@
#include <llarp/dnsd.hpp> // for llarp_handle_dnsd_recvfrom, dnsc
#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
terminated by a label with zero length. <character-string> is a single
@ -10,25 +32,62 @@
length (including the length octet).
*/
std::string
getDNSstring(const char *buffer)
getDNSstring(const char *const buffer, uint32_t *pos)
{
std::string str = "";
uint8_t length = *buffer++;
std::string str = "";
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);
// llarp::LogInfo("dnsStringLen ", length);
// llarp::LogInfo("dnsStringLen ", std::to_string(length));
if(!length)
return str;
while(length != 0)
{
// llarp::LogInfo("Reading ", std::to_string(length));
for(int i = 0; i < length; i++)
{
char c = *buffer++;
char c = *moveable++;
(*pos)++;
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)
str.append(1, '.');
}
// llarp::LogInfo("Returning ", str);
return str;
}
@ -113,12 +172,23 @@ extern "C"
}
dns_msg_question *
decode_question(const char *buffer)
decode_question(const char *buffer, uint32_t *pos)
{
// char *start = (char *)buffer;
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);
// buffer += m_qName.size() + 1;
/*
@ -138,15 +208,20 @@ extern "C"
}
*/
question->name = m_qName;
question->type = get16bits(buffer);
question->type = get16bits(moveable);
(*pos) += 2;
// printf("Now1 at [%d]\n", buffer - start);
question->qClass = get16bits(buffer);
question->qClass = get16bits(moveable);
(*pos) += 2;
// 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;
}
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;
// skip for now until we can handle compressed labels
@ -162,42 +237,95 @@ extern "C"
llarp::DumpBuffer(bob);
*/
char hex_buffer[12 * 3 + 1];
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);
// hexDump(buffer, 10);
uint8_t first = *buffer++;
// llarp::LogInfo("decode - first", std::to_string(first));
const char *moveable = buffer;
// 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
if(first != 12 && first != 14) // 0x0c (c0 0c) 0
{
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);
if(answer->type > 259)
{
llarp::LogWarn("Answer type is off the charts");
}
answer->aClass = get16bits(buffer);
answer->ttl = get32bits(buffer);
answer->rdLen = get16bits(buffer);
answer->aClass = get16bits(moveable);
(*pos) += 2;
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)
{
answer->rData = new uint8_t[answer->rdLen];
memcpy(answer->rData, buffer, answer->rdLen);
buffer += answer->rdLen; // advance the length
memcpy(answer->rData, moveable, answer->rdLen);
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
{
llarp::LogDebug("Got type ", answer->type);
// FIXME: move this out of here, this shouldn't be responsible for decode
switch(answer->type)
{
case 5:
buffer += answer->rdLen; // advance the length
moveable += answer->rdLen;
(*pos) += answer->rdLen; // advance the length
break;
case 6: // type 6 = SOA
{
@ -223,18 +351,51 @@ extern "C"
llarp::LogDebug("expire : ", expire);
llarp::LogDebug("minimum : ", minimum);
*/
moveable += answer->rdLen;
(*pos) += answer->rdLen; // advance the length
}
break;
case 12:
{
std::string revname = getDNSstring((char *)buffer);
std::string revname = getDNSstring(buffer, pos);
llarp::LogInfo("revDNSname: ", revname);
answer->rData = new uint8_t[answer->rdLen + 1];
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;
// type 28 AAAA
default:
buffer += answer->rdLen; // advance the length
moveable += answer->rdLen;
(*pos) += answer->rdLen; // advance the length
llarp::LogWarn("Unknown Type ", answer->type);
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;
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 *)dll->user;
@ -186,21 +230,19 @@ ReverseHandlerIter(struct llarp::service::Context::endpoint_iter *endpointCfg)
stoi(tokensSearch[searchTokens - 6]),
stoi(tokensSearch[searchTokens - 5]),
stoi(tokensSearch[searchTokens - 4]),
stoi(tokensSearch[searchTokens
- 3])); // create ip (llarp::Addr is untrustworthy atm)
stoi(tokensSearch[searchTokens - 3])); // create ip
llarp::huint32_t searchIPv4_search = llarp::ipaddr_ipv4_bits(
stoi(tokensSearch[searchTokens - 3]),
stoi(tokensSearch[searchTokens - 4]),
stoi(tokensSearch[searchTokens - 5]),
stoi(tokensSearch[searchTokens
- 6])); // create ip (llarp::Addr is untrustworthy atm)
stoi(tokensSearch[searchTokens - 6])); // create ip
// bool inRange = range.Contains(searchAddr.xtohl());
bool inRange = range.Contains(searchIPv4_search);
llarp::Addr searchAddr(searchIp);
llarp::Addr checkAddr(checkIp);
llarp::LogDebug(searchAddr, " vs ", range.ToString(), " = ",
llarp::LogDebug(searchAddr, " vs ", range, " = ",
inRange ? "inRange" : "not match");
if(inRange)
@ -214,6 +256,7 @@ ReverseHandlerIter(struct llarp::service::Context::endpoint_iter *endpointCfg)
}
else
{
// llarp::LogInfo("Returning [", addr.ToString(), "]");
writesend_dnss_revresponse(addr.ToString(), context->from,
(dnsd_question_request *)context->request);
}
@ -262,7 +305,7 @@ llarp_dotlokilookup_handler(std::string name, const struct sockaddr *from,
bool res = routerHiddenServiceContext->iterate(i);
if(!res)
{
llarp::LogInfo("Reverse is ours");
llarp::LogDebug("Reverse is ours");
response->dontSendResponse = true; // should have already sent it
}
else

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

@ -95,7 +95,7 @@ build_dns_packet(char *url, uint16_t id, uint16_t reqType)
dns_query *
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);
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");
return nullptr;
}
request->question.type = strstr(url, "in-addr.arpa") != nullptr ? 12 : 1;
request->question.type = type;
request->question.qClass = 1;
// 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);
unsigned char *castBuf = (unsigned char *)buf;
char *const castBufc = (char *const)buf;
// auto buffer = llarp::StackBuffer< decltype(castBuf) >(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
uint32_t pos = 12; // just set after header
dns_msg_question *question = nullptr;
for(uint32_t i = 0; i < hdr->qdCount; i++)
{
question = decode_question((const char *)castBuf);
llarp::LogDebug("Read a question");
question = decode_question(castBufc, &pos);
llarp::LogInfo("Read a question, now at ", std::to_string(pos));
// 1 dot: 1 byte for length + length
// 4 bytes for class/type
castBuf += question->name.length() + 1 + 4;
castBuf += 2; // skip answer label
// castBuf += question->name.length() + 1 + 4;
// castBuf += 2; // skip answer label
}
// FIXME: only handling one atm
@ -246,16 +248,18 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
dns_msg_answer *answer = nullptr;
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);
llarp::LogDebug("Read an answer ", answer->type, " for ",
request->question.name);
llarp::LogInfo("Read an answer ", answer->type, " for ",
request->question.name, ", now at ", std::to_string(pos));
// llarp::LogInfo("Read an answer. Label Len: ", answer->name.length(), "
// rdLen: ", answer->rdLen);
// 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
// 1: it should be 16 bytes long l0 + t2 + c2 + t4 + l2 + rd4 (14) + l2
// (2)
/*
castBuf += 0 + 2 + 2 + 4 + 2 + answer->rdLen;
castBuf += 2; // skip answer label
uint8_t first = *castBuf;
@ -265,7 +269,9 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
std::to_string(first));
castBuf++;
}
*/
// prevent reading past the end of the packet
/*
auto diff = castBuf - (unsigned char *)buf;
llarp::LogDebug("Read answer, bytes left ", diff);
if(diff > sz)
@ -274,16 +280,33 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
// request->question.name);
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
// stomp) usually NS records tho
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);
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();
}
llarp::LogDebug("qus type ", question->type);
llarp::LogDebug("ans class ", answer->aClass);
llarp::LogDebug("ans type ", answer->type);
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::LogDebug("rcode ", std::to_string(rcode));
if(rcode == 2)
{
llarp::LogWarn("nameserver ", upstreamAddr, " returned SERVFAIL:");
@ -370,11 +396,14 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
/* search for and print IPv4 addresses */
// if(dnsQuery->reqType == 0x01)
llarp::LogDebug("request question type: ",
std::to_string(request->question.type));
if(request->question.type == 1)
{
// llarp::LogInfo("DNS server's answer is: (type#=", ATYPE, "):");
llarp::LogDebug("IPv4 address(es) for ", request->question.name, ":");
// llarp::LogDebug("Answer rdLen ", std::to_string(answer->rdLen));
if(answer->rdLen == 4)
{
/*
@ -391,8 +420,18 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
ip[2] = answer->rData[2];
ip[3] = answer->rData[3];
*/
/*
request->result.from_4int(answer->rData[0], answer->rData[1],
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::LogDebug(request->result);
@ -416,14 +455,43 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
request->resolved(request);
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
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 =
answer_request_alloc(dnsc, nullptr, url, resolved, user);
answer_request_alloc(dnsc, nullptr, url, resolved, user, type);
if(!dns_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 ssize_t sz)
{
if(!saddr)
{
llarp::LogWarn("saddr isnt set");
}
unsigned char *castBuf = (unsigned char *)buf;
// auto buffer = llarp::StackBuffer< decltype(castBuf) >(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
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
/*
if (strstr(url, "in-addr.arpa") != nullptr)
{
type = 12;
}
*/
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)
{
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;
auto val = std::find_if(
tracker->client_request.begin(), tracker->client_request.end(),
[request](std::pair< const uint32_t, std::unique_ptr< dnsc_answer_request > >
&element) { return element.second.get() == request; });
[request](
std::pair< const uint32_t, std::unique_ptr< dnsc_answer_request > >
&element) { return element.second.get() == request; });
if(val != tracker->client_request.end())
{
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
// otherwise ttl, type and class can't be relayed correctly
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)
{
// llarp::Addr test(*from);
@ -229,7 +229,12 @@ writesend_dnss_response(struct sockaddr *hostRes, const struct sockaddr *from,
put16bits(write_buffer, request->question.qClass);
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
/*
struct sockaddr_in *sin = (struct sockaddr_in *)hostRes;
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[2];
*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;
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,
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
{
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)
useHostRes = client_request->result;
useHostRes = &client_request->result;
writesend_dnss_response(useHostRes, server_request->from, server_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
llarp_resolve_host(&request->context->client, m_qName.c_str(),
&handle_dnsc_result, (void *)request);
&handle_dnsc_result, (void *)request,
request->question.type);
}
else
{
// make raw/sync request
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(other.data(), other.size())
: Encrypted(other.data(), other.size())
{
}

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

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

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

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

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

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

@ -138,6 +138,20 @@ namespace llarp
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
Context::MapAddress(const llarp::service::Address &addr, huint32_t ip)
{

@ -1,10 +1,107 @@
#include <gtest/gtest.h>
#include <llarp/net.hpp>
#include <llarp/net_inaddr.hpp>
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)
{
ASSERT_TRUE(llarp::iprange_ipv4(10, 0, 0, 0, 8)

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

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