Coverage Report

Created: 2026-06-30 07:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/kea/src/lib/dhcpsrv/lease_mgr.h
Line
Count
Source
1
// Copyright (C) 2012-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
#ifndef LEASE_MGR_H
8
#define LEASE_MGR_H
9
10
#include <asiolink/io_address.h>
11
#include <asiolink/io_service.h>
12
#include <cc/data.h>
13
#include <database/database_connection.h>
14
#include <database/db_exceptions.h>
15
#include <dhcp/duid.h>
16
#include <dhcp/option.h>
17
#include <dhcp/hwaddr.h>
18
#include <dhcpsrv/cfg_consistency.h>
19
#include <dhcpsrv/lease.h>
20
#include <dhcpsrv/subnet.h>
21
22
#include <boost/noncopyable.hpp>
23
#include <boost/shared_ptr.hpp>
24
25
#include <fstream>
26
#include <iostream>
27
#include <map>
28
#include <string>
29
#include <utility>
30
#include <vector>
31
32
/// @file lease_mgr.h
33
/// @brief An abstract API for lease database
34
///
35
/// This file contains declarations of Lease4, Lease6 and LeaseMgr classes.
36
/// They are essential components of the interface to any database backend.
37
/// Each concrete database backend (e.g. MySQL) will define a class derived
38
/// from LeaseMgr class.
39
namespace isc {
40
namespace dhcp {
41
42
/// @brief Pair containing major and minor versions
43
typedef std::pair<uint32_t, uint32_t> VersionPair;
44
45
/// @brief Wraps value holding size of the page with leases.
46
class LeasePageSize {
47
public:
48
49
    /// @brief Constructor.
50
    ///
51
    /// @param page_size page size value.
52
    /// @throw OutOfRange if page size is 0 or greater than uint32_t numeric
53
    /// limit.
54
    explicit LeasePageSize(const size_t page_size);
55
56
    const size_t page_size_; ///< Holds page size.
57
};
58
59
/// @brief Contains a single row of lease statistical data
60
///
61
/// The contents of the row consist of a subnet ID, a lease
62
/// type, a lease state, and the number of leases in that state
63
/// for that type for that subnet ID.
64
struct LeaseStatsRow {
65
    /// @brief Default constructor
66
    LeaseStatsRow() :
67
8.97k
        subnet_id_(0), pool_id_(0), lease_type_(Lease::TYPE_NA),
68
8.97k
        lease_state_(Lease::STATE_DEFAULT), state_count_(0) {
69
8.97k
    }
70
71
    /// @brief Constructor
72
    ///
73
    /// Constructor which defaults the type to TYPE_NA.
74
    ///
75
    /// @param subnet_id The subnet id to which this data applies
76
    /// @param lease_state The lease state counted
77
    /// @param state_count The count of leases in the lease state
78
    /// @param pool_id The pool id to which this data applies or 0 if it is not
79
    /// used
80
    LeaseStatsRow(const SubnetID& subnet_id, const uint32_t lease_state,
81
                  const int64_t state_count, uint32_t pool_id = 0)
82
49.2k
        : subnet_id_(subnet_id), pool_id_(pool_id), lease_type_(Lease::TYPE_NA),
83
49.2k
          lease_state_(lease_state), state_count_(state_count) {
84
49.2k
    }
85
86
    /// @brief Constructor
87
    ///
88
    /// @param subnet_id The subnet id to which this data applies
89
    /// @param lease_type The lease type for this state count
90
    /// @param lease_state The lease state counted
91
    /// @param state_count The count of leases in the lease state
92
    /// @param pool_id The pool id to which this data applies or 0 if it is not
93
    /// used
94
    LeaseStatsRow(const SubnetID& subnet_id, const Lease::Type& lease_type,
95
                  const uint32_t lease_state, const int64_t state_count,
96
                  uint32_t pool_id = 0)
97
0
        : subnet_id_(subnet_id), pool_id_(pool_id), lease_type_(lease_type),
98
0
          lease_state_(lease_state), state_count_(state_count) {
99
0
    }
100
101
    /// @brief Less-than operator
102
0
    bool operator<(const LeaseStatsRow &rhs) const {
103
0
        if (subnet_id_ < rhs.subnet_id_) {
104
0
            return (true);
105
0
        }
106
0
107
0
        if (subnet_id_ == rhs.subnet_id_ &&
108
0
            pool_id_ < rhs.pool_id_) {
109
0
            return (true);
110
0
        }
111
0
112
0
        if (subnet_id_ == rhs.subnet_id_ &&
113
0
            pool_id_ == rhs.pool_id_ &&
114
0
            lease_type_ < rhs.lease_type_) {
115
0
            return (true);
116
0
        }
117
0
118
0
        if (subnet_id_ == rhs.subnet_id_ &&
119
0
            pool_id_ == rhs.pool_id_ &&
120
0
            lease_type_ == rhs.lease_type_ &&
121
0
            lease_state_ < rhs.lease_state_) {
122
0
            return (true);
123
0
        }
124
0
125
0
        return (false);
126
0
    }
127
128
    /// @brief The subnet ID to which this data applies
129
    SubnetID subnet_id_;
130
131
    /// @brief The pool ID to which this data applies
132
    uint32_t pool_id_;
133
134
    /// @brief The lease_type to which the count applies
135
    Lease::Type lease_type_;
136
137
    /// @brief The lease_state to which the count applies
138
    uint32_t lease_state_;
139
140
    /// @brief state_count The count of leases in the lease state
141
    int64_t state_count_;
142
};
143
144
/// @brief Base class for fulfilling a statistical lease data query
145
///
146
/// LeaseMgr derivations implement this class such that it provides
147
/// up to date statistical lease data organized as rows of LeaseStatsRow
148
/// instances. The rows must be accessible in ascending order by subnet id.
149
class LeaseStatsQuery {
150
public:
151
    /// @brief Defines the types of selection criteria supported
152
    typedef enum {
153
        ALL_SUBNETS,
154
        SINGLE_SUBNET,
155
        SUBNET_RANGE,
156
        ALL_SUBNET_POOLS
157
    } SelectMode;
158
159
    /// @brief Constructor to query statistics for all subnets
160
    ///
161
    /// The query created will return statistics for all subnets
162
    ///
163
    /// @param select_mode The selection criteria which is either ALL_SUBNETS or
164
    /// ALL_SUBNET_POOLS
165
    LeaseStatsQuery(const SelectMode& select_mode = ALL_SUBNETS);
166
167
    /// @brief Constructor to query for a single subnet's stats
168
    ///
169
    /// The query created will return statistics for a single subnet
170
    ///
171
    /// @param subnet_id id of the subnet for which stats are desired
172
    /// @throw BadValue if subnet_id given is 0.
173
    LeaseStatsQuery(const SubnetID& subnet_id);
174
175
    /// @brief Constructor to query for the stats for a range of subnets
176
    ///
177
    /// The query created will return statistics for the inclusive range of
178
    /// subnets described by first and last subnet IDs.
179
    ///
180
    /// @param first_subnet_id first subnet in the range of subnets
181
    /// @param last_subnet_id last subnet in the range of subnets
182
    /// @throw BadValue if either value given is 0 or if last <= first.
183
    LeaseStatsQuery(const SubnetID& first_subnet_id, const SubnetID& last_subnet_id);
184
185
    /// @brief virtual destructor
186
17.9k
    virtual ~LeaseStatsQuery() {}
187
188
    /// @brief Executes the query
189
    ///
190
    /// This method should conduct whatever steps are required to
191
    /// calculate the lease statistical data by examining the
192
    /// lease data and making that results available row by row.
193
0
    virtual void start() {}
194
195
    /// @brief Fetches the next row of data
196
    ///
197
    /// @param[out] row Storage into which the row is fetched
198
    ///
199
    /// @return True if a row was fetched, false if there are no
200
    /// more rows.
201
    virtual bool getNextRow(LeaseStatsRow& row);
202
203
    /// @brief Returns the value of first subnet ID specified (or zero)
204
0
    SubnetID getFirstSubnetID() const {
205
0
        return (first_subnet_id_);
206
0
    }
207
208
    /// @brief Returns the value of last subnet ID specified (or zero)
209
0
    SubnetID getLastSubnetID() const {
210
0
        return (last_subnet_id_);
211
0
    }
212
213
    /// @brief Returns the selection criteria mode
214
    /// The value returned is based upon the constructor variant used
215
    /// and it indicates which query variant will be executed.
216
35.9k
    SelectMode getSelectMode() const {
217
35.9k
        return (select_mode_);
218
35.9k
    }
219
220
protected:
221
    /// @brief First (or only) subnet_id in the selection criteria
222
    SubnetID first_subnet_id_;
223
224
    /// @brief Last subnet_id in the selection criteria when a range is given
225
    SubnetID last_subnet_id_;
226
227
private:
228
    /// @brief Indicates the type of selection criteria specified
229
    SelectMode select_mode_;
230
};
231
232
/// @brief Defines a pointer to a LeaseStatsQuery.
233
typedef boost::shared_ptr<LeaseStatsQuery> LeaseStatsQueryPtr;
234
235
/// @brief Defines a pointer to a LeaseStatsRow.
236
typedef boost::shared_ptr<LeaseStatsRow> LeaseStatsRowPtr;
237
238
/// @brief Describes a SFLQ pool.
239
class SflqPoolInfo {
240
public:
241
    SflqPoolInfo();
242
243
0
    ~SflqPoolInfo(){};
244
245
    Lease::Type lease_type_;
246
    asiolink::IOAddress start_address_;
247
    asiolink::IOAddress end_address_;
248
    uint8_t delegated_len_;
249
    SubnetID subnet_id_;
250
    uint64_t free_leases_;
251
    boost::posix_time::ptime created_ts_;
252
    boost::posix_time::ptime modified_ts_;
253
254
    data::ElementPtr toElement() const;
255
};
256
257
/// @brief A pointer to a SFLQPoolInfo instance.
258
typedef boost::shared_ptr<SflqPoolInfo> SflqPoolInfoPtr;
259
260
/// @brief A collection of SFLQPoolInfo structures.
261
typedef std::vector<SflqPoolInfoPtr> SflqPoolInfoCollection;
262
typedef boost::shared_ptr<SflqPoolInfoCollection> SflqPoolInfoCollectionPtr;
263
264
265
/// @brief Abstract Lease Manager
266
///
267
/// This is an abstract API for lease database backends. It provides unified
268
/// interface to all backends. As this is an abstract class, it should not
269
/// be used directly, but rather specialized derived class should be used
270
/// instead.
271
///
272
/// This class throws no exceptions.  However, methods in concrete
273
/// implementations of this class may throw exceptions: see the documentation
274
/// of those classes for details.
275
class LeaseMgr {
276
public:
277
    /// @brief Constructor
278
    ///
279
21.8k
    LeaseMgr() : extended_info_tables_enabled_(false)
280
21.8k
    {}
281
282
    /// @brief Destructor
283
    virtual ~LeaseMgr()
284
21.8k
    {}
285
286
    /// @brief Class method to return extended version info
287
    /// This class method must be redeclared and redefined in derived classes
288
    static std::string getDBVersion();
289
290
    /// @brief Adds an IPv4 lease.
291
    ///
292
    /// The lease may be modified due to sanity checks setting (see
293
    /// LeaseSanityChecks in CfgConsistency) before being inserted. For
294
    /// performance reasons, the sanity checks do not make a copy, but rather
295
    /// modify lease in place if needed.
296
    ///
297
    /// @param lease lease to be added
298
    ///
299
    /// @result true if the lease was added, false if not (because a lease
300
    ///         with the same address was already there or failed sanity checks)
301
    virtual bool addLease(const Lease4Ptr& lease) = 0;
302
303
    /// @brief Adds an IPv6 lease.
304
    ///
305
    /// The lease may be modified due to sanity checks setting (see
306
    /// LeaseSanityChecks in CfgConsistency) before being inserted. For
307
    /// performance reasons, the sanity checks do not make a copy, but rather
308
    /// modify lease in place if needed.
309
    ///
310
    /// @param lease lease to be added
311
    ///
312
    /// @result true if the lease was added, false if not (because a lease
313
    ///         with the same address was already there or failed sanity checks)
314
    virtual bool addLease(const Lease6Ptr& lease) = 0;
315
316
    /// @brief Returns an IPv4 lease for specified IPv4 address
317
    ///
318
    /// This method return a lease that is associated with a given address.
319
    /// For other query types (by hardware addr, by client-id) there can be
320
    /// several leases in different subnets (e.g. for mobile clients that
321
    /// got address in different subnets). However, for a single address
322
    /// there can be only one lease, so this method returns a pointer to
323
    /// a single lease, not a container of leases.
324
    ///
325
    /// @param addr address of the searched lease
326
    ///
327
    /// @return smart pointer to the lease (or NULL if a lease is not found)
328
    virtual Lease4Ptr getLease4(const isc::asiolink::IOAddress& addr) const = 0;
329
330
    /// @brief Returns existing IPv4 leases for specified hardware address.
331
    ///
332
    /// Although in the usual case there will be only one lease, for mobile
333
    /// clients or clients with multiple static/fixed/reserved leases there
334
    /// can be more than one. Thus return type is a container, not a single
335
    /// pointer.
336
    ///
337
    /// @param hwaddr hardware address of the client
338
    ///
339
    /// @return lease collection
340
    virtual Lease4Collection getLease4(const isc::dhcp::HWAddr& hwaddr) const = 0;
341
342
    /// @brief Returns existing IPv4 leases for specified hardware address
343
    ///        and a subnet
344
    ///
345
    /// There can be at most one lease for a given HW address in a single
346
    /// pool, so this method will either return a single lease or NULL.
347
    ///
348
    /// @param hwaddr hardware address of the client
349
    /// @param subnet_id identifier of the subnet that lease must belong to
350
    ///
351
    /// @return a pointer to the lease (or NULL if a lease is not found)
352
    virtual Lease4Ptr getLease4(const isc::dhcp::HWAddr& hwaddr,
353
                                SubnetID subnet_id) const = 0;
354
355
    /// @brief Returns existing IPv4 lease for specified client-id
356
    ///
357
    /// Although in the usual case there will be only one lease, for mobile
358
    /// clients or clients with multiple static/fixed/reserved leases there
359
    /// can be more than one. Thus return type is a container, not a single
360
    /// pointer.
361
    ///
362
    /// @param clientid client identifier
363
    ///
364
    /// @return lease collection
365
    virtual Lease4Collection getLease4(const ClientId& clientid) const = 0;
366
367
    /// @brief Returns existing IPv4 lease for specified client-id
368
    ///
369
    /// There can be at most one lease for a given client-id in a single
370
    /// pool, so this method will either return a single lease or NULL.
371
    ///
372
    /// @param clientid client identifier
373
    /// @param subnet_id identifier of the subnet that lease must belong to
374
    ///
375
    /// @return a pointer to the lease (or NULL if a lease is not found)
376
    virtual Lease4Ptr getLease4(const ClientId& clientid,
377
                                SubnetID subnet_id) const = 0;
378
379
    /// @brief Returns all IPv4 leases for the particular subnet identifier.
380
    ///
381
    /// @param subnet_id subnet identifier.
382
    ///
383
    /// @return Lease collection (may be empty if no IPv4 lease found).
384
    virtual Lease4Collection getLeases4(SubnetID subnet_id) const = 0;
385
386
    /// @brief Returns all IPv4 leases for the particular hostname.
387
    ///
388
    /// @param hostname hostname in lower case.
389
    ///
390
    /// @return Lease collection (may be empty if no IPv4 lease found).
391
    virtual Lease4Collection getLeases4(const std::string& hostname) const = 0;
392
393
    /// @brief Returns all IPv4 leases.
394
    ///
395
    /// @return Lease collection (may be empty if no IPv4 lease found).
396
    virtual Lease4Collection getLeases4() const = 0;
397
398
    /// @brief Returns range of IPv4 leases using paging.
399
    ///
400
    /// This method implements paged browsing of the lease database. The first
401
    /// parameter specifies a page size. The second parameter is optional and
402
    /// specifies the starting address of the range. This address is excluded
403
    /// from the returned range. The IPv4 zero address (default) denotes that
404
    /// the first page should be returned. There is no guarantee about the
405
    /// order of returned leases.
406
    ///
407
    /// The typical usage of this method is as follows:
408
    /// - Get the first page of leases by specifying IPv4 zero address as the
409
    ///   beginning of the range.
410
    /// - Last address of the returned range should be used as a starting
411
    ///   address for the next page in the subsequent call.
412
    /// - If the number of leases returned is lower than the page size, it
413
    ///   indicates that the last page has been retrieved.
414
    /// - If there are no leases returned it indicates that the previous page
415
    ///   was the last page.
416
    ///
417
    /// @param lower_bound_address IPv4 address used as lower bound for the
418
    /// returned range.
419
    /// @param page_size maximum size of the page returned.
420
    ///
421
    /// @return Lease collection (may be empty if no IPv4 lease found).
422
    virtual Lease4Collection
423
    getLeases4(const asiolink::IOAddress& lower_bound_address,
424
               const LeasePageSize& page_size) const = 0;
425
426
    /// @brief Returns all IPv4 leases for the particular state and subnet.
427
    ///
428
    /// @param state the state e.g. 1 (declined).
429
    /// @param subnet_id the subnet identifier (0 for all leases).
430
    ///
431
    /// @return Lease collection (may be empty if no IPv4 lease found).
432
    virtual Lease4Collection getLeases4(uint32_t state,
433
                                        SubnetID subnet_id) const = 0;
434
435
    /// @brief Returns existing IPv6 lease for a given IPv6 address.
436
    ///
437
    /// For a given address, we assume that there will be only one lease.
438
    /// The assumption here is that there will not be site or link-local
439
    /// addresses used, so there is no way of having address duplication.
440
    ///
441
    /// @param type specifies lease type: (NA, TA or PD)
442
    /// @param addr address of the searched lease
443
    ///
444
    /// @return smart pointer to the lease (or NULL if a lease is not found)
445
    virtual Lease6Ptr getLease6(Lease::Type type,
446
                                const isc::asiolink::IOAddress& addr) const = 0;
447
448
    /// @brief Returns existing IPv6 leases for specified hardware address.
449
    ///
450
    /// Although in the usual case there will be only one lease, for mobile
451
    /// clients or clients with multiple static/fixed/reserved leases there
452
    /// can be more than one. Thus return type is a container, not a single
453
    /// pointer.
454
    ///
455
    /// @param hwaddr hardware address of the client
456
    ///
457
    /// @return lease collection
458
    virtual Lease6Collection getLease6(const isc::dhcp::HWAddr& hwaddr) const = 0;
459
460
    /// @brief Returns existing IPv6 leases for a given DUID+IA combination
461
    ///
462
    /// Although in the usual case there will be only one lease, for mobile
463
    /// clients or clients with multiple static/fixed/reserved leases there
464
    /// can be more than one. Thus return type is a container, not a single
465
    /// pointer.
466
    ///
467
    /// @param type specifies lease type: (NA, TA or PD)
468
    /// @param duid client DUID
469
    /// @param iaid IA identifier
470
    ///
471
    /// @return Lease collection (may be empty if no lease is found)
472
    virtual Lease6Collection getLeases6(Lease::Type type, const DUID& duid,
473
                                        uint32_t iaid) const = 0;
474
475
    /// @brief Returns existing IPv6 lease for a given DUID+IA combination
476
    ///
477
    /// There may be more than one address, temp. address or prefix
478
    /// for specified duid/iaid/subnet-id tuple.
479
    ///
480
    /// @param type specifies lease type: (NA, TA or PD)
481
    /// @param duid client DUID
482
    /// @param iaid IA identifier
483
    /// @param subnet_id subnet id of the subnet the lease belongs to
484
    ///
485
    /// @return Lease collection (may be empty if no lease is found)
486
    virtual Lease6Collection getLeases6(Lease::Type type, const DUID& duid,
487
                                        uint32_t iaid, SubnetID subnet_id) const = 0;
488
489
    /// @brief returns zero or one IPv6 lease for a given duid+iaid+subnet_id
490
    ///
491
    /// This function is mostly intended to be used in unit-tests during the
492
    /// transition from single to multi address per IA. It may also be used
493
    /// in other cases where at most one lease is expected in the database.
494
    ///
495
    /// It is a wrapper around getLeases6(), which returns a collection of
496
    /// leases. That collection can be converted into a single pointer if
497
    /// there are no leases (NULL pointer) or one lease (use that single lease).
498
    /// If there are more leases in the collection, the function will
499
    /// throw MultipleRecords exception.
500
    ///
501
    /// Note: This method is not virtual on purpose. It is common for all
502
    /// backends.
503
    ///
504
    /// @param type specifies lease type: (NA, TA or PD)
505
    /// @param duid client DUID
506
    /// @param iaid IA identifier
507
    /// @param subnet_id subnet id of the subnet the lease belongs to
508
    ///
509
    /// @throw MultipleRecords if there is more than one lease matching
510
    ///
511
    /// @return Lease pointer (or NULL if none is found)
512
    Lease6Ptr getLease6(Lease::Type type, const DUID& duid,
513
                        uint32_t iaid, SubnetID subnet_id) const;
514
515
    /// @brief Returns all IPv6 leases for the particular subnet identifier.
516
    ///
517
    /// @param subnet_id subnet identifier.
518
    ///
519
    /// @return Lease collection (may be empty if no IPv6 lease found).
520
    virtual Lease6Collection getLeases6(SubnetID subnet_id) const = 0;
521
522
    /// @brief Returns all IPv6 leases for the particular hostname.
523
    ///
524
    /// @param hostname hostname in lower case.
525
    ///
526
    /// @return Lease collection (may be empty if no IPv6 lease found).
527
    virtual Lease6Collection getLeases6(const std::string& hostname) const = 0;
528
529
    /// @brief Returns all IPv6 leases.
530
    ///
531
    /// @return Lease collection (may be empty if no IPv6 lease found).
532
    virtual Lease6Collection getLeases6() const = 0;
533
534
    /// @brief Returns collection of leases for matching DUID
535
    ///
536
    /// @return Lease collection
537
    /// (may be empty if no IPv6 lease found for the DUID).
538
    virtual Lease6Collection getLeases6(const DUID& duid) const = 0;
539
540
    /// @brief Returns range of IPv6 leases using paging.
541
    ///
542
    /// This method implements paged browsing of the lease database. The first
543
    /// parameter specifies a page size. The second parameter is optional and
544
    /// specifies the starting address of the range. This address is excluded
545
    /// from the returned range. The IPv6 zero address (default) denotes that
546
    /// the first page should be returned. There is no guarantee about the
547
    /// order of returned leases.
548
    ///
549
    /// The typical usage of this method is as follows:
550
    /// - Get the first page of leases by specifying IPv6 zero address as the
551
    ///   beginning of the range.
552
    /// - Last address of the returned range should be used as a starting
553
    ///   address for the next page in the subsequent call.
554
    /// - If the number of leases returned is lower than the page size, it
555
    ///   indicates that the last page has been retrieved.
556
    /// - If there are no leases returned it indicates that the previous page
557
    ///   was the last page.
558
    ///
559
    /// @param lower_bound_address IPv6 address used as lower bound for the
560
    /// returned range.
561
    /// @param page_size maximum size of the page returned.
562
    ///
563
    /// @return Lease collection (may be empty if no IPv6 lease found).
564
    virtual Lease6Collection
565
    getLeases6(const asiolink::IOAddress& lower_bound_address,
566
               const LeasePageSize& page_size) const = 0;
567
568
    /// @brief Returns a page of IPv6 leases for a  subnet identifier.
569
    ///
570
    /// @param subnet_id subnet identifier.
571
    /// @param lower_bound_address IPv6 address used as lower bound for the
572
    /// returned range.
573
    /// @param page_size maximum size of the page returned.
574
    ///
575
    /// @return collection of IPv6 leases
576
    virtual Lease6Collection
577
    getLeases6(SubnetID subnet_id,
578
               const asiolink::IOAddress& lower_bound_address,
579
               const LeasePageSize& page_size) const = 0;
580
581
    /// @brief Returns all IPv6 leases for the particular state and subnet.
582
    ///
583
    /// @param state the state e.g. 1 (declined).
584
    /// @param subnet_id the subnet identifier (0 for all leases).
585
    ///
586
    /// @return Lease collection (may be empty if no IPv6 lease found).
587
    virtual Lease6Collection getLeases6(uint32_t state,
588
                                        SubnetID subnet_id) const = 0;
589
590
    /// @brief Returns a collection of expired DHCPv4 leases.
591
    ///
592
    /// This method returns at most @c max_leases expired leases. The leases
593
    /// returned haven't been reclaimed, i.e. the database query must exclude
594
    /// reclaimed leases from the results returned.
595
    ///
596
    /// @param [out] expired_leases A container to which expired leases returned
597
    /// by the database backend are added.
598
    /// @param max_leases A maximum number of leases to be returned. If this
599
    /// value is set to 0, all expired (but not reclaimed) leases are returned.
600
    virtual void getExpiredLeases4(Lease4Collection& expired_leases,
601
                                   const size_t max_leases) const = 0;
602
603
    /// @brief Returns a collection of expired DHCPv6 leases.
604
    ///
605
    /// This method returns at most @c max_leases expired leases. The leases
606
    /// returned haven't been reclaimed, i.e. the database query must exclude
607
    /// reclaimed leases from the results returned.
608
    ///
609
    /// @param [out] expired_leases A container to which expired leases returned
610
    /// by the database backend are added.
611
    /// @param max_leases A maximum number of leases to be returned. If this
612
    /// value is set to 0, all expired (but not reclaimed) leases are returned.
613
    virtual void getExpiredLeases6(Lease6Collection& expired_leases,
614
                                   const size_t max_leases) const = 0;
615
616
    /// @brief Updates IPv4 lease.
617
    ///
618
    /// @param lease4 The lease to be updated.
619
    ///
620
    /// If no such lease is present, an exception will be thrown.
621
    virtual void updateLease4(const Lease4Ptr& lease4) = 0;
622
623
    /// @brief Updates IPv6 lease.
624
    ///
625
    /// @param lease6 The lease to be updated.
626
    virtual void updateLease6(const Lease6Ptr& lease6) = 0;
627
628
    /// @brief Deletes an IPv4 lease.
629
    ///
630
    /// @param lease IPv4 lease to be deleted.
631
    ///
632
    /// @return true if deletion was successful, false if no such lease exists.
633
    ///
634
    /// @throw isc::dhcp::DbOperationError An operation on the open database has
635
    ///        failed.
636
    virtual bool deleteLease(const Lease4Ptr& lease) = 0;
637
638
    /// @brief Deletes an IPv6 lease.
639
    ///
640
    /// @param lease IPv6 lease to be deleted.
641
    ///
642
    /// @return true if deletion was successful, false if no such lease exists.
643
    ///
644
    /// @throw isc::db::DbOperationError An operation on the open database has
645
    ///        failed.
646
    virtual bool deleteLease(const Lease6Ptr& lease) = 0;
647
648
    /// @brief Deletes all expired and reclaimed DHCPv4 leases.
649
    ///
650
    /// @param secs Number of seconds since expiration of leases before
651
    /// they can be removed. Leases which have expired later than this
652
    /// time will not be deleted.
653
    ///
654
    /// @return Number of leases deleted.
655
    virtual uint64_t deleteExpiredReclaimedLeases4(const uint32_t secs) = 0;
656
657
    /// @brief Deletes all expired and reclaimed DHCPv6 leases.
658
    ///
659
    /// @param secs Number of seconds since expiration of leases before
660
    /// they can be removed. Leases which have expired later than this
661
    /// time will not be deleted.
662
    ///
663
    /// @return Number of leases deleted.
664
    virtual uint64_t deleteExpiredReclaimedLeases6(const uint32_t secs) = 0;
665
666
    /// @brief Recalculates per-subnet and global stats for IPv4 leases
667
    ///
668
    /// This method recalculates the following statistics:
669
    /// per-subnet:
670
    /// - assigned-addresses
671
    /// - declined-addresses
672
    /// global:
673
    /// - assigned-addresses
674
    /// - declined-addresses
675
    ///
676
    /// It invokes the virtual method, startLeaseStatsQuery4(), which
677
    /// returns an instance of an LeaseStatsQuery.  The query
678
    /// query contains a "result set"  where each row is an LeaseStatRow
679
    /// that contains a subnet id, a lease type (currently always TYPE_NA),
680
    /// a lease state, and the number of leases of that type, in that state
681
    /// and is ordered by subnet id.  The method iterates over the
682
    /// result set rows, setting the appropriate statistic per subnet and
683
    /// adding to the appropriate global statistic.
684
    void recountLeaseStats4();
685
686
    /// @brief Creates and runs the IPv4 lease stats query for all subnets
687
    ///
688
    /// LeaseMgr derivations implement this method such that it creates and
689
    /// returns an instance of an LeaseStatsQuery whose result set has been
690
    /// populated with up to date IPv4 lease statistical data for all subnets.
691
    /// Each row of the result set is an LeaseStatRow which ordered ascending
692
    /// by subnet ID.
693
    ///
694
    /// @return A populated LeaseStatsQuery
695
    virtual LeaseStatsQueryPtr startLeaseStatsQuery4();
696
697
    /// @brief Creates and runs the IPv4 lease stats query for all subnets and
698
    /// pools
699
    ///
700
    /// LeaseMgr derivations implement this method such that it creates and
701
    /// returns an instance of an LeaseStatsQuery whose result set has been
702
    /// populated with up to date IPv4 lease statistical data for all subnets
703
    /// and pools.
704
    /// Each row of the result set is an LeaseStatRow which ordered ascending
705
    /// by subnet ID and pool ID.
706
    ///
707
    /// @return A populated LeaseStatsQuery
708
    virtual LeaseStatsQueryPtr startPoolLeaseStatsQuery4();
709
710
    /// @brief Creates and runs the IPv4 lease stats query for a single subnet
711
    ///
712
    /// LeaseMgr derivations implement this method such that it creates and
713
    /// returns an instance of an LeaseStatsQuery whose result set has been
714
    /// populated with up to date IPv4 lease statistical data for a single
715
    /// subnet.  Each row of the result set is an LeaseStatRow.
716
    ///
717
    /// @param subnet_id id of the subnet for which stats are desired
718
    /// @return A populated LeaseStatsQuery
719
    virtual LeaseStatsQueryPtr startSubnetLeaseStatsQuery4(const SubnetID& subnet_id);
720
721
    /// @brief Creates and runs the IPv4 lease stats query for a single subnet
722
    ///
723
    /// LeaseMgr derivations implement this method such that it creates and
724
    /// returns an instance of an LeaseStatsQuery whose result set has been
725
    /// populated with up to date IPv4 lease statistical data for an inclusive
726
    /// range of subnets. Each row of the result set is an LeaseStatRow which
727
    /// ordered ascending by subnet ID.
728
    ///
729
    /// @param first_subnet_id first subnet in the range of subnets
730
    /// @param last_subnet_id last subnet in the range of subnets
731
    /// @return A populated LeaseStatsQuery
732
    virtual LeaseStatsQueryPtr startSubnetRangeLeaseStatsQuery4(const SubnetID& first_subnet_id,
733
                                                                const SubnetID& last_subnet_id);
734
735
    /// @brief Recalculates per-subnet and global stats for IPv6 leases
736
    ///
737
    /// This method recalculates the following statistics:
738
    /// per-subnet:
739
    /// - assigned-nas
740
    /// - declined-addresses
741
    /// - assigned-pds
742
    /// - registered
743
    /// global:
744
    /// - assigned-nas
745
    /// - declined-addresses
746
    /// - assigned-pds
747
    /// - registered
748
    ///
749
    /// It invokes the virtual method, startLeaseStatsQuery6(), which
750
    /// returns an instance of an LeaseStatsQuery.  The query contains
751
    /// a "result set" where each row is an LeaseStatRow that contains
752
    /// a subnet id, a lease type, a lease state, and the number of leases
753
    /// of that type, in that state and is ordered by subnet id. The method
754
    /// iterates over the result set rows, setting the appropriate statistic
755
    /// per subnet and adding to the appropriate global statistic.
756
    void recountLeaseStats6();
757
758
    /// @brief Creates and runs the IPv6 lease stats query for all subnets
759
    ///
760
    /// LeaseMgr derivations implement this method such that it creates and
761
    /// returns an instance of an LeaseStatsQuery whose result set has been
762
    /// populated with up to date IPv6 lease statistical data for all subnets.
763
    /// Each row of the result set is an LeaseStatRow which ordered ascending
764
    /// by subnet ID.
765
    ///
766
    /// @return A populated LeaseStatsQuery
767
    virtual LeaseStatsQueryPtr startLeaseStatsQuery6();
768
769
    /// @brief Creates and runs the IPv6 lease stats query for all subnets and
770
    /// pools
771
    ///
772
    /// LeaseMgr derivations implement this method such that it creates and
773
    /// returns an instance of an LeaseStatsQuery whose result set has been
774
    /// populated with up to date IPv6 lease statistical data for all subnets
775
    /// and pools.
776
    /// Each row of the result set is an LeaseStatRow which ordered ascending
777
    /// by subnet ID and pool ID.
778
    ///
779
    /// @return A populated LeaseStatsQuery
780
    virtual LeaseStatsQueryPtr startPoolLeaseStatsQuery6();
781
782
    /// @brief Creates and runs the IPv6 lease stats query for a single subnet
783
    ///
784
    /// LeaseMgr derivations implement this method such that it creates and
785
    /// returns an instance of an LeaseStatsQuery whose result set has been
786
    /// populated with up to date IPv6 lease statistical data for a single
787
    /// subnet.  Each row of the result set is an LeaseStatRow.
788
    ///
789
    /// @param subnet_id id of the subnet for which stats are desired
790
    /// @return A populated LeaseStatsQuery
791
    virtual LeaseStatsQueryPtr startSubnetLeaseStatsQuery6(const SubnetID& subnet_id);
792
793
    /// @brief Creates and runs the IPv6 lease stats query for a single subnet
794
    ///
795
    /// LeaseMgr derivations implement this method such that it creates and
796
    /// returns an instance of an LeaseStatsQuery whose result set has been
797
    /// populated with up to date IPv6 lease statistical data for an inclusive
798
    /// range of subnets. Each row of the result set is an LeaseStatRow which
799
    /// ordered ascending by subnet ID.
800
    ///
801
    /// @param first_subnet_id first subnet in the range of subnets
802
    /// @param last_subnet_id last subnet in the range of subnets
803
    /// @return A populated LeaseStatsQuery
804
    virtual LeaseStatsQueryPtr startSubnetRangeLeaseStatsQuery6(const SubnetID& first_subnet_id,
805
                                                                const SubnetID& last_subnet_id);
806
807
    /// @brief Virtual method which removes specified leases.
808
    ///
809
    /// This rather dangerous method is able to remove all leases from specified
810
    /// subnet.
811
    ///
812
    /// @param subnet_id identifier of the subnet (or 0 for all subnets)
813
    /// @return number of leases removed.
814
    virtual size_t wipeLeases4(const SubnetID& subnet_id) = 0;
815
816
    /// @brief Virtual method which removes specified leases.
817
    ///
818
    /// This rather dangerous method is able to remove all leases from specified
819
    /// subnet.
820
    ///
821
    /// @param subnet_id identifier of the subnet (or 0 for all subnets)
822
    /// @return number of leases removed.
823
    virtual size_t wipeLeases6(const SubnetID& subnet_id) = 0;
824
825
    /// @brief Checks if the IPv4 lease limits set in the given user context are exceeded.
826
    /// Abstract method.
827
    ///
828
    /// @param user_context all or part of the lease's user context which, for the intents and
829
    /// purposes of lease limiting should have the following format
830
    /// (not all nodes are mandatory and values are given only as examples):
831
    /// { "ISC": { "limits": { "client-classes": [ { "name": "foo", "address-limit": 2 } ],
832
    ///                        "subnet": { "id": 1, "address-limit": 2 } } } }
833
    ///
834
    /// @return a string describing a limit that is being exceeded, or an empty
835
    /// string if no limits are exceeded
836
    virtual std::string checkLimits4(isc::data::ConstElementPtr const& user_context) const = 0;
837
838
    /// @brief Checks if the IPv6 lease limits set in the given user context are exceeded.
839
    /// Abstract method.
840
    ///
841
    /// @param user_context all or part of the lease's user context which, for the intents and
842
    /// purposes of lease limiting should have the following format
843
    /// (not all nodes are mandatory and values are given only as examples):
844
    /// { "ISC": { "limits": { "client-classes": [ { "name": "foo", "address-limit": 2, "prefix-limit": 1 } ],
845
    ///                        "subnet": { "id": 1, "address-limit": 2, "prefix-limit": 1 } } } }
846
    ///
847
    /// @return a string describing a limit that is being exceeded, or an empty
848
    /// string if no limits are exceeded
849
    virtual std::string checkLimits6(isc::data::ConstElementPtr const& user_context) const = 0;
850
851
    /// @brief Return backend type
852
    ///
853
    /// Returns the type of the backend (e.g. "mysql", "memfile" etc.)
854
    ///
855
    /// @return Type of the backend.
856
    virtual std::string getType() const = 0;
857
858
    /// @brief Returns backend name.
859
    ///
860
    /// If the backend is a database, this is the name of the database or the
861
    /// file.  Otherwise it is just the same as the type.
862
    ///
863
    /// @return Name of the backend.
864
    virtual std::string getName() const = 0;
865
866
    /// @brief Returns description of the backend.
867
    ///
868
    /// This description may be multiline text that describes the backend.
869
    ///
870
    /// @return Description of the backend.
871
    virtual std::string getDescription() const = 0;
872
873
    /// @brief Returns backend version.
874
    ///
875
    /// @param timer_name The DB reconnect timer name.
876
    /// @return Version number as a pair of unsigned integers.  "first" is the
877
    ///         major version number, "second" the minor number.
878
    ///
879
    /// @todo: We will need to implement 3 version functions eventually:
880
    /// A. abstract API version
881
    /// B. backend version
882
    /// C. database version (stored in the database scheme)
883
    ///
884
    /// and then check that:
885
    /// B>=A and B=C (it is ok to have newer backend, as it should be backward
886
    /// compatible)
887
    /// Also if B>C, some database upgrade procedure may be triggered
888
    virtual VersionPair getVersion(const std::string& timer_name = std::string()) const = 0;
889
890
    /// @brief Commit Transactions
891
    ///
892
    /// Commits all pending database operations.  On databases that don't
893
    /// support transactions, this is a no-op.
894
    virtual void commit() = 0;
895
896
    /// @brief Rollback Transactions
897
    ///
898
    /// Rolls back all pending database operations.  On databases that don't
899
    /// support transactions, this is a no-op.
900
    virtual void rollback() = 0;
901
902
    // -- The following are memfile only, but defined in the base LeaseMgr for convenience. --
903
904
    /// @brief Returns the class lease count for a given class and lease type.
905
    ///
906
    /// @param client_class client class for which the count is desired
907
    /// @param ltype type of lease for which the count is desired. Defaults to
908
    /// Lease::TYPE_V4.
909
    ///
910
    /// @return number of leases
911
    virtual size_t getClassLeaseCount(const ClientClass& client_class,
912
                                      const Lease::Type& ltype = Lease::TYPE_V4) const = 0;
913
914
    /// @brief Recount the leases per class for V4 leases.
915
    virtual void recountClassLeases4() = 0;
916
917
    /// @brief Recount the leases per class for V6 leases.
918
    virtual void recountClassLeases6() = 0;
919
920
    /// @brief Clears the class-lease count map.
921
    virtual void clearClassLeaseCounts() = 0;
922
923
    /// The following queries are used to fulfill Bulk Lease Query
924
    /// queries. They rely on relay data contained in lease's
925
    /// user-context when the extended-store-info flag is enabled.
926
927
    /// @brief Upgrade a V4 lease user context to the new extended info entry.
928
    ///
929
    /// In details:
930
    ///  - perform sanity checks according to check level.
931
    ///  - change the "ISC" / "relay-agent-info" to a map.
932
    ///  - move the "relay-agent-info" string to the "sub-options" entry of
933
    ///    the map.
934
    ///  - decode remote-id and relay-id from the RAI option content and
935
    ///    add the raw value in hexadecimal in "remote-id" and/or "relay-id"
936
    ///    entries of the map.
937
    ///
938
    /// @param lease Pointer to the lease to be updated.
939
    /// @param check Sanity/consistency check level.
940
    /// @return True if the lease user context was updated, false otherwise.
941
    static bool
942
    upgradeLease4ExtendedInfo(const Lease4Ptr& lease,
943
                              CfgConsistency::ExtendedInfoSanity check =
944
                              CfgConsistency::EXTENDED_INFO_CHECK_FIX);
945
946
    /// @brief Upgrade a V6 lease user context to the new extended info entry.
947
    ///
948
    /// In details:
949
    ///  - perform sanity checks according to check level.
950
    ///  - change the "ISC" / "relays" list entry to "relay-info".
951
    ///  - decode remote-id and relay-id from each relay options and
952
    ///    add the raw value in hexadecimal in "remote-id" and/or "relay-id"
953
    ///    in the relay item of the list.
954
    ///
955
    /// @param lease Pointer to the lease to be updated.
956
    /// @param check Sanity/consistency check level.
957
    /// @return True if the lease user context was updated, false otherwise.
958
    static bool
959
    upgradeLease6ExtendedInfo(const Lease6Ptr& lease,
960
                              CfgConsistency::ExtendedInfoSanity check =
961
                              CfgConsistency::EXTENDED_INFO_CHECK_FIX);
962
963
    /// @brief Extract relay and remote identifiers from the extended info.
964
    ///
965
    /// @param lease Pointer to the lease to be updated.
966
    /// @param ignore_errors When true (the default) ignore errors,
967
    /// when false throw an exception.
968
    static void extractLease4ExtendedInfo(const Lease4Ptr& lease,
969
                                          bool ignore_errors = true);
970
971
    /// @brief Returns existing IPv4 leases with a given relay-id.
972
    ///
973
    /// @param relay_id RAI Relay-ID sub-option value for relay_id of interest
974
    /// @param lower_bound_address IPv4 address used as lower bound for the
975
    /// returned range.
976
    /// @param page_size maximum size of the page returned.
977
    /// @param qry_start_time when not zero, only leases whose CLTT is greater than
978
    /// or equal to this value will be included
979
    /// @param qry_end_time when not zero, only leases whose CLTT is less than
980
    /// or equal to this value will be included
981
    ///
982
    /// @return collection of IPv4 leases
983
    virtual Lease4Collection
984
    getLeases4ByRelayId(const OptionBuffer& relay_id,
985
                        const asiolink::IOAddress& lower_bound_address,
986
                        const LeasePageSize& page_size,
987
                        const time_t& qry_start_time = 0,
988
                        const time_t& qry_end_time = 0) = 0;
989
990
    /// @brief Returns existing IPv4 leases with a given remote-id.
991
    ///
992
    /// @param remote_id RAI Remote-ID sub-option value for remote-id of interest
993
    /// @param lower_bound_address IPv4 address used as lower bound for the
994
    /// returned range.
995
    /// @param page_size maximum size of the page returned.
996
    /// @param qry_start_time when not zero, only leases whose CLTT is greater than
997
    /// or equal to this value will be included. Defaults to zero.
998
    /// @param qry_end_time when not zero, only leases whose CLTT is less than
999
    /// or equal to this value will be included. Defaults to zero.
1000
    ///
1001
    /// @return collection of IPv4 leases
1002
    virtual Lease4Collection
1003
    getLeases4ByRemoteId(const OptionBuffer& remote_id,
1004
                         const asiolink::IOAddress& lower_bound_address,
1005
                         const LeasePageSize& page_size,
1006
                         const time_t& qry_start_time = 0,
1007
                         const time_t& qry_end_time = 0) = 0;
1008
1009
    /// @brief Returns existing IPv6 leases with a given relay-id.
1010
    ///
1011
    /// @param relay_id DUID for relay_id of interest.
1012
    /// @param lower_bound_address IPv6 address used as lower bound for the
1013
    /// returned range.
1014
    /// @param page_size maximum size of the page returned.
1015
    ///
1016
    /// @return collection of IPv6 leases
1017
    virtual Lease6Collection
1018
    getLeases6ByRelayId(const DUID& relay_id,
1019
                        const asiolink::IOAddress& lower_bound_address,
1020
                        const LeasePageSize& page_size) = 0;
1021
1022
    /// @brief Returns existing IPv6 leases with a given remote-id.
1023
    ///
1024
    /// @param remote_id remote-id option data of interest.
1025
    /// @param lower_bound_address IPv6 address used as lower bound for the
1026
    /// returned range.
1027
    /// @param page_size maximum size of the page returned.
1028
    ///
1029
    /// @return collection of IPv6 leases
1030
    virtual Lease6Collection
1031
    getLeases6ByRemoteId(const OptionBuffer& remote_id,
1032
                         const asiolink::IOAddress& lower_bound_address,
1033
                         const LeasePageSize& page_size) = 0;
1034
1035
    /// @brief Write V4 leases to a file.
1036
    ///
1037
    /// @param filename File name to write leases.
1038
    virtual void writeLeases4(const std::string& filename) = 0;
1039
1040
    /// @brief Write V6 leases to a file.
1041
    ///
1042
    /// @param filename File name to write leases.
1043
    virtual void writeLeases6(const std::string& filename) = 0;
1044
1045
    /// @brief Upgrade extended info (v4).
1046
    ///
1047
    /// On SQL backends for all leases with a not null user context.
1048
    ///  - sanitize the user context
1049
    ///  - update relay and remote ids
1050
    ///  - when the lease was modified update it in the database
1051
    /// On memfile backend a similar action is done when the database is
1052
    /// loaded from the file. This function implements the new BLQ hook
1053
    /// command named "extended-info4-upgrade".
1054
    ///
1055
    /// @param page_size The page size used for retrieval.
1056
    /// @return The number of updates in the database.
1057
    virtual size_t upgradeExtendedInfo4(const LeasePageSize& page_size) = 0;
1058
1059
    /// @brief Returns the setting indicating if lease6 extended info tables
1060
    /// are enabled.
1061
    ///
1062
    /// @return true if lease6 extended info tables are enabled or false
1063
    /// if they are disabled.
1064
5.65k
    bool getExtendedInfoTablesEnabled() const {
1065
5.65k
        return (extended_info_tables_enabled_);
1066
5.65k
    }
1067
1068
    /// @brief Modifies the setting whether the lease6 extended info tables
1069
    /// are enabled.
1070
    ///
1071
    /// @param enabled new setting.
1072
0
    void setExtendedInfoTablesEnabled(const bool enabled) {
1073
0
        extended_info_tables_enabled_ = enabled;
1074
0
    }
1075
1076
    /// @brief Upgrade extended info (v6).
1077
    ///
1078
    /// On SQL backends for all leases with a not null user context.
1079
    ///  - sanitize the user context
1080
    ///  - update relay and remote id tables
1081
    ///  - when the lease was modified update it in the database
1082
    /// On memfile backend a similar action is done when the database is
1083
    /// loaded from the file. This function implements the new BLQ hook
1084
    /// command named "extended-info6-upgrade".
1085
    ///
1086
    /// @param page_size The page size used for retrieval.
1087
    /// @return The number of updates in the database.
1088
    virtual size_t upgradeExtendedInfo6(const LeasePageSize& page_size) = 0;
1089
1090
    /// @brief Wipe extended info table (v6).
1091
    virtual void wipeExtendedInfoTables6() = 0;
1092
1093
    /// @brief Return the by-relay-id table size.
1094
    ///
1095
    /// Must be derived by backends implementing the table.
1096
    ///
1097
    /// @return Always 0.
1098
    virtual size_t byRelayId6size() const;
1099
1100
    /// @brief Return the by-remote-id table size.
1101
    ///
1102
    /// Must be derived by backends implementing the table.
1103
    ///
1104
    /// @return Always 0.
1105
    virtual size_t byRemoteId6size() const;
1106
1107
    /// @brief Return status information.
1108
    ///
1109
    /// Can be derived by backends (currently memfile).
1110
    ///
1111
    /// @return Null or a map to add to status-get command output.
1112
    virtual data::ElementPtr getStatus() const;
1113
1114
    /// @brief Handler for kea-lfc-start command.
1115
    ///
1116
    /// Derived by the memfile backend.
1117
    ///
1118
    /// @returns By default an error saying the backend is not the memfile one.
1119
    virtual isc::data::ConstElementPtr lfcStartHandler();
1120
1121
    /// @brief Creates a v4 SFLQ Pool
1122
    ///
1123
    /// Calls stored procedure to create a v4 SFLQ pool. If the pool already
1124
    /// exists and recreate is false it simply returns. Otherwise it (re)creates
1125
    /// and (re)populates the pool.
1126
    ///
1127
    /// @param start_address first address in the pool.
1128
    /// @param end_address last address in the pool.
1129
    /// @param subnet_id id of the subnet to which the pool belongs.
1130
    /// @param recreate when true, the pool is recreated if it already exits.
1131
    ///
1132
    /// @return True if the pool is (re)created, false it if already exists.
1133
    virtual bool sflqCreateFlqPool4(asiolink::IOAddress start_address,
1134
                                    asiolink::IOAddress end_address,
1135
                                    SubnetID subnet_id, bool recreate = false);
1136
1137
    /// @brief Finds a free V4 address within the given pool range.
1138
    ///
1139
    /// Calls the sflqPickFreeLease4 stored procedure to find a free address
1140
    /// within the SFLQ pool described by the given address range.  If there
1141
    /// are no free addresses in the pool or the pool does not exist it returns
1142
    /// 0.0.0.0. Note the returned address must still be checked for HR
1143
    /// conflicts.
1144
    ///
1145
    /// @param start_address first address in the pool.
1146
    /// @param end_address last address in the pool.
1147
    ///
1148
    /// @return A free V4 address or IOAddress::IPV4_ZERO_ADDRESS().
1149
    virtual asiolink::IOAddress sflqPickFreeLease4(asiolink::IOAddress start_address,
1150
                                                   asiolink::IOAddress end_address);
1151
1152
    /// @brief Calls stored procedure to create an SFLQ pool for v6.
1153
    ///
1154
    /// @param start_address first address/prefix in the pool.
1155
    /// @param end_address last address/prefix in the pool.
1156
    /// @param lease_type TYPE_NA or TYPE_PD.
1157
    /// @param delegated_len bit length of the address/prefix to be leases. For
1158
    /// TYPE_NA this parameter should be 128.
1159
    /// @param subnet_id id of the subnet to which the pool belongs.
1160
    /// @param recreate when true, the pool is recreated if it already exits.
1161
    ///
1162
    /// @return True if the pool is (re)created, false it if already exists.
1163
    virtual bool sflqCreateFlqPool6(asiolink::IOAddress start_address,
1164
                                    asiolink::IOAddress end_address,
1165
                                    Lease::Type lease_type, uint8_t delegated_len,
1166
                                    SubnetID subnet_id, bool recreate = false);
1167
1168
    /// @brief Finds a free V6 address/prefix within the given pool range.
1169
    ///
1170
    /// Calls the sflqPickFreeLease6 stored procedure to find a free address/prefix
1171
    /// within the SFLQ pool described by the given address range.  If there
1172
    /// are none free in the pool or the pool does not exist it returns ::.
1173
    /// Note the returned address/prefix must still be checked for HR conflicts.
1174
    ///
1175
    /// @param start_address first address in the pool.
1176
    /// @param end_address last address in the pool.
1177
    ///
1178
    /// @return A free V6 address/prefix or IOAddress::IPV6_ZERO_ADDRESS().
1179
    virtual asiolink::IOAddress sflqPickFreeLease6(asiolink::IOAddress start_address,
1180
                                                   asiolink::IOAddress end_address);
1181
1182
    /// @brief Fetch all SFLQ V4 pools.
1183
    ///
1184
    /// @return A collection of the SFLQ V4 pools.
1185
    virtual SflqPoolInfoCollectionPtr sflqPool4GetAll();
1186
1187
    /// @brief Fetch all SFLQ V4 pools belonging to a subnet.
1188
    ///
1189
    /// @param subnet_id id of the desired subnet.
1190
    ///
1191
    /// @return A collection of the SFLQ V4 pools.
1192
    virtual SflqPoolInfoCollectionPtr sflqPool4Get(SubnetID subnet_id);
1193
1194
    /// @brief Fetch all SFLQ V4 pools that overlap an address range.
1195
    ///
1196
    /// Since overlapping pools are supported, this function returns all V4
1197
    /// SFLQ pools whose range overlaps the given range.
1198
    ///
1199
    /// @param start_address range start address
1200
    /// @param end_address range end address
1201
    ///
1202
    /// @return A collection of the SFLQ V4 pools.
1203
    virtual SflqPoolInfoCollectionPtr sflqPool4Get(asiolink::IOAddress start_address,
1204
                                                   asiolink::IOAddress end_address);
1205
1206
    /// @brief Delete the SFLQ V4 pool that matches a start and end address.
1207
    ///
1208
    /// Deletes the flq_pool4 entry along with its free_lease4 data.
1209
    /// Fails If there are multiple pools that overlap the given range
1210
    /// unless force is true.
1211
    ///
1212
    /// @param start_address start address of the pool to delete.
1213
    /// @param end_address end address of the pool to delete.
1214
    /// @param force overrides check for overlapping pools when true. Defaults
1215
    /// to false.
1216
    ///
1217
    /// @return True a pool was deleted.
1218
    /// @throw InvalidOperation if force is false and overlapping pools are
1219
    /// detected.
1220
    virtual bool sflqPool4Del(asiolink::IOAddress start_address,
1221
                              asiolink::IOAddress end_address,
1222
                              bool force = false);
1223
1224
    /// @brief Fetch all SFLQ V6 pools.
1225
    ///
1226
    /// @return A collection of the SFLQ V6 pools.
1227
    virtual SflqPoolInfoCollectionPtr sflqPool6GetAll();
1228
1229
    /// @brief Fetch all SFLQ V6 pools belonging to a subnet.
1230
    ///
1231
    /// @param subnet_id id of the desired subnet.
1232
    ///
1233
    /// @return A collection of the SFLQ V6 pools.
1234
    virtual SflqPoolInfoCollectionPtr sflqPool6Get(SubnetID subnet_id);
1235
1236
    /// @brief Fetch all SFLQ V6 pools that overlap an address range.
1237
    ///
1238
    /// Since overlapping pools are supported, this function returns all V6
1239
    /// SFLQ pools whose range overlaps the given range.
1240
    ///
1241
    /// @param start_address range start address
1242
    /// @param end_address range end address
1243
    ///
1244
    /// @return A collection of the SFLQ V6 pools.
1245
    virtual SflqPoolInfoCollectionPtr sflqPool6Get(asiolink::IOAddress start_address,
1246
                                                   asiolink::IOAddress end_address);
1247
1248
    /// @brief Delete the SFLQ V6 pool that matches a start and end address.
1249
    ///
1250
    /// Deletes the flq_pool6 entry along with its free_lease6 data.
1251
    /// Fails If there are multiple pools that overlap the given range
1252
    /// unless force is true.
1253
    ///
1254
    /// @param start_address start address of the pool to delete.
1255
    /// @param end_address end address of the pool to delete.
1256
    /// @param force overrides check for overlapping pools when true. Defaults
1257
    /// to false.
1258
    ///
1259
    /// @return True a pool was deleted.
1260
    /// @throw InvalidOperation if force is false and overlapping pools are
1261
    /// detected.
1262
    virtual bool sflqPool6Del(asiolink::IOAddress start_address,
1263
                              asiolink::IOAddress end_address,
1264
                              bool force = false);
1265
1266
    /// @brief Determine if SFLQ alternate SQL statements should be used
1267
    /// for a given v4 lease
1268
    ///
1269
    /// @param lease v4 lease to test
1270
    ///
1271
    /// @return true if SFLQ is in use in this config and the lease's subnet uses
1272
    /// SFLQ allocation
1273
    static bool useSharedFlqStatement(Lease4Ptr lease);
1274
1275
    /// @brief Determine if SFLQ alternate SQL statements should be used
1276
    /// for a given v6 lease
1277
    ///
1278
    /// @param lease v6 lease to test
1279
    ///
1280
    /// @return true if SFLQ is in use in this config and the lease's subnet uses
1281
    /// SFLQ allocation for the lease's lease type.
1282
    static bool useSharedFlqStatement(Lease6Ptr lease);
1283
1284
    /// @brief Update in-memory stats when adding a v4 lease.
1285
    ///
1286
    /// @param lease Added lease.
1287
    static void updateStatsOnAdd(const Lease4Ptr& lease);
1288
1289
    /// @brief Update in-memory stats when adding a V6 lease.
1290
    ///
1291
    /// @param lease Added lease.
1292
    static void updateStatsOnAdd(const Lease6Ptr& lease);
1293
1294
    /// @brief Update in-memory stats when updating a v4 lease.
1295
    ///
1296
    /// @param existing Lease data before update.
1297
    /// @param lease Lease data after update.
1298
    static void updateStatsOnUpdate(const Lease4Ptr& existing,
1299
                                    const Lease4Ptr& lease);
1300
1301
    /// @brief Update in-memory stats when updating a v6 lease.
1302
    ///
1303
    /// @param existing Lease data before update.
1304
    /// @param lease Lease data after update.
1305
    static void updateStatsOnUpdate(const Lease6Ptr& existing,
1306
                                    const Lease6Ptr& lease);
1307
1308
    /// @brief Update in-memory stats when deleting a v4 lease.
1309
    ///
1310
    /// @param lease Deleted lease.
1311
    static void updateStatsOnDelete(const Lease4Ptr& lease);
1312
1313
    /// @brief Update in-memory stats when deleting a v6 lease.
1314
    ///
1315
    /// @param lease Deleted lease.
1316
    static void updateStatsOnDelete(const Lease6Ptr& lease);
1317
1318
    /// @brief Helper function that adds a value to an address stat's global,
1319
    /// subnet, and pool level values.
1320
    ///
1321
    /// @param stat base name of the statistic e.g. "assigned-addresses", "assigned-nas"
1322
    /// @param subnet_id id of desired subnet
1323
    /// @param pool pointer to the pool (if one) within the subnet, if empty
1324
    /// pool level is skipped.
1325
    /// @param value signed value to add to the statistic
1326
    static void bumpStat(const std::string& stat, SubnetID& subnet_id,
1327
                         PoolPtr pool, int value);
1328
1329
    /// @brief Helper function that adds a value to a prefix stat's global,
1330
    /// subnet, and pool level values.
1331
    ///
1332
    /// @param stat base name of the statistic e.g. "assigned-pds"
1333
    /// @param subnet_id id of desired subnet
1334
    /// @param pool pointer to the pool (if one) within the subnet, if empty
1335
    /// pool level is skipped.
1336
    /// @param value signed value to add to the statistic
1337
    static void bumpStatPrefix(const std::string& stat, SubnetID&
1338
                               subnet_id, PoolPtr pool, int value);
1339
protected:
1340
1341
    /// Extended information / Bulk Lease Query shared interface.
1342
1343
    /// @brief Decode parameters to set whether the lease extended info tables
1344
    /// are enabled.
1345
    ///
1346
    /// @note: common code in constructors.
1347
    ///
1348
    /// @param parameters The parameter map.
1349
    void setExtendedInfoTablesEnabled(const db::DatabaseConnection::ParameterMap& parameters);
1350
1351
    /// @brief Extract extended info from a lease6 and add it into tables.
1352
    ///
1353
    /// @param lease IPv6 lease to process.
1354
    /// @return true if something was added, false otherwise.
1355
    virtual bool addExtendedInfo6(const Lease6Ptr& lease);
1356
1357
    /// @brief Delete lease6 extended info from tables.
1358
    ///
1359
    /// @param addr The address of the lease.
1360
    virtual void deleteExtendedInfo6(const isc::asiolink::IOAddress& addr) = 0;
1361
1362
    /// @brief Add lease6 extended info into by-relay-id table.
1363
    ///
1364
    /// @param lease_addr The address of the lease.
1365
    /// @param relay_id The relay id from the relay header options.
1366
    virtual void addRelayId6(const isc::asiolink::IOAddress& lease_addr,
1367
                             const std::vector<uint8_t>& relay_id) = 0;
1368
1369
    /// @brief Add lease6 extended info into by-remote-id table.
1370
    ///
1371
    /// @param lease_addr The address of the lease.
1372
    /// @param remote_id The remote id from the relay header options.
1373
    virtual void addRemoteId6(const isc::asiolink::IOAddress& lease_addr,
1374
                              const std::vector<uint8_t>& remote_id) = 0;
1375
1376
private:
1377
1378
    /// @brief Holds the setting whether the lease extended info tables
1379
    /// are enabled or disabled. The default is disabled.
1380
    bool extended_info_tables_enabled_;
1381
};
1382
1383
}  // namespace dhcp
1384
}  // namespace isc
1385
1386
#endif // LEASE_MGR_H