memfile_lease_mgr.h 24.6 KB
Newer Older
1
// Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC")
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.

#ifndef MEMFILE_LEASE_MGR_H
#define MEMFILE_LEASE_MGR_H

18
#include <asiolink/interval_timer.h>
19
#include <dhcp/hwaddr.h>
20 21
#include <dhcpsrv/csv_lease_file4.h>
#include <dhcpsrv/csv_lease_file6.h>
22 23
#include <dhcpsrv/lease_mgr.h>

24 25
#include <boost/multi_index/indexed_by.hpp>
#include <boost/multi_index/member.hpp>
26 27
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index_container.hpp>
28
#include <boost/multi_index/composite_key.hpp>
29

30 31 32
namespace isc {
namespace dhcp {

33 34 35 36 37 38
/// @brief Concrete implementation of a lease database backend using flat file.
///
/// This class implements a lease database backend using CSV files to store
/// DHCPv4 and DHCPv6 leases on disk. The format of the files is determined
/// by the @c CSVLeaseFile4 and @c CSVLeaseFile6 classes.
///
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
/// In order to obtain good performance, the backend stores leases
/// incrementally, i.e. updates to leases are appended at the end of the lease
/// file. To record the deletion of a lease, the lease record is appended to
/// the lease file with the valid lifetime set to 0. However, this may result
/// in a significant growth of the lease file size over time, because the lease
/// file will contain many entries for each lease. In order to mitigate this
/// problem, the backend implements the Lease File Cleanup mechanism which is
/// described on the Kea wiki: http://kea.isc.org/wiki/LFCDesign.
///
/// The backend installs an @c asiolink::IntervalTimer to periodically execute
/// the @c Memfile_LeaseMgr::lfcCallback. This callback function controls
/// the startup of the background process which removes redundant information
/// from the lease file(s). Note that the @c asiolink::IntervalTimer uses
/// @c asiolink::IOService to execute the callback. The @c LeaseMgr class
/// creates this object, which can be obtained by the caller using the
/// @c LeaseMgr::getIOService. The caller should later call an appropriate
/// method, @c asio::io_service::poll_one to execute the callback when
/// the timer is ready.
57
///
58 59 60
/// When the backend is starting up, it reads leases from the lease file (one
/// by one) and adds them to the in-memory container as follows:
/// - if the lease record being parsed identifies a lease which is not present
61 62
/// in the container, and the lease has valid lifetime greater than 0,
/// the lease is added to the container,
63 64
/// - if the lease record being parsed identifies a lease which is present in
/// the container, and the valid lifetime of the lease record being parsed is
65
/// greater than 0, the lease in the container is updated
66 67 68
/// - if the lease record being parsed has valid lifetime equal to 0, and the
/// corresponding lease exists in the container, the lease is removed from
/// the container.
69 70 71 72 73 74 75
///
/// After the container holding leases is initialized, each subsequent update,
/// removal or addition of the lease is appended to the lease file
/// synchronously.
///
/// Originally, the Memfile backend didn't write leases to disk. This was
/// particularly useful for testing server performance in non-disk bound
76 77 78 79
/// conditions. In order to preserve this capability, the new parameter
/// "persist=true|false" has been introduced in the database access string.
/// For example, database access string: "type=memfile persist=true"
/// enables writes of leases to a disk.
80
///
81 82 83 84
/// The lease file locations can be specified with the "name=[path]"
/// parameter in the database access string. The [path] is the
/// absolute path to the file (including file name). If this parameter
/// is not specified, the default location in the installation
85 86
/// directory is used: var/kea/kea-leases4.csv and
/// var/kea/kea-leases6.csv.
87 88 89
class Memfile_LeaseMgr : public LeaseMgr {
public:

90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
    /// @defgroup versions Specified memfile backend version.
    ///
    /// @brief Defines major version of the memfile backend.
    ///
    /// Version history:
    /// 1.0 - initial version (released in Kea 0.9)
    /// 2.0 - hwaddr column added (to be released in Kea 0.9.1)
    ///
    /// @{
    static const int MAJOR_VERSION = 2;

