memfile_lease_mgr.h 19.1 KB
Newer Older
1
// Copyright (C) 2012-2014 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 <dhcp/hwaddr.h>
19 20
#include <dhcpsrv/csv_lease_file4.h>
#include <dhcpsrv/csv_lease_file6.h>
21 22
#include <dhcpsrv/lease_mgr.h>

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

29 30 31
namespace isc {
namespace dhcp {

32
/// @brief This is a concrete implementation of a Lease database.
33 34 35
class Memfile_LeaseMgr : public LeaseMgr {
public:

36 37 38 39 40 41 42 43 44 45 46
    /// @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
    };

47 48 49 50 51 52
    /// @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.
    ///
53 54 55
    /// @param parameters A data structure relating keywords and values
    ///        concerned with the database.
    Memfile_LeaseMgr(const ParameterMap& parameters);
56 57 58 59 60 61 62

    /// @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
63
    virtual bool addLease(const Lease4Ptr& lease);
64 65 66 67

    /// @brief Adds an IPv6 lease.
    ///
    /// @param lease lease to be added
Tomek Mrugalski's avatar
Tomek Mrugalski committed
68
    virtual bool addLease(const Lease6Ptr& lease);
69 70 71

    /// @brief Returns existing IPv4 lease for specified IPv4 address.
    ///
72 73 74 75
    /// 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.
76 77
    ///
    /// @return a collection of leases
78
    virtual Lease4Ptr getLease4(const isc::asiolink::IOAddress& addr) const;
79 80 81 82 83 84 85 86 87 88 89

    /// @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
90
    virtual Lease4Collection getLease4(const isc::dhcp::HWAddr& hwaddr) const;
91

92
    /// @brief Returns existing IPv4 lease for specified hardware address
93 94
    ///        and a subnet
    ///
95 96
    /// 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
97
    ///
98 99 100 101 102 103 104 105 106 107 108 109
    /// 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
    ///
110 111
    /// @param client_id client identifier
    virtual Lease4Collection getLease4(const ClientId& client_id) const;
112

113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
    /// @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;

128 129
    /// @brief Returns existing IPv4 lease for specified client-id
    ///
130 131 132
    /// This function returns a copy of the lease. The modification in the
    /// return lease does not affect the instance held in the lease storage.
    ///
133 134 135 136 137 138 139 140 141 142 143 144
    /// 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.
    ///
145 146 147
    /// This function returns a copy of the lease. The modification in the
    /// return lease does not affect the instance held in the lease storage.
    ///
148
    /// @param type specifies lease type: (NA, TA or PD)
149
    /// @param addr An address of the searched lease.
150 151
    ///
    /// @return smart pointer to the lease (or NULL if a lease is not found)
152
    virtual Lease6Ptr getLease6(Lease::Type type,
153
                                const isc::asiolink::IOAddress& addr) const;
154 155 156

    /// @brief Returns existing IPv6 lease for a given DUID+IA combination
    ///
Tomek Mrugalski's avatar
Tomek Mrugalski committed
157 158
    /// @todo Not implemented yet
    ///
159
    /// @param type specifies lease type: (NA, TA or PD)
160 161 162 163
    /// @param duid client DUID
    /// @param iaid IA identifier
    ///
    /// @return collection of IPv6 leases
164
    virtual Lease6Collection getLeases6(Lease::Type type,
165
                                        const DUID& duid, uint32_t iaid) const;
166

167
    /// @brief Returns existing IPv6 lease for a given DUID/IA/subnet-id tuple
168
    ///
169 170
    /// 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
171
    ///
172
    /// @param type specifies lease type: (NA, TA or PD)
173 174 175 176
    /// @param duid client DUID
    /// @param iaid IA identifier
    /// @param subnet_id identifier of the subnet the lease must belong to
    ///
177
    /// @return lease collection (may be empty if no lease is found)
178
    virtual Lease6Collection getLeases6(Lease::Type type, const DUID& duid,
179
                                        uint32_t iaid, SubnetID subnet_id) const;
180 181 182

    /// @brief Updates IPv4 lease.
    ///
183 184
    /// @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
185
    ///
186 187 188
    /// @param lease4 The lease to be updated.
    ///
    /// If no such lease is present, an exception will be thrown.
189
    virtual void updateLease4(const Lease4Ptr& lease4);
190

191
    /// @brief Updates IPv6 lease.
192
    ///
193 194
    /// @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
195
    ///
196
    /// @param lease6 The lease to be updated.
197 198
    ///
    /// If no such lease is present, an exception will be thrown.
199
    virtual void updateLease6(const Lease6Ptr& lease6);
200 201 202

    /// @brief Deletes a lease.
    ///
203 204
    /// @param addr Address of the lease to be deleted. (This can be IPv4 or
    ///        IPv6.)
205 206
    ///
    /// @return true if deletion was successful, false if no such lease exists
207
    virtual bool deleteLease(const isc::asiolink::IOAddress& addr);
208

209 210 211 212 213 214 215 216 217
    /// @brief Return backend type
    ///
    /// Returns the type of the backend.
    ///
    /// @return Type of the backend.
    virtual std::string getType() const {
        return (std::string("memfile"));
    }

218 219
    /// @brief Returns backend name.
    ///
220
    /// For now, memfile can only store data in memory.
221 222 223
    ///
    /// @return Name of the backend.
    virtual std::string getName() const {
224
        return ("memory");
225
    }
226 227 228 229

