+++ /dev/null
-/*
-The software in this package is distributed under the GNU General
-Public License version 2 (with a special exception described below).
-
-A copy of GNU General Public License (GPL) is included in this distribution,
-in the file COPYING.GPL.
-
-As a special exception, if other files instantiate templates or use macros
-or inline functions from this file, or you compile this file and link it
-with other works to produce a work based on this file, this file
-does not by itself cause the resulting work to be covered
-by the GNU General Public License.
-
-However the source code for this file must still be made available
-in accordance with section (3) of the GNU General Public License.
-
-This exception does not invalidate any other reasons why a work based
-on this file might be covered by the GNU General Public License.
-*/
-#include "dns/dnsresolver.h"
-
-#include <algorithm>
-#include <iostream>
-
-#include <boost/asio.hpp>
-#include <boost/foreach.hpp>
-#include <boost/net/resolve.hpp>
-#include <boost/shared_ptr.hpp>
-
-#include <logfunc.hpp>
-
-#include "boost_assert_handler.h"
-#include "dns/hostaddress.h"
-
-using namespace std;
-using boost::asio::io_service;
-using boost::asio::ip::address;
-using boost::asio::ip::address_v4;
-using boost::asio::ip::address_v6;
-using boost::net::dns::a_resource;
-using boost::net::dns::a6_resource;
-using boost::net::dns::resource_base_t;
-using boost::net::dns::message;
-using boost::net::dns::rr_list_t;
-using boost::net::dns::type_t;
-using boost::shared_ptr;
-using I2n::Logger::GlobalLogger;
-
-//-----------------------------------------------------------------------------
-// DnsResolver
-//-----------------------------------------------------------------------------
-
-/**
- * @brief Constructor.
- *
- * @param dns_address The DNS address to resolve.
- * @param nameserver The server to consult about name resolution.
- * @param address_resource_record_type 'A' resource records for the IPv4 addresses, or 'AAAA'
- * resource records for the IPv6 addresses
- */
-DnsResolver::DnsResolver(
- const string &dns_address,
- const string &nameserver,
- const type_t address_resource_record_type,
- const int resolved_ip_ttl_threshold
-) :
- ResolvedHostAddressList(),
- HostDnsAddress( dns_address ),
- NameServer( nameserver ),
- AddressResourceRecord( address_resource_record_type ),
- ResolvedIpTtlThreshold( resolved_ip_ttl_threshold )
-{
-}
-
-/**
- * @brief Destructor.
- */
-DnsResolver::~DnsResolver()
-{
-}
-
-/**
- * @brief Resolve the IPs from this DNS and build a list of these IPs.
- *
- * @return true if the host address could be resolved, or false otherwise.
- */
-bool DnsResolver::resolve()
-{
- BOOST_ASSERT( !HostDnsAddress.empty() );
- BOOST_ASSERT( !NameServer.empty() );
-
- // Handle IP addresses in HostDnsAddress
- if ( handle_ip_address() )
- {
- return true;
- }
-
- GlobalLogger.info() << "Trying to resolve IP(s) for host : " << HostDnsAddress << endl;
-
- try
- {
- rr_list_t answers_list = get_answers_list( HostDnsAddress, NameServer, AddressResourceRecord );
- size_t resolved_ip_count = answers_list.size();
- if ( resolved_ip_count < 1 )
- {
- GlobalLogger.error() << "IP host " << HostDnsAddress << " could not be resolved." << endl;
- return false;
- }
-
- ResolvedHostAddressList.clear();
-
- fill_resolved_ip_list( answers_list, &ResolvedHostAddressList );
- }
- catch ( const std::exception &ex )
- {
- GlobalLogger.error() << "Host " << HostDnsAddress << " could not be resolved. "
- << ex.what() << endl;
- return false;
- }
-
- BOOST_ASSERT( 1 <= ResolvedHostAddressList.size() );
-
- return true;
-}
-
-/**
- * @brief Obtain the amount of IP addresses resolved for the host name provided
- * to this object.
- *
- * @return The amount of IPs resolved for the DNS.
- */
-int DnsResolver::get_resolved_ip_count() const
-{
- size_t resolved_ip_count = ResolvedHostAddressList.size();
-
- BOOST_ASSERT( 1 <= resolved_ip_count );
-
- return static_cast<int>( resolved_ip_count );
-}
-
-/**
- * @brief Obtain the next IP address resolved for the host name provided to
- * this object.
- *
- * @return the next IP string in the list of resolved IPs. When reach the last
- * IP, it goes back to first, like a circular buffer.
- */
-string DnsResolver::get_next_ip()
-{
- size_t list_size_before = ResolvedHostAddressList.size();
-
- HostAddress host_address = ResolvedHostAddressList.front();
- string destination_ip = host_address.get_ip().to_string();
-
- rotate( ResolvedHostAddressList.begin(), ++ResolvedHostAddressList.begin(), ResolvedHostAddressList.end() );
-
- size_t list_size_after = ResolvedHostAddressList.size();
-
- BOOST_ASSERT( list_size_before == list_size_after );
-
- return destination_ip;
-}
-
-/**
- * @brief check if there is any IP that is still valid
- *
- * @return @c false if there is no IP whose TTL has not expired, thus
- * requiring another query to resolve()
- */
-bool DnsResolver::have_up_to_date_ip() const
-{
- BOOST_FOREACH( const HostAddress &host_address, ResolvedHostAddressList )
- {
- uint32_t ttl = host_address.get_ttl().get_updated_value();
- if ( ttl > ResolvedIpTtlThreshold )
- {
- return true;
- }
- }
-
- return false;
-}
-
-/**
- * @brief Check if hostname is already an IP address. Will insert it into
- * #ResolvedHostAddressList.
- *
- * @param host_dns_address
- * @return bool @c true if the address is already an IP, @c false if not.
- **/
-bool DnsResolver::handle_ip_address()
-{
- BOOST_ASSERT( !HostDnsAddress.empty() );
-
- try
- {
- // Convert string to IP address, to work with both IPv4 and IPv6
- address addr = address::from_string( HostDnsAddress );
-
- if ( addr.is_v4() || addr.is_v6() )
- {
- std::list<HostAddress> new_host_list;
-
- HostAddress ip_host( addr, 86400 * 365 ); // set fake TTL to one year
- new_host_list.push_back( ip_host );
-
- // Activate new host list
- ResolvedHostAddressList.swap( new_host_list );
-
- GlobalLogger.info() << "Host is already an IP: " << HostDnsAddress << endl;
-
- return true;
- }
- }
- catch ( const boost::system::system_error & /*ex*/ )
- {
- GlobalLogger.debug() << "Host is not an IP: " << HostDnsAddress << endl;
- }
-
- return false;
-}
-
-rr_list_t DnsResolver::get_answers_list(
- const string &host_dns_address,
- const string &name_server,
- const type_t message_type
-) const
-{
- BOOST_ASSERT( !host_dns_address.empty() );
- BOOST_ASSERT( !name_server.empty() );
-
- address nameServer;
- try{
- nameServer = address::from_string( name_server );
- }
- catch ( const std::exception &ex )
- {
- GlobalLogger.error() << "Name server " << name_server << " does not seem to be an IP address. ";
- throw; // forward exception to next handler
- }
- boost::net::dns::resolve resolver;
- resolver.addServer( nameServer );
-
- message dns_message( host_dns_address, message_type );
- message& dns_packet = resolver.query( dns_message );
-
- // Note: perform a copy of each element from one vector to the other, do not reference
- return *dns_packet.answers();
-}
-
-void DnsResolver::fill_resolved_ip_list(
- const rr_list_t& answers_list,
- HostAddressList *resolved_host_address_list
-) const
-{
- BOOST_ASSERT( 1 <= answers_list.size() );
- BOOST_ASSERT( resolved_host_address_list != NULL );
-
- size_t cname_count = 0;
-
- BOOST_FOREACH( shared_ptr<resource_base_t> resource_record, answers_list )
- {
- if ( resource_record )
- {
- switch ( resource_record->rtype() )
- {
- case boost::net::dns::type_a:
- // 'A' resource records carry IPv4 addresses
- append_resolved_ipv4( resource_record, resolved_host_address_list );
- break;
- case boost::net::dns::type_a6:
- // 'AAAA' resource records carry IPv6 addresses
- append_resolved_ipv6( resource_record, resolved_host_address_list );
- break;
- case boost::net::dns::type_cname:
- // 'CNAME' resource records that carry aliases
- cname_count++;
- break;
- default:
- // other types of resource records
- break;
- }
- }
- }
-
- 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 - cname_count ) );
- BOOST_ASSERT( size_equal || size_equal_minus_cname );
-}
-
-void DnsResolver::append_resolved_ipv4(
- const shared_ptr<resource_base_t> resource_record,
- HostAddressList *resolved_host_address_list
-) const
-{
- BOOST_ASSERT( resource_record->rtype() == boost::net::dns::type_a );
-
- a_resource *a_rr = dynamic_cast<a_resource *> ( resource_record.get() );
- if ( a_rr != NULL )
- {
- address_v4 current_ip = a_rr->address();
- uint32_t current_ttl = a_rr->ttl();
-
- HostAddress resolved_host( current_ip, current_ttl );
- resolved_host_address_list->push_back( resolved_host );
-
- GlobalLogger.info() << "Have IP " << current_ip << " [" << current_ttl << "s] for "
- << HostDnsAddress << endl;
- }
-}
-
-void DnsResolver::append_resolved_ipv6(
- const shared_ptr<resource_base_t> resource_record,
- HostAddressList *resolved_host_address_list
-) const
-{
- BOOST_ASSERT( resource_record->rtype() == boost::net::dns::type_a6 );
-
- a6_resource *a6_rr = dynamic_cast<a6_resource *> ( resource_record.get() );
- if ( a6_rr != NULL )
- {
- address_v6 current_ip = a6_rr->address();
- uint32_t current_ttl = a6_rr->ttl();
-
- HostAddress resolved_host( current_ip, current_ttl );
- resolved_host_address_list->push_back( resolved_host );
-
- GlobalLogger.info() << "Have IP " << current_ip << " [" << current_ttl << "s] for "
- << HostDnsAddress << endl;
- }
-}
+++ /dev/null
-/*
-The software in this package is distributed under the GNU General
-Public License version 2 (with a special exception described below).
-
-A copy of GNU General Public License (GPL) is included in this distribution,
-in the file COPYING.GPL.
-
-As a special exception, if other files instantiate templates or use macros
-or inline functions from this file, or you compile this file and link it
-with other works to produce a work based on this file, this file
-does not by itself cause the resulting work to be covered
-by the GNU General Public License.
-
-However the source code for this file must still be made available
-in accordance with section (3) of the GNU General Public License.
-
-This exception does not invalidate any other reasons why a work based
-on this file might be covered by the GNU General Public License.
-*/
-#ifndef DNS_RESOLVER_H
-#define DNS_RESOLVER_H
-
-#include <string>
-
-#include <boost/net/dns.hpp>
-#include <boost/shared_ptr.hpp>
-
-#include "dns/hostaddress.h"
-
-//-----------------------------------------------------------------------------
-// DnsResolver
-//-----------------------------------------------------------------------------
-
-/**
- * @brief The class which provides Domain Name resolution to IP addresses.
- */
-class DnsResolver
-{
-public:
- DnsResolver(
- const std::string &dns_address,
- const std::string &nameserver,
- const boost::net::dns::type_t address_resource_record_type,
- const int resolved_ip_ttl_threshold
- );
- ~DnsResolver();
-
- bool resolve();
-
- int get_resolved_ip_count() const;
- std::string get_next_ip();
- bool have_up_to_date_ip() const;
-
-private:
- bool handle_ip_address();
-
- boost::net::dns::rr_list_t get_answers_list(
- const std::string &host_dns_address,
- const std::string &name_server,
- const boost::net::dns::type_t message_type
- ) const;
- void fill_resolved_ip_list(
- const boost::net::dns::rr_list_t& answers_list,
- std::list<HostAddress> *resolved_host_address_list
- ) const;
- void append_resolved_ipv4(
- const shared_ptr<boost::net::dns::resource_base_t> resource_record,
- std::list<HostAddress> *resolved_host_address_list
- ) const;
- void append_resolved_ipv6(
- const shared_ptr<boost::net::dns::resource_base_t> resource_record,
- std::list<HostAddress> *resolved_host_address_list
- ) const;
-
-private:
- /// The list of IPs available to the host DNS.
- HostAddressList ResolvedHostAddressList;
- /// The DNS of the host.
- const std::string HostDnsAddress;
- /// The address of the server which can resolve the host address.
- const std::string NameServer;
- /// 'A' resource records for the IPv4 addresses, or 'AAAA' resource records for the IPv6 addresses
- boost::net::dns::type_t AddressResourceRecord;
- /// Minimum time that IP has to be valid before creating new dns request
- const uint32_t ResolvedIpTtlThreshold;
-
-};
-
-//-----------------------------------------------------------------------------
-// DnsResolverItem
-//-----------------------------------------------------------------------------
-
-typedef boost::shared_ptr<DnsResolver> DnsResolverItem;
-
-#endif // DNS_RESOLVER_H
+++ /dev/null
-/*
- The software in this package is distributed under the GNU General
- Public License version 2 (with a special exception described below).
-
- A copy of GNU General Public License (GPL) is included in this distribution,
- in the file COPYING.GPL.
-
- As a special exception, if other files instantiate templates or use macros
- or inline functions from this file, or you compile this file and link it
- with other works to produce a work based on this file, this file
- does not by itself cause the resulting work to be covered
- by the GNU General Public License.
-
- However the source code for this file must still be made available
- in accordance with section (3) of the GNU General Public License.
-
- This exception does not invalidate any other reasons why a work based
- on this file might be covered by the GNU General Public License.
- */
-
-#include "dns/dnsresolverfactory.h"
-
-#include <boost/net/dns.hpp>
-
-#include "boost_assert_handler.h"
-
-using namespace std;
-using boost::net::dns::type_t;
-
-//-----------------------------------------------------------------------------
-// DnsResolverFactory
-//-----------------------------------------------------------------------------
-
-/**
- * @brief Default constructor.
- */
-DnsResolverFactory::DnsResolverFactory()
-{
-}
-
-/**
- * @brief Destructor.
- */
-DnsResolverFactory::~DnsResolverFactory()
-{
-}
-
-/**
- * @brief Creates a DNS resolver suitable to the given protocol.
- *
- * @param destination_address The remote address to ping.
- * @param nameserver Server to resolve the addresses.
- * @param ping_protocol The protocol used to ping, in order to find the DNS resolver more
- * appropriated to resolve the addresses for this protocol.
- */
-DnsResolverItem DnsResolverFactory::createResolver(
- const string &destination_address,
- const string &nameserver,
- const int resolved_ip_ttl_threshold,
- const PingProtocol ping_protocol
-)
-{
- switch ( ping_protocol )
- {
- case PingProtocol_ICMP:
- case PingProtocol_TCP:
- return DnsResolverItem(
- new DnsResolver( destination_address, nameserver, boost::net::dns::type_a,
- resolved_ip_ttl_threshold)
- );
- case PingProtocol_ICMPv6:
- case PingProtocol_TCP_IPv6:
- return DnsResolverItem(
- new DnsResolver( destination_address, nameserver, boost::net::dns::type_a6,
- resolved_ip_ttl_threshold)
- );
- default:
- BOOST_ASSERT( !"Try to create a DNS from an invalid address resource record" ); //lint !e506
- return DnsResolverItem(); //lint !e527
- }
-}