mirror of
https://github.com/oxen-io/lokinet
synced 2023-12-14 06:53:00 +01:00
add dnslib
This commit is contained in:
parent
baa94ec345
commit
1d1bde2e88
27 changed files with 1293 additions and 400 deletions
|
@ -416,8 +416,18 @@ if(WIN32)
|
|||
set(UTP_SRC ${UTP_SRC} libutp/libutp_inet_ntop.cpp)
|
||||
endif()
|
||||
|
||||
set(DNSLIB_SRC
|
||||
llarp/dns/message.cpp
|
||||
llarp/dns/name.cpp
|
||||
llarp/dns/question.cpp
|
||||
llarp/dns/rr.cpp
|
||||
llarp/dns/serialize.cpp
|
||||
llarp/dns/server.cpp
|
||||
)
|
||||
|
||||
|
||||
set(LIB_SRC
|
||||
${DNSLIB_SRC}
|
||||
${UTP_SRC}
|
||||
llarp/address_info.cpp
|
||||
llarp/bencode.cpp
|
||||
|
@ -521,6 +531,7 @@ set(TEST_SRC
|
|||
test/test_dns_unit.cpp
|
||||
test/test_dnsc_unit.cpp
|
||||
test/test_dnsd_unit.cpp
|
||||
test/test_dnslib.cpp
|
||||
test/test_llarp_queue.cpp
|
||||
test/test_llarp_queue_manager.cpp
|
||||
test/test_llarp_thread_pool.cpp
|
||||
|
|
|
@ -191,7 +191,8 @@ main(int argc, char *argv[])
|
|||
return 0;
|
||||
}
|
||||
// Configure intercept
|
||||
dnsd.intercept = &llarp_dotlokilookup_handler;
|
||||
dnsd.intercept = nullptr;
|
||||
// dnsd.intercept = &llarp_dotlokilookup_handler;
|
||||
|
||||
llarp::LogInfo("singlethread start");
|
||||
llarp_ev_loop_run_single_process(netloop, worker, logic);
|
||||
|
@ -219,7 +220,8 @@ main(int argc, char *argv[])
|
|||
return 0;
|
||||
}
|
||||
// Configure intercept
|
||||
dnsd.intercept = &llarp_dotlokilookup_handler;
|
||||
dnsd.intercept = nullptr;
|
||||
// dnsd.intercept = &llarp_dotlokilookup_handler;
|
||||
|
||||
struct sockaddr_in m_address;
|
||||
int m_sockfd;
|
||||
|
|
5
include/llarp/dns/dns.hpp
Normal file
5
include/llarp/dns/dns.hpp
Normal file
|
@ -0,0 +1,5 @@
|
|||
#include <llarp/dns/name.hpp>
|
||||
#include <llarp/dns/rr.hpp>
|
||||
#include <llarp/dns/serialize.hpp>
|
||||
#include <llarp/dns/message.hpp>
|
||||
#include <llarp/dns/server.hpp>
|
60
include/llarp/dns/message.hpp
Normal file
60
include/llarp/dns/message.hpp
Normal file
|
@ -0,0 +1,60 @@
|
|||
#ifndef LLARP_DNS_MESSAGE_HPP
|
||||
#define LLARP_DNS_MESSAGE_HPP
|
||||
#include <llarp/dns/serialize.hpp>
|
||||
#include <llarp/dns/rr.hpp>
|
||||
#include <llarp/dns/question.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace dns
|
||||
{
|
||||
using MsgID_t = uint16_t;
|
||||
using Fields_t = uint16_t;
|
||||
using Count_t = uint16_t;
|
||||
|
||||
struct MessageHeader : public Serialize
|
||||
{
|
||||
MsgID_t id;
|
||||
Fields_t fields;
|
||||
Count_t qd_count;
|
||||
Count_t an_count;
|
||||
Count_t ns_count;
|
||||
Count_t ar_count;
|
||||
|
||||
bool
|
||||
Encode(llarp_buffer_t* buf) const override;
|
||||
|
||||
bool
|
||||
Decode(llarp_buffer_t* buf) override;
|
||||
};
|
||||
|
||||
struct Message : public Serialize
|
||||
{
|
||||
void
|
||||
UpdateHeader();
|
||||
|
||||
Message&
|
||||
AddNXReply();
|
||||
|
||||
Message&
|
||||
AddINReply(llarp::huint32_t addr);
|
||||
|
||||
Message&
|
||||
AddAReply(std::string name);
|
||||
|
||||
bool
|
||||
Encode(llarp_buffer_t* buf) const override;
|
||||
|
||||
bool
|
||||
Decode(llarp_buffer_t* buf) override;
|
||||
|
||||
MessageHeader hdr;
|
||||
std::vector< Question > questions;
|
||||
std::vector< ResourceRecord > answers;
|
||||
std::vector< ResourceRecord > authorities;
|
||||
std::vector< ResourceRecord > additional;
|
||||
};
|
||||
} // namespace dns
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
28
include/llarp/dns/name.hpp
Normal file
28
include/llarp/dns/name.hpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef LLARP_DNS_NAME_HPP
|
||||
#define LLARP_DNS_NAME_HPP
|
||||
|
||||
#include <string>
|
||||
#include <llarp/buffer.h>
|
||||
#include <llarp/net_int.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace dns
|
||||
{
|
||||
using Name_t = std::string;
|
||||
|
||||
/// decode name from buffer
|
||||
bool
|
||||
DecodeName(llarp_buffer_t* buf, Name_t& name);
|
||||
|
||||
/// encode name to buffer
|
||||
bool
|
||||
EncodeName(llarp_buffer_t* buf, const Name_t& name);
|
||||
|
||||
bool
|
||||
DecodePTR(const Name_t& name, huint32_t& ip);
|
||||
|
||||
} // namespace dns
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
4
include/llarp/dns/query.hpp
Normal file
4
include/llarp/dns/query.hpp
Normal file
|
@ -0,0 +1,4 @@
|
|||
#ifndef LLARP_DNS_QUERY_HPP
|
||||
#define LLARP_DNS_QUERY_HPP
|
||||
|
||||
#endif
|
29
include/llarp/dns/question.hpp
Normal file
29
include/llarp/dns/question.hpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef LLARP_DNS_QUESTION_HPP
|
||||
#define LLARP_DNS_QUESTION_HPP
|
||||
#include <llarp/dns/serialize.hpp>
|
||||
#include <llarp/dns/name.hpp>
|
||||
#include <llarp/net_int.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace dns
|
||||
{
|
||||
using QType_t = llarp::huint16_t;
|
||||
using QClass_t = llarp::huint16_t;
|
||||
|
||||
struct Question : public Serialize
|
||||
{
|
||||
bool
|
||||
Encode(llarp_buffer_t* buf) const override;
|
||||
|
||||
bool
|
||||
Decode(llarp_buffer_t* buf) override;
|
||||
|
||||
Name_t qname;
|
||||
QType_t qtype;
|
||||
QClass_t qclass;
|
||||
};
|
||||
} // namespace dns
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
35
include/llarp/dns/rr.hpp
Normal file
35
include/llarp/dns/rr.hpp
Normal file
|
@ -0,0 +1,35 @@
|
|||
#ifndef LLARP_DNS_RR_HPP
|
||||
#define LLARP_DNS_RR_HPP
|
||||
#include <llarp/dns/name.hpp>
|
||||
#include <llarp/dns/serialize.hpp>
|
||||
#include <llarp/net_int.hpp>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace dns
|
||||
{
|
||||
using RRClass_t = llarp::huint16_t;
|
||||
using RRType_t = llarp::huint16_t;
|
||||
using RR_RData_t = std::vector< byte_t >;
|
||||
using RR_TTL_t = llarp::huint32_t;
|
||||
|
||||
struct ResourceRecord : public Serialize
|
||||
{
|
||||
bool
|
||||
Encode(llarp_buffer_t* buf) const override;
|
||||
|
||||
bool
|
||||
Decode(llarp_buffer_t* buf) override;
|
||||
|
||||
Name_t rr_name;
|
||||
RRType_t rr_type;
|
||||
RRClass_t rr_class;
|
||||
RR_TTL_t ttl;
|
||||
RR_RData_t rData;
|
||||
};
|
||||
} // namespace dns
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
39
include/llarp/dns/serialize.hpp
Normal file
39
include/llarp/dns/serialize.hpp
Normal file
|
@ -0,0 +1,39 @@
|
|||
#ifndef LLARP_DNS_SERIALIZE_HPP
|
||||
#define LLARP_DNS_SERIALIZE_HPP
|
||||
#include <llarp/buffer.h>
|
||||
#include <vector>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace dns
|
||||
{
|
||||
/// base type for serializable dns entities
|
||||
struct Serialize
|
||||
{
|
||||
/// encode entity to buffer
|
||||
virtual bool
|
||||
Encode(llarp_buffer_t* buf) const = 0;
|
||||
|
||||
/// decode entity from buffer
|
||||
virtual bool
|
||||
Decode(llarp_buffer_t* buf) = 0;
|
||||
};
|
||||
|
||||
template < typename Int_t >
|
||||
bool
|
||||
EncodeInt(llarp_buffer_t* buf, const Int_t& i);
|
||||
|
||||
template < typename Int_t >
|
||||
bool
|
||||
DecodeInt(llarp_buffer_t* buf, Int_t& i);
|
||||
|
||||
bool
|
||||
EncodeRData(llarp_buffer_t* buf, const std::vector< byte_t >& rdata);
|
||||
|
||||
bool
|
||||
DecodeRData(llarp_buffer_t* buf, std::vector< byte_t >& rdata);
|
||||
|
||||
} // namespace dns
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
93
include/llarp/dns/server.hpp
Normal file
93
include/llarp/dns/server.hpp
Normal file
|
@ -0,0 +1,93 @@
|
|||
#ifndef LLARP_DNS_SERVER_HPP
|
||||
#define LLARP_DNS_SERVER_HPP
|
||||
#include <llarp/string_view.hpp>
|
||||
#include <llarp/dns/message.hpp>
|
||||
|
||||
#include <llarp/ev.h>
|
||||
#include <llarp/net.hpp>
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace dns
|
||||
{
|
||||
/// handler of dns query hooking
|
||||
struct IQueryHandler
|
||||
{
|
||||
/// return true if we should hook this message
|
||||
virtual bool
|
||||
ShouldHookDNSMessage(const Message& msg) const = 0;
|
||||
|
||||
/// handle a hooked message
|
||||
virtual bool
|
||||
HandleHookedDNSMessage(Message query,
|
||||
std::function< void(Message) > sendReply) = 0;
|
||||
};
|
||||
|
||||
struct Proxy
|
||||
{
|
||||
Proxy(llarp_ev_loop* loop, IQueryHandler* handler);
|
||||
|
||||
bool
|
||||
Start(const llarp::Addr& addr,
|
||||
const std::vector< llarp::Addr >& resolvers);
|
||||
|
||||
void
|
||||
Stop();
|
||||
|
||||
private:
|
||||
/// low level packet handler
|
||||
static void
|
||||
HandleUDPRecv(llarp_udp_io*, const struct sockaddr*, llarp_buffer_t);
|
||||
|
||||
/// low level ticker
|
||||
static void
|
||||
HandleTick(llarp_udp_io*);
|
||||
|
||||
void
|
||||
Tick(llarp_time_t now);
|
||||
|
||||
void
|
||||
HandlePkt(llarp::Addr from, llarp_buffer_t* buf);
|
||||
|
||||
void
|
||||
SendMessageTo(llarp::Addr to, Message msg);
|
||||
|
||||
llarp::Addr
|
||||
PickRandomResolver() const;
|
||||
|
||||
private:
|
||||
llarp_udp_io m_UDP;
|
||||
llarp_ev_loop* m_Loop;
|
||||
IQueryHandler* m_QueryHandler;
|
||||
std::vector< llarp::Addr > m_Resolvers;
|
||||
|
||||
struct TX
|
||||
{
|
||||
MsgID_t txid;
|
||||
llarp::Addr from;
|
||||
|
||||
bool
|
||||
operator==(const TX& other) const
|
||||
{
|
||||
return txid == other.txid && from == other.from;
|
||||
}
|
||||
|
||||
struct Hash
|
||||
{
|
||||
size_t
|
||||
operator()(const TX& t) const noexcept
|
||||
{
|
||||
return t.txid ^ llarp::Addr::Hash()(t.from);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// maps tx to who to send reply to
|
||||
std::unordered_map< TX, llarp::Addr, TX::Hash > m_Forwarded;
|
||||
};
|
||||
} // namespace dns
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
23
include/llarp/dns/string.hpp
Normal file
23
include/llarp/dns/string.hpp
Normal file
|
@ -0,0 +1,23 @@
|
|||
#ifndef LLARP_DNS_STRING_HPP
|
||||
#define LLARP_DNS_STRING_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace dns
|
||||
{
|
||||
using name_t = std::string;
|
||||
|
||||
/// decode name from buffer
|
||||
bool
|
||||
decode_name(llarp_buffer_t* buf, name_t& name);
|
||||
|
||||
/// encode name to buffer
|
||||
bool
|
||||
encode_name(llarp_buffer_t* buf, const name_t& name);
|
||||
|
||||
} // namespace dns
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
|
@ -5,36 +5,25 @@
|
|||
|
||||
#include "dnsd.hpp"
|
||||
|
||||
using map_address_hook_func =
|
||||
std::function< bool(const byte_t *addr, bool isSNode, uint32_t ip) >;
|
||||
struct dotLokiLookup;
|
||||
|
||||
using obtain_address_func =
|
||||
std::function< bool(struct dotLokiLookup *, const byte_t *addr,
|
||||
bool isSNode, llarp::huint32_t &ip) >;
|
||||
|
||||
/// dotLokiLookup context/config
|
||||
struct dotLokiLookup
|
||||
{
|
||||
/// for timers (MAYBEFIXME? maybe we decouple this, yes pls have a generic
|
||||
/// passed in)
|
||||
// we can use DNSc for access to the logic
|
||||
struct llarp_logic *logic;
|
||||
|
||||
/// which ip tracker to use
|
||||
struct dns_iptracker *ip_tracker;
|
||||
|
||||
/// tunEndpoint
|
||||
// llarp::handlers::TunEndpoint *tunEndpoint; // is this even needed here?
|
||||
void *user; // well dotLokiLookup current uses it to access the tun if
|
||||
// pointer to tunendpoint properties?
|
||||
// llarp::service::Context *hiddenServiceContext;
|
||||
|
||||
// need a way to reference
|
||||
// 1. mapaddress
|
||||
map_address_hook_func map_address_handler;
|
||||
// std::function< bool(const llarp::service::Address &addr, uint32_t ip),
|
||||
// llarp::handlers::TunEndpoint * > callback;
|
||||
// 2. prefetch
|
||||
/// opaque user data
|
||||
void *user;
|
||||
/// get address for lookup
|
||||
obtain_address_func obtainAddress;
|
||||
};
|
||||
|
||||
dnsd_query_hook_response *
|
||||
void
|
||||
llarp_dotlokilookup_handler(std::string name,
|
||||
const dnsd_question_request *request);
|
||||
const dnsd_question_request *request,
|
||||
struct dnsd_query_hook_response *result);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,9 +5,8 @@
|
|||
#include <llarp/ip.hpp>
|
||||
#include <llarp/service/endpoint.hpp>
|
||||
#include <llarp/threading.hpp>
|
||||
#include <llarp/dnsd.hpp> // for relay
|
||||
#include <llarp/dns_dotlokilookup.hpp> // for lookup
|
||||
#include <llarp/dns_iptracker.hpp> // for tracker
|
||||
#include <llarp/dns/server.hpp>
|
||||
#include <llarp/net.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
|
@ -18,7 +17,7 @@ namespace llarp
|
|||
static const char DefaultTunDstAddr[] = "10.10.0.1";
|
||||
static const char DefaultTunSrcAddr[] = "10.10.0.2";
|
||||
|
||||
struct TunEndpoint : public service::Endpoint
|
||||
struct TunEndpoint : public service::Endpoint, public dns::IQueryHandler
|
||||
{
|
||||
TunEndpoint(const std::string& nickname, llarp_router* r);
|
||||
~TunEndpoint();
|
||||
|
@ -29,6 +28,14 @@ namespace llarp
|
|||
virtual void
|
||||
Tick(llarp_time_t now);
|
||||
|
||||
bool
|
||||
ShouldHookDNSMessage(const dns::Message& msg) const override;
|
||||
|
||||
bool
|
||||
HandleHookedDNSMessage(
|
||||
dns::Message query,
|
||||
std::function< void(dns::Message) > sendreply) override;
|
||||
|
||||
void
|
||||
TickTun(llarp_time_t now);
|
||||
|
||||
|
@ -66,16 +73,6 @@ namespace llarp
|
|||
bool
|
||||
HasLocalIP(const huint32_t& ip) const;
|
||||
|
||||
#ifndef WIN32
|
||||
/// overrides Endpoint
|
||||
bool
|
||||
IsolationFailed()
|
||||
{
|
||||
m_TunSetupResult.set_value(false);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
llarp_tun_io tunif;
|
||||
std::unique_ptr< llarp_fd_promise > Promise;
|
||||
|
||||
|
@ -173,18 +170,18 @@ namespace llarp
|
|||
});
|
||||
}
|
||||
|
||||
void
|
||||
SendDNSReply(service::Address addr,
|
||||
service::Endpoint::OutboundContext* ctx, dns::Message query,
|
||||
std::function< void(dns::Message) > reply);
|
||||
|
||||
#ifndef WIN32
|
||||
/// handles setup, given value true on success and false on failure to set
|
||||
/// up interface
|
||||
std::promise< bool > m_TunSetupResult;
|
||||
/// handles fd injection force android
|
||||
std::promise< int > m_VPNPromise;
|
||||
#endif
|
||||
/// DNS server per tun
|
||||
struct dnsd_context dnsd;
|
||||
/// DNS loki lookup subsystem configuration (also holds optional iptracker
|
||||
/// for netns)
|
||||
struct dotLokiLookup dll;
|
||||
|
||||
/// our dns resolver
|
||||
dns::Proxy m_Resolver;
|
||||
|
||||
/// maps ip address to timestamp last active
|
||||
std::unordered_map< huint32_t, llarp_time_t, huint32_t::Hash >
|
||||
|
@ -195,8 +192,10 @@ namespace llarp
|
|||
huint32_t m_NextIP;
|
||||
/// highest ip address to allocate (host byte order)
|
||||
huint32_t m_MaxIP;
|
||||
/// upstream dns
|
||||
llarp::Addr m_UpstreamDNSAddr;
|
||||
/// our ip range we are using
|
||||
llarp::IPRange m_OurRange;
|
||||
/// upstream dns resolver list
|
||||
std::vector< llarp::Addr > m_UpstreamResolvers;
|
||||
/// local dns
|
||||
llarp::Addr m_LocalResolverAddr;
|
||||
};
|
||||
|
|
|
@ -3,25 +3,12 @@
|
|||
#include <llarp/address_info.hpp>
|
||||
#include <llarp/net.h>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include "logger.hpp"
|
||||
#include "mem.hpp"
|
||||
#include <llarp/string_view.hpp>
|
||||
#include <llarp/net_int.hpp>
|
||||
#include <vector>
|
||||
|
||||
#include <stdlib.h> // for itoa
|
||||
|
||||
// for addrinfo
|
||||
#ifndef _WIN32
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#else
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#define inet_aton(x, y) inet_pton(AF_INET, x, y)
|
||||
#endif
|
||||
|
||||
bool
|
||||
operator==(const sockaddr& a, const sockaddr& b);
|
||||
|
||||
|
@ -54,183 +41,6 @@ llarp_getPrivateIfs();
|
|||
|
||||
namespace llarp
|
||||
{
|
||||
// clang-format off
|
||||
|
||||
struct huint32_t
|
||||
{
|
||||
uint32_t h;
|
||||
|
||||
constexpr huint32_t
|
||||
operator &(huint32_t x) const { return huint32_t{uint32_t(h & x.h)}; }
|
||||
constexpr huint32_t
|
||||
operator |(huint32_t x) const { return huint32_t{uint32_t(h | x.h)}; }
|
||||
constexpr huint32_t
|
||||
operator ^(huint32_t x) const { return huint32_t{uint32_t(h ^ x.h)}; }
|
||||
|
||||
constexpr huint32_t
|
||||
operator ~() const { return huint32_t{uint32_t(~h)}; }
|
||||
|
||||
inline huint32_t operator ++() { ++h; return *this; }
|
||||
inline huint32_t operator --() { --h; return *this; }
|
||||
|
||||
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)
|
||||
{
|
||||
uint32_t n = htonl(a.h);
|
||||
char tmp[INET_ADDRSTRLEN] = {0};
|
||||
if(inet_ntop(AF_INET, (void*)&n, tmp, sizeof(tmp)))
|
||||
{
|
||||
out << tmp;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
struct Hash
|
||||
{
|
||||
inline size_t
|
||||
operator ()(huint32_t x) const
|
||||
{
|
||||
return std::hash< uint32_t >{}(x.h);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
struct nuint32_t
|
||||
{
|
||||
uint32_t n;
|
||||
|
||||
constexpr nuint32_t
|
||||
operator &(nuint32_t x) const { return nuint32_t{uint32_t(n & x.n)}; }
|
||||
constexpr nuint32_t
|
||||
operator |(nuint32_t x) const { return nuint32_t{uint32_t(n | x.n)}; }
|
||||
constexpr nuint32_t
|
||||
operator ^(nuint32_t x) const { return nuint32_t{uint32_t(n ^ x.n)}; }
|
||||
|
||||
constexpr nuint32_t
|
||||
operator ~() const { return nuint32_t{uint32_t(~n)}; }
|
||||
|
||||
inline nuint32_t operator ++() { ++n; return *this; }
|
||||
inline nuint32_t operator --() { --n; return *this; }
|
||||
|
||||
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, sizeof(tmp)))
|
||||
{
|
||||
out << tmp;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
struct Hash
|
||||
{
|
||||
inline size_t
|
||||
operator ()(nuint32_t x) const
|
||||
{
|
||||
return std::hash< uint32_t >{}(x.n);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
struct huint16_t
|
||||
{
|
||||
uint16_t h;
|
||||
|
||||
constexpr huint16_t
|
||||
operator &(huint16_t x) const { return huint16_t{uint16_t(h & x.h)}; }
|
||||
constexpr huint16_t
|
||||
operator |(huint16_t x) const { return huint16_t{uint16_t(h | x.h)}; }
|
||||
constexpr huint16_t
|
||||
operator ~() const { return huint16_t{uint16_t(~h)}; }
|
||||
|
||||
inline huint16_t operator ++() { ++h; return *this; }
|
||||
inline huint16_t operator --() { --h; return *this; }
|
||||
|
||||
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)
|
||||
{
|
||||
return out << a.h;
|
||||
}
|
||||
|
||||
struct Hash
|
||||
{
|
||||
inline size_t
|
||||
operator ()(huint16_t x) const
|
||||
{
|
||||
return std::hash< uint16_t >{}(x.h);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
struct nuint16_t
|
||||
{
|
||||
uint16_t n;
|
||||
|
||||
constexpr nuint16_t
|
||||
operator &(nuint16_t x) const { return nuint16_t{uint16_t(n & x.n)}; }
|
||||
constexpr nuint16_t
|
||||
operator |(nuint16_t x) const { return nuint16_t{uint16_t(n | x.n)}; }
|
||||
constexpr nuint16_t
|
||||
operator ~() const { return nuint16_t{uint16_t(~n)}; }
|
||||
|
||||
inline nuint16_t operator ++() { ++n; return *this; }
|
||||
inline nuint16_t operator --() { --n; return *this; }
|
||||
|
||||
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)
|
||||
{
|
||||
return out << ntohs(a.n);
|
||||
}
|
||||
|
||||
struct Hash
|
||||
{
|
||||
inline size_t
|
||||
operator ()(nuint16_t x) const
|
||||
{
|
||||
return std::hash< uint16_t >{}(x.n);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// clang-format on
|
||||
|
||||
static inline nuint32_t
|
||||
xhtonl(huint32_t x)
|
||||
{
|
||||
return nuint32_t{htonl(x.h)};
|
||||
}
|
||||
|
||||
static inline huint32_t
|
||||
xntohl(nuint32_t x)
|
||||
{
|
||||
return huint32_t{ntohl(x.n)};
|
||||
}
|
||||
|
||||
static inline nuint16_t
|
||||
xhtons(huint16_t x)
|
||||
{
|
||||
return nuint16_t{htons(x.h)};
|
||||
}
|
||||
|
||||
static inline huint16_t
|
||||
xntohs(nuint16_t x)
|
||||
{
|
||||
return huint16_t{ntohs(x.n)};
|
||||
}
|
||||
|
||||
struct IPRange
|
||||
{
|
||||
huint32_t addr;
|
||||
|
|
199
include/llarp/net_int.hpp
Normal file
199
include/llarp/net_int.hpp
Normal file
|
@ -0,0 +1,199 @@
|
|||
#ifndef LLARP_NET_INT_HPP
|
||||
#define LLARP_NET_INT_HPP
|
||||
|
||||
// for addrinfo
|
||||
#ifndef _WIN32
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#else
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#define inet_aton(x, y) inet_pton(AF_INET, x, y)
|
||||
#endif
|
||||
|
||||
#include <stdlib.h> // for itoa
|
||||
#include <iostream>
|
||||
#include <llarp/net.h>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
// clang-format off
|
||||
|
||||
struct huint32_t
|
||||
{
|
||||
uint32_t h;
|
||||
|
||||
constexpr huint32_t
|
||||
operator &(huint32_t x) const { return huint32_t{uint32_t(h & x.h)}; }
|
||||
constexpr huint32_t
|
||||
operator |(huint32_t x) const { return huint32_t{uint32_t(h | x.h)}; }
|
||||
constexpr huint32_t
|
||||
operator ^(huint32_t x) const { return huint32_t{uint32_t(h ^ x.h)}; }
|
||||
|
||||
constexpr huint32_t
|
||||
operator ~() const { return huint32_t{uint32_t(~h)}; }
|
||||
|
||||
inline huint32_t operator ++() { ++h; return *this; }
|
||||
inline huint32_t operator --() { --h; return *this; }
|
||||
|
||||
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)
|
||||
{
|
||||
uint32_t n = htonl(a.h);
|
||||
char tmp[INET_ADDRSTRLEN] = {0};
|
||||
if(inet_ntop(AF_INET, (void*)&n, tmp, sizeof(tmp)))
|
||||
{
|
||||
out << tmp;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
struct Hash
|
||||
{
|
||||
inline size_t
|
||||
operator ()(huint32_t x) const
|
||||
{
|
||||
return std::hash< uint32_t >{}(x.h);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
struct nuint32_t
|
||||
{
|
||||
uint32_t n;
|
||||
|
||||
constexpr nuint32_t
|
||||
operator &(nuint32_t x) const { return nuint32_t{uint32_t(n & x.n)}; }
|
||||
constexpr nuint32_t
|
||||
operator |(nuint32_t x) const { return nuint32_t{uint32_t(n | x.n)}; }
|
||||
constexpr nuint32_t
|
||||
operator ^(nuint32_t x) const { return nuint32_t{uint32_t(n ^ x.n)}; }
|
||||
|
||||
constexpr nuint32_t
|
||||
operator ~() const { return nuint32_t{uint32_t(~n)}; }
|
||||
|
||||
inline nuint32_t operator ++() { ++n; return *this; }
|
||||
inline nuint32_t operator --() { --n; return *this; }
|
||||
|
||||
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, sizeof(tmp)))
|
||||
{
|
||||
out << tmp;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
struct Hash
|
||||
{
|
||||
inline size_t
|
||||
operator ()(nuint32_t x) const
|
||||
{
|
||||
return std::hash< uint32_t >{}(x.n);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
struct huint16_t
|
||||
{
|
||||
uint16_t h;
|
||||
|
||||
constexpr huint16_t
|
||||
operator &(huint16_t x) const { return huint16_t{uint16_t(h & x.h)}; }
|
||||
constexpr huint16_t
|
||||
operator |(huint16_t x) const { return huint16_t{uint16_t(h | x.h)}; }
|
||||
constexpr huint16_t
|
||||
operator ~() const { return huint16_t{uint16_t(~h)}; }
|
||||
|
||||
inline huint16_t operator ++() { ++h; return *this; }
|
||||
inline huint16_t operator --() { --h; return *this; }
|
||||
|
||||
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)
|
||||
{
|
||||
return out << a.h;
|
||||
}
|
||||
|
||||
struct Hash
|
||||
{
|
||||
inline size_t
|
||||
operator ()(huint16_t x) const
|
||||
{
|
||||
return std::hash< uint16_t >{}(x.h);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
struct nuint16_t
|
||||
{
|
||||
uint16_t n;
|
||||
|
||||
constexpr nuint16_t
|
||||
operator &(nuint16_t x) const { return nuint16_t{uint16_t(n & x.n)}; }
|
||||
constexpr nuint16_t
|
||||
operator |(nuint16_t x) const { return nuint16_t{uint16_t(n | x.n)}; }
|
||||
constexpr nuint16_t
|
||||
operator ~() const { return nuint16_t{uint16_t(~n)}; }
|
||||
|
||||
inline nuint16_t operator ++() { ++n; return *this; }
|
||||
inline nuint16_t operator --() { --n; return *this; }
|
||||
|
||||
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)
|
||||
{
|
||||
return out << ntohs(a.n);
|
||||
}
|
||||
|
||||
struct Hash
|
||||
{
|
||||
inline size_t
|
||||
operator ()(nuint16_t x) const
|
||||
{
|
||||
return std::hash< uint16_t >{}(x.n);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// clang-format on
|
||||
|
||||
static inline nuint32_t
|
||||
xhtonl(huint32_t x)
|
||||
{
|
||||
return nuint32_t{htonl(x.h)};
|
||||
}
|
||||
|
||||
static inline huint32_t
|
||||
xntohl(nuint32_t x)
|
||||
{
|
||||
return huint32_t{ntohl(x.n)};
|
||||
}
|
||||
|
||||
static inline nuint16_t
|
||||
xhtons(huint16_t x)
|
||||
{
|
||||
return nuint16_t{htons(x.h)};
|
||||
}
|
||||
|
||||
static inline huint16_t
|
||||
xntohs(nuint16_t x)
|
||||
{
|
||||
return huint16_t{ntohs(x.n)};
|
||||
}
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
|
@ -9,14 +9,14 @@ namespace llarp
|
|||
{
|
||||
namespace service
|
||||
{
|
||||
/// Snapp Address
|
||||
/// Snapp/Snode Address
|
||||
struct Address
|
||||
{
|
||||
std::string
|
||||
ToString() const;
|
||||
ToString(const char* tld = ".loki") const;
|
||||
|
||||
bool
|
||||
FromString(const std::string& str);
|
||||
FromString(const std::string& str, const char* tld = ".loki");
|
||||
|
||||
Address()
|
||||
{
|
||||
|
|
|
@ -341,8 +341,10 @@ extern "C"
|
|||
llarp_main_init_dotLokiLookup(struct llarp_main *ptr,
|
||||
struct dotLokiLookup *dll)
|
||||
{
|
||||
dll->logic = ptr->ctx->logic;
|
||||
return true;
|
||||
(void)ptr;
|
||||
(void)dll;
|
||||
// TODO: gutt me
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
162
llarp/dns/message.cpp
Normal file
162
llarp/dns/message.cpp
Normal file
|
@ -0,0 +1,162 @@
|
|||
#include <llarp/dns/message.hpp>
|
||||
#include <llarp/endian.hpp>
|
||||
namespace llarp
|
||||
{
|
||||
namespace dns
|
||||
{
|
||||
bool
|
||||
MessageHeader::Encode(llarp_buffer_t* buf) const
|
||||
{
|
||||
if(!EncodeInt(buf, id))
|
||||
return false;
|
||||
if(!EncodeInt(buf, fields))
|
||||
return false;
|
||||
if(!EncodeInt(buf, qd_count))
|
||||
return false;
|
||||
if(!EncodeInt(buf, an_count))
|
||||
return false;
|
||||
if(!EncodeInt(buf, ns_count))
|
||||
return false;
|
||||
return EncodeInt(buf, ar_count);
|
||||
}
|
||||
|
||||
bool
|
||||
MessageHeader::Decode(llarp_buffer_t* buf)
|
||||
{
|
||||
if(!DecodeInt(buf, id))
|
||||
return false;
|
||||
if(!DecodeInt(buf, fields))
|
||||
return false;
|
||||
if(!DecodeInt(buf, qd_count))
|
||||
return false;
|
||||
if(!DecodeInt(buf, an_count))
|
||||
return false;
|
||||
if(!DecodeInt(buf, ns_count))
|
||||
return false;
|
||||
return DecodeInt(buf, ar_count);
|
||||
}
|
||||
|
||||
bool
|
||||
Message::Encode(llarp_buffer_t* buf) const
|
||||
{
|
||||
if(!hdr.Encode(buf))
|
||||
return false;
|
||||
|
||||
for(const auto& question : questions)
|
||||
if(!question.Encode(buf))
|
||||
return false;
|
||||
|
||||
for(const auto& answer : answers)
|
||||
if(!answer.Encode(buf))
|
||||
return false;
|
||||
|
||||
for(const auto& auth : authorities)
|
||||
if(!auth.Encode(buf))
|
||||
return false;
|
||||
|
||||
for(const auto& rr : additional)
|
||||
if(!rr.Encode(buf))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
Message::Decode(llarp_buffer_t* buf)
|
||||
{
|
||||
if(!hdr.Decode(buf))
|
||||
return false;
|
||||
questions.resize(hdr.qd_count);
|
||||
answers.resize(hdr.an_count);
|
||||
authorities.resize(hdr.ns_count);
|
||||
additional.resize(hdr.ar_count);
|
||||
|
||||
for(auto& qd : questions)
|
||||
if(!qd.Decode(buf))
|
||||
return false;
|
||||
|
||||
for(auto& an : answers)
|
||||
if(!an.Decode(buf))
|
||||
return false;
|
||||
|
||||
for(auto& ns : authorities)
|
||||
if(!ns.Decode(buf))
|
||||
return false;
|
||||
|
||||
for(auto& ar : additional)
|
||||
if(!ar.Decode(buf))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
Message::UpdateHeader()
|
||||
{
|
||||
hdr.qd_count = questions.size();
|
||||
hdr.an_count = answers.size();
|
||||
hdr.ns_count = authorities.size();
|
||||
hdr.ar_count = additional.size();
|
||||
}
|
||||
|
||||
Message&
|
||||
Message::AddINReply(llarp::huint32_t ip)
|
||||
{
|
||||
if(questions.size())
|
||||
{
|
||||
hdr.fields |= (1 << 15);
|
||||
const auto& question = questions[0];
|
||||
answers.emplace_back();
|
||||
auto& rec = answers.back();
|
||||
rec.rr_name = question.qname;
|
||||
rec.rr_type.h = 1;
|
||||
rec.rr_class = question.qclass;
|
||||
rec.ttl.h = 1;
|
||||
rec.rData.resize(4);
|
||||
htobe32buf(rec.rData.data(), ip.h);
|
||||
UpdateHeader();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Message&
|
||||
Message::AddAReply(std::string name)
|
||||
{
|
||||
if(questions.size())
|
||||
{
|
||||
hdr.fields |= (1 << 15);
|
||||
const auto& question = questions[0];
|
||||
answers.emplace_back();
|
||||
auto& rec = answers.back();
|
||||
rec.rr_name = question.qname;
|
||||
rec.rr_type = question.qtype;
|
||||
rec.rr_class.h = 1;
|
||||
rec.ttl.h = 1;
|
||||
rec.rData.resize(name.size());
|
||||
memcpy(rec.rData.data(), name.c_str(), rec.rData.size());
|
||||
UpdateHeader();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Message&
|
||||
Message::AddNXReply()
|
||||
{
|
||||
if(questions.size())
|
||||
{
|
||||
hdr.fields |= (1 << 15) | (1 << 3);
|
||||
const auto& question = questions[0];
|
||||
answers.emplace_back();
|
||||
auto& nx = answers.back();
|
||||
nx.rr_name = question.qname;
|
||||
nx.rr_type = question.qtype;
|
||||
nx.rr_class = question.qclass;
|
||||
nx.ttl.h = 1;
|
||||
nx.rData.resize(1);
|
||||
nx.rData.data()[0] = 0;
|
||||
UpdateHeader();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // namespace dns
|
||||
} // namespace llarp
|
82
llarp/dns/name.cpp
Normal file
82
llarp/dns/name.cpp
Normal file
|
@ -0,0 +1,82 @@
|
|||
#include <llarp/dns/name.hpp>
|
||||
#include <llarp/net.hpp>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace dns
|
||||
{
|
||||
bool
|
||||
DecodeName(llarp_buffer_t* buf, Name_t& name)
|
||||
{
|
||||
if(llarp_buffer_size_left(*buf) < 1)
|
||||
return false;
|
||||
std::stringstream ss;
|
||||
size_t l;
|
||||
do
|
||||
{
|
||||
l = *buf->cur;
|
||||
buf->cur++;
|
||||
if(llarp_buffer_size_left(*buf) < l)
|
||||
return false;
|
||||
if(l)
|
||||
ss << Name_t((const char*)buf->cur, l);
|
||||
ss << ".";
|
||||
} while(l);
|
||||
name = ss.str();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
EncodeName(llarp_buffer_t* buf, const Name_t& name)
|
||||
{
|
||||
std::stringstream ss(name);
|
||||
if(name.size() == 0 || name[name.size() - 1] != '.')
|
||||
ss << ".";
|
||||
std::string part;
|
||||
while(std::getline(ss, part, '.'))
|
||||
{
|
||||
uint8_t l;
|
||||
if(part.size() > 63)
|
||||
return false;
|
||||
l = part.size();
|
||||
*buf->cur = l;
|
||||
buf->cur++;
|
||||
if(llarp_buffer_size_left(*buf) < l)
|
||||
return false;
|
||||
memcpy(buf->cur, part.c_str(), l);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DecodePTR(const Name_t& name, huint32_t& ip)
|
||||
{
|
||||
auto pos = name.find(".in-addr.arpa.");
|
||||
if(pos == Name_t::npos)
|
||||
return false;
|
||||
std::string sub = name.substr(0, pos - 1);
|
||||
if(std::count(sub.begin(), sub.end(), '.') == 4)
|
||||
{
|
||||
uint8_t a, b, c, d;
|
||||
pos = sub.find('.');
|
||||
d = atoi(sub.substr(0, pos).c_str());
|
||||
sub = sub.substr(pos);
|
||||
pos = sub.find('.');
|
||||
c = atoi(sub.substr(0, pos).c_str());
|
||||
sub = sub.substr(pos);
|
||||
pos = sub.find('.');
|
||||
b = atoi(sub.substr(0, pos).c_str());
|
||||
sub = sub.substr(pos);
|
||||
pos = sub.find('.');
|
||||
a = atoi(sub.substr(0, pos).c_str());
|
||||
ip = llarp::ipaddr_ipv4_bits(a, b, c, d);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace dns
|
||||
} // namespace llarp
|
27
llarp/dns/question.cpp
Normal file
27
llarp/dns/question.cpp
Normal file
|
@ -0,0 +1,27 @@
|
|||
#include <llarp/dns/question.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace dns
|
||||
{
|
||||
bool
|
||||
Question::Encode(llarp_buffer_t* buf) const
|
||||
{
|
||||
if(!EncodeName(buf, qname))
|
||||
return false;
|
||||
if(!EncodeInt(buf, qtype))
|
||||
return false;
|
||||
return EncodeInt(buf, qclass);
|
||||
}
|
||||
|
||||
bool
|
||||
Question::Decode(llarp_buffer_t* buf)
|
||||
{
|
||||
if(!DecodeName(buf, qname))
|
||||
return false;
|
||||
if(!DecodeInt(buf, qtype))
|
||||
return false;
|
||||
return DecodeInt(buf, qclass);
|
||||
}
|
||||
} // namespace dns
|
||||
} // namespace llarp
|
35
llarp/dns/rr.cpp
Normal file
35
llarp/dns/rr.cpp
Normal file
|
@ -0,0 +1,35 @@
|
|||
#include <llarp/dns/rr.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace dns
|
||||
{
|
||||
bool
|
||||
ResourceRecord::Encode(llarp_buffer_t* buf) const
|
||||
{
|
||||
if(!EncodeName(buf, rr_name))
|
||||
return false;
|
||||
if(!EncodeInt(buf, rr_type))
|
||||
return false;
|
||||
if(!EncodeInt(buf, rr_class))
|
||||
return false;
|
||||
if(!EncodeInt(buf, ttl))
|
||||
return false;
|
||||
return EncodeRData(buf, rData);
|
||||
}
|
||||
|
||||
bool
|
||||
ResourceRecord::Decode(llarp_buffer_t* buf)
|
||||
{
|
||||
if(!DecodeName(buf, rr_name))
|
||||
return false;
|
||||
if(!DecodeInt(buf, rr_type))
|
||||
return false;
|
||||
if(!DecodeInt(buf, rr_class))
|
||||
return false;
|
||||
if(!DecodeInt(buf, ttl))
|
||||
return false;
|
||||
return DecodeRData(buf, rData);
|
||||
}
|
||||
} // namespace dns
|
||||
} // namespace llarp
|
76
llarp/dns/serialize.cpp
Normal file
76
llarp/dns/serialize.cpp
Normal file
|
@ -0,0 +1,76 @@
|
|||
#include <llarp/dns/serialize.hpp>
|
||||
#include <llarp/net_int.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace dns
|
||||
{
|
||||
template <>
|
||||
bool
|
||||
DecodeInt(llarp_buffer_t* buf, llarp::huint32_t& i)
|
||||
{
|
||||
return llarp_buffer_read_uint32(buf, &i.h);
|
||||
}
|
||||
|
||||
template <>
|
||||
bool
|
||||
EncodeInt(llarp_buffer_t* buf, const llarp::huint32_t& i)
|
||||
{
|
||||
return llarp_buffer_put_uint32(buf, i.h);
|
||||
}
|
||||
|
||||
template <>
|
||||
bool
|
||||
DecodeInt(llarp_buffer_t* buf, llarp::huint16_t& i)
|
||||
{
|
||||
return llarp_buffer_read_uint16(buf, &i.h);
|
||||
}
|
||||
|
||||
template <>
|
||||
bool
|
||||
EncodeInt(llarp_buffer_t* buf, const llarp::huint16_t& i)
|
||||
{
|
||||
return llarp_buffer_put_uint16(buf, i.h);
|
||||
}
|
||||
|
||||
template <>
|
||||
bool
|
||||
DecodeInt(llarp_buffer_t* buf, uint16_t& i)
|
||||
{
|
||||
return llarp_buffer_read_uint16(buf, &i);
|
||||
}
|
||||
|
||||
template <>
|
||||
bool
|
||||
EncodeInt(llarp_buffer_t* buf, const uint16_t& i)
|
||||
{
|
||||
return llarp_buffer_put_uint16(buf, i);
|
||||
}
|
||||
|
||||
bool
|
||||
EncodeRData(llarp_buffer_t* buf, const std::vector< byte_t >& v)
|
||||
{
|
||||
if(v.size() > 65536)
|
||||
return false;
|
||||
llarp::huint16_t len;
|
||||
len.h = v.size();
|
||||
return EncodeInt(buf, len) && llarp_buffer_write(buf, v.data(), v.size());
|
||||
}
|
||||
|
||||
bool
|
||||
DecodeRData(llarp_buffer_t* buf, std::vector< byte_t >& v)
|
||||
{
|
||||
llarp::huint16_t len = {0};
|
||||
if(!DecodeInt(buf, len))
|
||||
return false;
|
||||
size_t left = llarp_buffer_size_left(*buf);
|
||||
if(left < len.h)
|
||||
return false;
|
||||
v.resize(size_t(len.h));
|
||||
memcpy(v.data(), buf->cur, len.h);
|
||||
buf->cur += len.h;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace dns
|
||||
} // namespace llarp
|
112
llarp/dns/server.cpp
Normal file
112
llarp/dns/server.cpp
Normal file
|
@ -0,0 +1,112 @@
|
|||
#include <llarp/dns/server.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace dns
|
||||
{
|
||||
Proxy::Proxy(llarp_ev_loop* loop, IQueryHandler* h)
|
||||
: m_Loop(loop), m_QueryHandler(h)
|
||||
{
|
||||
m_UDP.user = this;
|
||||
m_UDP.tick = &HandleTick;
|
||||
m_UDP.recvfrom = &HandleUDPRecv;
|
||||
}
|
||||
|
||||
void
|
||||
Proxy::Stop()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
Proxy::Start(const llarp::Addr& addr,
|
||||
const std::vector< llarp::Addr >& resolvers)
|
||||
{
|
||||
m_Resolvers.clear();
|
||||
m_Resolvers = resolvers;
|
||||
if(m_Resolvers.size() == 0)
|
||||
{
|
||||
llarp::LogError("no upstream dns provide specified");
|
||||
return false;
|
||||
}
|
||||
return llarp_ev_add_udp(m_Loop, &m_UDP, addr) == 0;
|
||||
}
|
||||
|
||||
void
|
||||
Proxy::HandleUDPRecv(llarp_udp_io* u, const sockaddr* from,
|
||||
llarp_buffer_t buf)
|
||||
{
|
||||
static_cast< Proxy* >(u->user)->HandlePkt(*from, &buf);
|
||||
}
|
||||
|
||||
llarp::Addr
|
||||
Proxy::PickRandomResolver() const
|
||||
{
|
||||
size_t sz = m_Resolvers.size();
|
||||
if(sz == 0)
|
||||
return llarp::Addr("1.1.1.1", 52);
|
||||
if(sz == 1)
|
||||
return m_Resolvers[0];
|
||||
auto itr = m_Resolvers.begin();
|
||||
std::advance(itr, llarp_randint() % sz);
|
||||
return *itr;
|
||||
}
|
||||
|
||||
void
|
||||
Proxy::HandleTick(llarp_udp_io*)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Proxy::SendMessageTo(llarp::Addr to, Message msg)
|
||||
{
|
||||
byte_t tmp[1500] = {0};
|
||||
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
|
||||
if(msg.Encode(&buf))
|
||||
{
|
||||
buf.sz = buf.cur - buf.base;
|
||||
buf.cur = buf.base;
|
||||
llarp_ev_udp_sendto(&m_UDP, to, buf);
|
||||
}
|
||||
else
|
||||
llarp::LogWarn("failed to encode dns message when sending");
|
||||
}
|
||||
|
||||
void
|
||||
Proxy::HandlePkt(llarp::Addr from, llarp_buffer_t* pkt)
|
||||
{
|
||||
Message msg;
|
||||
if(!msg.Decode(pkt))
|
||||
{
|
||||
llarp::LogWarn("failed to handle dns message from ", from);
|
||||
llarp::DumpBuffer(*pkt);
|
||||
return;
|
||||
}
|
||||
if(m_QueryHandler && m_QueryHandler->ShouldHookDNSMessage(msg))
|
||||
{
|
||||
if(!m_QueryHandler->HandleHookedDNSMessage(
|
||||
msg,
|
||||
std::bind(&Proxy::SendMessageTo, this, from,
|
||||
std::placeholders::_1)))
|
||||
{
|
||||
llarp::LogWarn("failed to handle hooked dns");
|
||||
}
|
||||
return;
|
||||
}
|
||||
TX tx = {msg.hdr.id, from};
|
||||
auto itr = m_Forwarded.find(tx);
|
||||
if(itr == m_Forwarded.end())
|
||||
{
|
||||
// new forwarded query
|
||||
tx.from = PickRandomResolver();
|
||||
m_Forwarded[tx] = from;
|
||||
SendMessageTo(tx.from, msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
SendMessageTo(itr->second, msg);
|
||||
m_Forwarded.erase(itr);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dns
|
||||
} // namespace llarp
|
|
@ -70,47 +70,8 @@ llarp_dotlokilookup_checkQuery(void *u, __attribute__((unused)) uint64_t orig,
|
|||
// check_query_request * >(u);
|
||||
struct check_query_simple_request *qr =
|
||||
static_cast< struct check_query_simple_request * >(u);
|
||||
dotLokiLookup *dll = (dotLokiLookup *)qr->request->context->user;
|
||||
if(!dll)
|
||||
{
|
||||
llarp::LogError("DNSd dotLokiLookup is not configured");
|
||||
write404_dnss_response(qr->request);
|
||||
delete qr;
|
||||
return;
|
||||
}
|
||||
dotLokiLookup *lookup = (dotLokiLookup *)qr->request->context->user;
|
||||
|
||||
// we do have result
|
||||
// if so send that
|
||||
// else
|
||||
// if we have a free private ip, send that
|
||||
|
||||
/*
|
||||
// cache hit
|
||||
auto itr = loki_tld_lookup_cache.find(addr.ToString());
|
||||
if(itr != loki_tld_lookup_cache.end())
|
||||
{
|
||||
llarp::LogDebug("Found in .loki lookup cache");
|
||||
writesend_dnss_response(itr->second->returnThis, qr->from, qr->request);
|
||||
delete qr;
|
||||
return;
|
||||
}
|
||||
|
||||
struct dns_pointer *free_private = dns_iptracker_get_free(dll->ip_tracker);
|
||||
if(free_private)
|
||||
{
|
||||
*/
|
||||
|
||||
// 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->request);
|
||||
delete qr;
|
||||
return;
|
||||
}
|
||||
llarp::huint32_t serviceIP;
|
||||
llarp::AlignedBuffer< 32 > addr;
|
||||
bool isSNode = false;
|
||||
|
@ -121,7 +82,7 @@ llarp_dotlokilookup_checkQuery(void *u, __attribute__((unused)) uint64_t orig,
|
|||
delete qr;
|
||||
return;
|
||||
}
|
||||
if(!routerHiddenServiceContext->FindBestAddressFor(addr, isSNode, serviceIP))
|
||||
if(!lookup->obtainAddress(lookup, addr, isSNode, serviceIP))
|
||||
{
|
||||
llarp::LogWarn("dotLokiLookup failed to map address");
|
||||
write404_dnss_response(qr->request);
|
||||
|
@ -168,6 +129,7 @@ llarp_dotlokilookup_checkQuery(void *u, __attribute__((unused)) uint64_t orig,
|
|||
return;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
llarp::huint32_t foundAddr;
|
||||
if(!routerHiddenServiceContext->FindBestAddressFor(addr, isSNode, foundAddr))
|
||||
{
|
||||
|
@ -175,7 +137,7 @@ llarp_dotlokilookup_checkQuery(void *u, __attribute__((unused)) uint64_t orig,
|
|||
delete qr;
|
||||
return;
|
||||
}
|
||||
|
||||
*/
|
||||
// make a dnsd_query_hook_response for the cache
|
||||
/*
|
||||
dnsd_query_hook_response *response = new dnsd_query_hook_response;
|
||||
|
@ -189,7 +151,7 @@ llarp_dotlokilookup_checkQuery(void *u, __attribute__((unused)) uint64_t orig,
|
|||
// 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(&foundAddr, qr->request);
|
||||
// writesend_dnss_response(&foundAddr, qr->request);
|
||||
delete qr;
|
||||
return;
|
||||
}
|
||||
|
@ -324,14 +286,14 @@ should_intercept_query_with_name(const std::string &lName)
|
|||
return false;
|
||||
}
|
||||
|
||||
dnsd_query_hook_response *
|
||||
void
|
||||
llarp_dotlokilookup_handler(std::string name,
|
||||
const dnsd_question_request *request)
|
||||
const dnsd_question_request *request,
|
||||
struct dnsd_query_hook_response *response)
|
||||
{
|
||||
dnsd_query_hook_response *response = new dnsd_query_hook_response;
|
||||
response->dontLookUp = false;
|
||||
response->dontSendResponse = false;
|
||||
response->returnThis.h = 0;
|
||||
response->dontLookUp = false;
|
||||
response->dontSendResponse = false;
|
||||
response->returnThis.h = 0;
|
||||
llarp::LogDebug("Hooked ", name);
|
||||
std::string lName = name;
|
||||
std::transform(lName.begin(), lName.end(), lName.begin(), ::tolower);
|
||||
|
@ -341,14 +303,7 @@ llarp_dotlokilookup_handler(std::string name,
|
|||
if(lName.find(".in-addr.arpa") != std::string::npos)
|
||||
{
|
||||
// llarp::LogDebug("Checking ", lName);
|
||||
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;
|
||||
}
|
||||
// dotLokiLookup *dll = (dotLokiLookup *)request->context->user;
|
||||
// llarp::LogDebug("Starting rev iter for ", lName);
|
||||
// which range?
|
||||
// for each tun interface
|
||||
|
@ -361,7 +316,9 @@ llarp_dotlokilookup_handler(std::string name,
|
|||
i.user = &context;
|
||||
i.index = 0;
|
||||
i.visit = &ReverseHandlerIter;
|
||||
bool res = routerHiddenServiceContext->iterate(i);
|
||||
bool res = true;
|
||||
(void)i;
|
||||
// bool res = routerHiddenServiceContext->iterate(i);
|
||||
if(!res)
|
||||
{
|
||||
llarp::LogDebug("Reverse is ours");
|
||||
|
@ -382,8 +339,7 @@ llarp_dotlokilookup_handler(std::string name,
|
|||
// was in cache
|
||||
llarp::LogInfo("Reused address from LokiLookupCache");
|
||||
// FIXME: avoid the response allocation if you could
|
||||
delete response;
|
||||
return cache_check->second;
|
||||
return;
|
||||
}
|
||||
|
||||
// decode address
|
||||
|
@ -392,7 +348,6 @@ llarp_dotlokilookup_handler(std::string name,
|
|||
if(!decode_request_name(lName, addr, isSNode))
|
||||
{
|
||||
response->dontLookUp = true;
|
||||
return response;
|
||||
}
|
||||
|
||||
dotLokiLookup *dll = (dotLokiLookup *)request->context->user;
|
||||
|
@ -401,7 +356,6 @@ llarp_dotlokilookup_handler(std::string name,
|
|||
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
|
||||
|
@ -420,7 +374,7 @@ llarp_dotlokilookup_handler(std::string name,
|
|||
{
|
||||
llarp_dotlokilookup_checkQuery(qr, 0, 0);
|
||||
response->dontSendResponse = true; // will send it shortly
|
||||
return response;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -429,7 +383,7 @@ llarp_dotlokilookup_handler(std::string name,
|
|||
{
|
||||
llarp_dotlokilookup_checkQuery(qr, 0, 0);
|
||||
response->dontSendResponse = true; // will send it shortly
|
||||
return response;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -439,5 +393,5 @@ llarp_dotlokilookup_handler(std::string name,
|
|||
|
||||
response->dontSendResponse = true; // will send it shortly
|
||||
}
|
||||
return response;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ namespace llarp
|
|||
: service::Endpoint(nickname, r)
|
||||
, m_UserToNetworkPktQueue(nickname + "_sendq", r->netloop, r->netloop)
|
||||
, m_NetworkToUserPktQueue(nickname + "_recvq", r->netloop, r->netloop)
|
||||
, m_Resolver(r->netloop, this)
|
||||
{
|
||||
#ifdef ANDROID
|
||||
tunif.get_fd_promise = &get_tun_fd_promise;
|
||||
|
@ -40,12 +41,9 @@ namespace llarp
|
|||
strncpy(tunif.ifaddr, DefaultTunSrcAddr, sizeof(tunif.ifaddr) - 1);
|
||||
strncpy(tunif.ifname, DefaultTunIfname, sizeof(tunif.ifname) - 1);
|
||||
#endif
|
||||
tunif.tick = nullptr;
|
||||
tunif.before_write = &tunifBeforeWrite;
|
||||
tunif.recvpkt = &tunifRecvPkt;
|
||||
this->dll.ip_tracker = nullptr;
|
||||
this->dll.user = &r->hiddenServiceContext;
|
||||
// this->dll.callback = std::bind(&TunEndpoint::MapAddress, this);
|
||||
tunif.tick = nullptr;
|
||||
tunif.before_write = &tunifBeforeWrite;
|
||||
tunif.recvpkt = &tunifRecvPkt;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -89,8 +87,9 @@ namespace llarp
|
|||
resolverAddr = v.substr(0, pos);
|
||||
dnsport = std::atoi(v.substr(pos + 1).c_str());
|
||||
}
|
||||
m_UpstreamDNSAddr = llarp::Addr(resolverAddr, dnsport);
|
||||
llarp::LogInfo(Name(), " upstream dns set to ", m_UpstreamDNSAddr);
|
||||
m_UpstreamResolvers.emplace_back(resolverAddr, dnsport);
|
||||
llarp::LogInfo(Name(), "adding upstream dns set to ", resolverAddr, ":",
|
||||
dnsport);
|
||||
}
|
||||
if(k == "mapaddr")
|
||||
{
|
||||
|
@ -156,15 +155,6 @@ namespace llarp
|
|||
llarp::LogInfo(Name() + " set ifaddr to ", addr, " with netmask ",
|
||||
tunif.netmask);
|
||||
strncpy(tunif.ifaddr, addr.c_str(), sizeof(tunif.ifaddr) - 1);
|
||||
|
||||
// set up address in dotLokiLookup
|
||||
// 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,
|
||||
tunIpV4); // claim GW IP to make sure it's not inuse
|
||||
return true;
|
||||
}
|
||||
return Endpoint::SetOption(k, v);
|
||||
|
@ -184,6 +174,102 @@ namespace llarp
|
|||
std::move(pkt));
|
||||
}
|
||||
|
||||
bool
|
||||
TunEndpoint::HandleHookedDNSMessage(
|
||||
dns::Message msg, std::function< void(dns::Message) > reply)
|
||||
{
|
||||
if(msg.questions.size() != 1)
|
||||
{
|
||||
llarp::LogWarn("bad number of dns questions: ", msg.questions.size());
|
||||
return false;
|
||||
}
|
||||
std::string qname = msg.questions[0].qname;
|
||||
if(msg.questions[0].qtype.h == 1)
|
||||
{
|
||||
llarp::service::Address addr;
|
||||
|
||||
if(addr.FromString(qname, ".loki"))
|
||||
{
|
||||
return EnsurePathToService(
|
||||
addr,
|
||||
std::bind(&TunEndpoint::SendDNSReply, this, std::placeholders::_1,
|
||||
std::placeholders::_2, msg, reply),
|
||||
2000);
|
||||
}
|
||||
else if(addr.FromString(qname, ".snode"))
|
||||
{
|
||||
EnsurePathToSNode(addr.data());
|
||||
huint32_t ip = ObtainIPForAddr(addr.data(), true);
|
||||
reply(msg.AddINReply(ip));
|
||||
}
|
||||
else
|
||||
reply(msg.AddNXReply());
|
||||
}
|
||||
else if(msg.questions[0].qtype.h == 12)
|
||||
{
|
||||
huint32_t ip = {0};
|
||||
if(!dns::DecodePTR(msg.questions[0].qname, ip))
|
||||
{
|
||||
reply(msg.AddNXReply());
|
||||
return true;
|
||||
}
|
||||
llarp::service::Address addr =
|
||||
ObtainAddrForIP< llarp::service::Address >(ip, true);
|
||||
if(!addr.IsZero())
|
||||
{
|
||||
reply(msg.AddAReply(addr.ToString(".snode")));
|
||||
return true;
|
||||
}
|
||||
addr = ObtainAddrForIP< llarp::service::Address >(ip, false);
|
||||
if(!addr.IsZero())
|
||||
{
|
||||
reply(msg.AddAReply(addr.ToString(".loki")));
|
||||
return true;
|
||||
}
|
||||
reply(msg.AddNXReply());
|
||||
return true;
|
||||
}
|
||||
else
|
||||
reply(msg.AddNXReply());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TunEndpoint::ShouldHookDNSMessage(const dns::Message &msg) const
|
||||
{
|
||||
llarp::service::Address addr;
|
||||
if(msg.questions.size() == 1)
|
||||
{
|
||||
if(addr.FromString(msg.questions[0].qname, ".loki"))
|
||||
return true;
|
||||
if(addr.FromString(msg.questions[0].qname, ".snode"))
|
||||
return true;
|
||||
if(msg.questions[0].qtype.h == 12)
|
||||
{
|
||||
huint32_t ip = {0};
|
||||
if(!dns::DecodePTR(msg.questions[0].qname, ip))
|
||||
return false;
|
||||
return m_OurRange.Contains(ip);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
TunEndpoint::SendDNSReply(service::Address addr,
|
||||
service::Endpoint::OutboundContext *ctx,
|
||||
dns::Message request,
|
||||
std::function< void(dns::Message) > reply)
|
||||
{
|
||||
if(ctx)
|
||||
{
|
||||
huint32_t ip = ObtainIPForAddr(addr.data(), false);
|
||||
reply(request.AddINReply(ip));
|
||||
}
|
||||
else
|
||||
reply(request.AddNXReply());
|
||||
}
|
||||
|
||||
bool
|
||||
TunEndpoint::MapAddress(const service::Address &addr, huint32_t ip,
|
||||
bool SNode)
|
||||
|
@ -208,44 +294,9 @@ namespace llarp
|
|||
bool
|
||||
TunEndpoint::Start()
|
||||
{
|
||||
// do network isolation first
|
||||
if(!Endpoint::Start())
|
||||
return false;
|
||||
#ifdef WIN32
|
||||
return SetupNetworking();
|
||||
#else
|
||||
if(!NetworkIsIsolated())
|
||||
{
|
||||
llarp::LogInfo("Setting up global DNS IP tracker");
|
||||
llarp::huint32_t tunIpV4;
|
||||
tunIpV4.h = inet_addr(tunif.ifaddr);
|
||||
dns_iptracker_setup_dotLokiLookup(
|
||||
&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())
|
||||
return false;
|
||||
}
|
||||
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, 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...");
|
||||
return m_TunSetupResult.get_future().get();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -288,8 +339,8 @@ namespace llarp
|
|||
int s = inet_pton(res->ai_family, tunif.ifaddr, buf);
|
||||
if (s <= 0)
|
||||
{
|
||||
llarp::LogError(Name(), " failed to set up tun interface, cant parse ",
|
||||
tunif.ifaddr); return false;
|
||||
llarp::LogError(Name(), " failed to set up tun interface, cant parse
|
||||
", tunif.ifaddr); return false;
|
||||
}
|
||||
*/
|
||||
if(res->ai_family == AF_INET6)
|
||||
|
@ -311,13 +362,15 @@ namespace llarp
|
|||
|
||||
llarp::Addr lAddr(tunif.ifaddr);
|
||||
|
||||
m_OurIP = lAddr.xtohl();
|
||||
m_NextIP = m_OurIP;
|
||||
auto xmask = netmask_ipv4_bits(tunif.netmask);
|
||||
m_MaxIP = m_OurIP ^ (~xmask);
|
||||
m_OurIP = lAddr.xtohl();
|
||||
m_NextIP = m_OurIP;
|
||||
m_OurRange.netmask_bits = netmask_ipv4_bits(tunif.netmask);
|
||||
m_OurRange.addr = m_OurIP;
|
||||
m_MaxIP = m_OurIP | (~m_OurRange.netmask_bits);
|
||||
llarp::LogInfo(Name(), " set ", tunif.ifname, " to have address ", lAddr);
|
||||
|
||||
llarp::LogInfo(Name(), " allocated up to ", m_MaxIP);
|
||||
llarp::LogInfo(Name(), " allocated up to ", m_MaxIP, " on range ",
|
||||
m_OurRange);
|
||||
MapAddress(m_Identity.pub.Addr(), m_OurIP, IsSNode());
|
||||
return true;
|
||||
}
|
||||
|
@ -326,37 +379,17 @@ namespace llarp
|
|||
TunEndpoint::SetupNetworking()
|
||||
{
|
||||
llarp::LogInfo("Set Up networking for ", Name());
|
||||
bool result = SetupTun();
|
||||
#ifndef WIN32
|
||||
m_TunSetupResult.set_value(
|
||||
result); // now that NT has tun, we don't need the CPP guard
|
||||
#endif
|
||||
if(!NetworkIsIsolated())
|
||||
if(!SetupTun())
|
||||
{
|
||||
// need to check to see if we have more than one hidden service
|
||||
// well we'll only use the primary
|
||||
// FIXME: detect number of hidden services
|
||||
llarp::LogWarn(
|
||||
"Only utilizing first hidden service for .loki look ups");
|
||||
// because we can't find to the tun interface because we don't want it
|
||||
// accessible on lokinet we can only bind one to loopback, and we can't
|
||||
// really utilize anything other than port 53 we can't bind to our
|
||||
// public interface, don't want it exploitable maybe we could detect if
|
||||
// you have a private interface
|
||||
llarp::LogError(Name(), " failed to set up network interface");
|
||||
return false;
|
||||
}
|
||||
|
||||
llarp::LogInfo("TunDNS set up ", m_LocalResolverAddr, " to ",
|
||||
m_UpstreamDNSAddr);
|
||||
if(!llarp_dnsd_init(&this->dnsd, EndpointLogic(), EndpointNetLoop(),
|
||||
m_LocalResolverAddr, m_UpstreamDNSAddr))
|
||||
if(!m_Resolver.Start(m_LocalResolverAddr, m_UpstreamResolvers))
|
||||
{
|
||||
llarp::LogError("Couldnt init dns daemon");
|
||||
llarp::LogError(Name(), " failed to start dns server");
|
||||
return false;
|
||||
}
|
||||
// configure hook for .loki lookup
|
||||
dnsd.intercept = &llarp_dotlokilookup_handler;
|
||||
// set dotLokiLookup (this->dll) configuration
|
||||
dnsd.user = &this->dll;
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -6,17 +6,17 @@ namespace llarp
|
|||
namespace service
|
||||
{
|
||||
std::string
|
||||
Address::ToString() const
|
||||
Address::ToString(const char* tld) const
|
||||
{
|
||||
char tmp[(1 + 32) * 2] = {0};
|
||||
std::string str = Base32Encode(*this, tmp);
|
||||
return str + ".loki";
|
||||
return str + tld;
|
||||
}
|
||||
|
||||
bool
|
||||
Address::FromString(const std::string& str)
|
||||
Address::FromString(const std::string& str, const char* tld)
|
||||
{
|
||||
auto pos = str.find(".loki");
|
||||
auto pos = str.find(tld);
|
||||
if(pos == std::string::npos)
|
||||
return false;
|
||||
auto sub = str.substr(0, pos);
|
||||
|
|
84
test/test_dnslib.cpp
Normal file
84
test/test_dnslib.cpp
Normal file
|
@ -0,0 +1,84 @@
|
|||
#include <llarp/dns/dns.hpp>
|
||||
#include <gtest/gtest.h>
|
||||
#include <algorithm>
|
||||
|
||||
struct DNSLibTest : public ::testing::Test
|
||||
{
|
||||
byte_t mem[1500] = {0};
|
||||
llarp_buffer_t buf;
|
||||
|
||||
void
|
||||
SetUp()
|
||||
{
|
||||
buf = llarp::StackBuffer< decltype(mem) >(mem);
|
||||
}
|
||||
|
||||
void
|
||||
TearDown()
|
||||
{
|
||||
Rewind();
|
||||
}
|
||||
|
||||
void
|
||||
Rewind()
|
||||
{
|
||||
buf.cur = buf.base;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(DNSLibTest, TestEncodeDecode_RData)
|
||||
{
|
||||
static constexpr size_t rdatasize = 32;
|
||||
llarp::dns::RR_RData_t rdata(rdatasize);
|
||||
std::fill(rdata.begin(), rdata.end(), 'a');
|
||||
|
||||
llarp::dns::RR_RData_t other_rdata;
|
||||
|
||||
ASSERT_TRUE(llarp::dns::EncodeRData(&buf, rdata));
|
||||
ASSERT_TRUE(buf.cur - buf.base == rdatasize + sizeof(uint16_t));
|
||||
Rewind();
|
||||
ASSERT_TRUE(llarp::dns::DecodeRData(&buf, other_rdata));
|
||||
ASSERT_TRUE(rdata == other_rdata);
|
||||
};
|
||||
|
||||
TEST_F(DNSLibTest, TestEncode_huint16)
|
||||
{
|
||||
llarp::huint16_t i = {0x1122};
|
||||
ASSERT_TRUE(llarp::dns::EncodeInt(&buf, i));
|
||||
ASSERT_TRUE(buf.cur - buf.base == sizeof(uint16_t));
|
||||
ASSERT_TRUE(buf.base[0] == 0x11);
|
||||
ASSERT_TRUE(buf.base[1] == 0x22);
|
||||
};
|
||||
|
||||
TEST_F(DNSLibTest, TestEncode_huint32)
|
||||
{
|
||||
llarp::huint32_t i = {0x11223344};
|
||||
ASSERT_TRUE(llarp::dns::EncodeInt(&buf, i));
|
||||
ASSERT_TRUE(buf.cur - buf.base == sizeof(uint32_t));
|
||||
ASSERT_TRUE(buf.base[0] == 0x11);
|
||||
ASSERT_TRUE(buf.base[1] == 0x22);
|
||||
ASSERT_TRUE(buf.base[2] == 0x33);
|
||||
ASSERT_TRUE(buf.base[3] == 0x44);
|
||||
};
|
||||
|
||||
TEST_F(DNSLibTest, TestDecode_huint16)
|
||||
{
|
||||
llarp::huint16_t i = {0};
|
||||
buf.base[0] = 0x11;
|
||||
buf.base[1] = 0x22;
|
||||
ASSERT_TRUE(llarp::dns::DecodeInt(&buf, i));
|
||||
ASSERT_TRUE(buf.cur - buf.base == sizeof(uint16_t));
|
||||
ASSERT_TRUE(i.h == 0x1122);
|
||||
};
|
||||
|
||||
TEST_F(DNSLibTest, TestDecode_huint32)
|
||||
{
|
||||
llarp::huint32_t i = {0};
|
||||
buf.base[0] = 0x11;
|
||||
buf.base[1] = 0x22;
|
||||
buf.base[2] = 0x33;
|
||||
buf.base[3] = 0x44;
|
||||
ASSERT_TRUE(llarp::dns::DecodeInt(&buf, i));
|
||||
ASSERT_TRUE(buf.cur - buf.base == sizeof(uint32_t));
|
||||
ASSERT_TRUE(i.h == 0x11223344);
|
||||
};
|
Loading…
Reference in a new issue