    /// @brief Returns description of the backend.
    ///
    /// This description may be multiline text that describes the backend.
230 231 232
    ///
    /// @return Description of the backend.
    virtual std::string getDescription() const;
233 234

    /// @brief Returns backend version.
235 236 237
    ///
    /// @return Version number as a pair of unsigned integers.  "first" is the
    ///         major version number, "second" the minor number.
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252
    virtual std::pair<uint32_t, uint32_t> getVersion() const {
        return (std::make_pair(1, 0));
    }

    /// @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();
253

254 255 256 257 258 259 260 261
    /// @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).
262 263 264 265
    ///
    /// @return Absolute path to the lease file or empty string if no lease
    /// file is used.
    std::string getLeaseFilePath(Universe u) const;
266 267 268 269 270 271 272 273 274 275 276 277 278 279

    /// @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;

280 281
protected:

282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325
    /// @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);

326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343
    /// @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
    /// it will set the empty location, which implies that leases belonging to
    /// the specified universe will not be written to disk.
    ///
    /// @param u Universe (v4 or v6)
    /// @param parameters Map holding parameters of the Lease Manager, passed to
    /// the constructor.
    ///
    /// @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);

344 345 346 347 348 349 350 351 352
    // 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.
353 354
            boost::multi_index::ordered_unique<
                boost::multi_index::member<Lease, isc::asiolink::IOAddress, &Lease::addr_>
355 356 357 358 359 360 361 362
            >,

            // Specification of the second index starts here.
            boost::multi_index::ordered_unique<
                // This is a composite index that will be used to search for
                // the lease using three attributes: DUID, IAID, Subnet Id.
                boost::multi_index::composite_key<
                    Lease6,
363 364 365 366
                    // 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>,
367 368 369 370 371
                    // The two other ingredients of this index are IAID and
                    // subnet id.
                    boost::multi_index::member<Lease6, uint32_t, &Lease6::iaid_>,
                    boost::multi_index::member<Lease, SubnetID, &Lease::subnet_id_>
                >
372 373
            >
        >
374 375 376 377 378 379
     > 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.
380
        Lease4Ptr,
381 382 383 384 385 386 387 388
        // 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.
389
                boost::multi_index::member<Lease, isc::asiolink::IOAddress, &Lease::addr_>
390
            >,
391 392

            // Specification of the second index starts here.
393
            boost::multi_index::ordered_unique<
394 395
                // This is a composite index that combines two attributes of the
                // Lease4 object: hardware address and subnet id.
396 397
                boost::multi_index::composite_key<
                    Lease4,
398 399
                    // The hardware address is held in the hwaddr_ member of the
                    // Lease4 object.
400 401
                    boost::multi_index::member<Lease4, std::vector<uint8_t>,
                                               &Lease4::hwaddr_>,
402 403 404 405
                    // 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.
406 407 408
                    boost::multi_index::member<Lease, SubnetID, &Lease::subnet_id_>
                >
            >,
409 410

            // Specification of the third index starts here.
411
            boost::multi_index::ordered_non_unique<
412 413
                // This is a composite index that uses two values to search for a
                // lease: client id and subnet id.
414 415
                boost::multi_index::composite_key<
                    Lease4,
416 417
                    // The client id can be retrieved from the Lease4 object by
                    // calling getClientIdVector const function.
418
                    boost::multi_index::const_mem_fun<Lease4, const std::vector<uint8_t>&,
419
                                                      &Lease4::getClientIdVector>,
420
                    // The subnet id is accessed through the subnet_id_ member.
421 422
                    boost::multi_index::member<Lease, uint32_t, &Lease::subnet_id_>
                >
423 424 425
            >,

            // Specification of the fourth index starts here.
426
            boost::multi_index::ordered_non_unique<
427 428 429 430
                // 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,
431 432
                    // The client id can be retrieved from the Lease4 object by
                    // calling getClientIdVector const function.
433
                    boost::multi_index::const_mem_fun<Lease4, const std::vector<uint8_t>&,
434
                                                      &Lease4::getClientIdVector>,
435 436 437 438 439 440 441
                    // The hardware address is held in the hwaddr_ member of the
                    // Lease4 object.
                    boost::multi_index::member<Lease4, std::vector<uint8_t>,
                                               &Lease4::hwaddr_>,
                    // The subnet id is accessed through the subnet_id_ member.
                    boost::multi_index::member<Lease, SubnetID, &Lease::subnet_id_>
                >
442 443
            >
        >
444
    > Lease4Storage; // Specify the type name for this container.
445 446 447 448 449

    /// @brief stores IPv4 leases
    Lease4Storage storage4_;

    /// @brief stores IPv6 leases
450
    Lease6Storage storage6_;
451

452 453
    /// @brief Holds the pointer to the DHCPv4 lease file IO.
    boost::shared_ptr<CSVLeaseFile4> lease_file4_;
454

455 456
    /// @brief Holds the pointer to the DHCPv6 lease file IO.
    boost::shared_ptr<CSVLeaseFile6> lease_file6_;
457 458 459 460 461
};

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

462
#endif // MEMFILE_LEASE_MGR