// stop pinger and resolver
GlobalLogger.debug() << LogPrefix << "scheduler: stop pinging";
Ping->stop_pinging();
- Resolver->cancel_resolve();
+ cancel_resolve(true);
// now cancel the own timer in case that pinger cancelation called callback
GlobalLogger.debug() << LogPrefix << "scheduler: cancel timer";
ip = Resolver->get_next_ip(check_up_to_date);
}
if ( ip.is_valid() )
- Ping->ping(
- Resolver->get_next_ip().get_ip(),
- DestinationPort,
- boost::bind(&PingScheduler::ping_done_handler, this, _1)
- );
+ Ping->ping( ip.get_ip(),
+ DestinationPort,
+ boost::bind(&PingScheduler::ping_done_handler, this, _1) );
else
{ // should not happen
GlobalLogger.error() << LogPrefix << "No IP to ping "
if ( !Resolver->is_resolving() )
start_resolving_ping_address();
}
-
- // next time try with up-to-date IP
- ContinueOnOutdatedIps = false;
}
update_ping_interval();
update_ping_elapsed_time();
+ if (ping_success)
+ { // reset ContinueOnOutdatedIps
+ ContinueOnOutdatedIps = false;
+ update_log_prefix();
+ }
+
// get next protocol, possibly start resolving IPs
update_ping_protocol();
if (ProtocolIter == Protocols.end())
ProtocolIter = Protocols.begin();
PingProtocol ping_protocol = *ProtocolIter;
- // --> ProtocolIter still points to currently used protocol which is
+ // --> ProtocolIter still points to currently used protocol which is
// required in dns_resolve_callback
if (Ping)
NetworkInterfaceName, PingReplyTimeout);
update_dns_resolver( ping_protocol );
+
}
bool PingScheduler::can_change_ping_protocol() const
void PingScheduler::update_log_prefix()
{
std::stringstream temp;
- temp << "PS(" << DestinationAddress;
+ temp << "Sched(" << DestinationAddress;
if (ContinueOnOutdatedIps)
temp << "!";
temp << "): ";
void PingScheduler::update_dns_resolver( PingProtocol current_protocol )
{
if (Resolver && Resolver->is_resolving())
+ cancel_resolve(false);
+
+ if (ContinueOnOutdatedIps)
{
- GlobalLogger.warning() << LogPrefix
- << "Resolver still seems to be resolving --> cancel!";
- Resolver->cancel_resolve();
+ ContinueOnOutdatedIps = false;
+ update_log_prefix();
}
// DNS master caches created resolvers and resolved IPs, so this will
// start resolving if no ips available
if ( Resolver->have_up_to_date_ip() )
{
- if (!Resolver->is_resolving())
+ if (Resolver->is_resolving())
GlobalLogger.warning() << LogPrefix << "have up to date IPs but "
<< "resolver seems to be resolving all the same... "
<< "Start pinging anyway!";
<< "with success = " << was_success << " "
<< "and cname_count = " << cname_count;
- // TODO this is too simple, but need to think more about how to update here!
- // (may have to switch back some time to resolver for original host or so
- ContinueOnOutdatedIps = !was_success;
- update_log_prefix();
-
if ( was_success )
{
HostAnalyzer.set_resolved_ip_count( Resolver->get_resolved_ip_count());
else
{ // host name resolution failed; try again bypassing first outdated CNAME
// or using cached IP
+ ContinueOnOutdatedIps = true;
+ update_log_prefix();
std::string skip_host = Resolver->get_skip_cname();
GlobalLogger.notice() << LogPrefix << "DNS failed, "
<< "try again skipping a CNAME and resolving "
<< skip_host << " directly";
+
+ cancel_resolve(false);
+
+ // now create new resolver
Resolver = DnsMaster::get_instance()
->get_resolver_for(skip_host, *ProtocolIter);
start_resolving_ping_address();
-
- // (the original resolver is still alive and cached by DnsMaster and
- // counting down time to re-try on its own until cancel_resolve)
}
}
}
+
+/**
+ * cancel resolver if force_cancel or if it is not resolving DestinationAddress
+ *
+ * Resolvers have a life on their own: they are cached by DnsMaster so never go
+ * out of scope and even after calling callbacks, there might still be a
+ * longterm timer active to re-try resolving.
+ * We want to cancel that long-term timer only if the Resolver is not for our
+ * real, original DestinationAddress but a CNAME, which can happen when trying
+ * to skip cnames and working on out-dated IPs
+ */
+void PingScheduler::cancel_resolve(const bool force_cancel)
+{
+ if (force_cancel)
+ {
+ GlobalLogger.info() << "Cancelling resolver (forced)";
+ Resolver->cancel_resolve();
+ }
+ else if ( Resolver->get_hostname() == DestinationAddress )
+ GlobalLogger.info() << LogPrefix
+ << "Leave original resolver active in background";
+ else
+ {
+ GlobalLogger.info() << LogPrefix << "Cancel resolver for "
+ << Resolver->get_hostname() << " since is not the original "
+ << DestinationAddress;
+ Resolver->cancel_resolve();
+ }
+}
+