Kea 3.0.2-git
ping_check_mgr.cc
Go to the documentation of this file.
1// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#include <config.h>
8
9#include <ping_check_mgr.h>
10#include <ping_check_log.h>
11#include <dhcpsrv/cfgmgr.h>
12#include <hooks/hooks_manager.h>
15
16using namespace isc;
17using namespace isc::asiolink;
18using namespace isc::dhcp;
19using namespace isc::data;
20using namespace isc::hooks;
21using namespace isc::util;
22using namespace std;
23using namespace std::chrono;
24
25namespace ph = std::placeholders;
26
27namespace isc {
28namespace ping_check {
29
33 channel_(),
35 mutex_(new mutex()),
36 suspended_(false) {
37}
38
39PingCheckMgr::PingCheckMgr(uint32_t num_threads,
40 uint32_t min_echos,
41 uint32_t reply_timeout)
44 channel_(),
46 mutex_(new mutex()),
47 suspended_(false) {
49 config->setMinPingRequests(min_echos);
50 config->setReplyTimeout(reply_timeout);
51 config->setPingChannelThreads(num_threads);
52 config_cache_->setGlobalConfig(config);
53}
54
58
59void
61 if (!params) {
62 isc_throw(dhcp::DhcpConfigError, "params must not be null");
63 return;
64 }
65
66 if (params->getType() != Element::map) {
67 isc_throw(dhcp::DhcpConfigError, "params must be an Element::map");
68 return;
69 }
70
72 config->parse(params);
73 config_cache_->setGlobalConfig(config);
74}
75
76void
78 // Iterate over subnets and cache configurations for each.
79 ConfigCachePtr local_cache(new ConfigCache());
80 local_cache->setGlobalConfig(config_cache_->getGlobalConfig());
81 auto const& subnets = server_config->getCfgSubnets4()->getAll();
82 for (auto const& subnet : (*subnets)) {
83 auto user_context = subnet->getContext();
84 local_cache->parseAndCacheConfig(subnet->getID(), user_context);
85 }
86
87 // No errors above, replace the existing cache.
88 config_cache_ = local_cache;
89}
90
93 return (config_cache_->getGlobalConfig());
94}
95
98 if (!lease) {
99 // This really shouldn't happen.
100 isc_throw(InvalidOperation, "PingCheckConfig::getScopedConfig() - lease cannot be empty");
101 }
102
103 auto subnet_id = lease->subnet_id_;
104
105 // If the cache is stale, update it. We do this to catch subnets that have been updated
106 // via subnet_cmds.
107 auto server_config = CfgMgr::instance().getCurrentCfg();
108 auto const& subnet = server_config->getCfgSubnets4()->getBySubnetId(subnet_id);
109 if (!subnet) {
110 // This really shouldn't happen.
111 isc_throw(InvalidOperation, "PingCheckMgr::getScopedConfig() - "
112 "no subnet for id: " << subnet_id
113 << ", for lease address: " << lease->addr_);
114 }
115
116 // If cache is stale flush it and we'll lazy init subnets as we see them.
117 if (subnet->getModificationTime() > config_cache_->getLastFlushTime()) {
118 config_cache_->flush();
119 }
120
121 // If we don't find an entry for this subnet then we haven't seen it
122 // before so parse and cache it. If the subnet doesn't specify ping-check
123 // we cache an empty entry.
125 if (!config_cache_->findConfig(subnet_id, config)) {
126 auto user_context = subnet->getContext();
127 try {
128 config = config_cache_->parseAndCacheConfig(subnet_id, user_context);
129 } catch (const std::exception& ex) {
130 // We emit and error and then cache an empty entry. This causes us
131 // to log the error once and then default to global settings afterward.
132 // This avoids us relentlessly logging and failing. Remember this
133 // is happening because a subnet was updated with an invalid context via
134 // subnet-cmd.
136 .arg(subnet_id)
137 .arg(ex.what());
138 config_cache_->cacheConfig(subnet_id, config);
139 }
140 }
141
142 // Return subnet's ping-check config if it specified one, otherwise
143 // return the global config.
144 return (config ? config : config_cache_->getGlobalConfig());
145}
146
147void
149 const PingCheckConfigPtr& config) {
150 if (checkSuspended()) {
151 // Server should not be submitting requests.
152 isc_throw(InvalidOperation, "PingCheckMgr::startPing() - DHCP service is suspended!");
153 }
154
155 if (!channel_ || !channel_->isOpen()) {
156 isc_throw(InvalidOperation, "PingCheckMgr::startPing() - channel isn't open");
157 }
158
161 .arg(lease->addr_)
162 .arg(query->getLabel());
163
164 // Adds a context to the store
165 store_->addContext(lease, query, config->getMinPingRequests(),
166 config->getReplyTimeout(), parking_lot);
167
168 // Posts a call to channel's startSend() and startRead(). This will kick-start perpetual
169 // write and read cycles if they are not already running.
170 if (channel_) {
171 channel_->startSend();
172 channel_->startRead();
173 }
174}
175
176void
178 startPing(lease, query, parking_lot, getGlobalConfig());
179}
180
183 if (!checkSuspended()) {
184 return (store_->getNextToSend());
185 }
186
187 return (PingContextPtr());
188}
189
190void
192 // Transition to sending.
193 // Must not call @ref PingCheckMgr::checkSuspended() or
194 // it will cause a deadlock.
195 context->setState(PingContext::SENDING);
196 store_->updateContext(context);
197}
198
199void
200PingCheckMgr::sendCompleted(const ICMPMsgPtr& echo, bool send_failed) {
201 if (checkSuspended()) {
202 return;
203 }
204
205 try {
207
208 if (!echo) {
209 isc_throw(BadValue, "PingCheckMgr::sendCompleted() - echo is empty");
210 }
211
212 if (echo->getType() != ICMPMsg::ECHO_REQUEST) {
213 isc_throw(BadValue, "PingCheckMgr::sendCompleted() - message type: "
214 << echo->getType() << " is not an ECHO_REQUEST");
215 }
216
217 // Update the context associated with this ECHO_REQUEST.
218 PingContextPtr context = store_->getContextByAddress(echo->getDestination());
219 if (!context) {
220 isc_throw(Unexpected, "PingCheckMgr::sendCompleted() "
221 " no context found for: " << echo->getDestination());
222 }
223
224 if (send_failed) {
225 // Recoverable error occurred which means we can't get to the target's
226 // network (interface down?). Treat this the same as TARGET UNREACHABLE.
227 finishFree(context);
228 } else {
229 // Transition the context to WAITING_FOR_REPLY.
230 context->beginWaitingForReply();
231 store_->updateContext(context);
232 }
233
234 // Update the expiration timer if necessary.
236 } catch (const std::exception& ex) {
238 .arg(ex.what());
239 }
240}
241
242void
244 if (checkSuspended()) {
245 return;
246 }
247
248 try {
250
251 if (!reply) {
252 isc_throw(BadValue, "PingCheckMgr::replyReceived() - echo is empty");
253 }
254
255 switch (reply->getType()) {
257 handleEchoReply(reply);
258 break;
260 // Extract embedded ECHO REQUEST
262 break;
263 default:
264 // Ignore anything else.
265 return;
266 }
267
269 } catch (const std::exception& ex) {
271 .arg(ex.what());
272 }
273}
274
275void
277 // Update the context associated with this ECHO_REQUEST.
278 PingContextPtr context = store_->getContextByAddress(echo_reply->getSource());
279 if (!context) {
282 .arg(echo_reply->getSource())
283 .arg(echo_reply->getId())
284 .arg(echo_reply->getSequence());
285 return;
286 }
287
290 .arg(echo_reply->getSource())
291 .arg(echo_reply->getId())
292 .arg(echo_reply->getSequence());
293
294 context->setState(PingContext::TARGET_IN_USE);
295 store_->updateContext(context);
296
297 // If parking is employed, unpark the query from the parking lot,
298 // and set the offer_address_in_use argument in the callout handle
299 // to true, indicating to the server that the lease should be declined
300 // and the DHCPOFFER discarded.
301 auto parking_lot = context->getParkingLot();
302 if (parking_lot) {
303 auto query = context->getQuery();
304 auto callout_handle = query->getCalloutHandle();
305 callout_handle->setArgument("offer_address_in_use", true);
306 parking_lot->unpark(query);
307 }
308
309 // Remove the context from the store.
310 store_->deleteContext(context);
311}
312
313void
315 // Unpack the embedded ECHO REQUEST.
316 ICMPMsgPtr embedded_echo;
317 auto payload = unreachable->getPayload();
318 embedded_echo = ICMPMsg::unpack(payload.data(), payload.size());
319
320 // Fetch the context associated with the ECHO_REQUEST.
321 PingContextPtr context = store_->getContextByAddress(embedded_echo->getDestination());
322 if (!context) {
325 .arg(embedded_echo->getDestination())
326 .arg(embedded_echo->getId())
327 .arg(embedded_echo->getSequence());
328 return;
329 }
330
333 .arg(embedded_echo->getDestination())
334 .arg(embedded_echo->getId())
335 .arg(embedded_echo->getSequence());
336
337 // Render the address usable.
338 finishFree(context);
339}
340
341void
343 context->setState(PingContext::TARGET_FREE);
344 store_->updateContext(context);
345
348 .arg(context->getTarget())
349 .arg(context->getQuery()->getLabel());
350
351 // If parking is employed, unpark the query from the parking lot,
352 // and set the offer_address_in_use argument in the callout handle
353 // to false, indicating to the server that the lease is available
354 // and the DHCPOFFER should be sent to the client.
355 auto parking_lot = context->getParkingLot();
356 if (parking_lot) {
357 auto query = context->getQuery();
358 auto callout_handle = query->getCalloutHandle();
359 callout_handle->setArgument("offer_address_in_use", false);
360 parking_lot->unpark(context->getQuery());
361 }
362
363 // Remove the context from the store.
364 store_->deleteContext(context);
365}
366
367void
370 if (io_service_) {
371 // As this is a callback that may be invoked by a channel
372 // thread we post a call to stopService() rather than call
373 // it directly.
374 io_service_->post([&]() { stopService(true); });
375 }
376}
377
378size_t
379PingCheckMgr::processExpiredSince(const TimeStamp& since /* = PingContext::now() */) {
380 auto expired_pings = store_->getExpiredSince(since);
381 size_t more_pings = 0;
382 for (auto const& context : *(expired_pings)) {
385 .arg(context->getTarget())
386 .arg(context->getEchosSent())
387 .arg(context->getMinEchos())
388 .arg(context->getReplyTimeout());
389
390 if (context->getEchosSent() < context->getMinEchos()) {
391 doNextEcho(context);
392 ++more_pings;
393 } else {
394 finishFree(context);
395 }
396 }
397
398 return (more_pings);
399}
400
401void
403 // Position to do another ping by re-entering WAITING_TO_SEND
406 .arg(context->getTarget())
407 .arg(context->getEchosSent() + 1)
408 .arg(context->getMinEchos());
409
410 context->beginWaitingToSend();
411 store_->updateContext(context);
412}
413
419
420void
429
430void
432 // Find the context that expires soonest.
433 PingContextPtr context = store_->getExpiresNext();
434 if (context) {
435 // if the context's expiry is sooner than current expiry
436 // reschedule expiration timer
438 (context->getNextExpiry() < next_expiry_)) {
439 auto now = PingContext::now();
440 auto timeout = duration_cast<milliseconds>(context->getNextExpiry() - now);
442 timeout = (timeout > milliseconds(2) ? timeout : milliseconds(2));
443 next_expiry_ = now + timeout;
445 shared_from_this()),
446 timeout.count(), IntervalTimer::ONE_SHOT);
447 }
448 } else {
449 // Nothing waiting to expire. Cancel the timer.
451 }
452}
453
454void
459
460void
467
468void
472 return;
473 }
474
475 // Process everything that has expired since current time.
476 auto more_pings = processExpiredSince();
477
478 // Update the expiration timer.
481
482 // In the event there was nothing left to process when timed out,
483 // poke the channel to make sure things are moving.
484 if (more_pings && channel_) {
485 channel_->startSend();
486 channel_->startRead();
487 }
488}
489
492 Lease4Ptr& old_lease,
493 ConstHostPtr host,
494 const PingCheckConfigPtr& config) {
495 // If ping-check is disabled or the channel isn't open,
496 // drop the query from parking and release the offer to the client.
497 if (!config->getEnablePingCheck() || !channel_ || !channel_->isOpen()) {
499 }
500
501 // If we're already running check on this address then drop the
502 // query from parking and discard the offer.
503 if (store_->getContextByAddress(lease->addr_)) {
506 .arg(lease->addr_)
507 .arg(query->getLabel());
509 }
510
511 // Reserved addresses are never checked.
512 if (host && (host->getIPv4Reservation() == lease->addr_)) {
514 }
515
516 // If there's a previous lease that belongs to this client and it either
517 // active or was touched by the client less than ping-cltt-secs ago then
518 // no check is needed. Drop the query from parking and release the
519 // offer to the client,
520 if (old_lease && (old_lease->addr_ == lease->addr_)) {
521 if (old_lease->belongsToClient(lease->hwaddr_, lease->client_id_)) {
522 if (!old_lease->expired() ||
523 ((time(0) - old_lease->cltt_) < config->getPingClttSecs())) {
525 }
526 }
527 }
528
529 // Leave it parked and do the ping check.
531}
532
533void
535 network_state_ = network_state;
536 io_service_->post([&]() { start(); });
537}
538
539bool
544
545bool
547 if (!network_state_ || network_state_->isServiceEnabled()) {
548 suspended_ = false;
549 } else {
550 if (!suspended_) {
551 suspended_ = true;
552
553 // Flush the context store, dropping parked queries.
554 flush(false);
555 }
556 }
557
558 return (suspended_);
559}
560
561void
562PingCheckMgr::stopService(bool finish_free) {
563 // Pause the thread pool while we flush the store.
564 pause();
565
566 // Flush the context store. If finish_free is true
567 // the flush will treat the remaining context lease
568 // addresses as free to use and unpark them. This
569 // will cause the server to send out the associated
570 // OFFERs. If it's false we just drop them from
571 // the parking lot.
572 flush(finish_free);
573
574 // Stop the thread pool, destroy the channel and the like.
575 stop();
576}
577
578void
580 if (MultiThreadingMgr::instance().isTestMode()) {
581 return;
582 }
583 if (!MultiThreadingMgr::instance().getMode()) {
585 return;
586 }
587
588 // We must be in multi-threading mode.
589 // Add critical section callbacks.
591 std::bind(&PingCheckMgr::checkPermissions, this),
592 std::bind(&PingCheckMgr::pause, this),
593 std::bind(&PingCheckMgr::resume, this));
594
595 // Punt if we're already started.
596 if (thread_pool_ && thread_pool_->isStopped()) {
597 isc_throw(InvalidOperation, "PingCheckMgr already started!");
598 }
599
600 try {
601 auto config = config_cache_->getGlobalConfig();
602 auto use_threads = (config->getPingChannelThreads() ? config->getPingChannelThreads()
603 : MultiThreadingMgr::instance().getThreadPoolSize());
604 thread_pool_.reset(new IoServiceThreadPool(IOServicePtr(), use_threads, true));
605 IOServicePtr pool_ios = thread_pool_->getIOService();
606 channel_ = createChannel(pool_ios);
607 channel_->open();
608 expiration_timer_.reset(new IntervalTimer(pool_ios));
609 thread_pool_->run();
611 .arg(use_threads);
612 } catch (const std::exception& ex) {
613 channel_.reset();
614 thread_pool_.reset();
615 isc_throw(Unexpected, "PingCheckMgr::start failed:" << ex.what());
616 }
617}
618
619void
621 try {
622 auto config = config_cache_->getGlobalConfig();
624 channel_->open();
627 } catch (const std::exception& ex) {
628 channel_.reset();
629 isc_throw(Unexpected, "PingCheckMgr::startSingleThreaded() failed:" << ex.what());
630 }
631}
632
635 return (PingChannelPtr(new PingChannel(io_service,
636 std::bind(&PingCheckMgr::nextToSend,
637 this),
639 this, ph::_1),
641 this, ph::_1, ph::_2),
643 this, ph::_1),
645 this))));
646}
647
648void
650 // Since this function is used as CS callback all exceptions must be
651 // suppressed, unlikely though they may be.
652 try {
653 if (thread_pool_) {
654 thread_pool_->checkPausePermissions();
655 }
656 } catch (const isc::MultiThreadingInvalidOperation& ex) {
658 .arg(ex.what());
659 // The exception needs to be propagated to the caller of the
660 // @ref MultiThreadingCriticalSection constructor.
661 throw;
662 } catch (const std::exception& ex) {
664 .arg(ex.what());
665 }
666}
667
668void
670 if (!MultiThreadingMgr::instance().getMode()) {
671 return;
672 }
673
674 // Since this function is used as CS callback all exceptions must be
675 // suppressed, unlikely though they may be.
676 try {
677 // Cancel the expiration timer.
679
680 // Pause the thread pool.
681 if (thread_pool_) {
682 thread_pool_->pause();
683 }
684 } catch (const std::exception& ex) {
686 .arg(ex.what());
687 }
688}
689
690void
692 if (!MultiThreadingMgr::instance().getMode()) {
693 return;
694 }
695
696 // Since this function is used as CS callback all exceptions must be
697 // suppressed, unlikely though they may be.
698 try {
699 if (thread_pool_) {
700 thread_pool_->run();
701 }
702
703 // Restore the expiration timer.
705 } catch (const std::exception& ex) {
707 .arg(ex.what());
708 }
709}
710
711void
714
715 // Cancel the expiration timer.
717
718 if (channel_) {
719 channel_->close();
720 }
721
722 if (thread_pool_) {
723 // Remove critical section callbacks.
725
726 // Stop the thread pool.
727 thread_pool_->stop();
728
729 thread_pool_->getIOService()->stopAndPoll();
730
731 // Ditch the thread_pool
732 thread_pool_.reset();
733 }
734 // Ditch the timer. It must be destroyed before the thread pool because in
735 // MT it holds a reference to the pool's IOService.
736 expiration_timer_.reset();
737
738 // Get rid of the channel.
739 channel_.reset();
740
741 if (io_service_) {
742 io_service_->stopAndPoll();
743 }
744
746}
747
748bool
750 // In ST mode, running is an open channel.
751 if (!MultiThreadingMgr::instance().getMode()) {
752 return (channel_ && channel_->isOpen());
753 }
754
755 if (thread_pool_) {
756 return (thread_pool_->isRunning());
757 }
758
759 return (false);
760}
761
762bool
764 // In ST mode, stopped equates to no channel.
765 if (!MultiThreadingMgr::instance().getMode()) {
766 return (!channel_);
767 }
768
769 if (thread_pool_) {
770 return (thread_pool_->isStopped());
771 }
772
773 return (true);
774}
775
776bool
778 if (thread_pool_) {
779 return (thread_pool_->isPaused());
780 }
781
782 return (false);
783}
784
785void
786PingCheckMgr::flush(bool finish_free /* = false */) {
787 if (!store_) {
788 return;
789 }
790
791 // Fetch them all.
792 auto contexts = store_->getAll();
793 for (auto const& context : *contexts) {
794 if (finish_free) {
795 finishFree(context);
796 } else {
797 auto parking_lot = context->getParkingLot();
798 if (parking_lot) {
799 parking_lot->drop(context->getQuery());
800 }
801 }
802 }
803
804 store_->clear();
805}
806
807} // end of namespace ping_check
808} // end of namespace isc
CalloutNextStep
Specifies allowed next steps.
@ map
Definition data.h:147
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
A generic exception that is thrown if a function is called in a prohibited way.
Exception thrown when a worker thread is trying to stop or pause the respective thread pool (which wo...
A generic exception that is thrown when an unexpected error condition occurs.
static CfgMgr & instance()
returns a single instance of Configuration Manager
Definition cfgmgr.cc:29
SrvConfigPtr getCurrentCfg()
Returns a pointer to the current configuration.
Definition cfgmgr.cc:116
To be removed. Please use ConfigError instead.
@ NEXT_STEP_PARK
park the packet
@ NEXT_STEP_CONTINUE
continue normally
@ NEXT_STEP_DROP
drop the packet
ConfigCache stores ping check config per subnet.
static ICMPMsgPtr unpack(const uint8_t *wire_data, size_t length)
Unpacks an ICMP message from the given wire_data.
Definition icmp_msg.cc:30
Provides thread-safe ICMP ECHO REQUEST/ECHO REPLY service.
Houses the Ping check configuration parameters for a single scope (e.g.
virtual void channelShutdown()
Callback passed to PingChannel to invoke when it shuts down.
virtual void expirationTimedOut()
Callback passed to expiration timer to invoke on timeout.
virtual void updateContextToSend(PingContextPtr context)
Callback passed to PingChannel to update a context to SENDING state just before sending.
asiolink::IntervalTimerPtr expiration_timer_
Timer which tracks the next expiration event.
bool isRunning()
Indicates if the thread pool is running.
void checkPermissions()
Check if the current thread can perform thread pool state transition.
void configure(data::ConstElementPtr params)
Configure the PingCheckMgr.
asiolink::IoServiceThreadPoolPtr thread_pool_
Thread pool used when running multi-threaded.
void cancelExpirationTimerInternal()
Cancels the expiration timer.
TimeStamp next_expiry_
TimeStamp of the next expiration event.
virtual void setNextExpirationInternal()
Updates the expiration timer.
void stopService(bool finish_free=false)
Shuts down the manager's channel, flushes the store.
void resume()
Resume PingChannel operations.
void startService(dhcp::NetworkStatePtr network_state)
Performs a deferred start by posting an invocation of start() to the given IOService.
const PingCheckConfigPtr getScopedConfig(dhcp::Lease4Ptr &lease)
Fetches the current, scoped configuration parameters.
bool isStopped()
Indicates if the thread pool is stopped.
virtual PingChannelPtr createChannel(asiolink::IOServicePtr io_service)
Creates a ping channel instance.
const PingCheckConfigPtr getGlobalConfig() const
Fetches the current, global configuration parameters.
TimeStamp getNextExpiry()
Fetches the time at which expiration timer will next expire.
void handleTargetUnreachable(const ICMPMsgPtr &unreachable)
Process an UNREACHABLE message.
void startPing(dhcp::Lease4Ptr &lease, dhcp::Pkt4Ptr &query, hooks::ParkingLotHandlePtr &parking_lot, const PingCheckConfigPtr &config)
Initiates a ping check for a given lease and its associated DHCPDISCOVER packet.
void finishFree(const PingContextPtr &context)
Processes a context whose address has been deemed free to use.
const boost::scoped_ptr< std::mutex > mutex_
The mutex used to protect internal state.
virtual size_t processExpiredSince(const TimeStamp &since=PingContext::now())
Performs expiration processing for contexts whose WAITING_FOR_REPLY states expired prior to a given p...
bool checkSuspendedInternal()
Checks if operations are currently suspended due to NetworkState.
void pause()
Pause PingChannel operations.
virtual ~PingCheckMgr()
Destructor.
bool checkSuspended()
Checks if operations are currently suspended due to NetworkState.
void flush(bool finish_free=false)
Flushes the ping context store.
PingChannelPtr channel_
Channel that conducts ICMP messaging.
bool suspended_
Indicates whether or not operations have been suspended.
void cancelExpirationTimer()
Cancels the expiration timer (thread safe).
void start()
Start PingChannel operations.
void updateSubnetConfig(dhcp::SrvConfigPtr server_config)
Update the cache of subnet ping check configurations.
virtual void replyReceived(const ICMPMsgPtr &reply)
Callback passed to PingChannel to invoke when an ICMP reply has been received.
PingContextStorePtr store_
In-memory store of PingContexts.
virtual hooks::CalloutHandle::CalloutNextStep shouldPing(dhcp::Lease4Ptr &lease, dhcp::Pkt4Ptr &query, dhcp::Lease4Ptr &old_lease, dhcp::ConstHostPtr host, const PingCheckConfigPtr &config)
Determines whether or not a lease should be ping checked.
virtual PingContextPtr nextToSend()
Callback passed to PingChannel to use to retrieve the next context with address to check.
void startSingleThreaded()
Start single-threaded PingChannel operations.
void stop()
Stop PingChannel operations.
ConfigCachePtr config_cache_
Warehouses parsed global and subnet configuration.
isc::asiolink::IOServicePtr io_service_
The hook I/O service.
dhcp::NetworkStatePtr network_state_
Tracks whether or not the server is processing DHCP packets.
void handleEchoReply(const ICMPMsgPtr &echo_reply)
Process an ECHO REPLY message.
virtual void setNextExpiration()
Updates the expiration timer (thread safe).
void doNextEcho(const PingContextPtr &context)
Position a context to do another ping test.
virtual void sendCompleted(const ICMPMsgPtr &echo, bool send_failed)
Callback passed to PingChannel to invoke when an ECHO REQUEST send has completed.
bool isPaused()
Indicates if the thread pool is paused.
Maintains an in-memory store of PingContexts.
static const TimeStamp & EMPTY_TIME()
Fetches an empty timestamp.
static TimeStamp now()
Fetches the current timestamp (UTC/milliseconds precision).
static MultiThreadingMgr & instance()
Returns a single instance of Multi Threading Manager.
void removeCriticalSectionCallbacks(const std::string &name)
Removes the set of callbacks associated with a given name from the list of CriticalSection callbacks.
void addCriticalSectionCallbacks(const std::string &name, const CSCallbackSet::Callback &check_cb, const CSCallbackSet::Callback &entry_cb, const CSCallbackSet::Callback &exit_cb)
Adds a set of callbacks to the list of CriticalSection callbacks.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
Definition macros.h:32
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
Definition macros.h:20
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition macros.h:14
boost::shared_ptr< const Element > ConstElementPtr
Definition data.h:29
boost::shared_ptr< Pkt4 > Pkt4Ptr
A pointer to Pkt4 object.
Definition pkt4.h:555
boost::shared_ptr< SrvConfig > SrvConfigPtr
Non-const pointer to the SrvConfig.
boost::shared_ptr< NetworkState > NetworkStatePtr
Pointer to the NetworkState object.
boost::shared_ptr< const Host > ConstHostPtr
Const pointer to the Host object.
Definition host.h:840
boost::shared_ptr< Lease4 > Lease4Ptr
Pointer to a Lease4 structure.
Definition lease.h:315
boost::shared_ptr< ParkingLotHandle > ParkingLotHandlePtr
Pointer to the parking lot handle.
const int DBGLVL_TRACE_BASIC
Trace basic operations.
const int DBGLVL_TRACE_DETAIL
Trace detailed operations.
boost::shared_ptr< PingCheckConfig > PingCheckConfigPtr
Defines a shared pointer to a PingCheckConfig.
boost::shared_ptr< ICMPMsg > ICMPMsgPtr
Shared pointer type for ICMPMsg.
Definition icmp_msg.h:26
isc::log::Logger ping_check_logger("ping-check-hooks")
std::chrono::time_point< std::chrono::system_clock > TimeStamp
Specifies the type for time stamps.
boost::shared_ptr< ConfigCache > ConfigCachePtr
Defines a shared pointer to a ConfigCache.
boost::shared_ptr< PingContext > PingContextPtr
Defines a shared pointer to a PingContext.
boost::shared_ptr< PingChannel > PingChannelPtr
Defines a smart pointer to PingChannel.
Defines the logger used by the top-level component of kea-lfc.
const isc::log::MessageID PING_CHECK_MGR_STARTED
const isc::log::MessageID PING_CHECK_MGR_NEXT_ECHO_SCHEDULED
const isc::log::MessageID PING_CHECK_MGR_STARTED_SINGLE_THREADED
const isc::log::MessageID PING_CHECK_DUPLICATE_CHECK
const isc::log::MessageID PING_CHECK_MGR_CHANNEL_DOWN
const isc::log::MessageID PING_CHECK_MGR_RECEIVED_UNREACHABLE_MSG
const isc::log::MessageID PING_CHECK_MGR_RECEIVED_ECHO_REPLY
const isc::log::MessageID PING_CHECK_MGR_RECEIVED_UNEXPECTED_ECHO_REPLY
const isc::log::MessageID PING_CHECK_RESUME_FAILED
const isc::log::MessageID PING_CHECK_MGR_STOPPING
const isc::log::MessageID PING_CHECK_MGR_REPLY_RECEIVED_ERROR
const isc::log::MessageID PING_CHECK_MGR_SEND_COMPLETED_ERROR
const isc::log::MessageID PING_CHECK_MGR_SUBNET_CONFIG_FAILED
const isc::log::MessageID PING_CHECK_MGR_LEASE_FREE_TO_USE
const isc::log::MessageID PING_CHECK_MGR_STOPPED
const isc::log::MessageID PING_CHECK_MGR_REPLY_TIMEOUT_EXPIRED
const isc::log::MessageID PING_CHECK_PAUSE_FAILED
const isc::log::MessageID PING_CHECK_MGR_START_PING_CHECK
const isc::log::MessageID PING_CHECK_MGR_RECEIVED_UNEXPECTED_UNREACHABLE_MSG
const isc::log::MessageID PING_CHECK_PAUSE_PERMISSIONS_FAILED
const isc::log::MessageID PING_CHECK_PAUSE_ILLEGAL
RAII lock object to protect the code in the same scope with a mutex.