8 #include <kea_version.h>
66 #include <boost/foreach.hpp>
67 #include <boost/tokenizer.hpp>
68 #include <boost/algorithm/string/erase.hpp>
69 #include <boost/algorithm/string/join.hpp>
70 #include <boost/algorithm/string/split.hpp>
92 namespace ph = std::placeholders;
98 int hook_index_buffer6_receive_;
99 int hook_index_pkt6_receive_;
100 int hook_index_subnet6_select_;
101 int hook_index_leases6_committed_;
102 int hook_index_lease6_release_;
103 int hook_index_pkt6_send_;
104 int hook_index_buffer6_send_;
105 int hook_index_lease6_decline_;
106 int hook_index_host6_identifier_;
107 int hook_index_ddns6_update_;
111 hook_index_buffer6_receive_ = HooksManager::registerHook(
"buffer6_receive");
112 hook_index_pkt6_receive_ = HooksManager::registerHook(
"pkt6_receive");
113 hook_index_subnet6_select_ = HooksManager::registerHook(
"subnet6_select");
114 hook_index_leases6_committed_ = HooksManager::registerHook(
"leases6_committed");
115 hook_index_lease6_release_ = HooksManager::registerHook(
"lease6_release");
116 hook_index_pkt6_send_ = HooksManager::registerHook(
"pkt6_send");
117 hook_index_buffer6_send_ = HooksManager::registerHook(
"buffer6_send");
118 hook_index_lease6_decline_ = HooksManager::registerHook(
"lease6_decline");
119 hook_index_host6_identifier_ = HooksManager::registerHook(
"host6_identifier");
120 hook_index_ddns6_update_ = HooksManager::registerHook(
"ddns6_update");
142 createStatusCode(
const Pkt6& pkt,
const uint16_t status_code,
143 const std::string& status_message) {
148 .arg(option_status->dataToText());
149 return (option_status);
167 createStatusCode(
const Pkt6& pkt,
const Option6IA& ia,
const uint16_t status_code,
168 const std::string& status_message) {
174 .arg(option_status->dataToText());
175 return (option_status);
180 std::set<std::string> dhcp6_statistics = {
182 "pkt6-solicit-received",
183 "pkt6-advertise-received",
184 "pkt6-request-received",
185 "pkt6-reply-received",
186 "pkt6-renew-received",
187 "pkt6-rebind-received",
188 "pkt6-decline-received",
189 "pkt6-release-received",
190 "pkt6-infrequest-received",
191 "pkt6-dhcpv4-query-received",
192 "pkt6-dhcpv4-response-received",
193 "pkt6-unknown-received",
195 "pkt6-advertise-sent",
197 "pkt6-dhcpv4-response-sent",
200 "v6-allocation-fail",
201 "v6-allocation-fail-shared-network",
202 "v6-allocation-fail-subnet",
203 "v6-allocation-fail-no-pools",
204 "v6-allocation-fail-classes",
205 "v6-ia-na-lease-reuses",
206 "v6-ia-pd-lease-reuses",
214 const std::string Dhcpv6Srv::VENDOR_CLASS_PREFIX(
"VENDOR_CLASS_");
216 Dhcpv6Srv::Dhcpv6Srv(uint16_t server_port, uint16_t client_port)
217 : io_service_(new
IOService()), server_port_(server_port),
218 client_port_(client_port), serverid_(), shutdown_(true),
219 alloc_engine_(), name_change_reqs_(),
249 }
catch (
const std::exception &e) {
264 for (
auto it = dhcp6_statistics.begin(); it != dhcp6_statistics.end(); ++it) {
266 stats_mgr.
setValue((*it),
static_cast<int64_t
>(0));
276 }
catch (
const std::exception& ex) {
283 }
catch (
const std::exception& ex) {
293 HooksManager::prepareUnloadLibraries();
294 if (!HooksManager::unloadLibraries()) {
295 auto names = HooksManager::getLibraryNames();
297 if (!names.empty()) {
299 for (
size_t i = 1; i < names.size(); ++i) {
300 msg += std::string(
", ") + names[i];
330 if (
getServerID()->getData() != server_id->getData()){
332 .arg(pkt->getLabel())
344 switch (pkt->getType()) {
349 if (pkt->relay_info_.empty() && !pkt->getLocalAddr().isV6Multicast()) {
351 .arg(pkt->getLabel())
352 .arg(pkt->getName());
368 cfg->getIdentifierTypes()) {
385 if (HooksManager::calloutsPresent(
Hooks.hook_index_host6_identifier_)) {
389 std::vector<uint8_t> id;
398 callout_handle->setArgument(
"query6", ctx.
query_);
399 callout_handle->setArgument(
"id_type", type);
400 callout_handle->setArgument(
"id_value",
id);
403 HooksManager::callCallouts(
Hooks.hook_index_host6_identifier_,
406 callout_handle->getArgument(
"id_type", type);
407 callout_handle->getArgument(
"id_value",
id);
409 if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_CONTINUE) &&
432 ctx.
duid_ = query->getClientId();
452 if (global_host && !global_host->getClientClasses6().empty()) {
457 const ClientClasses& classes = global_host->getClientClasses6();
459 cclass != classes.
cend(); ++cclass) {
460 query->addClass(*cclass);
469 query->addClass(
"KNOWN");
471 .arg(query->getLabel())
478 if (query->inClass(
"DROP")) {
481 .arg(query->toText());
482 StatsMgr::instance().addValue(
"pkt6-receive-drop",
483 static_cast<int64_t
>(1));
488 ctx.
hosts_[SUBNET_ID_GLOBAL] = global_host;
525 ctx.
subnet_->getSharedNetwork(sn);
537 global_host && !global_host->getClientClasses6().empty()) ||
538 (!sn && current_host && !current_host->getClientClasses6().empty())) {
559 if (!ctx.
hosts_.empty()) {
560 pkt->addClass(
"KNOWN");
562 .arg(pkt->getLabel())
565 pkt->addClass(
"UNKNOWN");
567 .arg(pkt->getLabel())
575 if (!classes.
empty()) {
577 .arg(pkt->getLabel())
582 if (pkt->inClass(
"DROP")) {
585 StatsMgr::instance().addValue(
"pkt6-receive-drop",
586 static_cast<int64_t
>(1));
598 while (__AFL_LOOP(fuzzer.maxLoopCount())) {
608 }
catch (
const std::exception& e) {
625 MultiThreadingMgr::instance().apply(
false, 0, 0);
638 uint32_t timeout = 1;
649 .arg(query->getRemoteAddr().toText())
650 .arg(query->getRemotePort())
651 .arg(query->getLocalAddr().toText())
652 .arg(query->getLocalPort())
653 .arg(query->getIface());
659 StatsMgr::instance().addValue(
"pkt6-received",
static_cast<int64_t
>(1));
675 }
catch (
const std::exception& e) {
688 .arg(query->getLabel());
691 if (MultiThreadingMgr::instance().getMode()) {
692 typedef function<void()> CallBack;
693 boost::shared_ptr<CallBack> call_back =
696 if (!MultiThreadingMgr::instance().getThreadPool().add(call_back)) {
709 }
catch (
const std::exception& e) {
732 query->addClass(
"ALL");
734 bool skip_unpack =
false;
738 if (HooksManager::calloutsPresent(
Hooks.hook_index_buffer6_receive_)) {
751 callout_handle->setArgument(
"query6", query);
754 HooksManager::callCallouts(
Hooks.hook_index_buffer6_receive_, *callout_handle);
760 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
762 .arg(query->getRemoteAddr().toText())
763 .arg(query->getLocalAddr().toText())
764 .arg(query->getIface());
771 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
773 .arg(query->getRemoteAddr().toText())
774 .arg(query->getLocalAddr().toText())
775 .arg(query->getIface());
778 StatsMgr::instance().addValue(
"pkt6-receive-drop",
779 static_cast<int64_t
>(1));
783 callout_handle->getArgument(
"query6", query);
791 .arg(query->getRemoteAddr().toText())
792 .arg(query->getLocalAddr().toText())
793 .arg(query->getIface());
801 }
catch (
const std::exception &e) {
804 .arg(query->getRemoteAddr().toText())
805 .arg(query->getLocalAddr().toText())
806 .arg(query->getIface())
810 StatsMgr::instance().addValue(
"pkt6-parse-failed",
811 static_cast<int64_t
>(1));
812 StatsMgr::instance().addValue(
"pkt6-receive-drop",
813 static_cast<int64_t
>(1));
819 processStatsReceived(query);
826 StatsMgr::instance().addValue(
"pkt6-receive-drop",
static_cast<int64_t
>(1));
836 StatsMgr::instance().addValue(
"pkt6-receive-drop",
static_cast<int64_t
>(1));
844 .arg(query->getLabel())
845 .arg(query->getName())
846 .arg(
static_cast<int>(query->getType()))
847 .arg(query->getRemoteAddr())
848 .arg(query->getLocalAddr())
849 .arg(query->getIface());
851 .arg(query->getLabel())
852 .arg(query->toText());
857 if (HooksManager::calloutsPresent(
Hooks.hook_index_pkt6_receive_)) {
870 callout_handle->setArgument(
"query6", query);
873 HooksManager::callCallouts(
Hooks.hook_index_pkt6_receive_, *callout_handle);
878 if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) ||
879 (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP)) {
881 .arg(query->getLabel());
883 StatsMgr::instance().addValue(
"pkt6-receive-drop",
884 static_cast<int64_t
>(1));
888 callout_handle->getArgument(
"query6", query);
897 if (query->inClass(
"DROP")) {
899 .arg(query->toText());
900 StatsMgr::instance().addValue(
"pkt6-receive-drop",
901 static_cast<int64_t
>(1));
918 }
catch (
const std::exception& e) {
932 if (MultiThreadingMgr::instance().getMode() &&
942 if (!client_handler.
tryLock(query, cont)) {
972 switch (query->getType()) {
1009 }
catch (
const std::exception& e) {
1019 .arg(query->getName())
1020 .arg(query->getRemoteAddr().toText())
1024 StatsMgr::instance().addValue(
"pkt6-receive-drop",
static_cast<int64_t
>(1));
1043 rsp->setRemoteAddr(query->getRemoteAddr());
1044 rsp->setLocalAddr(query->getLocalAddr());
1049 }
else if (rsp->relay_info_.empty()) {
1051 rsp->setRemotePort(DHCP6_CLIENT_PORT);
1055 rsp->setRemotePort(relay_port ? relay_port : DHCP6_SERVER_PORT);
1061 rsp->setLocalPort(DHCP6_SERVER_PORT);
1063 rsp->setIndex(query->getIndex());
1064 rsp->setIface(query->getIface());
1069 HooksManager::calloutsPresent(
Hooks.hook_index_leases6_committed_)) {
1093 std::shared_ptr<ScopedCalloutHandleState> callout_handle_state =
1094 std::make_shared<ScopedCalloutHandleState>(callout_handle);
1099 callout_handle->setArgument(
"query6", query);
1105 if (new_lease->reuseable_valid_lft_ == 0) {
1106 new_leases->push_back(new_lease);
1110 callout_handle->setArgument(
"leases6", new_leases);
1115 for (
auto const& iac : ctx.
ias_) {
1116 if (!iac.old_leases_.empty()) {
1117 for (
auto old_lease : iac.old_leases_) {
1119 deleted_leases->push_back(old_lease);
1122 bool in_new =
false;
1124 if ((new_lease->addr_ == old_lease->addr_) &&
1126 (new_lease->prefixlen_ == old_lease->prefixlen_))) {
1132 deleted_leases->push_back(old_lease);
1137 callout_handle->setArgument(
"deleted_leases6", deleted_leases);
1140 uint32_t parked_packet_limit = 0;
1144 parked_packet_limit = ppl->intValue();
1147 if (parked_packet_limit) {
1148 const auto& parking_lot = ServerHooks::getServerHooks().
1149 getParkingLotPtr(
"leases6_committed");
1150 if (parking_lot && (parking_lot->size() >= parked_packet_limit)) {
1154 .arg(parked_packet_limit)
1155 .arg(query->getLabel());
1157 static_cast<int64_t
>(1));
1167 HooksManager::park(
"leases6_committed", query,
1168 [
this, callout_handle, query, rsp, callout_handle_state]()
mutable {
1169 if (MultiThreadingMgr::instance().getMode()) {
1170 typedef function<void()> CallBack;
1171 boost::shared_ptr<CallBack> call_back =
1173 this, callout_handle, query, rsp));
1174 callout_handle_state->on_completion_ = [call_back]() {
1175 MultiThreadingMgr::instance().getThreadPool().add(call_back);
1185 HooksManager::callCallouts(
Hooks.hook_index_leases6_committed_,
1189 HooksManager::drop(
"leases6_committed", query);
1193 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_PARK) {
1195 .arg(query->getLabel());
1203 HooksManager::drop(
"leases6_committed", query);
1204 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
1206 .arg(query->getLabel());
1224 }
catch (
const std::exception& e) {
1240 bool skip_pack =
false;
1246 if (HooksManager::calloutsPresent(
Hooks.hook_index_pkt6_send_)) {
1258 callout_handle->setArgument(
"query6", query);
1261 callout_handle->setArgument(
"response6", rsp);
1264 HooksManager::callCallouts(
Hooks.hook_index_pkt6_send_, *callout_handle);
1271 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
1273 .arg(rsp->getLabel());
1278 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
1280 .arg(rsp->getLabel());
1289 }
catch (
const std::exception& e) {
1309 if (HooksManager::calloutsPresent(
Hooks.hook_index_buffer6_send_)) {
1321 callout_handle->setArgument(
"response6", rsp);
1324 HooksManager::callCallouts(
Hooks.hook_index_buffer6_send_,
1330 if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) ||
1331 (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP)) {
1334 .arg(rsp->getLabel());
1338 callout_handle->getArgument(
"response6", rsp);
1342 .arg(rsp->getLabel())
1343 .arg(rsp->getName())
1344 .arg(
static_cast<int>(rsp->getType()))
1345 .arg(rsp->getLocalAddr().isV6Zero() ?
"*" : rsp->getLocalAddr().toText())
1346 .arg(rsp->getLocalPort())
1347 .arg(rsp->getRemoteAddr())
1348 .arg(rsp->getRemotePort())
1349 .arg(rsp->getIface());
1352 .arg(
static_cast<int>(rsp->getType())).arg(rsp->toText());
1359 }
catch (
const std::exception& e) {
1375 tmp << hex << setw(2) << setfill('0') << static_cast<uint16_t>(*it);
1389 answer->addOption(clientid);
1394 if (!question->relay_info_.empty()) {
1395 answer->copyRelayInfo(question);
1413 co_list.push_back(ctx.
currentHost()->getCfgOption6());
1421 ctx.
subnet_->getPool(resource.getPrefixLength() == 128 ?
1423 resource.getAddress(),
1425 if (pool && !pool->getCfgOption()->empty()) {
1426 co_list.push_back(pool->getCfgOption());
1431 if (!ctx.
subnet_->getCfgOption()->empty()) {
1432 co_list.push_back(ctx.
subnet_->getCfgOption());
1437 ctx.
subnet_->getSharedNetwork(network);
1438 if (network && !network->getCfgOption()->empty()) {
1439 co_list.push_back(network->getCfgOption());
1446 cclass != classes.
cend(); ++cclass) {
1449 getClientClassDictionary()->findClass(*cclass);
1454 .arg(question->getLabel())
1461 if (ccdef->getCfgOption()->empty()) {
1466 co_list.push_back(ccdef->getCfgOption());
1479 if (co_list.empty()) {
1483 set<uint16_t> requested_opts;
1492 for (uint16_t code : option_oro->getValues()) {
1493 static_cast<void>(requested_opts.insert(code));
1497 set<uint16_t> cancelled_opts;
1501 for (
auto const& copts : co_list) {
1509 for (OptionContainerPersistIndex::const_iterator desc = prange.first;
1510 desc != prange.second; ++desc) {
1512 if (desc->option_) {
1513 uint16_t code = desc->option_->
getType();
1514 static_cast<void>(requested_opts.insert(code));
1520 for (OptionContainerCancelIndex::const_iterator desc = crange.first;
1521 desc != crange.second; ++desc) {
1523 if (desc->option_) {
1524 uint16_t code = desc->option_->getType();
1525 static_cast<void>(cancelled_opts.insert(code));
1532 for (uint16_t opt : requested_opts) {
1534 if (cancelled_opts.count(opt) > 0) {
1542 if (!answer->getOption(opt)) {
1544 for (
auto const& copts : co_list) {
1548 answer->addOption(desc.
option_);
1561 set<uint32_t> vendor_ids;
1565 vendor_class = boost::dynamic_pointer_cast<OptionVendorClass>(opt.second);
1567 uint32_t vendor_id = vendor_class->getVendorId();
1568 static_cast<void>(vendor_ids.insert(vendor_id));
1572 for (
auto const& copts : co_list) {
1575 if (!desc.option_) {
1579 boost::dynamic_pointer_cast<OptionVendorClass>(desc.option_);
1580 if (!vendor_class) {
1584 uint32_t vendor_id = vendor_class->getVendorId();
1585 if (vendor_ids.count(vendor_id) > 0) {
1589 answer->addOption(desc.option_);
1590 static_cast<void>(vendor_ids.insert(vendor_id));
1599 set<uint32_t> vendor_ids;
1603 vendor_opts = boost::dynamic_pointer_cast<OptionVendor>(opt.second);
1605 uint32_t vendor_id = vendor_opts->getVendorId();
1606 static_cast<void>(vendor_ids.insert(vendor_id));
1610 for (
auto const& copts : co_list) {
1613 if (!desc.option_) {
1617 boost::dynamic_pointer_cast<OptionVendor>(desc.option_);
1622 uint32_t vendor_id = vendor_opts->getVendorId();
1623 if (vendor_ids.count(vendor_id) > 0) {
1629 answer->addOption(vendor_opts);
1630 static_cast<void>(vendor_ids.insert(vendor_id));
1649 if (!ctx.
subnet_ || co_list.empty()) {
1653 set<uint32_t> vendor_ids;
1657 map<uint32_t, OptionVendorPtr> vendor_rsps;
1660 vendor_rsp = boost::dynamic_pointer_cast<OptionVendor>(opt.second);
1662 uint32_t vendor_id = vendor_rsp->getVendorId();
1663 vendor_rsps[vendor_id] = vendor_rsp;
1664 static_cast<void>(vendor_ids.insert(vendor_id));
1670 map<uint32_t, OptionVendorPtr> vendor_reqs;
1673 vendor_req = boost::dynamic_pointer_cast<OptionVendor>(opt.second);
1675 uint32_t vendor_id = vendor_req->getVendorId();
1676 vendor_reqs[vendor_id] = vendor_req;
1677 static_cast<void>(vendor_ids.insert(vendor_id));
1685 vendor_class = boost::dynamic_pointer_cast<OptionVendorClass>(opt.second);
1687 uint32_t vendor_id = vendor_class->getVendorId();
1688 static_cast<void>(vendor_ids.insert(vendor_id));
1694 if (vendor_ids.empty()) {
1698 map<uint32_t, set<uint16_t> > requested_opts;
1712 oro = boost::dynamic_pointer_cast<OptionUint16Array>(oro_generic);
1715 set<uint16_t> oro_req_opts;
1716 for (uint16_t code : oro->getValues()) {
1717 static_cast<void>(oro_req_opts.insert(code));
1723 map<uint32_t, set<uint16_t> > cancelled_opts;
1727 for (uint32_t vendor_id : vendor_ids) {
1728 for (
auto const& copts : co_list) {
1736 for (OptionContainerPersistIndex::const_iterator desc = prange.first;
1737 desc != prange.second; ++desc) {
1738 if (!desc->option_) {
1742 uint16_t code = desc->option_->getType();
1743 static_cast<void>(requested_opts[vendor_id].insert(code));
1748 for (OptionContainerCancelIndex::const_iterator desc = crange.first;
1749 desc != crange.second; ++desc) {
1750 if (!desc->option_) {
1754 uint16_t code = desc->option_->getType();
1755 static_cast<void>(cancelled_opts[vendor_id].insert(code));
1764 if (requested_opts[vendor_id].empty()) {
1771 if (vendor_rsps.count(vendor_id) > 0) {
1772 vendor_rsp = vendor_rsps[vendor_id];
1780 for (uint16_t opt : requested_opts[vendor_id]) {
1781 if (cancelled_opts[vendor_id].count(opt) > 0) {
1784 if (!vendor_rsp->getOption(opt)) {
1785 for (
auto const& copts : co_list) {
1788 vendor_rsp->addOption(desc.
option_);
1798 if (added && (vendor_rsps.count(vendor_id) == 0)) {
1799 answer->addOption(vendor_rsp);
1807 switch (pkt->getType()) {
1829 .arg(
static_cast<int>(pkt->getType()))
1830 .arg(pkt->getIface());
1835 .arg(pkt->getName())
1836 .arg(pkt->getRemoteAddr().toText())
1842 StatsMgr::instance().addValue(
"pkt6-receive-drop",
static_cast<int64_t
>(1));
1852 if (client_ids.size() != 1) {
1854 << pkt->getName() <<
", but " << client_ids.size()
1861 if (client_ids.size() > 1) {
1863 <<
") client-id options received in " << pkt->getName());
1865 if (!client_ids.empty()) {
1878 if (!server_ids.empty()) {
1880 << server_ids.size() <<
" received in " << pkt->getName());
1885 if (server_ids.size() != 1) {
1887 << server_ids.size() <<
"), exactly 1 expected in message "
1894 if (server_ids.size() > 1) {
1896 <<
") server-id options received in " << pkt->getName());
1898 if (!server_ids.empty()) {
1911 uint16_t len = opt->len() - opt->getHeaderLen();
1924 getCfgSubnets6()->selectSubnet(selector);
1927 if (HooksManager::calloutsPresent(
Hooks.hook_index_subnet6_select_)) {
1940 callout_handle->setArgument(
"query6", question);
1941 callout_handle->setArgument(
"subnet6", subnet);
1946 callout_handle->setArgument(
"subnet6collection",
1948 getCfgSubnets6()->getAll());
1951 HooksManager::callCallouts(
Hooks.hook_index_subnet6_select_, *callout_handle);
1957 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
1959 .arg(question->getLabel());
1965 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
1967 .arg(question->getLabel());
1973 callout_handle->getArgument(
"subnet6", subnet);
1979 .arg(question->getLabel())
1980 .arg(subnet->getID());
1984 .arg(question->getLabel())
1985 .arg(subnet->toText());
1989 .arg(question->getLabel());
2014 for (
const auto& opt : question->options_) {
2015 switch (opt.second->getType()) {
2018 boost::dynamic_pointer_cast<
2021 answer->addOption(answer_opt);
2027 boost::dynamic_pointer_cast<
2030 answer->addOption(answer_opt);
2055 if (ddns_params->getEnableUpdates() &&
2065 .arg(question->getLabel());
2078 .arg(question->getLabel())
2079 .arg(fqdn->toText());
2098 *ddns_params,
true),
2108 ctx.
hostname_ = fqdn_resp->getDomainName();
2115 .arg(question->getLabel())
2116 .arg(fqdn_resp->toText());
2117 answer->addOption(fqdn_resp);
2121 if (HooksManager::calloutsPresent(
Hooks.hook_index_ddns6_update_)) {
2132 callout_handle->setArgument(
"query6", question);
2133 callout_handle->setArgument(
"response6", answer);
2134 callout_handle->setArgument(
"subnet6", subnet);
2135 callout_handle->setArgument(
"hostname", ctx.
hostname_);
2138 callout_handle->setArgument(
"ddns-params", ddns_params);
2141 HooksManager::callCallouts(
Hooks.hook_index_ddns6_update_, *callout_handle);
2144 string hook_hostname;
2145 bool hook_fwd_dns_update;
2146 bool hook_rev_dns_update;
2147 callout_handle->getArgument(
"hostname", hook_hostname);
2148 callout_handle->getArgument(
"fwd-update", hook_fwd_dns_update);
2149 callout_handle->getArgument(
"rev-update", hook_rev_dns_update);
2160 fqdn_resp = boost::dynamic_pointer_cast<Option6ClientFqdn>(answer->getOption(
D6O_CLIENT_FQDN));
2163 if (!(hook_fwd_dns_update || hook_rev_dns_update)) {
2190 <<
" encapsulating server's message must not be"
2191 <<
" NULL when creating DNS NameChangeRequest");
2204 bool do_fwd =
false;
2205 bool do_rev =
false;
2215 "client identifier is required when creating a new"
2216 " DNS NameChangeRequest");
2223 opt_fqdn->packDomainName(name_buf);
2224 const uint8_t* name_data =
static_cast<const uint8_t*
>(name_buf.
getData());
2227 std::vector<uint8_t> buf_vec(name_data, name_data + name_buf.
getLength());
2233 for (
auto answer_ia : answer->getOptions(
D6O_IA_NA)) {
2248 bool extended_only =
false;
2252 if ((*l)->addr_ == iaaddr->getAddress()) {
2257 ((*l)->hostname_ == opt_fqdn->getDomainName() &&
2258 (*l)->fqdn_fwd_ == do_fwd && (*l)->fqdn_rev_ == do_rev)) {
2259 extended_only =
true;
2271 if (!(do_fwd || do_rev) || (extended_only)) {
2286 opt_fqdn->getDomainName(),
2287 iaaddr->getAddress().toText(),
2309 getMACSources().get();
2311 for (CfgMACSources::const_iterator it = mac_sources.begin();
2312 it != mac_sources.end(); ++it) {
2313 hwaddr = pkt->getMAC(*it);
2324 boost::shared_ptr<Option6IA> ia) {
2330 boost::dynamic_pointer_cast<Option6IAAddr>(ia->getOption(
D6O_IAADDR));
2333 hint = hint_opt->getAddress();
2337 .arg(query->getLabel())
2339 .arg(hint_opt ? hint.
toText() :
"(no hint)");
2358 "Server could not select subnet for"
2381 if (!leases.empty()) {
2382 lease = *leases.begin();
2395 .arg(query->getLabel())
2396 .arg(lease->addr_.toText())
2397 .arg(ia->getIAID());
2398 }
else if (lease->reuseable_valid_lft_ == 0) {
2400 .arg(query->getLabel())
2401 .arg(lease->addr_.toText())
2405 lease->valid_lft_ = lease->reuseable_valid_lft_;
2406 lease->preferred_lft_ = lease->reuseable_preferred_lft_;
2408 .arg(query->getLabel())
2409 .arg(lease->addr_.toText())
2414 StatsMgr::instance().addValue(
"v6-ia-na-lease-reuses", int64_t(1));
2415 StatsMgr::instance().addValue(StatsMgr::generateName(
"subnet", lease->subnet_id_,
2416 "v6-ia-na-lease-reuses"),
2420 .arg(query->getLabel())
2422 .arg(lease->toText());
2425 setTeeTimes(lease->preferred_lft_, subnet, ia_rsp);
2428 lease->preferred_lft_,
2429 lease->valid_lft_));
2430 ia_rsp->addOption(addr);
2443 .arg(query->getLabel())
2444 .arg(ia->getIAID());
2446 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
2448 "Sorry, no address could be"
2457 boost::shared_ptr<Option6IA> ia) {
2464 boost::dynamic_pointer_cast<Option6IAPrefix>(ia->getOption(
D6O_IAPREFIX));
2467 hint = hint_opt->getAddress();
2471 .arg(query->getLabel())
2473 .arg(hint_opt ? hint.
toText() :
"(no hint)");
2490 "Sorry, no subnet available."));
2510 if (!leases.empty()) {
2514 uint32_t min_preferred_lft = (*leases.begin())->preferred_lft_;
2516 const bool pd_exclude_requested = requestedInORO(query,
D6O_PD_EXCLUDE);
2517 for (Lease6Collection::iterator l = leases.begin();
2518 l != leases.end(); ++l) {
2524 .arg(query->getLabel())
2525 .arg((*l)->addr_.toText())
2526 .arg(
static_cast<int>((*l)->prefixlen_))
2527 .arg(ia->getIAID());
2528 }
else if ((*l)->reuseable_valid_lft_ == 0) {
2530 .arg(query->getLabel())
2531 .arg((*l)->addr_.toText())
2532 .arg(
static_cast<int>((*l)->prefixlen_))
2536 (*l)->valid_lft_ = (*l)->reuseable_valid_lft_;
2537 (*l)->preferred_lft_ = (*l)->reuseable_preferred_lft_;
2539 .arg(query->getLabel())
2540 .arg((*l)->addr_.toText())
2541 .arg(
static_cast<int>((*l)->prefixlen_))
2546 StatsMgr::instance().addValue(
"v6-ia-pd-lease-reuses", int64_t(1));
2547 StatsMgr::instance().addValue(StatsMgr::generateName(
"subnet", (*l)->subnet_id_,
2548 "v6-ia-pd-lease-reuses"),
2553 if (((*l)->preferred_lft_ > 0) && (min_preferred_lft > (*l)->preferred_lft_)) {
2554 min_preferred_lft = (*l)->preferred_lft_;
2557 boost::shared_ptr<Option6IAPrefix>
2559 (*l)->prefixlen_, (*l)->preferred_lft_,
2561 ia_rsp->addOption(addr);
2563 if (pd_exclude_requested) {
2566 Pool6Ptr pool = boost::dynamic_pointer_cast<
2570 if (pd_exclude_option) {
2571 addr->addOption(pd_exclude_option);
2591 .arg(query->getLabel())
2592 .arg(ia->getIAID());
2594 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
2596 "Sorry, no prefixes could"
2605 boost::shared_ptr<Option6IA> ia) {
2608 .arg(query->getLabel())
2609 .arg(ia->getIAID());
2628 "Sorry, no known leases for this duid/iaid."));
2640 for (OptionCollection::const_iterator it = addrs.begin();
2641 it != addrs.end(); ++it) {
2645 Option6IAAddrPtr iaaddr = boost::dynamic_pointer_cast<Option6IAAddr>(it->second);
2672 uint32_t min_preferred_lft = std::numeric_limits<uint32_t>::max();
2675 for (Lease6Collection::iterator l = leases.begin(); l != leases.end(); ++l) {
2676 if ((*l)->reuseable_valid_lft_ == 0) {
2678 .arg(query->getLabel())
2679 .arg((*l)->addr_.toText())
2680 .arg(ia->getIAID());
2682 (*l)->valid_lft_ = (*l)->reuseable_valid_lft_;
2683 (*l)->preferred_lft_ = (*l)->reuseable_preferred_lft_;
2685 .arg(query->getLabel())
2686 .arg((*l)->addr_.toText())
2691 StatsMgr::instance().addValue(
"v6-ia-na-lease-reuses", int64_t(1));
2692 StatsMgr::instance().addValue(StatsMgr::generateName(
"subnet", (*l)->subnet_id_,
2693 "v6-ia-na-lease-reuses"),
2698 (*l)->addr_, (*l)->preferred_lft_, (*l)->valid_lft_));
2699 ia_rsp->addOption(iaaddr);
2702 if (((*l)->preferred_lft_ > 0) && (min_preferred_lft > (*l)->preferred_lft_)) {
2703 min_preferred_lft = (*l)->preferred_lft_;
2708 hints.erase(std::remove(hints.begin(), hints.end(), hint_type),
2719 if (
equalValues(query->getClientId(), (*l)->duid_)) {
2721 (*l)->addr_, 0, 0));
2722 ia_rsp->addOption(iaaddr);
2727 hints.erase(std::remove(hints.begin(), hints.end(), hint_type), hints.end());
2735 .arg(query->getLabel())
2736 .arg((*l)->toText())
2747 for (AllocEngine::HintContainer::const_iterator hint = hints.begin();
2748 hint != hints.end(); ++hint) {
2750 hint->getAddress(), 0, 0));
2751 ia_rsp->addOption(iaaddr);
2754 if (!leases.empty()) {
2760 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
2762 "Sorry, no addresses could be"
2763 " assigned at this time."));
2772 boost::shared_ptr<Option6IA> ia) {
2775 .arg(query->getLabel())
2776 .arg(ia->getIAID());
2793 "Sorry, no known PD leases"
2794 " for this duid/iaid."));
2814 " client sending Rebind to extend lifetime of the"
2815 " prefix (DUID=" << duid->toText() <<
", IAID="
2816 << ia->getIAID() <<
")");
2828 for (OptionCollection::const_iterator it = addrs.begin();
2829 it != addrs.end(); ++it) {
2863 const bool pd_exclude_requested = requestedInORO(query,
D6O_PD_EXCLUDE);
2867 uint32_t min_preferred_lft = std::numeric_limits<uint32_t>::max();
2869 for (Lease6Collection::iterator l = leases.begin(); l != leases.end(); ++l) {
2870 if ((*l)->reuseable_valid_lft_ == 0) {
2872 .arg(query->getLabel())
2873 .arg((*l)->addr_.toText())
2874 .arg(
static_cast<int>((*l)->prefixlen_))
2875 .arg(ia->getIAID());
2877 (*l)->valid_lft_ = (*l)->reuseable_valid_lft_;
2878 (*l)->preferred_lft_ = (*l)->reuseable_preferred_lft_;
2880 .arg(query->getLabel())
2881 .arg((*l)->addr_.toText())
2882 .arg(
static_cast<int>((*l)->prefixlen_))
2887 StatsMgr::instance().addValue(
"v6-ia-pd-lease-reuses", int64_t(1));
2888 StatsMgr::instance().addValue(StatsMgr::generateName(
"subnet", (*l)->subnet_id_,
2889 "v6-ia-pd-lease-reuses"),
2894 (*l)->addr_, (*l)->prefixlen_,
2895 (*l)->preferred_lft_, (*l)->valid_lft_));
2896 ia_rsp->addOption(prf);
2898 if (pd_exclude_requested) {
2901 Pool6Ptr pool = boost::dynamic_pointer_cast<
2906 if (pd_exclude_option) {
2907 prf->addOption(pd_exclude_option);
2913 if (((*l)->preferred_lft_ > 0) && ((*l)->preferred_lft_ < min_preferred_lft)) {
2914 min_preferred_lft = (*l)->preferred_lft_;
2919 hints.erase(std::remove(hints.begin(), hints.end(), hint_type),
2930 if (
equalValues(query->getClientId(), (*l)->duid_)) {
2932 (*l)->prefixlen_, 0, 0));
2933 ia_rsp->addOption(prefix);
2938 hints.erase(std::remove(hints.begin(), hints.end(), hint_type), hints.end());
2943 for (AllocEngine::HintContainer::const_iterator prefix = hints.begin();
2944 prefix != hints.end(); ++prefix) {
2949 if (!prefix->getAddress().isV6Zero()) {
2951 prefix->getAddress(),
2952 prefix->getPrefixLength(),
2954 ia_rsp->addOption(prefix_opt);
2958 if (!leases.empty()) {
2965 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
2967 "Sorry, no prefixes could be"
2968 " assigned at this time."));
2989 for (
const auto& opt : query->options_) {
2990 switch (opt.second->getType()) {
2993 boost::dynamic_pointer_cast<
2996 reply->addOption(answer_opt);
3003 boost::dynamic_pointer_cast<
3006 reply->addOption(answer_opt);
3041 for (
const auto& opt : release->options_) {
3043 switch (opt.second->getType()) {
3046 boost::dynamic_pointer_cast<Option6IA>(opt.second),
3049 reply->addOption(answer_opt);
3055 boost::dynamic_pointer_cast<Option6IA>(opt.second),
3058 reply->addOption(answer_opt);
3075 reply->addOption(createStatusCode(*release, general_status,
3076 "Summary status for all processed IA_NAs"));
3081 int& general_status, boost::shared_ptr<Option6IA> ia,
3085 .arg(query->getLabel())
3086 .arg(ia->getIAID());
3102 if (!release_addr) {
3104 "You did not include an address in your RELEASE"));
3110 release_addr->getAddress());
3117 "Sorry, no known leases for this duid/iaid, can't release."));
3123 if (!lease->duid_) {
3129 .arg(query->getLabel())
3130 .arg(release_addr->getAddress().toText());
3134 "Database consistency check failed when trying to RELEASE"));
3138 if (*duid != *(lease->duid_)) {
3142 .arg(query->getLabel())
3143 .arg(release_addr->getAddress().toText())
3144 .arg(lease->duid_->toText());
3148 "This address does not belong to you, you can't release it"));
3152 if (ia->getIAID() != lease->iaid_) {
3155 .arg(query->getLabel())
3156 .arg(release_addr->getAddress().toText())
3158 .arg(ia->getIAID());
3160 "This is your address, but you used wrong IAID"));
3170 if (HooksManager::calloutsPresent(
Hooks.hook_index_lease6_release_)) {
3183 callout_handle->deleteAllArguments();
3186 callout_handle->setArgument(
"query6", query);
3189 callout_handle->setArgument(
"lease6", lease);
3192 HooksManager::callCallouts(
Hooks.hook_index_lease6_release_, *callout_handle);
3197 if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) ||
3198 (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP)) {
3201 .arg(query->getLabel());
3206 bool success =
false;
3207 bool expired =
false;
3214 if (expiration_cfg->getFlushReclaimedTimerWaitTime() &&
3215 expiration_cfg->getHoldReclaimedTime() &&
3218 lease->valid_lft_ = 0;
3219 lease->preferred_lft_ = 0;
3233 "Server failed to release a lease"));
3236 .arg(query->getLabel())
3237 .arg(lease->addr_.toText())
3246 .arg(query->getLabel())
3247 .arg(lease->addr_.toText())
3250 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
STATUS_Success,
3251 "Lease released. Thank you, please come again."));
3255 .arg(query->getLabel())
3256 .arg(lease->addr_.toText())
3260 .arg(query->getLabel())
3261 .arg(lease->addr_.toText())
3265 StatsMgr::instance().addValue(
3266 StatsMgr::generateName(
"subnet", lease->subnet_id_,
"assigned-nas"),
3267 static_cast<int64_t
>(-1));
3271 const auto& pool = subnet->getPool(
Lease::TYPE_NA, lease->addr_,
false);
3273 StatsMgr::instance().addValue(
3274 StatsMgr::generateName(
"subnet", subnet->getID(),
3275 StatsMgr::generateName(
"pool", pool->getID(),
"assigned-nas")),
3276 static_cast<int64_t
>(-1));
3292 int& general_status, boost::shared_ptr<Option6IA> ia,
3307 boost::shared_ptr<Option6IAPrefix> release_prefix =
3308 boost::dynamic_pointer_cast<Option6IAPrefix>(ia->getOption(
D6O_IAPREFIX));
3309 if (!release_prefix) {
3311 "You did not include a prefix in your RELEASE"));
3317 release_prefix->getAddress());
3324 "Sorry, no known leases for this duid/iaid, can't release."));
3330 if (!lease->duid_) {
3335 .arg(query->getLabel())
3336 .arg(release_prefix->getAddress().toText())
3337 .arg(
static_cast<int>(release_prefix->getLength()));
3341 "Database consistency check failed when trying to RELEASE"));
3345 if (*duid != *(lease->duid_)) {
3348 .arg(query->getLabel())
3349 .arg(release_prefix->getAddress().toText())
3350 .arg(
static_cast<int>(release_prefix->getLength()))
3351 .arg(lease->duid_->toText());
3355 "This address does not belong to you, you can't release it"));
3359 if (ia->getIAID() != lease->iaid_) {
3362 .arg(query->getLabel())
3363 .arg(release_prefix->getAddress().toText())
3364 .arg(
static_cast<int>(release_prefix->getLength()))
3366 .arg(ia->getIAID());
3368 "This is your address, but you used wrong IAID"));
3378 if (HooksManager::calloutsPresent(
Hooks.hook_index_lease6_release_)) {
3391 callout_handle->setArgument(
"query6", query);
3394 callout_handle->setArgument(
"lease6", lease);
3397 HooksManager::callCallouts(
Hooks.hook_index_lease6_release_, *callout_handle);
3402 if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) ||
3403 (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP)) {
3406 .arg(query->getLabel());
3411 bool success =
false;
3412 bool expired =
false;
3419 if (expiration_cfg->getFlushReclaimedTimerWaitTime() &&
3420 expiration_cfg->getHoldReclaimedTime() &&
3423 lease->valid_lft_ = 0;
3424 lease->preferred_lft_ = 0;
3438 "Server failed to release a lease"));
3441 .arg(query->getLabel())
3442 .arg(lease->addr_.toText())
3443 .arg(
static_cast<int>(lease->prefixlen_))
3451 .arg(query->getLabel())
3452 .arg(lease->addr_.toText())
3453 .arg(
static_cast<int>(lease->prefixlen_))
3456 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
STATUS_Success,
3457 "Lease released. Thank you, please come again."));
3461 .arg(query->getLabel())
3462 .arg(lease->addr_.toText())
3463 .arg(
static_cast<int>(lease->prefixlen_))
3467 .arg(query->getLabel())
3468 .arg(lease->addr_.toText())
3469 .arg(
static_cast<int>(lease->prefixlen_))
3473 StatsMgr::instance().addValue(
3474 StatsMgr::generateName(
"subnet", lease->subnet_id_,
"assigned-pds"),
3475 static_cast<int64_t
>(-1));
3479 const auto& pool = subnet->getPool(
Lease::TYPE_PD, lease->addr_,
false);
3481 StatsMgr::instance().addValue(
3482 StatsMgr::generateName(
"subnet", subnet->getID(),
3483 StatsMgr::generateName(
"pd-pool", pool->getID(),
"assigned-pds")),
3484 static_cast<int64_t
>(-1));
3502 if (opt_rapid_commit) {
3505 .arg(solicit->getLabel());
3510 response->addOption(opt_rapid_commit);
3529 if (MultiThreadingMgr::instance().getMode()) {
3548 updateReservedFqdn(ctx, response);
3567 if (MultiThreadingMgr::instance().getMode()) {
3586 updateReservedFqdn(ctx, reply);
3587 generateFqdn(reply, ctx);
3601 if (MultiThreadingMgr::instance().getMode()) {
3620 updateReservedFqdn(ctx, reply);
3621 generateFqdn(reply, ctx);
3635 if (MultiThreadingMgr::instance().getMode()) {
3654 updateReservedFqdn(ctx, reply);
3655 generateFqdn(reply, ctx);
3687 bool verified =
false;
3696 for (OptionCollection::const_iterator ia = ias.begin();
3697 ia != ias.end(); ++ia) {
3699 for (OptionCollection::const_iterator opt = opts.begin();
3700 opt != opts.end(); ++opt) {
3712 if (subnet && !subnet->inRange(iaaddr->getAddress())) {
3713 std::ostringstream status_msg;
3714 status_msg <<
"Address " << iaaddr->
getAddress()
3715 <<
" is not on link.";
3716 reply->addOption(createStatusCode(*confirm,
3724 " to the Option6IAAddrPtr. This is programming"
3725 " error and should be reported");
3742 "All addresses are on-link"));
3745 "No subnet selected"));
3821 for (
const auto& opt : decline->options_) {
3822 switch (opt.second->getType()) {
3825 boost::dynamic_pointer_cast<Option6IA>(opt.second),
3830 reply->addOption(answer_opt);
3851 int& general_status, boost::shared_ptr<Option6IA> ia,
3855 .arg(decline->getLabel())
3856 .arg(ia->getIAID());
3871 int total_addrs = 0;
3872 for (OptionCollection::const_iterator opt = opts.begin(); opt != opts.end();
3882 if (!decline_addr) {
3889 decline_addr->getAddress());
3894 .arg(decline->getLabel()).arg(decline_addr->getAddress().toText());
3902 "Server does not know about such an address."));
3910 if (!lease->duid_) {
3916 .arg(decline->getLabel())
3917 .arg(decline_addr->getAddress().toText());
3920 "Database consistency check failed when attempting Decline."));
3926 if (*duid != *(lease->duid_)) {
3930 .arg(decline->getLabel())
3931 .arg(decline_addr->getAddress().toText())
3932 .arg(lease->duid_->toText());
3935 "This address does not belong to you, you can't decline it"));
3941 if (ia->getIAID() != lease->iaid_) {
3944 .arg(decline->getLabel())
3945 .arg(lease->addr_.toText())
3949 "This is your address, but you used wrong IAID"));
3961 new_leases.push_back(lease);
3965 if (total_addrs == 0) {
3967 "No addresses sent in IA_NA"));
3980 container->addOption(status);
3985 boost::shared_ptr<Option6IA> ia_rsp) {
3996 if (HooksManager::calloutsPresent(
Hooks.hook_index_lease6_decline_)) {
4009 callout_handle->setArgument(
"query6", decline);
4012 callout_handle->setArgument(
"lease6", lease);
4015 HooksManager::callCallouts(
Hooks.hook_index_lease6_decline_,
4021 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
4023 .arg(decline->getLabel())
4024 .arg(decline->getIface())
4025 .arg(lease->addr_.toText());
4031 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
4033 .arg(decline->getLabel())
4034 .arg(decline->getIface())
4035 .arg(lease->addr_.toText());
4040 Lease6Ptr old_values = boost::make_shared<Lease6>(*lease);
4054 .arg(decline->getLabel())
4055 .arg(lease->addr_.toText())
4066 StatsMgr::instance().addValue(
4067 StatsMgr::generateName(
"subnet", lease->subnet_id_,
"declined-addresses"),
4068 static_cast<int64_t
>(1));
4072 const auto& pool = subnet->getPool(
Lease::TYPE_NA, lease->addr_,
false);
4074 StatsMgr::instance().addValue(
4075 StatsMgr::generateName(
"subnet", subnet->getID(),
4076 StatsMgr::generateName(
"pool", pool->getID(),
"declined-addresses")),
4077 static_cast<int64_t
>(1));
4082 StatsMgr::instance().addValue(
"declined-addresses",
static_cast<int64_t
>(1));
4085 .arg(lease->addr_.toText()).arg(lease->valid_lft_);
4087 ia_rsp->addOption(createStatusCode(*decline, *ia_rsp,
STATUS_Success,
4088 "Lease declined. Hopefully the next one will be better."));
4147 void Dhcpv6Srv::classifyByVendor(
const Pkt6Ptr& pkt) {
4150 vclass = boost::dynamic_pointer_cast<OptionVendorClass>(opt.second);
4151 if (!vclass || vclass->getTuplesNum() == 0) {
4169 pkt->addClass(
"ALL");
4172 classifyByVendor(pkt);
4183 for (ClientClassDefList::const_iterator it = defs_ptr->cbegin();
4184 it != defs_ptr->cend(); ++it) {
4192 if ((*it)->getRequired()) {
4196 if ((*it)->getDependOnKnown() != depend_on_known) {
4199 (*it)->test(pkt, expr_ptr);
4208 for (
auto def : *defs_ptr) {
4212 if (def->getMatchExpr()) {
4213 pkt->classes_.erase(def->getName());
4224 cclass != classes.
cend(); ++cclass) {
4225 pkt->addClass(*cclass);
4230 if (!classes.
empty()) {
4232 .arg(pkt->getLabel())
4242 ctx.
subnet_->getSharedNetwork(shared_network);
4243 if (shared_network) {
4245 if (host && (host->getIPv6SubnetID() != SUBNET_ID_GLOBAL)) {
4261 subnet->getSharedNetwork(network);
4263 const ClientClasses& to_add = network->getRequiredClasses();
4265 cclass != to_add.
cend(); ++cclass) {
4273 cclass != to_add.
cend(); ++cclass) {
4280 ctx.
subnet_->getPool(resource.getPrefixLength() == 128 ?
4282 resource.getAddress(),
4287 cclass != to_add.
cend(); ++cclass) {
4301 cclass != classes.
cend(); ++cclass) {
4324 pkt->addClass(*cclass);
4337 .arg(
"get exception?");
4347 " a message must not be NULL when updating reserved FQDN");
4358 std::string name = fqdn->getDomainName();
4370 if (new_name != name) {
4375 answer->addOption(fqdn);
4381 Dhcpv6Srv::generateFqdn(
const Pkt6Ptr& answer,
4385 " a message must not be NULL when generating FQDN");
4396 if (!fqdn || !fqdn->getDomainName().empty()) {
4414 std::string generated_name =
4418 .arg(answer->getLabel())
4419 .arg(generated_name);
4436 lease->hostname_ = generated_name;
4437 lease->reuseable_valid_lft_ = 0;
4442 " for address " << addr <<
", so as it is impossible"
4443 " to update FQDN data. This is a programmatic error"
4444 " as the given address is now being handed to the"
4452 answer->addOption(fqdn);
4456 .arg(answer->getLabel())
4470 this, ph::_1, ph::_2));
4488 arg(result).arg((ncr ? ncr->toText() :
" NULL "));
4497 std::stringstream tmp;
4501 tmp << endl << EXTENDED_VERSION << endl;
4502 tmp <<
"linked with:" << endl;
4503 tmp << Logger::getVersion() << endl;
4504 tmp << CryptoLink::getVersion() << endl;
4505 tmp <<
"database:" << endl;
4522 if (query->relay_info_.empty()) {
4533 for (
int i = query->relay_info_.size(); i > 0 ; --i) {
4535 if (rsoo_container) {
4540 for (OptionCollection::const_iterator opt = rsoo.begin();
4541 opt != rsoo.end(); ++opt) {
4545 if (cfg_rsoo->enabled(opt->second->getType()) &&
4546 !rsp->getOption(opt->second->getType())) {
4547 rsp->addOption(opt->second);
4556 if (query->relay_info_.empty()) {
4564 return (query->getRemotePort());
4570 void Dhcpv6Srv::processStatsReceived(
const Pkt6Ptr& query) {
4574 string stat_name =
"pkt6-unknown-received";
4575 switch (query->getType()) {
4577 stat_name =
"pkt6-solicit-received";
4581 stat_name =
"pkt6-advertise-received";
4584 stat_name =
"pkt6-request-received";
4587 stat_name =
"pkt6-confirm-received";
4590 stat_name =
"pkt6-renew-received";
4593 stat_name =
"pkt6-rebind-received";
4597 stat_name =
"pkt6-reply-received";
4600 stat_name =
"pkt6-release-received";
4603 stat_name =
"pkt6-decline-received";
4606 stat_name =
"pkt6-reconfigure-received";
4609 stat_name =
"pkt6-infrequest-received";
4612 stat_name =
"pkt6-dhcpv4-query-received";
4616 stat_name =
"pkt6-dhcpv4-response-received";
4622 StatsMgr::instance().addValue(stat_name,
static_cast<int64_t
>(1));
4627 StatsMgr::instance().addValue(
"pkt6-sent",
static_cast<int64_t
>(1));
4631 switch (response->getType()) {
4633 stat_name =
"pkt6-advertise-sent";
4636 stat_name =
"pkt6-reply-sent";
4639 stat_name =
"pkt6-dhcpv4-response-sent";
4646 StatsMgr::instance().addValue(stat_name,
static_cast<int64_t
>(1));
4650 return (
Hooks.hook_index_buffer6_send_);
4654 Dhcpv6Srv::requestedInORO(
const Pkt6Ptr& query,
const uint16_t code)
const {
4656 boost::dynamic_pointer_cast<OptionUint16Array>(query->getOption(
D6O_ORO));
4659 const std::vector<uint16_t>& codes = oro->getValues();
4660 return (std::find(codes.begin(), codes.end(), code) != codes.end());
4668 HooksManager::clearParkingLots();
4675 uint32_t t2_time = 0;
4678 if (!subnet->getT2().unspecified()) {
4679 t2_time = subnet->getT2();
4680 }
else if (subnet->getCalculateTeeTimes()) {
4682 t2_time =
static_cast<uint32_t
>(round(subnet->getT2Percent() * preferred_lft));
4686 resp->setT2(t2_time);
4689 uint32_t t1_time = 0;
4692 if (!subnet->getT1().unspecified()) {
4693 t1_time = subnet->getT1();
4694 }
else if (subnet->getCalculateTeeTimes()) {
4696 t1_time =
static_cast<uint32_t
>(round(subnet->getT1Percent() * preferred_lft));
4700 if (t1_time < t2_time) {
4701 resp->setT1(t1_time);
4713 if ((!ctx.
subnet_) || (!orig_subnet) || (orig_subnet->getID() == ctx.
subnet_->getID())) {
4721 orig_subnet->getSharedNetwork(network);
4723 .arg(question->getLabel())
4724 .arg(orig_subnet->toText())
4726 .arg(network ? network->getName() :
"<no network?>");
4732 std::string prev_hostname = ctx.
hostname_;
4749 for (Lease6Collection::const_iterator l = ctx.
new_leases_.begin();
4754 (*l)->reuseable_valid_lft_ = 0;
4761 static std::list<std::list<std::string>>
const list({
4762 {
"config-control",
"config-databases",
"[]"},
4763 {
"hooks-libraries",
"[]",
"parameters",
"*"},
4765 {
"hosts-databases",
"[]"},
This is a base class for exceptions thrown from the DNS library module.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
A generic exception that is thrown when an unexpected error condition occurs.
The IOAddress class represents an IP addresses (version agnostic)
std::string toText() const
Convert the address to a string.
static const IOAddress & IPV6_ZERO_ADDRESS()
Returns an IPv6 zero address.
The IOService class is a wrapper for the ASIO io_service class.
DHCPv4 and DHCPv6 allocation engine.
std::vector< Resource > HintContainer
Container for client's hints.
Implementation of the mechanisms to control the use of the Configuration Backends by the DHCPv6 serve...
@ EARLY_GLOBAL_RESERVATIONS_LOOKUP
D2ClientMgr & getD2ClientMgr()
Fetches the DHCP-DDNS manager.
static CfgMgr & instance()
returns a single instance of Configuration Manager
SrvConfigPtr getCurrentCfg()
Returns a pointer to the current configuration.
static SubnetSelector initSelector(const Pkt6Ptr &query)
Build selector from a client's message.
Container for storing client class names.
ClientClassContainer::const_iterator const_iterator
Type of iterators.
void insert(const ClientClass &class_name)
Insert an element.
bool empty() const
Check if classes is empty.
std::string toText(const std::string &separator=", ") const
Returns all class names as text.
const_iterator cbegin() const
Iterators to the first element.
const_iterator cend() const
Iterators to the past the end element.
Client race avoidance RAII handler.
bool tryLock(Pkt4Ptr query, ContinuationPtr cont=ContinuationPtr())
Tries to acquires a client.
D2ClientMgr isolates Kea from the details of being a D2 client.
std::string generateFqdn(const asiolink::IOAddress &address, const DdnsParams &ddns_params, const bool trailing_dot=true) const
Builds a FQDN based on the configuration and given IP address.
bool ddnsEnabled()
Convenience method for checking if DHCP-DDNS is enabled.
void startSender(D2ClientErrorHandler error_handler, isc::asiolink::IOService &io_service)
Enables sending NameChangeRequests to kea-dhcp-ddns.
void getUpdateDirections(const T &fqdn_resp, bool &forward, bool &reverse)
Get directional update flags based on server FQDN flags.
void suspendUpdates()
Suspends sending requests.
void adjustDomainName(const T &fqdn, T &fqdn_resp, const DdnsParams &ddns_params)
Set server FQDN name based on configuration and a given FQDN.
void sendRequest(dhcp_ddns::NameChangeRequestPtr &ncr)
Send the given NameChangeRequests to kea-dhcp-ddns.
void stopSender()
Disables sending NameChangeRequests to kea-dhcp-ddns.
void adjustFqdnFlags(const T &fqdn, T &fqdn_resp, const DdnsParams &ddns_params)
Set server FQDN flags based on configuration and a given FQDN.
std::string qualifyName(const std::string &partial_name, const DdnsParams &ddns_params, const bool trailing_dot) const
Adds a qualifying suffix to a given domain name.
This exception is thrown when DHCP server hits the error which should result in discarding the messag...
Factory for generating DUIDs (DHCP Unique Identifiers).
DuidPtr get()
Returns current DUID.
Holds DUID (DHCPv6 Unique Identifier)
static constexpr size_t MIN_DUID_LEN
minimum duid size
static constexpr size_t MAX_DUID_LEN
maximum duid size
void send(const Pkt6Ptr &pkt)
Send message over IPC.
void close()
Close communication socket.
static Dhcp6to4Ipc & instance()
Returns pointer to the sole instance of Dhcp6to4Ipc.
static uint16_t client_port
void run_one()
Main server processing step.
void shutdown() override
Instructs the server to shut down.
RequirementLevel
defines if certain option may, must or must not appear
OptionPtr getServerID()
Returns server-identifier option.
OptionPtr extendIA_PD(const Pkt6Ptr &query, AllocEngine::ClientContext6 &ctx, Option6IAPtr ia)
Extends lifetime of the prefix.
void setReservedClientClasses(const Pkt6Ptr &pkt, const AllocEngine::ClientContext6 &ctx)
Assigns classes retrieved from host reservation database.
Pkt6Ptr processDecline(AllocEngine::ClientContext6 &ctx)
Process incoming Decline message.
void evaluateClasses(const Pkt6Ptr &pkt, bool depend_on_known)
Evaluate classes.
Pkt6Ptr processRenew(AllocEngine::ClientContext6 &ctx)
Processes incoming Renew message.
static void processStatsSent(const Pkt6Ptr &response)
Updates statistics for transmitted packets.
int run()
Main server processing loop.
void setPacketStatisticsDefaults()
This function sets statistics related to DHCPv6 packets processing to their initial values.
bool sanityCheck(const Pkt6Ptr &pkt)
Verifies if specified packet meets RFC requirements.
static uint16_t checkRelaySourcePort(const Pkt6Ptr &query)
Used for DHCPv4-over-DHCPv6 too.
void assignLeases(const Pkt6Ptr &question, Pkt6Ptr &answer, AllocEngine::ClientContext6 &ctx)
Assigns leases.
void stopD2()
Stops DHCP_DDNS client IO if DDNS updates are enabled.
void copyClientOptions(const Pkt6Ptr &question, Pkt6Ptr &answer)
Copies required options from client message to server answer.
boost::shared_ptr< AllocEngine > alloc_engine_
Allocation Engine.
virtual void sendPacket(const Pkt6Ptr &pkt)
dummy wrapper around IfaceMgr::send()
bool testServerID(const Pkt6Ptr &pkt)
Compare received server id with our server id.
void processPacketPktSend(hooks::CalloutHandlePtr &callout_handle, Pkt6Ptr &query, Pkt6Ptr &rsp)
Executes pkt6_send callout.
virtual void d2ClientErrorHandler(const dhcp_ddns::NameChangeSender::Result result, dhcp_ddns::NameChangeRequestPtr &ncr)
Implements the error handler for DHCP_DDNS IO errors.
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.
virtual Pkt6Ptr receivePacket(int timeout)
dummy wrapper around IfaceMgr::receive6
void processPacketBufferSend(hooks::CalloutHandlePtr &callout_handle, Pkt6Ptr &rsp)
Executes buffer6_send callout and sends the response.
void requiredClassify(const Pkt6Ptr &pkt, AllocEngine::ClientContext6 &ctx)
Assigns incoming packet to zero or more classes (required pass).
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.
void buildCfgOptionList(const Pkt6Ptr &question, AllocEngine::ClientContext6 &ctx, CfgOptionList &co_list)
Build the configured option list.
void appendDefaultOptions(const Pkt6Ptr &question, Pkt6Ptr &answer, const CfgOptionList &co_list)
Appends default options to server's answer.
OptionPtr assignIA_NA(const isc::dhcp::Pkt6Ptr &query, AllocEngine::ClientContext6 &ctx, Option6IAPtr ia)
Processes IA_NA option (and assigns addresses if necessary).
static const std::string VENDOR_CLASS_PREFIX
this is a prefix added to the content of vendor-class option
OptionPtr serverid_
Server DUID (to be sent in server-identifier option)
asiolink::IOServicePtr & getIOService()
Returns pointer to the IO service used by the server.
void initContext(const Pkt6Ptr &pkt, AllocEngine::ClientContext6 &ctx, bool &drop)
Initializes client context for specified packet.
void checkDynamicSubnetChange(const Pkt6Ptr &question, Pkt6Ptr &answer, AllocEngine::ClientContext6 &ctx, const Subnet6Ptr orig_subnet)
Iterates over new leases, update stale DNS entries.
void conditionallySetReservedClientClasses(const Pkt6Ptr &pkt, const AllocEngine::ClientContext6 &ctx)
Assigns classes retrieved from host reservation database if they haven't been yet set.
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 processDhcp4Query(const Pkt6Ptr &dhcp4_query)
Processes incoming DHCPv4-query message.
Pkt6Ptr processRebind(AllocEngine::ClientContext6 &ctx)
Processes incoming Rebind message.
bool earlyGHRLookup(const Pkt6Ptr &query, AllocEngine::ClientContext6 &ctx)
Initialize client context and perform early global reservations lookup.
void processPacketAndSendResponseNoThrow(Pkt6Ptr &query)
Process a single incoming DHCPv6 packet and sends the response.
void processDhcp6Query(Pkt6Ptr &query, Pkt6Ptr &rsp)
Process a single incoming DHCPv6 query.
virtual ~Dhcpv6Srv()
Destructor. Used during DHCPv6 service shutdown.
void setTeeTimes(uint32_t preferred_lft, const Subnet6Ptr &subnet, Option6IAPtr &resp)
Sets the T1 and T2 timers in the outbound IA.
Pkt6Ptr processRequest(AllocEngine::ClientContext6 &ctx)
Processes incoming Request and returns Reply response.
NetworkStatePtr network_state_
Holds information about disabled DHCP service and/or disabled subnet/network scopes.
std::list< std::list< std::string > > jsonPathsToRedact() const final override
Return a list of all paths that contain passwords or secrets for kea-dhcp6.
void processPacket(Pkt6Ptr &query, Pkt6Ptr &rsp)
Process a single incoming DHCPv6 packet.
OptionPtr assignIA_PD(const Pkt6Ptr &query, AllocEngine::ClientContext6 &ctx, boost::shared_ptr< Option6IA > ia)
Processes IA_PD option (and assigns prefixes if necessary).
bool testUnicast(const Pkt6Ptr &pkt) const
Check if the message can be sent to unicast.
Pkt6Ptr processRelease(AllocEngine::ClientContext6 &ctx)
Process incoming Release message.
void processClientFqdn(const Pkt6Ptr &question, const Pkt6Ptr &answer, AllocEngine::ClientContext6 &ctx)
Processes Client FQDN Option.
void setStatusCode(boost::shared_ptr< Option6IA > &container, const OptionPtr &status)
A simple utility method that sets the status code.
static int getHookIndexBuffer6Send()
Returns the index of the buffer6_send hook.
void sendResponseNoThrow(hooks::CalloutHandlePtr &callout_handle, Pkt6Ptr &query, Pkt6Ptr &rsp)
Process an unparked DHCPv6 packet and sends the response.
void classifyPacket(const Pkt6Ptr &pkt)
Assigns incoming packet to zero or more classes.
static HWAddrPtr getMAC(const Pkt6Ptr &pkt)
Attempts to get a MAC/hardware address using configured sources.
bool declineLeases(const Pkt6Ptr &decline, Pkt6Ptr &reply, AllocEngine::ClientContext6 &ctx)
Attempts to decline all leases in specified Decline message.
void releaseLeases(const Pkt6Ptr &release, Pkt6Ptr &reply, AllocEngine::ClientContext6 &ctx)
Attempts to release received addresses.
void extendLeases(const Pkt6Ptr &query, Pkt6Ptr &reply, AllocEngine::ClientContext6 &ctx)
Attempts to extend the lifetime of IAs.
void processRSOO(const Pkt6Ptr &query, const Pkt6Ptr &rsp)
Processes Relay-supplied options, if present.
static std::string getVersion(bool extended)
returns Kea version on stdout and exit.
void processPacketAndSendResponse(Pkt6Ptr &query)
Process a single incoming DHCPv6 packet and sends the response.
OptionPtr extendIA_NA(const Pkt6Ptr &query, AllocEngine::ClientContext6 &ctx, Option6IAPtr ia)
Extends lifetime of the specific IA_NA option.
Pkt6Ptr processConfirm(AllocEngine::ClientContext6 &ctx)
Processes incoming Confirm message and returns Reply.
void sanityCheckDUID(const OptionPtr &opt, const std::string &opt_name)
verifies if received DUID option (client-id or server-id) is sane
static void setHostIdentifiers(AllocEngine::ClientContext6 &ctx)
Set host identifiers within a context.
void appendRequestedOptions(const Pkt6Ptr &question, Pkt6Ptr &answer, const CfgOptionList &co_list)
Appends requested options to server's answer.
uint16_t client_port_
UDP port number to which server sends all responses.
volatile bool shutdown_
Indicates if shutdown is in progress.
Pkt6Ptr processSolicit(AllocEngine::ClientContext6 &ctx)
Processes incoming Solicit and returns response.
void startD2()
Starts DHCP_DDNS client IO if DDNS updates are enabled.
static std::string duidToString(const OptionPtr &opt)
converts DUID to text Converts content of DUID option to a text representation, e....
static void removeDependentEvaluatedClasses(const Pkt6Ptr &pkt)
Removed evaluated client classes.
void createNameChangeRequests(const Pkt6Ptr &answer, AllocEngine::ClientContext6 &ctx)
Creates a number of isc::dhcp_ddns::NameChangeRequest objects based on the DHCPv6 Client FQDN Option.
Pkt6Ptr processInfRequest(AllocEngine::ClientContext6 &ctx)
Processes incoming Information-request message.
void processDhcp6QueryAndSendResponse(Pkt6Ptr &query, Pkt6Ptr &rsp)
Process a single incoming DHCPv6 query.
uint16_t server_port_
UDP port number on which server listens.
isc::dhcp::Subnet6Ptr selectSubnet(const Pkt6Ptr &question, bool &drop)
Selects a subnet for a given client's packet.
void appendRequestedVendorOptions(const Pkt6Ptr &question, Pkt6Ptr &answer, AllocEngine::ClientContext6 &ctx, const CfgOptionList &co_list)
Appends requested vendor options to server's answer.
bool declineLease(const Pkt6Ptr &decline, const Lease6Ptr lease, boost::shared_ptr< Option6IA > ia_rsp)
Declines specific IPv6 lease.
void discardPackets()
Discards parked packets Clears the packet parking lots of all packets.
IdentifierType
Type of the host identifier.
@ IDENT_FLEX
Flexible host identifier.
std::string getIdentifierAsText() const
Returns host identifier in a textual form.
static IfaceMgr & instance()
IfaceMgr is a singleton class.
bool send(const Pkt6Ptr &pkt)
Sends an IPv6 packet.
void closeSockets()
Closes all open sockets.
static TrackingLeaseMgr & instance()
Return current lease manager.
static void destroy()
Destroy lease manager.
virtual bool deleteLease(const Lease4Ptr &lease)=0
Deletes an IPv4 lease.
static std::string getDBVersion()
Class method to return extended version info This class method must be redeclared and redefined in de...
virtual Lease6Ptr getLease6(Lease::Type type, const isc::asiolink::IOAddress &addr) const =0
Returns existing IPv6 lease for a given IPv6 address.
virtual void updateLease6(const Lease6Ptr &lease6)=0
Updates IPv6 lease.
static std::string getDBVersion()
Local version of getDBVersion() class method.
Holds information about DHCP service enabling status.
Represents DHCPv6 Client FQDN Option (code 39).
static const uint8_t FLAG_S
S bit.
static const uint8_t FLAG_N
N bit.
isc::asiolink::IOAddress getAddress() const
Returns address contained within this option.
Class that represents IAPREFIX option in DHCPv6.
uint32_t getIAID() const
Returns IA identifier.
This class represents Status Code option (13) from RFC 8415.
OptionPtr option_
Option instance.
Forward declaration to OptionIntArray.
This class represents vendor-specific information option.
OptionPtr getOption(uint16_t type) const
Returns shared_ptr to suboption of specific type.
uint16_t getType() const
Returns option type (0-255 for DHCPv4, 0-65535 for DHCPv6)
const OptionCollection & getOptions() const
Returns all encapsulated options.
static std::string getDBVersion()
Local version of getDBVersion() class method.
Represents a DHCPv6 packet.
virtual std::string getLabel() const
Returns text representation of the primary packet identifiers.
Pool information for IPv6 addresses and prefixes.
Option6PDExcludePtr getPrefixExcludeOption() const
Returns instance of the pool specific Prefix Exclude option.
An exception that is thrown if a DHCPv6 protocol violation occurs while processing a message (e....
RAII object enabling copying options retrieved from the packet.
Exception thrown when a call to select is interrupted by a signal.
Exception thrown during option unpacking This exception is thrown when an error has occurred,...
Container class for handling the DHCID value within a NameChangeRequest.
Represents a DHCP-DDNS client request.
Result
Defines the outcome of an asynchronous NCR send.
Wrapper class around callout handle which automatically resets handle's state.
int getExitValue()
Fetches the exit value.
Statistics Manager class.
static StatsMgr & instance()
Statistics Manager accessor method.
RAII class creating a critical section.
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
const void * getData() const
Return a pointer to the head of the data stored in the buffer.
size_t getLength() const
Return the length of data written in the buffer.
@ DHCPV6_INFORMATION_REQUEST
Defines the Dhcp6to4Ipc class.
#define VENDOR_ID_CABLE_LABS
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::shared_ptr< OptionUint16Array > OptionUint16ArrayPtr
void setValue(const std::string &name, const int64_t value)
Records absolute integer observation.
void addValue(const std::string &name, const int64_t value)
Records incremental integer observation.
An abstract API for lease database.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
boost::shared_ptr< const Element > ConstElementPtr
boost::shared_ptr< NameChangeRequest > NameChangeRequestPtr
Defines a pointer to a NameChangeRequest.
const isc::log::MessageID DHCP6_DDNS_REQUEST_SEND_FAILED
boost::shared_ptr< OptionVendor > OptionVendorPtr
Pointer to a vendor option.
const isc::log::MessageID DHCP6_PD_LEASE_ADVERT
const isc::log::MessageID DHCP6_BUFFER_RECEIVED
const isc::log::MessageID DHCP6_RELEASE_NA_DELETED
isc::log::Logger bad_packet6_logger(DHCP6_BAD_PACKET_LOGGER_NAME)
Logger for rejected packets.
const isc::log::MessageID DHCP6_PACKET_DROP_PARSE_FAIL
const isc::log::MessageID DHCP6_RELEASE_PD_DELETED
const isc::log::MessageID DHCP6_LEASE_ALLOC
const isc::log::MessageID DHCP6_FLEX_ID
boost::shared_ptr< Subnet > SubnetPtr
A generic pointer to either Subnet4 or Subnet6 object.
const isc::log::MessageID DHCP6_HOOK_PACKET_SEND_SKIP
uint32_t calculateDdnsTtl(uint32_t lease_lft, const util::Optional< double > &ddns_ttl_percent)
Calculates TTL for a DNS resource record based on lease life time.
const isc::log::MessageID DHCP6_SUBNET_SELECTION_FAILED
const isc::log::MessageID DHCP6_CLASS_UNDEFINED
const isc::log::MessageID DHCP6_PACKET_DROP_SERVERID_MISMATCH
const isc::log::MessageID DHCP6_HOOK_DECLINE_SKIP
const isc::log::MessageID DHCP6_PD_LEASE_REUSE
const isc::log::MessageID DHCP6_PACKET_DROP_UNICAST
const isc::log::MessageID DHCP6_LEASE_PD_WITHOUT_DUID
const isc::log::MessageID DHCP6_LEASE_ALLOC_FAIL
const isc::log::MessageID DHCP6_PACKET_SEND_FAIL
const isc::log::MessageID DHCP6_PACKET_PROCESS_EXCEPTION
void queueNCR(const NameChangeType &chg_type, const Lease4Ptr &lease)
Creates name change request from the DHCPv4 lease.
boost::shared_ptr< Option6PDExclude > Option6PDExcludePtr
Pointer to the Option6PDExclude object.
const isc::log::MessageID EVAL_RESULT
const isc::log::MessageID DHCP6_BUFFER_UNPACK
std::vector< uint32_t > CfgMACSources
Container for defined MAC/hardware address sources.
const isc::log::MessageID DHCP6_SRV_D2STOP_ERROR
const isc::log::MessageID DHCP6_PACKET_SEND
const isc::log::MessageID DHCP6_DECLINE_FAIL_LEASE_WITHOUT_DUID
const int DBG_DHCP6_BASIC_DATA
Debug level used to log the traces with some basic data.
const isc::log::MessageID DHCP6_HOOK_PACKET_RCVD_SKIP
boost::shared_ptr< DUID > DuidPtr
const isc::log::MessageID DHCP6_OPEN_SOCKET
const isc::log::MessageID DHCP6_PACK_FAIL
const isc::log::MessageID DHCP6_RELEASE_PD_FAIL_WRONG_IAID
const isc::log::MessageID DHCP6_HOOK_DDNS_UPDATE
OptionBuffer::const_iterator OptionBufferConstIter
const_iterator for walking over OptionBuffer
boost::shared_ptr< Lease6 > Lease6Ptr
Pointer to a Lease6 structure.
std::vector< Lease6Ptr > Lease6Collection
A collection of IPv6 leases.
const int DBG_DHCP6_HOOKS
Debug level used to trace hook related operations.
const isc::log::MessageID DHCP6_HOOK_LEASE6_RELEASE_NA_SKIP
ContinuationPtr makeContinuation(Continuation &&cont)
Continuation factory.
const int DBG_DHCP6_START
Debug level used to log information during server startup.
const isc::log::MessageID DHCP6_PD_LEASE_ALLOC
const isc::log::MessageID DHCP6_DDNS_GENERATE_FQDN
const isc::log::MessageID DHCP6_RELEASE_PD_EXPIRED
boost::shared_ptr< Option6IA > Option6IAPtr
A pointer to the Option6IA object.
boost::shared_ptr< Subnet6 > Subnet6Ptr
A pointer to a Subnet6 object.
const isc::log::MessageID DHCP6_DDNS_REMOVE_OLD_LEASE_FQDN
boost::shared_ptr< const CfgRSOO > ConstCfgRSOOPtr
Pointer to the const object.
boost::shared_ptr< const CfgHostOperations > ConstCfgHostOperationsPtr
Pointer to the const object.
std::multimap< unsigned int, OptionPtr > OptionCollection
A collection of DHCP (v4 or v6) options.
const isc::log::MessageID DHCP6_SUBNET_DATA
const isc::log::MessageID DHCP6_UNKNOWN_MSG_RECEIVED
boost::shared_ptr< ClientClassDef > ClientClassDefPtr
a pointer to an ClientClassDef
boost::shared_ptr< DdnsParams > DdnsParamsPtr
Defines a pointer for DdnsParams instances.
const isc::log::MessageID DHCP6_HOOK_SUBNET6_SELECT_DROP
const isc::log::MessageID DHCP6_ADD_GLOBAL_STATUS_CODE
boost::shared_ptr< Option6IAPrefix > Option6IAPrefixPtr
Pointer to the Option6IAPrefix object.
const isc::log::MessageID DHCP6_DDNS_RESPONSE_FQDN_DATA
const isc::log::MessageID DHCP6_RELEASE_NA
const isc::log::MessageID DHCP6_REQUIRED_OPTIONS_CHECK_FAIL
const isc::log::MessageID DHCP6_PROCESS_IA_NA_EXTEND
const isc::log::MessageID DHCP6_RELEASE_PD_FAIL
const isc::log::MessageID DHCP6_SRV_CONSTRUCT_ERROR
const isc::log::MessageID DHCP6_LEASE_RENEW
const char * DOCSIS3_CLASS_EROUTER
The class as specified in vendor-class option by the devices.
const isc::log::MessageID DHCP6_RELEASE_NA_FAIL
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
const isc::log::MessageID DHCP6_PACKET_PROCESS_STD_EXCEPTION
const isc::log::MessageID DHCP6_PACKET_RECEIVE_FAIL
const isc::log::MessageID DHCP6_DECLINE_FAIL_IAID_MISMATCH
OptionContainer::nth_index< 5 >::type OptionContainerCancelIndex
Type of the index #5 - option cancellation flag.
boost::shared_ptr< Option6StatusCode > Option6StatusCodePtr
Pointer to the isc::dhcp::Option6StatusCode.
std::pair< OptionContainerPersistIndex::const_iterator, OptionContainerPersistIndex::const_iterator > OptionContainerPersistRange
Pair of iterators to represent the range of options having the same persistency flag.
boost::shared_ptr< SharedNetwork6 > SharedNetwork6Ptr
Pointer to SharedNetwork6 object.
isc::log::Logger packet6_logger(DHCP6_PACKET_LOGGER_NAME)
Logger for processed packets.
const isc::log::MessageID DHCP6_DECLINE_LEASE
boost::shared_ptr< Expression > ExpressionPtr
const isc::log::MessageID DHCP6_LEASE_ADVERT_FAIL
const isc::log::MessageID DHCP6_HOOK_LEASES6_PARKING_LOT_FULL
const isc::log::MessageID DHCP6_PD_LEASE_ADVERT_FAIL
boost::shared_ptr< Pool > PoolPtr
a pointer to either IPv4 or IPv6 Pool
isc::hooks::CalloutHandlePtr getCalloutHandle(const T &pktptr)
CalloutHandle Store.
const isc::log::MessageID DHCP6_PACKET_PROCESS_FAIL
const isc::log::MessageID DHCP6_RELEASE_NA_EXPIRED
boost::shared_ptr< ClientClassDictionary > ClientClassDictionaryPtr
Defines a pointer to a ClientClassDictionary.
const isc::log::MessageID DHCP6_PACKET_RECEIVED
const isc::log::MessageID DHCP6_RESPONSE_DATA
const isc::log::MessageID DHCP6_DDNS_RECEIVE_FQDN
const isc::log::MessageID DHCP6_PACKET_OPTIONS_SKIPPED
const isc::log::MessageID DHCP6_NO_INTERFACES
const isc::log::MessageID DHCP6_RELEASE_PD_FAIL_WRONG_DUID
const isc::log::MessageID DHCP6_LEASE_REUSE
isc::log::Logger ddns6_logger(DHCP6_DDNS_LOGGER_NAME)
Logger for Hostname or FQDN processing.
boost::shared_ptr< Continuation > ContinuationPtr
Define the type of shared pointers to continuations.
boost::shared_ptr< OptionContainer > OptionContainerPtr
Pointer to the OptionContainer object.
boost::shared_ptr< ClientClassDefList > ClientClassDefListPtr
Defines a pointer to a ClientClassDefList.
const isc::log::MessageID DHCP6_HOOK_LEASES6_COMMITTED_DROP
const isc::log::MessageID DHCP6_HOOK_PACKET_SEND_DROP
const isc::log::MessageID DHCP6_DDNS_GENERATED_FQDN_UPDATE_FAIL
const isc::log::MessageID DHCP6_PACKET_DROP_DROP_CLASS2
boost::shared_ptr< Option6IAAddr > Option6IAAddrPtr
A pointer to the isc::dhcp::Option6IAAddr object.
const char * DOCSIS3_CLASS_MODEM
DOCSIS3.0 compatible cable modem.
const isc::log::MessageID DHCP6_SHUTDOWN_REQUEST