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