    /// Defines minor version of the memfile backend.
    static const int MINOR_VERSION = 0;

    /// @}


107 108 109 110 111 112 113 114 115 116 117
    /// @brief Specifies universe (V4, V6)
    ///
    /// This enumeration is used by various functions in Memfile Lease Manager,
    /// to identify the lease type referred to. In particular, it is used by
    /// functions operating on the lease files to distinguish between lease
    /// files for DHCPv4 and DHCPv6.
    enum Universe {
        V4,
        V6
    };

118 119 120 121 122 123
    /// @brief The sole lease manager constructor
    ///
    /// dbconfig is a generic way of passing parameters. Parameters
    /// are passed in the "name=value" format, separated by spaces.
    /// Values may be enclosed in double quotes, if needed.
    ///
124 125 126
    /// @param parameters A data structure relating keywords and values
    ///        concerned with the database.
    Memfile_LeaseMgr(const ParameterMap& parameters);
127 128 129 130 131 132 133

    /// @brief Destructor (closes file)
    virtual ~Memfile_LeaseMgr();

    /// @brief Adds an IPv4 lease.
    ///
    /// @param lease lease to be added
Tomek Mrugalski's avatar
Tomek Mrugalski committed
134
    virtual bool addLease(const Lease4Ptr& lease);
135 136 137 138

    /// @brief Adds an IPv6 lease.
    ///
    /// @param lease lease to be added
Tomek Mrugalski's avatar
Tomek Mrugalski committed
139
    virtual bool addLease(const Lease6Ptr& lease);
140 141 142

    /// @brief Returns existing IPv4 lease for specified IPv4 address.
    ///
143 144 145 146
    /// This function returns a copy of the lease. The modification in the
    /// return lease does not affect the instance held in the lease storage.
    ///
    /// @param addr An address of the searched lease.
147 148
    ///
    /// @return a collection of leases
149
    virtual Lease4Ptr getLease4(const isc::asiolink::IOAddress& addr) const;
150 151 152 153 154 155 156 157 158 159 160

    /// @brief Returns existing IPv4 leases for specified hardware address.
    ///
    /// Although in the usual case there will be only one lease, for mobile
    /// clients or clients with multiple static/fixed/reserved leases there
    /// can be more than one. Thus return type is a container, not a single
    /// pointer.
    ///
    /// @param hwaddr hardware address of the client
    ///
    /// @return lease collection
161
    virtual Lease4Collection getLease4(const isc::dhcp::HWAddr& hwaddr) const;
162

163
    /// @brief Returns existing IPv4 lease for specified hardware address
164 165
    ///        and a subnet
    ///
166 167
    /// This function returns a copy of the lease. The modification in the
    /// return lease does not affect the instance held in the lease storage.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
168
    ///
169 170 171 172 173 174 175 176 177 178 179 180
    /// There can be at most one lease for a given HW address in a single
    /// pool, so this method with either return a single lease or NULL.
    ///
    /// @param hwaddr hardware address of the client
    /// @param subnet_id identifier of the subnet that lease must belong to
    ///
    /// @return a pointer to the lease (or NULL if a lease is not found)
    virtual Lease4Ptr getLease4(const HWAddr& hwaddr,
                                SubnetID subnet_id) const;

