diff options
author | moneromooo-monero <moneromooo-monero@users.noreply.github.com> | 2015-08-29 12:53:01 +0100 |
---|---|---|
committer | moneromooo-monero <moneromooo-monero@users.noreply.github.com> | 2015-08-30 15:04:09 +0100 |
commit | f928468b9b9fa584c2da252f2263f0bc7d7485fc (patch) | |
tree | 70f99572d9b5172520ea029f9ff8af2ac41b50ed | |
parent | dns_utils: simplify string handling and fix leak (diff) | |
download | monero-f928468b9b9fa584c2da252f2263f0bc7d7485fc.tar.xz |
dns_utils: factor the fetching code for different DNS record types
-rw-r--r-- | src/common/dns_utils.cpp | 80 | ||||
-rw-r--r-- | src/common/dns_utils.h | 13 |
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 |