1 // Copyright (C) 2012-2021 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 <database/db_exceptions.h>
13 #include <dhcp/duid.h>
14 #include <dhcp/option.h>
15 #include <dhcp/hwaddr.h>
16 #include <dhcpsrv/lease.h>
17 #include <dhcpsrv/subnet.h>
18 
19 #include <boost/noncopyable.hpp>
20 #include <boost/shared_ptr.hpp>
21 
22 #include <fstream>
23 #include <iostream>
24 #include <map>
25 #include <string>
26 #include <utility>
27 #include <vector>
28 
29 /// @file lease_mgr.h
30 /// @brief An abstract API for lease database
31 ///
32 /// This file contains declarations of Lease4, Lease6 and LeaseMgr classes.
33 /// They are essential components of the interface to any database backend.
34 /// Each concrete database backend (e.g. MySQL) will define a class derived
35 /// from LeaseMgr class.
36 namespace isc {
37 namespace dhcp {
38 
39 /// @brief Pair containing major and minor versions
40 typedef std::pair<uint32_t, uint32_t> VersionPair;
41 
42 /// @brief Wraps value holding size of the page with leases.
43 class LeasePageSize {
44 public:
45 
46     /// @brief Constructor.
47     ///
48     /// @param page_size page size value.
49     /// @throw OutOfRange if page size is 0 or greater than uint32_t numeric
50     /// limit.
51     explicit LeasePageSize(const size_t page_size);
52 
53     const size_t page_size_; ///< Holds page size.
54 };
55 
56 /// @brief Contains a single row of lease statistical data
57 ///
58 /// The contents of the row consist of a subnet ID, a lease
59 /// type, a lease state, and the number of leases in that state
60 /// for that type for that subnet ID.
61 struct LeaseStatsRow {
62     /// @brief Default constructor
LeaseStatsRowLeaseStatsRow63     LeaseStatsRow() :
64         subnet_id_(0), lease_type_(Lease::TYPE_NA),
65         lease_state_(Lease::STATE_DEFAULT), state_count_(0) {
66     }
67 
68     /// @brief Constructor
69     ///
70     /// Constructor which defaults the type to TYPE_NA.
71     ///
72     /// @param subnet_id The subnet id to which this data applies
73     /// @param lease_state The lease state counted
74     /// @param state_count The count of leases in the lease state
LeaseStatsRowLeaseStatsRow75     LeaseStatsRow(const SubnetID& subnet_id, const uint32_t lease_state,
76                   const int64_t state_count)
77         : subnet_id_(subnet_id), lease_type_(Lease::TYPE_NA),
78           lease_state_(lease_state), state_count_(state_count) {
79     }
80 
81     /// @brief Constructor
82     ///
83     /// @param subnet_id The subnet id to which this data applies
84     /// @param lease_type The lease type for this state count
85     /// @param lease_state The lease state counted
86     /// @param state_count The count of leases in the lease state
LeaseStatsRowLeaseStatsRow87     LeaseStatsRow(const SubnetID& subnet_id, const Lease::Type& lease_type,
88                   const uint32_t lease_state, const int64_t state_count)
89         : subnet_id_(subnet_id), lease_type_(lease_type),
90           lease_state_(lease_state), state_count_(state_count) {
91     }
92 
93     /// @brief Less-than operator
94     bool operator< (const LeaseStatsRow &rhs) const {
95         if (subnet_id_ < rhs.subnet_id_) {
96             return (true);
97         }
98 
99         if (subnet_id_ == rhs.subnet_id_ &&
100             lease_type_ < rhs.lease_type_) {
101                 return (true);
102         }
103 
104         if (subnet_id_ == rhs.subnet_id_ &&
105             lease_type_ == rhs.lease_type_ &&
106             lease_state_ < rhs.lease_state_) {
107                 return (true);
108         }
109 
110         return (false);
111     }
112 
113     /// @brief The subnet ID to which this data applies
114     SubnetID subnet_id_;
115     /// @brief The lease_type to which the count applies
116     Lease::Type lease_type_;
117     /// @brief The lease_state to which the count applies
118     uint32_t lease_state_;
119     /// @brief state_count The count of leases in the lease state
120     int64_t state_count_;
121 };
122 
123 /// @brief Base class for fulfilling a statistical lease data query
124 ///
125 /// LeaseMgr derivations implement this class such that it provides
126 /// up to date statistical lease data organized as rows of LeaseStatsRow
127 /// instances. The rows must be accessible in ascending order by subnet id.
128 class LeaseStatsQuery {
129 public:
130     /// @brief Defines the types of selection criteria supported
131     typedef enum {
132         ALL_SUBNETS,
133         SINGLE_SUBNET,
134         SUBNET_RANGE
135     } SelectMode;
136 
137     /// @brief Default constructor
138     /// The query created will return statistics for all subnets
139     LeaseStatsQuery();
140 
141     /// @brief Constructor to query for a single subnet's stats
142     ///
143     /// The query created will return statistics for a single subnet
144     ///
145     /// @param subnet_id id of the subnet for which stats are desired
146     /// @throw BadValue if subnet_id given is 0.
147     LeaseStatsQuery(const SubnetID& subnet_id);
148 
149     /// @brief Constructor to query for the stats for a range of subnets
150     ///
151     /// The query created will return statistics for the inclusive range of
152     /// subnets described by first and last subnet IDs.
153     ///
154     /// @param first_subnet_id first subnet in the range of subnets
155     /// @param last_subnet_id last subnet in the range of subnets
156     /// @throw BadValue if either value given is 0 or if last <= first.
157     LeaseStatsQuery(const SubnetID& first_subnet_id, const SubnetID& last_subnet_id);
158 
159     /// @brief virtual destructor
~LeaseStatsQuery()160     virtual ~LeaseStatsQuery() {};
161 
162     /// @brief Executes the query
163     ///
164     /// This method should conduct whatever steps are required to
165     /// calculate the lease statistical data by examining the
166     /// lease data and making that results available row by row.
start()167     virtual void start() {};
168 
169     /// @brief Fetches the next row of data
170     ///
171     /// @param[out] row Storage into which the row is fetched
172     ///
173     /// @return True if a row was fetched, false if there are no
174     /// more rows.
175     virtual bool getNextRow(LeaseStatsRow& row);
176 
177     /// @brief Returns the value of first subnet ID specified (or zero)
getFirstSubnetID()178     SubnetID getFirstSubnetID() const {
179         return (first_subnet_id_);
180     };
181 
182     /// @brief Returns the value of last subnet ID specified (or zero)
getLastSubnetID()183     SubnetID getLastSubnetID() const {
184         return (last_subnet_id_);
185     };
186 
187     /// @brief Returns the selection criteria mode
188     /// The value returned is based upon the constructor variant used
189     /// and it indicates which query variant will be executed.
getSelectMode()190     SelectMode getSelectMode() const {
191         return (select_mode_);
192     };
193 
194 protected:
195     /// @brief First (or only) subnet_id in the selection criteria
196     SubnetID first_subnet_id_;
197 
198     /// @brief Last subnet_id in the selection criteria when a range is given
199     SubnetID last_subnet_id_;
200 
201 private:
202     /// @brief Indicates the type of selection criteria specified
203     SelectMode select_mode_;
204 };
205 
206 /// @brief Defines a pointer to a LeaseStatsQuery.
207 typedef boost::shared_ptr<LeaseStatsQuery> LeaseStatsQueryPtr;
208 
209 /// @brief Defines a pointer to a LeaseStatsRow.
210 typedef boost::shared_ptr<LeaseStatsRow> LeaseStatsRowPtr;
211 
212 /// @brief Abstract Lease Manager
213 ///
214 /// This is an abstract API for lease database backends. It provides unified
215 /// interface to all backends. As this is an abstract class, it should not
216 /// be used directly, but rather specialized derived class should be used
217 /// instead.
218 ///
219 /// This class throws no exceptions.  However, methods in concrete
220 /// implementations of this class may throw exceptions: see the documentation
221 /// of those classes for details.
222 class LeaseMgr {
223 public:
224     /// @brief Constructor
225     ///
LeaseMgr()226     LeaseMgr()
227     {}
228 
229     /// @brief Destructor
~LeaseMgr()230     virtual ~LeaseMgr()
231     {}
232 
233     /// @brief Class method to return extended version info
234     /// This class method must be redeclared and redefined in derived classes
235     static std::string getDBVersion();
236 
237     /// @brief Adds an IPv4 lease.
238     ///
239     /// The lease may be modified due to sanity checks setting (see
240     /// LeaseSanityChecks in CfgConsistency) before being inserted. For
241     /// performance reasons, the sanity checks do not make a copy, but rather
242     /// modify lease in place if needed.
243     ///
244     /// @param lease lease to be added
245     ///
246     /// @result true if the lease was added, false if not (because a lease
247     ///         with the same address was already there or failed sanity checks)
248     virtual bool addLease(const Lease4Ptr& lease) = 0;
249 
250     /// @brief Adds an IPv6 lease.
251     ///
252     /// The lease may be modified due to sanity checks setting (see
253     /// LeaseSanityChecks in CfgConsistency) before being inserted. For
254     /// performance reasons, the sanity checks do not make a copy, but rather
255     /// modify lease in place if needed.
256     ///
257     /// @param lease lease to be added
258     ///
259     /// @result true if the lease was added, false if not (because a lease
260     ///         with the same address was already there or failed sanity checks)
261     virtual bool addLease(const Lease6Ptr& lease) = 0;
262 
263     /// @brief Returns an IPv4 lease for specified IPv4 address
264     ///
265     /// This method return a lease that is associated with a given address.
266     /// For other query types (by hardware addr, by client-id) there can be
267     /// several leases in different subnets (e.g. for mobile clients that
268     /// got address in different subnets). However, for a single address
269     /// there can be only one lease, so this method returns a pointer to
270     /// a single lease, not a container of leases.
271     ///
272     /// @param addr address of the searched lease
273     ///
274     /// @return smart pointer to the lease (or NULL if a lease is not found)
275     virtual Lease4Ptr getLease4(const isc::asiolink::IOAddress& addr) const = 0;
276 
277     /// @brief Returns existing IPv4 leases for specified hardware address.
278     ///
279     /// Although in the usual case there will be only one lease, for mobile
280     /// clients or clients with multiple static/fixed/reserved leases there
281     /// can be more than one. Thus return type is a container, not a single
282     /// pointer.
283     ///
284     /// @param hwaddr hardware address of the client
285     ///
286     /// @return lease collection
287     virtual Lease4Collection getLease4(const isc::dhcp::HWAddr& hwaddr) const = 0;
288 
289     /// @brief Returns existing IPv4 leases for specified hardware address
290     ///        and a subnet
291     ///
292     /// There can be at most one lease for a given HW address in a single
293     /// pool, so this method will either return a single lease or NULL.
294     ///
295     /// @param hwaddr hardware address of the client
296     /// @param subnet_id identifier of the subnet that lease must belong to
297     ///
298     /// @return a pointer to the lease (or NULL if a lease is not found)
299     virtual Lease4Ptr getLease4(const isc::dhcp::HWAddr& hwaddr,
300                                 SubnetID subnet_id) const = 0;
301 
302     /// @brief Returns existing IPv4 lease for specified client-id
303     ///
304     /// Although in the usual case there will be only one lease, for mobile
305     /// clients or clients with multiple static/fixed/reserved leases there
306     /// can be more than one. Thus return type is a container, not a single
307     /// pointer.
308     ///
309     /// @param clientid client identifier
310     ///
311     /// @return lease collection
312     virtual Lease4Collection getLease4(const ClientId& clientid) const = 0;
313 
314     /// @brief Returns existing IPv4 lease for specified client-id
315     ///
316     /// There can be at most one lease for a given client-id in a single
317     /// pool, so this method will either return a single lease or NULL.
318     ///
319     /// @param clientid client identifier
320     /// @param subnet_id identifier of the subnet that lease must belong to
321     ///
322     /// @return a pointer to the lease (or NULL if a lease is not found)
323     virtual Lease4Ptr getLease4(const ClientId& clientid,
324                                 SubnetID subnet_id) const = 0;
325 
326     /// @brief Returns all IPv4 leases for the particular subnet identifier.
327     ///
328     /// @param subnet_id subnet identifier.
329     ///
330     /// @return Lease collection (may be empty if no IPv4 lease found).
331     virtual Lease4Collection getLeases4(SubnetID subnet_id) const = 0;
332 
333     /// @brief Returns all IPv4 leases for the particular hostname.
334     ///
335     /// @param hostname hostname in lower case.
336     ///
337     /// @return Lease collection (may be empty if no IPv4 lease found).
338     virtual Lease4Collection getLeases4(const std::string& hostname) const = 0;
339 
340     /// @brief Returns all IPv4 leases.
341     ///
342     /// @return Lease collection (may be empty if no IPv4 lease found).
343     virtual Lease4Collection getLeases4() const = 0;
344 
345     /// @brief Returns range of IPv4 leases using paging.
346     ///
347     /// This method implements paged browsing of the lease database. The first
348     /// parameter specifies a page size. The second parameter is optional and
349     /// specifies the starting address of the range. This address is excluded
350     /// from the returned range. The IPv4 zero address (default) denotes that
351     /// the first page should be returned. There is no guarantee about the
352     /// order of returned leases.
353     ///
354     /// The typical usage of this method is as follows:
355     /// - Get the first page of leases by specifying IPv4 zero address as the
356     ///   beginning of the range.
357     /// - Last address of the returned range should be used as a starting
358     ///   address for the next page in the subsequent call.
359     /// - If the number of leases returned is lower than the page size, it
360     ///   indicates that the last page has been retrieved.
361     /// - If there are no leases returned it indicates that the previous page
362     ///   was the last page.
363     ///
364     /// @param lower_bound_address IPv4 address used as lower bound for the
365     /// returned range.
366     /// @param page_size maximum size of the page returned.
367     ///
368     /// @return Lease collection (may be empty if no IPv4 lease found).
369     virtual Lease4Collection
370     getLeases4(const asiolink::IOAddress& lower_bound_address,
371                const LeasePageSize& page_size) const = 0;
372 
373     /// @brief Returns existing IPv6 lease for a given IPv6 address.
374     ///
375     /// For a given address, we assume that there will be only one lease.
376     /// The assumption here is that there will not be site or link-local
377     /// addresses used, so there is no way of having address duplication.
378     ///
379     /// @param type specifies lease type: (NA, TA or PD)
380     /// @param addr address of the searched lease
381     ///
382     /// @return smart pointer to the lease (or NULL if a lease is not found)
383     virtual Lease6Ptr getLease6(Lease::Type type,
384                                 const isc::asiolink::IOAddress& addr) const = 0;
385 
386     /// @brief Returns existing IPv6 leases for a given DUID+IA combination
387     ///
388     /// Although in the usual case there will be only one lease, for mobile
389     /// clients or clients with multiple static/fixed/reserved leases there
390     /// can be more than one. Thus return type is a container, not a single
391     /// pointer.
392     ///
393     /// @param type specifies lease type: (NA, TA or PD)
394     /// @param duid client DUID
395     /// @param iaid IA identifier
396     ///
397     /// @return Lease collection (may be empty if no lease is found)
398     virtual Lease6Collection getLeases6(Lease::Type type, const DUID& duid,
399                                         uint32_t iaid) const = 0;
400 
401     /// @brief Returns existing IPv6 lease for a given DUID+IA combination
402     ///
403     /// There may be more than one address, temp. address or prefix
404     /// for specified duid/iaid/subnet-id tuple.
405     ///
406     /// @param type specifies lease type: (NA, TA or PD)
407     /// @param duid client DUID
408     /// @param iaid IA identifier
409     /// @param subnet_id subnet id of the subnet the lease belongs to
410     ///
411     /// @return Lease collection (may be empty if no lease is found)
412     virtual Lease6Collection getLeases6(Lease::Type type, const DUID& duid,
413                                         uint32_t iaid, SubnetID subnet_id) const = 0;
414 
415     /// @brief returns zero or one IPv6 lease for a given duid+iaid+subnet_id
416     ///
417     /// This function is mostly intended to be used in unit-tests during the
418     /// transition from single to multi address per IA. It may also be used
419     /// in other cases where at most one lease is expected in the database.
420     ///
421     /// It is a wrapper around getLeases6(), which returns a collection of
422     /// leases. That collection can be converted into a single pointer if
423     /// there are no leases (NULL pointer) or one lease (use that single lease).
424     /// If there are more leases in the collection, the function will
425     /// throw MultipleRecords exception.
426     ///
427     /// Note: This method is not virtual on purpose. It is common for all
428     /// backends.
429     ///
430     /// @param type specifies lease type: (NA, TA or PD)
431     /// @param duid client DUID
432     /// @param iaid IA identifier
433     /// @param subnet_id subnet id of the subnet the lease belongs to
434     ///
435     /// @throw MultipleRecords if there is more than one lease matching
436     ///
437     /// @return Lease pointer (or NULL if none is found)
438     Lease6Ptr getLease6(Lease::Type type, const DUID& duid,
439                         uint32_t iaid, SubnetID subnet_id) const;
440 
441     /// @brief Returns all IPv6 leases for the particular subnet identifier.
442     ///
443     /// @param subnet_id subnet identifier.
444     ///
445     /// @return Lease collection (may be empty if no IPv6 lease found).
446     virtual Lease6Collection getLeases6(SubnetID subnet_id) const = 0;
447 
448     /// @brief Returns all IPv6 leases for the particular hostname.
449     ///
450     /// @param hostname hostname in lower case.
451     ///
452     /// @return Lease collection (may be empty if no IPv6 lease found).
453     virtual Lease6Collection getLeases6(const std::string& hostname) const = 0;
454 
455     /// @brief Returns all IPv6 leases.
456     ///
457     /// @return Lease collection (may be empty if no IPv6 lease found).
458     virtual Lease6Collection getLeases6() const = 0;
459 
460     /// @brief Returns collection of leases for matching DUID
461     ///
462     /// @return Lease collection
463     /// (may be empty if no IPv6 lease found for the DUID).
464     virtual Lease6Collection getLeases6(const DUID& duid) const = 0;
465 
466     /// @brief Returns range of IPv6 leases using paging.
467     ///
468     /// This method implements paged browsing of the lease database. The first
469     /// parameter specifies a page size. The second parameter is optional and
470     /// specifies the starting address of the range. This address is excluded
471     /// from the returned range. The IPv6 zero address (default) denotes that
472     /// the first page should be returned. There is no guarantee about the
473     /// order of returned leases.
474     ///
475     /// The typical usage of this method is as follows:
476     /// - Get the first page of leases by specifying IPv6 zero address as the
477     ///   beginning of the range.
478     /// - Last address of the returned range should be used as a starting
479     ///   address for the next page in the subsequent call.
480     /// - If the number of leases returned is lower than the page size, it
481     ///   indicates that the last page has been retrieved.
482     /// - If there are no leases returned it indicates that the previous page
483     ///   was the last page.
484     ///
485     /// @param lower_bound_address IPv6 address used as lower bound for the
486     /// returned range.
487     /// @param page_size maximum size of the page returned.
488     ///
489     /// @return Lease collection (may be empty if no IPv6 lease found).
490     virtual Lease6Collection
491     getLeases6(const asiolink::IOAddress& lower_bound_address,
492                const LeasePageSize& page_size) const = 0;
493 
494     /// @brief Returns a collection of expired DHCPv4 leases.
495     ///
496     /// This method returns at most @c max_leases expired leases. The leases
497     /// returned haven't been reclaimed, i.e. the database query must exclude
498     /// reclaimed leases from the results returned.
499     ///
500     /// @param [out] expired_leases A container to which expired leases returned
501     /// by the database backend are added.
502     /// @param max_leases A maximum number of leases to be returned. If this
503     /// value is set to 0, all expired (but not reclaimed) leases are returned.
504     virtual void getExpiredLeases4(Lease4Collection& expired_leases,
505                                    const size_t max_leases) const = 0;
506 
507     /// @brief Returns a collection of expired DHCPv6 leases.
508     ///
509     /// This method returns at most @c max_leases expired leases. The leases
510     /// returned haven't been reclaimed, i.e. the database query must exclude
511     /// reclaimed leases from the results returned.
512     ///
513     /// @param [out] expired_leases A container to which expired leases returned
514     /// by the database backend are added.
515     /// @param max_leases A maximum number of leases to be returned. If this
516     /// value is set to 0, all expired (but not reclaimed) leases are returned.
517     virtual void getExpiredLeases6(Lease6Collection& expired_leases,
518                                    const size_t max_leases) const = 0;
519 
520     /// @brief Updates IPv4 lease.
521     ///
522     /// @param lease4 The lease to be updated.
523     ///
524     /// If no such lease is present, an exception will be thrown.
525     virtual void updateLease4(const Lease4Ptr& lease4) = 0;
526 
527     /// @brief Updates IPv6 lease.
528     ///
529     /// @param lease6 The lease to be updated.
530     virtual void updateLease6(const Lease6Ptr& lease6) = 0;
531 
532     /// @brief Deletes an IPv4 lease.
533     ///
534     /// @param lease IPv4 lease to be deleted.
535     ///
536     /// @return true if deletion was successful, false if no such lease exists.
537     ///
538     /// @throw isc::dhcp::DbOperationError An operation on the open database has
539     ///        failed.
540     virtual bool deleteLease(const Lease4Ptr& lease) = 0;
541 
542     /// @brief Deletes an IPv6 lease.
543     ///
544     /// @param lease IPv6 lease to be deleted.
545     ///
546     /// @return true if deletion was successful, false if no such lease exists.
547     ///
548     /// @throw isc::db::DbOperationError An operation on the open database has
549     ///        failed.
550     virtual bool deleteLease(const Lease6Ptr& lease) = 0;
551 
552     /// @brief Deletes all expired and reclaimed DHCPv4 leases.
553     ///
554     /// @param secs Number of seconds since expiration of leases before
555     /// they can be removed. Leases which have expired later than this
556     /// time will not be deleted.
557     ///
558     /// @return Number of leases deleted.
559     virtual uint64_t deleteExpiredReclaimedLeases4(const uint32_t secs) = 0;
560 
561     /// @brief Deletes all expired and reclaimed DHCPv6 leases.
562     ///
563     /// @param secs Number of seconds since expiration of leases before
564     /// they can be removed. Leases which have expired later than this
565     /// time will not be deleted.
566     ///
567     /// @return Number of leases deleted.
568     virtual uint64_t deleteExpiredReclaimedLeases6(const uint32_t secs) = 0;
569 
570     /// @brief Recalculates per-subnet and global stats for IPv4 leases
571     ///
572     /// This method recalculates the following statistics:
573     /// per-subnet:
574     /// - assigned-addresses
575     /// - declined-addresses
576     /// global:
577     /// - declined-addresses
578     ///
579     /// It invokes the virtual method, startLeaseStatsQuery4(), which
580     /// returns an instance of an LeaseStatsQuery.  The query
581     /// query contains a "result set"  where each row is an LeaseStatRow
582     /// that contains a subnet id, a lease type (currently always TYPE_NA),
583     /// a lease state, and the number of leases of that type, in that state
584     /// and is ordered by subnet id.  The method iterates over the
585     /// result set rows, setting the appropriate statistic per subnet and
586     /// adding to the appropriate global statistic.
587     void recountLeaseStats4();
588 
589     /// @brief Creates and runs the IPv4 lease stats query for all subnets
590     ///
591     /// LeaseMgr derivations implement this method such that it creates and
592     /// returns an instance of an LeaseStatsQuery whose result set has been
593     /// populated with up to date IPv4 lease statistical data for all subnets.
594     /// Each row of the result set is an LeaseStatRow which ordered ascending
595     /// by subnet ID.
596     ///
597     /// @return A populated LeaseStatsQuery
598     virtual LeaseStatsQueryPtr startLeaseStatsQuery4();
599 
600     /// @brief Creates and runs the IPv4 lease stats query for a single subnet
601     ///
602     /// LeaseMgr derivations implement this method such that it creates and
603     /// returns an instance of an LeaseStatsQuery whose result set has been
604     /// populated with up to date IPv4 lease statistical data for a single
605     /// subnet.  Each row of the result set is an LeaseStatRow.
606     ///
607     /// @param subnet_id id of the subnet for which stats are desired
608     /// @return A populated LeaseStatsQuery
609     virtual LeaseStatsQueryPtr startSubnetLeaseStatsQuery4(const SubnetID& subnet_id);
610 
611     /// @brief Creates and runs the IPv4 lease stats query for a single subnet
612     ///
613     /// LeaseMgr derivations implement this method such that it creates and
614     /// returns an instance of an LeaseStatsQuery whose result set has been
615     /// populated with up to date IPv4 lease statistical data for an inclusive
616     /// range of subnets. Each row of the result set is an LeaseStatRow which
617     /// ordered ascending by subnet ID.
618     ///
619     /// @param first_subnet_id first subnet in the range of subnets
620     /// @param last_subnet_id last subnet in the range of subnets
621     /// @return A populated LeaseStatsQuery
622     virtual LeaseStatsQueryPtr startSubnetRangeLeaseStatsQuery4(const SubnetID& first_subnet_id,
623                                                                 const SubnetID& last_subnet_id);
624 
625     /// @brief Recalculates per-subnet and global stats for IPv6 leases
626     ///
627     /// This method recalculates the following statistics:
628     /// per-subnet:
629     /// - assigned-nas
630     /// - declined-addresses
631     /// - assigned-pds
632     /// global:
633     /// - assigned-nas
634     /// - declined-addresses
635     /// - assigned-pds
636     ///
637     /// It invokes the virtual method, startLeaseStatsQuery6(), which
638     /// returns an instance of an LeaseStatsQuery.  The query contains
639     /// a "result set" where each row is an LeaseStatRow that contains
640     /// a subnet id, a lease type, a lease state, and the number of leases
641     /// of that type, in that state and is ordered by subnet id. The method
642     /// iterates over the result set rows, setting the appropriate statistic
643     /// per subnet and adding to the appropriate global statistic.
644     void recountLeaseStats6();
645 
646     /// @brief Creates and runs the IPv6 lease stats query for all subnets
647     ///
648     /// LeaseMgr derivations implement this method such that it creates and
649     /// returns an instance of an LeaseStatsQuery whose result set has been
650     /// populated with up to date IPv6 lease statistical data for all subnets.
651     /// Each row of the result set is an LeaseStatRow which ordered ascending
652     /// by subnet ID.
653     ///
654     /// @return A populated LeaseStatsQuery
655     virtual LeaseStatsQueryPtr startLeaseStatsQuery6();
656 
657     /// @brief Creates and runs the IPv6 lease stats query for a single subnet
658     ///
659     /// LeaseMgr derivations implement this method such that it creates and
660     /// returns an instance of an LeaseStatsQuery whose result set has been
661     /// populated with up to date IPv6 lease statistical data for a single
662     /// subnet.  Each row of the result set is an LeaseStatRow.
663     ///
664     /// @param subnet_id id of the subnet for which stats are desired
665     /// @return A populated LeaseStatsQuery
666     virtual LeaseStatsQueryPtr startSubnetLeaseStatsQuery6(const SubnetID& subnet_id);
667 
668     /// @brief Creates and runs the IPv6 lease stats query for a single subnet
669     ///
670     /// LeaseMgr derivations implement this method such that it creates and
671     /// returns an instance of an LeaseStatsQuery whose result set has been
672     /// populated with up to date IPv6 lease statistical data for an inclusive
673     /// range of subnets. Each row of the result set is an LeaseStatRow which
674     /// ordered ascending by subnet ID.
675     ///
676     /// @param first_subnet_id first subnet in the range of subnets
677     /// @param last_subnet_id last subnet in the range of subnets
678     /// @return A populated LeaseStatsQuery
679     virtual LeaseStatsQueryPtr startSubnetRangeLeaseStatsQuery6(const SubnetID& first_subnet_id,
680                                                                 const SubnetID& last_subnet_id);
681 
682     /// @brief Virtual method which removes specified leases.
683     ///
684     /// This rather dangerous method is able to remove all leases from specified
685     /// subnet.
686     ///
687     /// @param subnet_id identifier of the subnet (or 0 for all subnets)
688     /// @return number of leases removed.
689     virtual size_t wipeLeases4(const SubnetID& subnet_id) = 0;
690 
691     /// @brief Virtual method which removes specified leases.
692     ///
693     /// This rather dangerous method is able to remove all leases from specified
694     /// subnet.
695     ///
696     /// @param subnet_id identifier of the subnet (or 0 for all subnets)
697     /// @return number of leases removed.
698     virtual size_t wipeLeases6(const SubnetID& subnet_id) = 0;
699 
700     /// @brief Return backend type
701     ///
702     /// Returns the type of the backend (e.g. "mysql", "memfile" etc.)
703     ///
704     /// @return Type of the backend.
705     virtual std::string getType() const = 0;
706 
707     /// @brief Returns backend name.
708     ///
709     /// If the backend is a database, this is the name of the database or the
710     /// file.  Otherwise it is just the same as the type.
711     ///
712     /// @return Name of the backend.
713     virtual std::string getName() const = 0;
714 
715     /// @brief Returns description of the backend.
716     ///
717     /// This description may be multiline text that describes the backend.
718     ///
719     /// @return Description of the backend.
720     virtual std::string getDescription() const = 0;
721 
722     /// @brief Returns backend version.
723     ///
724     /// @return Version number as a pair of unsigned integers.  "first" is the
725     ///         major version number, "second" the minor number.
726     ///
727     /// @todo: We will need to implement 3 version functions eventually:
728     /// A. abstract API version
729     /// B. backend version
730     /// C. database version (stored in the database scheme)
731     ///
732     /// and then check that:
733     /// B>=A and B=C (it is ok to have newer backend, as it should be backward
734     /// compatible)
735     /// Also if B>C, some database upgrade procedure may be triggered
736     virtual VersionPair getVersion() const = 0;
737 
738     /// @brief Commit Transactions
739     ///
740     /// Commits all pending database operations.  On databases that don't
741     /// support transactions, this is a no-op.
742     virtual void commit() = 0;
743 
744     /// @brief Rollback Transactions
745     ///
746     /// Rolls back all pending database operations.  On databases that don't
747     /// support transactions, this is a no-op.
748     virtual void rollback() = 0;
749 
750     /// @brief Sets IO service to be used by the Lease Manager.
751     ///
752     /// @param io_service IOService object, used for all ASIO operations.
setIOService(const isc::asiolink::IOServicePtr & io_service)753     static void setIOService(const isc::asiolink::IOServicePtr& io_service) {
754         io_service_ = io_service;
755     }
756 
757     /// @brief Returns pointer to the IO service.
getIOService()758     static isc::asiolink::IOServicePtr& getIOService() {
759         return (io_service_);
760     }
761 
762 private:
763     /// The IOService object, used for all ASIO operations.
764     static isc::asiolink::IOServicePtr io_service_;
765 };
766 
767 }  // namespace dhcp
768 }  // namespace isc
769 
770 #endif // LEASE_MGR_H
771