24#include <sys/resource.h>
43class ExchangeLimitInit {
48 memset(&rlimit, 0,
sizeof(rlimit));
49 if (getrlimit(RLIMIT_NOFILE, &rlimit) == 0) {
58ExchangeLimitInit init;
62 : io_service_(io_service), thread_pool_size_(thread_pool_size) {
64 if (thread_pool_size == 0) {
69 thread_io_service_.reset(
new IOService());
71 boost::make_shared<IoServiceThreadPool>(thread_io_service_,
77 [
this]() {
pause(); },
87 return (thread_pool_size_);
92 return (thread_io_service_);
101 .arg(thread_pool_size_);
109 thread_pool_->stop();
110 for (
auto const& exchange : exchange_list_) {
111 exchange->shutdown();
113 thread_pool_->getIOService()->stopAndPoll();
114 thread_pool_.reset();
116 for (
auto const& exchange : exchange_list_) {
117 exchange->shutdown();
119 io_service_->stopAndPoll();
121 exchange_list_.clear();
130 thread_pool_->checkPausePermissions();
138 }
catch (
const exception& ex) {
151 thread_pool_->pause();
153 }
catch (
const exception& ex) {
167 }
catch (
const exception& ex) {
176 exchange_list_.push_back(exchange);
182 exchange_list_.remove(exchange);
215 io_context_(new
IOService()), io_service_(io_context_) {
221 }
catch(exception
const& exception) {
223 .arg(exception.what());
298 io_service_ = io_context_;
303 std::unique_ptr<void, void(*)(
void*)> p(
static_cast<void*
>(
this), [](
void*) {
RadiusImpl::shutdown_ =
false; });
315 if (
auth_->enabled_) {
327 if (
acct_->enabled_) {
337 bool multi_threaded(
false);
338 unsigned thread_pool_size(0);
339 uint32_t dhcp_threads(0);
340 uint32_t dummy_queue_size(0);
344 if (multi_threaded) {
348 if (dhcp_threads == 0) {
349 uint32_t
const hardware_threads(
351 if (hardware_threads == 0) {
353 multi_threaded =
false;
354 thread_pool_size = 0;
356 thread_pool_size = hardware_threads;
359 thread_pool_size = dhcp_threads;
366 if (multi_threaded) {
370 io_service_->post([
this, thread_pool_size]() {
379 io_service_->post([
this, multi_threaded, thread_pool_size]() {
430 return (
auth_->servers_);
432 return (
tls_->servers_);
439 return (
acct_->servers_);
441 return (
tls_->servers_);
451 auth_->setIdleTimer();
453 tls_->setIdleTimer();
463 acct_->setIdleTimer();
465 tls_->setIdleTimer();
482 if (!subnet_hr_global.unspecified() && !subnet_hr_subnet.unspecified()) {
483 return (subnet_hr_global && !subnet_hr_subnet);
485 if (!subnet_hr_global.unspecified() || !subnet_hr_subnet.unspecified()) {
490 if (!network_hr_global.unspecified() && !network_hr_subnet.unspecified()) {
491 return (network_hr_global && !network_hr_subnet);
493 if (!network_hr_global.unspecified() || !network_hr_subnet.unspecified()) {
498 getConfiguredGlobal(
"reservations-global");
500 if (!global_hr_mode_elem) {
504 getConfiguredGlobal(
"reservations-in-subnet");
506 if (!subnet_hr_mode_elem) {
510 isc_throw(Unexpected,
"'reservations-global' global value must be a boolean");
512 if (!global_hr_mode_elem->boolValue()) {
516 isc_throw(Unexpected,
"'reservations-in-subnet' global value must be a boolean");
518 if (subnet_hr_mode_elem->boolValue()) {
529 if (flag && (flag->boolValue())) {
531 "compatible with RADIUS");
536 bool need_disable_single_query =
false;
539 getCfgSharedNetworks4()->getAll();
540 if (networks->empty()) {
543 need_disable_single_query =
true;
544 for (
auto const& network : *networks) {
545 auto subnets = network->getAllSubnets();
546 if (subnets->size() <= 1) {
549 for (
auto const& subnet : *subnets) {
550 if (!isHostReservationModeGlobal(subnet, network)) {
552 <<
" '" << subnet->toText() <<
"' of shared "
553 <<
"network " << network->getName()
554 <<
" does not use only global host reservations "
555 <<
"which are required for subnets in "
556 <<
"shared networks by RADIUS");
562 getCfgSharedNetworks6()->getAll();
563 if (networks->empty()) {
566 need_disable_single_query =
true;
567 for (
auto const& network : *networks) {
568 auto subnets = network->getAllSubnets();
569 if (subnets->size() <= 1) {
572 for (
auto const& subnet : *subnets) {
573 if (!isHostReservationModeGlobal(subnet, network)) {
575 <<
" '" << subnet->toText() <<
"' of shared "
576 <<
"network " << network->getName()
577 <<
" does not use only global host reservations "
578 <<
"which are required for subnets in "
579 <<
"shared networks by RADIUS");
584 if (need_disable_single_query) {
594 static bool already_tried =
false;
598 already_tried =
true;
607 }
catch (
const std::exception& ex) {
615 cache_ = boost::dynamic_pointer_cast<CacheHostDataSource>(cache);
636 result->set(
"canonical-mac-address",
652 result->set(
"identifier-type4",
656 result->set(
"identifier-type6",
660 result->set(
"reselect-subnet-address",
664 result->set(
"reselect-subnet-pool",
680 result->set(
"use-message-authenticator",
685 result->set(
"tls",
tls_->toElement());
687 result->set(
"access",
auth_->toElement());
688 result->set(
"accounting",
acct_->toElement());
693 for (
auto const& item :
remap_) {
695 if (item.first != 0) {
696 entry->set(
"subnet-id",
703 result->set(
"nas-ports", ports);
709unordered_set<thread::id> InHook::set_;
714 const auto&
id = this_thread::get_id();
716 auto ret = set_.insert(
id);
718 std::cerr <<
"InHook insert error on " <<
id <<
"\n";
723 const auto&
id = this_thread::get_id();
725 size_t ret = set_.erase(
id);
727 std::cerr <<
"InHook erase error on " <<
id <<
"\n";
732 const auto&
id = this_thread::get_id();
734 size_t ret = set_.count(
id);
static ElementPtr create(const Position &pos=ZERO_POSITION())
Create a NullElement.
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
An exception that is thrown if an error occurs while configuring any server.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
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.
The IOService class is a wrapper for the ASIO io_context class.
std::map< std::string, std::string > ParameterMap
Database configuration parameter map.
@ EARLY_GLOBAL_RESERVATIONS_LOOKUP
static CfgMgr & instance()
returns a single instance of Configuration Manager
SrvConfigPtr getStagingCfg()
Returns a pointer to the staging configuration.
static void extract(data::ConstElementPtr value, bool &enabled, uint32_t &thread_count, uint32_t &queue_size)
Extract multi-threading parameters from a given configuration.
static bool deregisterFactory(const std::string &db_type, bool no_log=false)
Deregister a host data source factory.
static bool registerFactory(const std::string &db_type, const Factory &factory, bool no_log=false, DBVersion db_version=DBVersion())
Register a host data source factory.
static bool registeredFactory(const std::string &db_type)
Check if a host data source factory was registered.
void setDisableSingleQuery(bool disable_single_query)
Sets the disable single query flag.
static bool delBackend(const std::string &db_type)
Delete an alternate host backend (aka host data source).
static void addBackend(const std::string &access)
Add an alternate host backend (aka host data source).
HostDataSourcePtr getHostDataSource() const
Returns the first host data source.
static HostMgr & instance()
Returns a sole instance of the HostMgr.
Represents a device with IPv4 and/or IPv6 reservations.
static std::string getIdentifierName(const IdentifierType &type)
Returns name of the identifier of a specified type.
static bool check()
Check if the current thread is in hook code or not.
Configuration parser for Radius.
void parse(data::ElementPtr &config)
Parses Radius configuration.
Radius hooks library implementation.
static std::atomic< bool > shutdown_
Flag which indicates that the instance is shutting down.
unsigned thread_pool_size_
Thread pool size.
void checkSharedNetworks()
Check shared network server configuration.
std::string dictionary_
Dictionary path.
bool checkHostBackends()
Check host backends (cache and radius).
RadiusImpl()
Protected constructor.
boost::shared_ptr< RadiusTls > tls_
Pointer to tls (never null).
dhcp::CacheHostDataSourcePtr cache_
Host cache.
std::string bindaddr_
bindaddr.
bool clientid_pop0_
Client Id pop leading zero(s).
isc::asiolink::IOServicePtr getIOContext()
Get the hook I/O service.
void setAccountingIdleTimer()
Set the accounting idle timer.
const Servers & getAccessServers() const
Get servers for access.
dhcp::Host::IdentifierType id_type4_
Identifier type for IPv4.
void reset()
Reset the state as it was just created.
void unregisterExchange(ExchangePtr exchange)
Unregister Exchange.
bool reselect_subnet_address_
Reselect subnet using address.
void init(data::ElementPtr &config)
Initialize.
void registerExchange(ExchangePtr exchange)
Register Exchange.
boost::shared_ptr< RadiusAccess > auth_
Pointer to access (never null).
bool extract_duid_
Extract Duid from Client Id.
void startServices()
Start the I/O mechanisms.
unsigned timeout_
Timeout.
dhcp::Host::IdentifierType id_type6_
Identifier type for IPv6.
bool canonical_mac_address_
Canonical MAC address.
unsigned deadtime_
Deadtime.
bool serveAccounting() const
Check if accounting is served.
RadiusBackendPtr backend_
Radius backend.
boost::shared_ptr< RadiusAccounting > acct_
Pointer to accounting (never null).
void cleanup()
Clean up members.
data::ElementPtr toElement() const override
Unparse implementation configuration.
bool checkExchangeListRoom()
Check Exchange List Room.
unsigned retries_
Retries.
std::map< uint32_t, uint32_t > remap_
Subnet ID to NAS port map.
UdpClientPtr udp_client_
UDP client.
static const RadiusImplPtr & instancePtr()
Returns pointer to the sole instance of radius implementation.
const Servers & getAccountingServers() const
Get servers for accounting.
std::string session_history_filename_
Session history filename.
void setAccessIdleTimer()
Set the access idle timer.
bool reselect_subnet_pool_
Reselect subnet using pool.
isc::tcp::TcpClientPtr tcp_client_
TCP client.
void checkEarlyGlobalResvLookup()
Check the early global host reservations lookup flag.
bool clientid_printable_
Client Id try printable.
RadiusProtocol proto_
Transport protocol.
isc::asiolink::IOServicePtr getIOService()
Get the hook I/O service.
static RadiusImpl & instance()
RadiusImpl is a singleton class.
bool serveAccess() const
Check if access is served.
bool use_message_authenticator_
Use Message-Authenticator attribute.
Radius service for TLS transport.
void registerExchange(ExchangePtr exchange)
Register Exchange.
void unregisterExchange(ExchangePtr exchange)
Unregister Exchange.
const asiolink::IOServicePtr getThreadIOService() const
Fetches a pointer to the internal IOService used to drive the thread-pool in multi-threaded mode.
void checkPermissions()
Check if the current thread can perform thread pool state transition.
void resume()
Resumes running the client's thread pool.
void stop()
Halts client-side IO activity.
static size_t exchangeListMaxSize
Exchange List Maximum Size (currently the max(200,soft_limit/2)).
UdpClient(const asiolink::IOServicePtr &io_service, unsigned thread_pool_size=0)
Constructor.
void pause()
Pauses the client's thread pool.
void start()
Starts running the client's thread pool, if multi-threaded.
bool checkExchangeListRoom()
Check Exchange List Room.
unsigned getThreadPoolSize() const
Fetches the maximum size of the thread pool.
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.
static uint32_t detectThreadCount()
The system current detected hardware concurrency thread count.
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.
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
boost::shared_ptr< IOService > IOServicePtr
Defines a smart pointer to an IOService instance.
boost::shared_ptr< const Element > ConstElementPtr
boost::shared_ptr< Element > ElementPtr
boost::shared_ptr< BaseHostDataSource > HostDataSourcePtr
HostDataSource pointer.
boost::shared_ptr< Subnet > SubnetPtr
A generic pointer to either Subnet4 or Subnet6 object.
boost::shared_ptr< Network > NetworkPtr
Pointer to the Network object.
const isc::log::MessageID RADIUS_ACCESS_HOST_BACKEND_ERROR
const isc::log::MessageID RADIUS_RESUME_FAILED
boost::shared_ptr< RadiusImpl > RadiusImplPtr
std::vector< ServerPtr > Servers
Type of RADIUS server collection.
boost::shared_ptr< Exchange > ExchangePtr
Type of shared pointers to RADIUS exchange object.
const isc::log::MessageID RADIUS_CLEANUP_EXCEPTION
string protocolToText(const int proto)
Transport protocol to text.
const isc::log::MessageID RADIUS_PAUSE_FAILED
const isc::log::MessageID RADIUS_ACCESS_NO_HOST_CACHE
isc::log::Logger radius_logger("radius-hooks")
Radius Logger.
const isc::log::MessageID RADIUS_THREAD_POOL_STARTED
const isc::log::MessageID RADIUS_PAUSE_ILLEGAL
const isc::log::MessageID RADIUS_PAUSE_PERMISSIONS_FAILED
Defines the logger used by the top-level component of kea-lfc.
RAII lock object to protect the code in the same scope with a mutex.