lease.cc 9.42 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 18 19 20 21 22 23 24 25
//
// 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.

#include <dhcpsrv/lease.h>
#include <sstream>

using namespace std;

namespace isc {
namespace dhcp {

Lease::Lease(const isc::asiolink::IOAddress& addr, uint32_t t1, uint32_t t2,
             uint32_t valid_lft, SubnetID subnet_id, time_t cltt,
             const bool fqdn_fwd, const bool fqdn_rev,
26
             const std::string& hostname, const HWAddrPtr& hwaddr)
27 28
    :addr_(addr), t1_(t1), t2_(t2), valid_lft_(valid_lft), cltt_(cltt),
     subnet_id_(subnet_id), fixed_(false), hostname_(hostname),
29
     fqdn_fwd_(fqdn_fwd), fqdn_rev_(fqdn_rev), hwaddr_(hwaddr) {
30 31 32 33 34
}

std::string
Lease::typeToText(Lease::Type type) {
   switch (type) {
35 36
   case Lease::TYPE_V4:
       return string("V4");
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
   case Lease::TYPE_NA:
       return string("IA_NA");
   case Lease::TYPE_TA:
       return string("IA_TA");
   case Lease::TYPE_PD:
       return string("IA_PD");
       break;
   default: {
       stringstream tmp;
       tmp << "unknown (" << type << ")";
       return (tmp.str());
   }
   }
}

bool Lease::expired() const {

    // Let's use int64 to avoid problems with negative/large uint32 values
    int64_t expire_time = cltt_ + valid_lft_;
    return (expire_time < time(NULL));
}

59 60 61 62 63 64 65
bool
Lease::hasIdenticalFqdn(const Lease& other) const {
    return (hostname_ == other.hostname_ &&
            fqdn_fwd_ == other.fqdn_fwd_ &&
            fqdn_rev_ == other.fqdn_rev_);
}

66 67 68
Lease4::Lease4(const Lease4& other)
    : Lease(other.addr_, other.t1_, other.t2_, other.valid_lft_,
            other.subnet_id_, other.cltt_, other.fqdn_fwd_,
69 70
            other.fqdn_rev_, other.hostname_, other.hwaddr_),
            ext_(other.ext_) {
71 72 73 74

    fixed_ = other.fixed_;
    comments_ = other.comments_;

Tomek Mrugalski's avatar
Tomek Mrugalski committed
75 76 77 78 79
    // Copy the hardware address if it is defined.
    if (other.hwaddr_) {
        hwaddr_.reset(new HWAddr(*other.hwaddr_));
    }

80 81 82 83 84 85 86 87 88
    if (other.client_id_) {
        client_id_.reset(new ClientId(other.client_id_->getClientId()));

    } else {
        client_id_.reset();

    }
}

89
const std::vector<uint8_t>&
90 91
Lease4::getClientIdVector() const {
    if(!client_id_) {
92 93
        static std::vector<uint8_t> empty_vec;
        return (empty_vec);
94 95 96 97 98
    }

    return (client_id_->getClientId());
}

99
const std::vector<uint8_t>&
Tomek Mrugalski's avatar
Tomek Mrugalski committed
100
Lease::getHWAddrVector() const {
101
    if (!hwaddr_) {
Tomek Mrugalski's avatar
Tomek Mrugalski committed
102 103
        static std::vector<uint8_t> empty_vec;
        return (empty_vec);
104 105 106 107
    }
    return (hwaddr_->hwaddr_);
}

108 109 110 111 112 113 114 115 116 117 118 119 120 121
bool
Lease4::matches(const Lease4& other) const {
    if ((client_id_ && !other.client_id_) ||
        (!client_id_ && other.client_id_)) {
        // One lease has client-id, but the other doesn't
        return false;
    }

    if (client_id_ && other.client_id_ &&
        *client_id_ != *other.client_id_) {
        // Different client-ids
        return false;
    }

122 123
    // Note that hwaddr_ is now a poiner to the HWAddr structure.
    // We can't simply compare smart pointers, we need to compare the
Tomek Mrugalski's avatar
Tomek Mrugalski committed
124 125 126 127 128 129 130 131 132 133
    // actual objects they point to. If one of the leases had a hardware address
    // and the other doesn't, they clearly don't match.
    if ( (!hwaddr_ && other.hwaddr_) ||
         (hwaddr_ && !other.hwaddr_) ) {
        return (false);
    }

    // The lease is equal if addresses and extensions match and there is
    // either the same hardware address on both or neither have hardware address
    // specified.
134 135
    return (addr_ == other.addr_ &&
            ext_ == other.ext_ &&
Tomek Mrugalski's avatar
Tomek Mrugalski committed
136 137
            (!hwaddr_ ||
             *hwaddr_ == *other.hwaddr_) );
138 139
}

140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
Lease4&
Lease4::operator=(const Lease4& other) {
    if (this != &other) {
        addr_ = other.addr_;
        t1_ = other.t1_;
        t2_ = other.t2_;
        valid_lft_ = other.valid_lft_;
        cltt_ = other.cltt_;
        subnet_id_ = other.subnet_id_;
        fixed_ = other.fixed_;
        hostname_ = other.hostname_;
        fqdn_fwd_ = other.fqdn_fwd_;
        fqdn_rev_ = other.fqdn_rev_;
        comments_ = other.comments_;
        ext_ = other.ext_;
Tomek Mrugalski's avatar
Tomek Mrugalski committed
155 156 157 158 159

        // Copy the hardware address if it is defined.
        if (other.hwaddr_) {
            hwaddr_.reset(new HWAddr(*other.hwaddr_));
        }
160 161 162 163 164 165 166 167 168 169 170 171

        if (other.client_id_) {
            client_id_.reset(new ClientId(other.client_id_->getClientId()));
        } else {
            client_id_.reset();
        }
    }
    return (*this);
}

Lease6::Lease6(Type type, const isc::asiolink::IOAddress& addr,
               DuidPtr duid, uint32_t iaid, uint32_t preferred, uint32_t valid,
172 173 174
               uint32_t t1, uint32_t t2, SubnetID subnet_id,
               const HWAddrPtr& hwaddr, uint8_t prefixlen)
    : Lease(addr, t1, t2, valid, subnet_id, 0/*cltt*/, false, false, "", hwaddr),
175 176 177
      type_(type), prefixlen_(prefixlen), iaid_(iaid), duid_(duid),
      preferred_lft_(preferred) {
    if (!duid) {
178
        isc_throw(InvalidOperation, "DUID is mandatory for an IPv6 lease");
179 180 181 182 183 184 185 186 187
    }

    cltt_ = time(NULL);
}

Lease6::Lease6(Type type, const isc::asiolink::IOAddress& addr,
               DuidPtr duid, uint32_t iaid, uint32_t preferred, uint32_t valid,
               uint32_t t1, uint32_t t2, SubnetID subnet_id,
               const bool fqdn_fwd, const bool fqdn_rev,
188 189
               const std::string& hostname, const HWAddrPtr& hwaddr,
               uint8_t prefixlen)
190
    : Lease(addr, t1, t2, valid, subnet_id, 0/*cltt*/,
191
            fqdn_fwd, fqdn_rev, hostname, hwaddr),
192 193 194
      type_(type), prefixlen_(prefixlen), iaid_(iaid), duid_(duid),
      preferred_lft_(preferred) {
    if (!duid) {
195
        isc_throw(InvalidOperation, "DUID is mandatory for an IPv6 lease");
196 197 198 199 200
    }

    cltt_ = time(NULL);
}

201
Lease6::Lease6()
202 203 204
    : Lease(isc::asiolink::IOAddress("::"), 0, 0, 0, 0, 0, false, false, "",
            HWAddrPtr()), type_(TYPE_NA), prefixlen_(0), iaid_(0),
            duid_(DuidPtr()), preferred_lft_(0) {
205 206
}

207 208 209 210 211 212 213 214 215 216
const std::vector<uint8_t>&
Lease6::getDuidVector() const {
    if (!duid_) {
        static std::vector<uint8_t> empty_vec;
        return (empty_vec);
    }

    return (duid_->getDuid());
}

217 218 219 220
std::string
Lease6::toText() const {
    ostringstream stream;

221
    stream << "Type:          " << typeToText(type_) << "("
222
           << static_cast<int>(type_) << ") ";
223
    stream << "Address:       " << addr_ << "\n"
224 225 226 227 228
           << "Prefix length: " << static_cast<int>(prefixlen_) << "\n"
           << "IAID:          " << iaid_ << "\n"
           << "Pref life:     " << preferred_lft_ << "\n"
           << "Valid life:    " << valid_lft_ << "\n"
           << "Cltt:          " << cltt_ << "\n"
Tomek Mrugalski's avatar
Tomek Mrugalski committed
229
           << "Hardware addr: " << (hwaddr_?hwaddr_->toText(false):"(none)")
230 231 232 233 234 235 236 237 238
           << "Subnet ID:     " << subnet_id_ << "\n";

    return (stream.str());
}

std::string
Lease4::toText() const {
    ostringstream stream;

239
    stream << "Address:       " << addr_ << "\n"
240 241 242 243
           << "Valid life:    " << valid_lft_ << "\n"
           << "T1:            " << t1_ << "\n"
           << "T2:            " << t2_ << "\n"
           << "Cltt:          " << cltt_ << "\n"
Tomek Mrugalski's avatar
Tomek Mrugalski committed
244
           << "Hardware addr: " << (hwaddr_?hwaddr_->toText(false):"(none)")
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264
           << "Subnet ID:     " << subnet_id_ << "\n";

    return (stream.str());
}


bool
Lease4::operator==(const Lease4& other) const {
    if ( (client_id_ && !other.client_id_) ||
         (!client_id_ && other.client_id_) ) {
        // One lease has client-id, but the other doesn't
        return false;
    }

    if (client_id_ && other.client_id_ &&
        *client_id_ != *other.client_id_) {
        // Different client-ids
        return false;
    }

265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284
    return (matches(other) &&
            subnet_id_ == other.subnet_id_ &&
            t1_ == other.t1_ &&
            t2_ == other.t2_ &&
            valid_lft_ == other.valid_lft_ &&
            cltt_ == other.cltt_ &&
            fixed_ == other.fixed_ &&
            hostname_ == other.hostname_ &&
            fqdn_fwd_ == other.fqdn_fwd_ &&
            fqdn_rev_ == other.fqdn_rev_ &&
            comments_ == other.comments_);
}

bool
Lease6::matches(const Lease6& other) const {
    return (addr_ == other.addr_ &&
            type_ == other.type_ &&
            prefixlen_ == other.prefixlen_ &&
            iaid_ == other.iaid_ &&
            *duid_ == *other.duid_);
285 286 287 288
}

bool
Lease6::operator==(const Lease6& other) const {
289 290 291 292 293 294 295 296 297 298 299 300
    return (matches(other) &&
            preferred_lft_ == other.preferred_lft_ &&
            valid_lft_ == other.valid_lft_ &&
            t1_ == other.t1_ &&
            t2_ == other.t2_ &&
            cltt_ == other.cltt_ &&
            subnet_id_ == other.subnet_id_ &&
            fixed_ == other.fixed_ &&
            hostname_ == other.hostname_ &&
            fqdn_fwd_ == other.fqdn_fwd_ &&
            fqdn_rev_ == other.fqdn_rev_ &&
            comments_ == other.comments_);
301 302
}

303 304 305 306 307 308
std::ostream&
operator<<(std::ostream& os, const Lease& lease) {
    os << lease.toText();
    return (os);
}

309 310
} // namespace isc::dhcp
} // namespace isc