Kea 3.3.3
ping_check_mgr.cc
Go to the documentation of this file.
1// Copyright (C) 2023-2026 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 <dhcpsrv/cfgmgr.h>
10#include <hooks/hooks_manager.h>
12#include <stats/stats_mgr.h>
15
16#include <ping_check_log.h>
17
18using namespace isc;
19using namespace isc::asiolink;
20using namespace isc::dhcp;
21using namespace isc::data;
22using namespace isc::hooks;
23using namespace isc::stats;
24using namespace isc::util;
25using namespace std;
26using namespace std::chrono;
27
28namespace ph = std::placeholders;
29
30namespace isc {
31namespace ping_check {
32
36 channel_(),
38 mutex_(new mutex()),
39 suspended_(false) {
40}
41
42PingCheckMgr::PingCheckMgr(uint32_t num_threads,
43 uint32_t min_echos,
44 uint32_t reply_timeout)
47 channel_(),
49 mutex_(new mutex()),
50 suspended_(false) {
52 config->setMinPingRequests(min_echos);
53 config->setReplyTimeout(reply_timeout);
54 config->setPingChannelThreads(num_threads);
55 config_cache_->setGlobalConfig(config);
56}
57
61
62void
64 if (!params) {
65 isc_throw(dhcp::DhcpConfigError, "params must not be null");
66 return;
67 }
68
69 if (params->getType() != Element::map) {
70 isc_throw(dhcp::DhcpConfigError, "params must be an Element::map");
71 return;
72 }
73
75 config->parse(params);
76 config_cache_->setGlobalConfig(config);
77}
78
79void
81 // Iterate over subnets and cache configurations for each.
82 ConfigCachePtr local_cache(new ConfigCache());
83 local_cache->setGlobalConfig(config_cache_->getGlobalConfig());
84 auto const& subnets = server_config->getCfgSubnets4()->getAll();
85 for (auto const& subnet : (*subnets)) {
86 auto user_context = subnet->getContext();
87 local_cache->parseAndCacheConfig(subnet->getID(), user_context);
88 }
89
90 // No errors above, replace the existing cache.
91 config_cache_ = local_cache;
92}
93
96 return (config_cache_->getGlobalConfig());
97}
98
101 if (!lease) {
102 // This really shouldn't happen.
103 isc_throw(InvalidOperation, "PingCheckConfig::getScopedConfig() - lease cannot be empty");
104 }
105
106 auto subnet_id = lease->subnet_id_;
107
108 // If the cache is stale, update it. We do this to catch subnets that have been updated
109 // via subnet_cmds.
110 auto server_config = CfgMgr::instance().getCurrentCfg();
111 auto const& subnet = server_config->getCfgSubnets4()->getBySubnetId(subnet_id);
112 if (!subnet) {
113 // This really shouldn't happen.
114 isc_throw(InvalidOperation, "PingCheckMgr::getScopedConfig() - "
115 "no subnet for id: " << subnet_id
116 << ", for lease address: " << lease->addr_);
117 }
118
119 // If cache is stale flush it and we'll lazy init subnets as we see them.
120 if (subnet->getModificationTime() > config_cache_->getLastFlushTime()) {
121 config_cache_->flush();
122 }
123
124 // If we don't find an entry for this subnet then we haven't seen it
125 // before so parse and cache it. If the subnet doesn't specify ping-check
126 // we cache an empty entry.
128 if (!config_cache_->findConfig(subnet_id, config)) {
129 auto user_context = subnet->getContext();
130 try {
131 config = config_cache_->parseAndCacheConfig(subnet_id, user_context);
132 } catch (const std::exception& ex) {
133 // We emit and error and then cache an empty entry. This causes us
134 // to log the error once and then default to global settings afterward.
135 // This avoids us relentlessly logging and failing. Remember this
136 // is happening because a subnet was updated with an invalid context via
137 // subnet-cmd.
139 .arg(subnet_id)
140 .arg(ex.what());
141 config_cache_->cacheConfig(subnet_id, config);
142 }
143 }
144
145 // Return subnet's ping-check config if it specified one, otherwise
146 // return the global config.
147 return (config ? config : config_cache_->getGlobalConfig());
148}
149
150void
152 const PingCheckConfigPtr& config) {
153 if (checkSuspended()) {
154 // Server should not be submitting requests.
155 isc_throw(InvalidOperation, "PingCheckMgr::startPing() - DHCP service is suspended!");
156 }
157
158 if (!channel_ || !channel_->isOpen()) {
159 isc_throw(InvalidOperation, "PingCheckMgr::startPing() - channel isn't open");
160 }
161
164 .arg(lease->addr_)
165 .arg(query->getLabel());
166
167 // Adds a context to the store
168 store_->addContext(lease, query, config->getMinPingRequests(),
169 config->getReplyTimeout(), parking_lot);
170
171 // Posts a call to channel's startSend() and startRead(). This will kick-start perpetual
172 // write and read cycles if they are not already running.
173 if (channel_) {
174 channel_->startSend();
175 channel_->startRead();
176 }
177}
178
179void
181 startPing(lease, query, parking_lot, getGlobalConfig());
182}
183
186 if (!checkSuspended()) {
187 return (store_->getNextToSend());
188 }
189
190 return (PingContextPtr());
191}
192
193void
195 // Transition to sending.
196 // Must not call @ref PingCheckMgr::checkSuspended() or
197 // it will cause a deadlock.
198 context->setState(PingContext::SENDING);
199 store_->updateContext(context);
200}
201
202void
203PingCheckMgr::sendCompleted(const ICMPMsgPtr& echo, bool send_failed) {
204 if (checkSuspended()) {
205 return;
206 }
207
208 try {
210
211 if (!echo) {
212 isc_throw(BadValue, "PingCheckMgr::sendCompleted() - echo is empty");
213 }
214
215 if (echo->getType() != ICMPMsg::ECHO_REQUEST) {
216 isc_throw(BadValue, "PingCheckMgr::sendCompleted() - message type: "
217 << echo->getType() << " is not an ECHO_REQUEST");
218 }
219
220 // Update the context associated with this ECHO_REQUEST.
221 PingContextPtr context = store_->getContextByAddress(echo->getDestination());
222 if (!context) {
223 isc_throw(Unexpected, "PingCheckMgr::sendCompleted() "
224 " no context found for: " << echo->getDestination());
225 }
226
227 if (send_failed) {
228 // Recoverable error occurred which means we can't get to the target's
229 // network (interface down?). Treat this the same as TARGET UNREACHABLE.
230 finishFree(context);
231 } else {
232 // Transition the context to WAITING_FOR_REPLY.
233 context->beginWaitingForReply();
234 store_->updateContext(context);
235 }
236
237 // Update the expiration timer if necessary.
239 } catch (const std::exception& ex) {
241 .arg(ex.what());
242 }
243}
244
245void
247 if (checkSuspended()) {
248 return;
249 }
250
251 try {
253
254 if (!reply) {
255 isc_throw(BadValue, "PingCheckMgr::replyReceived() - echo is empty");
256 }
257
258 switch (reply->getType()) {
260 handleEchoReply(reply);
261 break;
263 // Extract embedded ECHO REQUEST
265 break;
266 default:
267 // Ignore anything else.
268 return;
269 }
270
272 } catch (const std::exception& ex) {
274 .arg(ex.what());
275 }
276}
277
278void
280 // Update the context associated with this ECHO_REQUEST.
281 PingContextPtr context = store_->getContextByAddress(echo_reply->getSource());
282 if (!context) {
285 .arg(echo_reply->getSource())
286 .arg(echo_reply->getId())
287 .arg(echo_reply->getSequence());
288 return;
289 }
290
293 .arg(echo_reply->getSource())
294 .arg(echo_reply->getId())
295 .arg(echo_reply->getSequence());
296
297 context->setState(PingContext::TARGET_IN_USE);
298 store_->updateContext(context);
299
300 // If parking is employed, unpark the query from the parking lot,
301 // and set the offer_address_in_use argument in the callout handle
302 // to true, indicating to the server that the lease should be declined
303 // and the DHCPOFFER discarded.
304 auto parking_lot = context->getParkingLot();
305 if (parking_lot) {
306 auto query = context->getQuery();
307 auto callout_handle = query->getCalloutHandle();
308 callout_handle->setArgument("offer_address_in_use", true);
309 parking_lot->unpark(query);
310 }
311
312 // Remove the context from the store.
313 store_->deleteContext(context);
314}
315
316void
318 // Unpack the embedded ECHO REQUEST.
319 ICMPMsgPtr embedded_echo;
320 auto payload = unreachable->getPayload();
321 embedded_echo = ICMPMsg::unpack(payload.data(), payload.size());
322
323 // Fetch the context associated with the ECHO_REQUEST.
324 PingContextPtr context = store_->getContextByAddress(embedded_echo->getDestination());
325 if (!context) {
328 .arg(embedded_echo->getDestination())
329 .arg(embedded_echo->getId())
330 .arg(embedded_echo->getSequence());
331 return;
332 }
333
336 .arg(embedded_echo->getDestination())
337 .arg(embedded_echo->getId())
338 .arg(embedded_echo->getSequence());
339
340 // Render the address usable.
341 finishFree(context);
342}
343
344void
346 context->setState(PingContext::TARGET_FREE);
347 store_->updateContext(context);
348
351 .arg(context->getTarget())
352 .arg(context->getQuery()->getLabel());
353
354 // If parking is employed, unpark the query from the parking lot,
355 // and set the offer_address_in_use argument in the callout handle
356 // to false, indicating to the server that the lease is available
357 // and the DHCPOFFER should be sent to the client.
358 auto parking_lot = context->getParkingLot();
359 if (parking_lot) {
360 auto query = context->getQuery();
361 auto callout_handle = query->getCalloutHandle();
362 callout_handle->setArgument("offer_address_in_use", false);
363 parking_lot->unpark(context->getQuery());
364 }
365
366 // Remove the context from the store.
367 store_->deleteContext(context);
368}
369
370void
373 if (io_service_) {
374 // As this is a callback that may be invoked by a channel
375 // thread we post a call to stopService() rather than call
376 // it directly.
377 io_service_->post([&]() { stopService(true); });
378 }
379}
380
381size_t
382PingCheckMgr::processExpiredSince(const TimeStamp& since /* = PingContext::now() */) {
383 auto expired_pings = store_->getExpiredSince(since);
384 size_t more_pings = 0;
385 for (auto const& context : *(expired_pings)) {
388 .arg(context->getTarget())
389 .arg(context->getEchosSent())
390 .arg(context->getMinEchos())
391 .arg(context->getReplyTimeout());
392
393 if (context->getEchosSent() < context->getMinEchos()) {
394 doNextEcho(context);
395 ++more_pings;
396 } else {
397 finishFree(context);
398 }
399 }
400
401 return (more_pings);
402}
403
404void
406 // Position to do another ping by re-entering WAITING_TO_SEND
409 .arg(context->getTarget())
410 .arg(context->getEchosSent() + 1)
411 .arg(context->getMinEchos());
412
413 context->beginWaitingToSend();
414 store_->updateContext(context);
415}
416
422
423void
432
433void
435 // Find the context that expires soonest.
436 PingContextPtr context = store_->getExpiresNext();
437 if (context) {
438 // if the context's expiry is sooner than current expiry
439 // reschedule expiration timer
441 (context->getNextExpiry() < next_expiry_)) {
442 auto now = PingContext::now();
443 auto timeout = duration_cast<milliseconds>(context->getNextExpiry() - now);
445 timeout = (timeout > milliseconds(2) ? timeout : milliseconds(2));
446 next_expiry_ = now + timeout;
448 shared_from_this()),
449 timeout.count(), IntervalTimer::ONE_SHOT);
450 }
451 } else {
452 // Nothing waiting to expire. Cancel the timer.
454 }
455}
456
457void
462
463void
470
471void
475 return;
476 }
477
478 // Process everything that has expired since current time.
479 auto more_pings = processExpiredSince();
480
481 // Update the expiration timer.
484
485 // In the event there was nothing left to process when timed out,
486 // poke the channel to make sure things are moving.
487 if (more_pings && channel_) {
488 channel_->startSend();
489 channel_->startRead();
490 }
491}
492
495 Lease4Ptr& old_lease,
496 ConstHostPtr host,
497 const PingCheckConfigPtr& config) {
498 // If ping-check is disabled or the channel isn't open,
499 // drop the query from parking and release the offer to the client.
500 if (!config->getEnablePingCheck() || !channel_ || !channel_->isOpen()) {
502 }
503
504 // If we're already running check on this address then drop the
505 // query from parking and discard the offer.
506 if (store_->getContextByAddress(lease->addr_)) {
509 .arg(lease->addr_)
510 .arg(query->getLabel());
511 StatsMgr::instance().addValue("pkt4-duplicate",
512 static_cast<int64_t>(1));
513 StatsMgr::instance().addValue("pkt4-receive-drop",
514 static_cast<int64_t>(1));
516 }
517
518 // Reserved addresses are never checked.
519 if (host && (host->getIPv4Reservation() == lease->addr_)) {
521 }
522
523 // If there's a previous lease that belongs to this client and it either
524 // active or was touched by the client less than ping-cltt-secs ago then
525 // no check is needed. Drop the query from parking and release the
526 // offer to the client,
527 if (old_lease && (old_lease->addr_ == lease->addr_)) {
528 if (old_lease->belongsToClient(lease->hwaddr_, lease->client_id_)) {
529 if (!old_lease->expired() ||
530 ((time(0) - old_lease->cltt_) < static_cast<time_t>(config->getPingClttSecs()))) {
532 }
533 }
534 }
535
536 // Leave it parked and do the ping check.
538}
539
540void
542 network_state_ = network_state;
543 io_service_->post([&]() { start(); });
544}
545
546bool
551
552bool
554 if (!network_state_ || network_state_->isServiceEnabled()) {
555 suspended_ = false;
556 } else {
557 if (!suspended_) {
558 suspended_ = true;
559
560 // Flush the context store, dropping parked queries.
561 flush(false);
562 }
563 }
564
565 return (suspended_);
566}
567
568void
569PingCheckMgr::stopService(bool finish_free) {
570 // Pause the thread pool while we flush the store.
571 pause();
572
573 // Flush the context store. If finish_free is true
574 // the flush will treat the remaining context lease
575 // addresses as free to use and unpark them. This
576 // will cause the server to send out the associated
577 // OFFERs. If it's false we just drop them from
578 // the parking lot.
579 flush(finish_free);
580
581 // Stop the thread pool, destroy the channel and the like.
582 stop();
583}
584
585void
587 if (MultiThreadingMgr::instance().isTestMode()) {
588 return;
589 }
590 if (!MultiThreadingMgr::instance().getMode()) {
592 return;
593 }
594
595 // We must be in multi-threading mode.
596 // Add critical section callbacks.
598 std::bind(&PingCheckMgr::checkPermissions, this),
599 std::bind(&PingCheckMgr::pause, this),
600 std::bind(&PingCheckMgr::resume, this));
601
602 // Punt if we're already started.
603 if (thread_pool_ && thread_pool_->isStopped()) {
604 isc_throw(InvalidOperation, "PingCheckMgr already started!");
605 }
606
607 try {
608 auto config = config_cache_->getGlobalConfig();
609 auto use_threads = (config->getPingChannelThreads() ? config->getPingChannelThreads()
610 : MultiThreadingMgr::instance().getThreadPoolSize());
611 thread_pool_.reset(new IoServiceThreadPool(IOServicePtr(), use_threads, true));
612 IOServicePtr pool_ios = thread_pool_->getIOService();
613 channel_ = createChannel(pool_ios);
614 channel_->open();
615 expiration_timer_.reset(new IntervalTimer(pool_ios));
616 thread_pool_->run();
618 .arg(use_threads);
619 } catch (const std::exception& ex) {
620 channel_.reset();
621 thread_pool_.reset();
622 isc_throw(Unexpected, "PingCheckMgr::start failed:" << ex.what());
623 }
624}
625
626void
628 try {
629 auto config = config_cache_->getGlobalConfig();
631 channel_->open();
634 } catch (const std::exception& ex) {
635 channel_.reset();
636 isc_throw(Unexpected, "PingCheckMgr::startSingleThreaded() failed:" << ex.what());
637 }
638}
639
642 return (PingChannelPtr(new PingChannel(io_service,
643 std::bind(&PingCheckMgr::nextToSend,
644 this),
646 this, ph::_1),
648 this, ph::_1, ph::_2),
650 this, ph::_1),
652 this))));
653}
654
655void
657 // Since this function is used as CS callback all exceptions must be
658 // suppressed, unlikely though they may be.
659 try {
660 if (thread_pool_) {
661 thread_pool_->checkPausePermissions();
662 }
663 } catch (const isc::MultiThreadingInvalidOperation& ex) {
665 .arg(ex.what());
666 // The exception needs to be propagated to the caller of the
667 // @ref MultiThreadingCriticalSection constructor.
668 throw;
669 } catch (const std::exception& ex) {
671 .arg(ex.what());
672 }
673}
674
675void
677 if (!MultiThreadingMgr::instance().getMode()) {
678 return;
679 }
680
681 // Since this function is used as CS callback all exceptions must be
682 // suppressed, unlikely though they may be.
683 try {
684 // Cancel the expiration timer.
686
687 // Pause the thread pool.
688 if (thread_pool_) {
689 thread_pool_->pause();
690 }
691 } catch (const std::exception& ex) {
693 .arg(ex.what());
694 }
695}
696
697void
699 if (!MultiThreadingMgr::instance().getMode()) {
700 return;
701 }
702
703 // Since this function is used as CS callback all exceptions must be
704 // suppressed, unlikely though they may be.
705 try {
706 if (thread_pool_) {
707 thread_pool_->run();
708 }
709
710 // Restore the expiration timer.
712 } catch (const std::exception& ex) {
714 .arg(ex.what());
715 }
716}
717
718void
721
722 // Cancel the expiration timer.
724
725 if (thread_pool_) {
726 thread_pool_->pause();
727 }
728
729 if (channel_) {
730 channel_->close();
731 }
732
733 if (thread_pool_) {
734 // Remove critical section callbacks.
736
737 // Stop the thread pool.
738 thread_pool_->stop();
739
740 thread_pool_->getIOService()->stopAndPoll();
741
742 // Ditch the thread_pool
743 thread_pool_.reset();
744 }
745 // Ditch the timer. It must be destroyed before the thread pool because in
746 // MT it holds a reference to the pool's IOService.
747 expiration_timer_.reset();
748
749 // Get rid of the channel.
750 channel_.reset();
751
752 if (io_service_) {
753 io_service_->stopAndPoll();
754 }
755
757}
758
759bool
761 // In ST mode, running is an open channel.
762 if (!MultiThreadingMgr::instance().getMode()) {
763 return (channel_ && channel_->isOpen());
764 }
765
766 if (thread_pool_) {
767 return (thread_pool_->isRunning());
768 }
769
770 return (false);
771}
772
773bool
775 // In ST mode, stopped equates to no channel.
776 if (!MultiThreadingMgr::instance().getMode()) {
777 return (!channel_);
778 }
779
780 if (thread_pool_) {
781 return (thread_pool_->isStopped());
782 }
783
784 return (true);
785}
786
787bool
789 if (thread_pool_) {
790 return (thread_pool_->isPaused());
791 }
792
793 return (false);
794}
795
796void
797PingCheckMgr::flush(bool finish_free /* = false */) {
798 if (!store_) {
799 return;
800 }
801
802 // Fetch them all.
803 auto contexts = store_->getAll();
804 for (auto const& context : *contexts) {
805 if (finish_free) {
806 finishFree(context);
807 } else {
808 auto parking_lot = context->getParkingLot();
809 if (parking_lot) {
810 parking_lot->drop(context->getQuery());
811 }
812 }
813 }
814
815 store_->clear();
816}
817
818} // end of namespace ping_check
819} // end of namespace isc
CalloutNextStep
Specifies allowed next steps.
@ map
Definition data.h:160
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:32
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 StatsMgr & instance()
Statistics Manager accessor method.
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.
void addValue(const std::string &name, const int64_t value)
Records incremental integer observation.
#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:30
boost::shared_ptr< Pkt4 > Pkt4Ptr
A pointer to Pkt4 object.
Definition pkt4.h:556
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:843
boost::shared_ptr< Lease4 > Lease4Ptr
Pointer to a Lease4 structure.
Definition lease.h:317
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:29
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.