- created a class TimeToLive which is self updatable, and can get the ttl updated
- before each ping checks if the address is valid, if not, builds another IP list (which renews the ttl)
config/host.cpp
dns/dnsresolver.cpp
dns/hostaddress.cpp
+ dns/timetolive.cpp
host/boostpinger.cpp
host/hoststatusanalyzer.cpp
host/pingscheduler.cpp
#include <iostream>
#include <boost/asio.hpp>
+#include <boost/foreach.hpp>
#include <boost/net/dns.hpp>
#include <boost/net/resolve.hpp>
return false;
}
+ ResolvedHostAddressList.clear();
+
for ( rr_list_t::iterator riter = answers->begin();
riter != answers->end();
++riter )
HostAddress resolved_host( ip, ttl );
ResolvedHostAddressList.push_back( resolved_host );
- cout << "- " << ip << endl;
+ cout << "- " << ip << " [" << ttl << "s]" << endl;
}
}
}
HostAddress host_address = ResolvedHostAddressList.front();
ResolvedHostAddressList.pop_front();
string destination_ip = host_address.get_ip();
+ int ttl = host_address.get_ttl().get_updated_value();
ResolvedHostAddressList.push_back( host_address );
size_t list_size_after = ResolvedHostAddressList.size();
+ BOOST_ASSERT( 0 < ttl );
BOOST_ASSERT( list_size_before == list_size_after );
- // TODO check the ttl of the resolved IP, if it is next to zero, call the resolve again
-
return destination_ip;
}
+
+bool DnsResolver::expired_resolved_ip()
+{
+ const int threshold = 10; // TODO configurable
+
+ BOOST_FOREACH( HostAddress host_address, ResolvedHostAddressList )
+ {
+ int ttl = host_address.get_ttl().get_updated_value();
+ if ( ttl <= threshold )
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
bool resolve();
int get_resolved_ip_count() const;
+
std::string get_next_ip();
+ bool expired_resolved_ip();
+
private:
std::list<HostAddress> ResolvedHostAddressList;
const std::string HostDnsAddress;
#include "dns/hostaddress.h"
+#include <boost/assert.hpp>
+
using namespace std;
//-----------------------------------------------------------------------------
}
HostAddress::HostAddress(
- string ip,
+ const string &ip,
int ttl
) :
Ip( ip ),
{
}
-void HostAddress::set_ip( string ip )
+string HostAddress::get_ip() const
{
- this->Ip = ip;
+ return Ip;
}
-string HostAddress::get_ip() const
+void HostAddress::set_ip( const string &ip )
{
- return Ip;
+ BOOST_ASSERT( !ip.empty() );
+
+ Ip = ip;
}
-int HostAddress::get_ttl() const
+TimeToLive HostAddress::get_ttl() const
{
return Ttl;
}
-void HostAddress::set_ttl( int ttl )
+void HostAddress::set_ttl( const TimeToLive &ttl )
{
- this->Ttl = ttl;
+ Ttl = ttl;
}
-
#ifndef HOSTADDRESS_H_
#define HOSTADDRESS_H_
-#include <sys/types.h>
-
#include <string>
+#include "dns/timetolive.h"
+
//-----------------------------------------------------------------------------
// HostAddress
//-----------------------------------------------------------------------------
{
public:
HostAddress();
- HostAddress( std::string ip, int ttl );
+ HostAddress(
+ const std::string &ip,
+ int ttl
+ );
~HostAddress();
std::string get_ip() const;
- void set_ip( std::string ip );
+ void set_ip( const std::string &ip );
- int get_ttl() const;
- void set_ttl( int ttl );
+ TimeToLive get_ttl() const;
+ void set_ttl( const TimeToLive &ttl );
private:
std::string Ip;
- int Ttl;
+ TimeToLive Ttl;
};
--- /dev/null
+#include "dns/timetolive.h"
+
+#include <boost/assert.hpp>
+
+using boost::date_time::time_resolution_traits_adapted64_impl;
+using boost::posix_time::microsec_clock;
+using boost::posix_time::ptime;
+
+//-----------------------------------------------------------------------------
+// TimeToLive
+//-----------------------------------------------------------------------------
+
+TimeToLive::TimeToLive( int ttl ) :
+ Ttl( ttl ),
+ TtlSetTime( microsec_clock::universal_time() )
+{
+}
+
+TimeToLive::~TimeToLive()
+{
+}
+
+int TimeToLive::get_value() const
+{
+ return Ttl;
+}
+
+void TimeToLive::set_value( const int ttl )
+{
+ BOOST_ASSERT( 0 < ttl );
+
+ Ttl = ttl;
+ TtlSetTime = microsec_clock::universal_time();
+}
+
+int TimeToLive::get_updated_value() const
+{
+ ptime now = microsec_clock::universal_time();
+ int elapsed_seconds = static_cast<int> (
+ (now - TtlSetTime).total_seconds()
+ );
+ int original_ttl = get_value();
+ int remaining_seconds = original_ttl - elapsed_seconds;
+
+ return remaining_seconds;
+}
--- /dev/null
+#ifndef TIMETOLIVE_H
+#define TIMETOLIVE_H
+
+#include <boost/asio.hpp>
+
+//-----------------------------------------------------------------------------
+// TimeToLive
+//-----------------------------------------------------------------------------
+
+class TimeToLive
+{
+public:
+ TimeToLive( int ttl = 0 );
+ ~TimeToLive();
+
+ int get_value() const;
+ void set_value( const int ttl );
+
+ int get_updated_value() const;
+
+private:
+ int Ttl;
+ boost::posix_time::ptime TtlSetTime;
+};
+
+#endif /* TIMETOLIVE_H */
#include <boost/bind.hpp>
#include "dns/dnsresolver.h"
-#include "link/linkstatusanalyzer.h"
#include "host/boostpinger.h"
+#include "link/linkstatusanalyzer.h"
using namespace std;
using boost::asio::io_service;
using boost::bind;
+using boost::date_time::time_resolution_traits_adapted64_impl;
using boost::posix_time::microsec_clock;
using boost::posix_time::ptime;
using boost::posix_time::seconds;
bool PingScheduler::start_pinging()
{
- // TODO the DNS resolution is called only once. Find a way to resolve when
- // the TTL ends
- // TODO does the DNS keeps the same number of IPs?
bool address_resolved = resolve_ping_address();
if ( !address_resolved )
{
{
BOOST_ASSERT( 1 <= IpList.get_resolved_ip_count() );
+ // TODO this code is similar to the one at start_pinging(), make it simple!
+ if ( IpList.expired_resolved_ip() )
+ {
+ cout << "Updating DNS ... "; // TODO
+ bool address_resolved = resolve_ping_address();
+ if ( !address_resolved )
+ {
+ cerr << "Error: could not update host IP, may use outdated address"
+ << endl;
+ }
+ }
+
string destination_ip = IpList.get_next_ip();
bool ping_success = ping( destination_ip );
void PingScheduler::update_ping_elapsed_time()
{
ptime now = microsec_clock::universal_time();
- cout << "- Time elapsed since last ping: "
- << (now - TimeSentLastPing).total_seconds() << "s"
+ time_resolution_traits_adapted64_impl::int_type elapsed_time_in_sec =
+ (now - TimeSentLastPing).total_seconds();
+ cout << "- Time elapsed since last ping: " << elapsed_time_in_sec << "s"
<< endl; // TODO output log
TimeSentLastPing = microsec_clock::universal_time();