1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
// Copyright (C) 2015-2022 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef CFG_EXPIRATION_H
#define CFG_EXPIRATION_H

#include <asiolink/interval_timer.h>
#include <cc/cfg_to_element.h>
#include <dhcpsrv/timer_mgr.h>
#include <boost/shared_ptr.hpp><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <functional><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <stdint.h><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <string><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.

namespace isc {
namespace dhcp {

/// @brief Holds configuration parameters pertaining to lease expiration
/// and lease affinity.
///
/// This class holds the values of the following configuration parameters:
///
/// - reclaim-timer-wait-time - is the time between two cycles of processing
///   expired leases, expressed in seconds, i.e. the time between the end of
///   one cycle and the beginning of the next cycle. If this value is 0, the
///   expired leases are not processed.
///
/// - flush-reclaimed-timer-wait-time - is the time between two cycles of
///   recycling "expired-reclaimed" leases, expressed in seconds. If this
///   value is 0, the expired leases are removed by the leases reclamation
///   routine rather than recycling function. The recycling function is not
///   executed and the value of the "hold-reclaimed-time" is ignored.
///
/// - hold-reclaimed-time -is the time for which "expired-reclaimed" leases
///   are held in the lease database in the "expired-reclaimed" state after
///   they expire. If this time is set to 0, the recycling function is not
///   executed and the value of the "recycle-timer-wait-time" is ignored.
///   This value is expressed in seconds.
///
/// - max-reclaim-leases - is the maximum number of leases to be processed
///   in a single cycle. If this value is 0, all expired leases are
///   processed in a single cycle, unless the maximum processing time
///   (configured with the "max-time") parameter elapses first.
///
/// - max-reclaim-time - the maximum time that a single processing cycle
///   may last, expressed in milliseconds. If this value is 0, there is no
///   limitation for the maximum processing time. This value is expressed
///   in milliseconds.
///
/// - unwarned-reclaim-cycles - is the number of consecutive processing
///   cycles of expired leases, after which the system issues a warning if
///   there are still expired leases in the database. If this value is 0,
///   the warning is never issued.
///
/// The @c CfgExpiration class provides a collection of accessors and
/// modifiers to manage the data. Each accessor checks if the given value
/// is in range allowed for this value.
class CfgExpiration : public isc::data::CfgToElement {
public:

    /// @name Default values.
    ///@{
    ///
    /// @brief Default value for reclaim-timer-wait-time.
    static const uint16_t DEFAULT_RECLAIM_TIMER_WAIT_TIME;

    /// @brief Default value for flush-reclaimed-timer-wait-time.
    static const uint16_t DEFAULT_FLUSH_RECLAIMED_TIMER_WAIT_TIME;

    /// @brief Default value for hold-reclaimed-time.
    static const uint32_t DEFAULT_HOLD_RECLAIMED_TIME;

    /// @brief Default value for max-reclaim-leases.
    static const uint32_t DEFAULT_MAX_RECLAIM_LEASES;

    /// @brief Default value for max-reclaim-time.
    static const uint16_t DEFAULT_MAX_RECLAIM_TIME;

    /// @brief Default value for unwarned-reclaim-cycles.
    static const uint16_t DEFAULT_UNWARNED_RECLAIM_CYCLES;

    ///@}

    /// @name Upper limits for the parameters
    ///@{
    ///
    /// @brief Maximum value for reclaim-timer-wait-time.
    static const uint16_t LIMIT_RECLAIM_TIMER_WAIT_TIME;

    /// @brief Maximum value for flush-reclaimed-timer-wait-time.
    static const uint16_t LIMIT_FLUSH_RECLAIMED_TIMER_WAIT_TIME;

    /// @brief Maximum value for hold-reclaimed-time.
    static const uint32_t LIMIT_HOLD_RECLAIMED_TIME;

    /// @brief Maximum value for max-reclaim-leases.
    static const uint32_t LIMIT_MAX_RECLAIM_LEASES;

    /// @brief Default value for max-reclaim-time.
    static const uint16_t LIMIT_MAX_RECLAIM_TIME;

    /// @brief Maximum value for unwarned-reclaim-cycles.
    static const uint16_t LIMIT_UNWARNED_RECLAIM_CYCLES;

    ///@}

    /// @name Timers' names
    ///@{

