8 #include <kea_version.h> 43 #include <eval/eval_messages.h> 65 #include <boost/algorithm/string.hpp> 66 #include <boost/bind.hpp> 67 #include <boost/foreach.hpp> 68 #include <boost/pointer_cast.hpp> 69 #include <boost/shared_ptr.hpp> 87 int hook_index_buffer4_receive_;
88 int hook_index_pkt4_receive_;
89 int hook_index_subnet4_select_;
90 int hook_index_leases4_committed_;
91 int hook_index_lease4_release_;
92 int hook_index_pkt4_send_;
93 int hook_index_buffer4_send_;
94 int hook_index_lease4_decline_;
95 int hook_index_host4_identifier_;
99 hook_index_buffer4_receive_ = HooksManager::registerHook(
"buffer4_receive");
100 hook_index_pkt4_receive_ = HooksManager::registerHook(
"pkt4_receive");
101 hook_index_subnet4_select_ = HooksManager::registerHook(
"subnet4_select");
102 hook_index_leases4_committed_ = HooksManager::registerHook(
"leases4_committed");
103 hook_index_pkt4_send_ = HooksManager::registerHook(
"pkt4_send");
104 hook_index_lease4_release_ = HooksManager::registerHook(
"lease4_release");
105 hook_index_buffer4_send_ = HooksManager::registerHook(
"buffer4_send");
106 hook_index_lease4_decline_ = HooksManager::registerHook(
"lease4_decline");
107 hook_index_host4_identifier_ = HooksManager::registerHook(
"host4_identifier");
126 : alloc_engine_(alloc_engine), query_(query), resp_(),
129 if (!alloc_engine_) {
131 " when creating an instance of the Dhcpv4Exchange");
136 " creating an instance of the Dhcpv4Exchange");
142 context_->subnet_ = subnet;
144 context_->hwaddr_ = query->getHWAddr();
146 context_->query_ = query;
154 context_->clientid_.reset(
new ClientId(opt_clientid->getData()));
161 setHostIdentifiers();
164 alloc_engine->findReservation(*context_);
169 if (!context_->hosts_.empty()) {
170 query->addClass(
"KNOWN");
172 .arg(query->getLabel())
175 query->addClass(
"UNKNOWN");
177 .arg(query->getLabel())
185 if (!classes.
empty()) {
187 .arg(query_->getLabel())
194 uint8_t resp_type = 0;
208 resp_.reset(
new Pkt4(resp_type,
getQuery()->getTransid()));
210 copyDefaultOptions();
224 const Pkt6Ptr& query6 = query->getPkt6();
228 if (!query6->relay_info_.empty()) {
229 resp6->copyRelayInfo(query6);
232 resp6->setIface(query6->getIface());
233 resp6->setIndex(query6->getIndex());
234 resp6->setRemoteAddr(query6->getRemoteAddr());
235 resp6->setRemotePort(query6->getRemotePort());
236 resp_.reset(
new Pkt4o6(resp_, resp6));
240 Dhcpv4Exchange::copyDefaultFields() {
241 resp_->setIface(query_->getIface());
242 resp_->setIndex(query_->getIndex());
249 resp_->setHops(query_->getHops());
252 resp_->setHWAddr(query_->getHWAddr());
255 resp_->setGiaddr(query_->getGiaddr());
264 HWAddrPtr src_hw_addr = query_->getLocalHWAddr();
266 resp_->setLocalHWAddr(src_hw_addr);
268 HWAddrPtr dst_hw_addr = query_->getRemoteHWAddr();
270 resp_->setRemoteHWAddr(dst_hw_addr);
274 resp_->setFlags(query_->getFlags());
278 Dhcpv4Exchange::copyDefaultOptions() {
283 if (client_id && echo) {
284 resp_->addOption(client_id);
290 resp_->addOption(rai);
303 resp_->addOption(subnet_sel);
308 Dhcpv4Exchange::setHostIdentifiers() {
315 cfg->getIdentifierTypes()) {
318 if (context_->hwaddr_ && !context_->hwaddr_->hwaddr_.empty()) {
319 context_->addHostIdentifier(id_type, context_->hwaddr_->hwaddr_);
324 if (context_->clientid_) {
325 const std::vector<uint8_t>& vec = context_->clientid_->getDuid();
330 if ((vec[0] == CLIENT_ID_OPTION_TYPE_DUID) && (vec.size() > 5)) {
332 context_->addHostIdentifier(id_type,
333 std::vector<uint8_t>(vec.begin() + 5,
344 OptionPtr circuit_id_opt = rai->getOption(RAI_OPTION_AGENT_CIRCUIT_ID);
345 if (circuit_id_opt) {
346 const OptionBuffer& circuit_id_vec = circuit_id_opt->getData();
347 if (!circuit_id_vec.empty()) {
348 context_->addHostIdentifier(id_type, circuit_id_vec);
356 if (context_->clientid_) {
357 const std::vector<uint8_t>& vec = context_->clientid_->getDuid();
359 context_->addHostIdentifier(id_type, vec);
365 if (!HooksManager::calloutsPresent(
Hooks.hook_index_host4_identifier_)) {
372 std::vector<uint8_t> id;
381 callout_handle->setArgument(
"query4", context_->query_);
382 callout_handle->setArgument(
"id_type", type);
383 callout_handle->setArgument(
"id_value",
id);
386 HooksManager::callCallouts(
Hooks.hook_index_host4_identifier_,
389 callout_handle->getArgument(
"id_type", type);
390 callout_handle->getArgument(
"id_value",
id);
392 if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_CONTINUE) &&
398 context_->addHostIdentifier(type,
id);
410 if (context_->currentHost() && query_) {
411 const ClientClasses& classes = context_->currentHost()->getClientClasses4();
413 cclass != classes.
cend(); ++cclass) {
414 query_->addClass(*cclass);
424 if (!host->getNextServer().isV4Zero()) {
425 resp_->setSiaddr(host->getNextServer());
428 std::string sname = host->getServerHostname();
429 if (!sname.empty()) {
430 resp_->setSname(reinterpret_cast<const uint8_t*>(sname.c_str()),
434 std::string bootfile = host->getBootFileName();
435 if (!bootfile.empty()) {
436 resp_->setFile(reinterpret_cast<const uint8_t*>(bootfile.c_str()),
445 const bool direct_response_desired)
446 : io_service_(new
IOService()), shutdown_(true), alloc_engine_(), port_(port),
473 }
catch (
const std::exception &e) {
488 }
catch(
const std::exception& ex) {
495 }
catch(
const std::exception& ex) {
507 HooksManager::getHooksManager().unloadLibraries();
518 bool sanity_only)
const {
521 if (query->isDhcp4o6()) {
530 subnet = cfgmgr.
getCurrentCfg()->getCfgSubnets4()->selectSubnet(selector);
535 HooksManager::calloutsPresent(
Hooks.hook_index_subnet4_select_)) {
548 callout_handle->setArgument(
"query4", query);
549 callout_handle->setArgument(
"subnet4", subnet);
550 callout_handle->setArgument(
"subnet4collection",
552 getCfgSubnets4()->getAll());
555 HooksManager::callCallouts(
Hooks.hook_index_subnet4_select_,
561 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
563 DHCP4_HOOK_SUBNET4_SELECT_SKIP)
564 .arg(query->getLabel());
570 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
572 DHCP4_HOOK_SUBNET4_SELECT_DROP)
573 .arg(query->getLabel());
579 callout_handle->getArgument(
"subnet4", subnet);
585 .arg(query->getLabel())
586 .arg(subnet->getID());
590 .arg(query->getLabel())
591 .arg(subnet->toText());
595 DHCP4_SUBNET_SELECTION_FAILED)
596 .arg(query->getLabel());
604 bool sanity_only)
const {
609 selector.
ciaddr_ = query->getCiaddr();
610 selector.
giaddr_ = query->getGiaddr();
621 Pkt4o6Ptr query4o6 = boost::dynamic_pointer_cast<Pkt4o6>(query);
625 const Pkt6Ptr& query6 = query4o6->getPkt6();
628 if (query6 && !query6->relay_info_.empty()) {
644 OptionCustomPtr oc = boost::dynamic_pointer_cast<OptionCustom>(sbnsel);
651 subnet = cfgmgr.
getCurrentCfg()->getCfgSubnets4()->selectSubnet4o6(selector);
656 HooksManager::calloutsPresent(
Hooks.hook_index_subnet4_select_)) {
666 callout_handle->setArgument(
"query4", query);
667 callout_handle->setArgument(
"subnet4", subnet);
668 callout_handle->setArgument(
"subnet4collection",
670 getCfgSubnets4()->getAll());
673 HooksManager::callCallouts(
Hooks.hook_index_subnet4_select_,
679 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
681 DHCP4_HOOK_SUBNET4_SELECT_SKIP)
682 .arg(query->getLabel());
688 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
690 DHCP4_HOOK_SUBNET4_SELECT_DROP)
691 .arg(query->getLabel());
697 callout_handle->getArgument(
"subnet4", subnet);
703 .arg(query->getLabel())
704 .arg(subnet->getID());
708 .arg(query->getLabel())
709 .arg(subnet->toText());
713 DHCP4_SUBNET_SELECTION_FAILED)
714 .arg(query->getLabel());
736 }
catch (
const std::exception& e) {
762 uint32_t timeout = 1;
773 .arg(query->getRemoteAddr().toText())
774 .arg(query->getRemotePort())
775 .arg(query->getLocalAddr().toText())
776 .arg(query->getLocalPort())
777 .arg(query->getIface());
794 }
catch (
const std::exception& e) {
811 }
catch (
const std::exception& e) {
828 DHCP4_PACKET_DROP_0008)
829 .arg(query->getLabel());
850 static_cast<int64_t>(1));
852 bool skip_unpack =
false;
856 if (HooksManager::calloutsPresent(
Hooks.hook_index_buffer4_receive_)) {
869 callout_handle->setArgument(
"query4", query);
872 HooksManager::callCallouts(
Hooks.hook_index_buffer4_receive_,
878 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
880 DHCP4_HOOK_BUFFER_RCVD_DROP)
881 .arg(query->getRemoteAddr().toText())
882 .arg(query->getLocalAddr().toText())
883 .arg(query->getIface());
891 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
893 DHCP4_HOOK_BUFFER_RCVD_SKIP)
894 .arg(query->getRemoteAddr().toText())
895 .arg(query->getLocalAddr().toText())
896 .arg(query->getIface());
900 callout_handle->getArgument(
"query4", query);
908 .arg(query->getRemoteAddr().toText())
909 .arg(query->getLocalAddr().toText())
910 .arg(query->getIface());
916 DHCP4_PACKET_OPTIONS_SKIPPED)
918 }
catch (
const std::exception& e) {
921 DHCP4_PACKET_DROP_0001)
922 .arg(query->getRemoteAddr().toText())
923 .arg(query->getLocalAddr().toText())
924 .arg(query->getIface())
929 static_cast<int64_t>(1));
931 static_cast<int64_t>(1));
952 static_cast<int64_t>(1));
958 int type = query->getType();
960 .arg(query->getLabel())
961 .arg(query->getName())
963 .arg(query->getRemoteAddr())
964 .arg(query->getLocalAddr())
965 .arg(query->getIface());
967 .arg(query->getLabel())
968 .arg(query->toText());
971 if (HooksManager::calloutsPresent(
Hooks.hook_index_pkt4_receive_)) {
984 callout_handle->setArgument(
"query4", query);
987 HooksManager::callCallouts(
Hooks.hook_index_pkt4_receive_,
993 if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) ||
994 (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP)) {
996 DHCP4_HOOK_PACKET_RCVD_SKIP)
997 .arg(query->getLabel());
1001 callout_handle->getArgument(
"query4", query);
1007 switch (query->getType()) {
1037 }
catch (
const std::exception& e) {
1047 DHCP4_PACKET_DROP_0007)
1048 .arg(query->getLabel())
1053 static_cast<int64_t>(1));
1056 bool packet_park =
false;
1058 if (ctx && HooksManager::calloutsPresent(
Hooks.hook_index_leases4_committed_)) {
1070 callout_handle->setArgument(
"query4", query);
1073 if (ctx->new_lease_) {
1074 new_leases->push_back(ctx->new_lease_);
1076 callout_handle->setArgument(
"leases4", new_leases);
1079 if (ctx->old_lease_) {
1080 if ((!ctx->new_lease_) || (ctx->new_lease_->addr_ != ctx->old_lease_->addr_)) {
1081 deleted_leases->push_back(ctx->old_lease_);
1084 callout_handle->setArgument(
"deleted_leases4", deleted_leases);
1087 HooksManager::callCallouts(
Hooks.hook_index_leases4_committed_,
1090 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
1092 DHCP4_HOOK_LEASES4_COMMITTED_DROP)
1093 .arg(query->getLabel());
1096 }
else if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_PARK)
1097 && allow_packet_park) {
1110 DHCP4_HOOK_LEASES4_COMMITTED_PARK)
1111 .arg(query->getLabel());
1115 HooksManager::park(
"leases4_committed", query,
1116 [
this, callout_handle, query, rsp]()
mutable {
1139 bool skip_pack =
false;
1142 if (HooksManager::calloutsPresent(
Hooks.hook_index_pkt4_send_)) {
1155 callout_handle->setArgument(
"response4", rsp);
1158 callout_handle->setArgument(
"query4", query);
1161 HooksManager::callCallouts(
Hooks.hook_index_pkt4_send_,
1167 if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) ||
1168 (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP)) {
1170 DHCP4_HOOK_PACKET_SEND_SKIP)
1171 .arg(query->getLabel());
1179 .arg(rsp->getLabel());
1181 }
catch (
const std::exception& e) {
1183 .arg(rsp->getLabel())
1201 if (HooksManager::calloutsPresent(
Hooks.hook_index_buffer4_send_)) {
1213 callout_handle->setArgument(
"response4", rsp);
1216 HooksManager::callCallouts(
Hooks.hook_index_buffer4_send_,
1222 if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) ||
1223 (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP)) {
1225 DHCP4_HOOK_BUFFER_SEND_SKIP)
1226 .arg(rsp->getLabel());
1230 callout_handle->getArgument(
"response4", rsp);
1234 .arg(rsp->getLabel())
1235 .arg(rsp->getName())
1236 .arg(static_cast<int>(rsp->getType()))
1237 .arg(rsp->getLocalAddr().isV4Zero() ?
"*" : rsp->getLocalAddr().toText())
1238 .arg(rsp->getLocalPort())
1239 .arg(rsp->getRemoteAddr())
1240 .arg(rsp->getRemotePort())
1241 .arg(rsp->getIface().empty() ?
"to be determined from routing" :
1245 DHCP4_RESPONSE_DATA)
1246 .arg(rsp->getLabel())
1247 .arg(rsp->getName())
1248 .arg(static_cast<int>(rsp->getType()))
1249 .arg(rsp->toText());
1255 }
catch (
const std::exception& e) {
1257 .arg(rsp->getLabel())
1267 boost::shared_ptr<Option4AddrLst> generated =
1268 boost::dynamic_pointer_cast<Option4AddrLst>(srvid);
1274 if (addrs.size() != 1) {
1276 <<
"Expected to contain a single IPv4 address.");
1279 return (addrs[0].toText());
1297 if (local_addr.
isV4Bcast() || query->isDhcp4o6()) {
1299 local_addr = sock_info.
addr_;
1321 if (host && !host->getCfgOption4()->empty()) {
1322 co_list.push_back(host->getCfgOption4());
1329 addr = resp->getYiaddr();
1333 if (pool && !pool->getCfgOption()->empty()) {
1334 co_list.push_back(pool->getCfgOption());
1339 if (!subnet->getCfgOption()->empty()) {
1340 co_list.push_back(subnet->getCfgOption());
1345 subnet->getSharedNetwork(network);
1346 if (network && !network->getCfgOption()->empty()) {
1347 co_list.push_back(network->getCfgOption());
1353 cclass != classes.
cend(); ++cclass) {
1356 getClientClassDictionary()->findClass(*cclass);
1367 if (ccdef->getCfgOption()->empty()) {
1371 co_list.push_back(ccdef->getCfgOption());
1395 if (co_list.empty()) {
1401 std::vector<uint8_t> requested_opts;
1409 requested_opts = option_prl->getValues();
1412 for (CfgOptionList::const_iterator copts = co_list.begin();
1413 copts != co_list.end(); ++copts) {
1421 for (OptionContainerPersistIndex::const_iterator desc = range.first;
1422 desc != range.second; ++desc) {
1424 if (desc->option_) {
1425 uint8_t code = static_cast<uint8_t>(desc->option_->getType());
1426 requested_opts.push_back(code);
1433 for (std::vector<uint8_t>::const_iterator opt = requested_opts.begin();
1434 opt != requested_opts.end(); ++opt) {
1436 if (!resp->getOption(*opt)) {
1438 for (CfgOptionList::const_iterator copts = co_list.begin();
1439 copts != co_list.end(); ++copts) {
1443 resp->addOption(desc.
option_);
1466 if (co_list.empty()) {
1471 boost::shared_ptr<OptionVendor> vendor_req = boost::dynamic_pointer_cast<
1478 std::vector<uint8_t> requested_opts;
1484 boost::dynamic_pointer_cast<OptionUint8Array>(vendor_req->getOption(
DOCSIS3_V4_ORO));
1487 requested_opts = oro->getValues();
1490 for (CfgOptionList::const_iterator copts = co_list.begin();
1491 copts != co_list.end(); ++copts) {
1499 for (OptionContainerPersistIndex::const_iterator desc = range.first;
1500 desc != range.second; ++desc) {
1502 if (desc->option_) {
1503 uint8_t code = static_cast<uint8_t>(desc->option_->getType());
1504 requested_opts.push_back(code);
1510 if (requested_opts.empty()) {
1518 for (std::vector<uint8_t>::const_iterator code = requested_opts.begin();
1519 code != requested_opts.end(); ++code) {
1520 if (!vendor_rsp->getOption(*code)) {
1521 for (CfgOptionList::const_iterator copts = co_list.begin();
1522 copts != co_list.end(); ++copts) {
1525 vendor_rsp->addOption(desc.
option_);
1543 static const uint16_t required_options[] = {
1549 static size_t required_options_size =
1550 sizeof(required_options) /
sizeof(required_options[0]);
1560 if (co_list.empty()) {
1568 for (
int i = 0; i < required_options_size; ++i) {
1569 OptionPtr opt = resp->getOption(required_options[i]);
1572 for (CfgOptionList::const_iterator copts = co_list.begin();
1573 copts != co_list.end(); ++copts) {
1575 required_options[i]);
1577 resp->addOption(desc.
option_);
1597 processClientFqdnOption(ex);
1601 DHCP4_CLIENT_HOSTNAME_PROCESS)
1603 processHostnameOption(ex);
1628 .arg(fqdn->toText());
1644 !ex.
getContext()->currentHost()->getHostname().empty()) {
1669 .arg(fqdn_resp->toText());
1679 OptionStringPtr opt_hostname = boost::dynamic_pointer_cast<OptionString>
1685 .arg(opt_hostname->getValue());
1692 if (ctx->currentHost() && !ctx->currentHost()->getHostname().empty()) {
1700 bool should_send_hostname = static_cast<bool>(opt_hostname);
1702 if (!should_send_hostname) {
1704 option_prl = boost::dynamic_pointer_cast<OptionUint8Array>
1709 const std::vector<uint8_t>&
1710 requested_opts = option_prl->getValues();
1711 if (std::find(requested_opts.begin(), requested_opts.end(),
1715 should_send_hostname =
true;
1723 if (should_send_hostname) {
1724 std::string hostname =
1725 d2_mgr.
qualifyName(ctx->currentHost()->getHostname(),
false);
1728 boost::algorithm::to_lower(hostname);
1731 DHCP4_RESERVED_HOSTNAME_ASSIGNED)
1754 if (!opt_hostname) {
1760 DHCP4_GENERATE_FQDN)
1774 .arg(opt_hostname->getValue());
1782 if (label_count == 0) {
1800 || label_count < 2) {
1814 ->getHostnameSanitizer();
1816 hostname = sanitizer->scrub(hostname);
1820 boost::algorithm::to_lower(hostname);
1822 if (label_count == 2) {
1839 .arg(opt_hostname_resp->getValue());
1848 "NULL lease specified when creating NameChangeRequest");
1850 }
else if (!old_lease || !lease->hasIdenticalFqdn(*old_lease)) {
1881 .arg(query->getLabel())
1882 .arg(query->getRemoteAddr().toText())
1883 .arg(query->getName());
1900 if (opt_requested_address) {
1901 hint = opt_requested_address->readAddress();
1903 }
else if (!query->getCiaddr().isV4Zero()) {
1904 hint = query->getCiaddr();
1916 bool fake_allocation = (query->getType() ==
DHCPDISCOVER);
1925 if (!fake_allocation && !opt_serverid && opt_requested_address) {
1928 .arg(query->getLabel())
1929 .arg(hint.toText());
1946 if (!leases_client_id.empty()) {
1952 for (
auto l = leases_client_id.begin(); l != leases_client_id.end(); ++l) {
1953 if ((*l)->subnet_id_ == s->getID()) {
1963 s = s->getNextSubnet(original_subnet, query->getClasses());
1971 if (!lease && hwaddr) {
1975 if (!leases_hwaddr.empty()) {
1980 for (
auto l = leases_hwaddr.begin(); l != leases_hwaddr.end(); ++l) {
1981 if ((*l)->subnet_id_ == s->getID()) {
1991 s = s->getNextSubnet(original_subnet, query->getClasses());
2000 bool authoritative = original_subnet->getAuthoritative();
2001 bool known_client = lease && lease->belongsToClient(hwaddr, client_id);
2002 if (!authoritative && !known_client) {
2004 DHCP4_NO_LEASE_INIT_REBOOT)
2005 .arg(query->getLabel())
2006 .arg(hint.toText());
2014 if ((known_client && (lease->addr_ != hint)) ||
2015 (!known_client && authoritative)) {
2017 DHCP4_PACKET_NAK_0002)
2018 .arg(query->getLabel())
2019 .arg(hint.toText());
2030 std::string hostname;
2031 bool fqdn_fwd =
false;
2032 bool fqdn_rev =
false;
2042 opt_hostname = boost::dynamic_pointer_cast<OptionString>
2046 hostname = opt_hostname->getValue();
2051 if (hostname ==
".") {
2062 ctx->requested_address_ = hint;
2063 ctx->fwd_dns_update_ = fqdn_fwd;
2064 ctx->rev_dns_update_ = fqdn_rev;
2065 ctx->hostname_ = hostname;
2066 ctx->fake_allocation_ = fake_allocation;
2067 ctx->callout_handle_ = callout_handle;
2073 if (subnet->getID() != ctx->subnet_->getID()) {
2075 subnet->getSharedNetwork(network);
2078 .arg(query->getLabel())
2079 .arg(subnet->toText())
2080 .arg(ctx->subnet_->toText())
2081 .arg(network->getName());
2083 subnet = ctx->subnet_;
2090 .arg(query->getLabel())
2091 .arg(lease->addr_.toText());
2097 if (!ctx->subnet_->getMatchClientId()) {
2099 .arg(ctx->query_->getLabel())
2100 .arg(ctx->subnet_->getID());
2103 resp->setYiaddr(lease->addr_);
2109 if (!fake_allocation) {
2114 resp->setCiaddr(query->getCiaddr());
2121 if (fqdn || opt_hostname) {
2122 bool should_update =
false;
2126 if (ctx->currentHost() && !ctx->currentHost()->getHostname().empty()) {
2130 static_cast<bool>(fqdn));
2131 should_update =
true;
2137 }
else if (lease->hostname_.empty()) {
2148 .arg(query->getLabel())
2149 .arg(lease->hostname_);
2151 should_update =
true;
2154 if (should_update) {
2160 if (!fake_allocation) {
2170 fqdn->setDomainName(lease->hostname_,
2172 }
else if (opt_hostname) {
2173 opt_hostname->setValue(lease->hostname_);
2178 .arg(query->getLabel())
2179 .arg(lease->hostname_)
2187 lease->valid_lft_));
2188 resp->addOption(opt);
2191 resp->addOption(getNetmaskOption(subnet));
2197 uint32_t timer_ceiling = lease->valid_lft_;
2198 if ((!subnet->getT2().unspecified()) &&
2199 (subnet->getT2() < timer_ceiling)) {
2203 resp->addOption(t2);
2206 timer_ceiling = subnet->getT2();
2211 if ((!subnet->getT1().unspecified()) &&
2212 (subnet->getT1() < timer_ceiling)) {
2216 resp->addOption(t1);
2225 .arg(query->getLabel());
2230 .arg(query->getLabel())
2239 DHCP4_PACKET_NAK_0003 : DHCP4_PACKET_NAK_0004)
2240 .arg(query->getLabel())
2241 .arg(query->getCiaddr().toText())
2242 .arg(opt_requested_address ?
2243 opt_requested_address->readAddress().toText() :
"(no address)");
2259 if (rai && rai->getOption(RAI_OPTION_RELAY_PORT)) {
2261 return (query->getRemotePort());
2286 ((!query->getCiaddr().isV4Zero()) ||
2287 (!query->isRelayed() && !query->getRemoteAddr().isV4Zero()))) ||
2288 ((query->getType() !=
DHCPINFORM) && !query->isRelayed())) {
2289 response->setRemotePort(DHCP4_CLIENT_PORT);
2294 response->setRemotePort(relay_port ? relay_port : DHCP4_SERVER_PORT);
2298 if (query->isRelayed() &&
2304 response->resetIndex();
2306 response->setIface(query->getIface());
2310 IOAddress local_addr = query->getLocalAddr();
2319 if (local_addr.
isV4Bcast() || query->isDhcp4o6()) {
2321 local_addr = sock_info.
addr_;
2331 response->setLocalAddr(local_addr);
2340 response->setIndex(query->getIndex());
2341 response->setIface(query->getIface());
2344 response->setLocalPort(DHCP4_SERVER_PORT);
2355 if (query->isDhcp4o6()) {
2356 response->setRemoteAddr(query->getRemoteAddr());
2368 if (!query->getCiaddr().isV4Zero()) {
2369 response->setRemoteAddr(query->getCiaddr());
2376 }
else if (query->isRelayed()) {
2377 response->setRemoteAddr(query->getGiaddr());
2378 response->setFlags(response->getFlags() | BOOTP_BROADCAST);
2383 response->setRemoteAddr(query->getRemoteAddr());
2390 if (query->isRelayed()) {
2399 query->getCiaddr().isV4Zero()) {
2400 response->setFlags(BOOTP_BROADCAST);
2402 response->setRemoteAddr(query->getGiaddr());
2406 }
else if (!query->getCiaddr().isV4Zero()) {
2407 response->setRemoteAddr(query->getCiaddr());
2412 }
else if (response->getType() ==
DHCPNAK) {
2416 }
else if (!response->getYiaddr().isV4Zero()) {
2431 response->setRemoteAddr(response ->getYiaddr());
2439 response->setRemoteAddr(query->getRemoteAddr());
2452 IOAddress subnet_next_server = subnet->getSiaddr();
2453 if (!subnet_next_server.
isV4Zero()) {
2454 response->setSiaddr(subnet_next_server);
2457 const string& sname = subnet->getSname();
2458 if (!sname.empty()) {
2464 response->setSname(reinterpret_cast<const uint8_t*>(sname.c_str()),
2468 const string& filename = subnet->getFilename();
2469 if (!filename.empty()) {
2475 response->setFile(reinterpret_cast<const uint8_t*>(filename.c_str()),
2483 if (!classes.
empty()) {
2492 name != classes.
cend(); ++name) {
2503 IOAddress next_server = cl->getNextServer();
2505 response->setSiaddr(next_server);
2508 const string& sname = cl->getSname();
2509 if (!sname.empty()) {
2515 response->setSname(reinterpret_cast<const uint8_t*>(sname.c_str()),
2519 const string& filename = cl->getFilename();
2520 if (!filename.empty()) {
2526 response->setFile(reinterpret_cast<const uint8_t*>(filename.c_str()),
2538 Dhcpv4Srv::getNetmaskOption(
const Subnet4Ptr& subnet) {
2539 uint32_t netmask =
getNetmask4(subnet->get().second).toUint32();
2696 .arg(release->getLabel())
2697 .arg(release->getCiaddr().toText());
2701 if (!lease->belongsToClient(release->getHWAddr(), client_id)) {
2703 .arg(release->getLabel())
2704 .arg(release->getCiaddr().toText());
2711 if (HooksManager::calloutsPresent(
Hooks.hook_index_lease4_release_)) {
2724 callout_handle->setArgument(
"query4", release);
2727 callout_handle->setArgument(
"lease4", lease);
2730 HooksManager::callCallouts(
Hooks.hook_index_lease4_release_,
2736 if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) ||
2737 (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP)) {
2740 DHCP4_HOOK_LEASE4_RELEASE_SKIP)
2741 .arg(release->getLabel());
2753 context->old_lease_ = lease;
2757 .arg(release->getLabel())
2758 .arg(lease->addr_.toText());
2761 StatsMgr::instance().addValue(
2762 StatsMgr::generateName(
"subnet", lease->subnet_id_,
"assigned-addresses"),
2763 static_cast<int64_t>(-1));
2771 .arg(release->getLabel())
2772 .arg(lease->addr_.toText());
2777 .arg(release->getLabel())
2778 .arg(release->getCiaddr())
2796 if (!opt_requested_address) {
2799 "in DHCPDECLINE sent from " << decline->getLabel());
2801 IOAddress addr(opt_requested_address->readAddress());
2819 .arg(addr.toText()).arg(decline->getLabel());
2827 client_id.reset(
new ClientId(opt_clientid->getData()));
2831 if (!lease->belongsToClient(decline->getHWAddr(), client_id)) {
2834 string client_hw = decline->getHWAddr() ?
2835 decline->getHWAddr()->toText(
false) :
"(none)";
2836 string lease_hw = lease->hwaddr_ ?
2837 lease->hwaddr_->toText(
false) :
"(none)";
2840 string client_id_txt = client_id ? client_id->toText() :
"(none)";
2841 string lease_id_txt = lease->client_id_ ?
2842 lease->client_id_->toText() :
"(none)";
2846 .arg(addr.toText()).arg(decline->getLabel())
2847 .arg(client_hw).arg(lease_hw).arg(client_id_txt).arg(lease_id_txt);
2864 if (HooksManager::calloutsPresent(
Hooks.hook_index_lease4_decline_)) {
2877 callout_handle->setArgument(
"lease4", lease);
2878 callout_handle->setArgument(
"query4", decline);
2881 HooksManager::callCallouts(
Hooks.hook_index_lease4_decline_,
2886 if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) ||
2887 (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP)) {
2889 .arg(decline->getLabel()).arg(lease->addr_.toText());
2901 StatsMgr::instance().addValue(
2902 StatsMgr::generateName(
"subnet", lease->subnet_id_,
"declined-addresses"),
2903 static_cast<int64_t>(1));
2906 StatsMgr::instance().addValue(
"declined-addresses", static_cast<int64_t>(1));
2927 context->new_lease_ = lease;
2930 .arg(decline->getLabel()).arg(lease->valid_lft_);
2966 if (ack->getRemoteAddr() != inform->getGiaddr()) {
2968 .arg(inform->getLabel())
2969 .arg(ack->getRemoteAddr())
2970 .arg(ack->getIface());
2993 .arg(query->getLabel())
2994 .arg(query->getIface());
3002 .arg(query->getLabel())
3003 .arg(query->getIface());
3013 if (pkt->isRelayed()) {
3018 if (pkt->isDhcp4o6()) {
3027 if (pkt->getRemoteAddr().isV4Zero() &&
3028 pkt->getCiaddr().isV4Zero()) {
3039 bool result = (!pkt->getLocalAddr().isV4Bcast() ||
3054 type = query->getType();
3058 .arg(query->getLabel())
3059 .arg(query->getIface());
3083 .arg(query->getLabel());
3090 .arg(query->getLabel())
3095 .arg(query->getLabel())
3122 boost::dynamic_pointer_cast<OptionCustom>(option);
3125 if (!option_custom) {
3133 if (option_custom->getDataFieldsNum() != 1) {
3139 IOAddress server_id = option_custom->readAddress();
3140 if (!server_id.
isV4()) {
3181 if (cfg_subnets->hasSubnetWithServerId(server_id)) {
3188 if (cfg_networks->hasNetworkWithServerId(server_id)) {
3195 OptionCustomPtr opt_server_id = boost::dynamic_pointer_cast<OptionCustom>
3198 return (opt_server_id && (opt_server_id->readAddress() == server_id));
3209 << query->getName());
3216 " received in message " 3217 << query->getName());
3227 if (query->getHWAddr() && !query->getHWAddr()->hwaddr_.empty()) {
3236 if (!client_id || client_id->len() == client_id->getHeaderLen()) {
3238 " provided in message " 3239 << query->getName());
3245 boost::shared_ptr<OptionString> vendor_class =
3248 if (!vendor_class) {
3257 pkt->addClass(
"ALL");
3271 for (ClientClassDefList::const_iterator it = defs_ptr->cbegin();
3272 it != defs_ptr->cend(); ++it) {
3280 if ((*it)->getRequired()) {
3284 if ((*it)->getDependOnKnown() != depend_on_known) {
3293 .arg((*it)->getName())
3296 pkt->addClass((*it)->getName());
3299 .arg((*it)->getName())
3304 .arg((*it)->getName())
3308 .arg((*it)->getName())
3309 .arg(
"get exception?");
3323 subnet->getSharedNetwork(network);
3325 const ClientClasses& to_add = network->getRequiredClasses();
3327 cclass != to_add.
cend(); ++cclass) {
3335 cclass != to_add.
cend(); ++cclass) {
3343 addr = resp->getYiaddr();
3350 cclass != to_add.
cend(); ++cclass) {
3364 cclass != classes.
cend(); ++cclass) {
3387 query->addClass(*cclass);
3400 .arg(
"get exception?");
3409 BOOST_FOREACH(
const uint16_t& code, query->getDeferredOptions()) {
3414 cclass != classes.
cend(); ++cclass) {
3418 getClientClassDictionary()->findClass(*cclass);
3424 if (!ccdef->getCfgOptionDef()) {
3455 while (query->delOption(code)) {
3459 opt = def->optionFactory(
Option::V4, code, buf.cbegin(), buf.cend());
3460 query->addOption(opt);
3490 arg(result).arg((ncr ? ncr->toText() :
" NULL "));
3502 std::stringstream tmp;
3506 tmp << endl << EXTENDED_VERSION << endl;
3507 tmp <<
"linked with:" << endl;
3508 tmp << Logger::getVersion() << endl;
3509 tmp << CryptoLink::getVersion() << endl;
3510 tmp <<
"database:" << endl;
3532 string stat_name =
"pkt4-unknown-received";
3534 switch (query->getType()) {
3536 stat_name =
"pkt4-discover-received";
3540 stat_name =
"pkt4-offer-received";
3543 stat_name =
"pkt4-request-received";
3547 stat_name =
"pkt4-ack-received";
3551 stat_name =
"pkt4-nak-received";
3554 stat_name =
"pkt4-release-received";
3557 stat_name =
"pkt4-decline-received";
3560 stat_name =
"pkt4-inform-received";
3574 static_cast<int64_t>(1));
3580 static_cast<int64_t>(1));
3584 switch (response->getType()) {
3586 stat_name =
"pkt4-offer-sent";
3589 stat_name =
"pkt4-ack-sent";
3592 stat_name =
"pkt4-nak-sent";
3600 static_cast<int64_t>(1));
3604 return (
Hooks.hook_index_buffer4_receive_);
3608 return (
Hooks.hook_index_pkt4_receive_);
3612 return (
Hooks.hook_index_subnet4_select_);
3616 return (
Hooks.hook_index_lease4_release_);
3620 return (
Hooks.hook_index_pkt4_send_);
3624 return (
Hooks.hook_index_buffer4_send_);
3628 return (
Hooks.hook_index_lease4_decline_);
3636 HooksManager::clearParkingLots();
std::string generateFqdn(const asiolink::IOAddress &address, const bool trailing_dot=true) const
Builds a FQDN based on the configuration and given IP address.
void setReservedClientClasses()
Assigns classes retrieved from host reservation database.
asiolink::IOAddress ciaddr_
ciaddr from the client's message.
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
static OptionDefinitionPtr getRuntimeOptionDef(const std::string &space, const uint16_t code)
Returns runtime (non-standard) option definition by space and option code.
void run_one()
Main server processing step.
static int getHookIndexBuffer4Send()
Returns the index for "buffer4_send" hook point.
std::string toText(const std::string &separator=", ") const
Returns all class names as text.
virtual void updateLease4(const Lease4Ptr &lease4)=0
Updates IPv4 lease.
uint32_t getVendorId() const
Returns enterprise identifier.
void appendRequestedVendorOptions(Dhcpv4Exchange &ex)
Appends requested vendor options as requested by client.
virtual ~Dhcpv4Srv()
Destructor. Used during DHCPv4 service shutdown.
std::string qualifyName(const std::string &partial_name, const bool trailing_dot) const
Adds a qualifying suffix to a given domain name.
asiolink::IOAddress remote_address_
Source address of the message.
void adjustFqdnFlags(const T &fqdn, T &fqdn_resp)
Set server FQDN flags based on configuration and a given FQDN.
isc::asiolink::IOAddress getNetmask4(uint8_t len)
Generates an IPv4 netmask of specified length.
void processPacketPktSend(hooks::CalloutHandlePtr &callout_handle, Pkt4Ptr &query, Pkt4Ptr &rsp)
Executes pkt4_send callout.
Message Type option missing.
bool getFlag(const uint8_t flag) const
Checks if the specified flag of the DHCPv4 Client FQDN Option is set.
void processPacketBufferSend(hooks::CalloutHandlePtr &callout_handle, Pkt4Ptr &rsp)
Executes buffer4_send callout and sends the response.
static std::string getDBVersion()
Local version of getDBVersion() class method.
const int DBGLVL_TRACE_BASIC
Trace basic operations.
boost::shared_ptr< OptionCustom > OptionCustomPtr
A pointer to the OptionCustom object.
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
virtual bool deleteLease(const isc::asiolink::IOAddress &addr)=0
Deletes a lease.
bool acceptMessageType(const Pkt4Ptr &query) const
Check if received message type is valid for the server to process.
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
virtual void handleSignal()
Invokes handler for the next received signal.
static int getHookIndexBuffer4Receive()
Returns the index for "buffer4_receive" hook point.
bool acceptDirectRequest(const Pkt4Ptr &query) const
Check if a message sent by directly connected client should be accepted or discarded.
Exception thrown during option unpacking This exception is thrown when an error has occurred,...
DHCPv4 Option class for handling list of IPv4 addresses.
static SubnetSelector initSelector(const Pkt4Ptr &query)
Build selector from a client's message.
std::vector< isc::asiolink::IOAddress > AddressContainer
Defines a collection of IPv4 addresses.
void buildCfgOptionList(Dhcpv4Exchange &ex)
Build the configured option list.
static void destroy()
Destroy lease manager.
void shutdown()
Instructs the server to shut down.
An abstract API for lease database.
boost::shared_ptr< const CfgOption > ConstCfgOptionPtr
Const pointer.
static CfgMgr & instance()
returns a single instance of Configuration Manager
asiolink::IOAddress option_select_
RAI link select or subnet select option.
void startSender(D2ClientErrorHandler error_handler, isc::asiolink::IOService &io_service)
Enables sending NameChangeRequests to kea-dhcp-ddns.
Result
Defines the outcome of an asynchronous NCR send.
boost::shared_ptr< SrvConfig > SrvConfigPtr
Non-const pointer to the SrvConfig.
OptionPtr interface_id_
Interface id option.
boost::shared_ptr< OptionUint8Array > OptionUint8ArrayPtr
std::vector< Lease4Ptr > Lease4Collection
A collection of IPv4 leases.
boost::shared_ptr< Option > OptionPtr
boost::shared_ptr< Subnet4 > Subnet4Ptr
A pointer to a Subnet4 object.
void initResponse()
Initializes the instance of the response message.
static void adjustRemoteAddr(Dhcpv4Exchange &ex)
Sets remote addresses for outgoing packet.
boost::shared_ptr< Option4ClientFqdn > Option4ClientFqdnPtr
A pointer to the Option4ClientFqdn object.
Represents a DHCPv6 packet.
boost::shared_ptr< OptionString > OptionStringPtr
Pointer to the OptionString object.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
void classifyPacket(const Pkt4Ptr &pkt)
Assigns incoming packet to zero or more classes.
isc::log::Logger bad_packet4_logger(DHCP4_BAD_PACKET_LOGGER_NAME)
Logger for rejected packets.
SrvConfigPtr getCurrentCfg()
Returns a pointer to the current configuration.
Holds information about DHCP service enabling status.
virtual void sendPacket(const Pkt4Ptr &pkt)
dummy wrapper around IfaceMgr::send()
boost::shared_ptr< CfgIface > CfgIfacePtr
A pointer to the CfgIface .
isc::util::SignalSetPtr signal_set_
A pointer to the object installing custom signal handlers.
asiolink::IOAddress giaddr_
giaddr from the client's message.
Represents DHCPv4 Client FQDN Option (code 81).
Forward declaration to OptionInt.
boost::shared_ptr< Pool > PoolPtr
a pointer to either IPv4 or IPv6 Pool
static Dhcp4to6Ipc & instance()
Returns pointer to the sole instance of Dhcp4to6Ipc.
boost::shared_ptr< NameChangeRequest > NameChangeRequestPtr
Defines a pointer to a NameChangeRequest.
const int DBG_DHCP4_BASIC_DATA
Debug level used to log the traces with some basic data.
isc::log::Logger options4_logger(DHCP4_OPTIONS_LOGGER_NAME)
Logger for options parser.
const int DBG_DHCP4_START
Debug level used to log information during server startup.
void discardPackets()
Discard all in-progress packets.
const_iterator cbegin() const
Iterator to the first element.
boost::shared_ptr< OptionUint32 > OptionUint32Ptr
RAII object enabling copying options retrieved from the packet.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
isc::log::Logger packet4_logger(DHCP4_PACKET_LOGGER_NAME)
Logger for processed packets.
static std::string getDBVersion()
Local version of getDBVersion() class method.
boost::shared_ptr< AllocEngine > AllocEnginePtr
A pointer to the AllocEngine object.
static int getHookIndexLease4Release()
Returns the index for "lease4_release" hook point.
static StatsMgr & instance()
Statistics Manager accessor method.
const int DBG_DHCP4_BASIC
Debug level used to trace basic operations within the code.
boost::shared_ptr< const CfgSubnets4 > ConstCfgSubnets4Ptr
Const pointer.
bool isV6LinkLocal() const
checks whether and address is IPv6 and is link-local
std::vector< uint8_t > OptionBuffer
buffer types used in DHCP code.
void processRelease(Pkt4Ptr &release, AllocEngine::ClientContext4Ptr &context)
Processes incoming DHCPRELEASE messages.
ClientClasses client_classes_
Classes that the client belongs to.
The IOService class is a wrapper for the ASIO io_service class.
Server uses routing to determine the right interface to send response.
asiolink::IOAddress first_relay_linkaddr_
First relay link address.
void setFixedFields(Dhcpv4Exchange &ex)
Sets fixed fields of the outgoing packet.
bool send(const Pkt6Ptr &pkt)
Sends an IPv6 packet.
void setMatchingPacketFilter(const bool direct_response_desired=false)
Set Packet Filter object to handle send/receive packets.
Subnet selector used to specify parameters used to select a subnet.
OptionInt< uint32_t > OptionUint32
isc::log::Logger dhcp4_logger(DHCP4_APP_LOGGER_NAME)
Base logger for DHCPv4 server.
Dhcpv4Srv(uint16_t port=DHCP4_SERVER_PORT, const bool use_bcast=true, const bool direct_response_desired=true)
Default constructor.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
boost::shared_ptr< CfgSharedNetworks4 > CfgSharedNetworks4Ptr
Pointer to the configuration of IPv4 shared networks.
void queueNCR(const NameChangeType &chg_type, const Lease4Ptr &lease)
Creates name change request from the DHCPv4 lease.
boost::shared_ptr< Pkt6 > Pkt6Ptr
A pointer to Pkt6 packet.
asiolink::IOServicePtr & getIOService()
Returns pointer to the IO service used by the server.
virtual void d2ClientErrorHandler(const dhcp_ddns::NameChangeSender::Result result, dhcp_ddns::NameChangeRequestPtr &ncr)
Implements the error handler for DHCP_DDNS IO errors.
std::list< ClientClass >::const_iterator const_iterator
Type of iterators.
structure that describes a single relay information
Forward declaration to OptionIntArray.
void processDecline(Pkt4Ptr &decline, AllocEngine::ClientContext4Ptr &context)
Process incoming DHCPDECLINE messages.
bool acceptServerId(const Pkt4Ptr &pkt) const
Verifies if the server id belongs to our server.
std::list< ConstCfgOptionPtr > CfgOptionList
Const pointer list.
volatile bool shutdown_
indicates if shutdown is in progress.
boost::shared_ptr< Lease4 > Lease4Ptr
Pointer to a Lease4 structure.
static void sanityCheck(const Pkt4Ptr &query, RequirementLevel serverid)
Verifies if specified packet meets RFC requirements.
static void appendServerID(Dhcpv4Exchange &ex)
Adds server identifier option to the server's response.
std::string getIdentifierAsText() const
Returns host identifier in a textual form.
Pkt4Ptr processRequest(Pkt4Ptr &request, AllocEngine::ClientContext4Ptr &context)
Processes incoming REQUEST and returns REPLY response.
void processPacket(Pkt4Ptr &query, Pkt4Ptr &rsp, bool allow_packet_park=true)
Process a single incoming DHCPv4 packet.
void classifyByVendor(const Pkt4Ptr &pkt)
Assign class using vendor-class-identifier option.
bool isV4Bcast() const
Convenience function to check if it is an IPv4 broadcast address.
bool isV6Zero() const
Convenience function to check if it is an IPv4 zero address.
void appendRequestedOptions(Dhcpv4Exchange &ex)
Appends options requested by client.
boost::shared_ptr< Lease4Collection > Lease4CollectionPtr
A shared pointer to the collection of IPv4 leases.
boost::shared_ptr< ClientContext4 > ClientContext4Ptr
Pointer to the ClientContext4.
static int getHookIndexLease4Decline()
Returns the index for "lease4_decline" hook point.
static std::string getDBVersion()
Local version of getDBVersion() class method.
bool hasOpenSocket(const uint16_t family) const
Checks if there is at least one socket of the specified family open.
std::pair< OptionContainerPersistIndex::const_iterator, OptionContainerPersistIndex::const_iterator > OptionContainerPersistRange
Pair of iterators to represent the range of options having the same persistency flag.
static int getHookIndexSubnet4Select()
Returns the index for "subnet4_select" hook point.
static int getHookIndexPkt4Send()
Returns the index for "pkt4_send" hook point.
const int DBG_DHCP4_DETAIL_DATA
This level is used to log the contents of packets received and sent.
A generic exception that is thrown when an unexpected error condition occurs.
boost::shared_ptr< ClientClassDictionary > ClientClassDictionaryPtr
Defines a pointer to a ClientClassDictionary.
bool run()
Main server processing loop.
static std::string getDBVersion()
Local version of getDBVersion() class method.
Wrapper class around callout handle which automatically resets handle's state.
Pkt4Ptr processInform(Pkt4Ptr &inform)
Processes incoming DHCPINFORM messages.
void stopD2()
Stops DHCP_DDNS client IO if DDNS updates are enabled.
bool isV4Zero() const
Convenience function to check if it is an IPv4 zero address.
static const IOAddress & IPV4_ZERO_ADDRESS()
Returns an address set to all zeros.
bool ddnsEnabled()
Convenience method for checking if DHCP-DDNS is enabled.
asiolink::IOAddress local_address_
Address on which the message was received.
boost::shared_ptr< Pkt4 > Pkt4Ptr
A pointer to Pkt4 object.
Flexible host identifier.
isc::asiolink::IOAddress addr_
boost::shared_ptr< const Host > ConstHostPtr
Const pointer to the Host object.
std::string getDomainName() const
Returns the domain-name in the text format.
const char *const * dhcp4_config_report
const D2ClientConfigPtr & getD2ClientConfig() const
Fetches the DHCP-DDNS configuration pointer.
void adjustDomainName(const T &fqdn, T &fqdn_resp)
Set server FQDN name based on configuration and a given FQDN.
None - host reservation is disabled.
const int DBG_DHCP4_DETAIL
Debug level used to trace detailed errors.
boost::shared_ptr< ClientId > ClientIdPtr
Shared pointer to a Client ID.
#define DHCP4_OPTION_SPACE
bool isV4() const
Convenience function to check for an IPv4 address.
static OptionDefinitionPtr getOptionDef(const std::string &space, const uint16_t code)
Return the first option definition matching a particular option code.
bool empty() const
Check if classes is empty.
const int DBG_DHCP4_HOOKS
Debug level used to trace hook related operations.
boost::shared_ptr< ClientClassDef > ClientClassDefPtr
a pointer to an ClientClassDef
OptionPtr option_
Option instance.
virtual Pkt4Ptr receivePacket(int timeout)
dummy wrapper around IfaceMgr::receive4
boost::shared_ptr< SharedNetwork4 > SharedNetwork4Ptr
Pointer to SharedNetwork4 object.
bool evaluateBool(const Expression &expr, Pkt &pkt)
Evaluate a RPN expression for a v4 or v6 packet and return a true or false decision.
static void processStatsSent(const Pkt4Ptr &response)
Updates statistics for transmitted packets.
void addValue(const std::string &name, const int64_t value)
Records incremental integer observation.
boost::shared_ptr< AllocEngine > alloc_engine_
Allocation Engine.
This is a base class for exceptions thrown from the DNS library module.
Defines the logger used by the top-level component of kea-dhcp-ddns.
NetworkStatePtr network_state_
Holds information about disabled DHCP service and/or disabled subnet/network scopes.
Datagram socket, i.e. IP/UDP socket.
void startD2()
Starts DHCP_DDNS client IO if DDNS updates are enabled.
void declineLease(const Lease4Ptr &lease, const Pkt4Ptr &decline, AllocEngine::ClientContext4Ptr &context)
Marks lease as declined.
void createNameChangeRequests(const Lease4Ptr &lease, const Lease4Ptr &old_lease)
Creates NameChangeRequests which correspond to the lease which has been acquired.
const char *const config_report[]
Represents DHCPv4 packet.
D2ClientMgr isolates Kea from the details of being a D2 client.
void getUpdateDirections(const T &fqdn_resp, bool &forward, bool &reverse)
Get directional update flags based on server FQDN flags.
static const uint8_t FLAG_E
Bit E.
RequirementLevel
defines if certain option may, must or must not appear
ReplaceClientNameMode
Defines the client name replacement modes.
boost::shared_ptr< ClientClassDefList > ClientClassDefListPtr
Defines a pointer to a ClientClassDefList.
isc::dhcp::Subnet4Ptr selectSubnet(const Pkt4Ptr &query, bool &drop, bool sanity_only=false) const
Selects a subnet for a given client's packet.
Exception thrown when a call to select is interrupted by a signal.
boost::shared_ptr< CalloutHandle > CalloutHandlePtr
A shared pointer to a CalloutHandle object.
static std::string srvidToString(const OptionPtr &opt)
converts server-id to text Converts content of server-id option to a text representation,...
isc::log::Logger hooks_logger("hooks")
Hooks Logger.
void requiredClassify(Dhcpv4Exchange &ex)
Assigns incoming packet to zero or more classes (required pass).
Pkt4Ptr getQuery() const
Returns the pointer to the query from the client.
boost::shared_ptr< Pkt4o6 > Pkt4o6Ptr
A pointer to Pkt4o6 object.
void assignLease(Dhcpv4Exchange &ex)
Assigns a lease and appends corresponding options.
static const IOAddress & IPV4_BCAST_ADDRESS()
Returns a "255.255.255.255" broadcast address.
static const std::string VENDOR_CLASS_PREFIX
this is a prefix added to the content of vendor-class option
void closeSockets()
Closes all open sockets.
Holds Client identifier or client IPv4 address.
isc::dhcp::Subnet4Ptr selectSubnet4o6(const Pkt4Ptr &query, bool &drop, bool sanity_only=false) const
Selects a subnet for a given client's DHCP4o6 packet.
bool accept(const Pkt4Ptr &query) const
Checks whether received message should be processed or discarded.
void initResponse4o6()
Initializes the DHCPv6 part of the response message.
static IfaceMgr & instance()
IfaceMgr is a singleton class.
An exception that is thrown if a DHCPv6 protocol violation occurs while processing a message (e....
boost::shared_ptr< OptionContainer > OptionContainerPtr
Pointer to the OptionContainer object.
const_iterator cend() const
Iterator to the past the end element.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
void deleteResponse()
Removes the response message by resetting the pointer to NULL.
void appendBasicOptions(Dhcpv4Exchange &ex)
Append basic options if they are not present.
std::string iface_name_
Name of the interface on which the message was received.
void processClientName(Dhcpv4Exchange &ex)
Processes Client FQDN and Hostname Options sent by a client.
CfgOptionList & getCfgOptionList()
Returns the configured option list (non-const version)
static OptionDefinitionPtr getLastResortOptionDef(const std::string &space, const uint16_t code)
Returns last resort option definition by space and option code.
isc::log::Logger ddns4_logger(DHCP4_DDNS_LOGGER_NAME)
Logger for Hostname or FQDN processing.
static uint16_t checkRelayPort(const Dhcpv4Exchange &ex)
Check if the relay port RAI sub-option was set in the query.
boost::shared_ptr< const CfgHostOperations > ConstCfgHostOperationsPtr
Pointer to the const object.
void close()
Close communication socket.
boost::shared_ptr< OptionDefinition > OptionDefinitionPtr
Pointer to option definition object.
void suspendUpdates()
Suspends sending requests.
bool dhcp4o6_
Specifies if the packet is DHCP4o6.
Defines the Dhcp4o6Ipc class.
virtual Lease4Ptr getLease4(const isc::asiolink::IOAddress &addr) const =0
Returns an IPv4 lease for specified IPv4 address.
void setReservedMessageFields()
Sets reserved values of siaddr, sname and file in the server's response.
string trim(const string &instring)
Trim Leading and Trailing Spaces.
D2ClientMgr & getD2ClientMgr()
Fetches the DHCP-DDNS manager.
isc::asiolink::IOAddress linkaddr_
fixed field in relay-forw/relay-reply
bool isDirectResponseSupported() const
Check if packet be sent directly to the client having no address.
bool isClientClassBuiltIn(const ClientClass &client_class)
Check if a client class name is builtin.
isc::log::Logger lease4_logger(DHCP4_LEASE_LOGGER_NAME)
Logger for lease allocation logic.
void insert(const ClientClass &class_name)
Insert an element.
boost::shared_ptr< StringSanitizer > StringSanitizerPtr
IdentifierType
Type of the host identifier.
static unsigned int getLabelCount(const std::string &text_name)
Return the number of labels in the Name.
The IOAddress class represents an IP addresses (version agnostic)
static LeaseMgr & instance()
Return current lease manager.
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...
void deferredUnpack(Pkt4Ptr &query)
Perform deferred option unpacking.
isc::hooks::CalloutHandlePtr getCalloutHandle(const T &pktptr)
CalloutHandle Store.
Option with defined data fields represented as buffers that can be accessed using data field index.
static std::string getVersion(bool extended)
returns Kea version on stdout and exit.
Context information for the DHCPv4 lease allocation.
static void adjustIfaceData(Dhcpv4Exchange &ex)
Set IP/UDP and interface parameters for the DHCPv4 response.
DHCPv4 and DHCPv6 allocation engine.
static void processStatsReceived(const Pkt4Ptr &query)
Class methods for DHCPv4-over-DHCPv6 handler.
OptionContainer::nth_index< 2 >::type OptionContainerPersistIndex
Type of the index #2 - option persistency flag.
Class which represents an option carrying a single string value.
Pkt4Ptr getResponse() const
Returns the pointer to the server's response.
Pkt4Ptr processDiscover(Pkt4Ptr &discover)
Processes incoming DISCOVER and returns response.
uint16_t getSocket(const isc::dhcp::Pkt6 &pkt)
Return most suitable socket for transmitting specified IPv6 packet.
Container for storing client class names.
Represents DHCPv4-over-DHCPv6 packet.
boost::shared_ptr< Expression > ExpressionPtr
Contains declarations for loggers used by the DHCPv4 server component.
This class represents vendor-specific information option.
void setFlag(const uint8_t flag, const bool set)
Modifies the value of the specified DHCPv4 Client Fqdn Option flag.
static void evaluateClasses(const Pkt4Ptr &pkt, bool depend_on_known)
Evaluate classes.
static int getHookIndexPkt4Receive()
Returns the index for "pkt4_receive" hook point.
AllocEngine::ClientContext4Ptr getContext() const
Returns the copy of the context for the Allocation engine.
Holds information about socket.
void stopSender()
Disables sending NameChangeRequests to kea-dhcp-ddns.