    /// @brief Returns existing IPv4 lease for specified client-id
    ///
181 182
    /// @param client_id client identifier
    virtual Lease4Collection getLease4(const ClientId& client_id) const;
183

184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
    /// @brief Returns IPv4 lease for specified client-id/hwaddr/subnet-id tuple
    ///
    /// There can be at most one lease for a given client-id/hwaddr tuple
    /// in a single pool, so this method with either return a single lease
    /// or NULL.
    ///
    /// @param clientid client identifier
    /// @param hwaddr hardware address of the client
    /// @param subnet_id identifier of the subnet that lease must belong to
    ///
    /// @return a pointer to the lease (or NULL if a lease is not found)
    virtual Lease4Ptr getLease4(const ClientId& clientid,
                                const HWAddr& hwaddr,
                                SubnetID subnet_id) const;

199 200
    /// @brief Returns existing IPv4 lease for specified client-id
    ///
201 202 203
    /// This function returns a copy of the lease. The modification in the
    /// return lease does not affect the instance held in the lease storage.
    ///
204 205 206 207 208 209 210 211 212 213 214 215
    /// There can be at most one lease for a given HW address in a single
    /// pool, so this method with either return a single lease or NULL.
    ///
    /// @param clientid client identifier
    /// @param subnet_id identifier of the subnet that lease must belong to
    ///
    /// @return a pointer to the lease (or NULL if a lease is not found)
    virtual Lease4Ptr getLease4(const ClientId& clientid,
                                SubnetID subnet_id) const;

    /// @brief Returns existing IPv6 lease for a given IPv6 address.
    ///
216 217 218
    /// This function returns a copy of the lease. The modification in the
    /// return lease does not affect the instance held in the lease storage.
    ///
219
    /// @param type specifies lease type: (NA, TA or PD)
220
    /// @param addr An address of the searched lease.
221 222
    ///
    /// @return smart pointer to the lease (or NULL if a lease is not found)
223
    virtual Lease6Ptr getLease6(Lease::Type type,
224
                                const isc::asiolink::IOAddress& addr) const;
225

226 227
    /// @brief Returns existing IPv6 lease for a given DUID + IA + lease type
    /// combination
Tomek Mrugalski's avatar
Tomek Mrugalski committed
228
    ///
229
    /// @param type specifies lease type: (NA, TA or PD)
230 231 232 233
    /// @param duid client DUID
    /// @param iaid IA identifier
    ///
    /// @return collection of IPv6 leases
234
    virtual Lease6Collection getLeases6(Lease::Type type,
235
                                        const DUID& duid, uint32_t iaid) const;
236

237 238
    /// @brief Returns existing IPv6 lease for a given DUID + IA + subnet-id +
    /// lease type combination.
239
    ///
240 241
    /// This function returns a copy of the lease. The modification in the
    /// return lease does not affect the instance held in the lease storage.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
242
    ///
243
    /// @param type specifies lease type: (NA, TA or PD)
244 245 246 247
    /// @param duid client DUID
    /// @param iaid IA identifier
    /// @param subnet_id identifier of the subnet the lease must belong to
    ///
248
    /// @return lease collection (may be empty if no lease is found)
249
    virtual Lease6Collection getLeases6(Lease::Type type, const DUID& duid,
250 251
                                        uint32_t iaid,
                                        SubnetID subnet_id) const;
252 253 254

    /// @brief Updates IPv4 lease.
    ///
255 256
    /// @warning This function does not validate the pointer to the lease.
    /// It is caller's responsibility to pass the valid pointer.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
257
    ///
258 259 260
    /// @param lease4 The lease to be updated.
    ///
    /// If no such lease is present, an exception will be thrown.
261
    virtual void updateLease4(const Lease4Ptr& lease4);
262

263
    /// @brief Updates IPv6 lease.
264
    ///
265 266
    /// @warning This function does not validate the pointer to the lease.
    /// It is caller's responsibility to pass the valid pointer.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
267
    ///
268
    /// @param lease6 The lease to be updated.
269 270
    ///
    /// If no such lease is present, an exception will be thrown.
271
    virtual void updateLease6(const Lease6Ptr& lease6);
272 273 274

    /// @brief Deletes a lease.
    ///
275 276
    /// @param addr Address of the lease to be deleted. (This can be IPv4 or
    ///        IPv6.)
277 278
    ///
    /// @return true if deletion was successful, false if no such lease exists
279
    virtual bool deleteLease(const isc::asiolink::IOAddress& addr);
280

281 282 283 284 285 286 287 288 289
    /// @brief Return backend type
    ///
    /// Returns the type of the backend.
    ///
    /// @return Type of the backend.
    virtual std::string getType() const {
        return (std::string("memfile"));
    }

290 291
    /// @brief Returns backend name.
    ///
292
    /// For now, memfile can only store data in memory.
293 294 295
    ///
    /// @return Name of the backend.
    virtual std::string getName() const {
296
        return ("memory");
297
    }
298 299 300 301

