diff --git a/Makefile b/Makefile index c114f748f..5aa61325b 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ REPO := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) PREFIX ?= /usr/local -CC ?= cc +CC ?= cc CXX ?= c++ SETCAP ?= which setcap && setcap cap_net_admin=+eip @@ -66,7 +66,7 @@ debug-configure: $(CONFIG_CMD) -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=$(CC) -DCMAKE_CXX_COMPILER=$(CXX) -DDNS_PORT=$(DNS_PORT) release-configure: clean - mkdir -p '$(BUILD_ROOT)' + mkdir -p '$(BUILD_ROOT)' $(CONFIG_CMD) -DSTATIC_LINK=ON -DCMAKE_BUILD_TYPE=Release -DRELEASE_MOTTO="$(shell cat motto.txt)" -DCMAKE_C_COMPILER=$(CC) -DCMAKE_CXX_COMPILER=$(CXX) debug: debug-configure @@ -116,7 +116,7 @@ shared-configure: clean shared: shared-configure $(MAKE) -C $(BUILD_ROOT) -testnet: +testnet: cp $(EXE) $(TESTNET_EXE) mkdir -p $(TESTNET_ROOT) python3 contrib/testnet/genconf.py --bin=$(TESTNET_EXE) --svc=$(TESTNET_SERVERS) --clients=$(TESTNET_CLIENTS) --dir=$(TESTNET_ROOT) --out $(TESTNET_CONF) --connect=4 @@ -148,3 +148,13 @@ install: rm -f $(PREFIX)/bin/lokinet-bootstrap cp $(REPO)/lokinet-bootstrap $(PREFIX)/bin/lokinet-bootstrap chmod 755 $(PREFIX)/bin/lokinet-bootstrap + setcap cap_net_admin=+eip $(PREFIX)/bin/lokinet + +fuzz-configure: clean + cmake -GNinja -DCMAKE_BUILD_TYPE=Fuzz -DCMAKE_C_COMPILER=afl-gcc -DCMAKE_CXX_COMPILER=afl-g++ + +fuzz-build: fuzz-configure + ninja + +fuzz: fuzz-build + $(EXE) diff --git a/include/llarp/dns.hpp b/include/llarp/dns.hpp index 47695c17a..37edaf385 100644 --- a/include/llarp/dns.hpp +++ b/include/llarp/dns.hpp @@ -11,7 +11,7 @@ #include #endif -#include // for llarp::Addr +#include // 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(); diff --git a/include/llarp/dns_iptracker.hpp b/include/llarp/dns_iptracker.hpp index 4aeb18894..13bb451b4 100644 --- a/include/llarp/dns_iptracker.hpp +++ b/include/llarp/dns_iptracker.hpp @@ -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(); diff --git a/include/llarp/dnsc.hpp b/include/llarp/dnsc.hpp index 9e7b293a0..69427a3a2 100644 --- a/include/llarp/dnsc.hpp +++ b/include/llarp/dnsc.hpp @@ -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 diff --git a/include/llarp/dnsd.hpp b/include/llarp/dnsd.hpp index 798702ee9..6a7f6b58b 100644 --- a/include/llarp/dnsd.hpp +++ b/include/llarp/dnsd.hpp @@ -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 diff --git a/include/llarp/encrypted_frame.hpp b/include/llarp/encrypted_frame.hpp index 52e4e2da6..73c7821ad 100644 --- a/include/llarp/encrypted_frame.hpp +++ b/include/llarp/encrypted_frame.hpp @@ -18,7 +18,7 @@ namespace llarp } EncryptedFrame(const EncryptedFrame& other) - : EncryptedFrame(other.data(), other.size()) + : EncryptedFrame(other.data(), other.size()) { } diff --git a/include/llarp/link/server.hpp b/include/llarp/link/server.hpp index 6b57a0ef6..01cf2c8dc 100644 --- a/include/llarp/link/server.hpp +++ b/include/llarp/link/server.hpp @@ -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); } diff --git a/include/llarp/net.hpp b/include/llarp/net.hpp index 5b9365f5f..f5630903f 100644 --- a/include/llarp/net.hpp +++ b/include/llarp/net.hpp @@ -77,6 +77,17 @@ namespace llarp constexpr bool operator <(huint32_t x) const { return h < x.h; } constexpr bool operator ==(huint32_t x) const { return h == x.h; } + friend std::ostream& + operator<<(std::ostream& out, const huint32_t& a) + { + char tmp[INET_ADDRSTRLEN] = {0}; + if(inet_ntop(AF_INET, (void*)&a.h, tmp, INET_ADDRSTRLEN)) + { + out << tmp; + } + return out; + } + struct Hash { inline size_t @@ -107,6 +118,17 @@ namespace llarp constexpr bool operator <(nuint32_t x) const { return n < x.n; } constexpr bool operator ==(nuint32_t x) const { return n == x.n; } + friend std::ostream& + operator<<(std::ostream& out, const nuint32_t& a) + { + char tmp[INET_ADDRSTRLEN] = {0}; + if(inet_ntop(AF_INET, (void*)&a.n, tmp, INET_ADDRSTRLEN)) + { + out << tmp; + } + return out; + } + struct Hash { inline size_t @@ -134,6 +156,17 @@ namespace llarp constexpr bool operator <(huint16_t x) const { return h < x.h; } constexpr bool operator ==(huint16_t x) const { return h == x.h; } + friend std::ostream& + operator<<(std::ostream& out, const huint16_t& a) + { + char tmp[INET_ADDRSTRLEN] = {0}; + if(inet_ntop(AF_INET, (void*)&a.h, tmp, INET_ADDRSTRLEN)) + { + out << tmp; + } + return out; + } + struct Hash { inline size_t @@ -161,6 +194,17 @@ namespace llarp constexpr bool operator <(nuint16_t x) const { return n < x.n; } constexpr bool operator ==(nuint16_t x) const { return n == x.n; } + friend std::ostream& + operator<<(std::ostream& out, const nuint16_t& a) + { + char tmp[INET_ADDRSTRLEN] = {0}; + if(inet_ntop(AF_INET, (void*)&a.n, tmp, INET_ADDRSTRLEN)) + { + out << tmp; + } + return out; + } + struct Hash { inline size_t @@ -210,14 +254,15 @@ namespace llarp return (addr & netmask_bits) == (ip & netmask_bits); } - std::string - ToString() const + friend std::ostream& + operator<<(std::ostream& out, const IPRange& a) { char strbuf[32] = {0}; char netbuf[32] = {0}; - inet_ntop(AF_INET, &addr, strbuf, sizeof(strbuf)); - inet_ntop(AF_INET, &netmask_bits, netbuf, sizeof(netbuf)); - return std::string(strbuf) + "/" + std::string(netbuf); + inet_ntop(AF_INET, &a.addr, strbuf, sizeof(strbuf)); + inet_ntop(AF_INET, &a.netmask_bits, netbuf, sizeof(netbuf)); + out << std::string(strbuf) + "/" + std::string(netbuf); + return out; } }; @@ -268,510 +313,7 @@ namespace llarp bool IsBogonRange(const in6_addr& host, const in6_addr& mask); - struct Addr - { - // network order - sockaddr_in6 _addr; - sockaddr_in _addr4; // why do we even have this? favor cpu over memory - ~Addr(){}; - - Addr(){}; - - Addr(const Addr& other) - { - memcpy(&_addr, &other._addr, sizeof(sockaddr_in6)); - memcpy(&_addr4, &other._addr4, sizeof(sockaddr_in)); - } - - void - port(uint16_t port) - { - if(af() == AF_INET) - { - _addr4.sin_port = htons(port); - } - _addr.sin6_port = htons(port); - } - - in6_addr* - addr6() - { - return (in6_addr*)&_addr.sin6_addr.s6_addr[0]; - } - - in_addr* - addr4() - { - return (in_addr*)&_addr.sin6_addr.s6_addr[12]; - } - - const in6_addr* - addr6() const - { - return (const in6_addr*)&_addr.sin6_addr.s6_addr[0]; - } - - const in_addr* - addr4() const - { - return (const in_addr*)&_addr.sin6_addr.s6_addr[12]; - } - - Addr(const std::string str) - { - this->from_char_array(str.c_str()); - } - - Addr(const std::string str, const uint16_t p_port) - { - this->from_char_array(str.c_str()); - this->port(p_port); - } - - bool - from_char_array(const char* str) - { - llarp::Zero(&_addr, sizeof(sockaddr_in6)); - struct addrinfo hint, *res = NULL; - int ret; - - memset(&hint, '\0', sizeof hint); - - hint.ai_family = PF_UNSPEC; - hint.ai_flags = AI_NUMERICHOST; - - ret = getaddrinfo(str, NULL, &hint, &res); - if(ret) - { - llarp::LogError("failed to determine address family: ", str); - return false; - } - - if(res->ai_family == AF_INET6) - { - llarp::LogError("IPv6 address not supported yet", str); - return false; - } - else if(res->ai_family != AF_INET) - { - llarp::LogError("Address family not supported yet", str); - return false; - } - - // put it in _addr4 - struct in_addr* addr = &_addr4.sin_addr; - if(inet_aton(str, addr) == 0) - { - llarp::LogError("failed to parse ", str); - return false; - } - - _addr.sin6_family = res->ai_family; - _addr4.sin_family = res->ai_family; - _addr4.sin_port = 0; // save a call, 0 is 0 no matter how u arrange it -#if((__APPLE__ && __MACH__) || __FreeBSD__) - _addr4.sin_len = sizeof(in_addr); -#endif - // set up SIIT - uint8_t* addrptr = _addr.sin6_addr.s6_addr; - addrptr[11] = 0xff; - addrptr[10] = 0xff; - memcpy(12 + addrptr, &addr->s_addr, sizeof(in_addr)); - freeaddrinfo(res); - - return true; - } - - Addr(const char* str) - { - this->from_char_array(str); - } - - bool - from_4int(const uint8_t one, const uint8_t two, const uint8_t three, - const uint8_t four) - { - llarp::Zero(&_addr, sizeof(sockaddr_in6)); - struct in_addr* addr = &_addr4.sin_addr; - unsigned char* ip = (unsigned char*)&(addr->s_addr); - - _addr.sin6_family = AF_INET; // set ipv4 mode - _addr4.sin_family = AF_INET; - _addr4.sin_port = 0; - -#if((__APPLE__ && __MACH__) || __FreeBSD__) - _addr4.sin_len = sizeof(in_addr); -#endif - // FIXME: watch endian - ip[0] = one; - ip[1] = two; - ip[2] = three; - ip[3] = four; - // set up SIIT - uint8_t* addrptr = _addr.sin6_addr.s6_addr; - addrptr[11] = 0xff; - addrptr[10] = 0xff; - memcpy(12 + addrptr, &addr->s_addr, sizeof(in_addr)); - // copy ipv6 SIIT into _addr4 - memcpy(&_addr4.sin_addr.s_addr, addr4(), sizeof(in_addr)); - return true; - } - - Addr(const uint8_t one, const uint8_t two, const uint8_t three, - const uint8_t four) - { - this->from_4int(one, two, three, four); - } - - Addr(const uint8_t one, const uint8_t two, const uint8_t three, - const uint8_t four, const uint16_t p_port) - { - this->from_4int(one, two, three, four); - this->port(p_port); - } - - Addr(const AddressInfo& other) - { - memcpy(addr6(), other.ip.s6_addr, 16); - _addr.sin6_port = htons(other.port); - if(ipv6_is_siit(other.ip)) - { - _addr4.sin_family = AF_INET; - _addr4.sin_port = htons(other.port); - _addr.sin6_family = AF_INET; - memcpy(&_addr4.sin_addr.s_addr, addr4(), sizeof(in_addr)); - } - else - _addr.sin6_family = AF_INET6; - } - - Addr(const sockaddr_in& other) - { - llarp::Zero(&_addr, sizeof(sockaddr_in6)); - _addr.sin6_family = AF_INET; - uint8_t* addrptr = _addr.sin6_addr.s6_addr; - uint16_t* port = &_addr.sin6_port; - // SIIT - memcpy(12 + addrptr, &((const sockaddr_in*)(&other))->sin_addr, - sizeof(in_addr)); - addrptr[11] = 0xff; - addrptr[10] = 0xff; - *port = ((sockaddr_in*)(&other))->sin_port; - _addr4.sin_family = AF_INET; - _addr4.sin_port = *port; - memcpy(&_addr4.sin_addr.s_addr, addr4(), sizeof(in_addr)); - } - - Addr(const sockaddr_in6& other) - { - memcpy(addr6(), other.sin6_addr.s6_addr, 16); - _addr.sin6_port = htons(other.sin6_port); - auto ptr = &_addr.sin6_addr.s6_addr[0]; - // TODO: detect SIIT better - if(ptr[11] == 0xff && ptr[10] == 0xff && ptr[9] == 0 && ptr[8] == 0 - && ptr[7] == 0 && ptr[6] == 0 && ptr[5] == 0 && ptr[4] == 0 - && ptr[3] == 0 && ptr[2] == 0 && ptr[1] == 0 && ptr[0] == 0) - { - _addr4.sin_family = AF_INET; - _addr4.sin_port = htons(other.sin6_port); - _addr.sin6_family = AF_INET; - memcpy(&_addr4.sin_addr.s_addr, addr4(), sizeof(in_addr)); - } - else - _addr.sin6_family = AF_INET6; - } - - Addr(const sockaddr& other) - { - llarp::Zero(&_addr, sizeof(sockaddr_in6)); - _addr.sin6_family = other.sa_family; - uint8_t* addrptr = _addr.sin6_addr.s6_addr; - uint16_t* port = &_addr.sin6_port; - switch(other.sa_family) - { - case AF_INET: - // SIIT - memcpy(12 + addrptr, &((const sockaddr_in*)(&other))->sin_addr, - sizeof(in_addr)); - addrptr[11] = 0xff; - addrptr[10] = 0xff; - *port = ((sockaddr_in*)(&other))->sin_port; - _addr4.sin_family = AF_INET; - _addr4.sin_port = *port; - memcpy(&_addr4.sin_addr.s_addr, addr4(), sizeof(in_addr)); - break; - case AF_INET6: - memcpy(addrptr, &((const sockaddr_in6*)(&other))->sin6_addr.s6_addr, - 16); - *port = ((sockaddr_in6*)(&other))->sin6_port; - break; - // TODO : sockaddr_ll - default: - break; - } - } - - std::string - ToString() const - { - std::stringstream ss; - ss << (*this); - return std::string(ss.str().c_str()); - } - - friend std::ostream& - operator<<(std::ostream& out, const Addr& a) - { - char tmp[128] = {0}; - const void* ptr = nullptr; - if(a.af() == AF_INET6) - { - out << "["; - ptr = a.addr6(); - } - else - { - ptr = a.addr4(); - } -#ifndef _MSC_VER - if(inet_ntop(a.af(), ptr, tmp, sizeof(tmp))) -#else - if(inet_ntop(a.af(), (void*)ptr, tmp, sizeof(tmp))) -#endif - { - out << tmp; - if(a.af() == AF_INET6) - out << "]"; - } - return out << ":" << a.port(); - } - - operator const sockaddr*() const - { - if(af() == AF_INET) - return (const sockaddr*)&_addr4; - else - return (const sockaddr*)&_addr; - } - - operator sockaddr*() const - { - if(af() == AF_INET) - return (sockaddr*)&_addr4; - else - return (sockaddr*)&_addr; - } - - void - CopyInto(sockaddr* other) const - { - void *dst, *src; - in_port_t* ptr; - size_t slen; - switch(af()) - { - case AF_INET: - { - sockaddr_in* ipv4_dst = (sockaddr_in*)other; - dst = (void*)&ipv4_dst->sin_addr.s_addr; - src = (void*)&_addr4.sin_addr.s_addr; - ptr = &((sockaddr_in*)other)->sin_port; - slen = sizeof(in_addr); - break; - } - case AF_INET6: - { - dst = (void*)((sockaddr_in6*)other)->sin6_addr.s6_addr; - src = (void*)_addr.sin6_addr.s6_addr; - ptr = &((sockaddr_in6*)other)->sin6_port; - slen = sizeof(in6_addr); - break; - } - default: - { - return; - } - } - memcpy(dst, src, slen); - *ptr = htons(port()); - other->sa_family = af(); - } - - int - af() const - { - return _addr.sin6_family; - } - - uint16_t - port() const - { - return ntohs(_addr.sin6_port); - } - - bool - operator<(const Addr& other) const - { - if(af() == AF_INET && other.af() == AF_INET) - return port() < other.port() || addr4()->s_addr < other.addr4()->s_addr; - else - return port() < other.port() || *addr6() < *other.addr6() - || af() < other.af(); - } - - bool - operator==(const Addr& other) const - { - if(af() == AF_INET && other.af() == AF_INET) - return port() == other.port() - && addr4()->s_addr == other.addr4()->s_addr; - else - return af() == other.af() && memcmp(addr6(), other.addr6(), 16) == 0 - && port() == other.port(); - } - - Addr& - operator=(const sockaddr& other) - { - llarp::Zero(&_addr, sizeof(sockaddr_in6)); - _addr.sin6_family = other.sa_family; - uint8_t* addrptr = _addr.sin6_addr.s6_addr; - uint16_t* port = &_addr.sin6_port; - switch(other.sa_family) - { - case AF_INET: - // SIIT - memcpy(12 + addrptr, &((const sockaddr_in*)(&other))->sin_addr, - sizeof(in_addr)); - addrptr[11] = 0xff; - addrptr[10] = 0xff; - *port = ((sockaddr_in*)(&other))->sin_port; - _addr4.sin_family = AF_INET; - _addr4.sin_port = *port; - memcpy(&_addr4.sin_addr.s_addr, addr4(), sizeof(in_addr)); - break; - case AF_INET6: - memcpy(addrptr, &((const sockaddr_in6*)(&other))->sin6_addr.s6_addr, - 16); - *port = ((sockaddr_in6*)(&other))->sin6_port; - break; - // TODO : sockaddr_ll - default: - break; - } - return *this; - } - - inline uint32_t - tohl() const - { - return ntohl(addr4()->s_addr); - } - - inline huint32_t - xtohl() const - { - return huint32_t{ntohl(addr4()->s_addr)}; - } - - inline uint32_t - ton() const - { - return addr4()->s_addr; - } - - inline nuint32_t - xtonl() const - { - return nuint32_t{addr4()->s_addr}; - } - - bool - sameAddr(const Addr& other) const - { - return memcmp(addr6(), other.addr6(), 16) == 0; - } - - bool - operator!=(const Addr& other) const - { - return !(*this == other); - } - - inline uint32_t - getHostLong() - { - in_addr_t addr = this->addr4()->s_addr; - uint32_t byte = ntohl(addr); - return byte; - }; - - bool - isTenPrivate(uint32_t byte) - { - uint8_t byte1 = byte >> 24 & 0xff; - return byte1 == 10; - } - - bool - isOneSevenPrivate(uint32_t byte) - { - uint8_t byte1 = byte >> 24 & 0xff; - uint8_t byte2 = (0x00ff0000 & byte) >> 16; - return byte1 == 172 && (byte2 >= 16 || byte2 <= 31); - } - - bool - isOneNinePrivate(uint32_t byte) - { - uint8_t byte1 = byte >> 24 & 0xff; - uint8_t byte2 = (0x00ff0000 & byte) >> 16; - return byte1 == 192 && byte2 == 168; - } - - /// return true if our ipv4 address is a bogon - /// TODO: ipv6 - bool - IsBogon() const - { - return IsIPv4Bogon(xtohl()); - } - - socklen_t - SockLen() const - { - if(af() == AF_INET) - return sizeof(sockaddr_in); - else - return sizeof(sockaddr_in6); - } - - bool - isPrivate() const - { - return IsBogon(); - } - - bool - isLoopback() const - { - return (ntohl(addr4()->s_addr)) >> 24 == 127; - } - - struct Hash - { - std::size_t - operator()(Addr const& a) const noexcept - { - if(a.af() == AF_INET) - { - return a.port() ^ a.addr4()->s_addr; - } - static const uint8_t empty[16] = {0}; - return (a.af() + memcmp(a.addr6(), empty, 16)) ^ a.port(); - } - }; - }; // namespace llarp + struct Addr; // fwd declr bool AllInterfaces(int af, Addr& addr); @@ -794,4 +336,7 @@ namespace llarp } // namespace llarp +#include +#include + #endif diff --git a/include/llarp/routing/message.hpp b/include/llarp/routing/message.hpp index a174d0d6f..e9e861f8c 100644 --- a/include/llarp/routing/message.hpp +++ b/include/llarp/routing/message.hpp @@ -40,7 +40,7 @@ namespace llarp bool firstKey; char key; dict_reader reader; - std::unique_ptr msg; + std::unique_ptr< IMessage > msg; }; } // namespace routing } // namespace llarp diff --git a/include/llarp/service/context.hpp b/include/llarp/service/context.hpp index a2498f905..fa78a58a3 100644 --- a/include/llarp/service/context.hpp +++ b/include/llarp/service/context.hpp @@ -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); diff --git a/llarp/dht/got_router.cpp b/llarp/dht/got_router.cpp index 48b058671..aae028666 100644 --- a/llarp/dht/got_router.cpp +++ b/llarp/dht/got_router.cpp @@ -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 diff --git a/llarp/dns.cpp b/llarp/dns.cpp index 458115c0d..5cf0c2bdc 100644 --- a/llarp/dns.cpp +++ b/llarp/dns.cpp @@ -2,6 +2,28 @@ #include // for llarp_handle_dnsd_recvfrom, dnsc #include +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); +} + /* is a domain name represented as a series of labels, and terminated by a label with zero length. is a single @@ -10,25 +32,62 @@ length (including the length octet). */ std::string -getDNSstring(const char *buffer) +getDNSstring(const char *const buffer, uint32_t *pos) { - std::string str = ""; - uint8_t length = *buffer++; + std::string str = ""; + const char *moveable = buffer; + moveable += *pos; + uint8_t length = *moveable++; + (*pos)++; + if(length == 0xc0) + { + uint8_t cPos = *moveable++; + (*pos)++; + uint32_t cPos32 = cPos; + // llarp::LogInfo("Found reference at ", std::to_string(cPos)); + return getDNSstring(buffer, &cPos32); + } + // hexDump(moveable, length); + // hexDump(buffer, length); // printf("dnsStringLen[%d]\n", length); - // llarp::LogInfo("dnsStringLen ", length); + // llarp::LogInfo("dnsStringLen ", std::to_string(length)); if(!length) return str; while(length != 0) { + // llarp::LogInfo("Reading ", std::to_string(length)); for(int i = 0; i < length; i++) { - char c = *buffer++; + char c = *moveable++; + (*pos)++; str.append(1, c); } - length = *buffer++; + if(*moveable == '\xc0') + { + moveable++; + (*pos)++; // forward one char + uint8_t cPos = *moveable; // read char + uint32_t cPos32 = cPos; + // llarp::LogInfo("Remaining [", str, "] is an reference at ", (int)cPos); + std::string addl = getDNSstring(buffer, &cPos32); + // llarp::LogInfo("Addl str [", addl, "]"); + str += "." + addl; + // llarp::LogInfo("Final str [", str, "]"); + (*pos)++; // move past reference + + return str; + } + length = *moveable++; + (*pos)++; + if(length > 64) + llarp::LogError("bug detected"); + // else + // hexDump(buffer, length); + // llarp::LogInfo("NextLen ", std::to_string(length)); if(length != 0) str.append(1, '.'); } + // llarp::LogInfo("Returning ", str); return str; } @@ -113,12 +172,23 @@ extern "C" } dns_msg_question * - decode_question(const char *buffer) + decode_question(const char *buffer, uint32_t *pos) { // char *start = (char *)buffer; dns_msg_question *question = new dns_msg_question; - std::string m_qName = getDNSstring(buffer); - buffer += m_qName.length() + 2; // + length byte & ending terminator + + // uint32_t start = *pos; + std::string m_qName = getDNSstring(buffer, pos); + llarp::LogInfo("Got question name: ", m_qName); + // llarp::LogInfo("Started at ", std::to_string(start), " ended at: ", + // std::to_string(*pos)); llarp::LogInfo("Advancing question buffer by ", + // std::to_string(*pos)); buffer += (*pos) - start; buffer += + // m_qName.length() + 2; // + length byte & ending terminator + + const char *moveable = buffer; + moveable += *pos; // advance to position + // hexDump(moveable, 4); + // printf("Now0 at [%d]\n", buffer - start); // buffer += m_qName.size() + 1; /* @@ -138,15 +208,20 @@ extern "C" } */ question->name = m_qName; - question->type = get16bits(buffer); + question->type = get16bits(moveable); + (*pos) += 2; // printf("Now1 at [%d]\n", buffer - start); - question->qClass = get16bits(buffer); + question->qClass = get16bits(moveable); + (*pos) += 2; // printf("Now2 at [%d]\n", buffer - start); + llarp::LogInfo("Type ", std::to_string(question->type), " Class ", + std::to_string(question->qClass)); + // hexDump(moveable, 4); return question; } dns_msg_answer * - decode_answer(const char *buffer) + decode_answer(const char *const buffer, uint32_t *pos) { dns_msg_answer *answer = new dns_msg_answer; // skip for now until we can handle compressed labels @@ -162,42 +237,95 @@ extern "C" llarp::DumpBuffer(bob); */ - char hex_buffer[12 * 3 + 1]; - hex_buffer[12 * 3] = 0; - for(unsigned int j = 0; j < 10; j++) - sprintf(&hex_buffer[3 * j], "%02X ", buffer[j]); - llarp::LogDebug("First 12 bytes: ", hex_buffer); + // hexDump(buffer, 10); - uint8_t first = *buffer++; - // llarp::LogInfo("decode - first", std::to_string(first)); + const char *moveable = buffer; + // llarp::LogDebug("Advancing to pos ", std::to_string(*pos)); + moveable += (*pos); // advance to position + + // hexDumpAt(buffer, (*pos) - 2, 12); + // hexDump(moveable, 12); + if(*moveable == '\xc0') + { + // hexDump(moveable, 12); + // hexDumpAt(buffer, *pos, 12); + + // hexDump(moveable, 2); + + moveable++; + (*pos)++; + uint8_t readAt = *moveable; + uint32_t readAt32 = readAt; + llarp::LogInfo("Ref, skip. Read ", readAt32); + // hexDumpAt(buffer, readAt, 2); + answer->name = getDNSstring(buffer, &readAt32); + moveable++; + (*pos)++; + // hexDump(moveable, 10); + // hexDumpAt(buffer, *pos, 10); + } + else + { + // get DNSString? + llarp::LogWarn("Need to parse string"); + } + /* + hexDump(moveable, 10); + uint8_t first = *moveable++; (*pos)++; + llarp::LogInfo("decode - first", std::to_string(first)); // SOA hack if(first != 12 && first != 14) // 0x0c (c0 0c) 0 { llarp::LogDebug("decode - first isnt 12, stepping back"); - buffer--; // rewind buffer one byte + moveable--; (*pos)--; // rewind buffer one byte } - answer->type = get16bits(buffer); + */ + // hexDump(moveable, 10); + + answer->type = get16bits(moveable); + (*pos) += 2; + llarp::LogDebug("Answer Type: ", answer->type); // assert(answer->type < 259); if(answer->type > 259) { llarp::LogWarn("Answer type is off the charts"); } - answer->aClass = get16bits(buffer); - answer->ttl = get32bits(buffer); - answer->rdLen = get16bits(buffer); + answer->aClass = get16bits(moveable); + (*pos) += 2; + llarp::LogDebug("Answer Class: ", answer->aClass); + answer->ttl = get32bits(moveable); + (*pos) += 4; + llarp::LogDebug("Answer TTL: ", answer->ttl); + answer->rdLen = get16bits(moveable); + (*pos) += 2; + llarp::LogDebug("Answer rdL: ", answer->rdLen, " at ", + std::to_string(*pos)); + // uint32_t cPos = moveable - buffer; + // llarp::LogInfo("pos at ", std::to_string(*pos), " calculated: ", + // std::to_string(cPos)); + + // hexDump(moveable, answer->rdLen); + // hexDumpAt(buffer, *pos, answer->rdLen); if(answer->rdLen == 4) { answer->rData = new uint8_t[answer->rdLen]; - memcpy(answer->rData, buffer, answer->rdLen); - buffer += answer->rdLen; // advance the length + memcpy(answer->rData, moveable, answer->rdLen); + llarp::LogDebug("Read ", std::to_string(answer->rData[0]), ".", + std::to_string(answer->rData[1]), ".", + std::to_string(answer->rData[2]), ".", + std::to_string(answer->rData[3])); + moveable += answer->rdLen; + (*pos) += answer->rdLen; // advance the length } else { llarp::LogDebug("Got type ", answer->type); + // FIXME: move this out of here, this shouldn't be responsible for decode switch(answer->type) { case 5: - buffer += answer->rdLen; // advance the length + moveable += answer->rdLen; + (*pos) += answer->rdLen; // advance the length break; case 6: // type 6 = SOA { @@ -223,18 +351,51 @@ extern "C" llarp::LogDebug("expire : ", expire); llarp::LogDebug("minimum : ", minimum); */ + moveable += answer->rdLen; + (*pos) += answer->rdLen; // advance the length } break; case 12: { - std::string revname = getDNSstring((char *)buffer); + std::string revname = getDNSstring(buffer, pos); llarp::LogInfo("revDNSname: ", revname); answer->rData = new uint8_t[answer->rdLen + 1]; memcpy(answer->rData, revname.c_str(), answer->rdLen); + moveable += answer->rdLen; + (*pos) += answer->rdLen; // advance the length } break; + case 15: + { + uint16_t priority = get16bits(moveable); + (*pos) += 2; + std::string revname = getDNSstring(buffer, pos); + llarp::LogInfo("MX: ", revname, " @ ", priority); + // answer->rData = new uint8_t[revname.length() + 1]; + // memcpy(answer->rData, revname.c_str(), answer->rdLen); + answer->rData = (uint8_t *)strdup(revname.c_str()); + moveable += answer->rdLen - 2; // advance the length + // llarp::LogInfo("leaving at ", std::to_string(*pos)); + // hexDumpAt(buffer, *pos, 5); + // hexDump(moveable, 5); + } + break; + case 16: + { + // hexDump(buffer, 5); + // std::string revname = getDNSstring((char *)buffer); + llarp::LogInfo("TXT: size: ", answer->rdLen); + answer->rData = new uint8_t[answer->rdLen + 1]; + memcpy(answer->rData, moveable + 1, answer->rdLen - 1); + answer->rData[answer->rdLen - 1] = 0; // terminate string + moveable += answer->rdLen; + (*pos) += answer->rdLen; // advance the length + } + break; + // type 28 AAAA default: - buffer += answer->rdLen; // advance the length + moveable += answer->rdLen; + (*pos) += answer->rdLen; // advance the length llarp::LogWarn("Unknown Type ", answer->type); break; } diff --git a/llarp/dns_dotlokilookup.cpp b/llarp/dns_dotlokilookup.cpp index 6119d907c..df3846c23 100644 --- a/llarp/dns_dotlokilookup.cpp +++ b/llarp/dns_dotlokilookup.cpp @@ -79,6 +79,50 @@ llarp_dotlokilookup_checkQuery(void *u, uint64_t orig, uint64_t left) // in_addr ip_address = ((sockaddr_in *)free_private->hostResult)->sin_addr; + llarp::service::Context *routerHiddenServiceContext = + (llarp::service::Context *)dll->user; + if(!routerHiddenServiceContext) + { + llarp::LogWarn("dotLokiLookup user isnt a service::Context: ", dll->user); + write404_dnss_response(qr->from, qr->request); + delete qr; + return; + } + + llarp::huint32_t *tunIp = + new llarp::huint32_t(routerHiddenServiceContext->GetIpForAddr(addr)); + if(!tunIp->h) + { + llarp::LogWarn("dotLokiLookup failed to map address"); + write404_dnss_response(qr->from, qr->request); + delete qr; + return; + } + + /* + bool mapResult = routerHiddenServiceContext->MapAddressAll( + addr, free_private->hostResult); + if(!mapResult) + { + llarp::LogWarn("dotLokiLookup failed to map address"); + write404_dnss_response(qr->from, qr->request); + delete qr; + return; + } + */ + + // make a dnsd_query_hook_response for the cache + dnsd_query_hook_response *response = new dnsd_query_hook_response; + response->dontLookUp = true; + response->dontSendResponse = false; + // llarp::Addr test(*free_private->hostResult.getSockAddr()); + // llarp::LogInfo("IP Test: ", test); + // response->returnThis = &free_private->hostResult; + response->returnThis = tunIp; + llarp::LogInfo("Saving ", qr->request->question.name); + loki_tld_lookup_cache[qr->request->question.name] = response; + // we can't delete response now... + /* llarp::handlers::TunEndpoint *tunEndpoint = (llarp::handlers::TunEndpoint *)dll->user; @@ -186,21 +230,19 @@ ReverseHandlerIter(struct llarp::service::Context::endpoint_iter *endpointCfg) stoi(tokensSearch[searchTokens - 6]), stoi(tokensSearch[searchTokens - 5]), stoi(tokensSearch[searchTokens - 4]), - stoi(tokensSearch[searchTokens - - 3])); // create ip (llarp::Addr is untrustworthy atm) + stoi(tokensSearch[searchTokens - 3])); // create ip llarp::huint32_t searchIPv4_search = llarp::ipaddr_ipv4_bits( stoi(tokensSearch[searchTokens - 3]), stoi(tokensSearch[searchTokens - 4]), stoi(tokensSearch[searchTokens - 5]), - stoi(tokensSearch[searchTokens - - 6])); // create ip (llarp::Addr is untrustworthy atm) + stoi(tokensSearch[searchTokens - 6])); // create ip // bool inRange = range.Contains(searchAddr.xtohl()); bool inRange = range.Contains(searchIPv4_search); llarp::Addr searchAddr(searchIp); llarp::Addr checkAddr(checkIp); - llarp::LogDebug(searchAddr, " vs ", range.ToString(), " = ", + llarp::LogDebug(searchAddr, " vs ", range, " = ", inRange ? "inRange" : "not match"); if(inRange) @@ -214,6 +256,7 @@ ReverseHandlerIter(struct llarp::service::Context::endpoint_iter *endpointCfg) } else { + // llarp::LogInfo("Returning [", addr.ToString(), "]"); writesend_dnss_revresponse(addr.ToString(), context->from, (dnsd_question_request *)context->request); } @@ -262,7 +305,7 @@ llarp_dotlokilookup_handler(std::string name, const struct sockaddr *from, bool res = routerHiddenServiceContext->iterate(i); if(!res) { - llarp::LogInfo("Reverse is ours"); + llarp::LogDebug("Reverse is ours"); response->dontSendResponse = true; // should have already sent it } else diff --git a/llarp/dns_iptracker.cpp b/llarp/dns_iptracker.cpp index 7c5677222..2986d99eb 100644 --- a/llarp/dns_iptracker.cpp +++ b/llarp/dns_iptracker.cpp @@ -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; diff --git a/llarp/dnsc.cpp b/llarp/dnsc.cpp index 9a01ed2da..f51fec577 100644 --- a/llarp/dnsc.cpp +++ b/llarp/dnsc.cpp @@ -95,7 +95,7 @@ build_dns_packet(char *url, uint16_t id, uint16_t reqType) dns_query * answer_request_alloc(struct dnsc_context *dnsc, void *sock, const char *url, - dnsc_answer_hook_func resolved, void *user) + dnsc_answer_hook_func resolved, void *user, uint16_t type) { std::unique_ptr< dnsc_answer_request > request(new dnsc_answer_request); if(!request) @@ -123,7 +123,7 @@ answer_request_alloc(struct dnsc_context *dnsc, void *sock, const char *url, llarp::LogWarn("dnsc request question too long"); return nullptr; } - request->question.type = strstr(url, "in-addr.arpa") != nullptr ? 12 : 1; + request->question.type = type; request->question.qClass = 1; // register our self with the tracker @@ -159,6 +159,7 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request, // llarp::LogInfo("got a response, udp user is ", udp->user); unsigned char *castBuf = (unsigned char *)buf; + char *const castBufc = (char *const)buf; // auto buffer = llarp::StackBuffer< decltype(castBuf) >(castBuf); dns_msg_header *hdr = decode_hdr((const char *)castBuf); @@ -230,15 +231,16 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request, */ // FIXME: only handling one atm + uint32_t pos = 12; // just set after header dns_msg_question *question = nullptr; for(uint32_t i = 0; i < hdr->qdCount; i++) { - question = decode_question((const char *)castBuf); - llarp::LogDebug("Read a question"); + question = decode_question(castBufc, &pos); + llarp::LogInfo("Read a question, now at ", std::to_string(pos)); // 1 dot: 1 byte for length + length // 4 bytes for class/type - castBuf += question->name.length() + 1 + 4; - castBuf += 2; // skip answer label + // castBuf += question->name.length() + 1 + 4; + // castBuf += 2; // skip answer label } // FIXME: only handling one atm @@ -246,16 +248,18 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request, dns_msg_answer *answer = nullptr; for(uint32_t i = 0; i < hdr->anCount; i++) { - answer = decode_answer((const char *)castBuf); + // pos = 0; // reset pos + answer = decode_answer(castBufc, &pos); answers.push_back(answer); - llarp::LogDebug("Read an answer ", answer->type, " for ", - request->question.name); + llarp::LogInfo("Read an answer ", answer->type, " for ", + request->question.name, ", now at ", std::to_string(pos)); // llarp::LogInfo("Read an answer. Label Len: ", answer->name.length(), " // rdLen: ", answer->rdLen); // name + Type (2) + Class (2) + TTL (4) + rdLen (2) + rdData + skip next // answer label (1) first 2 was answer->name.length() if lbl is ref and type // 1: it should be 16 bytes long l0 + t2 + c2 + t4 + l2 + rd4 (14) + l2 // (2) + /* castBuf += 0 + 2 + 2 + 4 + 2 + answer->rdLen; castBuf += 2; // skip answer label uint8_t first = *castBuf; @@ -265,7 +269,9 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request, std::to_string(first)); castBuf++; } + */ // prevent reading past the end of the packet + /* auto diff = castBuf - (unsigned char *)buf; llarp::LogDebug("Read answer, bytes left ", diff); if(diff > sz) @@ -274,16 +280,33 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request, // request->question.name); break; } + */ + if(pos > sz) + { + llarp::LogWarn("Would read past end of dns packet. for ", + request->question.name); + break; + } + /* + uint8_t first = castBufc[pos]; + if(first != 0) + { + llarp::LogInfo("next byte isnt 12, skipping ahead one byte. ", + std::to_string(first)); + pos++; + } + */ } // handle authority records (usually no answers with these, so we'll just // stomp) usually NS records tho for(uint32_t i = 0; i < hdr->nsCount; i++) { - answer = decode_answer((const char *)castBuf); + // pos = 0; // reset pos + answer = decode_answer(castBufc, &pos); // answers.push_back(answer); llarp::LogDebug("Read an authority"); - castBuf += answer->name.length() + 4 + 4 + 4 + answer->rdLen; + // castBuf += answer->name.length() + 4 + 4 + 4 + answer->rdLen; } /* @@ -336,6 +359,8 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request, answer = answers.front(); } + llarp::LogDebug("qus type ", question->type); + llarp::LogDebug("ans class ", answer->aClass); llarp::LogDebug("ans type ", answer->type); llarp::LogDebug("ans ttl ", answer->ttl); @@ -348,6 +373,7 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request, llarp::LogInfo("ans2 rdlen ", answer2->rdLen); */ + llarp::LogDebug("rcode ", std::to_string(rcode)); if(rcode == 2) { llarp::LogWarn("nameserver ", upstreamAddr, " returned SERVFAIL:"); @@ -370,11 +396,14 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request, /* search for and print IPv4 addresses */ // if(dnsQuery->reqType == 0x01) + llarp::LogDebug("request question type: ", + std::to_string(request->question.type)); if(request->question.type == 1) { // llarp::LogInfo("DNS server's answer is: (type#=", ATYPE, "):"); llarp::LogDebug("IPv4 address(es) for ", request->question.name, ":"); + // llarp::LogDebug("Answer rdLen ", std::to_string(answer->rdLen)); if(answer->rdLen == 4) { /* @@ -391,8 +420,18 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request, ip[2] = answer->rData[2]; ip[3] = answer->rData[3]; */ + + /* request->result.from_4int(answer->rData[0], answer->rData[1], answer->rData[2], answer->rData[3]); + */ + // llarp::LogDebug("Passing back IPv4: ", + // std::to_string(answer->rData[3]), ".", std::to_string(answer->rData[2]), + // ".", std::to_string(answer->rData[1]), ".", + // std::to_string(answer->rData[0])); + request->result = + llarp::ipaddr_ipv4_bits(answer->rData[3], answer->rData[2], + answer->rData[1], answer->rData[0]); // llarp::Addr test(request->result); // llarp::LogDebug(request->result); @@ -416,14 +455,43 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request, request->resolved(request); return; } + else if(request->question.type == 15) + { + llarp::LogDebug("Resolving MX"); + request->found = true; + request->result.h = 99; + request->revDNS = std::string((char *)answer->rData); + delete answer->rData; + request->resolved(request); + return; + } + else if(request->question.type == 16) + { + llarp::LogDebug("Resolving TXT"); + request->found = true; + request->revDNS = std::string((char *)answer->rData); + request->resolved(request); + return; + } + else if(request->question.type == 28) + { + llarp::LogDebug("Resolving AAAA"); + return; + } + llarp::LogWarn("Unhandled question type ", request->question.type); } void raw_resolve_host(struct dnsc_context *const dnsc, const char *url, - dnsc_answer_hook_func resolved, void *const user) + dnsc_answer_hook_func resolved, void *const user, + uint16_t type) { + if(strstr(url, "in-addr.arpa") != nullptr) + { + type = 12; + } dns_query *dns_packet = - answer_request_alloc(dnsc, nullptr, url, resolved, user); + answer_request_alloc(dnsc, nullptr, url, resolved, user, type); if(!dns_packet) { llarp::LogError("Couldn't make dnsc packet"); @@ -512,6 +580,10 @@ llarp_handle_dnsc_recvfrom(struct llarp_udp_io *const udp, const struct sockaddr *saddr, const void *buf, const ssize_t sz) { + if(!saddr) + { + llarp::LogWarn("saddr isnt set"); + } unsigned char *castBuf = (unsigned char *)buf; // auto buffer = llarp::StackBuffer< decltype(castBuf) >(castBuf); dns_msg_header *hdr = decode_hdr((const char *)castBuf); @@ -535,11 +607,18 @@ llarp_handle_dnsc_recvfrom(struct llarp_udp_io *const udp, bool llarp_resolve_host(struct dnsc_context *const dnsc, const char *url, - dnsc_answer_hook_func resolved, void *const user) + dnsc_answer_hook_func resolved, void *const user, + uint16_t type) { // FIXME: probably can be stack allocated + /* + if (strstr(url, "in-addr.arpa") != nullptr) + { + type = 12; + } + */ dns_query *dns_packet = - answer_request_alloc(dnsc, &dnsc->udp, url, resolved, user); + answer_request_alloc(dnsc, &dnsc->udp, url, resolved, user, type); if(!dns_packet) { llarp::LogError("Couldn't make dnsc packet"); @@ -605,8 +684,9 @@ llarp_host_resolved(dnsc_answer_request *const request) dns_tracker *tracker = (dns_tracker *)request->context->tracker; auto val = std::find_if( tracker->client_request.begin(), tracker->client_request.end(), - [request](std::pair< const uint32_t, std::unique_ptr< dnsc_answer_request > > - &element) { return element.second.get() == request; }); + [request]( + std::pair< const uint32_t, std::unique_ptr< dnsc_answer_request > > + &element) { return element.second.get() == request; }); if(val != tracker->client_request.end()) { tracker->client_request[val->first].reset(); diff --git a/llarp/dnsd.cpp b/llarp/dnsd.cpp index f1005cbb4..0e32f31f6 100644 --- a/llarp/dnsd.cpp +++ b/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); } } diff --git a/llarp/encrypted_frame.cpp b/llarp/encrypted_frame.cpp index 3830c18ea..821111628 100644 --- a/llarp/encrypted_frame.cpp +++ b/llarp/encrypted_frame.cpp @@ -11,7 +11,7 @@ namespace llarp } Encrypted::Encrypted(const Encrypted& other) - : Encrypted(other.data(), other.size()) + : Encrypted(other.data(), other.size()) { } diff --git a/llarp/ev_kqueue.hpp b/llarp/ev_kqueue.hpp index 60529e3af..d94c612dc 100644 --- a/llarp/ev_kqueue.hpp +++ b/llarp/ev_kqueue.hpp @@ -57,7 +57,14 @@ namespace llarp return -1; } if(ret > sz) + { + llarp::LogWarn("ret > sz"); return -1; + } + if(!addr) + { + llarp::LogWarn("no source addr"); + } // Addr is the source udp->recvfrom(udp, addr, buf, ret); return 0; diff --git a/llarp/handlers/tun.cpp b/llarp/handlers/tun.cpp index 5fae89523..767cec257 100644 --- a/llarp/handlers/tun.cpp +++ b/llarp/handlers/tun.cpp @@ -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; } diff --git a/llarp/link_message.cpp b/llarp/link_message.cpp index 273f513b2..f124173f2 100644 --- a/llarp/link_message.cpp +++ b/llarp/link_message.cpp @@ -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; diff --git a/llarp/net.cpp b/llarp/net.cpp index 3698e1d00..5e9380bc8 100644 --- a/llarp/net.cpp +++ b/llarp/net.cpp @@ -11,6 +11,9 @@ #include #include "logger.hpp" +//#include +#include + bool operator==(const sockaddr& a, const sockaddr& b) { diff --git a/llarp/pathbuilder.cpp b/llarp/pathbuilder.cpp index d1d5dc56d..a3091cc3a 100644 --- a/llarp/pathbuilder.cpp +++ b/llarp/pathbuilder.cpp @@ -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"); diff --git a/llarp/pathset.cpp b/llarp/pathset.cpp index ff9416ac8..c1ac76241 100644 --- a/llarp/pathset.cpp +++ b/llarp/pathset.cpp @@ -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 diff --git a/llarp/service/context.cpp b/llarp/service/context.cpp index 4b65f193f..80a05c971 100644 --- a/llarp/service/context.cpp +++ b/llarp/service/context.cpp @@ -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) { diff --git a/test/net_unittest.cpp b/test/net_unittest.cpp index 99b7a4ca7..526cd97cf 100644 --- a/test/net_unittest.cpp +++ b/test/net_unittest.cpp @@ -1,10 +1,107 @@ #include #include +#include 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) diff --git a/test/test_dns_unit.cpp b/test/test_dns_unit.cpp index db96c8586..bfcaf935b 100644 --- a/test/test_dns_unit.cpp +++ b/test/test_dns_unit.cpp @@ -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); diff --git a/test/test_dnsd_unit.cpp b/test/test_dnsd_unit.cpp index b54bc89de..b77777bd6 100644 --- a/test/test_dnsd_unit.cpp +++ b/test/test_dnsd_unit.cpp @@ -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 ";