    /// @brief Name of the timer for reclaiming expired leases.
    static const std::string RECLAIM_EXPIRED_TIMER_NAME;

    /// @brief Name of the timer for flushing reclaimed leases.
    static const std::string FLUSH_RECLAIMED_TIMER_NAME;

    ///@}

    /// @brief Constructor.
    ///
    /// Sets all parameters to their defaults.
    ///
    /// @param test_mode Indicates if the instance should be created in the
    /// test mode. In this mode the intervals for the timers are considered to
    /// be specified in milliseconds, rather than seconds. This facilitates
    /// testing execution of timers without the delays.
    CfgExpiration(const bool test_mode = false);

    /// @brief Returns reclaim-timer-wait-time
    uint16_t getReclaimTimerWaitTime() const {
        return (reclaim_timer_wait_time_);
    }

    /// @brief Sets reclaim-timer-wait-time
    ///
    /// @param reclaim_timer_wait_time New value.
    void setReclaimTimerWaitTime(const int64_t reclaim_timer_wait_time);

    /// @brief Returns flush-reclaimed-timer-wait-time.
    uint16_t getFlushReclaimedTimerWaitTime() const {
        return (flush_reclaimed_timer_wait_time_);
    }

    /// @brief Sets flush-reclaimed-timer-wait-time.
    ///
    /// @param flush_reclaimed_wait_time New value.
    void setFlushReclaimedTimerWaitTime(const int64_t flush_reclaimed_wait_time);

    /// @brief Returns hold-reclaimed-time.
    uint32_t getHoldReclaimedTime() const {
        return (hold_reclaimed_time_);
    }

    /// @brief Sets hold-reclaimed-time
    ///
    /// @param hold_reclaimed_time New value.
    void setHoldReclaimedTime(const int64_t hold_reclaimed_time);

    /// @brief Returns max-reclaim-leases.
    uint32_t getMaxReclaimLeases() const {
        return (max_reclaim_leases_);
    }

    /// @brief Sets max-reclaim-leases.
    ///
    /// @param max_reclaim_leases New value.
    void setMaxReclaimLeases(const int64_t max_reclaim_leases);

    /// @brief Returns max-reclaim-time.
    uint16_t getMaxReclaimTime() const {
        return (max_reclaim_time_);
    }

    /// @brief Sets max-reclaim-time.
    ///
    /// @param max_reclaim_time New value.
    void setMaxReclaimTime(const int64_t max_reclaim_time);

    /// @brief Returns unwarned-reclaim-cycles.
    uint16_t getUnwarnedReclaimCycles() const {
        return (unwarned_reclaim_cycles_);
    }

    /// @brief Sets unwarned-reclaim-cycles.
    ///
    /// @param unwarned_reclaim_cycles New value.
    void setUnwarnedReclaimCycles(const int64_t unwarned_reclaim_cycles);

    /// @brief Setup timers for the reclamation of expired leases according
    /// to the configuration parameters.
    ///
    /// This method includes the logic for setting the interval timers
    /// performing the reclamation of the expired leases and the removal
    /// of expired-reclaimed leases.
    ///
    /// The following is the sample code illustrating how to call this function
    /// to setup the leases reclamation for the DHCPv4 server.
    /// @code
    ///     CfgExpiration cfg;
    ///
    ///     (set some cfg values here)
    ///
    ///     AllocEnginePtr alloc_engine(new AllocEngine(...));
    ///     cfg.setupTimers(&AllocEngine::reclaimExpiredLeases4,
    ///                     &AllocEngine::deleteExpiredReclaimedLeases4,
    ///                     alloc_engine.get());
    /// @endcode
    ///
    /// @param reclaim_fun Pointer to the leases reclamation routine.
    /// @param delete_fun Pointer to the function which removes the
    /// expired-reclaimed leases from the lease database.
    /// @param instance_ptr Pointer to the instance of the object which
    /// implements the lease reclamation routine. Typically it will be
    /// the pointer to the @c AllocEngine. In case of unit tests it
    /// will be a pointer to some test class which provides stub
    /// implementation of the leases reclamation routines.
    /// @tparam Instance Instance of the object in which both functions
    /// are implemented.
    template<typename Instance>
    void setupTimers(void (Instance::*reclaim_fun)(const size_t, const uint16_t,
                                                   const bool, const uint16_t),
                     void (Instance::*delete_fun)(const uint32_t),
                     Instance* instance_ptr) const;

