using boost::posix_time::microsec_clock;
using boost::posix_time::ptime;
using boost::posix_time::seconds;
+using boost::posix_time::milliseconds;
using boost::shared_ptr;
using I2n::Logger::GlobalLogger;
const int ping_reply_timeout,
LinkStatusItem link_analyzer,
const int first_delay,
- const int n_parallel_pings
+ const int n_parallel_pings,
const int parallel_ping_delay
) :
IoService( io_serv ),
NPingers( n_parallel_pings ),
NPingersDone( 0 ),
ParallelPingDelay( parallel_ping_delay ),
+ DelayedPingTimer( *io_serv ),
WantToPing( false ),
LogPrefix(),
ContinueOnOutdatedIps( false )
void PingScheduler::clear_pingers()
{
PingerItem pinger;
- while ( !Pingers.empty() )
+ while(!Pingers.empty())
{
- pinger = Pingers.front();
+ pinger = Pingers.back();
pinger->stop_pinging();
- Pingers.pop_front();
+ Pingers.pop_back();
}
}
boost::asio::ip::address actual_ip = ip.get_ip();
GlobalLogger.info() << LogPrefix << "pinging IP " << actual_ip
<< " with TTL " << ip.get_ttl().get_updated_value() << "s";
- int delay_count = 0;
- BOOST_FOREACH( const PingerItem &pinger, Pingers )
- {
- boost::asio::deadline_timer delayed_ping_timer( IoService );
- delayed_ping_timer.expires_from_now(
- milliseconds(delay_count * ParallelPingDelay);
- delayed_ping_timer.async_wait( bind( &PingScheduler::delayed_ping,
- this, pinger) );
- ++delay_count;
- }
- TimeSentLastPing = microsec_clock::universal_time();
+ delayed_ping(boost::system::error_code(), actual_ip, 0);
NPingersDone = 0;
+ TimeSentLastPing = microsec_clock::universal_time();
}
}
-void delayed_ping( const PingerItem &pinger )
+void PingScheduler::delayed_ping( const boost::system::error_code &error,
+ const boost::asio::ip::address &ip,
+ const int pinger_index )
{
- pinger->ping( actual_ip,
- DestinationPort,
- boost::bind(&PingScheduler::ping_done_handler,
- this, _1) );
+ if (error)
+ {
+ GlobalLogger.info() << LogPrefix << "delayed ping received an error: "
+ << error;
+ return;
+ }
+ if (pinger_index == NPingers)
+ {
+ GlobalLogger.debug() << LogPrefix << "started all delayed pings";
+ return;
+ }
+
+ GlobalLogger.debug() << LogPrefix << "starting delayed ping index "
+ << pinger_index;
+ Pingers[pinger_index]->ping(ip,
+ DestinationPort,
+ boost::bind(&PingScheduler::ping_done_handler,
+ this, _1, _2) );
+ DelayedPingTimer.expires_from_now( milliseconds(ParallelPingDelay) );
+ DelayedPingTimer.async_wait( bind( &PingScheduler::delayed_ping,
+ this, boost::asio::placeholders::error, ip, pinger_index+1) );
}
#include "host/pingprotocol.h"
#include "dns/resolverbase.h"
-typedef std::list<PingerItem> pinger_list;
+typedef std::vector<PingerItem> pinger_vec;
//-----------------------------------------------------------------------------
// PingScheduler
void update_dns_resolver( PingProtocol current_protocol );
void ping_when_ready();
+ void delayed_ping( const boost::system::error_code &error,
+ const boost::asio::ip::address &ip,
+ const int pinger_index );
void dns_resolve_callback(const bool was_success,
const int recursion_count);
void start_resolving_ping_address();
/// The Dns resolver
ResolverItem Resolver;
/// vector of pingers
- pinger_list Pingers;
+ pinger_vec Pingers;
/// number of pingers that work in parallel
int NPingers;
/// number of results from pingers
int NPingersDone;
/// delay (in ms) between pings to same IP
int ParallelPingDelay;
+ /// timers for delayed pings
+ boost::asio::deadline_timer DelayedPingTimer;
/// a flag whether we should ping as soon as dns is ready
bool WantToPing;
/// Prefix to log messages for quicker analysis/debugging