    /// @brief Returns description of the backend.
    ///
    /// This description may be multiline text that describes the backend.
302 303 304
    ///
    /// @return Description of the backend.
    virtual std::string getDescription() const;
305 306

    /// @brief Returns backend version.
307 308 309
    ///
    /// @return Version number as a pair of unsigned integers.  "first" is the
    ///         major version number, "second" the minor number.
310
    virtual std::pair<uint32_t, uint32_t> getVersion() const {
311
        return (std::make_pair(MAJOR_VERSION, MINOR_VERSION));
312 313 314 315 316 317 318 319 320 321 322 323 324
    }

    /// @brief Commit Transactions
    ///
    /// Commits all pending database operations.  On databases that don't
    /// support transactions, this is a no-op.
    virtual void commit();

    /// @brief Rollback Transactions
    ///
    /// Rolls back all pending database operations.  On databases that don't
    /// support transactions, this is a no-op.
    virtual void rollback();
325

326 327 328 329 330 331 332 333 334 335 336 337 338
    /// @brief Returns the interval at which the @c IOService events should
    /// be released.
    ///
    /// The Memfile backend may install a timer to execute the Lease File
    /// Cleanup periodically. If this timer is installed, the method returns
    /// the LFC interval in milliseconds.
    ///
    /// @return A maximum interval (in seconds) at which the @c IOService
    /// should be executed. A value of 0 means that no timers are installed
    /// and that there is no requirement for the @c IOService to be
    /// executed at any specific interval.
    virtual uint32_t getIOServiceExecInterval() const;

339 340 341 342 343 344 345 346
    /// @brief Returns default path to the lease file.
    ///
    /// @param u Universe (V4 or V6).
    std::string getDefaultLeaseFilePath(Universe u) const;

    /// @brief Returns an absolute path to the lease file.
    ///
    /// @param u Universe (V4 or V6).
347 348 349 350
    ///
    /// @return Absolute path to the lease file or empty string if no lease
    /// file is used.
    std::string getLeaseFilePath(Universe u) const;
351 352 353 354 355 356 357 358 359 360 361 362 363 364

    /// @brief Specifies whether or not leases are written to disk.
    ///
    /// It is possible that leases for DHCPv4 are written to disk whereas leases
    /// for DHCPv6 are not; or vice versa. The argument of the method specifies
    /// the type of lease in that respect.
    ///
    /// @param u Universe (V4 or V6).
    ///
    /// @return true if leases are written to lease file; if false is
    /// returned, leases will be held in memory and will be lost upon
    /// server shut down.
    bool persistLeases(Universe u) const;

365 366
protected:

367 368 369 370 371 372
    /// @brief A callback function triggering Lease File Cleanup.
    ///
    /// This method is virtual so as it can be overriden and customized in
    /// the unit tests. In particular, the unit test which checks that the
    /// callback function has been executed would override this function
    /// to increase the execution counter each time it is executed.
373 374 375 376
    ///
    /// @todo Once the callback is implemented, there is a need to
    /// extend the documentation of this method. Currently, it simply
    /// logs that it has been called.
377 378 379 380
    virtual void lfcCallback();

private:

381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424
    /// @brief Load all DHCPv4 leases from the file.
    ///
    /// This method loads all DHCPv4 leases from a file to memory. It removes
    /// existing leases before reading a file.
    ///
    /// @throw isc::DbOperationError If failed to read a lease from the lease
    /// file.
    void load4();

    /// @brief Loads a single DHCPv4 lease from the file.
    ///
    /// This method reads a single lease record from the lease file. If the
    /// corresponding record doesn't exist in the in-memory container, the
    /// lease is added to the container (except for a lease which valid lifetime
    /// is 0). If the corresponding lease exists, the lease being read updates
    /// the existing lease. If the lease being read from the lease file has
    /// valid lifetime of 0 and the corresponding lease exists in the in-memory
    /// database, the existing lease is removed.
    ///
    /// @param lease Pointer to the lease read from the lease file.
    void loadLease4(Lease4Ptr& lease);

