8#include <kea_version.h>
114#include <boost/foreach.hpp>
115#include <boost/pointer_cast.hpp>
116#include <boost/range/adaptor/reversed.hpp>
117#include <boost/shared_ptr.hpp>
131namespace ph = std::placeholders;
137 int hook_index_buffer4_receive_;
138 int hook_index_pkt4_receive_;
139 int hook_index_subnet4_select_;
140 int hook_index_leases4_committed_;
141 int hook_index_lease4_release_;
142 int hook_index_pkt4_send_;
143 int hook_index_buffer4_send_;
144 int hook_index_lease4_decline_;
145 int hook_index_host4_identifier_;
146 int hook_index_ddns4_update_;
147 int hook_index_lease4_offer_;
148 int hook_index_lease4_server_decline_;
169std::set<std::string> dhcp4_statistics = {
171 "pkt4-discover-received",
172 "pkt4-offer-received",
173 "pkt4-request-received",
176 "pkt4-release-received",
177 "pkt4-decline-received",
178 "pkt4-inform-received",
179 "pkt4-unknown-received",
184 "pkt4-service-disabled",
187 "v4-allocation-fail",
188 "v4-allocation-fail-shared-network",
189 "v4-allocation-fail-subnet",
190 "v4-allocation-fail-no-pools",
191 "v4-allocation-fail-classes",
192 "v4-reservation-conflicts",
212 : alloc_engine_(alloc_engine), query_(query), resp_(),
213 context_(context), ipv6_only_preferred_(false) {
215 if (!alloc_engine_) {
217 " when creating an instance of the Dhcpv4Exchange");
222 " creating an instance of the Dhcpv4Exchange");
231 context_->subnet_ = subnet;
237 if (subnet && !context_->early_global_reservations_lookup_) {
240 context_->clientid_.reset(
new ClientId(opt_clientid->getData()));
246 if (subnet->getReservationsInSubnet() ||
247 subnet->getReservationsGlobal()) {
250 if (!context_->early_global_reservations_lookup_) {
255 alloc_engine->findReservation(*context_);
258 subnet->getSharedNetwork(sn);
268 auto global_host = context_->globalHost();
269 auto current_host = context_->currentHost();
270 if ((!context_->early_global_reservations_lookup_ &&
271 global_host && !global_host->getClientClasses4().empty()) ||
272 (!sn && current_host && !current_host->getClientClasses4().empty())) {
293 if (!context_->hosts_.empty()) {
294 query->addClass(
"KNOWN");
296 .arg(query->getLabel())
299 query->addClass(
"UNKNOWN");
301 .arg(query->getLabel())
310 .arg(query_->getLabel())
314 if (query_->inClass(
"DROP")) {
316 .arg(query_->getHWAddrLabel())
317 .arg(query_->toText());
319 static_cast<int64_t
>(1));
326 uint8_t resp_type = 0;
340 resp_.reset(
new Pkt4(resp_type,
getQuery()->getTransid()));
342 copyDefaultOptions();
356 const Pkt6Ptr& query6 = query->getPkt6();
360 if (!query6->relay_info_.empty()) {
361 resp6->copyRelayInfo(query6);
364 resp6->setIface(query6->getIface());
365 resp6->setIndex(query6->getIndex());
366 resp6->setRemoteAddr(query6->getRemoteAddr());
367 resp6->setRemotePort(query6->getRemotePort());
368 resp_.reset(
new Pkt4o6(resp_, resp6));
372Dhcpv4Exchange::copyDefaultFields() {
373 resp_->setIface(query_->getIface());
374 resp_->setIndex(query_->getIndex());
381 resp_->setCiaddr(query_->getCiaddr());
385 resp_->setHops(query_->getHops());
388 resp_->setHWAddr(query_->getHWAddr());
391 resp_->setGiaddr(query_->getGiaddr());
400 HWAddrPtr src_hw_addr = query_->getLocalHWAddr();
402 resp_->setLocalHWAddr(src_hw_addr);
404 HWAddrPtr dst_hw_addr = query_->getRemoteHWAddr();
406 resp_->setRemoteHWAddr(dst_hw_addr);
410 resp_->setFlags(query_->getFlags());
414Dhcpv4Exchange::copyDefaultOptions() {
419 if (client_id && echo) {
420 resp_->addOption(client_id);
433 resp_->addOption(subnet_sel);
446 sao->boolValue() && query_->inClass(
"STASH_AGENT_OPTIONS")) {
449 resp_->addOption(rai);
459 for (
auto const& id_type : cfg->getIdentifierTypes()) {
462 if (context->hwaddr_ && !context->hwaddr_->hwaddr_.empty()) {
463 context->addHostIdentifier(id_type, context->hwaddr_->hwaddr_);
468 if (context->clientid_) {
469 const std::vector<uint8_t>& vec = context->clientid_->getClientId();
474 if ((vec[0] == CLIENT_ID_OPTION_TYPE_DUID) && (vec.size() > 5)) {
476 context->addHostIdentifier(id_type,
477 std::vector<uint8_t>(vec.begin() + 5,
489 if (circuit_id_opt) {
490 const OptionBuffer& circuit_id_vec = circuit_id_opt->getData();
491 if (!circuit_id_vec.empty()) {
492 context->addHostIdentifier(id_type, circuit_id_vec);
500 if (context->clientid_) {
501 const std::vector<uint8_t>& vec = context->clientid_->getClientId();
503 context->addHostIdentifier(id_type, vec);
516 std::vector<uint8_t> id;
525 callout_handle->setArgument(
"query4", context->query_);
526 callout_handle->setArgument(
"id_type", type);
527 callout_handle->setArgument(
"id_value",
id);
533 callout_handle->getArgument(
"id_type", type);
534 callout_handle->getArgument(
"id_value",
id);
540 .arg(context->query_->getLabel())
543 context->addHostIdentifier(type,
id);
558 for (
auto const& def : *defs_ptr) {
562 if (def->getMatchExpr()) {
563 query->classes_.erase(def->getName());
570 if (context->currentHost() && context->query_) {
571 const ClientClasses& classes = context->currentHost()->getClientClasses4();
572 for (
auto const& cclass : classes) {
573 context->query_->addClass(cclass);
580 if (context_->subnet_) {
582 context_->subnet_->getSharedNetwork(shared_network);
583 if (shared_network) {
585 if (host && (host->getIPv4SubnetID() != SUBNET_ID_GLOBAL)) {
597 if (!host->getNextServer().isV4Zero()) {
598 resp_->setSiaddr(host->getNextServer());
601 std::string sname = host->getServerHostname();
602 if (!sname.empty()) {
603 resp_->setSname(
reinterpret_cast<const uint8_t*
>(sname.c_str()),
607 std::string bootfile = host->getBootFileName();
608 if (!bootfile.empty()) {
609 resp_->setFile(
reinterpret_cast<const uint8_t*
>(bootfile.c_str()),
617 boost::shared_ptr<OptionString> vendor_class =
629 pkt->addClass(
"ALL");
643 for (
auto const& it : *defs_ptr) {
651 if (it->getAdditional()) {
655 if (it->getDependOnKnown() != depend_on_known) {
658 it->test(pkt, expr_ptr);
665 const bool use_bcast,
const bool direct_response_desired)
671 test_send_responses_to_source_(false) {
673 const char* env = std::getenv(
"KEA_TEST_SEND_RESPONSES_TO_SOURCE");
676 test_send_responses_to_source_ =
true;
704 }
catch (
const std::exception &e) {
720 for (
auto const& it : dhcp4_statistics) {
722 stats_mgr.
setValue(it,
static_cast<int64_t
>(0));
732 }
catch (
const std::exception& ex) {
739 }
catch (
const std::exception& ex) {
758 if (!names.empty()) {
760 for (
size_t i = 1; i < names.size(); ++i) {
761 msg += std::string(
", ") + names[i];
767 io_service_->stopAndPoll();
779 if (query->isDhcp4o6()) {
788 subnet = cfgmgr.
getCurrentCfg()->getCfgSubnets4()->selectSubnet(selector);
799 shared_ptr<ScopedCalloutHandleState> callout_handle_state(
800 std::make_shared<ScopedCalloutHandleState>(callout_handle));
806 callout_handle->setArgument(
"query4", query);
807 callout_handle->setArgument(
"subnet4", subnet);
808 callout_handle->setArgument(
"subnet4collection",
810 getCfgSubnets4()->getAll());
812 auto const tpl(parkingLimitExceeded(
"subnet4_select"));
813 bool const exceeded(
get<0>(tpl));
815 uint32_t
const limit(
get<1>(tpl));
820 .arg(query->getLabel());
826 "subnet4_select", query, [
this, query, allow_answer_park, callout_handle_state]() {
828 boost::shared_ptr<function<void()>> callback(
829 boost::make_shared<function<
void()>>(
830 [
this, query, allow_answer_park]()
mutable {
833 callout_handle_state->on_completion_ = [callback]() {
856 .arg(query->getLabel());
869 .arg(query->getLabel());
878 .arg(query->getLabel());
884 callout_handle->getArgument(
"subnet4", subnet);
890 .arg(query->getLabel())
891 .arg(subnet->getID());
895 .arg(query->getLabel())
896 .arg(subnet->toText());
901 .arg(query->getLabel());
909 bool allow_answer_park) {
913 selector.
ciaddr_ = query->getCiaddr();
914 selector.
giaddr_ = query->getGiaddr();
925 Pkt4o6Ptr query4o6 = boost::dynamic_pointer_cast<Pkt4o6>(query);
929 const Pkt6Ptr& query6 = query4o6->getPkt6();
932 if (query6 && !query6->relay_info_.empty()) {
933 for (
auto const& relay : boost::adaptors::reverse(query6->relay_info_)) {
934 if (!relay.linkaddr_.isV6Zero() &&
935 !relay.linkaddr_.isV6LinkLocal()) {
948 OptionCustomPtr oc = boost::dynamic_pointer_cast<OptionCustom>(sbnsel);
955 subnet = cfgmgr.
getCurrentCfg()->getCfgSubnets4()->selectSubnet4o6(selector);
966 shared_ptr<ScopedCalloutHandleState> callout_handle_state(
967 std::make_shared<ScopedCalloutHandleState>(callout_handle));
973 callout_handle->setArgument(
"query4", query);
974 callout_handle->setArgument(
"subnet4", subnet);
975 callout_handle->setArgument(
"subnet4collection",
977 getCfgSubnets4()->getAll());
979 auto const tpl(parkingLimitExceeded(
"subnet4_select"));
980 bool const exceeded(
get<0>(tpl));
982 uint32_t
const limit(
get<1>(tpl));
987 .arg(query->getLabel());
993 "subnet4_select", query, [
this, query, allow_answer_park, callout_handle_state]() {
995 boost::shared_ptr<function<void()>> callback(
996 boost::make_shared<function<
void()>>(
997 [
this, query, allow_answer_park]()
mutable {
1000 callout_handle_state->on_completion_ = [callback]() {
1023 .arg(query->getLabel());
1036 .arg(query->getLabel());
1045 .arg(query->getLabel());
1051 callout_handle->getArgument(
"subnet4", subnet);
1058 .arg(query->getLabel())
1059 .arg(subnet->getID());
1064 .arg(query->getLabel())
1065 .arg(subnet->toText());
1070 .arg(query->getLabel());
1090 ctx->query_ = query;
1093 ctx->hwaddr_ = query->getHWAddr();
1107 ctx->early_global_reservations_lookup_ = egrl->boolValue();
1111 if (ctx->early_global_reservations_lookup_) {
1115 ctx->clientid_.reset(
new ClientId(opt_clientid->getData()));
1124 if (global_host && !global_host->getClientClasses4().empty()) {
1129 const ClientClasses& classes = global_host->getClientClasses4();
1130 for (
auto const& cclass : classes) {
1131 query->addClass(cclass);
1140 query->addClass(
"KNOWN");
1142 .arg(query->getLabel())
1149 if (query->inClass(
"DROP")) {
1152 .arg(query->getHWAddrLabel())
1153 .arg(query->toText());
1155 static_cast<int64_t
>(1));
1160 ctx->hosts_[SUBNET_ID_GLOBAL] = global_host;
1174 const char*
interface = getenv(
"KEA_AFL_INTERFACE");
1176 isc_throw(FuzzInitFail,
"no fuzzing interface has been set");
1180 const char* address = getenv(
"KEA_AFL_ADDRESS");
1182 isc_throw(FuzzInitFail,
"no fuzzing address has been set");
1190 while (__AFL_LOOP(fuzzer.maxLoopCount())) {
1202 }
catch (
const std::exception& e) {
1233 uint32_t timeout = 1;
1244 .arg(query->getRemoteAddr().toText())
1245 .arg(query->getRemotePort())
1246 .arg(query->getLocalAddr().toText())
1247 .arg(query->getLocalPort())
1248 .arg(query->getIface());
1255 static_cast<int64_t
>(1));
1271 }
catch (
const std::exception& e) {
1287 .arg(query->getLabel());
1290 static_cast<int64_t
>(1));
1292 static_cast<int64_t
>(1));
1296 query->addPktEvent(
"mt_queued");
1297 typedef function<void()> CallBack;
1298 boost::shared_ptr<CallBack> call_back =
1314 }
catch (
const std::exception& e) {
1316 .arg(query->getLabel())
1337 query->addPktEvent(
"process_started");
1340 query->addClass(
"ALL");
1342 bool skip_unpack =
false;
1359 callout_handle->setArgument(
"query4", query);
1371 .arg(query->getRemoteAddr().toText())
1372 .arg(query->getLocalAddr().toText())
1373 .arg(query->getIface());
1384 .arg(query->getRemoteAddr().toText())
1385 .arg(query->getLocalAddr().toText())
1386 .arg(query->getIface());
1390 callout_handle->getArgument(
"query4", query);
1398 .arg(query->getRemoteAddr().toText())
1399 .arg(query->getLocalAddr().toText())
1400 .arg(query->getIface());
1407 .arg(query->getLabel())
1409 }
catch (
const std::exception& e) {
1412 .arg(query->getLabel())
1413 .arg(query->getRemoteAddr().toText())
1414 .arg(query->getLocalAddr().toText())
1415 .arg(query->getIface())
1417 .arg(query->getHWAddrLabel());
1421 static_cast<int64_t
>(1));
1423 static_cast<int64_t
>(1));
1430 .arg(query->getLabel());
1438 }
catch (
const std::exception&) {
1455 static_cast<int64_t
>(1));
1461 int type = query->getType();
1463 .arg(query->getLabel())
1464 .arg(query->getName())
1466 .arg(query->getRemoteAddr())
1467 .arg(query->getLocalAddr())
1468 .arg(query->getIface());
1470 .arg(query->getLabel())
1471 .arg(query->toText(
true));
1487 callout_handle->setArgument(
"query4", query);
1500 .arg(query->getLabel());
1504 callout_handle->getArgument(
"query4", query);
1508 if (query->inClass(
"DROP")) {
1510 .arg(query->getHWAddrLabel())
1511 .arg(query->toText());
1513 static_cast<int64_t
>(1));
1522 bool allow_answer_park) {
1531 }
catch (
const std::exception& e) {
1533 .arg(query->getLabel())
1553 this, query, allow_answer_park));
1554 if (!client_handler.
tryLock(query, cont)) {
1570 ctx->subnet_ =
selectSubnet(query, drop, allow_answer_park);
1576 }
catch (
const std::exception& e) {
1586 .arg(query->getLabel())
1591 static_cast<int64_t
>(1));
1600 bool allow_answer_park) {
1610 }
catch (
const std::exception& e) {
1612 .arg(query->getLabel())
1621 bool allow_answer_park) {
1629 callout_handle->getContext(
"subnet4", ctx->subnet_);
1639 bool allow_answer_park) {
1646 switch (query->getType()) {
1676 }
catch (
const std::exception& e) {
1686 .arg(query->getLabel())
1691 static_cast<int64_t
>(1));
1698 int hook_idx =
Hooks.hook_index_leases4_committed_;
1699 std::string hook_label =
"leases4_committed";
1703 if (ctx->fake_allocation_) {
1704 hook_idx =
Hooks.hook_index_lease4_offer_;
1705 hook_label =
"lease4_offer";
1735 std::shared_ptr<ScopedCalloutHandleState> callout_handle_state =
1736 std::make_shared<ScopedCalloutHandleState>(callout_handle);
1741 callout_handle->setArgument(
"query4", query);
1745 callout_handle->setArgument(
"response4", rsp);
1749 if (ctx->new_lease_ && (ctx->new_lease_->reuseable_valid_lft_ == 0)) {
1750 new_leases->push_back(ctx->new_lease_);
1752 callout_handle->setArgument(
"leases4", new_leases);
1754 if (ctx->fake_allocation_) {
1756 callout_handle->setArgument(
"offer_lifetime", ctx->offer_lft_);
1757 callout_handle->setArgument(
"old_lease", ctx->old_lease_);
1758 callout_handle->setArgument(
"host", ctx->currentHost());
1762 if (ctx->old_lease_) {
1763 if ((!ctx->new_lease_) || (ctx->new_lease_->addr_ != ctx->old_lease_->addr_)) {
1764 deleted_leases->push_back(ctx->old_lease_);
1767 callout_handle->setArgument(
"deleted_leases4", deleted_leases);
1770 if (allow_answer_park) {
1771 auto const tpl(parkingLimitExceeded(hook_label));
1772 bool const exceeded(
get<0>(tpl));
1774 uint32_t
const limit(
get<1>(tpl));
1778 .arg(query->getLabel());
1780 static_cast<int64_t
>(1));
1790 [
this, callout_handle, query, rsp, callout_handle_state, hook_idx, ctx]()
mutable {
1791 if (hook_idx ==
Hooks.hook_index_lease4_offer_) {
1792 bool offer_address_in_use =
false;
1794 callout_handle->getArgument(
"offer_address_in_use", offer_address_in_use);
1797 .arg(query->getLabel())
1801 if (offer_address_in_use) {
1803 bool lease_exists = (ctx->offer_lft_ > 0);
1805 typedef function<void()> CallBack;
1808 boost::shared_ptr<CallBack> call_back = boost::make_shared<CallBack>(
1810 callout_handle, query, lease, lease_exists));
1811 callout_handle_state->on_completion_ = [call_back]() {
1824 typedef function<void()> CallBack;
1825 boost::shared_ptr<CallBack> call_back = boost::make_shared<CallBack>(
1827 query, rsp, ctx->subnet_));
1828 callout_handle_state->on_completion_ = [call_back]() {
1843 if (allow_answer_park) {
1851 allow_answer_park) {
1853 .arg(query->getLabel());
1864 .arg(query->getLabel());
1886 }
catch (
const std::exception& e) {
1888 .arg(query->getLabel())
1899 query->addPktEvent(
"process_completed");
1905 bool skip_pack =
false;
1921 callout_handle->setArgument(
"query4", query);
1924 callout_handle->setArgument(
"response4", rsp);
1927 callout_handle->setArgument(
"subnet4", subnet);
1940 .arg(query->getLabel());
1947 .arg(rsp->getLabel());
1956 .arg(rsp->getLabel());
1958 }
catch (
const std::exception& e) {
1960 .arg(rsp->getLabel())
1990 callout_handle->setArgument(
"response4", rsp);
2003 .arg(rsp->getLabel());
2007 callout_handle->getArgument(
"response4", rsp);
2011 .arg(rsp->getLabel())
2012 .arg(rsp->getName())
2013 .arg(
static_cast<int>(rsp->getType()))
2014 .arg(rsp->getLocalAddr().isV4Zero() ?
"*" : rsp->getLocalAddr().toText())
2015 .arg(rsp->getLocalPort())
2016 .arg(rsp->getRemoteAddr())
2017 .arg(rsp->getRemotePort())
2018 .arg(rsp->getIface().empty() ?
"to be determined from routing" :
2023 .arg(rsp->getLabel())
2024 .arg(rsp->getName())
2025 .arg(
static_cast<int>(rsp->getType()))
2026 .arg(rsp->toText(
true));
2032 }
catch (
const std::exception& e) {
2034 .arg(rsp->getLabel())
2044 boost::shared_ptr<Option4AddrLst> generated =
2045 boost::dynamic_pointer_cast<Option4AddrLst>(srvid);
2051 if (addrs.size() != 1) {
2053 <<
"Expected to contain a single IPv4 address.");
2056 return (addrs[0].toText());
2074 if (local_addr.
isV4Bcast() || query->isDhcp4o6()) {
2080 opt_srvid->writeAddress(local_addr);
2098 if (host && !host->getCfgOption4()->empty()) {
2099 co_list.push_back(host->getCfgOption4());
2106 addr = resp->getYiaddr();
2110 if (pool && !pool->getCfgOption()->empty()) {
2111 co_list.push_back(pool->getCfgOption());
2116 if (!subnet->getCfgOption()->empty()) {
2117 co_list.push_back(subnet->getCfgOption());
2122 subnet->getSharedNetwork(network);
2123 if (network && !network->getCfgOption()->empty()) {
2124 co_list.push_back(network->getCfgOption());
2129 for (
auto const& cclass : classes) {
2132 getClientClassDictionary()->findClass(cclass);
2144 if (ccdef->getCfgOption()->empty()) {
2149 co_list.push_back(ccdef->getCfgOption());
2173 if (co_list.empty()) {
2179 set<uint8_t> requested_opts;
2188 for (uint16_t code : option_prl->getValues()) {
2189 static_cast<void>(requested_opts.insert(code));
2193 std::set<uint8_t> cancelled_opts;
2194 const auto& cclasses = query->getClasses();
2198 for (
auto const& copts : co_list) {
2206 BOOST_FOREACH(
auto const& desc, prange) {
2209 uint8_t code =
static_cast<uint8_t
>(desc.option_->getType());
2210 static_cast<void>(requested_opts.insert(code));
2216 BOOST_FOREACH(
auto const& desc, crange) {
2219 uint8_t code =
static_cast<uint8_t
>(desc.option_->getType());
2220 static_cast<void>(cancelled_opts.insert(code));
2227 for (uint8_t opt : requested_opts) {
2228 if (cancelled_opts.count(opt) > 0) {
2236 if (!resp->getOption(opt)) {
2238 for (
auto const& copts : co_list) {
2243 resp->addOption(desc.
option_);
2256 set<uint32_t> vendor_ids;
2260 vendor_opts = boost::dynamic_pointer_cast<OptionVendorClass>(opt.second);
2262 uint32_t vendor_id = vendor_opts->getVendorId();
2263 static_cast<void>(vendor_ids.insert(vendor_id));
2267 for (
auto const& copts : co_list) {
2270 if (!desc.option_ || !desc.allowedForClientClasses(cclasses)) {
2274 boost::dynamic_pointer_cast<OptionVendorClass>(desc.option_);
2279 uint32_t vendor_id = vendor_opts->getVendorId();
2280 if (vendor_ids.count(vendor_id) > 0) {
2284 resp->Pkt::addOption(desc.option_);
2285 static_cast<void>(vendor_ids.insert(vendor_id));
2294 set<uint32_t> vendor_ids;
2298 vendor_opts = boost::dynamic_pointer_cast<OptionVendor>(opt.second);
2300 uint32_t vendor_id = vendor_opts->getVendorId();
2301 static_cast<void>(vendor_ids.insert(vendor_id));
2305 for (
auto const& copts : co_list) {
2308 if (!desc.option_ || !desc.allowedForClientClasses(cclasses)) {
2312 boost::dynamic_pointer_cast<OptionVendor>(desc.option_);
2317 uint32_t vendor_id = vendor_opts->getVendorId();
2318 if (vendor_ids.count(vendor_id) > 0) {
2324 resp->Pkt::addOption(vendor_opts);
2325 static_cast<void>(vendor_ids.insert(vendor_id));
2345 if (!subnet || co_list.empty()) {
2351 set<uint32_t> vendor_ids;
2355 map<uint32_t, OptionVendorPtr> vendor_rsps;
2358 vendor_rsp = boost::dynamic_pointer_cast<OptionVendor>(opt.second);
2360 uint32_t vendor_id = vendor_rsp->getVendorId();
2361 vendor_rsps[vendor_id] = vendor_rsp;
2362 static_cast<void>(vendor_ids.insert(vendor_id));
2368 map<uint32_t, OptionVendorPtr> vendor_reqs;
2371 vendor_req = boost::dynamic_pointer_cast<OptionVendor>(opt.second);
2373 uint32_t vendor_id = vendor_req->getVendorId();
2374 vendor_reqs[vendor_id] = vendor_req;
2375 static_cast<void>(vendor_ids.insert(vendor_id));
2383 vendor_class = boost::dynamic_pointer_cast<OptionVendorClass>(opt.second);
2385 uint32_t vendor_id = vendor_class->getVendorId();
2386 static_cast<void>(vendor_ids.insert(vendor_id));
2392 if (vendor_ids.empty()) {
2396 map<uint32_t, set<uint8_t> > requested_opts;
2410 oro = boost::dynamic_pointer_cast<OptionUint8Array>(oro_generic);
2413 set<uint8_t> oro_req_opts;
2414 for (uint8_t code : oro->getValues()) {
2415 static_cast<void>(oro_req_opts.insert(code));
2421 const auto& cclasses = query->getClasses();
2422 for (uint32_t vendor_id : vendor_ids) {
2424 std::set<uint8_t> cancelled_opts;
2428 for (
auto const& copts : co_list) {
2437 BOOST_FOREACH(
auto const& desc, prange) {
2440 uint8_t code =
static_cast<uint8_t
>(desc.option_->getType());
2441 static_cast<void>(requested_opts[vendor_id].insert(code));
2448 BOOST_FOREACH(
auto const& desc, crange) {
2451 uint8_t code =
static_cast<uint8_t
>(desc.option_->getType());
2452 static_cast<void>(cancelled_opts.insert(code));
2462 if (requested_opts[vendor_id].empty()) {
2470 if (vendor_rsps.count(vendor_id) > 0) {
2471 vendor_rsp = vendor_rsps[vendor_id];
2479 for (uint8_t opt : requested_opts[vendor_id]) {
2480 if (cancelled_opts.count(opt) > 0) {
2483 if (!vendor_rsp->getOption(opt)) {
2484 for (
auto const& copts : co_list) {
2488 vendor_rsp->addOption(desc.
option_);
2498 if (added && (vendor_rsps.count(vendor_id) == 0)) {
2499 resp->Pkt::addOption(vendor_rsp);
2508 static const std::vector<uint16_t> required_options = {
2522 if (co_list.empty()) {
2527 const auto& cclasses = ex.
getQuery()->getClasses();
2531 for (
auto const& required : required_options) {
2532 OptionPtr opt = resp->getOption(required);
2535 for (
auto const& copts : co_list) {
2537 required, cclasses);
2539 resp->addOption(desc.
option_);
2559 .arg(query->getLabel());
2560 processClientFqdnOption(ex);
2565 .arg(query->getLabel());
2566 processHostnameOption(ex);
2572 std::string hostname;
2573 bool fqdn_fwd =
false;
2574 bool fqdn_rev =
false;
2577 fqdn = boost::dynamic_pointer_cast<Option4ClientFqdn>(resp->getOption(
DHO_FQDN));
2579 hostname = fqdn->getDomainName();
2582 opt_hostname = boost::dynamic_pointer_cast<OptionString>
2586 hostname = opt_hostname->getValue();
2591 if (hostname ==
".") {
2597 if (ex.
getContext()->getDdnsParams()->getEnableUpdates()) {
2617 callout_handle->setArgument(
"query4", query);
2618 callout_handle->setArgument(
"response4", resp);
2619 callout_handle->setArgument(
"subnet4", subnet);
2620 callout_handle->setArgument(
"hostname", hostname);
2621 callout_handle->setArgument(
"fwd-update", fqdn_fwd);
2622 callout_handle->setArgument(
"rev-update", fqdn_rev);
2623 callout_handle->setArgument(
"ddns-params", ex.
getContext()->getDdnsParams());
2629 string hook_hostname;
2630 bool hook_fqdn_fwd =
false;
2631 bool hook_fqdn_rev =
false;
2632 callout_handle->getArgument(
"hostname", hook_hostname);
2633 callout_handle->getArgument(
"fwd-update", hook_fqdn_fwd);
2634 callout_handle->getArgument(
"rev-update", hook_fqdn_rev);
2638 if ((hostname != hook_hostname) || (fqdn_fwd != hook_fqdn_fwd) ||
2639 (fqdn_rev != hook_fqdn_rev)) {
2641 .arg(hostname).arg(hook_hostname).arg(fqdn_fwd).arg(hook_fqdn_fwd)
2642 .arg(fqdn_rev).arg(hook_fqdn_rev);
2643 hostname = hook_hostname;
2644 fqdn_fwd = hook_fqdn_fwd;
2645 fqdn_rev = hook_fqdn_rev;
2649 OptionStringPtr hostname_opt = boost::dynamic_pointer_cast<OptionString>
2652 hostname_opt->setValue(hook_hostname);
2657 fqdn = boost::dynamic_pointer_cast<Option4ClientFqdn>(resp->getOption(
DHO_FQDN));
2669 ctx->fwd_dns_update_ = fqdn_fwd;
2670 ctx->rev_dns_update_ = fqdn_rev;
2671 ctx->hostname_ = hostname;
2696 .arg(fqdn->toText());
2712 !ex.
getContext()->currentHost()->getHostname().empty()) {
2738 .arg(fqdn_resp->
toText());
2743Dhcpv4Srv::processHostnameOption(Dhcpv4Exchange& ex) {
2748 OptionStringPtr opt_hostname = boost::dynamic_pointer_cast<OptionString>
2754 .arg(opt_hostname->getValue());
2762 if (ctx->currentHost() && !ctx->currentHost()->getHostname().empty()) {
2764 std::string hostname = d2_mgr.
qualifyName(ctx->currentHost()->getHostname(),
2767 boost::algorithm::to_lower(hostname);
2785 ex.
getContext()->getDdnsParams()->getReplaceClientNameMode();
2788 if (!opt_hostname) {
2808 .arg(opt_hostname->getValue());
2811 unsigned int label_count;
2817 }
catch (
const std::exception& exc) {
2828 if (label_count == 0) {
2846 || label_count < 2) {
2860 ex.
getContext()->getDdnsParams()->getHostnameSanitizer();
2863 hostname = sanitizer->scrub(hostname);
2867 boost::algorithm::to_lower(hostname);
2869 if (label_count == 2) {
2877 opt_hostname_resp.reset(
2888 .arg(opt_hostname_resp->getValue());
2898 "NULL lease specified when creating NameChangeRequest");
2906 if ((lease->reuseable_valid_lft_ == 0) &&
2908 !lease->hasIdenticalFqdn(*old_lease))) {
2926 while (current_subnet) {
2932 subnet = current_subnet;
2936 current_subnet = current_subnet->getNextSubnet(subnet, client_classes);
2940 subnet->getSharedNetwork(network);
2972 bool fake_allocation = (query->getType() ==
DHCPDISCOVER);
2979 auto const& requested_opts = option_prl->getValues();
2980 if ((std::find(requested_opts.cbegin(), requested_opts.cend(),
2984 ctx->subnet_ = subnet;
2986 if (!fake_allocation) {
2987 resp->setCiaddr(query->getCiaddr());
3004 if (opt_requested_address) {
3005 hint = opt_requested_address->readAddress();
3007 }
else if (!query->getCiaddr().isV4Zero()) {
3008 hint = query->getCiaddr();
3015 auto authoritative =
false;
3021 auto init_reboot = (!fake_allocation && !opt_serverid && opt_requested_address);
3025 .arg(query->getLabel())
3030 authoritative = subnet->getAuthoritative();
3036 authoritative = flag->boolValue();
3039 }
else if (fake_allocation) {
3041 .arg(query->getLabel())
3045 .arg(query->getLabel())
3059 if (!fake_allocation && !opt_serverid && !opt_requested_address
3060 && !query->getCiaddr().isV4Zero() && query->getLocalAddr().isV4Bcast()) {
3065 if (!init_reboot || authoritative) {
3068 .arg(query->getLabel())
3069 .arg(query->getRemoteAddr().toText())
3070 .arg(query->getName());
3089 auto const& classes = query->getClasses();
3099 if (original_subnet && client_id) {
3103 if (!leases_client_id.empty()) {
3109 for (
auto const& l : leases_client_id) {
3110 if (l->subnet_id_ == s->getID()) {
3120 s = s->getNextSubnet(original_subnet, classes);
3128 if (original_subnet && !lease && hwaddr) {
3132 if (!leases_hwaddr.empty()) {
3137 for (
auto const& l : leases_hwaddr) {
3138 if (l->subnet_id_ == s->getID()) {
3148 s = s->getNextSubnet(original_subnet, classes);
3157 bool known_client = lease && lease->belongsToClient(hwaddr, client_id);
3158 if (!authoritative && !known_client) {
3161 .arg(query->getLabel())
3170 if ((known_client && (lease->addr_ != hint)) ||
3171 (!known_client && authoritative) ||
3172 (!original_subnet)) {
3175 .arg(query->getLabel())
3187 ctx->requested_address_ = hint;
3188 ctx->fake_allocation_ = fake_allocation;
3189 ctx->callout_handle_ = callout_handle;
3203 bool reprocess_client_name =
false;
3207 auto ddns_params = ex.
getContext()->getDdnsParams();
3208 auto pool = ddns_params->setPoolFromAddress(lease->addr_);
3210 reprocess_client_name = pool->hasDdnsParameters();
3216 if (subnet && ctx->subnet_ && subnet->getID() != ctx->subnet_->getID()) {
3225 subnet->getSharedNetwork(network);
3227 .arg(query->getLabel())
3228 .arg(subnet->toText())
3229 .arg(ctx->subnet_->toText())
3230 .arg(network ? network->getName() :
"<no network?>");
3232 subnet = ctx->subnet_;
3234 reprocess_client_name =
true;
3240 bool client_name_changed =
false;
3242 if (reprocess_client_name) {
3247 ctx->hostname_ =
"";
3248 ctx->fwd_dns_update_ =
false;
3249 ctx->rev_dns_update_ =
false;
3256 if ((lease->hostname_ != ctx->hostname_) ||
3257 (lease->fqdn_fwd_ != ctx->fwd_dns_update_) ||
3258 (lease->fqdn_rev_ != ctx->rev_dns_update_)) {
3259 lease->hostname_ = ctx->hostname_;
3260 lease->fqdn_fwd_ = ctx->fwd_dns_update_;
3261 lease->fqdn_rev_ = ctx->rev_dns_update_;
3262 client_name_changed =
true;
3269 if (fake_allocation) {
3271 .arg(query->getLabel())
3272 .arg(lease->addr_.toText());
3275 .arg(query->getLabel())
3276 .arg(lease->addr_.toText())
3284 if (!ctx->subnet_->getMatchClientId()) {
3286 .arg(ctx->query_->getLabel())
3287 .arg(ctx->subnet_->getID());
3290 resp->setYiaddr(lease->addr_);
3296 if (!fake_allocation) {
3301 resp->setCiaddr(query->getCiaddr());
3310 if (lease->reuseable_valid_lft_ > 0) {
3311 lease->valid_lft_ = lease->reuseable_valid_lft_;
3313 .arg(query->getLabel())
3314 .arg(lease->addr_.toText())
3331 resp->addOption(opt);
3334 resp->addOption(getNetmaskOption(subnet));
3340 if (!fake_allocation) {
3346 .arg(query->getLabel())
3354 if (ctx->unknown_requested_addr_) {
3366 s = s->getNextSubnet(original_subnet);
3374 .arg(query->getLabel())
3375 .arg(query->getCiaddr().toText())
3376 .arg(opt_requested_address ?
3377 opt_requested_address->readAddress().toText() :
"(no address)");
3385 .arg(query->getLabel())
3386 .arg(query->getCiaddr().toText())
3387 .arg(opt_requested_address ?
3388 opt_requested_address->readAddress().toText() :
"(no address)");
3400 const Pkt4Ptr& query,
const Pkt4Ptr& resp,
bool client_name_changed) {
3409 opt_hostname = boost::dynamic_pointer_cast<OptionString>(resp->getOption(
DHO_HOST_NAME));
3410 if (!opt_hostname) {
3417 if (lease->hostname_.empty()) {
3424 .
generateFqdn(lease->addr_, *(ctx->getDdnsParams()),
static_cast<bool>(fqdn));
3427 .arg(query->getLabel())
3428 .arg(lease->hostname_);
3430 client_name_changed =
true;
3433 if (client_name_changed) {
3439 if (!ctx->fake_allocation_ || (ctx->offer_lft_ > 0)) {
3441 lease->reuseable_valid_lft_ = 0;
3454 opt_hostname->setValue(lease->hostname_);
3458 .arg(query->getLabel())
3459 .arg(lease->hostname_)
3469 uint32_t t2_time = 0;
3471 if (!subnet->getT2().unspecified()) {
3472 t2_time = subnet->getT2();
3473 }
else if (subnet->getCalculateTeeTimes()) {
3475 t2_time =
static_cast<uint32_t
>(round(subnet->getT2Percent() * (lease->valid_lft_)));
3480 uint32_t timer_ceiling = lease->valid_lft_;
3481 if (t2_time > 0 && t2_time < timer_ceiling) {
3483 resp->addOption(t2);
3485 timer_ceiling = t2_time;
3488 uint32_t t1_time = 0;
3490 if (!subnet->getT1().unspecified()) {
3491 t1_time = subnet->getT1();
3492 }
else if (subnet->getCalculateTeeTimes()) {
3494 t1_time =
static_cast<uint32_t
>(round(subnet->getT1Percent() * (lease->valid_lft_)));
3499 if (t1_time > 0 && t1_time < timer_ceiling) {
3501 resp->addOption(t1);
3513 return (query->getRemotePort());
3541 }
else if (((query->getType() ==
DHCPINFORM) &&
3542 ((!query->getCiaddr().isV4Zero()) ||
3543 (!query->isRelayed() && !query->getRemoteAddr().isV4Zero()))) ||
3544 ((query->getType() !=
DHCPINFORM) && !query->isRelayed())) {
3545 response->setRemotePort(DHCP4_CLIENT_PORT);
3550 response->setRemotePort(relay_port ? relay_port : DHCP4_SERVER_PORT);
3554 if (query->isRelayed() &&
3560 response->resetIndex();
3562 response->setIface(query->getIface());
3566 IOAddress local_addr = query->getLocalAddr();
3575 if (local_addr.
isV4Bcast() || query->isDhcp4o6()) {
3586 response->setLocalAddr(local_addr);
3595 response->setIndex(query->getIndex());
3596 response->setIface(query->getIface());
3602 response->setLocalPort(DHCP4_SERVER_PORT);
3614 if (query->isDhcp4o6()) {
3615 response->setRemoteAddr(query->getRemoteAddr());
3627 if (!query->getCiaddr().isV4Zero()) {
3628 response->setRemoteAddr(query->getCiaddr());
3635 }
else if (query->isRelayed()) {
3636 response->setRemoteAddr(query->getGiaddr());
3637 response->setFlags(response->getFlags() | BOOTP_BROADCAST);
3642 response->setRemoteAddr(query->getRemoteAddr());
3649 if (query->isRelayed()) {
3658 query->getCiaddr().isV4Zero()) {
3659 response->setFlags(BOOTP_BROADCAST);
3661 response->setRemoteAddr(query->getGiaddr());
3665 }
else if (!query->getCiaddr().isV4Zero()) {
3666 response->setRemoteAddr(query->getCiaddr());
3671 }
else if (response->getType() ==
DHCPNAK) {
3675 }
else if (!response->getYiaddr().isV4Zero()) {
3690 response->setRemoteAddr(response ->getYiaddr());
3698 response->setRemoteAddr(query->getRemoteAddr());
3703 response->setRemoteAddr(query->getRemoteAddr());
3715 IOAddress subnet_next_server = subnet->getSiaddr();
3716 if (!subnet_next_server.
isV4Zero()) {
3717 response->setSiaddr(subnet_next_server);
3720 const string& sname = subnet->getSname();
3721 if (!sname.empty()) {
3727 response->setSname(
reinterpret_cast<const uint8_t*
>(sname.c_str()),
3731 const string& filename = subnet->getFilename();
3732 if (!filename.empty()) {
3738 response->setFile(
reinterpret_cast<const uint8_t*
>(filename.c_str()),
3746 if (!classes.
empty()) {
3759 size_t found_cnt = 0;
3760 for (
auto const& name : classes) {
3762 if (found_cnt >= 3) {
3776 next_server = cl->getNextServer();
3778 response->setSiaddr(next_server);
3783 if (sname.empty()) {
3784 sname = cl->getSname();
3785 if (!sname.empty()) {
3791 response->setSname(
reinterpret_cast<const uint8_t*
>(sname.c_str()),
3797 if (filename.empty()) {
3798 filename = cl->getFilename();
3799 if (!filename.empty()) {
3805 response->setFile(
reinterpret_cast<const uint8_t*
>(filename.c_str()),
3828tuple<bool, uint32_t>
3829Dhcpv4Srv::parkingLimitExceeded(
string const& hook_label) {
3831 uint32_t parked_packet_limit(0);
3835 parked_packet_limit = ppl->intValue();
3838 if (parked_packet_limit) {
3842 if (parking_lot && parked_packet_limit <= parking_lot->size()) {
3843 return make_tuple(
true, parked_packet_limit);
3846 return make_tuple(
false, parked_packet_limit);
3884 .arg(discover->getLabel())
3885 .arg(discover->getName())
3886 .arg(discover->getClasses().toText());
3895 .arg(discover->getLabel());
3954 }
else if (request->inClass(
"BOOTP")) {
3956 response->addClass(
"BOOTP");
3970 .arg(request->getLabel())
3971 .arg(request->getName())
3972 .arg(request->getClasses().toText());
3981 .arg(request->getLabel());
4034 .arg(release->getLabel())
4035 .arg(release->getCiaddr().toText());
4039 if (!lease->belongsToClient(release->getHWAddr(), client_id)) {
4041 .arg(release->getLabel())
4042 .arg(release->getCiaddr().toText());
4062 callout_handle->setArgument(
"query4", release);
4065 callout_handle->setArgument(
"lease4", lease);
4079 .arg(release->getLabel());
4087 bool success =
false;
4088 bool expired =
false;
4092 if (expiration_cfg->getFlushReclaimedTimerWaitTime() &&
4093 expiration_cfg->getHoldReclaimedTime() &&
4096 lease->valid_lft_ = 0;
4112 context->old_lease_ = lease;
4116 .arg(release->getLabel())
4117 .arg(lease->addr_.toText());
4121 .arg(release->getLabel())
4122 .arg(lease->addr_.toText());
4125 .arg(release->getLabel())
4126 .arg(lease->addr_.toText());
4137 static_cast<int64_t
>(-1));
4141 auto const& pool = subnet->getPool(
Lease::TYPE_V4, lease->addr_,
false);
4146 static_cast<int64_t
>(-1));
4153 .arg(release->getLabel())
4154 .arg(lease->addr_.toText());
4159 .arg(release->getLabel())
4160 .arg(release->getCiaddr())
4173 if (!opt_requested_address) {
4176 " in DHCPDECLINE sent from " << decline->getLabel());
4178 IOAddress addr(opt_requested_address->readAddress());
4196 .arg(addr.
toText()).arg(decline->getLabel());
4204 client_id.reset(
new ClientId(opt_clientid->getData()));
4213 !lease->belongsToClient(decline->getHWAddr(), client_id)) {
4216 string client_hw = decline->getHWAddr() ?
4217 decline->getHWAddr()->toText(
false) :
"(none)";
4218 string lease_hw = lease->hwaddr_ ?
4219 lease->hwaddr_->toText(
false) :
"(none)";
4222 string client_id_txt = client_id ? client_id->toText() :
"(none)";
4223 string lease_id_txt = lease->client_id_ ?
4224 lease->client_id_->toText() :
"(none)";
4228 .arg(addr.
toText()).arg(decline->getLabel())
4229 .arg(client_hw).arg(lease_hw).arg(client_id_txt).arg(lease_id_txt);
4259 callout_handle->setArgument(
"query4", decline);
4262 callout_handle->setArgument(
"lease4", lease);
4273 .arg(decline->getLabel()).arg(lease->addr_.toText());
4278 Lease4Ptr old_values = boost::make_shared<Lease4>(*lease);
4292 .arg(decline->getLabel())
4293 .arg(lease->addr_.toText())
4307 static_cast<int64_t
>(1));
4311 auto const& pool = subnet->getPool(
Lease::TYPE_V4, lease->addr_,
false);
4316 static_cast<int64_t
>(1));
4333 context->new_lease_ = lease;
4336 .arg(decline->getLabel()).arg(lease->valid_lft_);
4343 .arg(query->getLabel())
4344 .arg(lease->addr_.toText())
4345 .arg(lease->valid_lft_);
4353 .arg(query->getLabel())
4354 .arg(lease->addr_.toText());
4370 lease_exists =
false;
4374 .arg(query->getLabel())
4375 .arg(lease->addr_.toText());
4380 if (!lease_exists) {
4385 .arg(query->getLabel())
4386 .arg(lease->addr_.toText());
4403 static_cast<int64_t
>(1));
4405 if (!lease_exists) {
4408 static_cast<int64_t
>(1));
4413 auto const& pool = subnet->getPool(
Lease::TYPE_V4, lease->addr_,
false);
4418 static_cast<int64_t
>(1));
4419 if (!lease_exists) {
4423 static_cast<int64_t
>(1));
4430 if (!lease_exists) {
4444 callout_handle->setArgument(
"query4", query);
4447 callout_handle->setArgument(
"lease4", lease);
4485 .arg(inform->getLabel())
4486 .arg(inform->getName())
4487 .arg(inform->getClasses().toText());
4504 if (ack->getRemoteAddr() != inform->getGiaddr()) {
4506 .arg(inform->getLabel())
4507 .arg(ack->getRemoteAddr())
4508 .arg(ack->getIface());
4522 if (query->getCiaddr().isV4Zero() || !query->getGiaddr().isV4Zero()) {
4539 if (query->inClass(
"STASH_AGENT_OPTIONS")) {
4543 if (!lease || lease->expired()) {
4547 if (!user_context || (user_context->getType() !=
Element::map)) {
4555 if (!relay_agent_info) {
4560 relay_agent_info = relay_agent_info->get(
"sub-options");
4561 if (!relay_agent_info) {
4572 client_id.reset(
new ClientId(opt_clientid->getData()));
4574 if (!lease->belongsToClient(query->getHWAddr(), client_id)) {
4578 string rai_hex = relay_agent_info->stringValue();
4579 if (rai_hex.empty()) {
4582 vector<uint8_t> rai_data;
4587 if (!rai || rai->getOptions().empty()) {
4594 query->addOption(rai);
4595 query->addClass(
"STASH_AGENT_OPTIONS");
4598 .arg(query->getLabel())
4599 .arg(query->getCiaddr())
4600 .arg(rai->toText());
4614 .arg(query->getLabel())
4615 .arg(query->getIface());
4623 .arg(query->getLabel())
4624 .arg(query->getIface());
4634 if (pkt->isRelayed()) {
4639 if (pkt->isDhcp4o6()) {
4648 if (pkt->getRemoteAddr().isV4Zero() &&
4649 pkt->getCiaddr().isV4Zero()) {
4669 type = query->getType();
4673 .arg(query->getLabel())
4674 .arg(query->getIface());
4698 .arg(query->getLabel());
4705 .arg(query->getLabel())
4710 .arg(query->getLabel())
4737 boost::dynamic_pointer_cast<OptionCustom>(option);
4740 if (!option_custom) {
4748 if (option_custom->getDataFieldsNum() != 1) {
4754 IOAddress server_id = option_custom->readAddress();
4755 if (!server_id.
isV4()) {
4764 if (rai_suboption && (server_id.
toBytes() == rai_suboption->toBinary())) {
4771 if (cfg->getIgnoreServerIdentifier()) {
4809 if (cfg_subnets->hasSubnetWithServerId(server_id)) {
4816 if (cfg_networks->hasNetworkWithServerId(server_id)) {
4822 for (
auto const& cclass : classes) {
4825 getClientClassDictionary()->findClass(cclass);
4830 if (ccdef->getCfgOption()->empty()) {
4835 OptionCustomPtr context_opt_server_id = boost::dynamic_pointer_cast<OptionCustom>
4837 if (context_opt_server_id && (context_opt_server_id->readAddress() == server_id)) {
4845 OptionCustomPtr opt_server_id = boost::dynamic_pointer_cast<OptionCustom>
4848 return (opt_server_id && (opt_server_id->readAddress() == server_id));
4853 switch (query->getType()) {
4888 <<
" received in message "
4889 << query->getName());
4896 " received in message "
4897 << query->getName());
4907 if (query->getHWAddr() && !query->getHWAddr()->hwaddr_.empty()) {
4916 if (!client_id || client_id->len() == client_id->getHeaderLen()) {
4918 " provided in message "
4919 << query->getName());
4940 addr = resp->getYiaddr();
4945 const ClientClasses& pool_to_add = pool->getAdditionalClasses();
4946 for (
auto const& cclass : pool_to_add) {
4953 const ClientClasses& to_add = subnet->getAdditionalClasses();
4954 for (
auto const& cclass : to_add) {
4960 subnet->getSharedNetwork(network);
4962 const ClientClasses& net_to_add = network->getAdditionalClasses();
4963 for (
auto const& cclass : net_to_add) {
4973 for (
auto const& cclass : classes) {
4988 query->addClass(cclass);
4996 .arg(query->getLabel())
4998 .arg(status ?
"true" :
"false");
5001 query->addClass(cclass);
5005 .arg(query->getLabel())
5015 for (
auto const& code : query->getDeferredOptions()) {
5019 for (
auto const& cclass : classes) {
5023 getClientClassDictionary()->findClass(cclass);
5029 if (!ccdef->getCfgOptionDef()) {
5059 .arg(query->getLabel())
5068 opt = def->optionFactory(
Option::V4, code, buf);
5069 }
catch (
const std::exception& e) {
5073 .arg(query->getLabel())
5078 while (query->delOption(code)) {
5082 query->addOption(opt);
5094 this, ph::_1, ph::_2));
5113 arg(result).arg((ncr ? ncr->toText() :
" NULL "));
5122 std::stringstream tmp;
5126 tmp <<
" (" << EXTENDED_VERSION <<
")" << endl;
5127 tmp <<
"premium: " << PREMIUM_EXTENDED_VERSION << endl;
5128 tmp <<
"linked with:" << endl;
5133 tmp << endl <<
"lease backends:";
5135 tmp << endl <<
"- " <<
version;
5140 tmp << endl <<
"host backends:";
5142 tmp << endl <<
"- " <<
version;
5147 tmp << endl <<
"forensic backends:";
5149 tmp << endl <<
"- " <<
version;
5162 string stat_name =
"pkt4-unknown-received";
5164 switch (query->getType()) {
5166 stat_name =
"pkt4-discover-received";
5170 stat_name =
"pkt4-offer-received";
5173 stat_name =
"pkt4-request-received";
5177 stat_name =
"pkt4-ack-received";
5181 stat_name =
"pkt4-nak-received";
5184 stat_name =
"pkt4-release-received";
5187 stat_name =
"pkt4-decline-received";
5190 stat_name =
"pkt4-inform-received";
5204 static_cast<int64_t
>(1));
5210 static_cast<int64_t
>(1));
5214 switch (response->getType()) {
5216 stat_name =
"pkt4-offer-sent";
5219 stat_name =
"pkt4-ack-sent";
5222 stat_name =
"pkt4-nak-sent";
5230 static_cast<int64_t
>(1));
5234 return (
Hooks.hook_index_buffer4_receive_);
5238 return (
Hooks.hook_index_pkt4_receive_);
5242 return (
Hooks.hook_index_subnet4_select_);
5246 return (
Hooks.hook_index_lease4_release_);
5250 return (
Hooks.hook_index_pkt4_send_);
5254 return (
Hooks.hook_index_buffer4_send_);
5258 return (
Hooks.hook_index_lease4_decline_);
5268 char const*
const rotate(getenv(
"KEA_DHCP4_FUZZING_ROTATE_PORT"));
5272 while (!locker.
lock()) {
5273 this_thread::sleep_for(1s);
5276 port_file.open(
"/tmp/port4.txt", ios::in);
5279 getline(port_file, line);
5291 port_file.open(
"/tmp/port4.txt", ios::out | ios::trunc);
5292 port_file << to_string(port) << endl;
5302 static std::list<std::list<std::string>>
const list({
5303 {
"config-control",
"config-databases",
"[]"},
5304 {
"hooks-libraries",
"[]",
"parameters",
"*"},
5306 {
"hosts-databases",
"[]"},
Defines elements for storing the names of client classes.
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)
static const IOAddress & IPV4_ZERO_ADDRESS()
Returns an address set to all zeros.
bool isV4Zero() const
Convenience function to check if it is an IPv4 zero address.
std::string toText() const
Convert the address to a string.
static const IOAddress & IPV4_BCAST_ADDRESS()
Returns a "255.255.255.255" broadcast address.
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 isV4Bcast() const
Convenience function to check if it is an IPv4 broadcast address.
void clearIOServices()
Clear the list of IOService objects.
static IOServiceMgr & instance()
Access the IOServiceMgr singleton instance.
size_t pollIOServices()
Poll IOService objects.
The IOService class is a wrapper for the ASIO io_context class.
static std::string getVersion()
Get version string.
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.
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.
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 getUpdateDirections(const T &fqdn_resp, bool &forward, bool &reverse)
Get directional update flags based on server FQDN flags.
void stop()
Stop the sender.
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.
void startSender(D2ClientErrorHandler error_handler, const isc::asiolink::IOServicePtr &io_service)
Enables sending NameChangeRequests to kea-dhcp-ddns.
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.
CfgOptionList & getCfgOptionList()
Returns the configured option list (non-const version)
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.
void setIPv6OnlyPreferred(bool ipv6_only_preferred)
Set the IPv6-Only Preferred flag.
Dhcpv4Exchange(const AllocEnginePtr &alloc_engine, const Pkt4Ptr &query, AllocEngine::ClientContext4Ptr &context, const ConstSubnet4Ptr &subnet, bool &drop)
Constructor.
static void classifyPacket(const Pkt4Ptr &pkt)
Assigns incoming packet to zero or more classes.
static void removeDependentEvaluatedClasses(const Pkt4Ptr &query)
Removed evaluated client classes.
bool getIPv6OnlyPreferred() const
Returns the IPv6-Only Preferred flag.
void conditionallySetReservedClientClasses()
Assigns classes retrieved from host reservation database if they haven't been yet set.
void initContext0(const Pkt4Ptr &query, AllocEngine::ClientContext4Ptr ctx)
Initialize client context (first part).
int run()
Main server processing loop.
void declineLease(const Lease4Ptr &lease, const Pkt4Ptr &decline, AllocEngine::ClientContext4Ptr &context)
Marks lease as declined.
void processPacketAndSendResponse(Pkt4Ptr query)
Process a single incoming DHCPv4 packet and sends the response.
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.
static uint16_t checkRelayPort(const Dhcpv4Exchange &ex)
Check if the relay port RAI sub-option was set in the query.
virtual ~Dhcpv4Srv()
Destructor. Used during DHCPv4 service shutdown.
virtual Pkt4Ptr receivePacket(int timeout)
dummy wrapper around IfaceMgr::receive4
bool accept(const Pkt4Ptr &query)
Checks whether received message should be processed or discarded.
void setTeeTimes(const Lease4Ptr &lease, const ConstSubnet4Ptr &subnet, Pkt4Ptr resp)
Adds the T1 and T2 timers to the outbound response as appropriate.
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.
bool use_bcast_
Should broadcast be enabled on sockets (if true).
void runOne()
Main server processing step.
void startD2()
Starts DHCP_DDNS client IO if DDNS updates are enabled.
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.
isc::dhcp::ConstSubnet4Ptr selectSubnet(const Pkt4Ptr &query, bool &drop, bool allow_answer_park=true)
Selects a subnet for a given client's packet.
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.
static int getHookIndexPkt4Receive()
Returns the index for "pkt4_receive" hook point.
void assignLease(Dhcpv4Exchange &ex)
Assigns a lease and appends corresponding options.
void evaluateAdditionalClasses(Dhcpv4Exchange &ex)
Evaluates classes in the additional classes lists.
Pkt4Ptr processDhcp4Query(Pkt4Ptr query, bool allow_answer_park)
Process a single incoming DHCPv4 query.
asiolink::IOServicePtr & getIOService()
Returns pointer to the IO service used by the server.
void setFixedFields(Dhcpv4Exchange &ex)
Sets fixed fields of the outgoing packet.
void appendBasicOptions(Dhcpv4Exchange &ex)
Append basic options if they are not present.
void recoverStashedAgentOption(const Pkt4Ptr &query)
Recover stashed agent options from client address lease.
void processClientName(Dhcpv4Exchange &ex)
Processes Client FQDN and Hostname Options sent by a client.
boost::shared_ptr< AllocEngine > alloc_engine_
Allocation Engine.
void serverDecline(hooks::CalloutHandlePtr &callout_handle, Pkt4Ptr &query, Lease4Ptr lease, bool lease_exists)
Renders a lease declined after the server has detected, via ping-check or other means,...
Pkt4Ptr processInform(Pkt4Ptr &inform, AllocEngine::ClientContext4Ptr &context)
Processes incoming DHCPINFORM messages.
uint16_t client_port_
UDP port number to which server sends all responses.
void serverDeclineNoThrow(hooks::CalloutHandlePtr &callout_handle, Pkt4Ptr &query, Lease4Ptr lease, bool lease_exists)
Exception safe wrapper around serverDecline()
void processPacketPktSend(hooks::CalloutHandlePtr &callout_handle, Pkt4Ptr &query, Pkt4Ptr &rsp, ConstSubnet4Ptr &subnet)
Executes pkt4_send callout.
void processPacketAndSendResponseNoThrow(Pkt4Ptr query)
Process a single incoming DHCPv4 packet and sends the response.
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.
void processLocalizedQuery4AndSendResponse(Pkt4Ptr query, AllocEngine::ClientContext4Ptr &ctx, bool allow_answer_park)
Process a localized incoming DHCPv4 query.
static std::string getVersion(bool extended)
returns Kea version on stdout and exit.
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.
void sendResponseNoThrow(hooks::CalloutHandlePtr &callout_handle, Pkt4Ptr &query, Pkt4Ptr &rsp, ConstSubnet4Ptr &subnet)
Process an unparked DHCPv4 packet and sends the response.
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 processDhcp4QueryAndSendResponse(Pkt4Ptr query, bool allow_answer_park)
Process a single incoming DHCPv4 query.
bool getSendResponsesToSource() const
Returns value of the test_send_responses_to_source_ flag.
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.
uint16_t getServerPort() const
Get UDP port on which server should listen.
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.
static void sanityCheck(const Pkt4Ptr &query)
Verifies if specified packet meets RFC requirements.
bool acceptMessageType(const Pkt4Ptr &query) const
Check if received message type is valid for the server to process.
void discardPackets()
Discards parked packets Clears the packet parking lots of all packets.
isc::dhcp::ConstSubnet4Ptr selectSubnet4o6(const Pkt4Ptr &query, bool &drop, bool allow_answer_park=true)
Selects a subnet for a given client's DHCP4o6 packet.
static int getHookIndexLease4Decline()
Returns the index for "lease4_decline" hook point.
void processRelease(Pkt4Ptr &release, AllocEngine::ClientContext4Ptr &context)
Processes incoming DHCPRELEASE messages.
bool acceptDirectRequest(const Pkt4Ptr &query)
Check if a message sent by directly connected client should be accepted or discarded.
CBControlDHCPv4Ptr cb_control_
Controls access to the configuration backends.
RequirementLevel
defines if certain option may, must or must not appear
Pkt4Ptr processPacket(Pkt4Ptr query, bool allow_answer_park=true)
Process a single incoming DHCPv4 packet.
void processPacketBufferSend(hooks::CalloutHandlePtr &callout_handle, Pkt4Ptr &rsp)
Executes buffer4_send callout and sends the response.
bool assignZero(ConstSubnet4Ptr &subnet, const ClientClasses &client_classes)
Assign the 0.0.0.0 address to an IPv6-Only client.
void deferredUnpack(Pkt4Ptr &query)
Perform deferred option unpacking.
Pkt4Ptr processLocalizedQuery4(AllocEngine::ClientContext4Ptr &ctx, bool allow_answer_park)
Process a localized incoming DHCPv4 query.
static std::list< std::string > getDBVersions()
Return extended version info for registered backends.
static void create()
Creates new instance of the HostMgr.
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 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 std::list< std::string > getDBVersions()
Return extended version info for registered backends.
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 addLease(const Lease4Ptr &lease)=0
Adds an IPv4 lease.
virtual bool deleteLease(const Lease4Ptr &lease)=0
Deletes an IPv4 lease.
virtual void updateLease4(const Lease4Ptr &lease4)=0
Updates IPv4 lease.
static std::list< std::string > getDBVersions()
Return extended version info for registered backends.
static OptionDefinitionPtr getOptionDef(const std::string &space, const uint16_t code)
Return the first option definition matching a particular option code.
static const OptionDefinition & DHO_DHCP_SERVER_IDENTIFIER_DEF()
Get definition of DHO_DHCP_SERVER_IDENTIFIER option.
static const OptionDefinition & DHO_DHCP_AGENT_OPTIONS_DEF()
Get definition of DHO_DHCP_AGENT_OPTIONS option.
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.
Controls the DHCP service enabling status.
Attempt to update lease that was not there.
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.
Base class representing a DHCP option definition.
OptionPtr option_
Option instance.
bool allowedForClientClasses(const ClientClasses &cclasses) const
Validates an OptionDescriptor's client-classes against a list of classes.
Forward declaration to OptionInt.
This class represents vendor-specific information option.
static const size_t OPTION4_HDR_LEN
length of the usual DHCPv4 option header (there are exceptions)
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....
Resource race avoidance RAII handler for DHCPv4.
bool tryLock4(const asiolink::IOAddress &addr)
Tries to acquires a resource.
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.
@ NEXT_STEP_PARK
park the packet
@ NEXT_STEP_CONTINUE
continue normally
@ NEXT_STEP_DROP
drop the packet
@ NEXT_STEP_SKIP
skip the next processing step
static int registerHook(const std::string &name)
Register Hook.
static bool calloutsPresent(int index)
Are callouts present?
static std::vector< std::string > getLibraryNames()
Return list of loaded libraries.
static bool unloadLibraries()
Unload libraries.
static void park(const std::string &hook_name, T parked_object, std::function< void()> unpark_callback)
Park an object (packet).
static void callCallouts(int index, CalloutHandle &handle)
Calls the callouts for a given hook.
static void prepareUnloadLibraries()
Prepare the unloading of libraries.
static bool drop(const std::string &hook_name, T parked_object)
Removes parked object without calling a callback.
static void clearParkingLots()
Clears any parking packets.
Wrapper class around callout handle which automatically resets handle's state.
static ServerHooks & getServerHooks()
Return ServerHooks object.
static std::string getVersion()
Version.
File-based Interprocess Sync Class.
Interprocess Sync Locker Class.
bool unlock()
Release the lock.
bool lock()
Acquire the lock (blocks if something else has acquired a lock on the same task name)
int getExitValue()
Fetches the exit value.
Statistics Manager class.
static StatsMgr & instance()
Statistics Manager accessor method.
static std::string generateName(const std::string &context, Type index, const std::string &stat_name)
Generates statistic name in a given context.
RAII class creating a critical section.
static MultiThreadingMgr & instance()
Returns a single instance of Multi Threading Manager.
ThreadPool< std::function< void()> > & getThreadPool()
Get the dhcp thread pool.
void apply(bool enabled, uint32_t thread_count, uint32_t queue_size)
Apply the multi-threading related settings.
Defines classes for storing client class definitions.
int version()
returns Kea hooks version.
Defines the D2ClientConfig class.
Defines the D2ClientMgr class.
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
OptionIntArray< uint8_t > OptionUint8Array
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.
int get(CalloutHandle &handle)
The gss-tsig-get command.
When a message is logged with DEBUG severity, the debug level associated with the message is also spe...
#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_HOOK_SUBNET4_SELECT_PARKING_LOT_FULL
const isc::log::MessageID DHCP4_DEFERRED_OPTION_UNPACK_FAIL
const isc::log::MessageID DHCP4_PACKET_DROP_0001
const isc::log::MessageID DHCP4_QUERY_DATA
const isc::log::MessageID DHCP4_NO_LEASE_INIT_REBOOT
const isc::log::MessageID DHCP4_INFORM_DIRECT_REPLY
const isc::log::MessageID DHCP4_SERVER_INITIATED_DECLINE_ADD_FAILED
boost::shared_ptr< Lease4Collection > Lease4CollectionPtr
A shared pointer to the collection of IPv4 leases.
const isc::log::MessageID DHCP4_HOOK_LEASE4_OFFER_ARGUMENT_MISSING
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 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_PROCESS_EXCEPTION_MAIN
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_HOOK_SUBNET4_SELECT_4O6_PARKING_LOT_FULL
const isc::log::MessageID DHCP4_DHCP4O6_SUBNET_SELECTION_FAILED
const isc::log::MessageID DHCP4_RELEASE_FAIL_WRONG_CLIENT
const isc::log::MessageID DHCP4_HOOK_LEASES4_COMMITTED_PARKING_LOT_FULL
const isc::log::MessageID DHCP4_HOOK_BUFFER_RCVD_DROP
boost::shared_ptr< const Subnet4 > ConstSubnet4Ptr
A const pointer to a Subnet4 object.
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_RECOVERED_STASHED_RELAY_AGENT_INFO
const isc::log::MessageID DHCP4_LEASE_REUSE
const isc::log::MessageID DHCP4_HOOK_SUBNET4_SELECT_PARK
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_ADDITIONAL_CLASS_EVAL_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_LEASE_OFFER
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
const isc::log::MessageID DHCP4_SERVER_INITIATED_DECLINE
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_V6_ONLY_PREFERRED_MISSING_IN_ACK
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_SERVER_INITIATED_DECLINE_UPDATE_FAILED
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.
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
const isc::log::MessageID DHCP4_ADDITIONAL_CLASS_NO_TEST
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_PACKET_PROCESS_STD_EXCEPTION_MAIN
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
const isc::log::MessageID DHCP4_V6_ONLY_PREFERRED_MISSING_IN_OFFER
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_REQUEST
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_SERVER_INITIATED_DECLINE_RESOURCE_BUSY
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_HOOK_LEASES4_COMMITTED_PARK
const isc::log::MessageID DHCP4_ADDITIONAL_CLASS_UNDEFINED
const isc::log::MessageID DHCP4_ADDITIONAL_CLASS_EVAL_RESULT
const isc::log::MessageID DHCP4_DHCP4O6_HOOK_SUBNET4_SELECT_SKIP
const isc::log::MessageID DHCP4_PACKET_DROP_0014
std::list< ConstCfgOptionPtr > CfgOptionList
Const pointer list.
const isc::log::MessageID DHCP4_DISCOVER
boost::shared_ptr< const CfgOption > ConstCfgOptionPtr
Const pointer.
const isc::log::MessageID DHCP4_PACKET_NAK_0004
const isc::log::MessageID DHCP4_CLIENT_FQDN_DATA
const isc::log::MessageID DHCP4_PACKET_DROP_0002
isc::log::Logger hooks_logger("hooks")
Hooks Logger.
boost::shared_ptr< CalloutHandle > CalloutHandlePtr
A shared pointer to a CalloutHandle object.
boost::shared_ptr< ParkingLot > ParkingLotPtr
Type of the pointer to the parking lot.
const int DBGLVL_TRACE_BASIC
Trace basic operations.
const int DBGLVL_PKT_HANDLING
This debug level is reserved for logging the details of packet handling, such as dropping the packet ...
std::unique_ptr< StringSanitizer > StringSanitizerPtr
Type representing the pointer to the StringSanitizer.
void decodeFormattedHexString(const string &hex_string, vector< uint8_t > &binary)
Converts a formatted string of hexadecimal digits into a vector.
string trim(const string &input)
Trim leading and trailing spaces.
Defines the logger used by the top-level component of kea-lfc.
This file defines abstract classes for exchanging NameChangeRequests.
This file provides the classes needed to embody, compose, and decompose DNS update requests that are ...
Standard implementation of read-write mutexes with writer preference using C++11 mutex and condition ...
#define DHCP4_OPTION_SPACE
global std option spaces
Context information for the DHCPv4 lease allocation.
static const uint32_t INFINITY_LFT
Infinity (means static, i.e. never expire)
static std::string lifetimeToText(uint32_t lifetime)
Print lifetime.
static const uint32_t STATE_DEFAULT
A lease in the default state.
static const uint32_t STATE_RELEASED
Released lease held in the database for lease affinity.
Subnet selector used to specify parameters used to select a subnet.
asiolink::IOAddress local_address_
Address on which the message was received.
bool dhcp4o6_
Specifies if the packet is DHCP4o6.
asiolink::IOAddress option_select_
RAI link select or subnet select option.
std::string iface_name_
Name of the interface on which the message was received.
asiolink::IOAddress ciaddr_
ciaddr from the client's message.
ClientClasses client_classes_
Classes that the client belongs to.
asiolink::IOAddress remote_address_
Source address of the message.
OptionPtr interface_id_
Interface id option.
asiolink::IOAddress first_relay_linkaddr_
First relay link address.
asiolink::IOAddress giaddr_
giaddr from the client's message.
bool add(const WorkItemPtr &item)
add a work item to the thread pool