Split the code of DnsResolver::resolve into more methods
authorGuilherme Maciel Ferreira <guilherme.maciel.ferreira@intra2net.com>
Tue, 19 Apr 2011 07:25:04 +0000 (09:25 +0200)
committerGuilherme Maciel Ferreira <guilherme.maciel.ferreira@intra2net.com>
Tue, 19 Apr 2011 07:25:04 +0000 (09:25 +0200)
src/dns/dnsresolver.cpp
src/dns/dnsresolver.h

index dea6720..2285b6f 100644 (file)
@@ -4,8 +4,8 @@
 
 #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"
 
@@ -13,8 +13,10 @@ using namespace std;
 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
@@ -48,41 +50,21 @@ bool DnsResolver::resolve()
 
     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 )
     {
@@ -130,6 +112,10 @@ string DnsResolver::get_next_ip()
     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
@@ -145,3 +131,56 @@ bool DnsResolver::expired_resolved_ip()
 
     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 );
+}
index 1d3b024..4b61f18 100644 (file)
@@ -4,6 +4,8 @@
 #include <string>
 #include <list>
 
+#include <boost/net/dns.hpp>
+
 class HostAddress;
 
 //-----------------------------------------------------------------------------
@@ -21,12 +23,21 @@ public:
 
     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;