    /// @brief Load all DHCPv6 leases from the file.
    ///
    /// This method loads all DHCPv6 leases from a file to memory. It removes
    /// existing leases before reading a file.
    ///
    /// @throw isc::DbOperationError If failed to read a lease from the lease
    /// file.
    void load6();

    /// @brief Loads a single DHCPv6 lease from the file.
    ///
    /// This method reads a single lease record from the lease file. If the
    /// corresponding record doesn't exist in the in-memory container, the
    /// lease is added to the container (except for a lease which valid lifetime
    /// is 0). If the corresponding lease exists, the lease being read updates
    /// the existing lease. If the lease being read from the lease file has
    /// valid lifetime of 0 and the corresponding lease exists in the in-memory
    /// database, the existing lease is removed.
    ///
    /// @param lease Pointer to the lease read from the lease file.
    void loadLease6(Lease6Ptr& lease);

425 426 427 428 429 430
    /// @brief Initialize the location of the lease file.
    ///
    /// This method uses the parameters passed as a map to the constructor to
    /// initialize the location of the lease file. If the lease file is not
    /// specified, the method will use the default location for the universe
    /// (v4 or v6) selected. If the location is specified in the map as empty
431 432 433
    /// or the "persist" parameter is set to "no" it will set the empty
    /// location, which implies that leases belonging to the specified universe
    /// will not be written to disk.
434 435 436 437 438 439 440 441
    ///
    /// @param u Universe (v4 or v6)
    ///
    /// @return The location of the lease file that should be assigned to the
    /// lease_file4_ or lease_file6_, depending on the universe specified as an
    /// argument to this function.
    std::string initLeaseFilePath(Universe u);

442 443 444 445
    /// @brief Initialize the timers used to perform repeating tasks.
    ///
    /// Currently only one timer is supported. This timer executes the
    /// Lease File Cleanup periodically.
446
    void initTimers();
447

448 449 450 451 452 453 454 455 456
    // This is a multi-index container, which holds elements that can
    // be accessed using different search indexes.
    typedef boost::multi_index_container<
        // It holds pointers to Lease6 objects.
        Lease6Ptr,
        boost::multi_index::indexed_by<
            // Specification of the first index starts here.
            // This index sorts leases by IPv6 addresses represented as
            // IOAddress objects.
457 458
            boost::multi_index::ordered_unique<
                boost::multi_index::member<Lease, isc::asiolink::IOAddress, &Lease::addr_>
459 460 461
            >,

            // Specification of the second index starts here.
462
            boost::multi_index::ordered_non_unique<
463
                // This is a composite index that will be used to search for
464
                // the lease using three attributes: DUID, IAID and lease type.
465 466
                boost::multi_index::composite_key<
                    Lease6,
467 468 469 470
                    // The DUID can be retrieved from the Lease6 object using
                    // a getDuidVector const function.
                    boost::multi_index::const_mem_fun<Lease6, const std::vector<uint8_t>&,
                                                      &Lease6::getDuidVector>,
471
                    // The two other ingredients of this index are IAID and
472
                    // lease type.
473
                    boost::multi_index::member<Lease6, uint32_t, &Lease6::iaid_>,
474
                    boost::multi_index::member<Lease6, Lease::Type, &Lease6::type_>
475
                >
476 477
            >
        >
478 479 480 481 482 483
     > Lease6Storage; // Specify the type name of this container.

    // This is a multi-index container, which holds elements that can
    // be accessed using different search indexes.
    typedef boost::multi_index_container<
        // It holds pointers to Lease4 objects.
484
        Lease4Ptr,
485 486 487 488 489 490 491 492
        // Specification of search indexes starts here.
        boost::multi_index::indexed_by<
            // Specification of the first index starts here.
            // This index sorts leases by IPv4 addresses represented as
            // IOAddress objects.
            boost::multi_index::ordered_unique<
                // The IPv4 address are held in addr_ members that belong to
                // Lease class.
493
                boost::multi_index::member<Lease, isc::asiolink::IOAddress, &Lease::addr_>
494
            >,
495 496

