8 #include <kea_version.h>
63 #include <boost/algorithm/string.hpp>
64 #include <boost/foreach.hpp>
65 #include <boost/pointer_cast.hpp>
66 #include <boost/shared_ptr.hpp>
83 namespace ph = std::placeholders;
89 int hook_index_buffer4_receive_;
90 int hook_index_pkt4_receive_;
91 int hook_index_subnet4_select_;
92 int hook_index_leases4_committed_;
93 int hook_index_lease4_release_;
94 int hook_index_pkt4_send_;
95 int hook_index_buffer4_send_;
96 int hook_index_lease4_decline_;
97 int hook_index_host4_identifier_;
98 int hook_index_ddns4_update_;
99 int hook_index_lease4_offer_;
103 hook_index_buffer4_receive_ = HooksManager::registerHook(
"buffer4_receive");
104 hook_index_pkt4_receive_ = HooksManager::registerHook(
"pkt4_receive");
105 hook_index_subnet4_select_ = HooksManager::registerHook(
"subnet4_select");
106 hook_index_leases4_committed_ = HooksManager::registerHook(
"leases4_committed");
107 hook_index_lease4_release_ = HooksManager::registerHook(
"lease4_release");
108 hook_index_pkt4_send_ = HooksManager::registerHook(
"pkt4_send");
109 hook_index_buffer4_send_ = HooksManager::registerHook(
"buffer4_send");
110 hook_index_lease4_decline_ = HooksManager::registerHook(
"lease4_decline");
111 hook_index_host4_identifier_ = HooksManager::registerHook(
"host4_identifier");
112 hook_index_ddns4_update_ = HooksManager::registerHook(
"ddns4_update");
113 hook_index_lease4_offer_ = HooksManager::registerHook(
"lease4_offer");
119 std::set<std::string> dhcp4_statistics = {
121 "pkt4-discover-received",
122 "pkt4-offer-received",
123 "pkt4-request-received",
126 "pkt4-release-received",
127 "pkt4-decline-received",
128 "pkt4-inform-received",
129 "pkt4-unknown-received",
136 "v4-allocation-fail",
137 "v4-allocation-fail-shared-network",
138 "v4-allocation-fail-subnet",
139 "v4-allocation-fail-no-pools",
140 "v4-allocation-fail-classes",
141 "v4-reservation-conflicts",
161 : alloc_engine_(alloc_engine), query_(query), resp_(),
164 if (!alloc_engine_) {
166 " when creating an instance of the Dhcpv4Exchange");
171 " creating an instance of the Dhcpv4Exchange");
180 context_->subnet_ = subnet;
186 if (subnet && !context_->early_global_reservations_lookup_) {
189 context_->clientid_.reset(
new ClientId(opt_clientid->getData()));
195 if (subnet->getReservationsInSubnet() ||
196 subnet->getReservationsGlobal()) {
199 if (!context_->early_global_reservations_lookup_) {
204 alloc_engine->findReservation(*context_);
207 subnet->getSharedNetwork(sn);
217 auto global_host = context_->globalHost();
218 auto current_host = context_->currentHost();
219 if ((!context_->early_global_reservations_lookup_ &&
220 global_host && !global_host->getClientClasses4().empty()) ||
221 (!sn && current_host && !current_host->getClientClasses4().empty())) {
242 if (!context_->hosts_.empty()) {
243 query->addClass(
"KNOWN");
245 .arg(query->getLabel())
248 query->addClass(
"UNKNOWN");
250 .arg(query->getLabel())
259 .arg(query_->getLabel())
263 if (query_->inClass(
"DROP")) {
265 .arg(query_->getHWAddrLabel())
266 .arg(query_->toText());
268 static_cast<int64_t
>(1));
275 uint8_t resp_type = 0;
289 resp_.reset(
new Pkt4(resp_type,
getQuery()->getTransid()));
291 copyDefaultOptions();
305 const Pkt6Ptr& query6 = query->getPkt6();
309 if (!query6->relay_info_.empty()) {
310 resp6->copyRelayInfo(query6);
313 resp6->setIface(query6->getIface());
314 resp6->setIndex(query6->getIndex());
315 resp6->setRemoteAddr(query6->getRemoteAddr());
316 resp6->setRemotePort(query6->getRemotePort());
317 resp_.reset(
new Pkt4o6(resp_, resp6));
321 Dhcpv4Exchange::copyDefaultFields() {
322 resp_->setIface(query_->getIface());
323 resp_->setIndex(query_->getIndex());
330 resp_->setCiaddr(query_->getCiaddr());
334 resp_->setHops(query_->getHops());
337 resp_->setHWAddr(query_->getHWAddr());
340 resp_->setGiaddr(query_->getGiaddr());
349 HWAddrPtr src_hw_addr = query_->getLocalHWAddr();
351 resp_->setLocalHWAddr(src_hw_addr);
353 HWAddrPtr dst_hw_addr = query_->getRemoteHWAddr();
355 resp_->setRemoteHWAddr(dst_hw_addr);
359 resp_->setFlags(query_->getFlags());
363 Dhcpv4Exchange::copyDefaultOptions() {
368 if (client_id && echo) {
369 resp_->addOption(client_id);
376 resp_->addOption(rai);
389 resp_->addOption(subnet_sel);
401 cfg->getIdentifierTypes()) {
404 if (context->hwaddr_ && !context->hwaddr_->hwaddr_.empty()) {
405 context->addHostIdentifier(id_type, context->hwaddr_->hwaddr_);
410 if (context->clientid_) {
411 const std::vector<uint8_t>& vec = context->clientid_->getClientId();
416 if ((vec[0] == CLIENT_ID_OPTION_TYPE_DUID) && (vec.size() > 5)) {
418 context->addHostIdentifier(id_type,
419 std::vector<uint8_t>(vec.begin() + 5,
431 if (circuit_id_opt) {
432 const OptionBuffer& circuit_id_vec = circuit_id_opt->getData();
433 if (!circuit_id_vec.empty()) {
434 context->addHostIdentifier(id_type, circuit_id_vec);
442 if (context->clientid_) {
443 const std::vector<uint8_t>& vec = context->clientid_->getClientId();
445 context->addHostIdentifier(id_type, vec);
451 if (!HooksManager::calloutsPresent(
Hooks.hook_index_host4_identifier_)) {
458 std::vector<uint8_t> id;
467 callout_handle->setArgument(
"query4", context->query_);
468 callout_handle->setArgument(
"id_type", type);
469 callout_handle->setArgument(
"id_value",
id);
472 HooksManager::callCallouts(
Hooks.hook_index_host4_identifier_,
475 callout_handle->getArgument(
"id_type", type);
476 callout_handle->getArgument(
"id_value",
id);
478 if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_CONTINUE) &&
484 context->addHostIdentifier(type,
id);
499 for (
auto def : *defs_ptr) {
503 if (def->getMatchExpr()) {
504 query->classes_.erase(def->getName());
511 if (context->currentHost() && context->query_) {
512 const ClientClasses& classes = context->currentHost()->getClientClasses4();
514 cclass != classes.
cend(); ++cclass) {
515 context->query_->addClass(*cclass);
522 if (context_->subnet_) {
524 context_->subnet_->getSharedNetwork(shared_network);
525 if (shared_network) {
527 if (host && (host->getIPv4SubnetID() != SUBNET_ID_GLOBAL)) {
539 if (!host->getNextServer().isV4Zero()) {
540 resp_->setSiaddr(host->getNextServer());
543 std::string sname = host->getServerHostname();
544 if (!sname.empty()) {
545 resp_->setSname(
reinterpret_cast<const uint8_t*
>(sname.c_str()),
549 std::string bootfile = host->getBootFileName();
550 if (!bootfile.empty()) {
551 resp_->setFile(
reinterpret_cast<const uint8_t*
>(bootfile.c_str()),
559 boost::shared_ptr<OptionString> vendor_class =
571 pkt->addClass(
"ALL");
585 for (ClientClassDefList::const_iterator it = defs_ptr->cbegin();
586 it != defs_ptr->cend(); ++it) {
594 if ((*it)->getRequired()) {
598 if ((*it)->getDependOnKnown() != depend_on_known) {
601 (*it)->test(pkt, expr_ptr);
608 const bool use_bcast,
const bool direct_response_desired)
609 : io_service_(new
IOService()), server_port_(server_port),
610 client_port_(client_port), shutdown_(true),
611 alloc_engine_(), use_bcast_(use_bcast),
614 test_send_responses_to_source_(false) {
616 const char* env = std::getenv(
"KEA_TEST_SEND_RESPONSES_TO_SOURCE");
619 test_send_responses_to_source_ =
true;
647 }
catch (
const std::exception &e) {
662 for (
auto it = dhcp4_statistics.begin(); it != dhcp4_statistics.end(); ++it) {
664 stats_mgr.
setValue((*it),
static_cast<int64_t
>(0));
674 }
catch (
const std::exception& ex) {
681 }
catch (
const std::exception& ex) {
693 HooksManager::prepareUnloadLibraries();
694 if (!HooksManager::unloadLibraries()) {
695 auto names = HooksManager::getLibraryNames();
697 if (!names.empty()) {
699 for (
size_t i = 1; i < names.size(); ++i) {
700 msg += std::string(
", ") + names[i];
715 bool sanity_only)
const {
718 if (query->isDhcp4o6()) {
727 subnet = cfgmgr.
getCurrentCfg()->getCfgSubnets4()->selectSubnet(selector);
732 HooksManager::calloutsPresent(
Hooks.hook_index_subnet4_select_)) {
745 callout_handle->setArgument(
"query4", query);
746 callout_handle->setArgument(
"subnet4", subnet);
747 callout_handle->setArgument(
"subnet4collection",
749 getCfgSubnets4()->getAll());
752 HooksManager::callCallouts(
Hooks.hook_index_subnet4_select_,
758 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
761 .arg(query->getLabel());
767 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
770 .arg(query->getLabel());
776 callout_handle->getArgument(
"subnet4", subnet);
782 .arg(query->getLabel())
783 .arg(subnet->getID());
787 .arg(query->getLabel())
788 .arg(subnet->toText());
793 .arg(query->getLabel());
801 bool sanity_only)
const {
805 selector.
ciaddr_ = query->getCiaddr();
806 selector.
giaddr_ = query->getGiaddr();
817 Pkt4o6Ptr query4o6 = boost::dynamic_pointer_cast<Pkt4o6>(query);
821 const Pkt6Ptr& query6 = query4o6->getPkt6();
824 if (query6 && !query6->relay_info_.empty()) {
840 OptionCustomPtr oc = boost::dynamic_pointer_cast<OptionCustom>(sbnsel);
847 subnet = cfgmgr.
getCurrentCfg()->getCfgSubnets4()->selectSubnet4o6(selector);
852 HooksManager::calloutsPresent(
Hooks.hook_index_subnet4_select_)) {
862 callout_handle->setArgument(
"query4", query);
863 callout_handle->setArgument(
"subnet4", subnet);
864 callout_handle->setArgument(
"subnet4collection",
866 getCfgSubnets4()->getAll());
869 HooksManager::callCallouts(
Hooks.hook_index_subnet4_select_,
875 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
878 .arg(query->getLabel());
884 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
887 .arg(query->getLabel());
893 callout_handle->getArgument(
"subnet4", subnet);
900 .arg(query->getLabel())
901 .arg(subnet->getID());
906 .arg(query->getLabel())
907 .arg(subnet->toText());
912 .arg(query->getLabel());
935 ctx->hwaddr_ = query->getHWAddr();
941 ctx->early_global_reservations_lookup_ = egrl->boolValue();
945 if (ctx->early_global_reservations_lookup_) {
949 ctx->clientid_.reset(
new ClientId(opt_clientid->getData()));
958 if (global_host && !global_host->getClientClasses4().empty()) {
963 const ClientClasses& classes = global_host->getClientClasses4();
965 cclass != classes.
cend(); ++cclass) {
966 query->addClass(*cclass);
975 query->addClass(
"KNOWN");
977 .arg(query->getLabel())
984 if (query->inClass(
"DROP")) {
987 .arg(query->getHWAddrLabel())
988 .arg(query->toText());
990 static_cast<int64_t
>(1));
995 ctx->hosts_[SUBNET_ID_GLOBAL] = global_host;
1010 while (__AFL_LOOP(fuzzer.maxLoopCount())) {
1020 }
catch (
const std::exception& e) {
1037 MultiThreadingMgr::instance().apply(
false, 0, 0);
1051 uint32_t timeout = 1;
1062 .arg(query->getRemoteAddr().toText())
1063 .arg(query->getRemotePort())
1064 .arg(query->getLocalAddr().toText())
1065 .arg(query->getLocalPort())
1066 .arg(query->getIface());
1082 }
catch (
const std::exception& e) {
1097 .arg(query->getLabel());
1100 if (MultiThreadingMgr::instance().getMode()) {
1101 typedef function<void()> CallBack;
1102 boost::shared_ptr<CallBack> call_back =
1105 if (!MultiThreadingMgr::instance().getThreadPool().add(call_back)) {
1118 }
catch (
const std::exception& e) {
1141 query->addClass(
"ALL");
1148 static_cast<int64_t
>(1));
1150 bool skip_unpack =
false;
1154 if (HooksManager::calloutsPresent(
Hooks.hook_index_buffer4_receive_)) {
1167 callout_handle->setArgument(
"query4", query);
1170 HooksManager::callCallouts(
Hooks.hook_index_buffer4_receive_,
1176 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
1179 .arg(query->getRemoteAddr().toText())
1180 .arg(query->getLocalAddr().toText())
1181 .arg(query->getIface());
1189 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
1192 .arg(query->getRemoteAddr().toText())
1193 .arg(query->getLocalAddr().toText())
1194 .arg(query->getIface());
1198 callout_handle->getArgument(
"query4", query);
1206 .arg(query->getRemoteAddr().toText())
1207 .arg(query->getLocalAddr().toText())
1208 .arg(query->getIface());
1216 }
catch (
const std::exception& e) {
1219 .arg(query->getRemoteAddr().toText())
1220 .arg(query->getLocalAddr().toText())
1221 .arg(query->getIface())
1223 .arg(query->getHWAddrLabel());
1227 static_cast<int64_t
>(1));
1229 static_cast<int64_t
>(1));
1236 .arg(query->getLabel());
1254 static_cast<int64_t
>(1));
1260 int type = query->getType();
1262 .arg(query->getLabel())
1263 .arg(query->getName())
1265 .arg(query->getRemoteAddr())
1266 .arg(query->getLocalAddr())
1267 .arg(query->getIface());
1269 .arg(query->getLabel())
1270 .arg(query->toText());
1273 if (HooksManager::calloutsPresent(
Hooks.hook_index_pkt4_receive_)) {
1286 callout_handle->setArgument(
"query4", query);
1289 HooksManager::callCallouts(
Hooks.hook_index_pkt4_receive_,
1295 if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) ||
1296 (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP)) {
1299 .arg(query->getLabel());
1303 callout_handle->getArgument(
"query4", query);
1307 if (query->inClass(
"DROP")) {
1309 .arg(query->getHWAddrLabel())
1310 .arg(query->toText());
1312 static_cast<int64_t
>(1));
1321 bool allow_packet_park) {
1330 }
catch (
const std::exception& e) {
1340 bool allow_packet_park) {
1345 if (MultiThreadingMgr::instance().getMode() &&
1352 this, query, rsp, allow_packet_park));
1353 if (!client_handler.
tryLock(query, cont)) {
1364 switch (query->getType()) {
1394 }
catch (
const std::exception& e) {
1404 .arg(query->getLabel())
1409 static_cast<int64_t
>(1));
1416 int hook_idx =
Hooks.hook_index_leases4_committed_;
1417 std::string hook_label =
"leases4_committed";
1421 if (ctx->fake_allocation_) {
1422 hook_idx =
Hooks.hook_index_lease4_offer_;
1423 hook_label =
"lease4_offer";
1429 if (HooksManager::calloutsPresent(hook_idx)) {
1453 std::shared_ptr<ScopedCalloutHandleState> callout_handle_state =
1454 std::make_shared<ScopedCalloutHandleState>(callout_handle);
1459 callout_handle->setArgument(
"query4", query);
1463 if (ctx->new_lease_ && (ctx->new_lease_->reuseable_valid_lft_ == 0)) {
1464 new_leases->push_back(ctx->new_lease_);
1466 callout_handle->setArgument(
"leases4", new_leases);
1468 if (ctx->fake_allocation_) {
1470 callout_handle->setArgument(
"offer_lifetime", ctx->offer_lft_);
1471 callout_handle->setArgument(
"old_lease", ctx->old_lease_);
1475 if (ctx->old_lease_) {
1476 if ((!ctx->new_lease_) || (ctx->new_lease_->addr_ != ctx->old_lease_->addr_)) {
1477 deleted_leases->push_back(ctx->old_lease_);
1480 callout_handle->setArgument(
"deleted_leases4", deleted_leases);
1483 if (allow_packet_park) {
1485 uint32_t parked_packet_limit = 0;
1489 parked_packet_limit = ppl->intValue();
1492 if (parked_packet_limit) {
1493 const auto& parking_lot =
1494 ServerHooks::getServerHooks().getParkingLotPtr(hook_label);
1496 if (parking_lot && (parking_lot->size() >= parked_packet_limit)) {
1499 .arg(parked_packet_limit)
1500 .arg(query->getLabel());
1502 static_cast<int64_t
>(1));
1514 [
this, callout_handle, query, rsp, callout_handle_state]()
mutable {
1515 if (MultiThreadingMgr::instance().getMode()) {
1516 typedef function<void()> CallBack;
1517 boost::shared_ptr<CallBack> call_back = boost::make_shared<CallBack>(
1520 callout_handle_state->on_completion_ = [call_back]() {
1521 MultiThreadingMgr::instance().getThreadPool().add(call_back);
1532 HooksManager::callCallouts(hook_idx, *callout_handle);
1535 if (allow_packet_park) {
1536 HooksManager::drop(hook_label, query);
1542 if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_PARK) &&
1543 allow_packet_park) {
1545 .arg(query->getLabel());
1553 HooksManager::drop(hook_label, query);
1554 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
1556 .arg(query->getLabel());
1575 }
catch (
const std::exception& e) {
1591 bool skip_pack =
false;
1594 if (HooksManager::calloutsPresent(
Hooks.hook_index_pkt4_send_)) {
1607 callout_handle->setArgument(
"query4", query);
1610 callout_handle->setArgument(
"response4", rsp);
1613 HooksManager::callCallouts(
Hooks.hook_index_pkt4_send_,
1621 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
1623 .arg(query->getLabel());
1628 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
1630 .arg(rsp->getLabel());
1639 .arg(rsp->getLabel());
1641 }
catch (
const std::exception& e) {
1643 .arg(rsp->getLabel())
1661 if (HooksManager::calloutsPresent(
Hooks.hook_index_buffer4_send_)) {
1673 callout_handle->setArgument(
"response4", rsp);
1676 HooksManager::callCallouts(
Hooks.hook_index_buffer4_send_,
1682 if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) ||
1683 (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP)) {
1686 .arg(rsp->getLabel());
1690 callout_handle->getArgument(
"response4", rsp);
1694 .arg(rsp->getLabel())
1695 .arg(rsp->getName())
1696 .arg(
static_cast<int>(rsp->getType()))
1697 .arg(rsp->getLocalAddr().isV4Zero() ?
"*" : rsp->getLocalAddr().toText())
1698 .arg(rsp->getLocalPort())
1699 .arg(rsp->getRemoteAddr())
1700 .arg(rsp->getRemotePort())
1701 .arg(rsp->getIface().empty() ?
"to be determined from routing" :
1706 .arg(rsp->getLabel())
1707 .arg(rsp->getName())
1708 .arg(
static_cast<int>(rsp->getType()))
1709 .arg(rsp->toText());
1715 }
catch (
const std::exception& e) {
1717 .arg(rsp->getLabel())
1727 boost::shared_ptr<Option4AddrLst> generated =
1728 boost::dynamic_pointer_cast<Option4AddrLst>(srvid);
1734 if (addrs.size() != 1) {
1736 <<
"Expected to contain a single IPv4 address.");
1739 return (addrs[0].toText());
1757 if (local_addr.
isV4Bcast() || query->isDhcp4o6()) {
1780 if (host && !host->getCfgOption4()->empty()) {
1781 co_list.push_back(host->getCfgOption4());
1788 addr = resp->getYiaddr();
1792 if (pool && !pool->getCfgOption()->empty()) {
1793 co_list.push_back(pool->getCfgOption());
1798 if (!subnet->getCfgOption()->empty()) {
1799 co_list.push_back(subnet->getCfgOption());
1804 subnet->getSharedNetwork(network);
1805 if (network && !network->getCfgOption()->empty()) {
1806 co_list.push_back(network->getCfgOption());
1812 cclass != classes.
cend(); ++cclass) {
1815 getClientClassDictionary()->findClass(*cclass);
1827 if (ccdef->getCfgOption()->empty()) {
1832 co_list.push_back(ccdef->getCfgOption());
1856 if (co_list.empty()) {
1862 set<uint8_t> requested_opts;
1871 for (uint16_t code : option_prl->getValues()) {
1872 static_cast<void>(requested_opts.insert(code));
1876 std::set<uint8_t> cancelled_opts;
1880 for (
auto const& copts : co_list) {
1888 for (OptionContainerPersistIndex::const_iterator desc = prange.first;
1889 desc != prange.second; ++desc) {
1891 if (desc->option_) {
1892 uint8_t code =
static_cast<uint8_t
>(desc->option_->getType());
1893 static_cast<void>(requested_opts.insert(code));
1899 for (OptionContainerCancelIndex::const_iterator desc = crange.first;
1900 desc != crange.second; ++desc) {
1902 if (desc->option_) {
1903 uint8_t code =
static_cast<uint8_t
>(desc->option_->getType());
1904 static_cast<void>(cancelled_opts.insert(code));
1911 for (uint8_t opt : requested_opts) {
1912 if (cancelled_opts.count(opt) > 0) {
1920 if (!resp->getOption(opt)) {
1922 for (
auto const& copts : co_list) {
1926 resp->addOption(desc.
option_);
1939 set<uint32_t> vendor_ids;
1943 vendor_opts = boost::dynamic_pointer_cast<OptionVendorClass>(opt.second);
1945 uint32_t vendor_id = vendor_opts->getVendorId();
1946 static_cast<void>(vendor_ids.insert(vendor_id));
1950 for (
auto const& copts : co_list) {
1953 if (!desc.option_) {
1957 boost::dynamic_pointer_cast<OptionVendorClass>(desc.option_);
1962 uint32_t vendor_id = vendor_opts->getVendorId();
1963 if (vendor_ids.count(vendor_id) > 0) {
1967 resp->Pkt::addOption(desc.option_);
1968 static_cast<void>(vendor_ids.insert(vendor_id));
1977 set<uint32_t> vendor_ids;
1981 vendor_opts = boost::dynamic_pointer_cast<OptionVendor>(opt.second);
1983 uint32_t vendor_id = vendor_opts->getVendorId();
1984 static_cast<void>(vendor_ids.insert(vendor_id));
1988 for (
auto const& copts : co_list) {
1991 if (!desc.option_) {
1995 boost::dynamic_pointer_cast<OptionVendor>(desc.option_);
2000 uint32_t vendor_id = vendor_opts->getVendorId();
2001 if (vendor_ids.count(vendor_id) > 0) {
2007 resp->Pkt::addOption(vendor_opts);
2008 static_cast<void>(vendor_ids.insert(vendor_id));
2028 if (!subnet || co_list.empty()) {
2034 set<uint32_t> vendor_ids;
2038 map<uint32_t, OptionVendorPtr> vendor_rsps;
2041 vendor_rsp = boost::dynamic_pointer_cast<OptionVendor>(opt.second);
2043 uint32_t vendor_id = vendor_rsp->getVendorId();
2044 vendor_rsps[vendor_id] = vendor_rsp;
2045 static_cast<void>(vendor_ids.insert(vendor_id));
2051 map<uint32_t, OptionVendorPtr> vendor_reqs;
2054 vendor_req = boost::dynamic_pointer_cast<OptionVendor>(opt.second);
2056 uint32_t vendor_id = vendor_req->getVendorId();
2057 vendor_reqs[vendor_id] = vendor_req;
2058 static_cast<void>(vendor_ids.insert(vendor_id));
2066 vendor_class = boost::dynamic_pointer_cast<OptionVendorClass>(opt.second);
2068 uint32_t vendor_id = vendor_class->getVendorId();
2069 static_cast<void>(vendor_ids.insert(vendor_id));
2075 if (vendor_ids.empty()) {
2079 map<uint32_t, set<uint8_t> > requested_opts;
2093 oro = boost::dynamic_pointer_cast<OptionUint8Array>(oro_generic);
2096 set<uint8_t> oro_req_opts;
2097 for (uint8_t code : oro->getValues()) {
2098 static_cast<void>(oro_req_opts.insert(code));
2104 for (uint32_t vendor_id : vendor_ids) {
2106 std::set<uint8_t> cancelled_opts;
2110 for (
auto const& copts : co_list) {
2119 for (OptionContainerPersistIndex::const_iterator desc = prange.first;
2120 desc != prange.second; ++desc) {
2122 if (desc->option_) {
2123 uint8_t code =
static_cast<uint8_t
>(desc->option_->getType());
2124 static_cast<void>(requested_opts[vendor_id].insert(code));
2131 for (OptionContainerCancelIndex::const_iterator desc = crange.first;
2132 desc != crange.second; ++desc) {
2134 if (desc->option_) {
2135 uint8_t code =
static_cast<uint8_t
>(desc->option_->getType());
2136 static_cast<void>(cancelled_opts.insert(code));
2146 if (requested_opts[vendor_id].empty()) {
2154 if (vendor_rsps.count(vendor_id) > 0) {
2155 vendor_rsp = vendor_rsps[vendor_id];
2163 for (uint8_t opt : requested_opts[vendor_id]) {
2164 if (cancelled_opts.count(opt) > 0) {
2167 if (!vendor_rsp->getOption(opt)) {
2168 for (
auto const& copts : co_list) {
2171 vendor_rsp->addOption(desc.
option_);
2181 if (added && (vendor_rsps.count(vendor_id) == 0)) {
2182 resp->Pkt::addOption(vendor_rsp);
2191 static const std::vector<uint16_t> required_options = {
2205 if (co_list.empty()) {
2213 for (
auto const& required : required_options) {
2214 OptionPtr opt = resp->getOption(required);
2217 for (
auto const& copts : co_list) {
2220 resp->addOption(desc.
option_);
2240 .arg(query->getLabel());
2241 processClientFqdnOption(ex);
2246 .arg(query->getLabel());
2247 processHostnameOption(ex);
2253 std::string hostname;
2254 bool fqdn_fwd =
false;
2255 bool fqdn_rev =
false;
2259 fqdn = boost::dynamic_pointer_cast<Option4ClientFqdn>(resp->getOption(
DHO_FQDN));
2261 hostname = fqdn->getDomainName();
2264 opt_hostname = boost::dynamic_pointer_cast<OptionString>
2268 hostname = opt_hostname->getValue();
2273 if (hostname ==
".") {
2279 if (ex.
getContext()->getDdnsParams()->getEnableUpdates()) {
2288 if (HooksManager::calloutsPresent(
Hooks.hook_index_ddns4_update_)) {
2299 callout_handle->setArgument(
"query4", query);
2300 callout_handle->setArgument(
"response4", resp);
2301 callout_handle->setArgument(
"subnet4", subnet);
2302 callout_handle->setArgument(
"hostname", hostname);
2303 callout_handle->setArgument(
"fwd-update", fqdn_fwd);
2304 callout_handle->setArgument(
"rev-update", fqdn_rev);
2305 callout_handle->setArgument(
"ddns-params", ex.
getContext()->getDdnsParams());
2308 HooksManager::callCallouts(
Hooks.hook_index_ddns4_update_, *callout_handle);
2311 string hook_hostname;
2312 bool hook_fqdn_fwd =
false;
2313 bool hook_fqdn_rev =
false;
2314 callout_handle->getArgument(
"hostname", hook_hostname);
2315 callout_handle->getArgument(
"fwd-update", hook_fqdn_fwd);
2316 callout_handle->getArgument(
"rev-update", hook_fqdn_rev);
2320 if ((hostname != hook_hostname) || (fqdn_fwd != hook_fqdn_fwd) ||
2321 (fqdn_rev != hook_fqdn_rev)) {
2323 .arg(hostname).arg(hook_hostname).arg(fqdn_fwd).arg(hook_fqdn_fwd)
2324 .arg(fqdn_rev).arg(hook_fqdn_rev);
2325 hostname = hook_hostname;
2326 fqdn_fwd = hook_fqdn_fwd;
2327 fqdn_rev = hook_fqdn_rev;
2331 OptionStringPtr hostname_opt = boost::dynamic_pointer_cast<OptionString>
2334 hostname_opt->setValue(hook_hostname);
2352 ctx->fwd_dns_update_ = fqdn_fwd;
2353 ctx->rev_dns_update_ = fqdn_rev;
2354 ctx->hostname_ = hostname;
2379 .arg(fqdn->toText());
2395 !ex.
getContext()->currentHost()->getHostname().empty()) {
2422 .arg(fqdn_resp->
toText());
2432 OptionStringPtr opt_hostname = boost::dynamic_pointer_cast<OptionString>
2438 .arg(opt_hostname->getValue());
2446 if (ctx->currentHost() && !ctx->currentHost()->getHostname().empty()) {
2448 std::string hostname = d2_mgr.
qualifyName(ctx->currentHost()->getHostname(),
2451 boost::algorithm::to_lower(hostname);
2469 ex.
getContext()->getDdnsParams()->getReplaceClientNameMode();
2472 if (!opt_hostname) {
2492 .arg(opt_hostname->getValue());
2495 unsigned int label_count;
2501 }
catch (
const std::exception& exc) {
2512 if (label_count == 0) {
2530 || label_count < 2) {
2544 ex.
getContext()->getDdnsParams()->getHostnameSanitizer();
2547 hostname = sanitizer->scrub(hostname);
2551 boost::algorithm::to_lower(hostname);
2553 if (label_count == 2) {
2561 opt_hostname_resp.reset(
2572 .arg(opt_hostname_resp->getValue());
2582 "NULL lease specified when creating NameChangeRequest");
2590 if (!old_lease || ddns_params.
getUpdateOnRenew() || !lease->hasIdenticalFqdn(*old_lease)) {
2622 if (opt_requested_address) {
2623 hint = opt_requested_address->readAddress();
2625 }
else if (!query->getCiaddr().isV4Zero()) {
2626 hint = query->getCiaddr();
2636 bool fake_allocation = (query->getType() ==
DHCPDISCOVER);
2644 auto authoritative =
false;
2650 auto init_reboot = (!fake_allocation && !opt_serverid && opt_requested_address);
2653 .arg(query->getLabel())
2654 .arg(hint.toText());
2658 authoritative = subnet->getAuthoritative();
2664 authoritative = flag->boolValue();
2673 if (!subnet && (!init_reboot || authoritative)) {
2680 .arg(query->getLabel())
2681 .arg(query->getRemoteAddr().toText())
2682 .arg(query->getName());
2700 auto const& classes = query->getClasses();
2710 if (original_subnet && client_id) {
2714 if (!leases_client_id.empty()) {
2720 for (
auto l = leases_client_id.begin(); l != leases_client_id.end(); ++l) {
2721 if ((*l)->subnet_id_ == s->getID()) {
2731 s = s->getNextSubnet(original_subnet, classes);
2739 if (original_subnet && !lease && hwaddr) {
2743 if (!leases_hwaddr.empty()) {
2748 for (
auto l = leases_hwaddr.begin(); l != leases_hwaddr.end(); ++l) {
2749 if ((*l)->subnet_id_ == s->getID()) {
2759 s = s->getNextSubnet(original_subnet, classes);
2768 bool known_client = lease && lease->belongsToClient(hwaddr, client_id);
2769 if (!authoritative && !known_client) {
2772 .arg(query->getLabel())
2773 .arg(hint.toText());
2781 if ((known_client && (lease->addr_ != hint)) ||
2782 (!known_client && authoritative) ||
2783 (!original_subnet)) {
2786 .arg(query->getLabel())
2787 .arg(hint.toText());
2798 ctx->requested_address_ = hint;
2799 ctx->fake_allocation_ = fake_allocation;
2800 ctx->callout_handle_ = callout_handle;
2816 bool client_name_changed =
false;
2820 if (subnet && ctx->subnet_ && subnet->getID() != ctx->subnet_->getID()) {
2822 subnet->getSharedNetwork(network);
2824 .arg(query->getLabel())
2825 .arg(subnet->toText())
2826 .arg(ctx->subnet_->toText())
2827 .arg(network ? network->getName() :
"<no network?>");
2829 subnet = ctx->subnet_;
2844 ctx->hostname_ =
"";
2845 ctx->fwd_dns_update_ =
false;
2846 ctx->rev_dns_update_ =
false;
2853 if ((lease->hostname_ != ctx->hostname_) ||
2854 (lease->fqdn_fwd_ != ctx->fwd_dns_update_) ||
2855 (lease->fqdn_rev_ != ctx->rev_dns_update_)) {
2856 lease->hostname_ = ctx->hostname_;
2857 lease->fqdn_fwd_ = ctx->fwd_dns_update_;
2858 lease->fqdn_rev_ = ctx->rev_dns_update_;
2859 client_name_changed =
true;
2867 if (fake_allocation) {
2869 .arg(query->getLabel())
2870 .arg(lease->addr_.toText());
2873 .arg(query->getLabel())
2874 .arg(lease->addr_.toText())
2882 if (!ctx->subnet_->getMatchClientId()) {
2884 .arg(ctx->query_->getLabel())
2885 .arg(ctx->subnet_->getID());
2888 resp->setYiaddr(lease->addr_);
2894 if (!fake_allocation) {
2899 resp->setCiaddr(query->getCiaddr());
2908 if (lease->reuseable_valid_lft_ > 0) {
2909 lease->valid_lft_ = lease->reuseable_valid_lft_;
2911 .arg(query->getLabel())
2912 .arg(lease->addr_.toText())
2916 StatsMgr::instance().addValue(
"v4-lease-reuses", int64_t(1));
2917 StatsMgr::instance().addValue(StatsMgr::generateName(
"subnet", lease->subnet_id_,
2929 resp->addOption(opt);
2932 resp->addOption(getNetmaskOption(subnet));
2938 if (!fake_allocation) {
2944 .arg(query->getLabel())
2952 if (ctx->unknown_requested_addr_) {
2964 s = s->getNextSubnet(original_subnet);
2972 .arg(query->getLabel())
2973 .arg(query->getCiaddr().toText())
2974 .arg(opt_requested_address ?
2975 opt_requested_address->readAddress().toText() :
"(no address)");
2983 .arg(query->getLabel())
2984 .arg(query->getCiaddr().toText())
2985 .arg(opt_requested_address ?
2986 opt_requested_address->readAddress().toText() :
"(no address)");
2998 const Pkt4Ptr& query,
const Pkt4Ptr& resp,
bool client_name_changed) {
3007 opt_hostname = boost::dynamic_pointer_cast<OptionString>(resp->getOption(
DHO_HOST_NAME));
3008 if (!opt_hostname) {
3015 if (lease->hostname_.empty()) {
3022 .
generateFqdn(lease->addr_, *(ctx->getDdnsParams()),
static_cast<bool>(fqdn));
3025 .arg(query->getLabel())
3026 .arg(lease->hostname_);
3028 client_name_changed =
true;
3031 if (client_name_changed) {
3037 if (!ctx->fake_allocation_ || (ctx->offer_lft_ > 0)) {
3039 lease->reuseable_valid_lft_ = 0;
3052 opt_hostname->setValue(lease->hostname_);
3056 .arg(query->getLabel())
3057 .arg(lease->hostname_)
3067 uint32_t t2_time = 0;
3069 if (!subnet->getT2().unspecified()) {
3070 t2_time = subnet->getT2();
3071 }
else if (subnet->getCalculateTeeTimes()) {
3073 t2_time =
static_cast<uint32_t
>(round(subnet->getT2Percent() * (lease->valid_lft_)));
3078 uint32_t timer_ceiling = lease->valid_lft_;
3079 if (t2_time > 0 && t2_time < timer_ceiling) {
3081 resp->addOption(t2);
3083 timer_ceiling = t2_time;
3086 uint32_t t1_time = 0;
3088 if (!subnet->getT1().unspecified()) {
3089 t1_time = subnet->getT1();
3090 }
else if (subnet->getCalculateTeeTimes()) {
3092 t1_time =
static_cast<uint32_t
>(round(subnet->getT1Percent() * (lease->valid_lft_)));
3097 if (t1_time > 0 && t1_time < timer_ceiling) {
3099 resp->addOption(t1);
3111 return (query->getRemotePort());
3139 }
else if (((query->getType() ==
DHCPINFORM) &&
3140 ((!query->getCiaddr().isV4Zero()) ||
3141 (!query->isRelayed() && !query->getRemoteAddr().isV4Zero()))) ||
3142 ((query->getType() !=
DHCPINFORM) && !query->isRelayed())) {
3143 response->setRemotePort(DHCP4_CLIENT_PORT);
3148 response->setRemotePort(relay_port ? relay_port : DHCP4_SERVER_PORT);
3152 if (query->isRelayed() &&
3158 response->resetIndex();
3160 response->setIface(query->getIface());
3164 IOAddress local_addr = query->getLocalAddr();
3173 if (local_addr.
isV4Bcast() || query->isDhcp4o6()) {
3184 response->setLocalAddr(local_addr);
3193 response->setIndex(query->getIndex());
3194 response->setIface(query->getIface());
3200 response->setLocalPort(DHCP4_SERVER_PORT);
3212 if (query->isDhcp4o6()) {
3213 response->setRemoteAddr(query->getRemoteAddr());
3225 if (!query->getCiaddr().isV4Zero()) {
3226 response->setRemoteAddr(query->getCiaddr());
3233 }
else if (query->isRelayed()) {
3234 response->setRemoteAddr(query->getGiaddr());
3235 response->setFlags(response->getFlags() | BOOTP_BROADCAST);
3240 response->setRemoteAddr(query->getRemoteAddr());
3247 if (query->isRelayed()) {
3256 query->getCiaddr().isV4Zero()) {
3257 response->setFlags(BOOTP_BROADCAST);
3259 response->setRemoteAddr(query->getGiaddr());
3263 }
else if (!query->getCiaddr().isV4Zero()) {
3264 response->setRemoteAddr(query->getCiaddr());
3269 }
else if (response->getType() ==
DHCPNAK) {
3273 }
else if (!response->getYiaddr().isV4Zero()) {
3288 response->setRemoteAddr(response ->getYiaddr());
3296 response->setRemoteAddr(query->getRemoteAddr());
3301 response->setRemoteAddr(query->getRemoteAddr());
3313 IOAddress subnet_next_server = subnet->getSiaddr();
3314 if (!subnet_next_server.
isV4Zero()) {
3315 response->setSiaddr(subnet_next_server);
3318 const string& sname = subnet->getSname();
3319 if (!sname.empty()) {
3325 response->setSname(
reinterpret_cast<const uint8_t*
>(sname.c_str()),
3329 const string& filename = subnet->getFilename();
3330 if (!filename.empty()) {
3336 response->setFile(
reinterpret_cast<const uint8_t*
>(filename.c_str()),
3344 if (!classes.
empty()) {
3357 size_t found_cnt = 0;
3359 name != classes.
cend() && found_cnt < 3; ++name) {
3371 next_server = cl->getNextServer();
3373 response->setSiaddr(next_server);
3378 if (sname.empty()) {
3379 sname = cl->getSname();
3380 if (!sname.empty()) {
3386 response->setSname(
reinterpret_cast<const uint8_t*
>(sname.c_str()),
3392 if (filename.empty()) {
3393 filename = cl->getFilename();
3394 if (!filename.empty()) {
3400 response->setFile(
reinterpret_cast<const uint8_t*
>(filename.c_str()),
3414 Dhcpv4Srv::getNetmaskOption(
const Subnet4Ptr& subnet) {
3443 if (MultiThreadingMgr::instance().getMode()) {
3467 .arg(discover->getLabel())
3468 .arg(discover->getName())
3469 .arg(discover->getClasses().toText());
3526 if (MultiThreadingMgr::instance().getMode()) {
3539 }
else if (request->inClass(
"BOOTP")) {
3541 response->addClass(
"BOOTP");
3545 if (!response->getYiaddr().isV4Zero()) {
3554 .arg(request->getLabel())
3555 .arg(request->getName())
3556 .arg(request->getClasses().toText());
3613 .arg(release->getLabel())
3614 .arg(release->getCiaddr().toText());
3618 if (!lease->belongsToClient(release->getHWAddr(), client_id)) {
3620 .arg(release->getLabel())
3621 .arg(release->getCiaddr().toText());
3628 if (HooksManager::calloutsPresent(
Hooks.hook_index_lease4_release_)) {
3641 callout_handle->setArgument(
"query4", release);
3644 callout_handle->setArgument(
"lease4", lease);
3647 HooksManager::callCallouts(
Hooks.hook_index_lease4_release_,
3653 if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) ||
3654 (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP)) {
3658 .arg(release->getLabel());
3666 bool success =
false;
3667 bool expired =
false;
3671 if (expiration_cfg->getFlushReclaimedTimerWaitTime() &&
3672 expiration_cfg->getHoldReclaimedTime() &&
3675 lease->valid_lft_ = 0;
3685 context->old_lease_ = lease;
3689 .arg(release->getLabel())
3690 .arg(lease->addr_.toText());
3694 .arg(release->getLabel())
3695 .arg(lease->addr_.toText());
3698 .arg(release->getLabel())
3699 .arg(lease->addr_.toText());
3702 StatsMgr::instance().addValue(
3703 StatsMgr::generateName(
"subnet", lease->subnet_id_,
"assigned-addresses"),
3704 static_cast<int64_t
>(-1));
3708 const auto& pool = subnet->getPool(
Lease::TYPE_V4, lease->addr_,
false);
3710 StatsMgr::instance().addValue(
3711 StatsMgr::generateName(
"subnet", subnet->getID(),
3712 StatsMgr::generateName(
"pool", pool->getID(),
"assigned-addresses")),
3713 static_cast<int64_t
>(-1));
3723 .arg(release->getLabel())
3724 .arg(lease->addr_.toText());
3729 .arg(release->getLabel())
3730 .arg(release->getCiaddr())
3747 if (!opt_requested_address) {
3750 " in DHCPDECLINE sent from " << decline->getLabel());
3752 IOAddress addr(opt_requested_address->readAddress());
3770 .arg(addr.
toText()).arg(decline->getLabel());
3778 client_id.reset(
new ClientId(opt_clientid->getData()));
3782 if (!lease->belongsToClient(decline->getHWAddr(), client_id)) {
3785 string client_hw = decline->getHWAddr() ?
3786 decline->getHWAddr()->toText(
false) :
"(none)";
3787 string lease_hw = lease->hwaddr_ ?
3788 lease->hwaddr_->toText(
false) :
"(none)";
3791 string client_id_txt = client_id ? client_id->toText() :
"(none)";
3792 string lease_id_txt = lease->client_id_ ?
3793 lease->client_id_->toText() :
"(none)";
3797 .arg(addr.
toText()).arg(decline->getLabel())
3798 .arg(client_hw).arg(lease_hw).arg(client_id_txt).arg(lease_id_txt);
3815 if (HooksManager::calloutsPresent(
Hooks.hook_index_lease4_decline_)) {
3828 callout_handle->setArgument(
"query4", decline);
3831 callout_handle->setArgument(
"lease4", lease);
3834 HooksManager::callCallouts(
Hooks.hook_index_lease4_decline_,
3839 if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) ||
3840 (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP)) {
3842 .arg(decline->getLabel()).arg(lease->addr_.toText());
3847 Lease4Ptr old_values = boost::make_shared<Lease4>(*lease);
3861 .arg(decline->getLabel())
3862 .arg(lease->addr_.toText())
3874 StatsMgr::instance().addValue(
3875 StatsMgr::generateName(
"subnet", lease->subnet_id_,
"declined-addresses"),
3876 static_cast<int64_t
>(1));
3880 const auto& pool = subnet->getPool(
Lease::TYPE_V4, lease->addr_,
false);
3882 StatsMgr::instance().addValue(
3883 StatsMgr::generateName(
"subnet", subnet->getID(),
3884 StatsMgr::generateName(
"pool", pool->getID(),
"declined-addresses")),
3885 static_cast<int64_t
>(1));
3890 StatsMgr::instance().addValue(
"declined-addresses",
static_cast<int64_t
>(1));
3902 context->new_lease_ = lease;
3905 .arg(decline->getLabel()).arg(lease->valid_lft_);
3938 .arg(inform->getLabel())
3939 .arg(inform->getName())
3940 .arg(inform->getClasses().toText());
3957 if (ack->getRemoteAddr() != inform->getGiaddr()) {
3959 .arg(inform->getLabel())
3960 .arg(ack->getRemoteAddr())
3961 .arg(ack->getIface());
3984 .arg(query->getLabel())
3985 .arg(query->getIface());
3993 .arg(query->getLabel())
3994 .arg(query->getIface());
4004 if (pkt->isRelayed()) {
4009 if (pkt->isDhcp4o6()) {
4018 if (pkt->getRemoteAddr().isV4Zero() &&
4019 pkt->getCiaddr().isV4Zero()) {
4030 bool result = (!pkt->getLocalAddr().isV4Bcast() ||
4045 type = query->getType();
4049 .arg(query->getLabel())
4050 .arg(query->getIface());
4074 .arg(query->getLabel());
4081 .arg(query->getLabel())
4086 .arg(query->getLabel())
4113 boost::dynamic_pointer_cast<OptionCustom>(option);
4116 if (!option_custom) {
4124 if (option_custom->getDataFieldsNum() != 1) {
4130 IOAddress server_id = option_custom->readAddress();
4131 if (!server_id.
isV4()) {
4140 if (rai_suboption && (server_id.
toBytes() == rai_suboption->toBinary())) {
4147 if (cfg->getIgnoreServerIdentifier()) {
4185 if (cfg_subnets->hasSubnetWithServerId(server_id)) {
4192 if (cfg_networks->hasNetworkWithServerId(server_id)) {
4199 cclass != classes.
cend(); ++cclass) {
4202 getClientClassDictionary()->findClass(*cclass);
4207 if (ccdef->getCfgOption()->empty()) {
4212 OptionCustomPtr context_opt_server_id = boost::dynamic_pointer_cast<OptionCustom>
4214 if (context_opt_server_id && (context_opt_server_id->readAddress() == server_id)) {
4222 OptionCustomPtr opt_server_id = boost::dynamic_pointer_cast<OptionCustom>
4225 return (opt_server_id && (opt_server_id->readAddress() == server_id));
4235 <<
" received in message "
4236 << query->getName());
4243 " received in message "
4244 << query->getName());
4254 if (query->getHWAddr() && !query->getHWAddr()->hwaddr_.empty()) {
4263 if (!client_id || client_id->len() == client_id->getHeaderLen()) {
4265 " provided in message "
4266 << query->getName());
4283 subnet->getSharedNetwork(network);
4285 const ClientClasses& to_add = network->getRequiredClasses();
4287 cclass != to_add.
cend(); ++cclass) {
4295 cclass != to_add.
cend(); ++cclass) {
4303 addr = resp->getYiaddr();
4310 cclass != to_add.
cend(); ++cclass) {
4324 cclass != classes.
cend(); ++cclass) {
4347 query->addClass(*cclass);
4360 .arg(
"get exception?");
4368 BOOST_FOREACH(
const uint16_t& code, query->getDeferredOptions()) {
4373 cclass != classes.
cend(); ++cclass) {
4377 getClientClassDictionary()->findClass(*cclass);
4383 if (!ccdef->getCfgOptionDef()) {
4421 opt = def->optionFactory(
Option::V4, code, buf);
4422 }
catch (
const std::exception& e) {
4430 while (query->delOption(code)) {
4434 query->addOption(opt);
4446 this, ph::_1, ph::_2));
4464 arg(result).arg((ncr ? ncr->toText() :
" NULL "));
4473 std::stringstream tmp;
4477 tmp << endl << EXTENDED_VERSION << endl;
4478 tmp <<
"linked with:" << endl;
4479 tmp << Logger::getVersion() << endl;
4480 tmp << CryptoLink::getVersion() << endl;
4481 tmp <<
"database:" << endl;
4500 string stat_name =
"pkt4-unknown-received";
4502 switch (query->getType()) {
4504 stat_name =
"pkt4-discover-received";
4508 stat_name =
"pkt4-offer-received";
4511 stat_name =
"pkt4-request-received";
4515 stat_name =
"pkt4-ack-received";
4519 stat_name =
"pkt4-nak-received";
4522 stat_name =
"pkt4-release-received";
4525 stat_name =
"pkt4-decline-received";
4528 stat_name =
"pkt4-inform-received";
4542 static_cast<int64_t
>(1));
4548 static_cast<int64_t
>(1));
4552 switch (response->getType()) {
4554 stat_name =
"pkt4-offer-sent";
4557 stat_name =
"pkt4-ack-sent";
4560 stat_name =
"pkt4-nak-sent";
4568 static_cast<int64_t
>(1));
4572 return (
Hooks.hook_index_buffer4_receive_);
4576 return (
Hooks.hook_index_pkt4_receive_);
4580 return (
Hooks.hook_index_subnet4_select_);
4584 return (
Hooks.hook_index_lease4_release_);
4588 return (
Hooks.hook_index_pkt4_send_);
4592 return (
Hooks.hook_index_buffer4_send_);
4596 return (
Hooks.hook_index_lease4_decline_);
4601 HooksManager::clearParkingLots();
4605 static std::list<std::list<std::string>>
const list({
4606 {
"config-control",
"config-databases",
"[]"},
4607 {
"hooks-libraries",
"[]",
"parameters",
"*"},
4609 {
"hosts-databases",
"[]"},
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
This is a base class for exceptions thrown from the DNS library module.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
A generic exception that is thrown when an unexpected error condition occurs.
The IOAddress class represents an IP addresses (version agnostic)
bool isV4Zero() const
Convenience function to check if it is an IPv4 zero address.
std::string toText() const
Convert the address to a string.
uint32_t toUint32() const
Converts IPv4 address to uint32_t.
bool isV4() const
Convenience function to check for an IPv4 address.
std::vector< uint8_t > toBytes() const
Return address as set of bytes.
bool isV6Zero() const
Convenience function to check if it is an IPv4 zero address.
bool isV4Bcast() const
Convenience function to check if it is an IPv4 broadcast address.
bool isV6LinkLocal() const
checks whether and address is IPv6 and is link-local
static const IOAddress & IPV4_BCAST_ADDRESS()
Returns a "255.255.255.255" broadcast address.
static const IOAddress & IPV4_ZERO_ADDRESS()
Returns an address set to all zeros.
The IOService class is a wrapper for the ASIO io_service class.
DHCPv4 and DHCPv6 allocation engine.
boost::shared_ptr< ClientContext4 > ClientContext4Ptr
Pointer to the ClientContext4.
static uint32_t getValidLft(const ClientContext4 &ctx)
Returns the valid lifetime based on the v4 context.
Implementation of the mechanisms to control the use of the Configuration Backends by the DHCPv4 serve...
@ EARLY_GLOBAL_RESERVATIONS_LOOKUP
@ USE_ROUTING
Server uses routing to determine the right interface to send response.
@ SOCKET_UDP
Datagram socket, i.e. IP/UDP socket.
D2ClientMgr & getD2ClientMgr()
Fetches the DHCP-DDNS manager.
static CfgMgr & instance()
returns a single instance of Configuration Manager
SrvConfigPtr getCurrentCfg()
Returns a pointer to the current configuration.
static SubnetSelector initSelector(const Pkt4Ptr &query)
Build selector from a client's message.
Container for storing client class names.
ClientClassContainer::const_iterator const_iterator
Type of iterators.
void insert(const ClientClass &class_name)
Insert an element.
bool empty() const
Check if classes is empty.
std::string toText(const std::string &separator=", ") const
Returns all class names as text.
const_iterator cbegin() const
Iterators to the first element.
const_iterator cend() const
Iterators to the past the end element.
Client race avoidance RAII handler.
bool tryLock(Pkt4Ptr query, ContinuationPtr cont=ContinuationPtr())
Tries to acquires a client.
Holds Client identifier or client IPv4 address.
ReplaceClientNameMode
Defines the client name replacement modes.
D2ClientMgr isolates Kea from the details of being a D2 client.
std::string generateFqdn(const asiolink::IOAddress &address, const DdnsParams &ddns_params, const bool trailing_dot=true) const
Builds a FQDN based on the configuration and given IP address.
bool ddnsEnabled()
Convenience method for checking if DHCP-DDNS is enabled.
void startSender(D2ClientErrorHandler error_handler, isc::asiolink::IOService &io_service)
Enables sending NameChangeRequests to kea-dhcp-ddns.
void getUpdateDirections(const T &fqdn_resp, bool &forward, bool &reverse)
Get directional update flags based on server FQDN flags.
void suspendUpdates()
Suspends sending requests.
void adjustDomainName(const T &fqdn, T &fqdn_resp, const DdnsParams &ddns_params)
Set server FQDN name based on configuration and a given FQDN.
void stopSender()
Disables sending NameChangeRequests to kea-dhcp-ddns.
void adjustFqdnFlags(const T &fqdn, T &fqdn_resp, const DdnsParams &ddns_params)
Set server FQDN flags based on configuration and a given FQDN.
std::string qualifyName(const std::string &partial_name, const DdnsParams &ddns_params, const bool trailing_dot) const
Adds a qualifying suffix to a given domain name.
Convenience container for conveying DDNS behavioral parameters It is intended to be created per Packe...
bool getUpdateOnRenew() const
Returns whether or not DNS should be updated when leases renew.
bool getEnableUpdates() const
Returns whether or not DHCP DDNS updating is enabled.
void close()
Close communication socket.
static Dhcp4to6Ipc & instance()
Returns pointer to the sole instance of Dhcp4to6Ipc.
AllocEngine::ClientContext4Ptr getContext() const
Returns the copy of the context for the Allocation engine.
void deleteResponse()
Removes the response message by resetting the pointer to NULL.
Pkt4Ptr getQuery() const
Returns the pointer to the query from the client.
static void setHostIdentifiers(AllocEngine::ClientContext4Ptr context)
Set host identifiers within a context.
static void classifyByVendor(const Pkt4Ptr &pkt)
Assign class using vendor-class-identifier option.
void initResponse()
Initializes the instance of the response message.
void setReservedMessageFields()
Sets reserved values of siaddr, sname and file in the server's response.
Pkt4Ptr getResponse() const
Returns the pointer to the server's response.
static void setReservedClientClasses(AllocEngine::ClientContext4Ptr context)
Assigns classes retrieved from host reservation database.
void initResponse4o6()
Initializes the DHCPv6 part of the response message.
static void evaluateClasses(const Pkt4Ptr &pkt, bool depend_on_known)
Evaluate classes.
static void classifyPacket(const Pkt4Ptr &pkt)
Assigns incoming packet to zero or more classes.
static void removeDependentEvaluatedClasses(const Pkt4Ptr &query)
Removed evaluated client classes.
CfgOptionList & getCfgOptionList()
Returns the configured option list (non-const version)
void conditionallySetReservedClientClasses()
Assigns classes retrieved from host reservation database if they haven't been yet set.
int run()
Main server processing loop.
void declineLease(const Lease4Ptr &lease, const Pkt4Ptr &decline, AllocEngine::ClientContext4Ptr &context)
Marks lease as declined.
void classifyPacket(const Pkt4Ptr &pkt)
Assigns incoming packet to zero or more classes.
void appendRequestedVendorOptions(Dhcpv4Exchange &ex)
Appends requested vendor options as requested by client.
void adjustIfaceData(Dhcpv4Exchange &ex)
Set IP/UDP and interface parameters for the DHCPv4 response.
void run_one()
Main server processing step.
static uint16_t checkRelayPort(const Dhcpv4Exchange &ex)
Check if the relay port RAI sub-option was set in the query.
bool acceptDirectRequest(const Pkt4Ptr &query) const
Check if a message sent by directly connected client should be accepted or discarded.
virtual ~Dhcpv4Srv()
Destructor. Used during DHCPv4 service shutdown.
virtual Pkt4Ptr receivePacket(int timeout)
dummy wrapper around IfaceMgr::receive4
void processPacketAndSendResponseNoThrow(Pkt4Ptr &query)
Process a single incoming DHCPv4 packet and sends the response.
static void appendServerID(Dhcpv4Exchange &ex)
Adds server identifier option to the server's response.
void postAllocateNameUpdate(const AllocEngine::ClientContext4Ptr &ctx, const Lease4Ptr &lease, const Pkt4Ptr &query, const Pkt4Ptr &resp, bool client_name_changed)
Update client name and DNS flags in the lease and response.
void processDhcp4QueryAndSendResponse(Pkt4Ptr &query, Pkt4Ptr &rsp, bool allow_packet_park)
Process a single incoming DHCPv4 query.
void startD2()
Starts DHCP_DDNS client IO if DDNS updates are enabled.
bool accept(const Pkt4Ptr &query) const
Checks whether received message should be processed or discarded.
static int getHookIndexBuffer4Receive()
Returns the index for "buffer4_receive" hook point.
Pkt4Ptr processRequest(Pkt4Ptr &request, AllocEngine::ClientContext4Ptr &context)
Processes incoming REQUEST and returns REPLY response.
static void processStatsReceived(const Pkt4Ptr &query)
Class methods for DHCPv4-over-DHCPv6 handler.
static int getHookIndexPkt4Send()
Returns the index for "pkt4_send" hook point.
void processDecline(Pkt4Ptr &decline, AllocEngine::ClientContext4Ptr &context)
Process incoming DHCPDECLINE messages.
Dhcpv4Srv(uint16_t server_port=DHCP4_SERVER_PORT, uint16_t client_port=0, const bool use_bcast=true, const bool direct_response_desired=true)
Default constructor.
static int getHookIndexSubnet4Select()
Returns the index for "subnet4_select" hook point.
static void processStatsSent(const Pkt4Ptr &response)
Updates statistics for transmitted packets.
void shutdown() override
Instructs the server to shut down.
static int getHookIndexLease4Release()
Returns the index for "lease4_release" hook point.
void adjustRemoteAddr(Dhcpv4Exchange &ex)
Sets remote addresses for outgoing packet.
void processDhcp4Query(Pkt4Ptr &query, Pkt4Ptr &rsp, bool allow_packet_park)
Process a single incoming DHCPv4 query.
static int getHookIndexPkt4Receive()
Returns the index for "pkt4_receive" hook point.
void assignLease(Dhcpv4Exchange &ex)
Assigns a lease and appends corresponding options.
void setFixedFields(Dhcpv4Exchange &ex)
Sets fixed fields of the outgoing packet.
void appendBasicOptions(Dhcpv4Exchange &ex)
Append basic options if they are not present.
void sendResponseNoThrow(hooks::CalloutHandlePtr &callout_handle, Pkt4Ptr &query, Pkt4Ptr &rsp)
Process an unparked DHCPv4 packet and sends the response.
void processClientName(Dhcpv4Exchange &ex)
Processes Client FQDN and Hostname Options sent by a client.
boost::shared_ptr< AllocEngine > alloc_engine_
Allocation Engine.
void requiredClassify(Dhcpv4Exchange &ex)
Assigns incoming packet to zero or more classes (required pass).
Pkt4Ptr processInform(Pkt4Ptr &inform, AllocEngine::ClientContext4Ptr &context)
Processes incoming DHCPINFORM messages.
uint16_t client_port_
UDP port number to which server sends all responses.
std::list< std::list< std::string > > jsonPathsToRedact() const final override
Return a list of all paths that contain passwords or secrets for kea-dhcp4.
static std::string srvidToString(const OptionPtr &opt)
converts server-id to text Converts content of server-id option to a text representation,...
bool acceptServerId(const Pkt4Ptr &pkt) const
Verifies if the server id belongs to our server.
static const std::string VENDOR_CLASS_PREFIX
this is a prefix added to the content of vendor-class option
void createNameChangeRequests(const Lease4Ptr &lease, const Lease4Ptr &old_lease, const DdnsParams &ddns_params)
Creates NameChangeRequests which correspond to the lease which has been acquired.
void appendRequestedOptions(Dhcpv4Exchange &ex)
Appends options requested by client.
void setPacketStatisticsDefaults()
This function sets statistics related to DHCPv4 packets processing to their initial values.
static std::string getVersion(bool extended)
returns Kea version on stdout and exit.
isc::dhcp::Subnet4Ptr selectSubnet4o6(const Pkt4Ptr &query, bool &drop, bool sanity_only=false) const
Selects a subnet for a given client's DHCP4o6 packet.
void buildCfgOptionList(Dhcpv4Exchange &ex)
Build the configured option list.
volatile bool shutdown_
Indicates if shutdown is in progress.
uint16_t server_port_
UDP port number on which server listens.
bool earlyGHRLookup(const Pkt4Ptr &query, AllocEngine::ClientContext4Ptr ctx)
Initialize client context and perform early global reservations lookup.
NetworkStatePtr network_state_
Holds information about disabled DHCP service and/or disabled subnet/network scopes.
void setTeeTimes(const Lease4Ptr &lease, const Subnet4Ptr &subnet, Pkt4Ptr resp)
Adds the T1 and T2 timers to the outbound response as appropriate.
bool getSendResponsesToSource() const
Returns value of the test_send_responses_to_source_ flag.
void processPacketAndSendResponse(Pkt4Ptr &query)
Process a single incoming DHCPv4 packet and sends the response.
isc::dhcp::Subnet4Ptr selectSubnet(const Pkt4Ptr &query, bool &drop, bool sanity_only=false) const
Selects a subnet for a given client's packet.
Pkt4Ptr processDiscover(Pkt4Ptr &discover, AllocEngine::ClientContext4Ptr &context)
Processes incoming DISCOVER and returns response.
virtual void d2ClientErrorHandler(const dhcp_ddns::NameChangeSender::Result result, dhcp_ddns::NameChangeRequestPtr &ncr)
Implements the error handler for DHCP_DDNS IO errors.
virtual void sendPacket(const Pkt4Ptr &pkt)
dummy wrapper around IfaceMgr::send()
static int getHookIndexBuffer4Send()
Returns the index for "buffer4_send" hook point.
void stopD2()
Stops DHCP_DDNS client IO if DDNS updates are enabled.
bool acceptMessageType(const Pkt4Ptr &query) const
Check if received message type is valid for the server to process.
static void sanityCheck(const Pkt4Ptr &query, RequirementLevel serverid)
Verifies if specified packet meets RFC requirements.
void processPacket(Pkt4Ptr &query, Pkt4Ptr &rsp, bool allow_packet_park=true)
Process a single incoming DHCPv4 packet.
void discardPackets()
Discards parked packets Clears the packet parking lots of all packets.
static int getHookIndexLease4Decline()
Returns the index for "lease4_decline" hook point.
void processRelease(Pkt4Ptr &release, AllocEngine::ClientContext4Ptr &context)
Processes incoming DHCPRELEASE messages.
asiolink::IOServicePtr & getIOService()
Returns pointer to the IO service used by the server.
void processPacketPktSend(hooks::CalloutHandlePtr &callout_handle, Pkt4Ptr &query, Pkt4Ptr &rsp)
Executes pkt4_send callout.
RequirementLevel
defines if certain option may, must or must not appear
void processPacketBufferSend(hooks::CalloutHandlePtr &callout_handle, Pkt4Ptr &rsp)
Executes buffer4_send callout and sends the response.
void deferredUnpack(Pkt4Ptr &query)
Perform deferred option unpacking.
IdentifierType
Type of the host identifier.
@ IDENT_FLEX
Flexible host identifier.
std::string getIdentifierAsText() const
Returns host identifier in a textual form.
static IfaceMgr & instance()
IfaceMgr is a singleton class.
bool isDirectResponseSupported() const
Check if packet be sent directly to the client having no address.
bool send(const Pkt6Ptr &pkt)
Sends an IPv6 packet.
void closeSockets()
Closes all open sockets.
void setMatchingPacketFilter(const bool direct_response_desired=false)
Set Packet Filter object to handle send/receive packets.
uint16_t getSocket(const isc::dhcp::Pkt6Ptr &pkt)
Return most suitable socket for transmitting specified IPv6 packet.
static TrackingLeaseMgr & instance()
Return current lease manager.
static void destroy()
Destroy lease manager.
virtual Lease4Ptr getLease4(const isc::asiolink::IOAddress &addr) const =0
Returns an IPv4 lease for specified IPv4 address.
virtual bool deleteLease(const Lease4Ptr &lease)=0
Deletes an IPv4 lease.
static std::string getDBVersion()
Class method to return extended version info This class method must be redeclared and redefined in de...
virtual void updateLease4(const Lease4Ptr &lease4)=0
Updates IPv4 lease.
static OptionDefinitionPtr getOptionDef(const std::string &space, const uint16_t code)
Return the first option definition matching a particular option code.
static OptionDefinitionPtr getRuntimeOptionDef(const std::string &space, const uint16_t code)
Returns runtime (non-standard) option definition by space and option code.
static OptionDefinitionPtr getLastResortOptionDef(const std::string &space, const uint16_t code)
Returns last resort option definition by space and option code.
static std::string getDBVersion()
Local version of getDBVersion() class method.
Holds information about DHCP service enabling status.
DHCPv4 Option class for handling list of IPv4 addresses.
std::vector< isc::asiolink::IOAddress > AddressContainer
Defines a collection of IPv4 addresses.
Represents DHCPv4 Client FQDN Option (code 81).
static const uint8_t FLAG_N
Bit N.
bool getFlag(const uint8_t flag) const
Checks if the specified flag of the DHCPv4 Client FQDN Option is set.
static const uint8_t FLAG_S
Bit S.
void setDomainName(const std::string &domain_name, const DomainNameType domain_name_type)
Set new domain-name.
void setFlag(const uint8_t flag, const bool set)
Modifies the value of the specified DHCPv4 Client Fqdn Option flag.
static const uint8_t FLAG_E
Bit E.
virtual std::string toText(int indent=0) const
Returns string representation of the option.
Option with defined data fields represented as buffers that can be accessed using data field index.
static unsigned int getLabelCount(const std::string &text_name)
Return the number of labels in the Name.
OptionPtr option_
Option instance.
Forward declaration to OptionIntArray.
Forward declaration to OptionInt.
Class which represents an option carrying a single string value.
This class represents vendor-specific information option.
static const size_t OPTION4_HDR_LEN
length of the usual DHCPv4 option header (there are exceptions)
static std::string getDBVersion()
Local version of getDBVersion() class method.
Represents DHCPv4 packet.
static const uint16_t FLAG_BROADCAST_MASK
Mask for the value of flags field in the DHCPv4 message to check whether client requested broadcast r...
Represents DHCPv4-over-DHCPv6 packet.
Represents a DHCPv6 packet.
An exception that is thrown if a DHCPv6 protocol violation occurs while processing a message (e....
RAII object enabling copying options retrieved from the packet.
Exception thrown when a call to select is interrupted by a signal.
Exception thrown during option unpacking This exception is thrown when an error has occurred,...
Result
Defines the outcome of an asynchronous NCR send.
Wrapper class around callout handle which automatically resets handle's state.
int getExitValue()
Fetches the exit value.
Statistics Manager class.
static StatsMgr & instance()
Statistics Manager accessor method.
RAII class creating a critical section.
Contains declarations for loggers used by the DHCPv4 server component.
Defines the Dhcp4o6Ipc class.
#define VENDOR_ID_CABLE_LABS
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::shared_ptr< OptionUint8Array > OptionUint8ArrayPtr
OptionInt< uint32_t > OptionUint32
boost::shared_ptr< OptionUint32 > OptionUint32Ptr
void setValue(const std::string &name, const int64_t value)
Records absolute integer observation.
void addValue(const std::string &name, const int64_t value)
Records incremental integer observation.
An abstract API for lease database.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
IOAddress getNetmask4(uint8_t len)
Generates an IPv4 netmask of specified length.
boost::shared_ptr< const Element > ConstElementPtr
boost::shared_ptr< NameChangeRequest > NameChangeRequestPtr
Defines a pointer to a NameChangeRequest.
const isc::log::MessageID DHCP4_BUFFER_RECEIVE_FAIL
boost::shared_ptr< OptionVendor > OptionVendorPtr
Pointer to a vendor option.
isc::log::Logger ddns4_logger(DHCP4_DDNS_LOGGER_NAME)
Logger for Hostname or FQDN processing.
const isc::log::MessageID DHCP4_PACKET_DROP_0004
const isc::log::MessageID DHCP4_SRV_DHCP4O6_ERROR
const isc::log::MessageID DHCP4_RELEASE_EXCEPTION
const isc::log::MessageID DHCP4_SUBNET_DATA
const isc::log::MessageID DHCP4_INIT_REBOOT
const isc::log::MessageID DHCP4_HOOK_PACKET_SEND_SKIP
const isc::log::MessageID DHCP4_FLEX_ID
const isc::log::MessageID DHCP4_PACKET_DROP_0003
const isc::log::MessageID DHCP4_DEFERRED_OPTION_UNPACK_FAIL
const isc::log::MessageID DHCP4_PACKET_DROP_0001
const isc::log::MessageID DHCP4_QUERY_DATA
boost::shared_ptr< Subnet4 > Subnet4Ptr
A pointer to a Subnet4 object.
const isc::log::MessageID DHCP4_NO_LEASE_INIT_REBOOT
const isc::log::MessageID DHCP4_INFORM_DIRECT_REPLY
boost::shared_ptr< Lease4Collection > Lease4CollectionPtr
A shared pointer to the collection of IPv4 leases.
void queueNCR(const NameChangeType &chg_type, const Lease4Ptr &lease)
Creates name change request from the DHCPv4 lease.
const isc::log::MessageID DHCP4_CLIENT_FQDN_PROCESS
const isc::log::MessageID DHCP4_DEFERRED_OPTION_MISSING
const isc::log::MessageID EVAL_RESULT
const isc::log::MessageID DHCP4_HOOK_SUBNET4_SELECT_DROP
@ DHO_DOMAIN_NAME_SERVERS
@ DHO_VENDOR_CLASS_IDENTIFIER
@ DHO_DHCP_REBINDING_TIME
@ DHO_DHCP_SERVER_IDENTIFIER
@ DHO_DHCP_CLIENT_IDENTIFIER
@ DHO_DHCP_REQUESTED_ADDRESS
@ DHO_DHCP_PARAMETER_REQUEST_LIST
const isc::log::MessageID DHCP4_PACKET_DROP_0008
const isc::log::MessageID DHCP4_RELEASE_EXPIRED
const isc::log::MessageID DHCP4_HOOK_LEASES4_COMMITTED_DROP
const isc::log::MessageID DHCP4_DHCP4O6_SUBNET_SELECTION_FAILED
const isc::log::MessageID DHCP4_RELEASE_FAIL_WRONG_CLIENT
const isc::log::MessageID DHCP4_LEASE_ADVERT
const isc::log::MessageID DHCP4_HOOK_LEASES4_COMMITTED_PARKING_LOT_FULL
const isc::log::MessageID DHCP4_HOOK_BUFFER_RCVD_DROP
boost::shared_ptr< OptionCustom > OptionCustomPtr
A pointer to the OptionCustom object.
const isc::log::MessageID DHCP4_HOOK_PACKET_RCVD_SKIP
const int DBG_DHCP4_BASIC_DATA
Debug level used to log the traces with some basic data.
const isc::log::MessageID DHCP4_LEASE_ALLOC
const int DBG_DHCP4_DETAIL
Debug level used to trace detailed errors.
boost::shared_ptr< Pkt4 > Pkt4Ptr
A pointer to Pkt4 object.
isc::log::Logger lease4_logger(DHCP4_LEASE_LOGGER_NAME)
Logger for lease allocation logic.
const isc::log::MessageID DHCP4_NCR_CREATION_FAILED
isc::log::Logger options4_logger(DHCP4_OPTIONS_LOGGER_NAME)
Logger for options parser.
const isc::log::MessageID DHCP4_HOOK_SUBNET4_SELECT_SKIP
const int DBG_DHCP4_DETAIL_DATA
This level is used to log the contents of packets received and sent.
const isc::log::MessageID DHCP4_PACKET_PACK
boost::shared_ptr< AllocEngine > AllocEnginePtr
A pointer to the AllocEngine object.
ContinuationPtr makeContinuation(Continuation &&cont)
Continuation factory.
const isc::log::MessageID DHCP4_DECLINE_FAIL
const isc::log::MessageID DHCP4_LEASE_REUSE
boost::shared_ptr< const CfgHostOperations > ConstCfgHostOperationsPtr
Pointer to the const object.
boost::shared_ptr< CfgIface > CfgIfacePtr
A pointer to the CfgIface .
const isc::log::MessageID DHCP4_PACKET_PACK_FAIL
boost::shared_ptr< ClientClassDef > ClientClassDefPtr
a pointer to an ClientClassDef
const isc::log::MessageID DHCP4_DDNS_REQUEST_SEND_FAILED
const isc::log::MessageID DHCP4_GENERATE_FQDN
const isc::log::MessageID DHCP4_CLASS_ASSIGNED
const isc::log::MessageID DHCP4_PACKET_PROCESS_STD_EXCEPTION
boost::shared_ptr< SrvConfig > SrvConfigPtr
Non-const pointer to the SrvConfig.
const isc::log::MessageID DHCP4_RESPONSE_HOSTNAME_DATA
const isc::log::MessageID DHCP4_BUFFER_WAIT_SIGNAL
const isc::log::MessageID DHCP4_HOOK_LEASE4_RELEASE_SKIP
const isc::log::MessageID DHCP4_POST_ALLOCATION_NAME_UPDATE_FAIL
const isc::log::MessageID DHCP4_PACKET_NAK_0001
const isc::log::MessageID DHCP4_HOOK_DECLINE_SKIP
const isc::log::MessageID DHCP4_HOOK_LEASE4_OFFER_PARK
const isc::log::MessageID DHCP4_DECLINE_LEASE_MISMATCH
const isc::log::MessageID DHCP4_SRV_UNLOAD_LIBRARIES_ERROR
const isc::log::MessageID DHCP4_RESPONSE_HOSTNAME_GENERATE
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
const isc::log::MessageID DHCP4_PACKET_DROP_0013
const isc::log::MessageID DHCP4_PACKET_QUEUE_FULL
const isc::log::MessageID DHCP4_PACKET_DROP_0009
const isc::log::MessageID DHCP4_PACKET_RECEIVED
boost::shared_ptr< Pkt4o6 > Pkt4o6Ptr
A pointer to Pkt4o6 object.
const isc::log::MessageID DHCP4_RELEASE_DELETED
const isc::log::MessageID DHCP4_BUFFER_UNPACK
const isc::log::MessageID DHCP4_CLIENT_HOSTNAME_DATA
OptionContainer::nth_index< 5 >::type OptionContainerCancelIndex
Type of the index #5 - option cancellation flag.
const isc::log::MessageID DHCP4_CLASSES_ASSIGNED_AFTER_SUBNET_SELECTION
const isc::log::MessageID DHCP4_PACKET_SEND_FAIL
std::pair< OptionContainerPersistIndex::const_iterator, OptionContainerPersistIndex::const_iterator > OptionContainerPersistRange
Pair of iterators to represent the range of options having the same persistency flag.
boost::shared_ptr< OptionDefinition > OptionDefinitionPtr
Pointer to option definition object.
const isc::log::MessageID DHCP4_DHCP4O6_SUBNET_DATA
boost::shared_ptr< Option4ClientFqdn > Option4ClientFqdnPtr
A pointer to the Option4ClientFqdn object.
const isc::log::MessageID DHCP4_CLIENTID_IGNORED_FOR_LEASES
const isc::log::MessageID DHCP4_CLIENT_NAME_PROC_FAIL
const isc::log::MessageID DHCP4_CLIENT_HOSTNAME_PROCESS
const isc::log::MessageID DHCP4_HOOK_DDNS_UPDATE
const isc::log::MessageID DHCP4_SRV_CONSTRUCT_ERROR
boost::shared_ptr< Expression > ExpressionPtr
const isc::log::MessageID DHCP4_RELEASE_FAIL
const isc::log::MessageID DHCP4_RELEASE_FAIL_NO_LEASE
const isc::log::MessageID DHCP4_CLIENT_HOSTNAME_MALFORMED
boost::shared_ptr< Pool > PoolPtr
a pointer to either IPv4 or IPv6 Pool
boost::shared_ptr< OptionString > OptionStringPtr
Pointer to the OptionString object.
isc::log::Logger bad_packet4_logger(DHCP4_BAD_PACKET_LOGGER_NAME)
Logger for rejected packets.
isc::hooks::CalloutHandlePtr getCalloutHandle(const T &pktptr)
CalloutHandle Store.
const isc::log::MessageID DHCP4_PACKET_DROP_0006
const int DBG_DHCP4_BASIC
Debug level used to trace basic operations within the code.
boost::shared_ptr< ClientClassDictionary > ClientClassDictionaryPtr
Defines a pointer to a ClientClassDictionary.
const isc::log::MessageID DHCP4_SRV_D2STOP_ERROR
const isc::log::MessageID DHCP4_RESPONSE_FQDN_DATA
boost::shared_ptr< ClientId > ClientIdPtr
Shared pointer to a Client ID.
boost::shared_ptr< Continuation > ContinuationPtr
Define the type of shared pointers to continuations.
const isc::log::MessageID DHCP4_DECLINE_LEASE_NOT_FOUND
boost::shared_ptr< OptionContainer > OptionContainerPtr
Pointer to the OptionContainer object.
const isc::log::MessageID DHCP4_CLASS_UNTESTABLE
boost::shared_ptr< ClientClassDefList > ClientClassDefListPtr
Defines a pointer to a ClientClassDefList.
const isc::log::MessageID DHCP4_PACKET_DROP_0005
const isc::log::MessageID DHCP4_SUBNET_DYNAMICALLY_CHANGED
const isc::log::MessageID DHCP4_SHUTDOWN_REQUEST
@ DHCP_NOTYPE
Message Type option missing.
const isc::log::MessageID DHCP4_PACKET_NAK_0003
const isc::log::MessageID DHCP4_TESTING_MODE_SEND_TO_SOURCE_ENABLED
boost::shared_ptr< const CfgSubnets4 > ConstCfgSubnets4Ptr
Const pointer.
const isc::log::MessageID DHCP4_BUFFER_RECEIVED
bool evaluateBool(const Expression &expr, Pkt &pkt)
Evaluate a RPN expression for a v4 or v6 packet and return a true or false decision.
const isc::log::MessageID DHCP4_SUBNET_SELECTION_FAILED
boost::shared_ptr< const Host > ConstHostPtr
Const pointer to the Host object.
const isc::log::MessageID DHCP4_RESPONSE_DATA
isc::log::Logger packet4_logger(DHCP4_PACKET_LOGGER_NAME)
Logger for processed packets.
OptionContainer::nth_index< 2 >::type OptionContainerPersistIndex
Type of the index #2 - option persistency flag.
const isc::log::MessageID DHCP4_DECLINE_LEASE
const isc::log::MessageID DHCP4_PACKET_SEND
boost::shared_ptr< OptionVendorClass > OptionVendorClassPtr
Defines a pointer to the OptionVendorClass.
const isc::log::MessageID DHCP4_RELEASE
const isc::log::MessageID DHCP4_HOOK_LEASE4_OFFER_DROP
const isc::log::MessageID DHCP4_HOOK_BUFFER_RCVD_SKIP
const isc::log::MessageID DHCP4_UNKNOWN_ADDRESS_REQUESTED
boost::shared_ptr< Pkt6 > Pkt6Ptr
A pointer to Pkt6 packet.
const isc::log::MessageID DHCP4_DHCP4O6_HOOK_SUBNET4_SELECT_DROP
std::vector< uint8_t > OptionBuffer
buffer types used in DHCP code.
const isc::log::MessageID DHCP4_OPEN_SOCKET
const isc::log::MessageID DHCP4_PACKET_DROP_0007
boost::shared_ptr< CfgSharedNetworks4 > CfgSharedNetworks4Ptr
Pointer to the configuration of IPv4 shared networks.
const isc::log::MessageID DHCP4_HOOK_PACKET_SEND_DROP
const isc::log::MessageID DHCP4_RESERVED_HOSTNAME_ASSIGNED
isc::log::Logger dhcp4_logger(DHCP4_APP_LOGGER_NAME)
Base logger for DHCPv4 server.
const isc::log::MessageID DHCP4_CLASSES_ASSIGNED
@ RAI_OPTION_SERVER_ID_OVERRIDE
@ RAI_OPTION_AGENT_CIRCUIT_ID
const isc::log::MessageID DHCP4_QUERY_LABEL
bool isClientClassBuiltIn(const ClientClass &client_class)
Check if a client class name is builtin.
const isc::log::MessageID DHCP4_PACKET_NAK_0002
const int DBG_DHCP4_HOOKS
Debug level used to trace hook related operations.
boost::shared_ptr< SharedNetwork4 > SharedNetwork4Ptr
Pointer to SharedNetwork4 object.
std::vector< Lease4Ptr > Lease4Collection
A collection of IPv4 leases.
const isc::log::MessageID DHCP4_HOOK_BUFFER_SEND_SKIP
const isc::log::MessageID DHCP4_PACKET_PROCESS_EXCEPTION
std::pair< OptionContainerCancelIndex::const_iterator, OptionContainerCancelIndex::const_iterator > OptionContainerCancelRange
Pair of iterators to represent the range of options having the same cancellation flag.
const isc::log::MessageID DHCP4_PACKET_OPTIONS_SKIPPED
const isc::log::MessageID DHCP4_EMPTY_HOSTNAME
const isc::log::MessageID DHCP4_SUBNET_SELECTED
const isc::log::MessageID DHCP4_PACKET_DROP_0010
boost::shared_ptr< Lease4 > Lease4Ptr
Pointer to a Lease4 structure.
const isc::log::MessageID DHCP4_CLASS_UNCONFIGURED
const isc::log::MessageID DHCP4_DHCP4O6_SUBNET_SELECTED
boost::shared_ptr< Option > OptionPtr
const isc::log::MessageID DHCP4_HOOK_LEASE4_OFFER_PARKING_LOT_FULL
const int DBG_DHCP4_START
Debug level used to log information during server startup.
const isc::log::MessageID DHCP4_CLASS_UNDEFINED