aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormoneromooo-monero <moneromooo-monero@users.noreply.github.com>2015-08-29 12:53:01 +0100
committermoneromooo-monero <moneromooo-monero@users.noreply.github.com>2015-08-30 15:04:09 +0100
commitf928468b9b9fa584c2da252f2263f0bc7d7485fc (patch)
tree70f99572d9b5172520ea029f9ff8af2ac41b50ed
parentdns_utils: simplify string handling and fix leak (diff)
downloadmonero-f928468b9b9fa584c2da252f2263f0bc7d7485fc.tar.xz
dns_utils: factor the fetching code for different DNS record types
-rw-r--r--src/common/dns_utils.cpp80
-rw-r--r--src/common/dns_utils.h13
2 files changed, 34 insertions, 59 deletions
diff --git a/src/common/dns_utils.cpp b/src/common/dns_utils.cpp
index 33e71c79d..742e039fc 100644
--- a/src/common/dns_utils.cpp
+++ b/src/common/dns_utils.cpp
@@ -100,8 +100,10 @@ namespace tools
{
// 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;
unsigned int bytes[4];
for (int i = 0; i < 4; i++)
@@ -118,8 +120,10 @@ std::string ipv4_to_string(const char* src)
// this obviously will need to change, but is here to reflect the above
// 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;
unsigned int bytes[8];
for (int i = 0; i < 8; i++)
@@ -138,6 +142,11 @@ std::string ipv6_to_string(const char* src)
return ss.str();
}
+std::string txt_to_string(const char* src, size_t len)
+{
+ return std::string(src+1, len-1);
+}
+
// custom smart pointer.
// TODO: see if std::auto_ptr and the like support custom destructors
template<typename type, void (*freefunc)(type*)>
@@ -215,7 +224,7 @@ 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;
dnssec_available = false;
@@ -231,7 +240,7 @@ std::vector<std::string> DNSResolver::get_ipv4(const std::string& url, bool& dns
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_A, DNS_CLASS_IN, &result))
+ if (!ub_resolve(m_data->m_ub_context, urlC, record_type, DNS_CLASS_IN, &result))
{
dnssec_available = (result->secure || (!result->secure && result->bogus));
dnssec_valid = result->secure && !result->bogus;
@@ -239,7 +248,7 @@ std::vector<std::string> DNSResolver::get_ipv4(const std::string& url, bool& dns
{
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]));
}
}
}
@@ -247,66 +256,19 @@ std::vector<std::string> DNSResolver::get_ipv4(const std::string& url, bool& dns
return addresses;
}
-std::vector<std::string> DNSResolver::get_ipv6(const std::string& url, bool& dnssec_available, bool& dnssec_valid)
+std::vector<std::string> DNSResolver::get_ipv4(const std::string& url, bool& dnssec_available, bool& dnssec_valid)
{
- std::vector<std::string> addresses;
- 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 get_record(url, DNS_TYPE_A, ipv4_to_string, dnssec_available, dnssec_valid);
+}
- return addresses;
+std::vector<std::string> DNSResolver::get_ipv6(const std::string& url, bool& dnssec_available, bool& dnssec_valid)
+{
+ return get_record(url, DNS_TYPE_AAAA, ipv6_to_string, dnssec_available, 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;
- 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++)
- {
- records.push_back(std::string(result->data[i]+1, result->len[i]-1));
- }
- }
- }
-
- return records;
+ return get_record(url, DNS_TYPE_TXT, txt_to_string, dnssec_available, dnssec_valid);
}
std::string DNSResolver::get_dns_format_from_oa_address(const std::string& oa_addr)
diff --git a/src/common/dns_utils.h b/src/common/dns_utils.h
index 332bceafe..63bf25445 100644
--- a/src/common/dns_utils.h
+++ b/src/common/dns_utils.h
@@ -131,6 +131,19 @@ public:
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
*
* @param addr the string to be checked