memfile_lease_mgr.cc 8.75 KB
Newer Older
Stephen Morris's avatar
Stephen Morris committed
1
// Copyright (C) 2012-2013 Internet Systems Consortium, Inc. ("ISC")
2 3 4 5 6 7 8 9 10 11 12 13 14
//
// 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.

15
#include <dhcpsrv/dhcpsrv_log.h>
16
#include <dhcpsrv/memfile_lease_mgr.h>
17
#include <exceptions/exceptions.h>
18

19
#include <iostream>
20 21 22

using namespace isc::dhcp;

23 24
Memfile_LeaseMgr::Memfile_LeaseMgr(const ParameterMap& parameters)
    : LeaseMgr(parameters) {
25
    LOG_WARN(dhcpsrv_logger, DHCPSRV_MEMFILE_WARNING);
26 27 28 29 30
}

Memfile_LeaseMgr::~Memfile_LeaseMgr() {
}

31 32
bool
Memfile_LeaseMgr::addLease(const Lease4Ptr& lease) {
33 34
    LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
              DHCPSRV_MEMFILE_ADD_ADDR4).arg(lease->addr_.toText());
35

36 37 38 39 40 41
    if (getLease4(lease->addr_)) {
        // there is a lease with specified address already
        return (false);
    }
    storage4_.insert(lease);
    return (true);
42 43
}

44 45
bool
Memfile_LeaseMgr::addLease(const Lease6Ptr& lease) {
46 47
    LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
              DHCPSRV_MEMFILE_ADD_ADDR6).arg(lease->addr_.toText());
48

49 50 51 52 53 54 55 56
    if (getLease6(lease->addr_)) {
        // there is a lease with specified address already
        return (false);
    }
    storage6_.insert(lease);
    return (true);
}

57 58
Lease4Ptr
Memfile_LeaseMgr::getLease4(const isc::asiolink::IOAddress& addr) const {
59 60
    LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
              DHCPSRV_MEMFILE_GET_ADDR4).arg(addr.toText());
61

62 63 64
    typedef Lease4Storage::nth_index<0>::type SearchIndex;
    const SearchIndex& idx = storage4_.get<0>();
    Lease4Storage::iterator l = idx.find(addr);
65 66 67 68 69
    if (l == storage4_.end()) {
        return (Lease4Ptr());
    } else {
        return (*l);
    }
70 71
}

72 73
Lease4Collection
Memfile_LeaseMgr::getLease4(const HWAddr& hwaddr) const {
74
    LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
75
              DHCPSRV_MEMFILE_GET_HWADDR).arg(hwaddr.toText());
76 77 78 79 80 81 82 83 84 85 86
    typedef Lease4Storage::nth_index<0>::type SearchIndex;
    Lease4Collection collection;
    const SearchIndex& idx = storage4_.get<0>();
    for(SearchIndex::const_iterator lease = idx.begin();
        lease != idx.end(); ++lease) {

        // Every Lease4 has a hardware address, so we can compare it
        if((* lease)->hwaddr_ == hwaddr.hwaddr_) {
            collection.push_back((* lease));
        }
    }
87

88
    return (collection);
89 90
}

91 92
Lease4Ptr
Memfile_LeaseMgr::getLease4(const HWAddr& hwaddr, SubnetID subnet_id) const {
93 94
    LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
              DHCPSRV_MEMFILE_GET_SUBID_HWADDR).arg(subnet_id)
95 96
        .arg(hwaddr.toText());

97 98 99
    // We are going to use index #1 of the multi index container.
    // We define SearchIndex locally in this function because
    // currently only this function uses this index.
100
    typedef Lease4Storage::nth_index<1>::type SearchIndex;
101
    // Get the index.
102
    const SearchIndex& idx = storage4_.get<1>();
103 104 105 106
    // Try to find the lease using HWAddr and subnet id.
    SearchIndex::const_iterator lease =
        idx.find(boost::make_tuple(hwaddr.hwaddr_, subnet_id));
    // Lease was not found. Return empty pointer to the caller.
107
    if (lease == idx.end()) {
108
        return (Lease4Ptr());
109 110
    }

111
    // Lease was found. Return it to the caller.
112
    return (*lease);
113 114
}

115 116
Lease4Collection
Memfile_LeaseMgr::getLease4(const ClientId& clientid) const {
117 118
    LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
              DHCPSRV_MEMFILE_GET_CLIENTID).arg(clientid.toText());
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
    typedef Memfile_LeaseMgr::Lease4Storage::nth_index<0>::type SearchIndex;
    Lease4Collection collection;
    const SearchIndex& idx = storage4_.get<0>();
    for(SearchIndex::const_iterator lease = idx.begin();
        lease != idx.end(); ++ lease) {

        // client-id is not mandatory in DHCPv4. There can be a lease that does
        // not have a client-id. Dereferencing null pointer would be a bad thing
        if (!(*lease)->client_id_) {
            continue;
        }

        if(*(*lease)->client_id_ == clientid) {
            collection.push_back((* lease));
        }
    }

    return (collection);
