aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/common/dns_utils.cpp15
-rw-r--r--src/common/dns_utils.h8
-rw-r--r--src/simplewallet/simplewallet.cpp17
-rw-r--r--src/wallet/wallet2.cpp21
-rw-r--r--src/wallet/wallet2.h2
-rw-r--r--tests/unit_tests/address_from_url.cpp13
-rw-r--r--tests/unit_tests/dns_resolver.cpp11
7 files changed, 57 insertions, 30 deletions
diff --git a/src/common/dns_utils.cpp b/src/common/dns_utils.cpp
index 2ad98ca27..6755a30b2 100644
--- a/src/common/dns_utils.cpp
+++ b/src/common/dns_utils.cpp
@@ -89,7 +89,7 @@ std::vector<std::string> DNSResolver::get_ipv4(const std::string& url)
{
if (result.ptr->havedata)
{
- for (int i=0; result.ptr->data[i] != NULL; i++)
+ for (size_t i=0; result.ptr->data[i] != NULL; i++)
{
char as_str[INET_ADDRSTRLEN];
@@ -115,7 +115,7 @@ std::vector<std::string> DNSResolver::get_ipv6(const std::string& url)
{
if (result.ptr->havedata)
{
- for (int i=0; result.ptr->data[i] != NULL; i++)
+ for (size_t i=0; result.ptr->data[i] != NULL; i++)
{
char as_str[INET6_ADDRSTRLEN];
@@ -131,19 +131,24 @@ std::vector<std::string> DNSResolver::get_ipv6(const std::string& url)
return retval;
}
-std::string DNSResolver::get_txt_record(const std::string& url)
+std::vector<std::string> DNSResolver::get_txt_record(const std::string& url)
{
ub_result_ptr result;
+ std::vector<std::string> records;
// call DNS resolver, blocking. if return value not zero, something went wrong
if (!ub_resolve(m_data->m_ub_context, url.c_str(), LDNS_RR_TYPE_TXT, LDNS_RR_CLASS_IN, &(result.ptr)))
{
if (result.ptr->havedata)
{
- return std::string(result.ptr->data[0]);
+ for (size_t i=0; result.ptr->data[i] != NULL; i++)
+ {
+ records.push_back(result.ptr->data[i]);
+ }
}
}
- return std::string();
+
+ return records;
}
DNSResolver& DNSResolver::instance()
diff --git a/src/common/dns_utils.h b/src/common/dns_utils.h
index ff54c1e07..e57e55861 100644
--- a/src/common/dns_utils.h
+++ b/src/common/dns_utils.h
@@ -82,15 +82,15 @@ public:
std::vector<std::string> get_ipv6(const std::string& url);
/**
- * @brief gets a TXT record from a DNS query for the supplied URL;
- * if no TXT record present returns an empty string.
+ * @brief gets all TXT records from a DNS query for the supplied URL;
+ * if no TXT record present returns an empty vector.
*
* @param url A string containing a URL to query for
*
- * @return A string containing a TXT record; or an empty string
+ * @return A vector of strings containing a TXT record; or an empty vector
*/
// TODO: modify this to accomodate DNSSEC
- std::string get_txt_record(const std::string& url);
+ std::vector<std::string> get_txt_record(const std::string& url);
/**
* @brief Gets the singleton instance of DNSResolver
diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp
index 07b2f7935..e2564236b 100644
--- a/src/simplewallet/simplewallet.cpp
+++ b/src/simplewallet/simplewallet.cpp
@@ -913,16 +913,15 @@ bool simple_wallet::transfer(const std::vector<std::string> &args_)
{
// if treating as an address fails, try as url
bool dnssec_ok = false;
- std::string addr_from_dns;
std::string url = local_args[i];
// attempt to get address from dns query
- addr_from_dns = tools::wallet2::address_from_url(url, dnssec_ok);
+ auto addresses_from_dns = tools::wallet2::addresses_from_url(url, dnssec_ok);
- // if string not empty, see if it's an address
- if (addr_from_dns.size())
+ // for now, move on only if one address found
+ if (addresses_from_dns.size() == 1)
{
- if (get_account_address_from_str(de.addr, addr_from_dns))
+ if (get_account_address_from_str(de.addr, addresses_from_dns[0]))
{
// if it was an address, prompt user for confirmation.
// inform user of DNSSEC validation status as well.
@@ -938,8 +937,8 @@ bool simple_wallet::transfer(const std::vector<std::string> &args_)
}
std::stringstream prompt;
prompt << "For URL: " << url
- << "," << dnssec_str
- << " Monero Address = " << addr_from_dns
+ << "," << dnssec_str << std::endl
+ << " Monero Address = " << addresses_from_dns[0]
<< std::endl
<< "Is this OK? (Y/n) "
;
@@ -958,6 +957,10 @@ bool simple_wallet::transfer(const std::vector<std::string> &args_)
return true;
}
}
+ else if (addresses_from_dns.size() > 1)
+ {
+ tools::fail_msg_writer() << "Multiple Monero addresses found for given URL: " << url << ", this is not yet supported.";
+ }
else
{
fail_msg_writer() << "wrong address: " << local_args[i];
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index adc9c1f61..3161f3b16 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -831,21 +831,30 @@ std::vector<std::vector<cryptonote::tx_destination_entry>> split_amounts(
*
* @return a monero address (as a string) or an empty string
*/
-std::string wallet2::address_from_url(const std::string& url, bool& dnssec_valid)
+std::vector<std::string> wallet2::addresses_from_url(const std::string& url, bool& dnssec_valid)
{
// TODO: update this correctly once DNSResolver::get_txt_record() supports it.
dnssec_valid = false;
- // get txt record
- std::string txt = tools::DNSResolver::instance().get_txt_record(url);
- if (txt.size())
+ std::vector<std::string> addresses;
+ // get txt records
+ auto records = tools::DNSResolver::instance().get_txt_record(url);
+
+ // for each txt record, try to find a monero address in it.
+ for (auto& rec : records)
{
- return address_from_txt_record(txt);
+ std::string addr = address_from_txt_record(rec);
+ if (addr.size())
+ {
+ addresses.push_back(addr);
+ }
}
- return std::string();
+
+ return addresses;
}
//----------------------------------------------------------------------------------------------------
+// TODO: parse the string in a less stupid way, probably with regex
std::string wallet2::address_from_txt_record(const std::string& s)
{
// make sure the txt record has "oa1:xmr" and find it
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index 6e6d7cafb..90918677e 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -196,7 +196,7 @@ namespace tools
static bool parse_payment_id(const std::string& payment_id_str, crypto::hash& payment_id);
- static std::string address_from_url(const std::string& url, bool& dnssec_valid);
+ static std::vector<std::string> addresses_from_url(const std::string& url, bool& dnssec_valid);
static std::string address_from_txt_record(const std::string& s);
private:
diff --git a/tests/unit_tests/address_from_url.cpp b/tests/unit_tests/address_from_url.cpp
index 180257189..22301d568 100644
--- a/tests/unit_tests/address_from_url.cpp
+++ b/tests/unit_tests/address_from_url.cpp
@@ -85,18 +85,23 @@ TEST(AddressFromURL, Success)
std::string addr = "46BeWrHpwXmHDpDEUmZBWZfoQpdc6HaERCNmx1pEYL2rAcuwufPN9rXHHtyUA4QVy66qeFQkn6sfK8aHYjA3jk3o1Bv16em";
bool dnssec_result = false;
- std::string res = tools::wallet2::address_from_url("donate.monero.cc", dnssec_result);
- EXPECT_STREQ(addr.c_str(), res.c_str());
+ std::vector<std::string> addresses = tools::wallet2::addresses_from_url("donate.monero.cc", dnssec_result);
+
+ EXPECT_EQ(1, addresses.size());
+ if (addresses.size() == 1)
+ {
+ EXPECT_STREQ(addr.c_str(), addresses[0].c_str());
+ }
}
TEST(AddressFromURL, Failure)
{
bool dnssec_result = false;
- std::string res = tools::wallet2::address_from_url("example.invalid", dnssec_result);
+ std::vector<std::string> addresses = tools::wallet2::addresses_from_url("example.invalid", dnssec_result);
ASSERT_FALSE(dnssec_result);
- ASSERT_STREQ("", res.c_str());
+ ASSERT_EQ(0, addresses.size());
}
diff --git a/tests/unit_tests/dns_resolver.cpp b/tests/unit_tests/dns_resolver.cpp
index 3b52a5f40..27e981ef1 100644
--- a/tests/unit_tests/dns_resolver.cpp
+++ b/tests/unit_tests/dns_resolver.cpp
@@ -27,6 +27,7 @@
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <iostream>
+#include <vector>
#include "gtest/gtest.h"
@@ -97,8 +98,12 @@ TEST(DNSResolver, IPv6Failure)
TEST(DNSResolver, GetTXTRecord)
{
- std::string txt = tools::DNSResolver::instance().get_txt_record("donate.monero.cc");
- std::cout << "TXT record for donate.monero.cc: " << txt << std::endl;
+ std::vector<std::string> records = tools::DNSResolver::instance().get_txt_record("donate.monero.cc");
- EXPECT_STRNE("", txt.c_str());
+ EXPECT_NE(0, records.size());
+
+ for (auto& rec : records)
+ {
+ std::cout << "TXT record for donate.monero.cc: " << rec << std::endl;
+ }
}