    /// @brief Unparse a configuration object
    ///
    /// @return a pointer to unparsed configuration
    virtual isc::data::ElementPtr toElement() const;<--- Function in derived class

private:

    /// @brief Checks if the value being set by one of the modifiers is
    /// within an allowed range.
    ///
    /// @param value Value to be checked.
    /// @param max_value Maximum allowed value.
    /// @param config_parameter_name A name of the configuration parameter
    /// (used for logging purposes if value is out of range).
    ///
    /// @throw isc::OutOfRange if the value is negative or greater than
    /// the maximum value.
    void rangeCheck(const int64_t value, const uint64_t max_value,
                    const std::string& config_parameter_name) const;

    /// @brief reclaim-timer-wait-time
    uint16_t reclaim_timer_wait_time_;

    /// @brief flush-reclaimed-timer-wait-time
    uint16_t flush_reclaimed_timer_wait_time_;

    /// @brief hold-reclaimed-time
    uint32_t hold_reclaimed_time_;

    /// @brief max-reclaim-leases
    uint32_t max_reclaim_leases_;

    /// @brief max-reclaim-time
    uint16_t max_reclaim_time_;

    /// @brief unwarned-reclaim-cycles.
    uint16_t unwarned_reclaim_cycles_;

    /// @brief Pointer to the instance of the Timer Manager.
    TimerMgrPtr timer_mgr_;

    /// @brief Indicates if the instance is in the test mode.
    bool test_mode_;
};

/// @name Pointers to the @c CfgExpiration objects.
///@{
/// @brief Pointer to the Non-const object.
typedef boost::shared_ptr<CfgExpiration> CfgExpirationPtr;

/// @brief Pointer to the const object.
typedef boost::shared_ptr<const CfgExpiration> ConstCfgExpirationPtr;

///@}

template<typename Instance>
void
CfgExpiration::setupTimers(void (Instance::*reclaim_fun)(const size_t,
                                                         const uint16_t,
                                                         const bool,
                                                         const uint16_t),
                           void (Instance::*delete_fun)(const uint32_t),
                           Instance* instance_ptr) const {
    // One of the parameters passed to the leases' reclamation routine
    // is a boolean value which indicates if reclaimed leases should
    // be removed by the leases' reclamation routine. This is the case
    // when the timer for flushing reclaimed leases is set to 0
    // (disabled).
    const bool flush_timer_disabled = (getFlushReclaimedTimerWaitTime() == 0);

    // If the timer interval for the leases reclamation is non-zero
    // the timer will be scheduled.
    if (getReclaimTimerWaitTime() > 0) {
        // In the test mode the interval is expressed in milliseconds.
        // If this is not the test mode, the interval is in seconds.
        const long reclaim_interval = test_mode_ ? getReclaimTimerWaitTime() :
            1000 * getReclaimTimerWaitTime();
        // Register timer for leases' reclamation routine.
        timer_mgr_->registerTimer(RECLAIM_EXPIRED_TIMER_NAME,
                                  std::bind(reclaim_fun, instance_ptr,
                                            getMaxReclaimLeases(),
                                            getMaxReclaimTime(),
                                            flush_timer_disabled,
                                            getUnwarnedReclaimCycles()),
                                  reclaim_interval,
                                  asiolink::IntervalTimer::ONE_SHOT);
        timer_mgr_->setup(RECLAIM_EXPIRED_TIMER_NAME);
    }

    // If the interval for the timer flushing expired-reclaimed leases
    // is set we will schedule the timer.
    if (!flush_timer_disabled) {
        // The interval is specified in milliseconds if we're in the test mode.
        // It is specified in seconds otherwise.
        const long flush_interval = test_mode_ ?
            getFlushReclaimedTimerWaitTime() :
            1000 * getFlushReclaimedTimerWaitTime();
        // Register and setup the timer.
        timer_mgr_->registerTimer(FLUSH_RECLAIMED_TIMER_NAME,
                                  std::bind(delete_fun, instance_ptr,
                                            getHoldReclaimedTime()),
                                  flush_interval,
                                  asiolink::IntervalTimer::ONE_SHOT);
        timer_mgr_->setup(FLUSH_RECLAIMED_TIMER_NAME);
    }
}


} // end of isc::dhcp namespace
} // end of isc namespace

#endif // CFG_EXPIRATION_H