#include <boost/asio.hpp>
#include <boost/foreach.hpp>
-#include <boost/net/dns.hpp>
#include <boost/net/resolve.hpp>
+#include <boost/shared_ptr.hpp>
#include "dns/hostaddress.h"
using boost::asio::io_service;
using boost::asio::ip::address;
using boost::net::dns::a_resource;
+using boost::net::dns::resource_base_t;
using boost::net::dns::message;
using boost::net::dns::rr_list_t;
+using boost::shared_ptr;
//-----------------------------------------------------------------------------
// DnsResolver
try
{
- address nameServer( address::from_string( NameServer ) );
- boost::net::dns::resolve resolver;
- resolver.addServer( nameServer );
- message dns_message( HostDnsAddress, boost::net::dns::type_a );
- message& dns_packet = resolver.query( dns_message );
- rr_list_t* answers = dns_packet.answers();
- int resolved_ip = answers->size();
- if ( resolved_ip < 1 )
+ rr_list_t answers_list;
+ fill_answers_list( HostDnsAddress, NameServer, &answers_list );
+
+ int resolved_ip_count = answers_list.size();
+ if ( resolved_ip_count < 1 )
{
- cerr << "Error: host " << HostDnsAddress << " could not be resolved." << endl;
+ cerr << "Error: host " << HostDnsAddress << " could not be resolved."
+ << endl;
return false;
}
ResolvedHostAddressList.clear();
- for ( rr_list_t::iterator riter = answers->begin();
- riter != answers->end();
- ++riter )
- {
- a_resource *resource_record = dynamic_cast<a_resource*> (
- riter->get()
- );
-
- if ( ( resource_record != NULL ) &&
- ( resource_record->rtype() == boost::net::dns::type_a ) )
- {
- string ip = resource_record->address().to_string();
- int ttl = resource_record->ttl();
-
- HostAddress resolved_host( ip, ttl );
- ResolvedHostAddressList.push_back( resolved_host );
+ fill_resolved_ip_list( answers_list, &ResolvedHostAddressList );
- cout << "- " << ip << " [" << ttl << "s]" << endl;
- }
- }
}
catch ( const std::exception &ex )
{
return destination_ip;
}
+/**
+ * @return true if the last IPs resolved for the host have expired, thus
+ * requiring another query for up-to-date IPs.
+ */
bool DnsResolver::expired_resolved_ip()
{
const int threshold = 10; // TODO configurable
return false;
}
+
+void DnsResolver::fill_answers_list(
+ const string &host_dns_address,
+ const string &name_server,
+ rr_list_t *answers_list
+)
+{
+ BOOST_ASSERT( !host_dns_address.empty() );
+ BOOST_ASSERT( !name_server.empty() );
+ BOOST_ASSERT( answers_list != NULL );
+
+ address nameServer( address::from_string( name_server) );
+ boost::net::dns::resolve resolver;
+ resolver.addServer( nameServer );
+ message dns_message( host_dns_address, boost::net::dns::type_a );
+ message& dns_packet = resolver.query( dns_message );
+ // Note: perform a copy of each element from one vector to the other, do
+ // not reference
+ *answers_list = *dns_packet.answers();
+}
+
+void DnsResolver::fill_resolved_ip_list(
+ const rr_list_t& answers_list,
+ list<HostAddress> *resolved_host_address_list
+)
+{
+ BOOST_ASSERT( 1 <= answers_list.size() );
+ BOOST_ASSERT( resolved_host_address_list != NULL );
+
+ BOOST_FOREACH( shared_ptr<resource_base_t> resource_record, answers_list )
+ {
+ if ( ( resource_record != NULL ) &&
+ ( resource_record->rtype() == boost::net::dns::type_a ) )
+ {
+ a_resource *a_rr = dynamic_cast<a_resource *> (
+ resource_record.get()
+ );
+ string ip = a_rr->address().to_string();
+ int ttl = a_rr->ttl();
+
+ HostAddress resolved_host( ip, ttl );
+ resolved_host_address_list->push_back( resolved_host );
+
+ cout << "- " << ip << " [" << ttl << "s]" << endl;
+ }
+ }
+
+ size_t answer_list_size = answers_list.size();
+ size_t resolve_host_list_size = resolved_host_address_list->size();
+ bool size_equal = ( resolve_host_list_size == answer_list_size );
+ bool size_equal_minus_cname = ( resolve_host_list_size == ( answer_list_size - 1 ) );
+ BOOST_ASSERT( size_equal || size_equal_minus_cname );
+}
#include <string>
#include <list>
+#include <boost/net/dns.hpp>
+
class HostAddress;
//-----------------------------------------------------------------------------
bool resolve();
int get_resolved_ip_count() const;
-
std::string get_next_ip();
-
bool expired_resolved_ip();
private:
+ void fill_answers_list(
+ const std::string &host_dns_address,
+ const std::string &name_server,
+ boost::net::dns::rr_list_t *answers_list
+ );
+ void fill_resolved_ip_list(
+ const boost::net::dns::rr_list_t& answers_list,
+ std::list<HostAddress> *resolved_host_address_list
+ );
+
+private:
std::list<HostAddress> ResolvedHostAddressList;
const std::string HostDnsAddress;
const std::string NameServer;