12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964 |
- #include <config.h>
- #include <dhcpsrv/alloc_engine.h>
- #include <dhcpsrv/alloc_engine_log.h>
- #include <dhcpsrv/dhcpsrv_log.h>
- #include <dhcpsrv/host_mgr.h>
- #include <dhcpsrv/host.h>
- #include <dhcpsrv/lease_mgr_factory.h>
- #include <dhcp/dhcp6.h>
- #include <hooks/server_hooks.h>
- #include <hooks/hooks_manager.h>
- #include <cstring>
- #include <limits>
- #include <vector>
- #include <stdint.h>
- #include <string.h>
- using namespace isc::asiolink;
- using namespace isc::dhcp;
- using namespace isc::hooks;
- namespace {
- struct AllocEngineHooks {
- int hook_index_lease4_select_;
- int hook_index_lease4_renew_;
- int hook_index_lease6_select_;
- int hook_index_lease6_renew_;
- int hook_index_lease6_rebind_;
-
- AllocEngineHooks() {
- hook_index_lease4_select_ = HooksManager::registerHook("lease4_select");
- hook_index_lease4_renew_ = HooksManager::registerHook("lease4_renew");
- hook_index_lease6_select_ = HooksManager::registerHook("lease6_select");
- hook_index_lease6_renew_ = HooksManager::registerHook("lease6_renew");
- hook_index_lease6_rebind_ = HooksManager::registerHook("lease6_rebind");
- }
- };
- AllocEngineHooks Hooks;
- };
- namespace isc {
- namespace dhcp {
- AllocEngine::IterativeAllocator::IterativeAllocator(Lease::Type lease_type)
- :Allocator(lease_type) {
- }
- isc::asiolink::IOAddress
- AllocEngine::IterativeAllocator::increasePrefix(const isc::asiolink::IOAddress& prefix,
- const uint8_t prefix_len) {
- if (!prefix.isV6()) {
- isc_throw(BadValue, "Prefix operations are for IPv6 only (attempted to "
- "increase prefix " << prefix << ")");
- }
-
- const std::vector<uint8_t>& vec = prefix.toBytes();
- if (prefix_len < 1 || prefix_len > 128) {
- isc_throw(BadValue, "Cannot increase prefix: invalid prefix length: "
- << prefix_len);
- }
-
-
- uint8_t n_bytes = (prefix_len - 1)/8;
- uint8_t n_bits = 8 - (prefix_len - n_bytes*8);
- uint8_t mask = 1 << n_bits;
-
-
-
-
-
-
- uint8_t packed[V6ADDRESS_LEN];
-
- std::memcpy(packed, &vec[0], V6ADDRESS_LEN);
-
- if (packed[n_bytes] + uint16_t(mask) < 256u) {
- packed[n_bytes] += mask;
- return (IOAddress::fromBytes(AF_INET6, packed));
- }
-
- packed[n_bytes] += mask;
-
- for (int i = n_bytes - 1; i >= 0; --i) {
- ++packed[i];
-
- if (packed[i] != 0) {
- break;
- }
- }
- return (IOAddress::fromBytes(AF_INET6, packed));
- }
- isc::asiolink::IOAddress
- AllocEngine::IterativeAllocator::pickAddress(const SubnetPtr& subnet,
- const DuidPtr&,
- const IOAddress&) {
-
- bool prefix = pool_type_ == Lease::TYPE_PD;
-
-
-
- IOAddress last = subnet->getLastAllocated(pool_type_);
- const PoolCollection& pools = subnet->getPools(pool_type_);
- if (pools.empty()) {
- isc_throw(AllocFailed, "No pools defined in selected subnet");
- }
-
- PoolCollection::const_iterator it;
- for (it = pools.begin(); it != pools.end(); ++it) {
- if ((*it)->inRange(last)) {
- break;
- }
- }
-
-
-
-
- if (it == pools.end()) {
-
- IOAddress next = pools[0]->getFirstAddress();
- subnet->setLastAllocated(pool_type_, next);
- return (next);
- }
-
- IOAddress next("::");
- if (!prefix) {
- next = IOAddress::increase(last);
- } else {
- Pool6Ptr pool6 = boost::dynamic_pointer_cast<Pool6>(*it);
- if (!pool6) {
-
- isc_throw(Unexpected, "Wrong type of pool: " << (*it)->toText()
- << " is not Pool6");
- }
-
- next = increasePrefix(last, pool6->getLength());
- }
- if ((*it)->inRange(next)) {
-
- subnet->setLastAllocated(pool_type_, next);
- return (next);
- }
-
- ++it;
- if (it == pools.end()) {
-
-
- next = pools[0]->getFirstAddress();
- subnet->setLastAllocated(pool_type_, next);
- return (next);
- }
-
- next = (*it)->getFirstAddress();
- subnet->setLastAllocated(pool_type_, next);
- return (next);
- }
- AllocEngine::HashedAllocator::HashedAllocator(Lease::Type lease_type)
- :Allocator(lease_type) {
- isc_throw(NotImplemented, "Hashed allocator is not implemented");
- }
- isc::asiolink::IOAddress
- AllocEngine::HashedAllocator::pickAddress(const SubnetPtr&,
- const DuidPtr&,
- const IOAddress&) {
- isc_throw(NotImplemented, "Hashed allocator is not implemented");
- }
- AllocEngine::RandomAllocator::RandomAllocator(Lease::Type lease_type)
- :Allocator(lease_type) {
- isc_throw(NotImplemented, "Random allocator is not implemented");
- }
- isc::asiolink::IOAddress
- AllocEngine::RandomAllocator::pickAddress(const SubnetPtr&,
- const DuidPtr&,
- const IOAddress&) {
- isc_throw(NotImplemented, "Random allocator is not implemented");
- }
- AllocEngine::AllocEngine(AllocType engine_type, unsigned int attempts,
- bool ipv6)
- :attempts_(attempts) {
-
- Lease::Type basic_type = ipv6 ? Lease::TYPE_NA : Lease::TYPE_V4;
-
- switch (engine_type) {
- case ALLOC_ITERATIVE:
- allocators_[basic_type] = AllocatorPtr(new IterativeAllocator(basic_type));
- break;
- case ALLOC_HASHED:
- allocators_[basic_type] = AllocatorPtr(new HashedAllocator(basic_type));
- break;
- case ALLOC_RANDOM:
- allocators_[basic_type] = AllocatorPtr(new RandomAllocator(basic_type));
- break;
- default:
- isc_throw(BadValue, "Invalid/unsupported allocation algorithm");
- }
-
-
- if (ipv6) {
- switch (engine_type) {
- case ALLOC_ITERATIVE:
- allocators_[Lease::TYPE_TA] = AllocatorPtr(new IterativeAllocator(Lease::TYPE_TA));
- allocators_[Lease::TYPE_PD] = AllocatorPtr(new IterativeAllocator(Lease::TYPE_PD));
- break;
- case ALLOC_HASHED:
- allocators_[Lease::TYPE_TA] = AllocatorPtr(new HashedAllocator(Lease::TYPE_TA));
- allocators_[Lease::TYPE_PD] = AllocatorPtr(new HashedAllocator(Lease::TYPE_PD));
- break;
- case ALLOC_RANDOM:
- allocators_[Lease::TYPE_TA] = AllocatorPtr(new RandomAllocator(Lease::TYPE_TA));
- allocators_[Lease::TYPE_PD] = AllocatorPtr(new RandomAllocator(Lease::TYPE_PD));
- break;
- default:
- isc_throw(BadValue, "Invalid/unsupported allocation algorithm");
- }
- }
-
- hook_index_lease4_select_ = Hooks.hook_index_lease4_select_;
- hook_index_lease6_select_ = Hooks.hook_index_lease6_select_;
- }
- AllocEngine::AllocatorPtr AllocEngine::getAllocator(Lease::Type type) {
- std::map<Lease::Type, AllocatorPtr>::const_iterator alloc = allocators_.find(type);
- if (alloc == allocators_.end()) {
- isc_throw(BadValue, "No allocator initialized for pool type "
- << Lease::typeToText(type));
- }
- return (alloc->second);
- }
- AllocEngine::ClientContext6::ClientContext6()
- : subnet_(), duid_(), iaid_(0), type_(Lease::TYPE_NA), hwaddr_(),
- hints_(), fwd_dns_update_(false), rev_dns_update_(false), hostname_(""),
- callout_handle_(), fake_allocation_(false), old_leases_(), host_(),
- query_(), ia_rsp_(), allow_new_leases_in_renewals_(false) {
- }
- AllocEngine::ClientContext6::ClientContext6(const Subnet6Ptr& subnet, const DuidPtr& duid,
- const uint32_t iaid,
- const isc::asiolink::IOAddress& hint,
- const Lease::Type type, const bool fwd_dns,
- const bool rev_dns,
- const std::string& hostname,
- const bool fake_allocation):
- subnet_(subnet), duid_(duid), iaid_(iaid), type_(type), hwaddr_(),
- hints_(), fwd_dns_update_(fwd_dns), rev_dns_update_(rev_dns),
- hostname_(hostname), fake_allocation_(fake_allocation),
- old_leases_(), host_(), query_(), ia_rsp_(),
- allow_new_leases_in_renewals_(false) {
- static asiolink::IOAddress any("::");
- if (hint != any) {
- hints_.push_back(std::make_pair(hint, 128));
- }
-
-
- }
- void AllocEngine::findReservation(ClientContext6& ctx) const {
- if (!ctx.subnet_ || !ctx.duid_) {
- return;
- }
-
- Subnet::HRMode hr_mode = ctx.subnet_->getHostReservationMode();
-
-
- if (hr_mode != Subnet::HR_DISABLED) {
- ctx.host_ = HostMgr::instance().get6(ctx.subnet_->getID(), ctx.duid_,
- ctx.hwaddr_);
- } else {
-
- ctx.host_.reset();
- }
- }
- Lease6Collection
- AllocEngine::allocateLeases6(ClientContext6& ctx) {
- try {
- if (!ctx.subnet_) {
- isc_throw(InvalidOperation, "Subnet is required for IPv6 lease allocation");
- } else
- if (!ctx.duid_) {
- isc_throw(InvalidOperation, "DUID is mandatory for IPv6 lease allocation");
- }
-
-
- Lease6Collection leases =
- LeaseMgrFactory::instance().getLeases6(ctx.type_, *ctx.duid_, ctx.iaid_,
- ctx.subnet_->getID());
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- if (leases.empty() && ctx.host_) {
- LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
- ALLOC_ENGINE_V6_ALLOC_NO_LEASES_HR)
- .arg(ctx.query_->getLabel());
-
-
-
- allocateReservedLeases6(ctx, leases);
-
- if (!leases.empty()) {
- return (leases);
- }
-
-
-
-
-
-
-
-
-
-
-
-
- } else if (!leases.empty() && !ctx.host_) {
- LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
- ALLOC_ENGINE_V6_ALLOC_LEASES_NO_HR)
- .arg(ctx.query_->getLabel());
-
-
- removeNonmatchingReservedLeases6(ctx, leases);
- if (!leases.empty()) {
-
- return (updateFqdnData(ctx, leases));
- }
-
-
-
-
-
-
- } else if (!leases.empty() && ctx.host_) {
- LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
- ALLOC_ENGINE_V6_ALLOC_LEASES_HR)
- .arg(ctx.query_->getLabel());
-
-
- allocateReservedLeases6(ctx, leases);
-
-
-
-
-
-
-
-
-
- removeNonmatchingReservedLeases6(ctx, leases);
-
-
-
-
-
-
- removeNonreservedLeases6(ctx, leases);
-
-
- if (!leases.empty()) {
- return (leases);
- }
-
-
-
-
-
-
-
-
-
- }
-
-
-
-
-
-
-
-
-
-
- LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
- ALLOC_ENGINE_V6_ALLOC_UNRESERVED)
- .arg(ctx.query_->getLabel());
- leases = allocateUnreservedLeases6(ctx);
- if (!leases.empty()) {
- return (leases);
- }
-
- LOG_WARN(alloc_engine_logger, ALLOC_ENGINE_ADDRESS6_ALLOC_FAIL).arg(attempts_);
- } catch (const isc::Exception& e) {
-
- LOG_ERROR(alloc_engine_logger, ALLOC_ENGINE_ADDRESS6_ALLOC_ERROR).arg(e.what());
- }
- return (Lease6Collection());
- }
- Lease6Collection
- AllocEngine::allocateUnreservedLeases6(ClientContext6& ctx) {
- AllocatorPtr allocator = getAllocator(ctx.type_);
- if (!allocator) {
- isc_throw(InvalidOperation, "No allocator specified for "
- << Lease6::typeToText(ctx.type_));
- }
-
- Subnet::HRMode hr_mode = ctx.subnet_->getHostReservationMode();
- Lease6Collection leases;
- IOAddress hint("::");
- if (!ctx.hints_.empty()) {
-
- hint = ctx.hints_[0].first;
- }
-
-
- Pool6Ptr pool = boost::dynamic_pointer_cast<
- Pool6>(ctx.subnet_->getPool(ctx.type_, hint, false));
- if (pool) {
-
- Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(ctx.type_, hint);
- if (!lease) {
-
-
-
- ConstHostPtr host;
- if (hr_mode != Subnet::HR_DISABLED) {
- host = HostMgr::instance().get6(ctx.subnet_->getID(), hint);
- }
- if (!host) {
-
-
-
-
- lease = createLease6(ctx, hint, pool->getLength());
-
-
-
-
- if (lease) {
-
- Lease6Collection collection;
- collection.push_back(lease);
- return (collection);
- }
- }
- } else {
-
- if (lease->expired()) {
- ConstHostPtr host;
- if (hr_mode != Subnet::HR_DISABLED) {
- host = HostMgr::instance().get6(ctx.subnet_->getID(), hint);
- }
-
- if (!host) {
-
-
- Lease6Ptr old_lease(new Lease6(*lease));
- ctx.old_leases_.push_back(old_lease);
-
- lease = reuseExpiredLease(lease, ctx, pool->getLength());
-
- leases.push_back(lease);
- return (leases);
- }
- }
- }
- }
-
-
-
-
-
-
-
-
-
-
-
-
- uint32_t max_attempts = ctx.subnet_->getPoolCapacity(ctx.type_);
- for (uint32_t i = 0; i < max_attempts; ++i)
- {
- IOAddress candidate = allocator->pickAddress(ctx.subnet_, ctx.duid_, hint);
-
-
-
- if (hr_mode == Subnet::HR_ALL &&
- HostMgr::instance().get6(ctx.subnet_->getID(), candidate)) {
-
- continue;
- }
-
-
- uint8_t prefix_len = 128;
- if (ctx.type_ == Lease::TYPE_PD) {
- Pool6Ptr pool = boost::dynamic_pointer_cast<Pool6>(
- ctx.subnet_->getPool(ctx.type_, candidate, false));
-
- prefix_len = pool->getLength();
- }
- Lease6Ptr existing = LeaseMgrFactory::instance().getLease6(ctx.type_,
- candidate);
- if (!existing) {
-
-
- Lease6Ptr lease = createLease6(ctx, candidate, prefix_len);
- if (lease) {
-
-
- ctx.old_leases_.clear();
- leases.push_back(lease);
- return (leases);
- }
-
-
-
- } else {
- if (existing->expired()) {
-
-
- Lease6Ptr old_lease(new Lease6(*existing));
- ctx.old_leases_.push_back(old_lease);
- existing = reuseExpiredLease(existing,
- ctx,
- prefix_len);
- leases.push_back(existing);
- return (leases);
- }
- }
- }
-
- return (Lease6Collection());
- }
- void
- AllocEngine::allocateReservedLeases6(ClientContext6& ctx, Lease6Collection& existing_leases) {
-
- if (!ctx.host_ || !ctx.host_->hasIPv6Reservation()) {
- return;
- }
-
- IPv6Resrv::Type type = ctx.type_ == Lease::TYPE_NA ? IPv6Resrv::TYPE_NA : IPv6Resrv::TYPE_PD;
-
- const IPv6ResrvRange& reservs = ctx.host_->getIPv6Reservations(type);
- if (std::distance(reservs.first, reservs.second) == 0) {
-
- return;
- }
- for (IPv6ResrvIterator resv = reservs.first; resv != reservs.second; ++resv) {
-
- IOAddress addr = resv->second.getPrefix();
- uint8_t prefix_len = resv->second.getPrefixLen();
-
- for (Lease6Collection::const_iterator l = existing_leases.begin();
- l != existing_leases.end(); ++l) {
-
- if (((*l)->addr_ == addr) && (*l)->valid_lft_ != 0) {
- return;
- }
- }
-
-
- if (!LeaseMgrFactory::instance().getLease6(ctx.type_, addr)) {
-
- Lease6Ptr lease = createLease6(ctx, addr, prefix_len);
-
- existing_leases.push_back(lease);
- if (ctx.type_ == Lease::TYPE_NA) {
- LOG_INFO(alloc_engine_logger, ALLOC_ENGINE_HR_RESERVED_ADDR_GRANTED)
- .arg(addr.toText()).arg(ctx.duid_->toText());
- } else {
- LOG_INFO(alloc_engine_logger, ALLOC_ENGINE_HR_RESERVED_PREFIX_GRANTED)
- .arg(addr.toText()).arg(static_cast<int>(prefix_len))
- .arg(ctx.duid_->toText());
- }
-
-
-
-
-
-
-
-
-
- return;
- }
- }
- }
- void
- AllocEngine::removeNonmatchingReservedLeases6(ClientContext6& ctx,
- Lease6Collection& existing_leases) {
-
-
-
- if (existing_leases.empty() || !ctx.subnet_ ||
- (ctx.subnet_->getHostReservationMode() == Subnet::HR_DISABLED) ) {
- return;
- }
-
-
-
- Lease6Collection copy = existing_leases;
- for (Lease6Collection::const_iterator candidate = copy.begin();
- candidate != copy.end(); ++candidate) {
- ConstHostPtr host = HostMgr::instance().get6(ctx.subnet_->getID(),
- (*candidate)->addr_);
- if (!host || (host == ctx.host_)) {
-
-
- continue;
- }
-
-
- if (ctx.type_ == Lease::TYPE_NA) {
- LOG_INFO(alloc_engine_logger, ALLOC_ENGINE_HR_REVOKED_ADDR6_LEASE)
- .arg((*candidate)->addr_.toText()).arg(ctx.duid_->toText())
- .arg(host->getIdentifierAsText());
- } else {
- LOG_INFO(alloc_engine_logger, ALLOC_ENGINE_HR_REVOKED_PREFIX6_LEASE)
- .arg((*candidate)->addr_.toText())
- .arg(static_cast<int>((*candidate)->prefixlen_))
- .arg(ctx.duid_->toText())
- .arg(host->getIdentifierAsText());
- }
-
- LeaseMgrFactory::instance().deleteLease((*candidate)->addr_);
-
-
-
-
-
- ctx.old_leases_.push_back(*candidate);
-
- removeLeases(existing_leases, (*candidate)->addr_);
- }
- }
- bool
- AllocEngine::removeLeases(Lease6Collection& container, const asiolink::IOAddress& addr) {
- bool removed = false;
- for (Lease6Collection::iterator lease = container.begin();
- lease != container.end(); ++lease) {
- if ((*lease)->addr_ == addr) {
- lease->reset();
- removed = true;
- }
- }
-
- container.erase(std::remove(container.begin(), container.end(), Lease6Ptr()),
- container.end());
- return (removed);
- }
- void
- AllocEngine::removeNonreservedLeases6(ClientContext6& ctx,
- Lease6Collection& existing_leases) {
-
-
- if (existing_leases.empty() || !ctx.host_ || !ctx.host_->hasIPv6Reservation()) {
- return;
- }
-
- int total = existing_leases.size();
-
-
- for (Lease6Collection::iterator lease = existing_leases.begin();
- lease != existing_leases.end(); ++lease) {
- IPv6Resrv resv(ctx.type_ == Lease::TYPE_NA ? IPv6Resrv::TYPE_NA : IPv6Resrv::TYPE_PD,
- (*lease)->addr_, (*lease)->prefixlen_);
- if (!ctx.host_->hasReservation(resv)) {
-
-
- LeaseMgrFactory::instance().deleteLease((*lease)->addr_);
-
-
- ctx.old_leases_.push_back(*lease);
-
-
-
- lease->reset();
- if (--total == 1) {
-
- break;
- }
- }
- }
-
-
- existing_leases.erase(std::remove(existing_leases.begin(),
- existing_leases.end(), Lease6Ptr()), existing_leases.end());
- }
- Lease6Ptr
- AllocEngine::reuseExpiredLease(Lease6Ptr& expired, ClientContext6& ctx,
- uint8_t prefix_len) {
- if (!expired->expired()) {
- isc_throw(BadValue, "Attempt to recycle lease that is still valid");
- }
- if (expired->type_ != Lease::TYPE_PD) {
- prefix_len = 128;
- }
-
- expired->iaid_ = ctx.iaid_;
- expired->duid_ = ctx.duid_;
- expired->preferred_lft_ = ctx.subnet_->getPreferred();
- expired->valid_lft_ = ctx.subnet_->getValid();
- expired->t1_ = ctx.subnet_->getT1();
- expired->t2_ = ctx.subnet_->getT2();
- expired->cltt_ = time(NULL);
- expired->subnet_id_ = ctx.subnet_->getID();
- expired->fixed_ = false;
- expired->hostname_ = ctx.hostname_;
- expired->fqdn_fwd_ = ctx.fwd_dns_update_;
- expired->fqdn_rev_ = ctx.rev_dns_update_;
- expired->prefixlen_ = prefix_len;
-
-
-
- if (ctx.callout_handle_ &&
- HooksManager::getHooksManager().calloutsPresent(hook_index_lease6_select_)) {
-
- ctx.callout_handle_->deleteAllArguments();
-
-
- ctx.callout_handle_->setArgument("subnet6", ctx.subnet_);
-
- ctx.callout_handle_->setArgument("fake_allocation", ctx.fake_allocation_);
-
- ctx.callout_handle_->setArgument("lease6", expired);
-
- HooksManager::callCallouts(hook_index_lease6_select_, *ctx.callout_handle_);
-
-
-
- if (ctx.callout_handle_->getSkip()) {
- LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_HOOKS, DHCPSRV_HOOK_LEASE6_SELECT_SKIP);
- return (Lease6Ptr());
- }
-
-
- ctx.callout_handle_->getArgument("lease6", expired);
- }
- if (!ctx.fake_allocation_) {
-
- LeaseMgrFactory::instance().updateLease6(expired);
- }
-
-
-
-
- return (expired);
- }
- Lease6Ptr AllocEngine::createLease6(ClientContext6& ctx,
- const IOAddress& addr,
- uint8_t prefix_len) {
- if (ctx.type_ != Lease::TYPE_PD) {
- prefix_len = 128;
- }
- Lease6Ptr lease(new Lease6(ctx.type_, addr, ctx.duid_, ctx.iaid_,
- ctx.subnet_->getPreferred(), ctx.subnet_->getValid(),
- ctx.subnet_->getT1(), ctx.subnet_->getT2(),
- ctx.subnet_->getID(), ctx.hwaddr_, prefix_len));
- lease->fqdn_fwd_ = ctx.fwd_dns_update_;
- lease->fqdn_rev_ = ctx.rev_dns_update_;
- lease->hostname_ = ctx.hostname_;
-
- if (ctx.callout_handle_ &&
- HooksManager::getHooksManager().calloutsPresent(hook_index_lease6_select_)) {
-
- ctx.callout_handle_->deleteAllArguments();
-
-
- ctx.callout_handle_->setArgument("subnet6", ctx.subnet_);
-
- ctx.callout_handle_->setArgument("fake_allocation", ctx.fake_allocation_);
- ctx.callout_handle_->setArgument("lease6", lease);
-
- HooksManager::callCallouts(hook_index_lease6_select_, *ctx.callout_handle_);
-
-
-
- if (ctx.callout_handle_->getSkip()) {
- LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_HOOKS, DHCPSRV_HOOK_LEASE6_SELECT_SKIP);
- return (Lease6Ptr());
- }
-
-
- ctx.callout_handle_->getArgument("lease6", lease);
- }
- if (!ctx.fake_allocation_) {
-
- bool status = LeaseMgrFactory::instance().addLease(lease);
- if (status) {
- return (lease);
- } else {
-
-
-
-
- return (Lease6Ptr());
- }
- } else {
-
-
-
- Lease6Ptr existing = LeaseMgrFactory::instance().getLease6(
- Lease::TYPE_NA, addr);
- if (!existing) {
- return (lease);
- } else {
- return (Lease6Ptr());
- }
- }
- }
- Lease6Collection
- AllocEngine::renewLeases6(ClientContext6& ctx) {
- try {
- if (!ctx.subnet_) {
- isc_throw(InvalidOperation, "Subnet is required for allocation");
- }
- if (!ctx.duid_) {
- isc_throw(InvalidOperation, "DUID is mandatory for allocation");
- }
-
- Lease6Collection leases = LeaseMgrFactory::instance()
- .getLeases6(ctx.type_, *ctx.duid_, ctx.iaid_, ctx.subnet_->getID());
- if (!leases.empty()) {
- LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
- ALLOC_ENGINE_V6_RENEW_REMOVE_RESERVED)
- .arg(ctx.query_->getLabel());
-
-
- removeNonmatchingReservedLeases6(ctx, leases);
- }
- if (ctx.host_) {
- LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
- ALLOC_ENGINE_V6_RENEW_HR)
- .arg(ctx.query_->getLabel());
-
- allocateReservedLeases6(ctx, leases);
-
-
-
-
- removeNonreservedLeases6(ctx, leases);
- }
-
-
-
-
- if (leases.empty() && ctx.allow_new_leases_in_renewals_) {
- LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
- ALLOC_ENGINE_V6_EXTEND_ALLOC_UNRESERVED)
- .arg(ctx.query_->getLabel());
- leases = allocateUnreservedLeases6(ctx);
- }
-
- for (Lease6Collection::iterator l = leases.begin(); l != leases.end(); ++l) {
- LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE_DETAIL,
- ALLOC_ENGINE_V6_EXTEND_LEASE)
- .arg(ctx.query_->getLabel())
- .arg((*l)->typeToText((*l)->type_))
- .arg((*l)->addr_);
- extendLease6(ctx, *l);
- }
- return (leases);
- } catch (const isc::Exception& e) {
-
- LOG_ERROR(alloc_engine_logger, ALLOC_ENGINE_V6_EXTEND_ERROR)
- .arg(ctx.query_->getLabel())
- .arg(e.what());
- }
- return (Lease6Collection());
- }
- void
- AllocEngine::extendLease6(ClientContext6& ctx, Lease6Ptr lease) {
- if (!lease || !ctx.subnet_) {
- return;
- }
- LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE_DETAIL_DATA,
- ALLOC_ENGINE_V6_EXTEND_LEASE_DATA)
- .arg(ctx.query_->getLabel())
- .arg(lease->toText());
-
-
- if ((lease->type_ != Lease::TYPE_PD) && !ctx.subnet_->inRange(lease->addr_)) {
-
-
- LeaseMgrFactory::instance().deleteLease(lease->addr_);
-
- ctx.old_leases_.push_back(lease);
- return;
- }
-
- Lease6 old_data = *lease;
- lease->preferred_lft_ = ctx.subnet_->getPreferred();
- lease->valid_lft_ = ctx.subnet_->getValid();
- lease->t1_ = ctx.subnet_->getT1();
- lease->t2_ = ctx.subnet_->getT2();
- lease->cltt_ = time(NULL);
- lease->hostname_ = ctx.hostname_;
- lease->fqdn_fwd_ = ctx.fwd_dns_update_;
- lease->fqdn_rev_ = ctx.rev_dns_update_;
- lease->hwaddr_ = ctx.hwaddr_;
- LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE_DETAIL_DATA,
- ALLOC_ENGINE_V6_EXTEND_NEW_LEASE_DATA)
- .arg(ctx.query_->getLabel())
- .arg(lease->toText());
- bool skip = false;
-
- int hook_point = ctx.query_->getType() == DHCPV6_RENEW ?
- Hooks.hook_index_lease6_renew_ : Hooks.hook_index_lease6_rebind_;
- if (HooksManager::calloutsPresent(hook_point)) {
- CalloutHandlePtr callout_handle = ctx.callout_handle_;
-
- callout_handle->deleteAllArguments();
-
- callout_handle->setArgument("query6", ctx.query_);
-
- callout_handle->setArgument("lease6", lease);
-
- if (lease->type_ == Lease::TYPE_NA) {
- callout_handle->setArgument("ia_na", ctx.ia_rsp_);
- } else {
- callout_handle->setArgument("ia_pd", ctx.ia_rsp_);
- }
-
- HooksManager::callCallouts(hook_point, *callout_handle);
-
-
-
- if (callout_handle->getSkip()) {
- skip = true;
- LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_HOOKS,
- DHCPSRV_HOOK_LEASE6_EXTEND_SKIP)
- .arg(ctx.query_->getName());
- }
- }
- if (!skip) {
- LeaseMgrFactory::instance().updateLease6(lease);
- } else {
-
-
-
-
- *lease = old_data;
- }
- }
- Lease6Collection
- AllocEngine::updateFqdnData(ClientContext6& ctx, const Lease6Collection& leases) {
- Lease6Collection updated_leases;
- for (Lease6Collection::const_iterator lease_it = leases.begin();
- lease_it != leases.end(); ++lease_it) {
- Lease6Ptr lease(new Lease6(**lease_it));
- lease->fqdn_fwd_ = ctx.fwd_dns_update_;
- lease->fqdn_rev_ = ctx.rev_dns_update_;
- lease->hostname_ = ctx.hostname_;
- if (!ctx.fake_allocation_ &&
- ((lease->fqdn_fwd_ != (*lease_it)->fqdn_fwd_) ||
- (lease->fqdn_rev_ != (*lease_it)->fqdn_rev_) ||
- (lease->hostname_ != (*lease_it)->hostname_))) {
- ctx.changed_leases_.push_back(*lease_it);
- LeaseMgrFactory::instance().updateLease6(lease);
- }
- updated_leases.push_back(lease);
- }
- return (updated_leases);
- }
- }
- }
- namespace {
- bool
- addressReserved(const IOAddress& address, const AllocEngine::ClientContext4& ctx) {
- ConstHostPtr host = HostMgr::instance().get4(ctx.subnet_->getID(), address);
- HWAddrPtr host_hwaddr;
- if (host) {
- host_hwaddr = host->getHWAddress();
- if (ctx.hwaddr_ && host_hwaddr) {
-
-
-
-
- return (host_hwaddr->hwaddr_ != ctx.hwaddr_->hwaddr_);
- } else {
- return (false);
- }
- }
- return (false);
- }
- bool
- hasAddressReservation(const AllocEngine::ClientContext4& ctx) {
- return (ctx.host_ && !ctx.host_->getIPv4Reservation().isV4Zero());
- }
- void findClientLease(const AllocEngine::ClientContext4& ctx, Lease4Ptr& client_lease) {
- LeaseMgr& lease_mgr = LeaseMgrFactory::instance();
-
-
-
-
-
- if (ctx.clientid_) {
- client_lease = lease_mgr.getLease4(*ctx.clientid_, ctx.subnet_->getID());
- }
-
-
- if (!client_lease && ctx.hwaddr_) {
- client_lease = lease_mgr.getLease4(*ctx.hwaddr_, ctx.subnet_->getID());
-
-
-
-
- if (client_lease && !client_lease->belongsToClient(ctx.hwaddr_, ctx.clientid_)) {
- client_lease.reset();
- }
- }
- }
- }
- namespace isc {
- namespace dhcp {
- AllocEngine::ClientContext4::ClientContext4()
- : subnet_(), clientid_(), hwaddr_(),
- requested_address_(IOAddress::IPV4_ZERO_ADDRESS()),
- fwd_dns_update_(false), rev_dns_update_(false),
- hostname_(""), callout_handle_(), fake_allocation_(false),
- old_lease_(), host_(), conflicting_lease_(), query_() {
- }
- AllocEngine::ClientContext4::ClientContext4(const Subnet4Ptr& subnet,
- const ClientIdPtr& clientid,
- const HWAddrPtr& hwaddr,
- const asiolink::IOAddress& requested_addr,
- const bool fwd_dns_update,
- const bool rev_dns_update,
- const std::string& hostname,
- const bool fake_allocation)
- : subnet_(subnet), clientid_(clientid), hwaddr_(hwaddr),
- requested_address_(requested_addr),
- fwd_dns_update_(fwd_dns_update), rev_dns_update_(rev_dns_update),
- hostname_(hostname), callout_handle_(),
- fake_allocation_(fake_allocation), old_lease_(), host_() {
- }
- Lease4Ptr
- AllocEngine::allocateLease4(ClientContext4& ctx) {
-
-
-
- ctx.old_lease_.reset();
- Lease4Ptr new_lease;
- try {
- if (!ctx.subnet_) {
- isc_throw(BadValue, "Can't allocate IPv4 address without subnet");
- }
- if (!ctx.hwaddr_) {
- isc_throw(BadValue, "HWAddr must be defined");
- }
- new_lease = ctx.fake_allocation_ ? discoverLease4(ctx) : requestLease4(ctx);
- if (!new_lease) {
-
- LOG_WARN(alloc_engine_logger, ALLOC_ENGINE_ADDRESS4_ALLOC_FAIL).arg(attempts_);
- }
- } catch (const isc::Exception& e) {
-
- LOG_ERROR(alloc_engine_logger, ALLOC_ENGINE_ADDRESS4_ALLOC_ERROR).arg(e.what());
- }
- return (new_lease);
- }
- void
- AllocEngine::findReservation(ClientContext4& ctx) {
- ctx.host_.reset();
-
- if (ctx.subnet_) {
-
- Subnet::HRMode hr_mode = ctx.subnet_->getHostReservationMode();
-
-
- if (hr_mode != Subnet::HR_DISABLED) {
-
-
- ctx.host_ = HostMgr::instance().get4(ctx.subnet_->getID(), ctx.hwaddr_,
- ctx.clientid_);
- }
- }
- }
- Lease4Ptr
- AllocEngine::discoverLease4(AllocEngine::ClientContext4& ctx) {
-
-
-
- Lease4Ptr client_lease;
- findClientLease(ctx, client_lease);
-
-
- Lease4Ptr new_lease;
-
-
- if (hasAddressReservation(ctx)) {
- LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
- ALLOC_ENGINE_V4_DISCOVER_HR)
- .arg(ctx.query_->getLabel())
- .arg(ctx.host_->getIPv4Reservation().toText());
-
-
-
-
- if (!client_lease || (client_lease->addr_ != ctx.host_->getIPv4Reservation())) {
-
-
-
-
-
-
- new_lease = allocateOrReuseLease4(ctx.host_->getIPv4Reservation(), ctx);
- if (!new_lease) {
- LOG_WARN(alloc_engine_logger, ALLOC_ENGINE_DISCOVER_ADDRESS_CONFLICT)
- .arg(ctx.host_->getIPv4Reservation().toText())
- .arg(ctx.conflicting_lease_ ? ctx.conflicting_lease_->toText() :
- "(no lease info)");
- }
- } else {
- new_lease = renewLease4(client_lease, ctx);
- }
- }
-
-
-
-
-
-
-
-
-
- if (!new_lease && client_lease &&
- ctx.subnet_->inPool(Lease::TYPE_V4, client_lease->addr_) &&
- !addressReserved(client_lease->addr_, ctx)) {
- LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
- ALLOC_ENGINE_V4_OFFER_EXISTING_LEASE)
- .arg(ctx.query_->getLabel());
- new_lease = renewLease4(client_lease, ctx);
- }
-
-
-
-
-
-
-
- if (!new_lease && !ctx.requested_address_.isV4Zero() &&
- ctx.subnet_->inPool(Lease::TYPE_V4, ctx.requested_address_) &&
- !addressReserved(ctx.requested_address_, ctx)) {
- LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
- ALLOC_ENGINE_V4_OFFER_NEW_LEASE)
- .arg(ctx.query_->getLabel());
- new_lease = allocateOrReuseLease4(ctx.requested_address_, ctx);
- }
-
-
-
- if (!new_lease) {
- LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
- ALLOC_ENGINE_V4_OFFER_NEW_LEASE)
- .arg(ctx.query_->getLabel());
- new_lease = allocateUnreservedLease4(ctx);
- }
-
-
-
-
- if (!ctx.old_lease_ && client_lease) {
- ctx.old_lease_ = client_lease;
- }
- return (new_lease);
- }
- Lease4Ptr
- AllocEngine::requestLease4(AllocEngine::ClientContext4& ctx) {
-
-
-
- Lease4Ptr client_lease;
- findClientLease(ctx, client_lease);
-
- LeaseMgr& lease_mgr = LeaseMgrFactory::instance();
-
-
-
-
-
-
- if (!ctx.requested_address_.isV4Zero()) {
-
-
-
- if (addressReserved(ctx.requested_address_, ctx)) {
- LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
- ALLOC_ENGINE_V4_REQUEST_ADDRESS_RESERVED)
- .arg(ctx.query_->getLabel())
- .arg(ctx.requested_address_.toText());
- return (Lease4Ptr());
- }
- } else if (hasAddressReservation(ctx)) {
-
-
-
-
- ctx.requested_address_ = ctx.host_->getIPv4Reservation();
- LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
- ALLOC_ENGINE_V4_REQUEST_USE_HR)
- .arg(ctx.query_->getLabel())
- .arg(ctx.requested_address_.toText());
- }
- if (!ctx.requested_address_.isV4Zero()) {
-
-
- Lease4Ptr existing = LeaseMgrFactory::instance().getLease4(ctx.requested_address_);
-
-
-
-
- if (existing && !existing->expired() &&
- !existing->belongsToClient(ctx.hwaddr_, ctx.clientid_)) {
- LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
- ALLOC_ENGINE_V4_REQUEST_IN_USE)
- .arg(ctx.query_->getLabel())
- .arg(ctx.requested_address_.toText());
- return (Lease4Ptr());
- }
-
-
-
-
- if (hasAddressReservation(ctx) &&
- (ctx.host_->getIPv4Reservation() != ctx.requested_address_)) {
- existing = LeaseMgrFactory::instance().getLease4(ctx.host_->getIPv4Reservation());
-
-
-
-
- if (!existing || existing->expired()) {
- LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
- ALLOC_ENGINE_V4_REQUEST_INVALID)
- .arg(ctx.query_->getLabel())
- .arg(ctx.host_->getIPv4Reservation().toText())
- .arg(ctx.requested_address_.toText());
- return (Lease4Ptr());
- }
- }
-
-
-
- if ((!hasAddressReservation(ctx) ||
- (ctx.host_->getIPv4Reservation() != ctx.requested_address_)) &&
- !ctx.subnet_->inPool(Lease4::TYPE_V4, ctx.requested_address_)) {
- LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
- ALLOC_ENGINE_V4_REQUEST_OUT_OF_POOL)
- .arg(ctx.query_->getLabel())
- .arg(ctx.requested_address_);
- return (Lease4Ptr());
- }
- }
-
-
-
-
-
- if (client_lease) {
- if ((client_lease->addr_ == ctx.requested_address_) ||
- ctx.requested_address_.isV4Zero()) {
- LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
- ALLOC_ENGINE_V4_REQUEST_EXTEND_LEASE)
- .arg(ctx.query_->getLabel())
- .arg(ctx.requested_address_);
- return (renewLease4(client_lease, ctx));
- }
- }
-
-
- Lease4Ptr new_lease;
-
-
- if (!ctx.requested_address_.isV4Zero()) {
- LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
- ALLOC_ENGINE_V4_REQUEST_ALLOC_REQUESTED)
- .arg(ctx.query_->getLabel())
- .arg(ctx.requested_address_.toText());
-
-
-
-
-
- new_lease = allocateOrReuseLease4(ctx.requested_address_, ctx);
- } else {
- LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
- ALLOC_ENGINE_V4_REQUEST_PICK_ADDRESS)
- .arg(ctx.query_->getLabel());
-
-
-
- new_lease = allocateUnreservedLease4(ctx);
- }
-
-
-
- if (new_lease && client_lease) {
- ctx.old_lease_ = Lease4Ptr(new Lease4(*client_lease));
- LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
- ALLOC_ENGINE_V4_REQUEST_REMOVE_LEASE)
- .arg(ctx.query_->getLabel())
- .arg(client_lease->addr_.toText());
- lease_mgr.deleteLease(client_lease->addr_);
- }
-
-
- return (new_lease);
- }
- Lease4Ptr
- AllocEngine::createLease4(const ClientContext4& ctx, const IOAddress& addr) {
- if (!ctx.hwaddr_) {
- isc_throw(BadValue, "Can't create a lease with NULL HW address");
- }
- if (!ctx.subnet_) {
- isc_throw(BadValue, "Can't create a lease without a subnet");
- }
- time_t now = time(NULL);
-
- std::vector<uint8_t> local_copy;
- if (ctx.clientid_) {
- local_copy = ctx.clientid_->getDuid();
- }
- Lease4Ptr lease(new Lease4(addr, ctx.hwaddr_, &local_copy[0], local_copy.size(),
- ctx.subnet_->getValid(), ctx.subnet_->getT1(),
- ctx.subnet_->getT2(),
- now, ctx.subnet_->getID()));
-
- lease->fqdn_fwd_ = ctx.fwd_dns_update_;
- lease->fqdn_rev_ = ctx.rev_dns_update_;
- lease->hostname_ = ctx.hostname_;
-
- if (ctx.callout_handle_ &&
- HooksManager::getHooksManager().calloutsPresent(hook_index_lease4_select_)) {
-
- ctx.callout_handle_->deleteAllArguments();
-
-
-
-
-
- Subnet4Ptr subnet4 = boost::dynamic_pointer_cast<Subnet4>(ctx.subnet_);
- ctx.callout_handle_->setArgument("subnet4", subnet4);
-
- ctx.callout_handle_->setArgument("fake_allocation", ctx.fake_allocation_);
-
- ctx.callout_handle_->setArgument("lease4", lease);
-
- HooksManager::callCallouts(hook_index_lease4_select_, *ctx.callout_handle_);
-
-
-
- if (ctx.callout_handle_->getSkip()) {
- LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_HOOKS, DHCPSRV_HOOK_LEASE4_SELECT_SKIP);
- return (Lease4Ptr());
- }
-
-
- ctx.callout_handle_->getArgument("lease4", lease);
- }
- if (!ctx.fake_allocation_) {
-
- bool status = LeaseMgrFactory::instance().addLease(lease);
- if (status) {
- return (lease);
- } else {
-
-
-
-
- return (Lease4Ptr());
- }
- } else {
-
-
-
- Lease4Ptr existing = LeaseMgrFactory::instance().getLease4(addr);
- if (!existing) {
- return (lease);
- } else {
- return (Lease4Ptr());
- }
- }
- }
- Lease4Ptr
- AllocEngine::renewLease4(const Lease4Ptr& lease,
- AllocEngine::ClientContext4& ctx) {
- if (!lease) {
- isc_throw(BadValue, "null lease specified for renewLease4");
- }
-
-
-
-
- Lease4 old_values = *lease;
- ctx.old_lease_.reset(new Lease4(old_values));
-
- updateLease4Information(lease, ctx);
- bool skip = false;
-
- if (HooksManager::getHooksManager().
- calloutsPresent(Hooks.hook_index_lease4_renew_)) {
-
- ctx.callout_handle_->deleteAllArguments();
-
-
-
-
- Subnet4Ptr subnet4 = boost::dynamic_pointer_cast<Subnet4>(ctx.subnet_);
-
- ctx.callout_handle_->setArgument("subnet4", subnet4);
- ctx.callout_handle_->setArgument("clientid", ctx.clientid_);
- ctx.callout_handle_->setArgument("hwaddr", ctx.hwaddr_);
-
- ctx.callout_handle_->setArgument("lease4", lease);
-
- HooksManager::callCallouts(Hooks.hook_index_lease4_renew_,
- *ctx.callout_handle_);
-
-
-
- if (ctx.callout_handle_->getSkip()) {
- skip = true;
- LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_HOOKS,
- DHCPSRV_HOOK_LEASE4_RENEW_SKIP);
- }
- }
- if (!ctx.fake_allocation_ && !skip) {
-
- LeaseMgrFactory::instance().updateLease4(lease);
- }
- if (skip) {
-
-
- *lease = old_values;
- }
- return (lease);
- }
- Lease4Ptr
- AllocEngine::reuseExpiredLease4(Lease4Ptr& expired,
- AllocEngine::ClientContext4& ctx) {
- if (!expired) {
- isc_throw(BadValue, "null lease specified for reuseExpiredLease");
- }
- if (!ctx.subnet_) {
- isc_throw(BadValue, "null subnet specified for the reuseExpiredLease");
- }
- updateLease4Information(expired, ctx);
- expired->fixed_ = false;
-
-
-
- if (ctx.callout_handle_ && HooksManager::getHooksManager()
- .calloutsPresent(hook_index_lease4_select_)) {
-
- ctx.callout_handle_->deleteAllArguments();
-
-
-
-
-
- Subnet4Ptr subnet4 = boost::dynamic_pointer_cast<Subnet4>(ctx.subnet_);
- ctx.callout_handle_->setArgument("subnet4", subnet4);
-
- ctx.callout_handle_->setArgument("fake_allocation",
- ctx.fake_allocation_);
-
- ctx.callout_handle_->setArgument("lease4", expired);
-
- HooksManager::callCallouts(hook_index_lease4_select_, *ctx.callout_handle_);
-
-
-
- if (ctx.callout_handle_->getSkip()) {
- LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_HOOKS,
- DHCPSRV_HOOK_LEASE4_SELECT_SKIP);
- return (Lease4Ptr());
- }
-
-
- ctx.callout_handle_->getArgument("lease4", expired);
- }
- if (!ctx.fake_allocation_) {
-
- LeaseMgrFactory::instance().updateLease4(expired);
- }
-
-
-
-
- return (expired);
- }
- Lease4Ptr
- AllocEngine::allocateOrReuseLease4(const IOAddress& candidate, ClientContext4& ctx) {
- ctx.conflicting_lease_.reset();
- Lease4Ptr exist_lease = LeaseMgrFactory::instance().getLease4(candidate);
- if (exist_lease) {
- if (exist_lease->expired()) {
- ctx.old_lease_ = Lease4Ptr(new Lease4(*exist_lease));
- return (reuseExpiredLease4(exist_lease, ctx));
- } else {
-
-
-
- ctx.conflicting_lease_ = exist_lease;
- }
- } else {
- return (createLease4(ctx, candidate));
- }
- return (Lease4Ptr());
- }
- Lease4Ptr
- AllocEngine::allocateUnreservedLease4(ClientContext4& ctx) {
- Lease4Ptr new_lease;
- AllocatorPtr allocator = getAllocator(Lease::TYPE_V4);
- const uint64_t max_attempts = ctx.subnet_->getPoolCapacity(Lease::TYPE_V4);
- for (uint64_t i = 0; i < max_attempts; ++i) {
- IOAddress candidate = allocator->pickAddress(ctx.subnet_, ctx.clientid_,
- ctx.requested_address_);
-
- if (!addressReserved(candidate, ctx)) {
-
-
-
- new_lease = allocateOrReuseLease4(candidate, ctx);
- if (new_lease) {
- return (new_lease);
- }
- }
- }
- return (new_lease);
- }
- void
- AllocEngine::updateLease4Information(const Lease4Ptr& lease,
- AllocEngine::ClientContext4& ctx) const {
- lease->subnet_id_ = ctx.subnet_->getID();
- lease->hwaddr_ = ctx.hwaddr_;
- lease->client_id_ = ctx.clientid_;
- lease->cltt_ = time(NULL);
- lease->t1_ = ctx.subnet_->getT1();
- lease->t2_ = ctx.subnet_->getT2();
- lease->valid_lft_ = ctx.subnet_->getValid();
- lease->fqdn_fwd_ = ctx.fwd_dns_update_;
- lease->fqdn_rev_ = ctx.rev_dns_update_;
- lease->hostname_ = ctx.hostname_;
- }
- };
- };
|