            // Specification of the second index starts here.
497
            boost::multi_index::ordered_unique<
498 499
                // This is a composite index that combines two attributes of the
                // Lease4 object: hardware address and subnet id.
500 501
                boost::multi_index::composite_key<
                    Lease4,
502
                    // The hardware address is held in the hwaddr_ member of the
503 504 505
                    // Lease4 object, which is a HWAddr object. Boost does not
                    // provide a key extractor for getting a member of a member,
                    // so we need a simple method for that.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
506 507
                    boost::multi_index::const_mem_fun<Lease, const std::vector<uint8_t>&,
                                               &Lease::getHWAddrVector>,
508 509 510 511
                    // The subnet id is held in the subnet_id_ member of Lease4
                    // class. Note that the subnet_id_ is defined in the base
                    // class (Lease) so we have to point to this class rather
                    // than derived class: Lease4.
512 513 514
                    boost::multi_index::member<Lease, SubnetID, &Lease::subnet_id_>
                >
            >,
515 516

            // Specification of the third index starts here.
517
            boost::multi_index::ordered_non_unique<
518 519
                // This is a composite index that uses two values to search for a
                // lease: client id and subnet id.
520 521
                boost::multi_index::composite_key<
                    Lease4,
522 523
                    // The client id can be retrieved from the Lease4 object by
                    // calling getClientIdVector const function.
524
                    boost::multi_index::const_mem_fun<Lease4, const std::vector<uint8_t>&,
525
                                                      &Lease4::getClientIdVector>,
526
                    // The subnet id is accessed through the subnet_id_ member.
527 528
                    boost::multi_index::member<Lease, uint32_t, &Lease::subnet_id_>
                >
529 530 531
            >,

            // Specification of the fourth index starts here.
532
            boost::multi_index::ordered_non_unique<
533 534 535 536
                // This is a composite index that uses two values to search for a
                // lease: client id and subnet id.
                boost::multi_index::composite_key<
                    Lease4,
537 538
                    // The client id can be retrieved from the Lease4 object by
                    // calling getClientIdVector const function.
539
                    boost::multi_index::const_mem_fun<Lease4, const std::vector<uint8_t>&,
540
                                                      &Lease4::getClientIdVector>,
541 542 543 544
                    // The hardware address is held in the hwaddr_ object. We can
                    // access the raw data using lease->hwaddr_->hwaddr_, but Boost
                    // doesn't seem to provide a way to use member of a member for this,
                    // so we need a simple key extractor method (getRawHWAddr).
Tomek Mrugalski's avatar
Tomek Mrugalski committed
545 546
                    boost::multi_index::const_mem_fun<Lease, const std::vector<uint8_t>&,
                                            &Lease::getHWAddrVector>,
547 548 549
                    // The subnet id is accessed through the subnet_id_ member.
                    boost::multi_index::member<Lease, SubnetID, &Lease::subnet_id_>
                >
550 551
            >
        >
552
    > Lease4Storage; // Specify the type name for this container.
553 554 555 556 557

    /// @brief stores IPv4 leases
    Lease4Storage storage4_;

    /// @brief stores IPv6 leases
558
    Lease6Storage storage6_;
559

560 561
    /// @brief Holds the pointer to the DHCPv4 lease file IO.
    boost::shared_ptr<CSVLeaseFile4> lease_file4_;
562

563 564
    /// @brief Holds the pointer to the DHCPv6 lease file IO.
    boost::shared_ptr<CSVLeaseFile6> lease_file6_;
565

566 567 568
    /// @brief A timer scheduled to perform Lease File Cleanup.
    asiolink::IntervalTimer lfc_timer_;

569 570 571 572 573
};

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

574
#endif // MEMFILE_LEASE_MGR