8 #include <kea_version.h> 42 #include <eval/eval_messages.h> 68 #include <boost/bind.hpp> 69 #include <boost/foreach.hpp> 70 #include <boost/tokenizer.hpp> 71 #include <boost/algorithm/string/erase.hpp> 72 #include <boost/algorithm/string/join.hpp> 73 #include <boost/algorithm/string/split.hpp> 97 int hook_index_buffer6_receive_;
98 int hook_index_pkt6_receive_;
99 int hook_index_subnet6_select_;
100 int hook_index_leases6_committed_;
101 int hook_index_lease6_release_;
102 int hook_index_pkt6_send_;
103 int hook_index_buffer6_send_;
104 int hook_index_lease6_decline_;
105 int hook_index_host6_identifier_;
109 hook_index_buffer6_receive_ = HooksManager::registerHook(
"buffer6_receive");
110 hook_index_pkt6_receive_ = HooksManager::registerHook(
"pkt6_receive");
111 hook_index_subnet6_select_ = HooksManager::registerHook(
"subnet6_select");
112 hook_index_leases6_committed_ = HooksManager::registerHook(
"leases6_committed");
113 hook_index_lease6_release_ = HooksManager::registerHook(
"lease6_release");
114 hook_index_pkt6_send_ = HooksManager::registerHook(
"pkt6_send");
115 hook_index_buffer6_send_ = HooksManager::registerHook(
"buffer6_send");
116 hook_index_lease6_decline_ = HooksManager::registerHook(
"lease6_decline");
117 hook_index_host6_identifier_ = HooksManager::registerHook(
"host6_identifier");
139 createStatusCode(
const Pkt6& pkt,
const uint16_t status_code,
140 const std::string& status_message) {
145 .arg(option_status->dataToText());
146 return (option_status);
164 createStatusCode(
const Pkt6& pkt,
const Option6IA& ia,
const uint16_t status_code,
165 const std::string& status_message) {
171 .arg(option_status->dataToText());
172 return (option_status);
180 const std::string Dhcpv6Srv::VENDOR_CLASS_PREFIX(
"VENDOR_CLASS_");
182 Dhcpv6Srv::Dhcpv6Srv(uint16_t port)
183 : io_service_(new
IOService()), port_(port), serverid_(), shutdown_(true),
184 alloc_engine_(), name_change_reqs_(),
212 }
catch (
const std::exception &e) {
225 }
catch(
const std::exception& ex) {
232 }
catch(
const std::exception& ex) {
242 HooksManager::getHooksManager().unloadLibraries();
268 if (
getServerID()->getData() != server_id->getData()){
270 DHCP6_PACKET_DROP_SERVERID_MISMATCH)
271 .arg(pkt->getLabel())
283 switch (pkt->getType()) {
288 if (pkt->relay_info_.empty() && !pkt->getLocalAddr().isV6Multicast()) {
290 .arg(pkt->getLabel())
291 .arg(pkt->getName());
307 ctx.
duid_ = pkt->getClientId(),
327 cfg->getIdentifierTypes()) {
344 if (HooksManager::calloutsPresent(
Hooks.hook_index_host6_identifier_)) {
348 std::vector<uint8_t> id;
357 callout_handle->setArgument(
"query6", pkt);
358 callout_handle->setArgument(
"id_type", type);
359 callout_handle->setArgument(
"id_value",
id);
362 HooksManager::callCallouts(
Hooks.hook_index_host6_identifier_,
365 callout_handle->getArgument(
"id_type", type);
366 callout_handle->getArgument(
"id_value",
id);
368 if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_CONTINUE) &&
388 if (!ctx.
hosts_.empty()) {
389 pkt->addClass(
"KNOWN");
391 .arg(pkt->getLabel())
394 pkt->addClass(
"UNKNOWN");
396 .arg(pkt->getLabel())
409 }
catch (
const std::exception& e) {
433 uint32_t timeout = 1;
444 .arg(query->getRemoteAddr().toText())
445 .arg(query->getRemotePort())
446 .arg(query->getLocalAddr().toText())
447 .arg(query->getLocalPort())
448 .arg(query->getIface());
454 StatsMgr::instance().addValue(
"pkt6-received", static_cast<int64_t>(1));
472 }
catch (
const std::exception& e) {
488 }
catch (
const std::exception& e) {
503 DHCP6_PACKET_DROP_DHCP_DISABLED)
504 .arg(query->getLabel());
520 bool skip_unpack =
false;
524 if (HooksManager::calloutsPresent(
Hooks.hook_index_buffer6_receive_)) {
537 callout_handle->setArgument(
"query6", query);
540 HooksManager::callCallouts(
Hooks.hook_index_buffer6_receive_, *callout_handle);
546 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
548 .arg(query->getRemoteAddr().toText())
549 .arg(query->getLocalAddr().toText())
550 .arg(query->getIface());
557 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
559 .arg(query->getRemoteAddr().toText())
560 .arg(query->getLocalAddr().toText())
561 .arg(query->getIface());
564 StatsMgr::instance().addValue(
"pkt6-receive-drop",
565 static_cast<int64_t>(1));
569 callout_handle->getArgument(
"query6", query);
577 .arg(query->getRemoteAddr().toText())
578 .arg(query->getLocalAddr().toText())
579 .arg(query->getIface());
585 DHCP6_PACKET_OPTIONS_SKIPPED)
587 }
catch (
const std::exception &e) {
590 DHCP6_PACKET_DROP_PARSE_FAIL)
591 .arg(query->getRemoteAddr().toText())
592 .arg(query->getLocalAddr().toText())
593 .arg(query->getIface())
597 StatsMgr::instance().addValue(
"pkt6-parse-failed",
598 static_cast<int64_t>(1));
599 StatsMgr::instance().addValue(
"pkt6-receive-drop",
600 static_cast<int64_t>(1));
606 processStatsReceived(query);
613 StatsMgr::instance().addValue(
"pkt6-receive-drop", static_cast<int64_t>(1));
623 StatsMgr::instance().addValue(
"pkt6-receive-drop", static_cast<int64_t>(1));
631 .arg(query->getLabel())
632 .arg(query->getName())
633 .arg(static_cast<int>(query->getType()))
634 .arg(query->getRemoteAddr())
635 .arg(query->getLocalAddr())
636 .arg(query->getIface());
638 .arg(query->getLabel())
639 .arg(query->toText());
644 if (HooksManager::calloutsPresent(
Hooks.hook_index_pkt6_receive_)) {
657 callout_handle->setArgument(
"query6", query);
660 HooksManager::callCallouts(
Hooks.hook_index_pkt6_receive_, *callout_handle);
665 if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) ||
666 (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP)) {
668 .arg(query->getLabel());
670 StatsMgr::instance().addValue(
"pkt6-receive-drop",
671 static_cast<int64_t>(1));
675 callout_handle->getArgument(
"query6", query);
703 switch (query->getType()) {
740 }
catch (
const std::exception& e) {
750 .arg(query->getName())
751 .arg(query->getRemoteAddr().toText())
755 StatsMgr::instance().addValue(
"pkt6-receive-drop", static_cast<int64_t>(1));
774 rsp->setRemoteAddr(query->getRemoteAddr());
775 rsp->setLocalAddr(query->getLocalAddr());
777 if (rsp->relay_info_.empty()) {
779 rsp->setRemotePort(DHCP6_CLIENT_PORT);
783 rsp->setRemotePort(relay_port ? relay_port : DHCP6_SERVER_PORT);
786 rsp->setLocalPort(DHCP6_SERVER_PORT);
787 rsp->setIndex(query->getIndex());
788 rsp->setIface(query->getIface());
790 bool packet_park =
false;
794 HooksManager::calloutsPresent(
Hooks.hook_index_leases6_committed_)) {
806 callout_handle->setArgument(
"query6", query);
813 callout_handle->setArgument(
"leases6", new_leases);
818 for (
auto const iac : ctx.
ias_) {
819 if (!iac.old_leases_.empty()) {
820 for (
auto old_lease : iac.old_leases_) {
822 deleted_leases->push_back(old_lease);
827 if ((new_lease->addr_ == old_lease->addr_) &&
828 (new_lease->prefixlen_ == old_lease->prefixlen_)) {
834 deleted_leases->push_back(old_lease);
839 callout_handle->setArgument(
"deleted_leases6", deleted_leases);
842 HooksManager::callCallouts(
Hooks.hook_index_leases6_committed_,
845 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
847 DHCP6_HOOK_LEASES6_COMMITTED_DROP)
848 .arg(query->getLabel());
851 }
else if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_PARK) {
864 DHCP6_HOOK_LEASES6_COMMITTED_PARK)
865 .arg(query->getLabel());
869 HooksManager::park(
"leases6_committed", query,
870 [
this, callout_handle, query, rsp]()
mutable {
893 bool skip_pack =
false;
899 if (HooksManager::calloutsPresent(
Hooks.hook_index_pkt6_send_)) {
911 callout_handle->setArgument(
"query6", query);
914 callout_handle->setArgument(
"response6", rsp);
917 HooksManager::callCallouts(
Hooks.hook_index_pkt6_send_, *callout_handle);
924 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
926 .arg(rsp->getLabel());
931 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
933 .arg(rsp->getLabel());
942 }
catch (
const std::exception& e) {
962 if (HooksManager::calloutsPresent(
Hooks.hook_index_buffer6_send_)) {
974 callout_handle->setArgument(
"response6", rsp);
977 HooksManager::callCallouts(
Hooks.hook_index_buffer6_send_,
983 if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) ||
984 (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP)) {
986 DHCP6_HOOK_BUFFER_SEND_SKIP)
987 .arg(rsp->getLabel());
991 callout_handle->getArgument(
"response6", rsp);
995 .arg(static_cast<int>(rsp->getType())).arg(rsp->toText());
1002 }
catch (
const std::exception& e) {
1018 tmp << hex << setw(2) << setfill('0') << static_cast<uint16_t>(*it);
1032 answer->addOption(clientid);
1037 if (!question->relay_info_.empty()) {
1038 answer->copyRelayInfo(question);
1056 co_list.push_back(ctx.
currentHost()->getCfgOption6());
1066 resource.first,
false);
1067 if (pool && !pool->getCfgOption()->empty()) {
1068 co_list.push_back(pool->getCfgOption());
1075 if (!ctx.
subnet_->getCfgOption()->empty()) {
1076 co_list.push_back(ctx.
subnet_->getCfgOption());
1081 ctx.
subnet_->getSharedNetwork(network);
1082 if (network && !network->getCfgOption()->empty()) {
1083 co_list.push_back(network->getCfgOption());
1090 cclass != classes.
cend(); ++cclass) {
1093 getClientClassDictionary()->findClass(*cclass);
1098 .arg(question->getLabel())
1105 if (ccdef->getCfgOption()->empty()) {
1110 co_list.push_back(ccdef->getCfgOption());
1124 if (co_list.empty()) {
1128 std::vector<uint16_t> requested_opts;
1132 boost::shared_ptr<OptionIntArray<uint16_t> > option_oro =
1134 (question->getOption(
D6O_ORO));
1138 requested_opts = option_oro->getValues();
1141 for (CfgOptionList::const_iterator copts = co_list.begin();
1142 copts != co_list.end(); ++copts) {
1150 for (OptionContainerPersistIndex::const_iterator desc = range.first;
1151 desc != range.second; ++desc) {
1153 requested_opts.push_back(desc->option_->getType());
1157 BOOST_FOREACH(uint16_t opt, requested_opts) {
1159 for (CfgOptionList::const_iterator copts = co_list.begin();
1160 copts != co_list.end(); ++copts) {
1164 answer->addOption(desc.
option_);
1187 boost::shared_ptr<OptionVendor> vendor_req =
1188 boost::dynamic_pointer_cast<OptionVendor>(question->getOption(
D6O_VENDOR_OPTS));
1189 if (!vendor_req || co_list.empty()) {
1193 uint32_t vendor_id = vendor_req->getVendorId();
1194 std::vector<uint16_t> requested_opts;
1199 boost::shared_ptr<OptionUint16Array> oro =
1200 boost::dynamic_pointer_cast<OptionUint16Array>(vendor_req->getOption(
DOCSIS3_V6_ORO));
1202 requested_opts = oro->getValues();
1205 for (CfgOptionList::const_iterator copts = co_list.begin();
1206 copts != co_list.end(); ++copts) {
1214 for (OptionContainerPersistIndex::const_iterator desc = range.first;
1215 desc != range.second; ++desc) {
1217 requested_opts.push_back(desc->option_->getType());
1222 if (requested_opts.empty()) {
1231 BOOST_FOREACH(uint16_t opt, requested_opts) {
1232 for (CfgOptionList::const_iterator copts = co_list.begin();
1233 copts != co_list.end(); ++copts) {
1236 vendor_rsp->addOption(desc.
option_);
1244 answer->addOption(vendor_rsp);
1251 switch (pkt->getType()) {
1272 DHCP6_UNKNOWN_MSG_RECEIVED)
1273 .arg(static_cast<int>(pkt->getType()))
1274 .arg(pkt->getIface());
1279 .arg(pkt->getName())
1280 .arg(pkt->getRemoteAddr().toText())
1286 StatsMgr::instance().addValue(
"pkt6-receive-drop", static_cast<int64_t>(1));
1296 if (client_ids.size() != 1) {
1298 << pkt->getName() <<
", but " << client_ids.size()
1305 if (client_ids.size() > 1) {
1307 <<
") client-id options received in " << pkt->getName());
1309 if (!client_ids.empty()) {
1322 if (!server_ids.empty()) {
1324 << server_ids.size() <<
" received in " << pkt->getName());
1329 if (server_ids.size() != 1) {
1331 << server_ids.size() <<
"), exactly 1 expected in message " 1338 if (server_ids.size() > 1) {
1340 <<
") server-id options received in " << pkt->getName());
1342 if (!server_ids.empty()) {
1355 uint16_t len = opt->len() - opt->getHeaderLen();
1358 << len <<
" byte(s) only");
1367 getCfgSubnets6()->selectSubnet(selector);
1370 if (HooksManager::calloutsPresent(
Hooks.hook_index_subnet6_select_)) {
1383 callout_handle->setArgument(
"query6", question);
1384 callout_handle->setArgument(
"subnet6", subnet);
1389 callout_handle->setArgument(
"subnet6collection",
1391 getCfgSubnets6()->getAll());
1394 HooksManager::callCallouts(
Hooks.hook_index_subnet6_select_, *callout_handle);
1400 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
1402 .arg(question->getLabel());
1408 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
1410 .arg(question->getLabel());
1416 callout_handle->getArgument(
"subnet6", subnet);
1422 .arg(question->getLabel())
1423 .arg(subnet->getID());
1427 .arg(question->getLabel())
1428 .arg(subnet->toText());
1432 .arg(question->getLabel());
1457 for (OptionCollection::iterator opt = question->options_.begin();
1458 opt != question->options_.end(); ++opt) {
1459 switch (opt->second->getType()) {
1462 boost::dynamic_pointer_cast<
1465 answer->addOption(answer_opt);
1471 boost::dynamic_pointer_cast<
1474 answer->addOption(answer_opt);
1484 if (ctx.
subnet_ && subnet && (subnet->getID() != ctx.
subnet_->getID())) {
1486 subnet->getSharedNetwork(network);
1489 .arg(question->getLabel())
1490 .arg(subnet->toText())
1492 .arg(network->getName());
1520 .arg(question->getLabel());
1533 .arg(question->getLabel())
1534 .arg(fqdn->toText());
1559 ctx.
hostname_ = fqdn_resp->getDomainName();
1566 .arg(question->getLabel())
1567 .arg(fqdn_resp->toText());
1568 answer->addOption(fqdn_resp);
1584 <<
" encapsulating server's message must not be" 1585 <<
" NULL when creating DNS NameChangeRequest");
1598 bool do_fwd =
false;
1599 bool do_rev =
false;
1602 if (!do_fwd && !do_rev) {
1615 "client identifier is required when creating a new" 1616 " DNS NameChangeRequest");
1623 opt_fqdn->packDomainName(name_buf);
1624 const uint8_t* name_data = static_cast<const uint8_t*>(name_buf.
getData());
1627 std::vector<uint8_t> buf_vec(name_data, name_data + name_buf.
getLength());
1634 for (OptionCollection::const_iterator answer_ia =
1635 answer_ias.begin(); answer_ia != answer_ias.end(); ++answer_ia) {
1650 bool extended_only =
false;
1653 if ((*l)->addr_ == iaaddr->getAddress()) {
1654 if ((*l)->hostname_ == opt_fqdn->getDomainName() &&
1655 (*l)->fqdn_fwd_ == do_fwd && (*l)->fqdn_rev_ == do_rev) {
1656 extended_only =
true;
1662 if (extended_only) {
1673 opt_fqdn->getDomainName(),
1674 iaaddr->getAddress().toText(),
1675 dhcid, 0, iaaddr->getValid()));
1678 DHCP6_DDNS_CREATE_ADD_NAME_CHANGE_REQUEST).arg(ncr->toText());
1694 getMACSources().get();
1696 for (CfgMACSources::const_iterator it = mac_sources.begin();
1697 it != mac_sources.end(); ++it) {
1698 hwaddr = pkt->getMAC(*it);
1709 boost::shared_ptr<Option6IA> ia) {
1715 boost::dynamic_pointer_cast<Option6IAAddr>(ia->getOption(
D6O_IAADDR));
1718 hint = hint_opt->getAddress();
1722 .arg(query->getLabel())
1724 .arg(hint_opt ? hint.toText() :
"(no hint)");
1743 "Server could not select subnet for" 1749 bool do_fwd =
false;
1750 bool do_rev =
false;
1776 if (!leases.empty()) {
1777 lease = *leases.begin();
1789 .arg(query->getLabel())
1790 .arg(lease->addr_.toText())
1791 .arg(ia->getIAID());
1793 .arg(query->getLabel())
1795 .arg(lease->toText());
1797 ia_rsp->setT1(subnet->getT1());
1798 ia_rsp->setT2(subnet->getT2());
1801 lease->preferred_lft_,
1802 lease->valid_lft_));
1803 ia_rsp->addOption(addr);
1815 DHCP6_LEASE_ADVERT_FAIL : DHCP6_LEASE_ALLOC_FAIL)
1816 .arg(query->getLabel())
1817 .arg(ia->getIAID());
1819 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
1821 "Sorry, no address could be" 1830 boost::shared_ptr<Option6IA> ia) {
1837 boost::dynamic_pointer_cast<Option6IAPrefix>(ia->getOption(
D6O_IAPREFIX));
1840 hint = hint_opt->getAddress();
1844 .arg(query->getLabel())
1846 .arg(hint_opt ? hint.toText() :
"(no hint)");
1864 "Sorry, no subnet available."));
1880 if (!leases.empty()) {
1882 ia_rsp->setT1(subnet->getT1());
1883 ia_rsp->setT2(subnet->getT2());
1885 const bool pd_exclude_requested = requestedInORO(query,
D6O_PD_EXCLUDE);
1887 for (Lease6Collection::iterator l = leases.begin();
1888 l != leases.end(); ++l) {
1893 DHCP6_PD_LEASE_ADVERT : DHCP6_PD_LEASE_ALLOC)
1894 .arg(query->getLabel())
1895 .arg((*l)->addr_.toText())
1896 .arg(static_cast<int>((*l)->prefixlen_))
1897 .arg(ia->getIAID());
1899 boost::shared_ptr<Option6IAPrefix>
1901 (*l)->prefixlen_, (*l)->preferred_lft_,
1903 ia_rsp->addOption(addr);
1905 if (pd_exclude_requested) {
1908 Pool6Ptr pool = boost::dynamic_pointer_cast<
1912 if (pd_exclude_option) {
1913 addr->addOption(pd_exclude_option);
1929 DHCP6_PD_LEASE_ADVERT_FAIL : DHCP6_PD_LEASE_ALLOC_FAIL)
1930 .arg(query->getLabel())
1931 .arg(ia->getIAID());
1933 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
1935 "Sorry, no prefixes could" 1944 boost::shared_ptr<Option6IA> ia) {
1947 .arg(query->getLabel())
1948 .arg(ia->getIAID());
1967 "Sorry, no known leases for this duid/iaid."));
1972 ia_rsp->setT1(subnet->getT1());
1973 ia_rsp->setT2(subnet->getT2());
1976 bool do_fwd =
false;
1977 bool do_rev =
false;
1997 for (OptionCollection::const_iterator it = addrs.begin();
1998 it != addrs.end(); ++it) {
2002 Option6IAAddrPtr iaaddr = boost::dynamic_pointer_cast<Option6IAAddr>(it->second);
2028 for (Lease6Collection::const_iterator l = leases.begin(); l != leases.end(); ++l) {
2030 (*l)->addr_, (*l)->preferred_lft_, (*l)->valid_lft_));
2031 ia_rsp->addOption(iaaddr);
2033 .arg(query->getLabel())
2034 .arg((*l)->addr_.toText())
2035 .arg(ia_rsp->getIAID());
2039 hints.erase(std::remove(hints.begin(), hints.end(), hint_type),
2050 if (
equalValues(query->getClientId(), (*l)->duid_)) {
2052 (*l)->addr_, 0, 0));
2053 ia_rsp->addOption(iaaddr);
2058 hints.erase(std::remove(hints.begin(), hints.end(), hint_type), hints.end());
2062 if (((*l)->hostname_ != ctx.
hostname_) || ((*l)->fqdn_fwd_ != do_fwd) ||
2063 ((*l)->fqdn_rev_ != do_rev)) {
2065 DHCP6_DDNS_LEASE_RENEW_FQDN_CHANGE)
2066 .arg(query->getLabel())
2067 .arg((*l)->toText())
2069 .arg(do_rev ?
"true" :
"false")
2070 .arg(do_fwd ?
"true" :
"false");
2078 for (AllocEngine::HintContainer::const_iterator hint = hints.begin();
2079 hint != hints.end(); ++hint) {
2081 hint->first, 0, 0));
2082 ia_rsp->addOption(iaaddr);
2086 if (leases.empty()) {
2090 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
2092 "Sorry, no addresses could be" 2093 " assigned at this time."));
2102 boost::shared_ptr<Option6IA> ia) {
2105 .arg(query->getLabel())
2106 .arg(ia->getIAID());
2123 "Sorry, no known PD leases" 2124 " for this duid/iaid."));
2144 " client sending Rebind to extend lifetime of the" 2145 " prefix (DUID=" << duid->toText() <<
", IAID=" 2146 << ia->getIAID() <<
")");
2151 ia_rsp->setT1(subnet->getT1());
2152 ia_rsp->setT2(subnet->getT2());
2162 for (OptionCollection::const_iterator it = addrs.begin();
2163 it != addrs.end(); ++it) {
2197 const bool pd_exclude_requested = requestedInORO(query,
D6O_PD_EXCLUDE);
2200 for (Lease6Collection::const_iterator l = leases.begin(); l != leases.end(); ++l) {
2203 (*l)->addr_, (*l)->prefixlen_,
2204 (*l)->preferred_lft_, (*l)->valid_lft_));
2205 ia_rsp->addOption(prf);
2208 if (pd_exclude_requested) {
2211 Pool6Ptr pool = boost::dynamic_pointer_cast<
2216 if (pd_exclude_option) {
2217 prf->addOption(pd_exclude_option);
2224 .arg(query->getLabel())
2225 .arg((*l)->addr_.toText())
2226 .arg(static_cast<int>((*l)->prefixlen_))
2227 .arg(ia->getIAID());
2231 hints.erase(std::remove(hints.begin(), hints.end(), hint_type),
2242 if (
equalValues(query->getClientId(), (*l)->duid_)) {
2244 (*l)->prefixlen_, 0, 0));
2245 ia_rsp->addOption(prefix);
2250 hints.erase(std::remove(hints.begin(), hints.end(), hint_type), hints.end());
2255 for (AllocEngine::HintContainer::const_iterator prefix = hints.begin();
2256 prefix != hints.end(); ++prefix) {
2261 if (!prefix->first.isV6Zero()) {
2263 prefix->second, 0, 0));
2264 ia_rsp->addOption(prefix_opt);
2269 if (leases.empty()) {
2273 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
2275 "Sorry, no prefixes could be" 2276 " assigned at this time."));
2294 for (OptionCollection::iterator opt = query->options_.begin();
2295 opt != query->options_.end(); ++opt) {
2296 switch (opt->second->getType()) {
2299 boost::dynamic_pointer_cast<
2302 reply->addOption(answer_opt);
2309 boost::dynamic_pointer_cast<
2312 reply->addOption(answer_opt);
2343 for (OptionCollection::iterator opt = release->options_.begin();
2344 opt != release->options_.end(); ++opt) {
2346 switch (opt->second->getType()) {
2349 boost::dynamic_pointer_cast<Option6IA>(opt->second),
2352 reply->addOption(answer_opt);
2358 boost::dynamic_pointer_cast<Option6IA>(opt->second),
2361 reply->addOption(answer_opt);
2378 reply->addOption(createStatusCode(*release, general_status,
2379 "Summary status for all processed IA_NAs"));
2384 int& general_status, boost::shared_ptr<Option6IA> ia,
2388 .arg(query->getLabel())
2389 .arg(ia->getIAID());
2406 if (!release_addr) {
2408 "You did not include an address in your RELEASE"));
2414 release_addr->getAddress());
2421 "Sorry, no known leases for this duid/iaid, can't release."));
2427 if (!lease->duid_) {
2433 .arg(query->getLabel())
2434 .arg(release_addr->getAddress().toText());
2438 "Database consistency check failed when trying to RELEASE"));
2442 if (*duid != *(lease->duid_)) {
2446 .arg(query->getLabel())
2447 .arg(release_addr->getAddress().toText())
2448 .arg(lease->duid_->toText());
2452 "This address does not belong to you, you can't release it"));
2456 if (ia->getIAID() != lease->iaid_) {
2459 .arg(query->getLabel())
2460 .arg(release_addr->getAddress().toText())
2462 .arg(ia->getIAID());
2464 "This is your address, but you used wrong IAID"));
2474 if (HooksManager::calloutsPresent(
Hooks.hook_index_lease6_release_)) {
2487 callout_handle->deleteAllArguments();
2490 callout_handle->setArgument(
"query6", query);
2493 callout_handle->setArgument(
"lease6", lease);
2496 HooksManager::callCallouts(
Hooks.hook_index_lease6_release_, *callout_handle);
2501 if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) ||
2502 (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP)) {
2505 .arg(query->getLabel());
2510 bool success =
false;
2521 "Server failed to release a lease"));
2524 .arg(query->getLabel())
2525 .arg(lease->addr_.toText())
2534 .arg(query->getLabel())
2535 .arg(lease->addr_.toText())
2538 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
STATUS_Success,
2539 "Lease released. Thank you, please come again."));
2542 StatsMgr::instance().addValue(
2543 StatsMgr::generateName(
"subnet", lease->subnet_id_,
"assigned-nas"),
2544 static_cast<int64_t>(-1));
2557 int& general_status, boost::shared_ptr<Option6IA> ia,
2572 boost::shared_ptr<Option6IAPrefix> release_prefix =
2573 boost::dynamic_pointer_cast<Option6IAPrefix>(ia->getOption(
D6O_IAPREFIX));
2574 if (!release_prefix) {
2576 "You did not include a prefix in your RELEASE"));
2582 release_prefix->getAddress());
2589 "Sorry, no known leases for this duid/iaid, can't release."));
2595 if (!lease->duid_) {
2600 .arg(query->getLabel())
2601 .arg(release_prefix->getAddress().toText())
2602 .arg(static_cast<int>(release_prefix->getLength()));
2606 "Database consistency check failed when trying to RELEASE"));
2610 if (*duid != *(lease->duid_)) {
2613 .arg(query->getLabel())
2614 .arg(release_prefix->getAddress().toText())
2615 .arg(static_cast<int>(release_prefix->getLength()))
2616 .arg(lease->duid_->toText());
2620 "This address does not belong to you, you can't release it"));
2624 if (ia->getIAID() != lease->iaid_) {
2627 .arg(query->getLabel())
2628 .arg(release_prefix->getAddress().toText())
2629 .arg(static_cast<int>(release_prefix->getLength()))
2631 .arg(ia->getIAID());
2633 "This is your address, but you used wrong IAID"));
2643 if (HooksManager::calloutsPresent(
Hooks.hook_index_lease6_release_)) {
2656 callout_handle->setArgument(
"query6", query);
2659 callout_handle->setArgument(
"lease6", lease);
2662 HooksManager::callCallouts(
Hooks.hook_index_lease6_release_, *callout_handle);
2664 skip = callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP;
2668 bool success =
false;
2677 .arg(query->getLabel());
2685 "Server failed to release a lease"));
2688 .arg(query->getLabel())
2689 .arg(lease->addr_.toText())
2690 .arg(static_cast<int>(lease->prefixlen_))
2698 .arg(query->getLabel())
2699 .arg(lease->addr_.toText())
2700 .arg(static_cast<int>(lease->prefixlen_))
2703 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
STATUS_Success,
2704 "Lease released. Thank you, please come again."));
2707 StatsMgr::instance().addValue(
2708 StatsMgr::generateName(
"subnet", lease->subnet_id_,
"assigned-pds"),
2709 static_cast<int64_t>(-1));
2725 if (opt_rapid_commit) {
2728 .arg(solicit->getLabel());
2733 response->addOption(opt_rapid_commit);
2763 updateReservedFqdn(ctx, response);
2793 updateReservedFqdn(ctx, reply);
2794 generateFqdn(reply);
2819 updateReservedFqdn(ctx, reply);
2820 generateFqdn(reply);
2845 updateReservedFqdn(ctx, reply);
2846 generateFqdn(reply);
2878 bool verified =
false;
2887 for (OptionCollection::const_iterator ia = ias.begin();
2888 ia != ias.end(); ++ia) {
2890 for (OptionCollection::const_iterator opt = opts.begin();
2891 opt != opts.end(); ++opt) {
2903 if (subnet && !subnet->inRange(iaaddr->getAddress())) {
2904 std::ostringstream status_msg;
2905 status_msg <<
"Address " << iaaddr->
getAddress()
2906 <<
" is not on link.";
2907 reply->addOption(createStatusCode(*confirm,
2915 " to the Option6IAAddrPtr. This is programming" 2916 " error and should be reported");
2933 "All addresses are on-link"));
2936 "No subnet selected"));
3012 for (OptionCollection::iterator opt = decline->options_.begin();
3013 opt != decline->options_.end(); ++opt) {
3014 switch (opt->second->getType()) {
3017 boost::dynamic_pointer_cast<Option6IA>(opt->second),
3022 reply->addOption(answer_opt);
3043 int& general_status, boost::shared_ptr<Option6IA> ia,
3047 .arg(decline->getLabel())
3048 .arg(ia->getIAID());
3063 int total_addrs = 0;
3064 for (OptionCollection::const_iterator opt = opts.begin(); opt != opts.end();
3074 if (!decline_addr) {
3081 decline_addr->getAddress());
3086 .arg(decline->getLabel()).arg(decline_addr->getAddress().toText());
3094 "Server does not know about such an address."));
3102 if (!lease->duid_) {
3108 .arg(decline->getLabel())
3109 .arg(decline_addr->getAddress().toText());
3112 "Database consistency check failed when attempting Decline."));
3118 if (*duid != *(lease->duid_)) {
3122 .arg(decline->getLabel())
3123 .arg(decline_addr->getAddress().toText())
3124 .arg(lease->duid_->toText());
3127 "This address does not belong to you, you can't decline it"));
3133 if (ia->getIAID() != lease->iaid_) {
3136 .arg(decline->getLabel())
3137 .arg(lease->addr_.toText())
3141 "This is your address, but you used wrong IAID"));
3153 new_leases.push_back(lease);
3157 if (total_addrs == 0) {
3159 "No addresses sent in IA_NA"));
3172 container->addOption(status);
3177 boost::shared_ptr<Option6IA> ia_rsp) {
3188 if (HooksManager::calloutsPresent(
Hooks.hook_index_lease6_decline_)) {
3201 callout_handle->setArgument(
"query6", decline);
3202 callout_handle->setArgument(
"lease6", lease);
3205 HooksManager::callCallouts(
Hooks.hook_index_lease6_decline_,
3211 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
3213 .arg(decline->getLabel())
3214 .arg(decline->getIface())
3215 .arg(lease->addr_.toText());
3221 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
3223 .arg(decline->getLabel())
3224 .arg(decline->getIface())
3225 .arg(lease->addr_.toText());
3236 StatsMgr::instance().addValue(
3237 StatsMgr::generateName(
"subnet", lease->subnet_id_,
"declined-addresses"),
3238 static_cast<int64_t>(1));
3241 StatsMgr::instance().addValue(
"declined-addresses", static_cast<int64_t>(1));
3250 .arg(lease->addr_.toText()).arg(lease->valid_lft_);
3252 ia_rsp->addOption(createStatusCode(*decline, *ia_rsp,
STATUS_Success,
3253 "Lease declined. Hopefully the next one will be better."));
3316 if (!vclass || vclass->getTuplesNum() == 0) {
3336 pkt->addClass(
"ALL");
3337 string classes =
"ALL ";
3351 for (ClientClassDefList::const_iterator it = defs_ptr->cbegin();
3352 it != defs_ptr->cend(); ++it) {
3360 if ((*it)->getRequired()) {
3364 if ((*it)->getDependOnKnown() != depend_on_known) {
3373 .arg((*it)->getName())
3376 pkt->addClass((*it)->getName());
3379 .arg((*it)->getName())
3384 .arg((*it)->getName())
3388 .arg((*it)->getName())
3389 .arg(
"get exception?");
3400 cclass != classes.
cend(); ++cclass) {
3401 pkt->addClass(*cclass);
3406 if (!classes.
empty()) {
3408 .arg(pkt->getLabel())
3422 subnet->getSharedNetwork(network);
3424 const ClientClasses& to_add = network->getRequiredClasses();
3426 cclass != to_add.
cend(); ++cclass) {
3434 cclass != to_add.
cend(); ++cclass) {
3449 cclass != to_add.
cend(); ++cclass) {
3463 cclass != classes.
cend(); ++cclass) {
3486 pkt->addClass(*cclass);
3499 .arg(
"get exception?");
3509 " a message must not be NULL when updating reserved FQDN");
3520 std::string name = fqdn->getDomainName();
3530 qualifyName(ctx.
currentHost()->getHostname(),
true);
3532 if (new_name != name) {
3537 answer->addOption(fqdn);
3543 Dhcpv6Srv::generateFqdn(
const Pkt6Ptr& answer) {
3546 " a message must not be NULL when generating FQDN");
3557 if (!fqdn || !fqdn->getDomainName().empty()) {
3575 std::string generated_name =
3579 .arg(answer->getLabel())
3580 .arg(generated_name);
3592 lease->hostname_ = generated_name;
3597 " for address " << addr <<
", so as it is impossible" 3598 " to update FQDN data. This is a programmatic error" 3599 " as the given address is now being handed to the" 3607 answer->addOption(fqdn);
3611 .arg(answer->getLabel())
3643 arg(result).arg((ncr ? ncr->toText() :
" NULL "));
3655 std::stringstream tmp;
3659 tmp << endl << EXTENDED_VERSION << endl;
3660 tmp <<
"linked with:" << endl;
3661 tmp << Logger::getVersion() << endl;
3662 tmp << CryptoLink::getVersion() << endl;
3663 tmp <<
"database:" << endl;
3683 if (query->relay_info_.empty()) {
3694 for (
int i = query->relay_info_.size(); i > 0 ; --i) {
3696 if (rsoo_container) {
3701 for (OptionCollection::const_iterator opt = rsoo.begin();
3702 opt != rsoo.end(); ++opt) {
3706 if (cfg_rsoo->enabled(opt->second->getType()) &&
3707 !rsp->getOption(opt->second->getType())) {
3708 rsp->addOption(opt->second);
3717 if (query->relay_info_.empty()) {
3725 return (query->getRemotePort());
3731 void Dhcpv6Srv::processStatsReceived(
const Pkt6Ptr& query) {
3735 string stat_name =
"pkt6-unknown-received";
3736 switch (query->getType()) {
3738 stat_name =
"pkt6-solicit-received";
3742 stat_name =
"pkt6-advertise-received";
3745 stat_name =
"pkt6-request-received";
3748 stat_name =
"pkt6-confirm-received";
3751 stat_name =
"pkt6-renew-received";
3754 stat_name =
"pkt6-rebind-received";
3758 stat_name =
"pkt6-reply-received";
3761 stat_name =
"pkt6-release-received";
3764 stat_name =
"pkt6-decline-received";
3767 stat_name =
"pkt6-reconfigure-received";
3770 stat_name =
"pkt6-infrequest-received";
3773 stat_name =
"pkt6-dhcpv4-query-received";
3777 stat_name =
"pkt6-dhcpv4-response-received";
3783 StatsMgr::instance().addValue(stat_name, static_cast<int64_t>(1));
3788 StatsMgr::instance().addValue(
"pkt6-sent", static_cast<int64_t>(1));
3792 switch (response->getType()) {
3794 stat_name =
"pkt6-advertise-sent";
3797 stat_name =
"pkt6-reply-sent";
3800 stat_name =
"pkt6-dhcpv4-response-sent";
3807 StatsMgr::instance().addValue(stat_name, static_cast<int64_t>(1));
3811 return (
Hooks.hook_index_buffer6_send_);
3815 Dhcpv6Srv::requestedInORO(
const Pkt6Ptr& query,
const uint16_t code)
const {
3817 boost::dynamic_pointer_cast<OptionUint16Array>(query->getOption(
D6O_ORO));
3820 const std::vector<uint16_t>& codes = oro->getValues();
3821 return (std::find(codes.begin(), codes.end(), code) != codes.end());
3831 HooksManager::clearParkingLots();
boost::shared_ptr< OptionVendorClass > OptionVendorClassPtr
Defines a pointer to the OptionVendorClass.
std::string generateFqdn(const asiolink::IOAddress &address, const bool trailing_dot=true) const
Builds a FQDN based on the configuration and given IP address.
virtual Pkt6Ptr receivePacket(int timeout)
dummy wrapper around IfaceMgr::receive6
const int DBG_DHCP6_BASIC_DATA
Debug level used to log the traces with some basic data.
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
boost::shared_ptr< DUID > DuidPtr
Pkt6Ptr processInfRequest(AllocEngine::ClientContext6 &ctx)
Processes incoming Information-request message.
std::string toText(const std::string &separator=", ") const
Returns all class names as text.
volatile bool shutdown_
Indicates if shutdown is in progress.
std::string qualifyName(const std::string &partial_name, const bool trailing_dot) const
Adds a qualifying suffix to a given domain name.
void classifyPacket(const Pkt6Ptr &pkt)
Assigns incoming packet to zero or more classes.
void adjustFqdnFlags(const T &fqdn, T &fqdn_resp)
Set server FQDN flags based on configuration and a given FQDN.
HWAddrPtr hwaddr_
Hardware/MAC address (if available, may be NULL)
isc::log::Logger packet6_logger(DHCP6_PACKET_LOGGER_NAME)
Logger for processed packets.
Represents DHCPv6 Client FQDN Option (code 39).
void sanityCheckDUID(const OptionPtr &opt, const std::string &opt_name)
verifies if received DUID option (client-id or server-id) is sane
isc::log::Logger ddns6_logger(DHCP6_DDNS_LOGGER_NAME)
Logger for Hostname or FQDN processing.
Lease6Collection changed_leases_
A pointer to any leases that have changed FQDN information.
void appendDefaultOptions(const Pkt6Ptr &question, Pkt6Ptr &answer, const CfgOptionList &co_list)
Appends default options to server's answer.
static std::string getDBVersion()
Local version of getDBVersion() class method.
isc::log::Logger options6_logger(DHCP6_OPTIONS_LOGGER_NAME)
Logger for options parser.
const int DBGLVL_TRACE_BASIC
Trace basic operations.
HintContainer hints_
client's hints
#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.
static std::string getVersion(bool extended)
returns Kea version on stdout and exit.
virtual void sendPacket(const Pkt6Ptr &pkt)
dummy wrapper around IfaceMgr::send()
void addHint(const asiolink::IOAddress &prefix, const uint8_t prefix_len=128)
Convenience method adding new hint.
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
virtual void handleSignal()
Invokes handler for the next received signal.
boost::shared_ptr< Pool6 > Pool6Ptr
a pointer an IPv6 Pool
Exception thrown during option unpacking This exception is thrown when an error has occurred,...
void releaseLeases(const Pkt6Ptr &release, Pkt6Ptr &reply, AllocEngine::ClientContext6 &ctx)
Attempts to release received addresses.
static void destroy()
Destroy lease manager.
Lease6Collection old_leases_
A pointer to any old leases that the client had before update but are no longer valid after the updat...
static Dhcp6to4Ipc & instance()
Returns pointer to the sole instance of Dhcp6to4Ipc.
An abstract API for lease database.
static CfgMgr & instance()
returns a single instance of Configuration Manager
#define DHCP6_OPTION_SPACE
void extendLeases(const Pkt6Ptr &query, Pkt6Ptr &reply, AllocEngine::ClientContext6 &ctx)
Attempts to extend the lifetime of IAs.
isc::log::Logger lease6_logger(DHCP6_LEASE_LOGGER_NAME)
Logger for lease allocation logic.
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.
void processRSOO(const Pkt6Ptr &query, const Pkt6Ptr &rsp)
Processes Relay-supplied options, if present.
boost::shared_ptr< Option > OptionPtr
const int DBG_DHCP6_HOOKS
Debug level used to trace hook related operations.
boost::shared_ptr< const CfgRSOO > ConstCfgRSOOPtr
Pointer to the const object.
const int DBG_DHCP6_BASIC
Debug level used to trace basic operations within the code.
Represents a DHCPv6 packet.
static void processStatsSent(const Pkt6Ptr &response)
Updates statistics for transmitted packets.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
the lease contains IPv6 prefix (for prefix delegation)
void appendRequestedOptions(const Pkt6Ptr &question, Pkt6Ptr &answer, const CfgOptionList &co_list)
Appends requested options to server's answer.
SrvConfigPtr getCurrentCfg()
Returns a pointer to the current configuration.
Holds information about DHCP service enabling status.
bool fwd_dns_update_
A boolean value which indicates that server takes responsibility for the forward DNS Update for this ...
DuidPtr duid_
Client identifier.
isc::util::SignalSetPtr signal_set_
A pointer to the object installing custom signal handlers.
OptionPtr extendIA_PD(const Pkt6Ptr &query, AllocEngine::ClientContext6 &ctx, Option6IAPtr ia)
Extends lifetime of the prefix.
static SubnetSelector initSelector(const Pkt6Ptr &query)
Build selector from a client's message.
void evaluateClasses(const Pkt6Ptr &pkt, bool depend_on_known)
Evaluate classes.
static std::string duidToString(const OptionPtr &opt)
converts DUID to text Converts content of DUID option to a text representation, e....
boost::shared_ptr< Pool > PoolPtr
a pointer to either IPv4 or IPv6 Pool
boost::shared_ptr< NameChangeRequest > NameChangeRequestPtr
Defines a pointer to a NameChangeRequest.
void processPacketBufferSend(hooks::CalloutHandlePtr &callout_handle, Pkt6Ptr &rsp)
Executes buffer6_send callout and sends the response.
DuidPtr get()
Returns current DUID.
const_iterator cbegin() const
Iterator to the first element.
virtual std::string getLabel() const
Returns text representation of the primary packet identifiers.
RAII object enabling copying options retrieved from the packet.
void sendRequest(dhcp_ddns::NameChangeRequestPtr &ncr)
Send the given NameChangeRequests to kea-dhcp-ddns.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
static std::string getDBVersion()
Local version of getDBVersion() class method.
std::vector< uint8_t > OptionBuffer
buffer types used in DHCP code.
Holds DUID (DHCPv6 Unique Identifier)
const char *const * dhcp6_config_report
The IOService class is a wrapper for the ASIO io_service class.
void setReservedClientClasses(const Pkt6Ptr &pkt, const AllocEngine::ClientContext6 &ctx)
Assigns classes retrieved from host reservation database.
bool send(const Pkt6Ptr &pkt)
Sends an IPv6 packet.
void setDomainName(const std::string &domain_name, const DomainNameType domain_name_type)
Set new domain-name.
static const IOAddress & IPV6_ZERO_ADDRESS()
Returns an IPv6 zero address.
const OptionCollection & getOptions() const
Returns all encapsulated options.
Subnet selector used to specify parameters used to select a subnet.
boost::shared_ptr< Option6IA > Option6IAPtr
A pointer to the Option6IA object.
This class represents Status Code option (13) from RFC 8415.
void assignLeases(const Pkt6Ptr &question, Pkt6Ptr &answer, AllocEngine::ClientContext6 &ctx)
Assigns leases.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
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.
Subnet6Ptr subnet_
Subnet selected for the client by the server.
Pkt6Ptr processRebind(AllocEngine::ClientContext6 &ctx)
Processes incoming Rebind message.
ResourceContainer allocated_resources_
Holds addresses and prefixes allocated for all IAs.
Pool information for IPv6 addresses and prefixes.
std::list< ClientClass >::const_iterator const_iterator
Type of iterators.
void classifyByVendor(const Pkt6Ptr &pkt, std::string &classes)
Assign class using vendor-class-identifier option.
Forward declaration to OptionIntArray.
const int DBG_DHCP6_START
Debug level used to log information during server startup.
OptionPtr getServerID()
Returns server-identifier option.
Option6PDExcludePtr getPrefixExcludeOption() const
Returns instance of the pool specific Prefix Exclude option.
std::list< ConstCfgOptionPtr > CfgOptionList
Const pointer list.
boost::shared_ptr< Option6IAPrefix > Option6IAPrefixPtr
Pointer to the Option6IAPrefix object.
Pkt6Ptr processSolicit(AllocEngine::ClientContext6 &ctx)
Processes incoming Solicit and returns response.
const char * DOCSIS3_CLASS_MODEM
DOCSIS3.0 compatible cable modem.
std::string getIdentifierAsText() const
Returns host identifier in a textual form.
boost::shared_ptr< Option6ClientFqdn > Option6ClientFqdnPtr
A pointer to the Option6ClientFqdn object.
static HWAddrPtr getMAC(const Pkt6Ptr &pkt)
Attempts to get a MAC/hardware address using configured sources.
void processPacketPktSend(hooks::CalloutHandlePtr &callout_handle, Pkt6Ptr &query, Pkt6Ptr &rsp)
Executes pkt6_send callout.
std::map< SubnetID, ConstHostPtr > hosts_
Holds a map of hosts belonging to the client within different subnets.
void shutdown()
Instructs the server to shut down.
RequirementLevel
defines if certain option may, must or must not appear
std::vector< IAContext > ias_
Container holding IA specific contexts.
Context information for the DHCPv6 leases allocation.
bool testServerID(const Pkt6Ptr &pkt)
Compare received server id with our server id.
void setStatusCode(boost::shared_ptr< Option6IA > &container, const OptionPtr &status)
A simple utility method that sets the status code.
static std::string getDBVersion()
Local version of getDBVersion() class method.
std::pair< OptionContainerPersistIndex::const_iterator, OptionContainerPersistIndex::const_iterator > OptionContainerPersistRange
Pair of iterators to represent the range of options having the same persistency flag.
A generic exception that is thrown when an unexpected error condition occurs.
boost::shared_ptr< ClientClassDictionary > ClientClassDictionaryPtr
Defines a pointer to a ClientClassDictionary.
void requiredClassify(const Pkt6Ptr &pkt, AllocEngine::ClientContext6 &ctx)
Assigns incoming packet to zero or more classes (required pass).
void appendRequestedVendorOptions(const Pkt6Ptr &question, Pkt6Ptr &answer, AllocEngine::ClientContext6 &ctx, const CfgOptionList &co_list)
Appends requested vendor options to server's answer.
static std::string getDBVersion()
Local version of getDBVersion() class method.
bool equalValues(const T &ptr1, const T &ptr2)
This function checks if two pointers are non-null and values are equal.
Wrapper class around callout handle which automatically resets handle's state.
static int getHookIndexBuffer6Send()
Returns the index of the buffer6_send hook.
void buildCfgOptionList(const Pkt6Ptr &question, AllocEngine::ClientContext6 &ctx, CfgOptionList &co_list)
Build the configured option list.
OptionPtr releaseIA_NA(const DuidPtr &duid, const Pkt6Ptr &query, int &general_status, boost::shared_ptr< Option6IA > ia, Lease6Ptr &old_lease)
Releases specific IA_NA option.
OptionPtr getOption(uint16_t type) const
Returns shared_ptr to suboption of specific type.
bool sanityCheck(const Pkt6Ptr &pkt)
Verifies if specified packet meets RFC requirements.
bool ddnsEnabled()
Convenience method for checking if DHCP-DDNS is enabled.
Option6IAPtr ia_rsp_
A pointer to the IA_NA/IA_PD option to be sent in response.
Flexible host identifier.
const char * DOCSIS3_CLASS_EROUTER
The class as specified in vendor-class option by the devices.
const void * getData() const
Return a pointer to the head of the data stored in the buffer.
virtual ~Dhcpv6Srv()
Destructor. Used during DHCPv6 service shutdown.
void addHostIdentifier(const Host::IdentifierType &id_type, const std::vector< uint8_t > &identifier)
Convenience function adding host identifier into host_identifiers_ list.
std::vector< uint32_t > CfgMACSources
Container for defined MAC/hardware address sources.
Defines the Dhcp6to4Ipc class.
NetworkStatePtr network_state_
Holds information about disabled DHCP service and/or disabled subnet/network scopes.
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.
const int DBG_DHCP6_DETAIL
Debug level used to trace detailed errors.
std::vector< Lease6Ptr > Lease6Collection
A collection of IPv6 leases.
std::multimap< unsigned int, OptionPtr > OptionCollection
A collection of DHCP (v4 or v6) options.
virtual Lease6Ptr getLease6(Lease::Type type, const isc::asiolink::IOAddress &addr) const =0
Returns existing IPv6 lease for a given IPv6 address.
void processClientFqdn(const Pkt6Ptr &question, const Pkt6Ptr &answer, AllocEngine::ClientContext6 &ctx)
Processes Client FQDN Option.
boost::shared_ptr< SharedNetwork6 > SharedNetwork6Ptr
Pointer to SharedNetwork6 object.
OptionPtr assignIA_NA(const isc::dhcp::Pkt6Ptr &query, const isc::dhcp::Pkt6Ptr &answer, AllocEngine::ClientContext6 &ctx, Option6IAPtr ia)
Processes IA_NA option (and assigns addresses if necessary).
bool empty() const
Check if classes is empty.
Pkt6Ptr processRequest(AllocEngine::ClientContext6 &ctx)
Processes incoming Request and returns Reply response.
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
void discardPackets()
Discards cached and parked packets Clears the call_handle store and packet parking lots of all packet...
Pkt6Ptr processRelease(AllocEngine::ClientContext6 &ctx)
Process incoming Release message.
boost::shared_ptr< ClientClassDef > ClientClassDefPtr
a pointer to an ClientClassDef
the lease contains non-temporary IPv6 address
OptionPtr option_
Option instance.
virtual void d2ClientErrorHandler(const dhcp_ddns::NameChangeSender::Result result, dhcp_ddns::NameChangeRequestPtr &ncr)
Implements the error handler for DHCP_DDNS IO errors.
OptionBuffer::const_iterator OptionBufferConstIter
const_iterator for walking over OptionBuffer
bool evaluateBool(const Expression &expr, Pkt &pkt)
Evaluate a RPN expression for a v4 or v6 packet and return a true or false decision.
size_t getLength() const
Return the length of data written in the buffer.
std::pair< isc::asiolink::IOAddress, uint8_t > ResourceType
Defines a single hint (an address + prefix-length).
boost::shared_ptr< Option6PDExclude > Option6PDExcludePtr
Pointer to the Option6PDExclude object.
bool fake_allocation_
Indicates if this is a real or fake allocation.
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.
boost::shared_ptr< Option6StatusCode > Option6StatusCodePtr
Pointer to the isc::dhcp::Option6StatusCode.
Lease6Collection new_leases_
A collection of newly allocated leases.
void initContext(const Pkt6Ptr &pkt, AllocEngine::ClientContext6 &ctx, bool &drop)
Initializes client context for specified packet.
uint32_t iaid_
iaid IAID field from IA_NA or IA_PD that is being processed
const char *const config_report[]
std::string toText() const
Convert the address to a string.
const int DBG_DHCP6_DETAIL_DATA
This level is used to log the contents of packets received and sent.
D2ClientMgr isolates Kea from the details of being a D2 client.
void run_one()
Main server processing step.
Lease::Type type_
Lease type (IA or PD)
void getUpdateDirections(const T &fqdn_resp, bool &forward, bool &reverse)
Get directional update flags based on server FQDN flags.
OptionPtr releaseIA_PD(const DuidPtr &duid, const Pkt6Ptr &query, int &general_status, boost::shared_ptr< Option6IA > ia, Lease6Ptr &old_lease)
Releases specific IA_PD option.
void startD2()
Starts DHCP_DDNS client IO if DDNS updates are enabled.
This exception is thrown when DHCP server hits the error which should result in discarding the messag...
Pkt6Ptr query_
A pointer to the client's message.
ReplaceClientNameMode
Defines the client name replacement modes.
boost::shared_ptr< ClientClassDefList > ClientClassDefListPtr
Defines a pointer to a ClientClassDefList.
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 const uint8_t FLAG_S
S bit.
isc::log::Logger hooks_logger("hooks")
Hooks Logger.
asiolink::IOServicePtr & getIOService()
Returns pointer to the IO service used by the server.
Pkt6Ptr processRenew(AllocEngine::ClientContext6 &ctx)
Processes incoming Renew message.
void stopD2()
Stops DHCP_DDNS client IO if DDNS updates are enabled.
void closeSockets()
Closes all open sockets.
bool rev_dns_update_
A boolean value which indicates that server takes responsibility for the reverse DNS Update for this ...
static IfaceMgr & instance()
IfaceMgr is a singleton class.
An exception that is thrown if a DHCPv6 protocol violation occurs while processing a message (e....
Container class for handling the DHCID value within a NameChangeRequest.
boost::shared_ptr< Lease6Collection > Lease6CollectionPtr
A shared pointer to the collection of IPv6 leases.
boost::shared_ptr< OptionContainer > OptionContainerPtr
Pointer to the OptionContainer object.
isc::dhcp::Subnet6Ptr selectSubnet(const Pkt6Ptr &question, bool &drop)
Selects a subnet for a given client's packet.
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.
OptionPtr serverid_
Server DUID (to be sent in server-identifier option)
void createIAContext()
Creates new IA context.
IAContext & currentIA()
Returns IA specific context for the currently processed IA.
boost::shared_ptr< const CfgHostOperations > ConstCfgHostOperationsPtr
Pointer to the const object.
boost::shared_ptr< AllocEngine > alloc_engine_
Allocation Engine.
void close()
Close communication socket.
uint32_t getIAID() const
Returns IA identifier.
bool run()
Main server processing loop.
Pkt6Ptr processDecline(AllocEngine::ClientContext6 &ctx)
Process incoming Decline message.
void suspendUpdates()
Suspends sending requests.
D2ClientMgr & getD2ClientMgr()
Fetches the DHCP-DDNS manager.
void send(const Pkt6Ptr &pkt)
Send message over IPC.
void processDhcp4Query(const Pkt6Ptr &dhcp4_query)
Processes incoming DHCPv4-query message.
bool isClientClassBuiltIn(const ClientClass &client_class)
Check if a client class name is builtin.
Factory for generating DUIDs (DHCP Unique Identifiers).
boost::shared_ptr< Subnet6 > Subnet6Ptr
A pointer to a Subnet6 object.
void insert(const ClientClass &class_name)
Insert an element.
OptionPtr assignIA_PD(const Pkt6Ptr &query, const isc::dhcp::Pkt6Ptr &answer, AllocEngine::ClientContext6 &ctx, boost::shared_ptr< Option6IA > ia)
Processes IA_PD option (and assigns prefixes if necessary).
IdentifierType
Type of the host identifier.
hooks::CalloutHandlePtr callout_handle_
Callout handle associated with the client's message.
bool declineLeases(const Pkt6Ptr &decline, Pkt6Ptr &reply, AllocEngine::ClientContext6 &ctx)
Attempts to decline all leases in specified Decline message.
The IOAddress class represents an IP addresses (version agnostic)
static LeaseMgr & instance()
Return current lease manager.
Class that represents IAPREFIX option in DHCPv6.
isc::hooks::CalloutHandlePtr getCalloutHandle(const T &pktptr)
CalloutHandle Store.
std::vector< ResourceType > HintContainer
Container for client's hints.
std::string hostname_
Hostname.
DHCPv4 and DHCPv6 allocation engine.
OptionContainer::nth_index< 2 >::type OptionContainerPersistIndex
Type of the index #2 - option persistency flag.
isc::log::Logger bad_packet6_logger(DHCP6_BAD_PACKET_LOGGER_NAME)
Logger for rejected packets.
boost::shared_ptr< Lease6 > Lease6Ptr
Pointer to a Lease6 structure.
Represents a DHCP-DDNS client request.
bool testUnicast(const Pkt6Ptr &pkt) const
Check if the message can be sent to unicast.
boost::shared_ptr< OptionUint16Array > OptionUint16ArrayPtr
This file provides the classes needed to embody, compose, and decompose DNS update requests that are ...
ConstHostPtr currentHost() const
Returns host from the most preferred subnet.
Container for storing client class names.
static const std::string VENDOR_CLASS_PREFIX
this is a prefix added to the content of vendor-class option
boost::shared_ptr< Expression > ExpressionPtr
OptionPtr extendIA_NA(const Pkt6Ptr &query, const Pkt6Ptr &answer, AllocEngine::ClientContext6 &ctx, Option6IAPtr ia)
Extends lifetime of the specific IA_NA option.
This class represents vendor-specific information option.
bool declineLease(const Pkt6Ptr &decline, const Lease6Ptr lease, boost::shared_ptr< Option6IA > ia_rsp)
Declines specific IPv6 lease.
boost::shared_ptr< Option6IAAddr > Option6IAAddrPtr
A pointer to the isc::dhcp::Option6IAAddr object.
static uint16_t checkRelaySourcePort(const Pkt6Ptr &query)
Used for DHCPv4-over-DHCPv6 too.
void copyClientOptions(const Pkt6Ptr &question, Pkt6Ptr &answer)
Copies required options from client message to server answer.
Pkt6Ptr processConfirm(AllocEngine::ClientContext6 &ctx)
Processes incoming Confirm message and returns Reply.
isc::log::Logger dhcp6_logger(DHCP6_APP_LOGGER_NAME)
Base logger for DHCPv6 server.
boost::shared_ptr< Subnet > SubnetPtr
A generic pointer to either Subnet4 or Subnet6 object.
This class encapsulates DHCPv6 Vendor Class and DHCPv4 V-I Vendor Class options.
virtual void updateLease6(const Lease6Ptr &lease6)=0
Updates IPv6 lease.
isc::asiolink::IOAddress getAddress() const
Returns address contained within this option.
void createNameChangeRequests(const Pkt6Ptr &answer, AllocEngine::ClientContext6 &ctx)
Creates a number of isc::dhcp_ddns::NameChangeRequest objects based on the DHCPv6 Client FQDN Option.
void processPacket(Pkt6Ptr &query, Pkt6Ptr &rsp)
Process a single incoming DHCPv6 packet.
OptionPtr declineIA(const Pkt6Ptr &decline, const DuidPtr &duid, int &general_status, boost::shared_ptr< Option6IA > ia, Lease6Collection &new_leases)
Declines leases in a single IA_NA option.
void stopSender()
Disables sending NameChangeRequests to kea-dhcp-ddns.