mirror of
https://github.com/oxen-io/lokinet
synced 2023-12-14 06:53:00 +01:00
Merge remote-tracking branch 'ryan/master'
This commit is contained in:
commit
7c3f80e84b
29 changed files with 1729 additions and 632 deletions
|
@ -236,6 +236,9 @@ set(LIB_PLATFORM_SRC
|
|||
llarp/mem.cpp
|
||||
# for networking
|
||||
llarp/ev.cpp
|
||||
llarp/net.cpp
|
||||
llarp/net_addr.cpp
|
||||
llarp/net_inaddr.cpp
|
||||
# for timer
|
||||
llarp/time.cpp
|
||||
# for logic
|
||||
|
@ -408,7 +411,6 @@ set(LIB_SRC
|
|||
llarp/ip.cpp
|
||||
llarp/link_intro.cpp
|
||||
llarp/link_message.cpp
|
||||
llarp/net.cpp
|
||||
llarp/nodedb.cpp
|
||||
llarp/path.cpp
|
||||
llarp/pathbuilder.cpp
|
||||
|
@ -490,6 +492,9 @@ set(CLIENT_SRC
|
|||
include_directories(include)
|
||||
# TODO: exclude this from includes and expose stuff properly for rcutil
|
||||
include_directories(llarp)
|
||||
#include_directories(include)
|
||||
#include_directories(vendor/cppbackport-master/lib)
|
||||
#include_directories(${sodium_INCLUDE_DIR})
|
||||
|
||||
set(RC_EXE rcutil)
|
||||
set(DNS_EXE dns)
|
||||
|
|
11
Makefile
11
Makefile
|
@ -71,7 +71,6 @@ release-configure: clean
|
|||
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) -DCMAKE_ASM_FLAGS='$(ASFLAGS)' -DCMAKE_C_FLAGS='$(CFLAGS)' -DCMAKE_CXX_FLAGS='$(CXXFLAGS)'
|
||||
|
||||
|
||||
debug: debug-configure
|
||||
$(MAKE) -C $(BUILD_ROOT)
|
||||
cp $(EXE) lokinet
|
||||
|
@ -157,3 +156,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
|
||||
|
||||
|
|
|
@ -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,512 +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);
|
||||
}
|
||||
|
||||
Addr(string_view addr_str, string_view port_str)
|
||||
{
|
||||
this->from_char_array(llarp::string_view_string(addr_str).c_str());
|
||||
this->port(std::stoi(llarp::string_view_string(port_str)));
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
if(inet_ntop(a.af(), ptr, tmp, sizeof(tmp)))
|
||||
{
|
||||
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);
|
||||
|
@ -796,4 +336,7 @@ namespace llarp
|
|||
|
||||
} // namespace llarp
|
||||
|
||||
#include <llarp/net_inaddr.hpp>
|
||||
#include <llarp/net_addr.hpp>
|
||||
|
||||
#endif
|
||||
|
|
173
include/llarp/net_addr.hpp
Normal file
173
include/llarp/net_addr.hpp
Normal file
|
@ -0,0 +1,173 @@
|
|||
#ifndef LLARP_NET_ADDR_HPP
|
||||
#define LLARP_NET_ADDR_HPP
|
||||
#include <string>
|
||||
#include <llarp/net.h>
|
||||
#include <llarp/address_info.hpp>
|
||||
#include <llarp/string_view.hpp>
|
||||
|
||||
#include <llarp/net.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
// fwd declr
|
||||
struct huint32_t;
|
||||
struct nuint32_t;
|
||||
|
||||
// real work
|
||||
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);
|
||||
|
||||
void
|
||||
port(uint16_t port);
|
||||
|
||||
in6_addr*
|
||||
addr6();
|
||||
|
||||
in_addr*
|
||||
addr4();
|
||||
|
||||
const in6_addr*
|
||||
addr6() const;
|
||||
|
||||
const in_addr*
|
||||
addr4() const;
|
||||
|
||||
Addr(const std::string str);
|
||||
|
||||
Addr(const std::string str, const uint16_t p_port);
|
||||
|
||||
Addr(string_view addr_str, string_view port_str);
|
||||
|
||||
bool
|
||||
from_char_array(const char* str);
|
||||
|
||||
Addr(const char* str);
|
||||
|
||||
bool
|
||||
from_4int(const uint8_t one, const uint8_t two, const uint8_t three,
|
||||
const uint8_t four);
|
||||
|
||||
Addr(const uint8_t one, const uint8_t two, const uint8_t three,
|
||||
const uint8_t four);
|
||||
|
||||
Addr(const uint8_t one, const uint8_t two, const uint8_t three,
|
||||
const uint8_t four, const uint16_t p_port);
|
||||
|
||||
Addr(const AddressInfo& other);
|
||||
Addr(const sockaddr_in& other);
|
||||
Addr(const sockaddr_in6& other);
|
||||
Addr(const sockaddr& other);
|
||||
|
||||
std::string
|
||||
ToString() const;
|
||||
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& out, const Addr& a);
|
||||
|
||||
operator const sockaddr*() const;
|
||||
|
||||
operator sockaddr*() const;
|
||||
|
||||
void
|
||||
CopyInto(sockaddr* other) const;
|
||||
|
||||
int
|
||||
af() const;
|
||||
|
||||
uint16_t
|
||||
port() const;
|
||||
|
||||
bool
|
||||
operator<(const Addr& other) const;
|
||||
|
||||
bool
|
||||
operator==(const Addr& other) const;
|
||||
|
||||
Addr&
|
||||
operator=(const sockaddr& other);
|
||||
|
||||
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;
|
||||
|
||||
bool
|
||||
operator!=(const Addr& other) const;
|
||||
|
||||
inline uint32_t
|
||||
getHostLong()
|
||||
{
|
||||
in_addr_t addr = this->addr4()->s_addr;
|
||||
uint32_t byte = ntohl(addr);
|
||||
return byte;
|
||||
};
|
||||
|
||||
bool
|
||||
isTenPrivate(uint32_t byte);
|
||||
|
||||
bool
|
||||
isOneSevenPrivate(uint32_t byte);
|
||||
|
||||
bool
|
||||
isOneNinePrivate(uint32_t byte);
|
||||
|
||||
/// return true if our ipv4 address is a bogon
|
||||
/// TODO: ipv6
|
||||
bool
|
||||
IsBogon() const;
|
||||
|
||||
socklen_t
|
||||
SockLen() const;
|
||||
|
||||
bool
|
||||
isPrivate() const;
|
||||
|
||||
bool
|
||||
isLoopback() const;
|
||||
|
||||
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();
|
||||
}
|
||||
};
|
||||
}; // end struct
|
||||
} // namespace llarp
|
||||
#endif
|
81
include/llarp/net_inaddr.hpp
Normal file
81
include/llarp/net_inaddr.hpp
Normal file
|
@ -0,0 +1,81 @@
|
|||
#ifndef LLARP_NET_INADDR_HPP
|
||||
#define LLARP_NET_INADDR_HPP
|
||||
|
||||
#include <llarp/net.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
/// IPv4 or IPv6 holder
|
||||
struct inAddr
|
||||
{
|
||||
// unsigned char s6_addr[16];
|
||||
struct in6_addr _addr; // store in network order
|
||||
|
||||
/// zero out
|
||||
void
|
||||
reset();
|
||||
|
||||
/// from char*
|
||||
bool
|
||||
from_char_array(const char* str);
|
||||
|
||||
/// convert from SIIT to IPv4 Mode
|
||||
void
|
||||
fromSIIT();
|
||||
|
||||
/// convert from IPv4 Mode to SIIT
|
||||
void
|
||||
toSIIT();
|
||||
|
||||
/// not IPv4 Mode (an actual IPv6 address)
|
||||
inline bool
|
||||
isIPv6Mode() const;
|
||||
|
||||
/// IPv4 mode (not SIIT)
|
||||
bool
|
||||
isIPv4Mode() const;
|
||||
|
||||
/// clear out bytes 5-15 (Last 12 bytes)
|
||||
/// This is how inet_pton works with IPv4 addresses
|
||||
void
|
||||
setIPv4Mode();
|
||||
|
||||
/// make debugging/testing easier
|
||||
void
|
||||
hexDebug();
|
||||
|
||||
//
|
||||
// IPv4 specific functions
|
||||
//
|
||||
|
||||
/// make ipv4 in_addr struct
|
||||
in_addr
|
||||
toIAddr();
|
||||
|
||||
/// set an IPv4 addr
|
||||
void
|
||||
from4int(const uint8_t one, const uint8_t two, const uint8_t three,
|
||||
const uint8_t four);
|
||||
|
||||
/// set from an net-order uint32_t
|
||||
void
|
||||
fromN32(nuint32_t in);
|
||||
/// set from an host-order uint32_t
|
||||
void
|
||||
fromH32(huint32_t in);
|
||||
/// output as net-order uint32_t
|
||||
nuint32_t
|
||||
toN32();
|
||||
/// output as host-order uint32_t
|
||||
huint32_t
|
||||
toH32();
|
||||
|
||||
//
|
||||
// IPv6 specific functions
|
||||
//
|
||||
// coming soon
|
||||
};
|
||||
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
|
@ -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
|
||||
|
|
219
llarp/dns.cpp
219
llarp/dns.cpp
|
@ -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::LogDebug("Got question name: ", m_qName);
|
||||
// llarp::LogInfo("Started at ", std::to_string(start), " ended at: ",
|
||||
// std::to_string(*pos)); llarp::LogInfo("Advancing question buffer by ",
|
||||
// std::to_string(*pos)); buffer += (*pos) - start; buffer +=
|
||||
// m_qName.length() + 2; // + length byte & ending terminator
|
||||
|
||||
const char *moveable = buffer;
|
||||
moveable += *pos; // advance to position
|
||||
// hexDump(moveable, 4);
|
||||
|
||||
// printf("Now0 at [%d]\n", buffer - start);
|
||||
// buffer += m_qName.size() + 1;
|
||||
/*
|
||||
|
@ -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::LogDebug("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;
|
||||
|
@ -94,8 +138,6 @@ llarp_dotlokilookup_checkQuery(void *u, uint64_t orig, uint64_t left)
|
|||
return;
|
||||
}
|
||||
*/
|
||||
llarp::service::Context *routerHiddenServiceContext =
|
||||
(llarp::service::Context *)dll->user;
|
||||
llarp::huint32_t foundAddr;
|
||||
if(!routerHiddenServiceContext->FindBestAddressFor(addr, foundAddr))
|
||||
{
|
||||
|
@ -112,12 +154,12 @@ llarp_dotlokilookup_checkQuery(void *u, uint64_t orig, uint64_t left)
|
|||
loki_tld_lookup_cache[addr.ToString()]=response;
|
||||
*/
|
||||
// we can't delete response now...
|
||||
sockaddr_in saddr;
|
||||
saddr.sin_family = AF_INET;
|
||||
saddr.sin_addr.s_addr = llarp::xhtonl(foundAddr).n;
|
||||
// sockaddr_in saddr;
|
||||
// saddr.sin_family = AF_INET;
|
||||
// saddr.sin_addr.s_addr = llarp::xhtonl(foundAddr).n;
|
||||
// FIXME: flush cache to disk
|
||||
// on crash we'll need to bring up all the same IPs we assigned before...
|
||||
writesend_dnss_response((sockaddr *)&saddr, qr->from, qr->request);
|
||||
writesend_dnss_response(&foundAddr, qr->from, qr->request);
|
||||
delete qr;
|
||||
return;
|
||||
}
|
||||
|
@ -186,21 +228,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 +254,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 +303,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
|
||||
|
@ -295,6 +336,15 @@ llarp_dotlokilookup_handler(std::string name, const struct sockaddr *from,
|
|||
}
|
||||
llarp::LogDebug("Base32 decoded address ", addr);
|
||||
|
||||
dotLokiLookup *dll = (dotLokiLookup *)request->context->user;
|
||||
llarp::service::Context *routerHiddenServiceContext =
|
||||
(llarp::service::Context *)dll->user;
|
||||
if(!routerHiddenServiceContext)
|
||||
{
|
||||
llarp::LogWarn("dotLokiLookup user isnt a service::Context: ", dll->user);
|
||||
return response;
|
||||
}
|
||||
|
||||
// start path build early (if you're looking it up, you're probably going to
|
||||
// use it)
|
||||
// main_router_prefetch(ctx, addr);
|
||||
|
@ -303,6 +353,15 @@ llarp_dotlokilookup_handler(std::string name, const struct sockaddr *from,
|
|||
check_query_simple_request *qr = new check_query_simple_request;
|
||||
qr->from = from;
|
||||
qr->request = request;
|
||||
|
||||
auto tun = routerHiddenServiceContext->getFirstTun();
|
||||
if(tun->HasPathToService(addr))
|
||||
{
|
||||
llarp_dotlokilookup_checkQuery(qr, 0, 0);
|
||||
response->dontSendResponse = true; // will send it shortly
|
||||
return response;
|
||||
}
|
||||
|
||||
// nslookup on osx is about 5 sec before a retry, 2s on linux
|
||||
llarp_logic_call_later(request->context->client.logic,
|
||||
{2000, qr, &llarp_dotlokilookup_checkQuery});
|
||||
|
|
|
@ -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;
|
||||
|
|
108
llarp/dnsc.cpp
108
llarp/dnsc.cpp
|
@ -93,7 +93,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)
|
||||
|
@ -121,7 +121,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
|
||||
|
@ -157,6 +157,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);
|
||||
|
||||
|
@ -228,15 +229,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::LogDebug("Read a question, now at ", std::to_string(pos));
|
||||
// 1 dot: 1 byte for length + length
|
||||
// 4 bytes for class/type
|
||||
castBuf += question->name.length() + 1 + 4;
|
||||
castBuf += 2; // skip answer label
|
||||
// castBuf += question->name.length() + 1 + 4;
|
||||
// castBuf += 2; // skip answer label
|
||||
}
|
||||
|
||||
// FIXME: only handling one atm
|
||||
|
@ -244,16 +246,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);
|
||||
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;
|
||||
|
@ -263,7 +267,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)
|
||||
|
@ -272,16 +278,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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -335,6 +358,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);
|
||||
|
@ -347,6 +372,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:");
|
||||
|
@ -369,11 +395,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)
|
||||
{
|
||||
/*
|
||||
|
@ -390,8 +419,19 @@ 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);
|
||||
|
@ -415,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");
|
||||
|
@ -511,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);
|
||||
|
@ -534,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");
|
||||
|
|
122
llarp/dnsd.cpp
122
llarp/dnsd.cpp
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -173,7 +173,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)
|
||||
{
|
||||
|
|
486
llarp/net_addr.cpp
Normal file
486
llarp/net_addr.cpp
Normal file
|
@ -0,0 +1,486 @@
|
|||
#include <llarp/net_addr.hpp>
|
||||
|
||||
#include <llarp/net.hpp>
|
||||
#include <llarp/string_view.hpp>
|
||||
|
||||
// for addrinfo
|
||||
#ifndef _WIN32
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#else
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <wspiapi.h>
|
||||
#define inet_aton(x, y) inet_pton(AF_INET, x, y)
|
||||
#endif
|
||||
|
||||
llarp::Addr::operator const sockaddr*() const
|
||||
{
|
||||
if(af() == AF_INET)
|
||||
return (const sockaddr*)&_addr4;
|
||||
else
|
||||
return (const sockaddr*)&_addr;
|
||||
}
|
||||
|
||||
llarp::Addr::operator sockaddr*() const
|
||||
{
|
||||
if(af() == AF_INET)
|
||||
return (sockaddr*)&_addr4;
|
||||
else
|
||||
return (sockaddr*)&_addr;
|
||||
}
|
||||
|
||||
bool
|
||||
llarp::Addr::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
|
||||
llarp::Addr::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();
|
||||
}
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
Addr::Addr(){};
|
||||
Addr::~Addr(){};
|
||||
|
||||
Addr::Addr(const Addr& other)
|
||||
{
|
||||
memcpy(&_addr, &other._addr, sizeof(sockaddr_in6));
|
||||
memcpy(&_addr4, &other._addr4, sizeof(sockaddr_in));
|
||||
}
|
||||
|
||||
void
|
||||
Addr::port(uint16_t port)
|
||||
{
|
||||
if(af() == AF_INET)
|
||||
{
|
||||
_addr4.sin_port = htons(port);
|
||||
}
|
||||
_addr.sin6_port = htons(port);
|
||||
}
|
||||
|
||||
in6_addr*
|
||||
Addr::addr6()
|
||||
{
|
||||
return (in6_addr*)&_addr.sin6_addr.s6_addr[0];
|
||||
}
|
||||
|
||||
in_addr*
|
||||
Addr::addr4()
|
||||
{
|
||||
return (in_addr*)&_addr.sin6_addr.s6_addr[12];
|
||||
}
|
||||
|
||||
const in6_addr*
|
||||
Addr::addr6() const
|
||||
{
|
||||
return (const in6_addr*)&_addr.sin6_addr.s6_addr[0];
|
||||
}
|
||||
|
||||
const in_addr*
|
||||
Addr::addr4() const
|
||||
{
|
||||
return (const in_addr*)&_addr.sin6_addr.s6_addr[12];
|
||||
}
|
||||
|
||||
Addr::Addr(const std::string str)
|
||||
{
|
||||
this->from_char_array(str.c_str());
|
||||
}
|
||||
|
||||
Addr::Addr(const std::string str, const uint16_t p_port)
|
||||
{
|
||||
this->from_char_array(str.c_str());
|
||||
this->port(p_port);
|
||||
}
|
||||
|
||||
Addr::Addr(string_view addr_str, string_view port_str)
|
||||
{
|
||||
this->from_char_array(llarp::string_view_string(addr_str).c_str());
|
||||
this->port(std::stoi(llarp::string_view_string(port_str)));
|
||||
}
|
||||
|
||||
bool
|
||||
Addr::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::Addr(const char* str)
|
||||
{
|
||||
this->from_char_array(str);
|
||||
}
|
||||
|
||||
bool
|
||||
Addr::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::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::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::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::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::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::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
|
||||
Addr::ToString() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << (*this);
|
||||
return std::string(ss.str().c_str());
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
if(inet_ntop(a.af(), (void*)ptr, tmp, sizeof(tmp)))
|
||||
{
|
||||
out << tmp;
|
||||
if(a.af() == AF_INET6)
|
||||
out << "]";
|
||||
}
|
||||
return out << ":" << a.port();
|
||||
}
|
||||
|
||||
void
|
||||
Addr::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
|
||||
Addr::af() const
|
||||
{
|
||||
return _addr.sin6_family;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
Addr::port() const
|
||||
{
|
||||
return ntohs(_addr.sin6_port);
|
||||
}
|
||||
|
||||
Addr&
|
||||
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;
|
||||
}
|
||||
|
||||
bool
|
||||
Addr::sameAddr(const Addr& other) const
|
||||
{
|
||||
return memcmp(addr6(), other.addr6(), 16) == 0;
|
||||
}
|
||||
|
||||
bool
|
||||
Addr::operator!=(const Addr& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
bool
|
||||
Addr::isTenPrivate(uint32_t byte)
|
||||
{
|
||||
uint8_t byte1 = byte >> 24 & 0xff;
|
||||
return byte1 == 10;
|
||||
}
|
||||
|
||||
bool
|
||||
Addr::isOneSevenPrivate(uint32_t byte)
|
||||
{
|
||||
uint8_t byte1 = byte >> 24 & 0xff;
|
||||
uint8_t byte2 = (0x00ff0000 & byte) >> 16;
|
||||
return byte1 == 172 && (byte2 >= 16 || byte2 <= 31);
|
||||
}
|
||||
|
||||
bool
|
||||
Addr::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
|
||||
Addr::IsBogon() const
|
||||
{
|
||||
return IsIPv4Bogon(xtohl());
|
||||
}
|
||||
|
||||
socklen_t
|
||||
Addr::SockLen() const
|
||||
{
|
||||
if(af() == AF_INET)
|
||||
return sizeof(sockaddr_in);
|
||||
else
|
||||
return sizeof(sockaddr_in6);
|
||||
}
|
||||
|
||||
bool
|
||||
Addr::isPrivate() const
|
||||
{
|
||||
return IsBogon();
|
||||
}
|
||||
|
||||
bool
|
||||
Addr::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();
|
||||
}
|
||||
}; // end struct Hash
|
||||
} // namespace llarp
|
230
llarp/net_inaddr.cpp
Normal file
230
llarp/net_inaddr.cpp
Normal file
|
@ -0,0 +1,230 @@
|
|||
#include <llarp/net_inaddr.hpp>
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& out, const llarp::inAddr& a)
|
||||
{
|
||||
char tmp[128] = {0};
|
||||
if(a.isIPv6Mode())
|
||||
{
|
||||
out << "[";
|
||||
}
|
||||
if(inet_ntop(a.isIPv4Mode() ? AF_INET : AF_INET6, (void*)&a._addr, tmp,
|
||||
sizeof(tmp)))
|
||||
{
|
||||
out << tmp;
|
||||
if(a.isIPv6Mode())
|
||||
out << "]";
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
void
|
||||
inAddr::reset()
|
||||
{
|
||||
llarp::Zero(&this->_addr, sizeof(in6_addr));
|
||||
}
|
||||
|
||||
bool
|
||||
inAddr::from_char_array(const char* str)
|
||||
{
|
||||
this->reset();
|
||||
|
||||
// maybe refactor the family detection out
|
||||
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_INET && res->ai_family != AF_INET6)
|
||||
{
|
||||
llarp::LogError("Address family not supported yet", str);
|
||||
return false;
|
||||
}
|
||||
|
||||
// convert detected-family (ipv4 or ipv6) str to in6_addr
|
||||
|
||||
/*
|
||||
if (res->ai_family == AF_INET)
|
||||
{
|
||||
freeaddrinfo(res);
|
||||
// get IPv4
|
||||
struct in_addr addr; // basically a uint32_t network order
|
||||
if(inet_aton(str, &addr) == 0)
|
||||
{
|
||||
llarp::LogError("failed to parse ", str);
|
||||
return false;
|
||||
}
|
||||
nuint32_t result;
|
||||
result.n = addr.s_addr;
|
||||
this->fromN32(result);
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
ret = inet_pton(res->ai_family, str, &this->_addr);
|
||||
// inet_pton won't set SIIT
|
||||
// this->hexDebug();
|
||||
freeaddrinfo(res);
|
||||
if(ret <= 0)
|
||||
{
|
||||
if(ret == 0)
|
||||
{
|
||||
llarp::LogWarn("Not in presentation format");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
llarp::LogWarn("inet_pton failure");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
inAddr::fromSIIT()
|
||||
{
|
||||
if(ipv6_is_siit(this->_addr))
|
||||
{
|
||||
this->_addr.s6_addr[0] = this->_addr.s6_addr[12];
|
||||
this->_addr.s6_addr[1] = this->_addr.s6_addr[13];
|
||||
this->_addr.s6_addr[2] = this->_addr.s6_addr[14];
|
||||
this->_addr.s6_addr[3] = this->_addr.s6_addr[15];
|
||||
this->setIPv4Mode();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
inAddr::toSIIT()
|
||||
{
|
||||
if(!ipv6_is_siit(this->_addr))
|
||||
{
|
||||
this->_addr.s6_addr[10] = 0xff;
|
||||
this->_addr.s6_addr[11] = 0xff;
|
||||
this->_addr.s6_addr[12] = this->_addr.s6_addr[0];
|
||||
this->_addr.s6_addr[13] = this->_addr.s6_addr[1];
|
||||
this->_addr.s6_addr[14] = this->_addr.s6_addr[2];
|
||||
this->_addr.s6_addr[15] = this->_addr.s6_addr[3];
|
||||
llarp::Zero(&this->_addr, sizeof(in6_addr) - 6);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool
|
||||
inAddr::isIPv6Mode() const
|
||||
{
|
||||
return !this->isIPv4Mode();
|
||||
}
|
||||
|
||||
bool
|
||||
inAddr::isIPv4Mode() const
|
||||
{
|
||||
return ipv6_is_siit(this->_addr)
|
||||
|| (this->_addr.s6_addr[4] == 0 && this->_addr.s6_addr[5] == 0
|
||||
&& this->_addr.s6_addr[6] == 0 && this->_addr.s6_addr[7] == 0
|
||||
&& this->_addr.s6_addr[8] == 0 && this->_addr.s6_addr[9] == 0
|
||||
&& this->_addr.s6_addr[10] == 0 && this->_addr.s6_addr[11] == 0
|
||||
&& this->_addr.s6_addr[12] == 0 && this->_addr.s6_addr[13] == 0
|
||||
&& this->_addr.s6_addr[14] == 0 && this->_addr.s6_addr[15] == 0);
|
||||
}
|
||||
|
||||
void
|
||||
inAddr::setIPv4Mode()
|
||||
{
|
||||
// keep first 4
|
||||
// llarp::Zero(&this->_addr + 4, sizeof(in6_addr) - 4);
|
||||
this->_addr.s6_addr[4] = 0;
|
||||
this->_addr.s6_addr[5] = 0;
|
||||
this->_addr.s6_addr[6] = 0;
|
||||
this->_addr.s6_addr[7] = 0;
|
||||
this->_addr.s6_addr[8] = 0;
|
||||
this->_addr.s6_addr[9] = 0;
|
||||
this->_addr.s6_addr[10] = 0;
|
||||
this->_addr.s6_addr[11] = 0;
|
||||
this->_addr.s6_addr[12] = 0;
|
||||
this->_addr.s6_addr[13] = 0;
|
||||
this->_addr.s6_addr[14] = 0;
|
||||
this->_addr.s6_addr[15] = 0;
|
||||
}
|
||||
|
||||
void
|
||||
inAddr::hexDebug()
|
||||
{
|
||||
char hex_buffer[16 * 3 + 1];
|
||||
hex_buffer[16 * 3] = 0;
|
||||
for(unsigned int j = 0; j < 16; j++)
|
||||
sprintf(&hex_buffer[3 * j], "%02X ", this->_addr.s6_addr[j]);
|
||||
printf("in6_addr: [%s]\n", hex_buffer);
|
||||
}
|
||||
|
||||
//
|
||||
// IPv4 specific functions
|
||||
//
|
||||
|
||||
in_addr
|
||||
inAddr::toIAddr()
|
||||
{
|
||||
in_addr res;
|
||||
res.s_addr = toN32().n;
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
inAddr::from4int(const uint8_t one, const uint8_t two, const uint8_t three,
|
||||
const uint8_t four)
|
||||
{
|
||||
this->reset();
|
||||
this->setIPv4Mode();
|
||||
// Network byte order
|
||||
this->_addr.s6_addr[0] = one;
|
||||
this->_addr.s6_addr[1] = two;
|
||||
this->_addr.s6_addr[2] = three;
|
||||
this->_addr.s6_addr[3] = four;
|
||||
}
|
||||
|
||||
void
|
||||
inAddr::fromN32(nuint32_t in)
|
||||
{
|
||||
this->reset();
|
||||
this->setIPv4Mode();
|
||||
memcpy(&this->_addr, &in.n, sizeof(uint32_t));
|
||||
}
|
||||
void
|
||||
inAddr::fromH32(huint32_t in)
|
||||
{
|
||||
this->fromN32(xhtonl(in));
|
||||
}
|
||||
|
||||
nuint32_t
|
||||
inAddr::toN32()
|
||||
{
|
||||
nuint32_t result;
|
||||
result.n = 0; // return 0 for IPv6
|
||||
if(this->isIPv4Mode())
|
||||
{
|
||||
memcpy(&result.n, &this->_addr, sizeof(uint32_t));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
huint32_t
|
||||
inAddr::toH32()
|
||||
{
|
||||
return xntohl(this->toN32());
|
||||
}
|
||||
|
||||
//
|
||||
// IPv6 specific functions
|
||||
//
|
||||
|
||||
} // namespace llarp
|
|
@ -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…
Reference in a new issue