137
}
138

139 140
Lease4Ptr
Memfile_LeaseMgr::getLease4(const ClientId& client_id,
141
                                      SubnetID subnet_id) const {
142 143
    LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
              DHCPSRV_MEMFILE_GET_SUBID_CLIENTID).arg(subnet_id)
144
              .arg(client_id.toText());
145

146 147 148
    // We are going to use index #2 of the multi index container.
    // We define SearchIndex locally in this function because
    // currently only this function uses this index.
149
    typedef Lease4Storage::nth_index<2>::type SearchIndex;
150
    // Get the index.
151
    const SearchIndex& idx = storage4_.get<2>();
152 153 154 155
    // Try to get the lease using client id and subnet id.
    SearchIndex::const_iterator lease =
        idx.find(boost::make_tuple(client_id.getClientId(), subnet_id));
    // Lease was not found. Return empty pointer to the caller.
156
    if (lease == idx.end()) {
157
        return (Lease4Ptr());
158
    }
159
    // Lease was found. Return it to the caller.
160
    return (*lease);
161 162
}

163 164
Lease6Ptr
Memfile_LeaseMgr::getLease6(const isc::asiolink::IOAddress& addr) const {
165 166
    LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
              DHCPSRV_MEMFILE_GET_ADDR6).arg(addr.toText());
167 168 169 170 171 172 173 174 175

    Lease6Storage::iterator l = storage6_.find(addr);
    if (l == storage6_.end()) {
        return (Lease6Ptr());
    } else {
        return (*l);
    }
}

176 177
Lease6Collection
Memfile_LeaseMgr::getLease6(const DUID& duid, uint32_t iaid) const {
178 179
    LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
              DHCPSRV_MEMFILE_GET_IAID_DUID).arg(iaid).arg(duid.toText());
180

181 182 183
    return (Lease6Collection());
}

184 185 186
Lease6Ptr
Memfile_LeaseMgr::getLease6(const DUID& duid, uint32_t iaid,
                            SubnetID subnet_id) const {
187
    LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
188 189 190
              DHCPSRV_MEMFILE_GET_IAID_SUBID_DUID)
              .arg(iaid).arg(subnet_id).arg(duid.toText());

191 192 193 194 195 196 197 198 199 200 201 202
    // We are going to use index #1 of the multi index container.
    // We define SearchIndex locally in this function because
    // currently only this function uses this index.
    typedef Lease6Storage::nth_index<1>::type SearchIndex;
    // Get the index.
    const SearchIndex& idx = storage6_.get<1>();
    // Try to get the lease using the DUID, IAID and Subnet ID.
    SearchIndex::const_iterator lease =
        idx.find(boost::make_tuple(duid.getDuid(), iaid, subnet_id));
    // Lease was not found. Return empty pointer.
    if (lease == idx.end()) {
        return (Lease6Ptr());
203
    }
204 205
    // Lease was found, return it to the caller.
    return (*lease);
206 207
}

208 209
void
Memfile_LeaseMgr::updateLease4(const Lease4Ptr& lease) {
210 211
    LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
              DHCPSRV_MEMFILE_UPDATE_ADDR4).arg(lease->addr_.toText());
212 213
}

214 215
void
Memfile_LeaseMgr::updateLease6(const Lease6Ptr& lease) {
216 217
    LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
              DHCPSRV_MEMFILE_UPDATE_ADDR6).arg(lease->addr_.toText());
218 219
}

220 221
bool
Memfile_LeaseMgr::deleteLease(const isc::asiolink::IOAddress& addr) {
222 223
    LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
              DHCPSRV_MEMFILE_DELETE_ADDR).arg(addr.toText());
224
    if (addr.isV4()) {
225 226 227 228 229 230 231 232 233
        // v4 lease
        Lease4Storage::iterator l = storage4_.find(addr);
        if (l == storage4_.end()) {
            // No such lease
            return (false);
        } else {
            storage4_.erase(l);
            return (true);
        }
234

235
    } else {
236
        // v6 lease
237 238 239 240 241 242 243 244
        Lease6Storage::iterator l = storage6_.find(addr);
        if (l == storage6_.end()) {
            // No such lease
            return (false);
        } else {
            storage6_.erase(l);
            return (true);
        }
245 246 247
    }
}

248 249
std::string
Memfile_LeaseMgr::getDescription() const {
250 251 252 253
    return (std::string("This is a dummy memfile backend implementation.\n"
                        "It does not offer any useful lease management and its only\n"
                        "purpose is to test abstract lease manager API."));
}
254 255 256

void
Memfile_LeaseMgr::commit() {
257
    LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MEMFILE_COMMIT);
258 259 260 261
}

void
Memfile_LeaseMgr::rollback() {
262 263
    LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
              DHCPSRV_MEMFILE_ROLLBACK);
264
}