mirror of
https://github.com/monero-project/monero.git
synced 2024-11-18 10:01:02 +00:00
Merge pull request #394
3c10239
unbound: use the mini event fallback implementation (moneromooo-monero)4e138a0
dns_utils: remove unnecessary string conversion (moneromooo-monero)f928468
dns_utils: factor the fetching code for different DNS record types (moneromooo-monero)4ef0da1
dns_utils: simplify string handling and fix leak (moneromooo-monero)ae5f28c
dns_utils: add a const where possible (moneromooo-monero)f43d465
dns_utils: lock access to the singleton (moneromooo-monero)5990344
dns: make ctor private (moneromooo-monero)
This commit is contained in:
commit
cf88e4dd24
4 changed files with 64 additions and 77 deletions
3
external/unbound/config.h.cmake.in
vendored
3
external/unbound/config.h.cmake.in
vendored
|
@ -575,7 +575,8 @@
|
||||||
#cmakedefine USE_GOST
|
#cmakedefine USE_GOST
|
||||||
|
|
||||||
/* Define if you want to use internal select based events */
|
/* Define if you want to use internal select based events */
|
||||||
#cmakedefine USE_MINI_EVENT
|
/* #cmakedefine USE_MINI_EVENT */
|
||||||
|
#define USE_MINI_EVENT 1
|
||||||
|
|
||||||
/* Define this to enable SHA256 and SHA512 support. */
|
/* Define this to enable SHA256 and SHA512 support. */
|
||||||
#cmakedefine USE_SHA2
|
#cmakedefine USE_SHA2
|
||||||
|
|
|
@ -38,6 +38,8 @@
|
||||||
using namespace epee;
|
using namespace epee;
|
||||||
namespace bf = boost::filesystem;
|
namespace bf = boost::filesystem;
|
||||||
|
|
||||||
|
static std::mutex instance_lock;
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -98,8 +100,10 @@ namespace tools
|
||||||
{
|
{
|
||||||
|
|
||||||
// fuck it, I'm tired of dealing with getnameinfo()/inet_ntop/etc
|
// fuck it, I'm tired of dealing with getnameinfo()/inet_ntop/etc
|
||||||
std::string ipv4_to_string(const char* src)
|
std::string ipv4_to_string(const char* src, size_t len)
|
||||||
{
|
{
|
||||||
|
assert(memchr(src, 0, len));
|
||||||
|
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
unsigned int bytes[4];
|
unsigned int bytes[4];
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
|
@ -116,8 +120,10 @@ std::string ipv4_to_string(const char* src)
|
||||||
|
|
||||||
// this obviously will need to change, but is here to reflect the above
|
// this obviously will need to change, but is here to reflect the above
|
||||||
// stop-gap measure and to make the tests pass at least...
|
// stop-gap measure and to make the tests pass at least...
|
||||||
std::string ipv6_to_string(const char* src)
|
std::string ipv6_to_string(const char* src, size_t len)
|
||||||
{
|
{
|
||||||
|
assert(memchr(src, 0, len));
|
||||||
|
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
unsigned int bytes[8];
|
unsigned int bytes[8];
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
|
@ -136,6 +142,11 @@ std::string ipv6_to_string(const char* src)
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string txt_to_string(const char* src, size_t len)
|
||||||
|
{
|
||||||
|
return std::string(src+1, len-1);
|
||||||
|
}
|
||||||
|
|
||||||
// custom smart pointer.
|
// custom smart pointer.
|
||||||
// TODO: see if std::auto_ptr and the like support custom destructors
|
// TODO: see if std::auto_ptr and the like support custom destructors
|
||||||
template<typename type, void (*freefunc)(type*)>
|
template<typename type, void (*freefunc)(type*)>
|
||||||
|
@ -164,8 +175,6 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef class scoped_ptr<ub_result,ub_resolve_free> ub_result_ptr;
|
typedef class scoped_ptr<ub_result,ub_resolve_free> ub_result_ptr;
|
||||||
static void freestring(char *ptr) { free(ptr); }
|
|
||||||
typedef class scoped_ptr<char,freestring> string_ptr;
|
|
||||||
|
|
||||||
struct DNSResolverData
|
struct DNSResolverData
|
||||||
{
|
{
|
||||||
|
@ -213,14 +222,13 @@ DNSResolver::~DNSResolver()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> DNSResolver::get_ipv4(const std::string& url, bool& dnssec_available, bool& dnssec_valid)
|
std::vector<std::string> DNSResolver::get_record(const std::string& url, int record_type, std::string (*reader)(const char *,size_t), bool& dnssec_available, bool& dnssec_valid)
|
||||||
{
|
{
|
||||||
std::vector<std::string> addresses;
|
std::vector<std::string> addresses;
|
||||||
dnssec_available = false;
|
dnssec_available = false;
|
||||||
dnssec_valid = false;
|
dnssec_valid = false;
|
||||||
|
|
||||||
string_ptr urlC(strdup(url.c_str()));
|
if (!check_address_syntax(url.c_str()))
|
||||||
if (!check_address_syntax(urlC))
|
|
||||||
{
|
{
|
||||||
return addresses;
|
return addresses;
|
||||||
}
|
}
|
||||||
|
@ -229,7 +237,7 @@ std::vector<std::string> DNSResolver::get_ipv4(const std::string& url, bool& dns
|
||||||
ub_result_ptr result;
|
ub_result_ptr result;
|
||||||
|
|
||||||
// call DNS resolver, blocking. if return value not zero, something went wrong
|
// call DNS resolver, blocking. if return value not zero, something went wrong
|
||||||
if (!ub_resolve(m_data->m_ub_context, urlC, DNS_TYPE_A, DNS_CLASS_IN, &result))
|
if (!ub_resolve(m_data->m_ub_context, url.c_str(), record_type, DNS_CLASS_IN, &result))
|
||||||
{
|
{
|
||||||
dnssec_available = (result->secure || (!result->secure && result->bogus));
|
dnssec_available = (result->secure || (!result->secure && result->bogus));
|
||||||
dnssec_valid = result->secure && !result->bogus;
|
dnssec_valid = result->secure && !result->bogus;
|
||||||
|
@ -237,7 +245,7 @@ std::vector<std::string> DNSResolver::get_ipv4(const std::string& url, bool& dns
|
||||||
{
|
{
|
||||||
for (size_t i=0; result->data[i] != NULL; i++)
|
for (size_t i=0; result->data[i] != NULL; i++)
|
||||||
{
|
{
|
||||||
addresses.push_back(ipv4_to_string(result->data[i]));
|
addresses.push_back((*reader)(result->data[i], result->len[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -245,70 +253,19 @@ std::vector<std::string> DNSResolver::get_ipv4(const std::string& url, bool& dns
|
||||||
return addresses;
|
return addresses;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> DNSResolver::get_ipv4(const std::string& url, bool& dnssec_available, bool& dnssec_valid)
|
||||||
|
{
|
||||||
|
return get_record(url, DNS_TYPE_A, ipv4_to_string, dnssec_available, dnssec_valid);
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::string> DNSResolver::get_ipv6(const std::string& url, bool& dnssec_available, bool& dnssec_valid)
|
std::vector<std::string> DNSResolver::get_ipv6(const std::string& url, bool& dnssec_available, bool& dnssec_valid)
|
||||||
{
|
{
|
||||||
std::vector<std::string> addresses;
|
return get_record(url, DNS_TYPE_AAAA, ipv6_to_string, dnssec_available, dnssec_valid);
|
||||||
dnssec_available = false;
|
|
||||||
dnssec_valid = false;
|
|
||||||
|
|
||||||
string_ptr urlC(strdup(url.c_str()));
|
|
||||||
if (!check_address_syntax(urlC))
|
|
||||||
{
|
|
||||||
return addresses;
|
|
||||||
}
|
|
||||||
|
|
||||||
ub_result_ptr result;
|
|
||||||
|
|
||||||
// call DNS resolver, blocking. if return value not zero, something went wrong
|
|
||||||
if (!ub_resolve(m_data->m_ub_context, urlC, DNS_TYPE_AAAA, DNS_CLASS_IN, &result))
|
|
||||||
{
|
|
||||||
dnssec_available = (result->secure || (!result->secure && result->bogus));
|
|
||||||
dnssec_valid = result->secure && !result->bogus;
|
|
||||||
if (result->havedata)
|
|
||||||
{
|
|
||||||
for (size_t i=0; result->data[i] != NULL; i++)
|
|
||||||
{
|
|
||||||
addresses.push_back(ipv6_to_string(result->data[i]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return addresses;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> DNSResolver::get_txt_record(const std::string& url, bool& dnssec_available, bool& dnssec_valid)
|
std::vector<std::string> DNSResolver::get_txt_record(const std::string& url, bool& dnssec_available, bool& dnssec_valid)
|
||||||
{
|
{
|
||||||
std::vector<std::string> records;
|
return get_record(url, DNS_TYPE_TXT, txt_to_string, dnssec_available, dnssec_valid);
|
||||||
dnssec_available = false;
|
|
||||||
dnssec_valid = false;
|
|
||||||
|
|
||||||
string_ptr urlC(strdup(url.c_str()));
|
|
||||||
if (!check_address_syntax(urlC))
|
|
||||||
{
|
|
||||||
return records;
|
|
||||||
}
|
|
||||||
|
|
||||||
ub_result_ptr result;
|
|
||||||
|
|
||||||
// call DNS resolver, blocking. if return value not zero, something went wrong
|
|
||||||
if (!ub_resolve(m_data->m_ub_context, urlC, DNS_TYPE_TXT, DNS_CLASS_IN, &result))
|
|
||||||
{
|
|
||||||
dnssec_available = (result->secure || (!result->secure && result->bogus));
|
|
||||||
dnssec_valid = result->secure && !result->bogus;
|
|
||||||
if (result->havedata)
|
|
||||||
{
|
|
||||||
for (size_t i=0; result->data[i] != NULL; i++)
|
|
||||||
{
|
|
||||||
// plz fix this, but this does NOT work and spills over into parts of memory it shouldn't: records.push_back(result.ptr->data[i]);
|
|
||||||
char *restxt;
|
|
||||||
restxt = (char*) calloc(result->len[i]+1, 1);
|
|
||||||
memcpy(restxt, result->data[i]+1, result->len[i]-1);
|
|
||||||
records.push_back(restxt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return records;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DNSResolver::get_dns_format_from_oa_address(const std::string& oa_addr)
|
std::string DNSResolver::get_dns_format_from_oa_address(const std::string& oa_addr)
|
||||||
|
@ -326,6 +283,8 @@ std::string DNSResolver::get_dns_format_from_oa_address(const std::string& oa_ad
|
||||||
|
|
||||||
DNSResolver& DNSResolver::instance()
|
DNSResolver& DNSResolver::instance()
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(instance_lock);
|
||||||
|
|
||||||
static DNSResolver* staticInstance = NULL;
|
static DNSResolver* staticInstance = NULL;
|
||||||
if (staticInstance == NULL)
|
if (staticInstance == NULL)
|
||||||
{
|
{
|
||||||
|
@ -334,7 +293,12 @@ DNSResolver& DNSResolver::instance()
|
||||||
return *staticInstance;
|
return *staticInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DNSResolver::check_address_syntax(const char *addr)
|
DNSResolver DNSResolver::create()
|
||||||
|
{
|
||||||
|
return DNSResolver();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DNSResolver::check_address_syntax(const char *addr) const
|
||||||
{
|
{
|
||||||
// if string doesn't contain a dot, we won't consider it a url for now.
|
// if string doesn't contain a dot, we won't consider it a url for now.
|
||||||
if (strchr(addr,'.') == NULL)
|
if (strchr(addr,'.') == NULL)
|
||||||
|
|
|
@ -49,7 +49,7 @@ struct DNSResolverData;
|
||||||
*/
|
*/
|
||||||
class DNSResolver
|
class DNSResolver
|
||||||
{
|
{
|
||||||
public:
|
private:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constructs an instance of DNSResolver
|
* @brief Constructs an instance of DNSResolver
|
||||||
|
@ -58,6 +58,8 @@ public:
|
||||||
*/
|
*/
|
||||||
DNSResolver();
|
DNSResolver();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief takes care of freeing C pointers and such
|
* @brief takes care of freeing C pointers and such
|
||||||
*/
|
*/
|
||||||
|
@ -119,8 +121,28 @@ public:
|
||||||
*/
|
*/
|
||||||
static DNSResolver& instance();
|
static DNSResolver& instance();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets a new instance of DNSResolver
|
||||||
|
*
|
||||||
|
* @return returns a pointer to the new object
|
||||||
|
*/
|
||||||
|
static DNSResolver create();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief gets all records of a given type from a DNS query for the supplied URL;
|
||||||
|
* if no such record is present returns an empty vector.
|
||||||
|
*
|
||||||
|
* @param url A string containing a URL to query for
|
||||||
|
* @param record_type the record type to retrieve (DNS_TYPE_A, etc)
|
||||||
|
* @param reader a function that converts a record data to a string
|
||||||
|
*
|
||||||
|
* @return A vector of strings containing the requested record; or an empty vector
|
||||||
|
*/
|
||||||
|
// TODO: modify this to accomodate DNSSEC
|
||||||
|
std::vector<std::string> get_record(const std::string& url, int record_type, std::string (*reader)(const char *,size_t), bool& dnssec_available, bool& dnssec_valid);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Checks a string to see if it looks like a URL
|
* @brief Checks a string to see if it looks like a URL
|
||||||
*
|
*
|
||||||
|
@ -128,7 +150,7 @@ private:
|
||||||
*
|
*
|
||||||
* @return true if it looks enough like a URL, false if not
|
* @return true if it looks enough like a URL, false if not
|
||||||
*/
|
*/
|
||||||
bool check_address_syntax(const char *addr);
|
bool check_address_syntax(const char *addr) const;
|
||||||
|
|
||||||
DNSResolverData *m_data;
|
DNSResolverData *m_data;
|
||||||
}; // class DNSResolver
|
}; // class DNSResolver
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
|
|
||||||
TEST(DNSResolver, IPv4Success)
|
TEST(DNSResolver, IPv4Success)
|
||||||
{
|
{
|
||||||
tools::DNSResolver resolver;
|
tools::DNSResolver resolver = tools::DNSResolver::create();
|
||||||
|
|
||||||
bool avail, valid;
|
bool avail, valid;
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ TEST(DNSResolver, IPv4Success)
|
||||||
TEST(DNSResolver, IPv4Failure)
|
TEST(DNSResolver, IPv4Failure)
|
||||||
{
|
{
|
||||||
// guaranteed by IANA/ICANN/RFC to be invalid
|
// guaranteed by IANA/ICANN/RFC to be invalid
|
||||||
tools::DNSResolver resolver;
|
tools::DNSResolver resolver = tools::DNSResolver::create();
|
||||||
|
|
||||||
bool avail, valid;
|
bool avail, valid;
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ TEST(DNSResolver, IPv4Failure)
|
||||||
|
|
||||||
TEST(DNSResolver, DNSSECSuccess)
|
TEST(DNSResolver, DNSSECSuccess)
|
||||||
{
|
{
|
||||||
tools::DNSResolver resolver;
|
tools::DNSResolver resolver = tools::DNSResolver::create();
|
||||||
|
|
||||||
bool avail, valid;
|
bool avail, valid;
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ TEST(DNSResolver, DNSSECSuccess)
|
||||||
|
|
||||||
TEST(DNSResolver, DNSSECFailure)
|
TEST(DNSResolver, DNSSECFailure)
|
||||||
{
|
{
|
||||||
tools::DNSResolver resolver;
|
tools::DNSResolver resolver = tools::DNSResolver::create();
|
||||||
|
|
||||||
bool avail, valid;
|
bool avail, valid;
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ TEST(DNSResolver, DNSSECFailure)
|
||||||
// It would be great to include an IPv6 test and assume it'll pass, but not every ISP / resolver plays nicely with IPv6;)
|
// It would be great to include an IPv6 test and assume it'll pass, but not every ISP / resolver plays nicely with IPv6;)
|
||||||
/*TEST(DNSResolver, IPv6Success)
|
/*TEST(DNSResolver, IPv6Success)
|
||||||
{
|
{
|
||||||
tools::DNSResolver resolver;
|
tools::DNSResolver resolver = tools::DNSResolver::create();
|
||||||
|
|
||||||
bool avail, valid;
|
bool avail, valid;
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ TEST(DNSResolver, DNSSECFailure)
|
||||||
TEST(DNSResolver, IPv6Failure)
|
TEST(DNSResolver, IPv6Failure)
|
||||||
{
|
{
|
||||||
// guaranteed by IANA/ICANN/RFC to be invalid
|
// guaranteed by IANA/ICANN/RFC to be invalid
|
||||||
tools::DNSResolver resolver;
|
tools::DNSResolver resolver = tools::DNSResolver::create();
|
||||||
|
|
||||||
bool avail, valid;
|
bool avail, valid;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue