8#include <kea_version.h>
66#include <boost/algorithm/string.hpp>
67#include <boost/foreach.hpp>
68#include <boost/range/adaptor/reversed.hpp>
69#include <boost/pointer_cast.hpp>
70#include <boost/shared_ptr.hpp>
88namespace ph = std::placeholders;
94 int hook_index_buffer4_receive_;
95 int hook_index_pkt4_receive_;
96 int hook_index_subnet4_select_;
97 int hook_index_leases4_committed_;
98 int hook_index_lease4_release_;
99 int hook_index_pkt4_send_;
100 int hook_index_buffer4_send_;
101 int hook_index_lease4_decline_;
102 int hook_index_host4_identifier_;
103 int hook_index_ddns4_update_;
104 int hook_index_lease4_offer_;
105 int hook_index_lease4_server_decline_;
126std::set<std::string> dhcp4_statistics = {
128 "pkt4-discover-received",
129 "pkt4-offer-received",
130 "pkt4-request-received",
133 "pkt4-release-received",
134 "pkt4-decline-received",
135 "pkt4-inform-received",
136 "pkt4-unknown-received",
143 "v4-allocation-fail",
144 "v4-allocation-fail-shared-network",
145 "v4-allocation-fail-subnet",
146 "v4-allocation-fail-no-pools",
147 "v4-allocation-fail-classes",
148 "v4-reservation-conflicts",
168 : alloc_engine_(alloc_engine), query_(query), resp_(),
171 if (!alloc_engine_) {
173 " when creating an instance of the Dhcpv4Exchange");
178 " creating an instance of the Dhcpv4Exchange");
187 context_->subnet_ = subnet;
193 if (subnet && !context_->early_global_reservations_lookup_) {
196 context_->clientid_.reset(
new ClientId(opt_clientid->getData()));
202 if (subnet->getReservationsInSubnet() ||
203 subnet->getReservationsGlobal()) {
206 if (!context_->early_global_reservations_lookup_) {
211 alloc_engine->findReservation(*context_);
214 subnet->getSharedNetwork(sn);
224 auto global_host = context_->globalHost();
225 auto current_host = context_->currentHost();
226 if ((!context_->early_global_reservations_lookup_ &&
227 global_host && !global_host->getClientClasses4().empty()) ||
228 (!sn && current_host && !current_host->getClientClasses4().empty())) {
249 if (!context_->hosts_.empty()) {
250 query->addClass(
"KNOWN");
252 .arg(query->getLabel())
255 query->addClass(
"UNKNOWN");
257 .arg(query->getLabel())
266 .arg(query_->getLabel())
270 if (query_->inClass(
"DROP")) {
272 .arg(query_->getHWAddrLabel())
273 .arg(query_->toText());
275 static_cast<int64_t
>(1));
282 uint8_t resp_type = 0;
296 resp_.reset(
new Pkt4(resp_type,
getQuery()->getTransid()));
298 copyDefaultOptions();
312 const Pkt6Ptr& query6 = query->getPkt6();
316 if (!query6->relay_info_.empty()) {
317 resp6->copyRelayInfo(query6);
320 resp6->setIface(query6->getIface());
321 resp6->setIndex(query6->getIndex());
322 resp6->setRemoteAddr(query6->getRemoteAddr());
323 resp6->setRemotePort(query6->getRemotePort());
324 resp_.reset(
new Pkt4o6(resp_, resp6));
328Dhcpv4Exchange::copyDefaultFields() {
329 resp_->setIface(query_->getIface());
330 resp_->setIndex(query_->getIndex());
337 resp_->setCiaddr(query_->getCiaddr());
341 resp_->setHops(query_->getHops());
344 resp_->setHWAddr(query_->getHWAddr());
347 resp_->setGiaddr(query_->getGiaddr());
356 HWAddrPtr src_hw_addr = query_->getLocalHWAddr();
358 resp_->setLocalHWAddr(src_hw_addr);
360 HWAddrPtr dst_hw_addr = query_->getRemoteHWAddr();
362 resp_->setRemoteHWAddr(dst_hw_addr);
366 resp_->setFlags(query_->getFlags());
370Dhcpv4Exchange::copyDefaultOptions() {
375 if (client_id && echo) {
376 resp_->addOption(client_id);
383 resp_->addOption(rai);
396 resp_->addOption(subnet_sel);
407 for (
auto const& id_type : cfg->getIdentifierTypes()) {
410 if (context->hwaddr_ && !context->hwaddr_->hwaddr_.empty()) {
411 context->addHostIdentifier(id_type, context->hwaddr_->hwaddr_);
416 if (context->clientid_) {
417 const std::vector<uint8_t>& vec = context->clientid_->getClientId();
422 if ((vec[0] == CLIENT_ID_OPTION_TYPE_DUID) && (vec.size() > 5)) {
424 context->addHostIdentifier(id_type,
425 std::vector<uint8_t>(vec.begin() + 5,
437 if (circuit_id_opt) {
438 const OptionBuffer& circuit_id_vec = circuit_id_opt->getData();
439 if (!circuit_id_vec.empty()) {
440 context->addHostIdentifier(id_type, circuit_id_vec);
448 if (context->clientid_) {
449 const std::vector<uint8_t>& vec = context->clientid_->getClientId();
451 context->addHostIdentifier(id_type, vec);
464 std::vector<uint8_t> id;
473 callout_handle->setArgument(
"query4", context->query_);
474 callout_handle->setArgument(
"id_type", type);
475 callout_handle->setArgument(
"id_value",
id);
481 callout_handle->getArgument(
"id_type", type);
482 callout_handle->getArgument(
"id_value",
id);
490 context->addHostIdentifier(type,
id);
505 for (
auto const& def : *defs_ptr) {
509 if (def->getMatchExpr()) {
510 query->classes_.erase(def->getName());
517 if (context->currentHost() && context->query_) {
518 const ClientClasses& classes = context->currentHost()->getClientClasses4();
519 for (
auto const& cclass : classes) {
520 context->query_->addClass(cclass);
527 if (context_->subnet_) {
529 context_->subnet_->getSharedNetwork(shared_network);
530 if (shared_network) {
532 if (host && (host->getIPv4SubnetID() != SUBNET_ID_GLOBAL)) {
544 if (!host->getNextServer().isV4Zero()) {
545 resp_->setSiaddr(host->getNextServer());
548 std::string sname = host->getServerHostname();
549 if (!sname.empty()) {
550 resp_->setSname(
reinterpret_cast<const uint8_t*
>(sname.c_str()),
554 std::string bootfile = host->getBootFileName();
555 if (!bootfile.empty()) {
556 resp_->setFile(
reinterpret_cast<const uint8_t*
>(bootfile.c_str()),
564 boost::shared_ptr<OptionString> vendor_class =
576 pkt->addClass(
"ALL");
590 for (
auto const& it : *defs_ptr) {
598 if (it->getRequired()) {
602 if (it->getDependOnKnown() != depend_on_known) {
605 it->test(pkt, expr_ptr);
612 const bool use_bcast,
const bool direct_response_desired)
613 : io_service_(new
IOService()), server_port_(server_port),
614 client_port_(client_port), shutdown_(true),
615 alloc_engine_(), use_bcast_(use_bcast),
618 test_send_responses_to_source_(false) {
620 const char* env = std::getenv(
"KEA_TEST_SEND_RESPONSES_TO_SOURCE");
623 test_send_responses_to_source_ =
true;
651 }
catch (
const std::exception &e) {
666 for (
auto const& it : dhcp4_statistics) {
668 stats_mgr.
setValue(it,
static_cast<int64_t
>(0));
678 }
catch (
const std::exception& ex) {
685 }
catch (
const std::exception& ex) {
701 if (!names.empty()) {
703 for (
size_t i = 1; i < names.size(); ++i) {
704 msg += std::string(
", ") + names[i];
710 io_service_->restart();
725 bool sanity_only,
bool allow_answer_park) {
728 if (query->isDhcp4o6()) {
737 subnet = cfgmgr.
getCurrentCfg()->getCfgSubnets4()->selectSubnet(selector);
749 shared_ptr<ScopedCalloutHandleState> callout_handle_state(
750 std::make_shared<ScopedCalloutHandleState>(callout_handle));
756 callout_handle->setArgument(
"query4", query);
757 callout_handle->setArgument(
"subnet4", subnet);
758 callout_handle->setArgument(
"subnet4collection",
760 getCfgSubnets4()->getAll());
762 auto const tpl(parkingLimitExceeded(
"subnet4_select"));
763 bool const exceeded(get<0>(tpl));
765 uint32_t
const limit(get<1>(tpl));
770 .arg(query->getLabel());
776 "subnet4_select", query, [
this, query, allow_answer_park, callout_handle_state]() {
778 boost::shared_ptr<function<void()>> callback(
779 boost::make_shared<function<
void()>>(
780 [
this, query, allow_answer_park]()
mutable {
783 callout_handle_state->on_completion_ = [callback]() {
806 .arg(query->getLabel());
819 .arg(query->getLabel());
828 .arg(query->getLabel());
834 callout_handle->getArgument(
"subnet4", subnet);
840 .arg(query->getLabel())
841 .arg(subnet->getID());
845 .arg(query->getLabel())
846 .arg(subnet->toText());
851 .arg(query->getLabel());
859 bool sanity_only,
bool allow_answer_park) {
863 selector.
ciaddr_ = query->getCiaddr();
864 selector.
giaddr_ = query->getGiaddr();
875 Pkt4o6Ptr query4o6 = boost::dynamic_pointer_cast<Pkt4o6>(query);
879 const Pkt6Ptr& query6 = query4o6->getPkt6();
882 if (query6 && !query6->relay_info_.empty()) {
883 for (
auto const& relay : boost::adaptors::reverse(query6->relay_info_)) {
884 if (!relay.linkaddr_.isV6Zero() &&
885 !relay.linkaddr_.isV6LinkLocal()) {
898 OptionCustomPtr oc = boost::dynamic_pointer_cast<OptionCustom>(sbnsel);
905 subnet = cfgmgr.
getCurrentCfg()->getCfgSubnets4()->selectSubnet4o6(selector);
917 shared_ptr<ScopedCalloutHandleState> callout_handle_state(
918 std::make_shared<ScopedCalloutHandleState>(callout_handle));
924 callout_handle->setArgument(
"query4", query);
925 callout_handle->setArgument(
"subnet4", subnet);
926 callout_handle->setArgument(
"subnet4collection",
928 getCfgSubnets4()->getAll());
930 auto const tpl(parkingLimitExceeded(
"subnet4_select"));
931 bool const exceeded(get<0>(tpl));
933 uint32_t
const limit(get<1>(tpl));
938 .arg(query->getLabel());
944 "subnet4_select", query, [
this, query, allow_answer_park, callout_handle_state]() {
946 boost::shared_ptr<function<void()>> callback(
947 boost::make_shared<function<
void()>>(
948 [
this, query, allow_answer_park]()
mutable {
951 callout_handle_state->on_completion_ = [callback]() {
974 .arg(query->getLabel());
987 .arg(query->getLabel());
996 .arg(query->getLabel());
1002 callout_handle->getArgument(
"subnet4", subnet);
1009 .arg(query->getLabel())
1010 .arg(subnet->getID());
1015 .arg(query->getLabel())
1016 .arg(subnet->toText());
1021 .arg(query->getLabel());
1041 ctx->query_ = query;
1044 ctx->hwaddr_ = query->getHWAddr();
1058 ctx->early_global_reservations_lookup_ = egrl->boolValue();
1062 if (ctx->early_global_reservations_lookup_) {
1066 ctx->clientid_.reset(
new ClientId(opt_clientid->getData()));
1075 if (global_host && !global_host->getClientClasses4().empty()) {
1080 const ClientClasses& classes = global_host->getClientClasses4();
1081 for (
auto const& cclass : classes) {
1082 query->addClass(cclass);
1091 query->addClass(
"KNOWN");
1093 .arg(query->getLabel())
1100 if (query->inClass(
"DROP")) {
1103 .arg(query->getHWAddrLabel())
1104 .arg(query->toText());
1106 static_cast<int64_t
>(1));
1111 ctx->hosts_[SUBNET_ID_GLOBAL] = global_host;
1126 while (__AFL_LOOP(fuzzer.maxLoopCount())) {
1136 }
catch (
const std::exception& e) {
1167 uint32_t timeout = 1;
1178 .arg(query->getRemoteAddr().toText())
1179 .arg(query->getRemotePort())
1180 .arg(query->getLocalAddr().toText())
1181 .arg(query->getLocalPort())
1182 .arg(query->getIface());
1198 }
catch (
const std::exception& e) {
1213 .arg(query->getLabel());
1217 query->addPktEvent(
"mt_queued");
1218 typedef function<void()> CallBack;
1219 boost::shared_ptr<CallBack> call_back =
1235 }
catch (
const std::exception& e) {
1257 query->addPktEvent(
"process_started");
1260 query->addClass(
"ALL");
1267 static_cast<int64_t
>(1));
1269 bool skip_unpack =
false;
1286 callout_handle->setArgument(
"query4", query);
1298 .arg(query->getRemoteAddr().toText())
1299 .arg(query->getLocalAddr().toText())
1300 .arg(query->getIface());
1311 .arg(query->getRemoteAddr().toText())
1312 .arg(query->getLocalAddr().toText())
1313 .arg(query->getIface());
1317 callout_handle->getArgument(
"query4", query);
1325 .arg(query->getRemoteAddr().toText())
1326 .arg(query->getLocalAddr().toText())
1327 .arg(query->getIface());
1335 }
catch (
const std::exception& e) {
1338 .arg(query->getRemoteAddr().toText())
1339 .arg(query->getLocalAddr().toText())
1340 .arg(query->getIface())
1342 .arg(query->getHWAddrLabel());
1346 static_cast<int64_t
>(1));
1348 static_cast<int64_t
>(1));
1355 .arg(query->getLabel());
1373 static_cast<int64_t
>(1));
1379 int type = query->getType();
1381 .arg(query->getLabel())
1382 .arg(query->getName())
1384 .arg(query->getRemoteAddr())
1385 .arg(query->getLocalAddr())
1386 .arg(query->getIface());
1388 .arg(query->getLabel())
1389 .arg(query->toText());
1405 callout_handle->setArgument(
"query4", query);
1418 .arg(query->getLabel());
1422 callout_handle->getArgument(
"query4", query);
1426 if (query->inClass(
"DROP")) {
1428 .arg(query->getHWAddrLabel())
1429 .arg(query->toText());
1431 static_cast<int64_t
>(1));
1440 bool allow_answer_park) {
1449 }
catch (
const std::exception& e) {
1470 this, query, allow_answer_park));
1471 if (!client_handler.
tryLock(query, cont)) {
1487 ctx->subnet_ =
selectSubnet(query, drop,
false, allow_answer_park);
1493 }
catch (
const std::exception& e) {
1503 .arg(query->getLabel())
1508 static_cast<int64_t
>(1));
1517 bool allow_answer_park) {
1527 }
catch (
const std::exception& e) {
1537 bool allow_answer_park) {
1545 callout_handle->getContext(
"subnet4", ctx->subnet_);
1555 bool allow_answer_park) {
1562 switch (query->getType()) {
1592 }
catch (
const std::exception& e) {
1602 .arg(query->getLabel())
1607 static_cast<int64_t
>(1));
1614 int hook_idx =
Hooks.hook_index_leases4_committed_;
1615 std::string hook_label =
"leases4_committed";
1619 if (ctx->fake_allocation_) {
1620 hook_idx =
Hooks.hook_index_lease4_offer_;
1621 hook_label =
"lease4_offer";
1651 std::shared_ptr<ScopedCalloutHandleState> callout_handle_state =
1652 std::make_shared<ScopedCalloutHandleState>(callout_handle);
1657 callout_handle->setArgument(
"query4", query);
1661 if (ctx->new_lease_ && (ctx->new_lease_->reuseable_valid_lft_ == 0)) {
1662 new_leases->push_back(ctx->new_lease_);
1664 callout_handle->setArgument(
"leases4", new_leases);
1666 if (ctx->fake_allocation_) {
1668 callout_handle->setArgument(
"offer_lifetime", ctx->offer_lft_);
1669 callout_handle->setArgument(
"old_lease", ctx->old_lease_);
1673 if (ctx->old_lease_) {
1674 if ((!ctx->new_lease_) || (ctx->new_lease_->addr_ != ctx->old_lease_->addr_)) {
1675 deleted_leases->push_back(ctx->old_lease_);
1678 callout_handle->setArgument(
"deleted_leases4", deleted_leases);
1681 if (allow_answer_park) {
1682 auto const tpl(parkingLimitExceeded(hook_label));
1683 bool const exceeded(get<0>(tpl));
1685 uint32_t
const limit(get<1>(tpl));
1689 .arg(query->getLabel());
1691 static_cast<int64_t
>(1));
1701 [
this, callout_handle, query, rsp, callout_handle_state, hook_idx, ctx]()
mutable {
1702 if (hook_idx ==
Hooks.hook_index_lease4_offer_) {
1703 bool offer_address_in_use = false;
1705 callout_handle->getArgument(
"offer_address_in_use", offer_address_in_use);
1708 .arg(query->getLabel())
1712 if (offer_address_in_use) {
1714 bool lease_exists = (ctx->offer_lft_ > 0);
1716 typedef function<void()> CallBack;
1719 boost::shared_ptr<CallBack> call_back = boost::make_shared<CallBack>(
1721 callout_handle, query, lease, lease_exists));
1722 callout_handle_state->on_completion_ = [call_back]() {
1735 typedef function<void()> CallBack;
1736 boost::shared_ptr<CallBack> call_back = boost::make_shared<CallBack>(
1738 query, rsp, ctx->subnet_));
1739 callout_handle_state->on_completion_ = [call_back]() {
1754 if (allow_answer_park) {
1762 allow_answer_park) {
1764 .arg(query->getLabel());
1775 .arg(query->getLabel());
1796 }
catch (
const std::exception& e) {
1807 query->addPktEvent(
"process_completed");
1813 bool skip_pack =
false;
1829 callout_handle->setArgument(
"query4", query);
1832 callout_handle->setArgument(
"response4", rsp);
1835 callout_handle->setArgument(
"subnet4", subnet);
1848 .arg(query->getLabel());
1855 .arg(rsp->getLabel());
1864 .arg(rsp->getLabel());
1866 }
catch (
const std::exception& e) {
1868 .arg(rsp->getLabel())
1898 callout_handle->setArgument(
"response4", rsp);
1911 .arg(rsp->getLabel());
1915 callout_handle->getArgument(
"response4", rsp);
1919 .arg(rsp->getLabel())
1920 .arg(rsp->getName())
1921 .arg(
static_cast<int>(rsp->getType()))
1922 .arg(rsp->getLocalAddr().isV4Zero() ?
"*" : rsp->getLocalAddr().toText())
1923 .arg(rsp->getLocalPort())
1924 .arg(rsp->getRemoteAddr())
1925 .arg(rsp->getRemotePort())
1926 .arg(rsp->getIface().empty() ?
"to be determined from routing" :
1931 .arg(rsp->getLabel())
1932 .arg(rsp->getName())
1933 .arg(
static_cast<int>(rsp->getType()))
1934 .arg(rsp->toText());
1940 }
catch (
const std::exception& e) {
1942 .arg(rsp->getLabel())
1952 boost::shared_ptr<Option4AddrLst> generated =
1953 boost::dynamic_pointer_cast<Option4AddrLst>(srvid);
1959 if (addrs.size() != 1) {
1961 <<
"Expected to contain a single IPv4 address.");
1964 return (addrs[0].toText());
1982 if (local_addr.
isV4Bcast() || query->isDhcp4o6()) {
2005 if (host && !host->getCfgOption4()->empty()) {
2006 co_list.push_back(host->getCfgOption4());
2013 addr = resp->getYiaddr();
2017 if (pool && !pool->getCfgOption()->empty()) {
2018 co_list.push_back(pool->getCfgOption());
2023 if (!subnet->getCfgOption()->empty()) {
2024 co_list.push_back(subnet->getCfgOption());
2029 subnet->getSharedNetwork(network);
2030 if (network && !network->getCfgOption()->empty()) {
2031 co_list.push_back(network->getCfgOption());
2036 for (
auto const& cclass : classes) {
2039 getClientClassDictionary()->findClass(cclass);
2051 if (ccdef->getCfgOption()->empty()) {
2056 co_list.push_back(ccdef->getCfgOption());
2080 if (co_list.empty()) {
2086 set<uint8_t> requested_opts;
2095 for (uint16_t code : option_prl->getValues()) {
2096 static_cast<void>(requested_opts.insert(code));
2100 std::set<uint8_t> cancelled_opts;
2104 for (
auto const& copts : co_list) {
2112 BOOST_FOREACH(
auto const& desc, prange) {
2115 uint8_t code =
static_cast<uint8_t
>(desc.option_->getType());
2116 static_cast<void>(requested_opts.insert(code));
2122 BOOST_FOREACH(
auto const& desc, crange) {
2125 uint8_t code =
static_cast<uint8_t
>(desc.option_->getType());
2126 static_cast<void>(cancelled_opts.insert(code));
2133 for (uint8_t opt : requested_opts) {
2134 if (cancelled_opts.count(opt) > 0) {
2142 if (!resp->getOption(opt)) {
2144 for (
auto const& copts : co_list) {
2148 resp->addOption(desc.
option_);
2161 set<uint32_t> vendor_ids;
2165 vendor_opts = boost::dynamic_pointer_cast<OptionVendorClass>(opt.second);
2167 uint32_t vendor_id = vendor_opts->getVendorId();
2168 static_cast<void>(vendor_ids.insert(vendor_id));
2172 for (
auto const& copts : co_list) {
2175 if (!desc.option_) {
2179 boost::dynamic_pointer_cast<OptionVendorClass>(desc.option_);
2184 uint32_t vendor_id = vendor_opts->getVendorId();
2185 if (vendor_ids.count(vendor_id) > 0) {
2189 resp->Pkt::addOption(desc.option_);
2190 static_cast<void>(vendor_ids.insert(vendor_id));
2199 set<uint32_t> vendor_ids;
2203 vendor_opts = boost::dynamic_pointer_cast<OptionVendor>(opt.second);
2205 uint32_t vendor_id = vendor_opts->getVendorId();
2206 static_cast<void>(vendor_ids.insert(vendor_id));
2210 for (
auto const& copts : co_list) {
2213 if (!desc.option_) {
2217 boost::dynamic_pointer_cast<OptionVendor>(desc.option_);
2222 uint32_t vendor_id = vendor_opts->getVendorId();
2223 if (vendor_ids.count(vendor_id) > 0) {
2229 resp->Pkt::addOption(vendor_opts);
2230 static_cast<void>(vendor_ids.insert(vendor_id));
2250 if (!subnet || co_list.empty()) {
2256 set<uint32_t> vendor_ids;
2260 map<uint32_t, OptionVendorPtr> vendor_rsps;
2263 vendor_rsp = boost::dynamic_pointer_cast<OptionVendor>(opt.second);
2265 uint32_t vendor_id = vendor_rsp->getVendorId();
2266 vendor_rsps[vendor_id] = vendor_rsp;
2267 static_cast<void>(vendor_ids.insert(vendor_id));
2273 map<uint32_t, OptionVendorPtr> vendor_reqs;
2276 vendor_req = boost::dynamic_pointer_cast<OptionVendor>(opt.second);
2278 uint32_t vendor_id = vendor_req->getVendorId();
2279 vendor_reqs[vendor_id] = vendor_req;
2280 static_cast<void>(vendor_ids.insert(vendor_id));
2288 vendor_class = boost::dynamic_pointer_cast<OptionVendorClass>(opt.second);
2290 uint32_t vendor_id = vendor_class->getVendorId();
2291 static_cast<void>(vendor_ids.insert(vendor_id));
2297 if (vendor_ids.empty()) {
2301 map<uint32_t, set<uint8_t> > requested_opts;
2315 oro = boost::dynamic_pointer_cast<OptionUint8Array>(oro_generic);
2318 set<uint8_t> oro_req_opts;
2319 for (uint8_t code : oro->getValues()) {
2320 static_cast<void>(oro_req_opts.insert(code));
2326 for (uint32_t vendor_id : vendor_ids) {
2328 std::set<uint8_t> cancelled_opts;
2332 for (
auto const& copts : co_list) {
2341 BOOST_FOREACH(
auto const& desc, prange) {
2344 uint8_t code =
static_cast<uint8_t
>(desc.option_->getType());
2345 static_cast<void>(requested_opts[vendor_id].insert(code));
2352 BOOST_FOREACH(
auto const& desc, crange) {
2355 uint8_t code =
static_cast<uint8_t
>(desc.option_->getType());
2356 static_cast<void>(cancelled_opts.insert(code));
2366 if (requested_opts[vendor_id].empty()) {
2374 if (vendor_rsps.count(vendor_id) > 0) {
2375 vendor_rsp = vendor_rsps[vendor_id];
2383 for (uint8_t opt : requested_opts[vendor_id]) {
2384 if (cancelled_opts.count(opt) > 0) {
2387 if (!vendor_rsp->getOption(opt)) {
2388 for (
auto const& copts : co_list) {
2391 vendor_rsp->addOption(desc.
option_);
2401 if (added && (vendor_rsps.count(vendor_id) == 0)) {
2402 resp->Pkt::addOption(vendor_rsp);
2411 static const std::vector<uint16_t> required_options = {
2425 if (co_list.empty()) {
2433 for (
auto const& required : required_options) {
2434 OptionPtr opt = resp->getOption(required);
2437 for (
auto const& copts : co_list) {
2440 resp->addOption(desc.
option_);
2460 .arg(query->getLabel());
2461 processClientFqdnOption(ex);
2466 .arg(query->getLabel());
2467 processHostnameOption(ex);
2473 std::string hostname;
2474 bool fqdn_fwd =
false;
2475 bool fqdn_rev =
false;
2478 fqdn = boost::dynamic_pointer_cast<Option4ClientFqdn>(resp->getOption(
DHO_FQDN));
2480 hostname = fqdn->getDomainName();
2483 opt_hostname = boost::dynamic_pointer_cast<OptionString>
2487 hostname = opt_hostname->getValue();
2492 if (hostname ==
".") {
2498 if (ex.
getContext()->getDdnsParams()->getEnableUpdates()) {
2518 callout_handle->setArgument(
"query4", query);
2519 callout_handle->setArgument(
"response4", resp);
2520 callout_handle->setArgument(
"subnet4", subnet);
2521 callout_handle->setArgument(
"hostname", hostname);
2522 callout_handle->setArgument(
"fwd-update", fqdn_fwd);
2523 callout_handle->setArgument(
"rev-update", fqdn_rev);
2524 callout_handle->setArgument(
"ddns-params", ex.
getContext()->getDdnsParams());
2530 string hook_hostname;
2531 bool hook_fqdn_fwd =
false;
2532 bool hook_fqdn_rev =
false;
2533 callout_handle->getArgument(
"hostname", hook_hostname);
2534 callout_handle->getArgument(
"fwd-update", hook_fqdn_fwd);
2535 callout_handle->getArgument(
"rev-update", hook_fqdn_rev);
2539 if ((hostname != hook_hostname) || (fqdn_fwd != hook_fqdn_fwd) ||
2540 (fqdn_rev != hook_fqdn_rev)) {
2542 .arg(hostname).arg(hook_hostname).arg(fqdn_fwd).arg(hook_fqdn_fwd)
2543 .arg(fqdn_rev).arg(hook_fqdn_rev);
2544 hostname = hook_hostname;
2545 fqdn_fwd = hook_fqdn_fwd;
2546 fqdn_rev = hook_fqdn_rev;
2550 OptionStringPtr hostname_opt = boost::dynamic_pointer_cast<OptionString>
2553 hostname_opt->setValue(hook_hostname);
2558 fqdn = boost::dynamic_pointer_cast<Option4ClientFqdn>(resp->getOption(
DHO_FQDN));
2570 ctx->fwd_dns_update_ = fqdn_fwd;
2571 ctx->rev_dns_update_ = fqdn_rev;
2572 ctx->hostname_ = hostname;
2597 .arg(fqdn->toText());
2613 !ex.
getContext()->currentHost()->getHostname().empty()) {
2639 .arg(fqdn_resp->
toText());
2649 OptionStringPtr opt_hostname = boost::dynamic_pointer_cast<OptionString>
2655 .arg(opt_hostname->getValue());
2663 if (ctx->currentHost() && !ctx->currentHost()->getHostname().empty()) {
2665 std::string hostname = d2_mgr.
qualifyName(ctx->currentHost()->getHostname(),
2668 boost::algorithm::to_lower(hostname);
2686 ex.
getContext()->getDdnsParams()->getReplaceClientNameMode();
2689 if (!opt_hostname) {
2709 .arg(opt_hostname->getValue());
2712 unsigned int label_count;
2718 }
catch (
const std::exception& exc) {
2729 if (label_count == 0) {
2747 || label_count < 2) {
2761 ex.
getContext()->getDdnsParams()->getHostnameSanitizer();
2764 hostname = sanitizer->scrub(hostname);
2768 boost::algorithm::to_lower(hostname);
2770 if (label_count == 2) {
2778 opt_hostname_resp.reset(
2789 .arg(opt_hostname_resp->getValue());
2799 "NULL lease specified when creating NameChangeRequest");
2807 if (!old_lease || ddns_params.
getUpdateOnRenew() || !lease->hasIdenticalFqdn(*old_lease)) {
2839 if (opt_requested_address) {
2840 hint = opt_requested_address->readAddress();
2842 }
else if (!query->getCiaddr().isV4Zero()) {
2843 hint = query->getCiaddr();
2853 bool fake_allocation = (query->getType() ==
DHCPDISCOVER);
2861 auto authoritative =
false;
2867 auto init_reboot = (!fake_allocation && !opt_serverid && opt_requested_address);
2870 .arg(query->getLabel())
2871 .arg(hint.toText());
2875 authoritative = subnet->getAuthoritative();
2881 authoritative = flag->boolValue();
2884 }
else if (fake_allocation) {
2886 .arg(query->getLabel())
2890 .arg(query->getLabel())
2898 if (!subnet && (!init_reboot || authoritative)) {
2905 .arg(query->getLabel())
2906 .arg(query->getRemoteAddr().toText())
2907 .arg(query->getName());
2925 auto const& classes = query->getClasses();
2935 if (original_subnet && client_id) {
2939 if (!leases_client_id.empty()) {
2945 for (
auto const& l : leases_client_id) {
2946 if (l->subnet_id_ == s->getID()) {
2956 s = s->getNextSubnet(original_subnet, classes);
2964 if (original_subnet && !lease && hwaddr) {
2968 if (!leases_hwaddr.empty()) {
2973 for (
auto const& l : leases_hwaddr) {
2974 if (l->subnet_id_ == s->getID()) {
2984 s = s->getNextSubnet(original_subnet, classes);
2993 bool known_client = lease && lease->belongsToClient(hwaddr, client_id);
2994 if (!authoritative && !known_client) {
2997 .arg(query->getLabel())
2998 .arg(hint.toText());
3006 if ((known_client && (lease->addr_ != hint)) ||
3007 (!known_client && authoritative) ||
3008 (!original_subnet)) {
3011 .arg(query->getLabel())
3012 .arg(hint.toText());
3023 ctx->requested_address_ = hint;
3024 ctx->fake_allocation_ = fake_allocation;
3025 ctx->callout_handle_ = callout_handle;
3041 bool client_name_changed =
false;
3045 if (subnet && ctx->subnet_ && subnet->getID() != ctx->subnet_->getID()) {
3047 subnet->getSharedNetwork(network);
3049 .arg(query->getLabel())
3050 .arg(subnet->toText())
3051 .arg(ctx->subnet_->toText())
3052 .arg(network ? network->getName() :
"<no network?>");
3054 subnet = ctx->subnet_;
3069 ctx->hostname_ =
"";
3070 ctx->fwd_dns_update_ =
false;
3071 ctx->rev_dns_update_ =
false;
3078 if ((lease->hostname_ != ctx->hostname_) ||
3079 (lease->fqdn_fwd_ != ctx->fwd_dns_update_) ||
3080 (lease->fqdn_rev_ != ctx->rev_dns_update_)) {
3081 lease->hostname_ = ctx->hostname_;
3082 lease->fqdn_fwd_ = ctx->fwd_dns_update_;
3083 lease->fqdn_rev_ = ctx->rev_dns_update_;
3084 client_name_changed =
true;
3092 if (fake_allocation) {
3094 .arg(query->getLabel())
3095 .arg(lease->addr_.toText());
3098 .arg(query->getLabel())
3099 .arg(lease->addr_.toText())
3107 if (!ctx->subnet_->getMatchClientId()) {
3109 .arg(ctx->query_->getLabel())
3110 .arg(ctx->subnet_->getID());
3113 resp->setYiaddr(lease->addr_);
3119 if (!fake_allocation) {
3124 resp->setCiaddr(query->getCiaddr());
3133 if (lease->reuseable_valid_lft_ > 0) {
3134 lease->valid_lft_ = lease->reuseable_valid_lft_;
3136 .arg(query->getLabel())
3137 .arg(lease->addr_.toText())
3154 resp->addOption(opt);
3157 resp->addOption(getNetmaskOption(subnet));
3163 if (!fake_allocation) {
3169 .arg(query->getLabel())
3177 if (ctx->unknown_requested_addr_) {
3189 s = s->getNextSubnet(original_subnet);
3197 .arg(query->getLabel())
3198 .arg(query->getCiaddr().toText())
3199 .arg(opt_requested_address ?
3200 opt_requested_address->readAddress().toText() :
"(no address)");
3208 .arg(query->getLabel())
3209 .arg(query->getCiaddr().toText())
3210 .arg(opt_requested_address ?
3211 opt_requested_address->readAddress().toText() :
"(no address)");
3223 const Pkt4Ptr& query,
const Pkt4Ptr& resp,
bool client_name_changed) {
3232 opt_hostname = boost::dynamic_pointer_cast<OptionString>(resp->getOption(
DHO_HOST_NAME));
3233 if (!opt_hostname) {
3240 if (lease->hostname_.empty()) {
3247 .
generateFqdn(lease->addr_, *(ctx->getDdnsParams()),
static_cast<bool>(fqdn));
3250 .arg(query->getLabel())
3251 .arg(lease->hostname_);
3253 client_name_changed =
true;
3256 if (client_name_changed) {
3262 if (!ctx->fake_allocation_ || (ctx->offer_lft_ > 0)) {
3264 lease->reuseable_valid_lft_ = 0;
3277 opt_hostname->setValue(lease->hostname_);
3281 .arg(query->getLabel())
3282 .arg(lease->hostname_)
3292 uint32_t t2_time = 0;
3294 if (!subnet->getT2().unspecified()) {
3295 t2_time = subnet->getT2();
3296 }
else if (subnet->getCalculateTeeTimes()) {
3298 t2_time =
static_cast<uint32_t
>(round(subnet->getT2Percent() * (lease->valid_lft_)));
3303 uint32_t timer_ceiling = lease->valid_lft_;
3304 if (t2_time > 0 && t2_time < timer_ceiling) {
3306 resp->addOption(t2);
3308 timer_ceiling = t2_time;
3311 uint32_t t1_time = 0;
3313 if (!subnet->getT1().unspecified()) {
3314 t1_time = subnet->getT1();
3315 }
else if (subnet->getCalculateTeeTimes()) {
3317 t1_time =
static_cast<uint32_t
>(round(subnet->getT1Percent() * (lease->valid_lft_)));
3322 if (t1_time > 0 && t1_time < timer_ceiling) {
3324 resp->addOption(t1);
3336 return (query->getRemotePort());
3364 }
else if (((query->getType() ==
DHCPINFORM) &&
3365 ((!query->getCiaddr().isV4Zero()) ||
3366 (!query->isRelayed() && !query->getRemoteAddr().isV4Zero()))) ||
3367 ((query->getType() !=
DHCPINFORM) && !query->isRelayed())) {
3368 response->setRemotePort(DHCP4_CLIENT_PORT);
3373 response->setRemotePort(relay_port ? relay_port : DHCP4_SERVER_PORT);
3377 if (query->isRelayed() &&
3383 response->resetIndex();
3385 response->setIface(query->getIface());
3389 IOAddress local_addr = query->getLocalAddr();
3398 if (local_addr.
isV4Bcast() || query->isDhcp4o6()) {
3409 response->setLocalAddr(local_addr);
3418 response->setIndex(query->getIndex());
3419 response->setIface(query->getIface());
3425 response->setLocalPort(DHCP4_SERVER_PORT);
3437 if (query->isDhcp4o6()) {
3438 response->setRemoteAddr(query->getRemoteAddr());
3450 if (!query->getCiaddr().isV4Zero()) {
3451 response->setRemoteAddr(query->getCiaddr());
3458 }
else if (query->isRelayed()) {
3459 response->setRemoteAddr(query->getGiaddr());
3460 response->setFlags(response->getFlags() | BOOTP_BROADCAST);
3465 response->setRemoteAddr(query->getRemoteAddr());
3472 if (query->isRelayed()) {
3481 query->getCiaddr().isV4Zero()) {
3482 response->setFlags(BOOTP_BROADCAST);
3484 response->setRemoteAddr(query->getGiaddr());
3488 }
else if (!query->getCiaddr().isV4Zero()) {
3489 response->setRemoteAddr(query->getCiaddr());
3494 }
else if (response->getType() ==
DHCPNAK) {
3498 }
else if (!response->getYiaddr().isV4Zero()) {
3513 response->setRemoteAddr(response ->getYiaddr());
3521 response->setRemoteAddr(query->getRemoteAddr());
3526 response->setRemoteAddr(query->getRemoteAddr());
3538 IOAddress subnet_next_server = subnet->getSiaddr();
3539 if (!subnet_next_server.
isV4Zero()) {
3540 response->setSiaddr(subnet_next_server);
3543 const string& sname = subnet->getSname();
3544 if (!sname.empty()) {
3550 response->setSname(
reinterpret_cast<const uint8_t*
>(sname.c_str()),
3554 const string& filename = subnet->getFilename();
3555 if (!filename.empty()) {
3561 response->setFile(
reinterpret_cast<const uint8_t*
>(filename.c_str()),
3569 if (!classes.
empty()) {
3582 size_t found_cnt = 0;
3583 for (
auto const& name : classes) {
3585 if (found_cnt >= 3) {
3599 next_server = cl->getNextServer();
3601 response->setSiaddr(next_server);
3606 if (sname.empty()) {
3607 sname = cl->getSname();
3608 if (!sname.empty()) {
3614 response->setSname(
reinterpret_cast<const uint8_t*
>(sname.c_str()),
3620 if (filename.empty()) {
3621 filename = cl->getFilename();
3622 if (!filename.empty()) {
3628 response->setFile(
reinterpret_cast<const uint8_t*
>(filename.c_str()),
3642Dhcpv4Srv::getNetmaskOption(
const Subnet4Ptr& subnet) {
3651tuple<bool, uint32_t>
3652Dhcpv4Srv::parkingLimitExceeded(
string const& hook_label) {
3654 uint32_t parked_packet_limit(0);
3658 parked_packet_limit = ppl->intValue();
3661 if (parked_packet_limit) {
3665 if (parking_lot && parked_packet_limit <= parking_lot->size()) {
3666 return make_tuple(
true, parked_packet_limit);
3669 return make_tuple(
false, parked_packet_limit);
3706 .arg(discover->getLabel())
3707 .arg(discover->getName())
3708 .arg(discover->getClasses().toText());
3767 }
else if (request->inClass(
"BOOTP")) {
3769 response->addClass(
"BOOTP");
3773 if (!response->getYiaddr().isV4Zero()) {
3782 .arg(request->getLabel())
3783 .arg(request->getName())
3784 .arg(request->getClasses().toText());
3837 .arg(release->getLabel())
3838 .arg(release->getCiaddr().toText());
3842 if (!lease->belongsToClient(release->getHWAddr(), client_id)) {
3844 .arg(release->getLabel())
3845 .arg(release->getCiaddr().toText());
3865 callout_handle->setArgument(
"query4", release);
3868 callout_handle->setArgument(
"lease4", lease);
3882 .arg(release->getLabel());
3890 bool success =
false;
3891 bool expired =
false;
3895 if (expiration_cfg->getFlushReclaimedTimerWaitTime() &&
3896 expiration_cfg->getHoldReclaimedTime() &&
3899 lease->valid_lft_ = 0;
3909 context->old_lease_ = lease;
3913 .arg(release->getLabel())
3914 .arg(lease->addr_.toText());
3918 .arg(release->getLabel())
3919 .arg(lease->addr_.toText());
3922 .arg(release->getLabel())
3923 .arg(lease->addr_.toText());
3928 static_cast<int64_t
>(-1));
3932 auto const& pool = subnet->getPool(
Lease::TYPE_V4, lease->addr_,
false);
3937 static_cast<int64_t
>(-1));
3947 .arg(release->getLabel())
3948 .arg(lease->addr_.toText());
3953 .arg(release->getLabel())
3954 .arg(release->getCiaddr())
3967 if (!opt_requested_address) {
3970 " in DHCPDECLINE sent from " << decline->getLabel());
3972 IOAddress addr(opt_requested_address->readAddress());
3990 .arg(addr.
toText()).arg(decline->getLabel());
3998 client_id.reset(
new ClientId(opt_clientid->getData()));
4002 if (!lease->belongsToClient(decline->getHWAddr(), client_id)) {
4005 string client_hw = decline->getHWAddr() ?
4006 decline->getHWAddr()->toText(
false) :
"(none)";
4007 string lease_hw = lease->hwaddr_ ?
4008 lease->hwaddr_->toText(
false) :
"(none)";
4011 string client_id_txt = client_id ? client_id->toText() :
"(none)";
4012 string lease_id_txt = lease->client_id_ ?
4013 lease->client_id_->toText() :
"(none)";
4017 .arg(addr.
toText()).arg(decline->getLabel())
4018 .arg(client_hw).arg(lease_hw).arg(client_id_txt).arg(lease_id_txt);
4048 callout_handle->setArgument(
"query4", decline);
4051 callout_handle->setArgument(
"lease4", lease);
4062 .arg(decline->getLabel()).arg(lease->addr_.toText());
4067 Lease4Ptr old_values = boost::make_shared<Lease4>(*lease);
4081 .arg(decline->getLabel())
4082 .arg(lease->addr_.toText())
4096 static_cast<int64_t
>(1));
4100 auto const& pool = subnet->getPool(
Lease::TYPE_V4, lease->addr_,
false);
4105 static_cast<int64_t
>(1));
4122 context->new_lease_ = lease;
4125 .arg(decline->getLabel()).arg(lease->valid_lft_);
4132 .arg(lease->addr_.toText())
4133 .arg(lease->valid_lft_);
4141 .arg(query->getLabel())
4142 .arg(lease->addr_.toText());
4158 lease_exists =
false;
4162 .arg(query->getLabel())
4163 .arg(lease->addr_.toText());
4168 if (!lease_exists) {
4173 .arg(query->getLabel())
4174 .arg(lease->addr_.toText());
4191 static_cast<int64_t
>(1));
4193 if (!lease_exists) {
4196 static_cast<int64_t
>(1));
4201 auto const& pool = subnet->getPool(
Lease::TYPE_V4, lease->addr_,
false);
4206 static_cast<int64_t
>(1));
4207 if (!lease_exists) {
4211 static_cast<int64_t
>(1));
4218 if (!lease_exists) {
4232 callout_handle->setArgument(
"query4", query);
4235 callout_handle->setArgument(
"lease4", lease);
4272 .arg(inform->getLabel())
4273 .arg(inform->getName())
4274 .arg(inform->getClasses().toText());
4291 if (ack->getRemoteAddr() != inform->getGiaddr()) {
4293 .arg(inform->getLabel())
4294 .arg(ack->getRemoteAddr())
4295 .arg(ack->getIface());
4318 .arg(query->getLabel())
4319 .arg(query->getIface());
4327 .arg(query->getLabel())
4328 .arg(query->getIface());
4338 if (pkt->isRelayed()) {
4343 if (pkt->isDhcp4o6()) {
4352 if (pkt->getRemoteAddr().isV4Zero() &&
4353 pkt->getCiaddr().isV4Zero()) {
4364 bool result = (!pkt->getLocalAddr().isV4Bcast() ||
4379 type = query->getType();
4383 .arg(query->getLabel())
4384 .arg(query->getIface());
4408 .arg(query->getLabel());
4415 .arg(query->getLabel())
4420 .arg(query->getLabel())
4447 boost::dynamic_pointer_cast<OptionCustom>(option);
4450 if (!option_custom) {
4458 if (option_custom->getDataFieldsNum() != 1) {
4464 IOAddress server_id = option_custom->readAddress();
4465 if (!server_id.
isV4()) {
4474 if (rai_suboption && (server_id.
toBytes() == rai_suboption->toBinary())) {
4481 if (cfg->getIgnoreServerIdentifier()) {
4519 if (cfg_subnets->hasSubnetWithServerId(server_id)) {
4526 if (cfg_networks->hasNetworkWithServerId(server_id)) {
4532 for (
auto const& cclass : classes) {
4535 getClientClassDictionary()->findClass(cclass);
4540 if (ccdef->getCfgOption()->empty()) {
4545 OptionCustomPtr context_opt_server_id = boost::dynamic_pointer_cast<OptionCustom>
4547 if (context_opt_server_id && (context_opt_server_id->readAddress() == server_id)) {
4555 OptionCustomPtr opt_server_id = boost::dynamic_pointer_cast<OptionCustom>
4558 return (opt_server_id && (opt_server_id->readAddress() == server_id));
4563 switch (query->getType()) {
4598 <<
" received in message "
4599 << query->getName());
4606 " received in message "
4607 << query->getName());
4617 if (query->getHWAddr() && !query->getHWAddr()->hwaddr_.empty()) {
4626 if (!client_id || client_id->len() == client_id->getHeaderLen()) {
4628 " provided in message "
4629 << query->getName());
4646 subnet->getSharedNetwork(network);
4648 const ClientClasses& to_add = network->getRequiredClasses();
4649 for (
auto const& cclass : to_add) {
4656 for (
auto const& cclass : to_add) {
4664 addr = resp->getYiaddr();
4669 const ClientClasses& pool_to_add = pool->getRequiredClasses();
4670 for (
auto const& cclass : pool_to_add) {
4683 for (
auto const& cclass : classes) {
4706 query->addClass(cclass);
4719 .arg(
"get exception?");
4727 for (
auto const& code : query->getDeferredOptions()) {
4731 for (
auto const& cclass : classes) {
4735 getClientClassDictionary()->findClass(cclass);
4741 if (!ccdef->getCfgOptionDef()) {
4779 opt = def->optionFactory(
Option::V4, code, buf);
4780 }
catch (
const std::exception& e) {
4788 while (query->delOption(code)) {
4792 query->addOption(opt);
4804 this, ph::_1, ph::_2));
4823 arg(result).arg((ncr ? ncr->toText() :
" NULL "));
4832 std::stringstream tmp;
4836 tmp << endl << EXTENDED_VERSION << endl;
4837 tmp <<
"linked with:" << endl;
4840 tmp <<
"database:" << endl;
4859 string stat_name =
"pkt4-unknown-received";
4861 switch (query->getType()) {
4863 stat_name =
"pkt4-discover-received";
4867 stat_name =
"pkt4-offer-received";
4870 stat_name =
"pkt4-request-received";
4874 stat_name =
"pkt4-ack-received";
4878 stat_name =
"pkt4-nak-received";
4881 stat_name =
"pkt4-release-received";
4884 stat_name =
"pkt4-decline-received";
4887 stat_name =
"pkt4-inform-received";
4901 static_cast<int64_t
>(1));
4907 static_cast<int64_t
>(1));
4911 switch (response->getType()) {
4913 stat_name =
"pkt4-offer-sent";
4916 stat_name =
"pkt4-ack-sent";
4919 stat_name =
"pkt4-nak-sent";
4927 static_cast<int64_t
>(1));
4931 return (
Hooks.hook_index_buffer4_receive_);
4935 return (
Hooks.hook_index_pkt4_receive_);
4939 return (
Hooks.hook_index_subnet4_select_);
4943 return (
Hooks.hook_index_lease4_release_);
4947 return (
Hooks.hook_index_pkt4_send_);
4951 return (
Hooks.hook_index_buffer4_send_);
4955 return (
Hooks.hook_index_lease4_decline_);
4964 static std::list<std::list<std::string>>
const list({
4965 {
"config-control",
"config-databases",
"[]"},
4966 {
"hooks-libraries",
"[]",
"parameters",
"*"},
4968 {
"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)
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.
The IOService class is a wrapper for the ASIO io_service 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.
Dhcpv4Exchange(const AllocEnginePtr &alloc_engine, const Pkt4Ptr &query, AllocEngine::ClientContext4Ptr &context, const Subnet4Ptr &subnet, bool &drop)
Constructor.
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.
static void classifyPacket(const Pkt4Ptr &pkt)
Assigns incoming packet to zero or more classes.
static void removeDependentEvaluatedClasses(const Pkt4Ptr &query)
Removed evaluated client classes.
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.
isc::dhcp::Subnet4Ptr selectSubnet4o6(const Pkt4Ptr &query, bool &drop, bool sanity_only=false, bool allow_answer_park=true)
Selects a subnet for a given client's DHCP4o6 packet.
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.
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.
isc::dhcp::Subnet4Ptr selectSubnet(const Pkt4Ptr &query, bool &drop, bool sanity_only=false, bool allow_answer_park=true)
Selects a subnet for a given client's packet.
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.
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.
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 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,...
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.
void serverDeclineNoThrow(hooks::CalloutHandlePtr &callout_handle, Pkt4Ptr &query, Lease4Ptr lease, bool lease_exists)
Exception safe wrapper around serverDecline()
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 sendResponseNoThrow(hooks::CalloutHandlePtr &callout_handle, Pkt4Ptr &query, Pkt4Ptr &rsp, Subnet4Ptr &subnet)
Process an unparked DHCPv4 packet and sends the response.
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.
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.
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.
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.
static int getHookIndexLease4Decline()
Returns the index for "lease4_decline" hook point.
void processRelease(Pkt4Ptr &release, AllocEngine::ClientContext4Ptr &context)
Processes incoming DHCPRELEASE messages.
void processPacketPktSend(hooks::CalloutHandlePtr &callout_handle, Pkt4Ptr &query, Pkt4Ptr &rsp, Subnet4Ptr &subnet)
Executes pkt4_send callout.
bool acceptDirectRequest(const Pkt4Ptr &query)
Check if a message sent by directly connected client should be accepted or discarded.
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.
void deferredUnpack(Pkt4Ptr &query)
Perform deferred option unpacking.
Pkt4Ptr processLocalizedQuery4(AllocEngine::ClientContext4Ptr &ctx, bool allow_answer_park)
Process a localized incoming DHCPv4 query.
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 addLease(const Lease4Ptr &lease)=0
Adds an IPv4 lease.
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.
Controls the DHCP service enabling status.
Attempt to update lease that was not there.
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....
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.
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.
bool getMode() const
Get the multi-threading mode.
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_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
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
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 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_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< 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
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_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_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.
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_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_CLASS_UNDEFINED
const isc::log::MessageID DHCP4_HOOK_LEASES4_COMMITTED_PARK
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 ...
string trim(const string &input)
Trim leading and trailing spaces.
std::unique_ptr< StringSanitizer > StringSanitizerPtr
Type representing the pointer to the StringSanitizer.
Defines the logger used by the top-level component of kea-lfc.
#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.
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