7#ifndef ISC_LIMITS_RATE_LIMIT_MANAGER_H 
    8#define ISC_LIMITS_RATE_LIMIT_MANAGER_H 
   25#include <boost/circular_buffer.hpp> 
   28#include <unordered_map> 
   35using TimePoint = std::chrono::time_point<std::chrono::system_clock>;
 
   92    template <isc::util::DhcpSpace D>
 
  101        handle.
getArgument(
"audit_entries", audit_entries);
 
  102        if (!audit_entries) {
 
  107        auto const& client_class_range(object_type_index.equal_range(
 
  109        auto const& subnet_range(object_type_index.equal_range(
 
  113        if (std::distance(client_class_range.first, client_class_range.second) ||
 
  114            std::distance(subnet_range.first, subnet_range.second)) {
 
 
  129    template <isc::util::DhcpSpace D>
 
  140                const std::string 
error(
"The lease database you have configured " 
  141                    "does not support JSON operations which are required for lease " 
  149            recountClassLeases<D>();
 
  154                                                         ->getLeaseDbAccessString());
 
  155            if (lease_db_access_string.find(
"retry-on-startup=true") &&
 
  156                (lease_db_access_string.find(
"type=mysql") ||
 
  157                 lease_db_access_string.find(
"type=postgresql"))) {
 
 
  178    template <isc::util::DhcpSpace D>
 
  192        auto const& classes(packet->getClasses());
 
  197        auto const& relations = packet->getSubClassesRelations();
 
  200        TimePoint const now(std::chrono::system_clock::now());
 
  203        std::vector<isc::dhcp::ClientClass> common_client_classes;
 
  212        for (
auto const& c : relations) {
 
  218            auto const &limit_cfg = rate_limit_configuration_.parseUserContext(class_def->getContext());
 
  225            RateLimit const& limit(limit_cfg->stringValue());
 
  228            TimeSeries& time_series(clocked_in_times_by_class_[c.class_]);
 
  233            while (!time_series.empty()) {
 
  234                if (time_series.back() + limit.
time_unit_ < now) {
 
  235                    time_series.pop_back();
 
  250                    .arg(classes.toText())
 
  262            common_client_classes.push_back(c.class_);
 
  267            for (
auto const& c : common_client_classes) {
 
  268                TimeSeries& time_series(clocked_in_times_by_class_.at(c));
 
  269                time_series.push_front(now);
 
  273            if (!common_client_classes.empty()) {
 
  276                    .arg(classes.toText());
 
 
  295    template <isc::util::DhcpSpace D>
 
  314        auto const& limit_cfg = subnetRateLimit<D>(subnet_id);
 
  317            limit = 
RateLimit(limit_cfg->stringValue());
 
  330            if (!time_series_ref) {
 
  331                time_series_ref = std::make_shared<ProtectedTimeSeries>();
 
  333            time_series = time_series_ref;
 
  337        TimePoint const now(std::chrono::system_clock::now());
 
  345        while (!time_series->time_points_.empty()) {
 
  346            if (time_series->time_points_.back() + limit.
time_unit_ < now) {
 
  347                time_series->time_points_.pop_back();
 
  358            time_series->time_points_.push_front(now);
 
 
  394    template <isc::util::DhcpSpace D>
 
  416        auto const& classes(packet->getClasses());
 
  419        addClientClassesToLeaseContext(classes, lease);
 
  429        auto const& relations(packet->getSubClassesRelations());
 
  433        isc::data::ElementPtr client_class_limits = clientClassLimitsToElement<D>(relations, lease->getType());
 
  439        if (!client_class_limits->empty()) {
 
  440            limits->set(
"client-classes", client_class_limits);
 
  442        if (!subnet_limit->empty()) {
 
  443            limits->set(
"subnet", subnet_limit);
 
  451        ISC->set(
"limits", 
limits);
 
  453        context->set(
"ISC", ISC);
 
  456        std::string 
const limit_exceeded_text(checkLeaseLimits<D>(context));
 
  457        if (limit_exceeded_text.empty()) {
 
  465                .arg(limit_exceeded_text);
 
 
  490    template <isc::util::DhcpSpace D>
 
  504    template <isc::util::DhcpSpace D>
 
  515    template <isc::util::DhcpSpace D>
 
  529    template <isc::util::DhcpSpace D>
 
  535    template <isc::util::DhcpSpace D>
 
  536    void recountClassLeases() 
const;
 
  540    std::unordered_map<isc::dhcp::ClientClass, TimeSeries> clocked_in_times_by_class_;
 
  544    std::unordered_map<isc::dhcp::SubnetID, ProtectedTimeSeriesPtr> clocked_in_times_by_subnet_id_;
 
 
Defines elements for storing the names of client classes.
A generic exception that is thrown when an unexpected error condition occurs.
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
static CfgMgr & instance()
returns a single instance of Configuration Manager
SrvConfigPtr getCurrentCfg()
Returns a pointer to the current configuration.
Container for storing client class names.
static TrackingLeaseMgr & instance()
Return current lease manager.
static bool haveInstance()
Indicates if the lease manager has been instantiated.
Per-packet callout handle.
CalloutNextStep
Specifies allowed next steps.
@ NEXT_STEP_DROP
drop the packet
@ NEXT_STEP_SKIP
skip the next processing step
CalloutNextStep getStatus() const
Returns the next processing step.
void setStatus(const CalloutNextStep next)
Sets the next processing step.
void getArgument(const std::string &name, T &value) const
Get argument.
void setArgument(const std::string &name, T value)
Set argument.
#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_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
boost::shared_ptr< const Element > ConstElementPtr
boost::shared_ptr< Element > ElementPtr
boost::shared_ptr< AuditEntryCollection > AuditEntryCollectionPtr
boost::shared_ptr< PktT< D > > PktTPtr
boost::shared_ptr< LeaseT< D > > LeaseTPtr
boost::shared_ptr< SrvConfig > SrvConfigPtr
Non-const pointer to the SrvConfig.
boost::shared_ptr< const SubnetT< D > > ConstSubnetTPtr
boost::multi_index_container< SubClassRelation, boost::multi_index::indexed_by< boost::multi_index::sequenced< boost::multi_index::tag< TemplateClassSequenceTag > >, boost::multi_index::hashed_unique< boost::multi_index::tag< TemplateClassNameTag >, boost::multi_index::member< SubClassRelation, ClientClass, &SubClassRelation::class_def_ > > > > SubClassRelationContainer
the subclass multi-index.
uint32_t SubnetID
Defines unique IPv4 or IPv6 subnet identifier.
boost::shared_ptr< Lease > LeasePtr
Pointer to the lease object.
std::shared_ptr< ProtectedTimeSeries > ProtectedTimeSeriesPtr
Defines a smart pointer to a ProtectedTimeSeries.
const isc::log::MessageID LIMITS_CONFIGURATION_LEASE_BACKEND_NOT_AVAILABLE
std::chrono::time_point< std::chrono::system_clock > TimePoint
a point in time
const isc::log::MessageID LIMITS_PACKET_WITH_SUBNET_ID_RATE_LIMIT_HONORED
const isc::log::MessageID LIMITS_LEASE_LIMIT_EXCEEDED
const isc::log::MessageID LIMITS_PACKET_WITH_SUBNET_ID_RATE_LIMIT_DROPPED
const isc::log::MessageID LIMITS_LEASE_WITHIN_LIMITS
boost::circular_buffer< TimePoint > TimeSeries
Holds a number of time points, used in limiting by a single criterion.
const isc::log::MessageID LIMITS_PACKET_WITH_CLIENT_CLASSES_RATE_LIMIT_DROPPED
const isc::log::MessageID LIMITS_PACKET_WIIH_SUBNET_ID_RATE_NO_SUBNET
const isc::log::MessageID LIMITS_CONFIGURATION_LEASE_BACKEND_SHOULD_HAVE_BEEN_AVAILABLE
const isc::log::MessageID LIMITS_PACKET_WITH_CLIENT_CLASSES_RATE_LIMIT_HONORED
isc::log::Logger limits_logger("limits-hooks")
const int DBGLVL_TRACE_BASIC
Trace basic operations.
const int DBGLVL_TRACE_DETAIL_DATA
Trace data associated with detailed operations.
std::string formatDhcpSpace(char const *const format_string)
Replaces all occurrences of {} with 4 or 6 based on the templated DHCP space.
Defines the logger used by the top-level component of kea-lfc.
Tag used to access index by object type.
Type
Type of lease or pool.
the configuration manager for address limiting
Provides the capability to limit the number of leases or the response rate.
int cb_updated(isc::hooks::CalloutHandle &handle)
cbX_updated hook point
int dhcp_srv_configured(isc::hooks::CalloutHandle &handle)
dhcpX_srv_configured hook point
int subnet_select(isc::hooks::CalloutHandle &handle)
subnetX_select hook point
int pkt_receive(isc::hooks::CalloutHandle &handle)
pktX_receive hook point
void parse(isc::dhcp::SrvConfigPtr const &config)
Fetches limits from the given Kea configuration.
int lease_callout(isc::hooks::CalloutHandle &handle, bool lease_update=false)
leaseX_select hook point
void clear()
Clears the time series circular buffers in order to start over rate limiting.
void initialize(isc::dhcp::SrvConfigPtr const &config)
Reinitialize data structures required for limiting.
static LimitManager & instance()
singleton access function
the configuration manager for prefix limiting
Holds a number of time points, used in limiting by a single criterion, and a mutex to protect concurr...
std::mutex mutex_
Protects against races on the time points which can be edited at each hook callout.
TimeSeries time_points_
Holds the actual time points.
the configuration manager for rate limiting
a single rate-limiting entry configured as "rate-limit": "<n> packet[s] per <time-unit>"
std::string text_
a string representation of the rate limit as specified in the configuration used for logging purposes
std::chrono::seconds time_unit_
Seconds of one time unit's worth.
uint32_t allowed_packets_
the configured limit
RAII lock object to protect the code in the same scope with a mutex.