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" 212 const std::string Dhcpv6Srv::VENDOR_CLASS_PREFIX(
"VENDOR_CLASS_");
214 Dhcpv6Srv::Dhcpv6Srv(uint16_t server_port, uint16_t client_port)
215 : io_service_(new
IOService()), server_port_(server_port),
216 client_port_(client_port), serverid_(), shutdown_(true),
217 alloc_engine_(), name_change_reqs_(),
247 }
catch (
const std::exception &e) {
262 for (
auto it = dhcp6_statistics.begin(); it != dhcp6_statistics.end(); ++it) {
264 stats_mgr.
setValue((*it), static_cast<int64_t>(0));
274 }
catch (
const std::exception& ex) {
281 }
catch (
const std::exception& ex) {
291 HooksManager::prepareUnloadLibraries();
292 if (!HooksManager::unloadLibraries()) {
293 auto names = HooksManager::getLibraryNames();
295 if (!names.empty()) {
297 for (
size_t i = 1; i < names.size(); ++i) {
298 msg += std::string(
", ") + names[i];
328 if (
getServerID()->getData() != server_id->getData()){
330 .arg(pkt->getLabel())
342 switch (pkt->getType()) {
347 if (pkt->relay_info_.empty() && !pkt->getLocalAddr().isV6Multicast()) {
349 .arg(pkt->getLabel())
350 .arg(pkt->getName());
366 cfg->getIdentifierTypes()) {
383 if (HooksManager::calloutsPresent(Hooks.hook_index_host6_identifier_)) {
387 std::vector<uint8_t> id;
396 callout_handle->setArgument(
"query6", ctx.
query_);
397 callout_handle->setArgument(
"id_type", type);
398 callout_handle->setArgument(
"id_value",
id);
401 HooksManager::callCallouts(Hooks.hook_index_host6_identifier_,
404 callout_handle->getArgument(
"id_type", type);
405 callout_handle->getArgument(
"id_value",
id);
407 if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_CONTINUE) &&
430 ctx.
duid_ = query->getClientId();
450 if (global_host && !global_host->getClientClasses6().empty()) {
455 const ClientClasses& classes = global_host->getClientClasses6();
457 cclass != classes.
cend(); ++cclass) {
458 query->addClass(*cclass);
467 query->addClass(
"KNOWN");
469 .arg(query->getLabel())
476 if (query->inClass(
"DROP")) {
479 .arg(query->toText());
480 StatsMgr::instance().addValue(
"pkt6-receive-drop",
481 static_cast<int64_t>(1));
486 ctx.
hosts_[SUBNET_ID_GLOBAL] = global_host;
523 ctx.
subnet_->getSharedNetwork(sn);
535 global_host && !global_host->getClientClasses6().empty()) ||
536 (!sn && current_host && !current_host->getClientClasses6().empty())) {
557 if (!ctx.
hosts_.empty()) {
558 pkt->addClass(
"KNOWN");
560 .arg(pkt->getLabel())
563 pkt->addClass(
"UNKNOWN");
565 .arg(pkt->getLabel())
573 if (!classes.
empty()) {
575 .arg(pkt->getLabel())
580 if (pkt->inClass(
"DROP")) {
583 StatsMgr::instance().addValue(
"pkt6-receive-drop",
584 static_cast<int64_t>(1));
596 while (__AFL_LOOP(fuzzer.maxLoopCount())) {
606 }
catch (
const std::exception& e) {
623 MultiThreadingMgr::instance().apply(
false, 0, 0);
636 uint32_t timeout = 1;
647 .arg(query->getRemoteAddr().toText())
648 .arg(query->getRemotePort())
649 .arg(query->getLocalAddr().toText())
650 .arg(query->getLocalPort())
651 .arg(query->getIface());
657 StatsMgr::instance().addValue(
"pkt6-received", static_cast<int64_t>(1));
673 }
catch (
const std::exception& e) {
686 .arg(query->getLabel());
689 if (MultiThreadingMgr::instance().getMode()) {
690 typedef function<void()> CallBack;
691 boost::shared_ptr<CallBack> call_back =
694 if (!MultiThreadingMgr::instance().getThreadPool().add(call_back)) {
707 }
catch (
const std::exception& e) {
730 query->addClass(
"ALL");
732 bool skip_unpack =
false;
736 if (HooksManager::calloutsPresent(Hooks.hook_index_buffer6_receive_)) {
749 callout_handle->setArgument(
"query6", query);
752 HooksManager::callCallouts(Hooks.hook_index_buffer6_receive_, *callout_handle);
758 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
760 .arg(query->getRemoteAddr().toText())
761 .arg(query->getLocalAddr().toText())
762 .arg(query->getIface());
769 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
771 .arg(query->getRemoteAddr().toText())
772 .arg(query->getLocalAddr().toText())
773 .arg(query->getIface());
776 StatsMgr::instance().addValue(
"pkt6-receive-drop",
777 static_cast<int64_t>(1));
781 callout_handle->getArgument(
"query6", query);
789 .arg(query->getRemoteAddr().toText())
790 .arg(query->getLocalAddr().toText())
791 .arg(query->getIface());
799 }
catch (
const std::exception &e) {
802 .arg(query->getRemoteAddr().toText())
803 .arg(query->getLocalAddr().toText())
804 .arg(query->getIface())
808 StatsMgr::instance().addValue(
"pkt6-parse-failed",
809 static_cast<int64_t>(1));
810 StatsMgr::instance().addValue(
"pkt6-receive-drop",
811 static_cast<int64_t>(1));
817 processStatsReceived(query);
824 StatsMgr::instance().addValue(
"pkt6-receive-drop", static_cast<int64_t>(1));
834 StatsMgr::instance().addValue(
"pkt6-receive-drop", static_cast<int64_t>(1));
842 .arg(query->getLabel())
843 .arg(query->getName())
844 .arg(static_cast<int>(query->getType()))
845 .arg(query->getRemoteAddr())
846 .arg(query->getLocalAddr())
847 .arg(query->getIface());
849 .arg(query->getLabel())
850 .arg(query->toText());
855 if (HooksManager::calloutsPresent(Hooks.hook_index_pkt6_receive_)) {
868 callout_handle->setArgument(
"query6", query);
871 HooksManager::callCallouts(Hooks.hook_index_pkt6_receive_, *callout_handle);
876 if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) ||
877 (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP)) {
879 .arg(query->getLabel());
881 StatsMgr::instance().addValue(
"pkt6-receive-drop",
882 static_cast<int64_t>(1));
886 callout_handle->getArgument(
"query6", query);
895 if (query->inClass(
"DROP")) {
897 .arg(query->toText());
898 StatsMgr::instance().addValue(
"pkt6-receive-drop",
899 static_cast<int64_t>(1));
916 }
catch (
const std::exception& e) {
930 if (MultiThreadingMgr::instance().getMode() &&
940 if (!client_handler.
tryLock(query, cont)) {
970 switch (query->getType()) {
1007 }
catch (
const std::exception& e) {
1017 .arg(query->getName())
1018 .arg(query->getRemoteAddr().toText())
1022 StatsMgr::instance().addValue(
"pkt6-receive-drop", static_cast<int64_t>(1));
1041 rsp->setRemoteAddr(query->getRemoteAddr());
1042 rsp->setLocalAddr(query->getLocalAddr());
1047 }
else if (rsp->relay_info_.empty()) {
1049 rsp->setRemotePort(DHCP6_CLIENT_PORT);
1053 rsp->setRemotePort(relay_port ? relay_port : DHCP6_SERVER_PORT);
1059 rsp->setLocalPort(DHCP6_SERVER_PORT);
1061 rsp->setIndex(query->getIndex());
1062 rsp->setIface(query->getIface());
1067 HooksManager::calloutsPresent(Hooks.hook_index_leases6_committed_)) {
1091 std::shared_ptr<ScopedCalloutHandleState> callout_handle_state =
1092 std::make_shared<ScopedCalloutHandleState>(callout_handle);
1097 callout_handle->setArgument(
"query6", query);
1103 if (new_lease->reuseable_valid_lft_ == 0) {
1104 new_leases->push_back(new_lease);
1108 callout_handle->setArgument(
"leases6", new_leases);
1113 for (
auto const& iac : ctx.
ias_) {
1114 if (!iac.old_leases_.empty()) {
1115 for (
auto old_lease : iac.old_leases_) {
1117 deleted_leases->push_back(old_lease);
1120 bool in_new =
false;
1122 if ((new_lease->addr_ == old_lease->addr_) &&
1123 (new_lease->prefixlen_ == old_lease->prefixlen_)) {
1129 deleted_leases->push_back(old_lease);
1134 callout_handle->setArgument(
"deleted_leases6", deleted_leases);
1137 uint32_t parked_packet_limit = 0;
1141 parked_packet_limit = ppl->intValue();
1144 if (parked_packet_limit) {
1145 const auto& parking_lot = ServerHooks::getServerHooks().
1146 getParkingLotPtr(
"leases6_committed");
1147 if (parking_lot && (parking_lot->size() >= parked_packet_limit)) {
1151 .arg(parked_packet_limit)
1152 .arg(query->getLabel());
1154 static_cast<int64_t>(1));
1164 HooksManager::park(
"leases6_committed", query,
1165 [
this, callout_handle, query, rsp, callout_handle_state]()
mutable {
1166 if (MultiThreadingMgr::instance().getMode()) {
1167 typedef function<void()> CallBack;
1168 boost::shared_ptr<CallBack> call_back =
1170 this, callout_handle, query, rsp));
1171 callout_handle_state->on_completion_ = [call_back]() {
1172 MultiThreadingMgr::instance().getThreadPool().add(call_back);
1182 HooksManager::callCallouts(Hooks.hook_index_leases6_committed_,
1186 HooksManager::drop(
"leases6_committed", query);
1190 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_PARK) {
1192 .arg(query->getLabel());
1200 HooksManager::drop(
"leases6_committed", query);
1201 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
1203 .arg(query->getLabel());
1221 }
catch (
const std::exception& e) {
1237 bool skip_pack =
false;
1243 if (HooksManager::calloutsPresent(Hooks.hook_index_pkt6_send_)) {
1255 callout_handle->setArgument(
"query6", query);
1258 callout_handle->setArgument(
"response6", rsp);
1261 HooksManager::callCallouts(Hooks.hook_index_pkt6_send_, *callout_handle);
1268 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
1270 .arg(rsp->getLabel());
1275 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
1277 .arg(rsp->getLabel());
1286 }
catch (
const std::exception& e) {
1306 if (HooksManager::calloutsPresent(Hooks.hook_index_buffer6_send_)) {
1318 callout_handle->setArgument(
"response6", rsp);
1321 HooksManager::callCallouts(Hooks.hook_index_buffer6_send_,
1327 if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) ||
1328 (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP)) {
1331 .arg(rsp->getLabel());
1335 callout_handle->getArgument(
"response6", rsp);
1339 .arg(rsp->getLabel())
1340 .arg(rsp->getName())
1341 .arg(static_cast<int>(rsp->getType()))
1342 .arg(rsp->getLocalAddr().isV6Zero() ?
"*" : rsp->getLocalAddr().toText())
1343 .arg(rsp->getLocalPort())
1344 .arg(rsp->getRemoteAddr())
1345 .arg(rsp->getRemotePort())
1346 .arg(rsp->getIface());
1349 .arg(static_cast<int>(rsp->getType())).arg(rsp->toText());
1356 }
catch (
const std::exception& e) {
1372 tmp << hex << setw(2) << setfill('0') << static_cast<uint16_t>(*it);
1386 answer->addOption(clientid);
1391 if (!question->relay_info_.empty()) {
1392 answer->copyRelayInfo(question);
1410 co_list.push_back(ctx.
currentHost()->getCfgOption6());
1418 ctx.
subnet_->getPool(resource.getPrefixLength() == 128 ?
1420 resource.getAddress(),
1422 if (pool && !pool->getCfgOption()->empty()) {
1423 co_list.push_back(pool->getCfgOption());
1430 if (!ctx.
subnet_->getCfgOption()->empty()) {
1431 co_list.push_back(ctx.
subnet_->getCfgOption());
1436 ctx.
subnet_->getSharedNetwork(network);
1437 if (network && !network->getCfgOption()->empty()) {
1438 co_list.push_back(network->getCfgOption());
1445 cclass != classes.
cend(); ++cclass) {
1448 getClientClassDictionary()->findClass(*cclass);
1453 .arg(question->getLabel())
1460 if (ccdef->getCfgOption()->empty()) {
1465 co_list.push_back(ccdef->getCfgOption());
1479 if (co_list.empty()) {
1483 set<uint16_t> requested_opts;
1487 boost::shared_ptr<OptionIntArray<uint16_t> > option_oro =
1489 (question->getOption(
D6O_ORO));
1493 set<uint16_t> oro_req_opts;
1494 for (uint16_t code : option_oro->getValues()) {
1495 static_cast<void>(oro_req_opts.insert(code));
1497 requested_opts = oro_req_opts;
1501 for (CfgOptionList::const_iterator copts = co_list.begin();
1502 copts != co_list.end(); ++copts) {
1510 for (OptionContainerPersistIndex::const_iterator desc = range.first;
1511 desc != range.second; ++desc) {
1513 if (desc->option_) {
1514 uint16_t code = desc->option_->getType();
1515 static_cast<void>(requested_opts.insert(code));
1520 for (uint16_t opt : requested_opts) {
1522 if (!answer->getOption(opt)) {
1524 for (CfgOptionList::const_iterator copts = co_list.begin();
1525 copts != co_list.end(); ++copts) {
1529 answer->addOption(desc.
option_);
1538 set<uint32_t> vendor_ids;
1544 static_cast<void>(vendor_ids.insert(vendor_id));
1548 for (CfgOptionList::const_iterator copts = co_list.begin();
1549 copts != co_list.end(); ++copts) {
1552 if (!desc.option_) {
1557 if (!vendor_class) {
1562 if (vendor_ids.count(vendor_id) > 0) {
1566 answer->addOption(desc.option_);
1567 static_cast<void>(vendor_ids.insert(vendor_id));
1573 set<uint32_t> vendor_ids;
1576 vendor_opts = boost::dynamic_pointer_cast<
OptionVendor>(opt.second);
1579 static_cast<void>(vendor_ids.insert(vendor_id));
1583 for (CfgOptionList::const_iterator copts = co_list.begin();
1584 copts != co_list.end(); ++copts) {
1587 if (!desc.option_) {
1591 boost::dynamic_pointer_cast<
OptionVendor>(desc.option_);
1597 if (vendor_ids.count(vendor_id) > 0) {
1601 answer->addOption(desc.option_);
1602 static_cast<void>(vendor_ids.insert(vendor_id));
1621 if (!ctx.
subnet_ || co_list.empty()) {
1625 set<uint32_t> vendor_ids;
1629 map<uint32_t, OptionVendorPtr> vendor_rsps;
1632 vendor_rsp = boost::dynamic_pointer_cast<
OptionVendor>(opt.second);
1635 vendor_rsps[vendor_id] = vendor_rsp;
1636 static_cast<void>(vendor_ids.insert(vendor_id));
1642 map<uint32_t, OptionVendorPtr> vendor_reqs;
1645 vendor_req = boost::dynamic_pointer_cast<
OptionVendor>(opt.second);
1648 vendor_reqs[vendor_id] = vendor_req;
1649 static_cast<void>(vendor_ids.insert(vendor_id));
1660 static_cast<void>(vendor_ids.insert(vendor_id));
1666 if (vendor_ids.empty()) {
1670 map<uint32_t, set<uint16_t> > requested_opts;
1687 set<uint16_t> oro_req_opts;
1688 for (uint16_t code : oro->getValues()) {
1689 static_cast<void>(oro_req_opts.insert(code));
1696 for (uint32_t vendor_id : vendor_ids) {
1697 for (CfgOptionList::const_iterator copts = co_list.begin();
1698 copts != co_list.end(); ++copts) {
1706 for (OptionContainerPersistIndex::const_iterator desc = range.first;
1707 desc != range.second; ++desc) {
1708 if (!desc->option_) {
1712 uint16_t code = desc->option_->getType();
1713 static_cast<void>(requested_opts[vendor_id].insert(code));
1718 if (requested_opts[vendor_id].empty()) {
1725 if (vendor_rsps.count(vendor_id) > 0) {
1726 vendor_rsp = vendor_rsps[vendor_id];
1734 for (uint16_t opt : requested_opts[vendor_id]) {
1735 if (!vendor_rsp->getOption(opt)) {
1736 for (CfgOptionList::const_iterator copts = co_list.begin();
1737 copts != co_list.end(); ++copts) {
1740 vendor_rsp->addOption(desc.
option_);
1750 if (added && (vendor_rsps.count(vendor_id) == 0)) {
1751 answer->addOption(vendor_rsp);
1759 switch (pkt->getType()) {
1781 .arg(static_cast<int>(pkt->getType()))
1782 .arg(pkt->getIface());
1787 .arg(pkt->getName())
1788 .arg(pkt->getRemoteAddr().toText())
1794 StatsMgr::instance().addValue(
"pkt6-receive-drop", static_cast<int64_t>(1));
1804 if (client_ids.size() != 1) {
1806 << pkt->getName() <<
", but " << client_ids.size()
1813 if (client_ids.size() > 1) {
1815 <<
") client-id options received in " << pkt->getName());
1817 if (!client_ids.empty()) {
1830 if (!server_ids.empty()) {
1832 << server_ids.size() <<
" received in " << pkt->getName());
1837 if (server_ids.size() != 1) {
1839 << server_ids.size() <<
"), exactly 1 expected in message " 1846 if (server_ids.size() > 1) {
1848 <<
") server-id options received in " << pkt->getName());
1850 if (!server_ids.empty()) {
1863 uint16_t len = opt->len() - opt->getHeaderLen();
1866 << len <<
" byte(s). It must be at least 3 and no more than " 1876 getCfgSubnets6()->selectSubnet(selector);
1879 if (HooksManager::calloutsPresent(Hooks.hook_index_subnet6_select_)) {
1892 callout_handle->setArgument(
"query6", question);
1893 callout_handle->setArgument(
"subnet6", subnet);
1898 callout_handle->setArgument(
"subnet6collection",
1900 getCfgSubnets6()->getAll());
1903 HooksManager::callCallouts(Hooks.hook_index_subnet6_select_, *callout_handle);
1909 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
1911 .arg(question->getLabel());
1917 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
1919 .arg(question->getLabel());
1925 callout_handle->getArgument(
"subnet6", subnet);
1931 .arg(question->getLabel())
1932 .arg(subnet->getID());
1936 .arg(question->getLabel())
1937 .arg(subnet->toText());
1941 .arg(question->getLabel());
1966 for (
const auto& opt : question->options_) {
1967 switch (opt.second->getType()) {
1970 boost::dynamic_pointer_cast<
1973 answer->addOption(answer_opt);
1979 boost::dynamic_pointer_cast<
1982 answer->addOption(answer_opt);
2007 if (ddns_params->getEnableUpdates() &&
2017 .arg(question->getLabel());
2030 .arg(question->getLabel())
2031 .arg(fqdn->toText());
2050 *ddns_params,
true),
2067 .arg(question->getLabel())
2068 .arg(fqdn_resp->
toText());
2069 answer->addOption(fqdn_resp);
2073 if (HooksManager::calloutsPresent(Hooks.hook_index_ddns6_update_)) {
2084 callout_handle->setArgument(
"query6", question);
2085 callout_handle->setArgument(
"response6", answer);
2086 callout_handle->setArgument(
"subnet6", subnet);
2087 callout_handle->setArgument(
"hostname", ctx.
hostname_);
2090 callout_handle->setArgument(
"ddns-params", ddns_params);
2093 HooksManager::callCallouts(Hooks.hook_index_ddns6_update_, *callout_handle);
2096 string hook_hostname;
2097 bool hook_fwd_dns_update;
2098 bool hook_rev_dns_update;
2099 callout_handle->getArgument(
"hostname", hook_hostname);
2100 callout_handle->getArgument(
"fwd-update", hook_fwd_dns_update);
2101 callout_handle->getArgument(
"rev-update", hook_rev_dns_update);
2115 if (!(hook_fwd_dns_update || hook_rev_dns_update)) {
2142 <<
" encapsulating server's message must not be" 2143 <<
" NULL when creating DNS NameChangeRequest");
2156 bool do_fwd =
false;
2157 bool do_rev =
false;
2167 "client identifier is required when creating a new" 2168 " DNS NameChangeRequest");
2175 opt_fqdn->packDomainName(name_buf);
2176 const uint8_t* name_data =
static_cast<const uint8_t*
>(name_buf.
getData());
2179 std::vector<uint8_t> buf_vec(name_data, name_data + name_buf.
getLength());
2185 for (
auto answer_ia : answer->getOptions(
D6O_IA_NA)) {
2200 bool extended_only =
false;
2204 if ((*l)->addr_ == iaaddr->getAddress()) {
2209 ((*l)->hostname_ == opt_fqdn->getDomainName() &&
2210 (*l)->fqdn_fwd_ == do_fwd && (*l)->fqdn_rev_ == do_rev)) {
2211 extended_only =
true;
2223 if (!(do_fwd || do_rev) || (extended_only)) {
2238 opt_fqdn->getDomainName(),
2239 iaaddr->getAddress().toText(),
2259 getMACSources().get();
2261 for (CfgMACSources::const_iterator it = mac_sources.begin();
2262 it != mac_sources.end(); ++it) {
2263 hwaddr = pkt->getMAC(*it);
2274 boost::shared_ptr<Option6IA> ia) {
2283 hint = hint_opt->getAddress();
2287 .arg(query->getLabel())
2289 .arg(hint_opt ? hint.toText() :
"(no hint)");
2308 "Server could not select subnet for" 2331 if (!leases.empty()) {
2332 lease = *leases.begin();
2345 .arg(query->getLabel())
2346 .arg(lease->addr_.toText())
2347 .arg(ia->getIAID());
2348 }
else if (lease->reuseable_valid_lft_ == 0) {
2350 .arg(query->getLabel())
2351 .arg(lease->addr_.toText())
2355 lease->valid_lft_ = lease->reuseable_valid_lft_;
2356 lease->preferred_lft_ = lease->reuseable_preferred_lft_;
2358 .arg(query->getLabel())
2359 .arg(lease->addr_.toText())
2364 .arg(query->getLabel())
2366 .arg(lease->toText());
2369 setTeeTimes(lease->preferred_lft_, subnet, ia_rsp);
2372 lease->preferred_lft_,
2373 lease->valid_lft_));
2374 ia_rsp->addOption(addr);
2387 .arg(query->getLabel())
2388 .arg(ia->getIAID());
2390 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
2392 "Sorry, no address could be" 2401 boost::shared_ptr<Option6IA> ia) {
2411 hint = hint_opt->getAddress();
2415 .arg(query->getLabel())
2417 .arg(hint_opt ? hint.toText() :
"(no hint)");
2434 "Sorry, no subnet available."));
2454 if (!leases.empty()) {
2458 uint32_t min_preferred_lft = (*leases.begin())->preferred_lft_;
2460 const bool pd_exclude_requested = requestedInORO(query,
D6O_PD_EXCLUDE);
2461 for (Lease6Collection::iterator l = leases.begin();
2462 l != leases.end(); ++l) {
2468 .arg(query->getLabel())
2469 .arg((*l)->addr_.toText())
2470 .arg(static_cast<int>((*l)->prefixlen_))
2471 .arg(ia->getIAID());
2472 }
else if ((*l)->reuseable_valid_lft_ == 0) {
2474 .arg(query->getLabel())
2475 .arg((*l)->addr_.toText())
2476 .arg(static_cast<int>((*l)->prefixlen_))
2480 (*l)->valid_lft_ = (*l)->reuseable_valid_lft_;
2481 (*l)->preferred_lft_ = (*l)->reuseable_preferred_lft_;
2483 .arg(query->getLabel())
2484 .arg((*l)->addr_.toText())
2485 .arg(static_cast<int>((*l)->prefixlen_))
2491 if (((*l)->preferred_lft_ > 0) && (min_preferred_lft > (*l)->preferred_lft_)) {
2492 min_preferred_lft = (*l)->preferred_lft_;
2495 boost::shared_ptr<Option6IAPrefix>
2497 (*l)->prefixlen_, (*l)->preferred_lft_,
2499 ia_rsp->addOption(addr);
2501 if (pd_exclude_requested) {
2504 Pool6Ptr pool = boost::dynamic_pointer_cast<
2508 if (pd_exclude_option) {
2509 addr->addOption(pd_exclude_option);
2529 .arg(query->getLabel())
2530 .arg(ia->getIAID());
2532 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
2534 "Sorry, no prefixes could" 2543 boost::shared_ptr<Option6IA> ia) {
2546 .arg(query->getLabel())
2547 .arg(ia->getIAID());
2566 "Sorry, no known leases for this duid/iaid."));
2578 for (OptionCollection::const_iterator it = addrs.begin();
2579 it != addrs.end(); ++it) {
2610 uint32_t min_preferred_lft = std::numeric_limits<uint32_t>::max();
2613 for (Lease6Collection::iterator l = leases.begin(); l != leases.end(); ++l) {
2614 if ((*l)->reuseable_valid_lft_ == 0) {
2616 .arg(query->getLabel())
2617 .arg((*l)->addr_.toText())
2618 .arg(ia->getIAID());
2620 (*l)->valid_lft_ = (*l)->reuseable_valid_lft_;
2621 (*l)->preferred_lft_ = (*l)->reuseable_preferred_lft_;
2623 .arg(query->getLabel())
2624 .arg((*l)->addr_.toText())
2630 (*l)->addr_, (*l)->preferred_lft_, (*l)->valid_lft_));
2631 ia_rsp->addOption(iaaddr);
2634 if (((*l)->preferred_lft_ > 0) && (min_preferred_lft > (*l)->preferred_lft_)) {
2635 min_preferred_lft = (*l)->preferred_lft_;
2640 hints.erase(std::remove(hints.begin(), hints.end(), hint_type),
2651 if (
equalValues(query->getClientId(), (*l)->duid_)) {
2653 (*l)->addr_, 0, 0));
2654 ia_rsp->addOption(iaaddr);
2659 hints.erase(std::remove(hints.begin(), hints.end(), hint_type), hints.end());
2667 .arg(query->getLabel())
2668 .arg((*l)->toText())
2679 for (AllocEngine::HintContainer::const_iterator hint = hints.begin();
2680 hint != hints.end(); ++hint) {
2682 hint->getAddress(), 0, 0));
2683 ia_rsp->addOption(iaaddr);
2686 if (!leases.empty()) {
2692 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
2694 "Sorry, no addresses could be" 2695 " assigned at this time."));
2704 boost::shared_ptr<Option6IA> ia) {
2707 .arg(query->getLabel())
2708 .arg(ia->getIAID());
2725 "Sorry, no known PD leases" 2726 " for this duid/iaid."));
2746 " client sending Rebind to extend lifetime of the" 2747 " prefix (DUID=" << duid->toText() <<
", IAID=" 2748 << ia->getIAID() <<
")");
2760 for (OptionCollection::const_iterator it = addrs.begin();
2761 it != addrs.end(); ++it) {
2795 const bool pd_exclude_requested = requestedInORO(query,
D6O_PD_EXCLUDE);
2799 uint32_t min_preferred_lft = std::numeric_limits<uint32_t>::max();
2801 for (Lease6Collection::iterator l = leases.begin(); l != leases.end(); ++l) {
2802 if ((*l)->reuseable_valid_lft_ == 0) {
2804 .arg(query->getLabel())
2805 .arg((*l)->addr_.toText())
2806 .arg(static_cast<int>((*l)->prefixlen_))
2807 .arg(ia->getIAID());
2809 (*l)->valid_lft_ = (*l)->reuseable_valid_lft_;
2810 (*l)->preferred_lft_ = (*l)->reuseable_preferred_lft_;
2812 .arg(query->getLabel())
2813 .arg((*l)->addr_.toText())
2814 .arg(static_cast<int>((*l)->prefixlen_))
2820 (*l)->addr_, (*l)->prefixlen_,
2821 (*l)->preferred_lft_, (*l)->valid_lft_));
2822 ia_rsp->addOption(prf);
2824 if (pd_exclude_requested) {
2827 Pool6Ptr pool = boost::dynamic_pointer_cast<
2832 if (pd_exclude_option) {
2833 prf->addOption(pd_exclude_option);
2839 if (((*l)->preferred_lft_ > 0) && ((*l)->preferred_lft_ < min_preferred_lft)) {
2840 min_preferred_lft = (*l)->preferred_lft_;
2845 hints.erase(std::remove(hints.begin(), hints.end(), hint_type),
2856 if (
equalValues(query->getClientId(), (*l)->duid_)) {
2858 (*l)->prefixlen_, 0, 0));
2859 ia_rsp->addOption(prefix);
2864 hints.erase(std::remove(hints.begin(), hints.end(), hint_type), hints.end());
2869 for (AllocEngine::HintContainer::const_iterator prefix = hints.begin();
2870 prefix != hints.end(); ++prefix) {
2875 if (!prefix->getAddress().isV6Zero()) {
2877 prefix->getAddress(),
2878 prefix->getPrefixLength(),
2880 ia_rsp->addOption(prefix_opt);
2884 if (!leases.empty()) {
2891 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
2893 "Sorry, no prefixes could be" 2894 " assigned at this time."));
2915 for (
const auto& opt : query->options_) {
2916 switch (opt.second->getType()) {
2919 boost::dynamic_pointer_cast<
2922 reply->addOption(answer_opt);
2929 boost::dynamic_pointer_cast<
2932 reply->addOption(answer_opt);
2967 for (
const auto& opt : release->options_) {
2969 switch (opt.second->getType()) {
2972 boost::dynamic_pointer_cast<Option6IA>(opt.second),
2975 reply->addOption(answer_opt);
2981 boost::dynamic_pointer_cast<Option6IA>(opt.second),
2984 reply->addOption(answer_opt);
3001 reply->addOption(createStatusCode(*release, general_status,
3002 "Summary status for all processed IA_NAs"));
3007 int& general_status, boost::shared_ptr<Option6IA> ia,
3011 .arg(query->getLabel())
3012 .arg(ia->getIAID());
3028 if (!release_addr) {
3030 "You did not include an address in your RELEASE"));
3036 release_addr->getAddress());
3043 "Sorry, no known leases for this duid/iaid, can't release."));
3049 if (!lease->duid_) {
3055 .arg(query->getLabel())
3056 .arg(release_addr->getAddress().toText());
3060 "Database consistency check failed when trying to RELEASE"));
3064 if (*duid != *(lease->duid_)) {
3068 .arg(query->getLabel())
3069 .arg(release_addr->getAddress().toText())
3070 .arg(lease->duid_->toText());
3074 "This address does not belong to you, you can't release it"));
3078 if (ia->getIAID() != lease->iaid_) {
3081 .arg(query->getLabel())
3082 .arg(release_addr->getAddress().toText())
3084 .arg(ia->getIAID());
3086 "This is your address, but you used wrong IAID"));
3096 if (HooksManager::calloutsPresent(Hooks.hook_index_lease6_release_)) {
3109 callout_handle->deleteAllArguments();
3112 callout_handle->setArgument(
"query6", query);
3115 callout_handle->setArgument(
"lease6", lease);
3118 HooksManager::callCallouts(Hooks.hook_index_lease6_release_, *callout_handle);
3123 if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) ||
3124 (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP)) {
3127 .arg(query->getLabel());
3132 bool success =
false;
3133 bool expired =
false;
3140 if (expiration_cfg->getFlushReclaimedTimerWaitTime() &&
3141 expiration_cfg->getHoldReclaimedTime() &&
3144 lease->valid_lft_ = 0;
3145 lease->preferred_lft_ = 0;
3159 "Server failed to release a lease"));
3162 .arg(query->getLabel())
3163 .arg(lease->addr_.toText())
3172 .arg(query->getLabel())
3173 .arg(lease->addr_.toText())
3176 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
STATUS_Success,
3177 "Lease released. Thank you, please come again."));
3181 .arg(query->getLabel())
3182 .arg(lease->addr_.toText())
3186 .arg(query->getLabel())
3187 .arg(lease->addr_.toText())
3191 StatsMgr::instance().addValue(
3192 StatsMgr::generateName(
"subnet", lease->subnet_id_,
"assigned-nas"),
3193 static_cast<int64_t>(-1));
3207 int& general_status, boost::shared_ptr<Option6IA> ia,
3222 boost::shared_ptr<Option6IAPrefix> release_prefix =
3224 if (!release_prefix) {
3226 "You did not include a prefix in your RELEASE"));
3232 release_prefix->getAddress());
3239 "Sorry, no known leases for this duid/iaid, can't release."));
3245 if (!lease->duid_) {
3250 .arg(query->getLabel())
3251 .arg(release_prefix->getAddress().toText())
3252 .arg(static_cast<int>(release_prefix->getLength()));
3256 "Database consistency check failed when trying to RELEASE"));
3260 if (*duid != *(lease->duid_)) {
3263 .arg(query->getLabel())
3264 .arg(release_prefix->getAddress().toText())
3265 .arg(static_cast<int>(release_prefix->getLength()))
3266 .arg(lease->duid_->toText());
3270 "This address does not belong to you, you can't release it"));
3274 if (ia->getIAID() != lease->iaid_) {
3277 .arg(query->getLabel())
3278 .arg(release_prefix->getAddress().toText())
3279 .arg(static_cast<int>(release_prefix->getLength()))
3281 .arg(ia->getIAID());
3283 "This is your address, but you used wrong IAID"));
3293 if (HooksManager::calloutsPresent(Hooks.hook_index_lease6_release_)) {
3306 callout_handle->setArgument(
"query6", query);
3309 callout_handle->setArgument(
"lease6", lease);
3312 HooksManager::callCallouts(Hooks.hook_index_lease6_release_, *callout_handle);
3317 if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) ||
3318 (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP)) {
3321 .arg(query->getLabel());
3326 bool success =
false;
3327 bool expired =
false;
3334 if (expiration_cfg->getFlushReclaimedTimerWaitTime() &&
3335 expiration_cfg->getHoldReclaimedTime() &&
3338 lease->valid_lft_ = 0;
3339 lease->preferred_lft_ = 0;
3353 "Server failed to release a lease"));
3356 .arg(query->getLabel())
3357 .arg(lease->addr_.toText())
3358 .arg(static_cast<int>(lease->prefixlen_))
3366 .arg(query->getLabel())
3367 .arg(lease->addr_.toText())
3368 .arg(static_cast<int>(lease->prefixlen_))
3371 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
STATUS_Success,
3372 "Lease released. Thank you, please come again."));
3376 .arg(query->getLabel())
3377 .arg(lease->addr_.toText())
3378 .arg(static_cast<int>(lease->prefixlen_))
3382 .arg(query->getLabel())
3383 .arg(lease->addr_.toText())
3384 .arg(static_cast<int>(lease->prefixlen_))
3388 StatsMgr::instance().addValue(
3389 StatsMgr::generateName(
"subnet", lease->subnet_id_,
"assigned-pds"),
3390 static_cast<int64_t>(-1));
3406 if (opt_rapid_commit) {
3409 .arg(solicit->getLabel());
3414 response->addOption(opt_rapid_commit);
3433 if (MultiThreadingMgr::instance().getMode()) {
3452 updateReservedFqdn(ctx, response);
3471 if (MultiThreadingMgr::instance().getMode()) {
3490 updateReservedFqdn(ctx, reply);
3491 generateFqdn(reply, ctx);
3505 if (MultiThreadingMgr::instance().getMode()) {
3524 updateReservedFqdn(ctx, reply);
3525 generateFqdn(reply, ctx);
3539 if (MultiThreadingMgr::instance().getMode()) {
3558 updateReservedFqdn(ctx, reply);
3559 generateFqdn(reply, ctx);
3591 bool verified =
false;
3600 for (OptionCollection::const_iterator ia = ias.begin();
3601 ia != ias.end(); ++ia) {
3603 for (OptionCollection::const_iterator opt = opts.begin();
3604 opt != opts.end(); ++opt) {
3616 if (subnet && !subnet->inRange(iaaddr->getAddress())) {
3617 std::ostringstream status_msg;
3618 status_msg <<
"Address " << iaaddr->
getAddress()
3619 <<
" is not on link.";
3620 reply->addOption(createStatusCode(*confirm,
3628 " to the Option6IAAddrPtr. This is programming" 3629 " error and should be reported");
3646 "All addresses are on-link"));
3649 "No subnet selected"));
3725 for (
const auto& opt : decline->options_) {
3726 switch (opt.second->getType()) {
3729 boost::dynamic_pointer_cast<Option6IA>(opt.second),
3734 reply->addOption(answer_opt);
3755 int& general_status, boost::shared_ptr<Option6IA> ia,
3759 .arg(decline->getLabel())
3760 .arg(ia->getIAID());
3775 int total_addrs = 0;
3776 for (OptionCollection::const_iterator opt = opts.begin(); opt != opts.end();
3786 if (!decline_addr) {
3793 decline_addr->getAddress());
3798 .arg(decline->getLabel()).arg(decline_addr->getAddress().toText());
3806 "Server does not know about such an address."));
3814 if (!lease->duid_) {
3820 .arg(decline->getLabel())
3821 .arg(decline_addr->getAddress().toText());
3824 "Database consistency check failed when attempting Decline."));
3830 if (*duid != *(lease->duid_)) {
3834 .arg(decline->getLabel())
3835 .arg(decline_addr->getAddress().toText())
3836 .arg(lease->duid_->toText());
3839 "This address does not belong to you, you can't decline it"));
3845 if (ia->getIAID() != lease->iaid_) {
3848 .arg(decline->getLabel())
3849 .arg(lease->addr_.toText())
3853 "This is your address, but you used wrong IAID"));
3865 new_leases.push_back(lease);
3869 if (total_addrs == 0) {
3871 "No addresses sent in IA_NA"));
3884 container->addOption(status);
3889 boost::shared_ptr<Option6IA> ia_rsp) {
3900 if (HooksManager::calloutsPresent(Hooks.hook_index_lease6_decline_)) {
3913 callout_handle->setArgument(
"query6", decline);
3916 callout_handle->setArgument(
"lease6", lease);
3919 HooksManager::callCallouts(Hooks.hook_index_lease6_decline_,
3925 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
3927 .arg(decline->getLabel())
3928 .arg(decline->getIface())
3929 .arg(lease->addr_.toText());
3935 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
3937 .arg(decline->getLabel())
3938 .arg(decline->getIface())
3939 .arg(lease->addr_.toText());
3944 Lease6Ptr old_values = boost::make_shared<Lease6>(*lease);
3958 .arg(decline->getLabel())
3959 .arg(lease->addr_.toText())
3970 StatsMgr::instance().addValue(
3971 StatsMgr::generateName(
"subnet", lease->subnet_id_,
"declined-addresses"),
3972 static_cast<int64_t>(1));
3975 StatsMgr::instance().addValue(
"declined-addresses", static_cast<int64_t>(1));
3978 .arg(lease->addr_.toText()).arg(lease->valid_lft_);
3980 ia_rsp->addOption(createStatusCode(*decline, *ia_rsp,
STATUS_Success,
3981 "Lease declined. Hopefully the next one will be better."));
4040 void Dhcpv6Srv::classifyByVendor(
const Pkt6Ptr& pkt) {
4044 if (!vclass || vclass->getTuplesNum() == 0) {
4062 pkt->addClass(
"ALL");
4065 classifyByVendor(pkt);
4076 for (ClientClassDefList::const_iterator it = defs_ptr->cbegin();
4077 it != defs_ptr->cend(); ++it) {
4085 if ((*it)->getRequired()) {
4089 if ((*it)->getDependOnKnown() != depend_on_known) {
4092 (*it)->test(pkt, expr_ptr);
4101 for (
auto def : *defs_ptr) {
4105 if (def->getMatchExpr()) {
4106 pkt->classes_.erase(def->getName());
4117 cclass != classes.
cend(); ++cclass) {
4118 pkt->addClass(*cclass);
4123 if (!classes.
empty()) {
4125 .arg(pkt->getLabel())
4135 ctx.
subnet_->getSharedNetwork(shared_network);
4136 if (shared_network) {
4138 if (host && (host->getIPv6SubnetID() != SUBNET_ID_GLOBAL)) {
4154 subnet->getSharedNetwork(network);
4156 const ClientClasses& to_add = network->getRequiredClasses();
4158 cclass != to_add.
cend(); ++cclass) {
4166 cclass != to_add.
cend(); ++cclass) {
4173 ctx.
subnet_->getPool(resource.getPrefixLength() == 128 ?
4175 resource.getAddress(),
4180 cclass != to_add.
cend(); ++cclass) {
4194 cclass != classes.
cend(); ++cclass) {
4217 pkt->addClass(*cclass);
4230 .arg(
"get exception?");
4240 " a message must not be NULL when updating reserved FQDN");
4263 if (new_name != name) {
4268 answer->addOption(fqdn);
4274 Dhcpv6Srv::generateFqdn(
const Pkt6Ptr& answer,
4278 " a message must not be NULL when generating FQDN");
4289 if (!fqdn || !fqdn->getDomainName().empty()) {
4307 std::string generated_name =
4311 .arg(answer->getLabel())
4312 .arg(generated_name);
4329 lease->hostname_ = generated_name;
4330 lease->reuseable_valid_lft_ = 0;
4335 " for address " << addr <<
", so as it is impossible" 4336 " to update FQDN data. This is a programmatic error" 4337 " as the given address is now being handed to the" 4345 answer->addOption(fqdn);
4349 .arg(answer->getLabel())
4363 this, ph::_1, ph::_2));
4381 arg(result).arg((ncr ? ncr->toText() :
" NULL "));
4393 std::stringstream tmp;
4397 tmp << endl << EXTENDED_VERSION << endl;
4398 tmp <<
"linked with:" << endl;
4399 tmp << Logger::getVersion() << endl;
4400 tmp << CryptoLink::getVersion() << endl;
4401 tmp <<
"database:" << endl;
4418 if (query->relay_info_.empty()) {
4429 for (
int i = query->relay_info_.size(); i > 0 ; --i) {
4431 if (rsoo_container) {
4436 for (OptionCollection::const_iterator opt = rsoo.begin();
4437 opt != rsoo.end(); ++opt) {
4441 if (cfg_rsoo->enabled(opt->second->getType()) &&
4442 !rsp->getOption(opt->second->getType())) {
4443 rsp->addOption(opt->second);
4452 if (query->relay_info_.empty()) {
4460 return (query->getRemotePort());
4466 void Dhcpv6Srv::processStatsReceived(
const Pkt6Ptr& query) {
4470 string stat_name =
"pkt6-unknown-received";
4471 switch (query->getType()) {
4473 stat_name =
"pkt6-solicit-received";
4477 stat_name =
"pkt6-advertise-received";
4480 stat_name =
"pkt6-request-received";
4483 stat_name =
"pkt6-confirm-received";
4486 stat_name =
"pkt6-renew-received";
4489 stat_name =
"pkt6-rebind-received";
4493 stat_name =
"pkt6-reply-received";
4496 stat_name =
"pkt6-release-received";
4499 stat_name =
"pkt6-decline-received";
4502 stat_name =
"pkt6-reconfigure-received";
4505 stat_name =
"pkt6-infrequest-received";
4508 stat_name =
"pkt6-dhcpv4-query-received";
4512 stat_name =
"pkt6-dhcpv4-response-received";
4518 StatsMgr::instance().addValue(stat_name, static_cast<int64_t>(1));
4523 StatsMgr::instance().addValue(
"pkt6-sent", static_cast<int64_t>(1));
4527 switch (response->getType()) {
4529 stat_name =
"pkt6-advertise-sent";
4532 stat_name =
"pkt6-reply-sent";
4535 stat_name =
"pkt6-dhcpv4-response-sent";
4542 StatsMgr::instance().addValue(stat_name, static_cast<int64_t>(1));
4546 return (Hooks.hook_index_buffer6_send_);
4550 Dhcpv6Srv::requestedInORO(
const Pkt6Ptr& query,
const uint16_t code)
const {
4555 const std::vector<uint16_t>& codes = oro->
getValues();
4556 return (std::find(codes.begin(), codes.end(), code) != codes.end());
4564 HooksManager::clearParkingLots();
4571 uint32_t t2_time = 0;
4574 if (!subnet->getT2().unspecified()) {
4575 t2_time = subnet->getT2();
4576 }
else if (subnet->getCalculateTeeTimes()) {
4578 t2_time =
static_cast<uint32_t
>(round(subnet->getT2Percent() * preferred_lft));
4582 resp->setT2(t2_time);
4585 uint32_t t1_time = 0;
4588 if (!subnet->getT1().unspecified()) {
4589 t1_time = subnet->getT1();
4590 }
else if (subnet->getCalculateTeeTimes()) {
4592 t1_time =
static_cast<uint32_t
>(round(subnet->getT1Percent() * preferred_lft));
4596 if (t1_time < t2_time) {
4597 resp->setT1(t1_time);
4609 if ((!ctx.
subnet_) || (!orig_subnet) || (orig_subnet->getID() == ctx.
subnet_->getID())) {
4617 orig_subnet->getSharedNetwork(network);
4619 .arg(question->getLabel())
4620 .arg(orig_subnet->toText())
4622 .arg(network ? network->getName() :
"<no network?>");
4628 std::string prev_hostname = ctx.
hostname_;
4645 for (Lease6Collection::const_iterator l = ctx.
new_leases_.begin();
4650 (*l)->reuseable_valid_lft_ = 0;
4657 static std::list<std::list<std::string>>
const list({
4658 {
"config-control",
"config-databases",
"[]"},
4659 {
"hooks-libraries",
"[]",
"parameters",
"*"},
4661 {
"hosts-databases",
"[]"},
static const uint8_t FLAG_N
N bit.
Implementation of the mechanisms to control the use of the Configuration Backends by the DHCPv6 serve...
boost::shared_ptr< OptionVendorClass > OptionVendorClassPtr
Defines a pointer to the OptionVendorClass.
RAII class creating a critical section.
static std::string lifetimeToText(uint32_t lifetime)
Print lifetime.
virtual Pkt6Ptr receivePacket(int timeout)
dummy wrapper around IfaceMgr::receive6
const isc::log::MessageID DHCP6_PROCESS_IA_NA_EXTEND
uint32_t calculateDdnsTtl(uint32_t lease_lft)
Calculates TTL for a DNS resource record based on lease life time.
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.
const isc::log::MessageID DHCP6_DDNS_CREATE_ADD_NAME_CHANGE_REQUEST
uint16_t server_port_
UDP port number on which server listens.
boost::shared_ptr< DUID > DuidPtr
const isc::log::MessageID DHCP6_DECLINE_PROCESS_IA
Pkt6Ptr processInfRequest(AllocEngine::ClientContext6 &ctx)
Processes incoming Information-request message.
const isc::log::MessageID DHCP6_HOOK_SUBNET6_SELECT_SKIP
static uint16_t client_port
std::string toText(const std::string &separator=", ") const
Returns all class names as text.
uint32_t getVendorId() const
Returns enterprise identifier.
int run()
Main server processing loop.
volatile bool shutdown_
Indicates if shutdown is in progress.
const isc::log::MessageID DHCP6_SUBNET_DYNAMICALLY_CHANGED
const isc::log::MessageID DHCP6_RAPID_COMMIT
const isc::log::MessageID DHCP6_RELEASE_PD_FAIL_WRONG_DUID
void classifyPacket(const Pkt6Ptr &pkt)
Assigns incoming packet to zero or more classes.
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.
const isc::log::MessageID DHCP6_SRV_CONSTRUCT_ERROR
const isc::log::MessageID DHCP6_CLASS_UNTESTABLE
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.
const isc::log::MessageID DHCP6_LEASE_ALLOC
const isc::log::MessageID DHCP6_CLASS_ASSIGNED
const isc::log::MessageID DHCP6_PD_LEASE_ADVERT
HintContainer hints_
Client's hints.
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
static std::string getVersion(bool extended)
returns Kea version on stdout and exit.
void shutdown() override
Instructs the server to shut down.
virtual void sendPacket(const Pkt6Ptr &pkt)
dummy wrapper around IfaceMgr::send()
const isc::log::MessageID DHCP6_SUBNET_SELECTED
const isc::log::MessageID DHCP6_OPEN_SOCKET
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
const isc::log::MessageID DHCP6_RELEASE_PD_FAIL_WRONG_IAID
boost::shared_ptr< Pool6 > Pool6Ptr
a pointer an IPv6 Pool
const isc::log::MessageID DHCP6_LEASE_ADVERT_FAIL
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.
void adjustDomainName(const T &fqdn, T &fqdn_resp, const DdnsParams &ddns_params)
Set server FQDN name based on configuration and a given FQDN.
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...
const isc::log::MessageID DHCP6_LEASE_RENEW
const isc::log::MessageID DHCP6_LEASE_DATA
static Dhcp6to4Ipc & instance()
Returns pointer to the sole instance of Dhcp6to4Ipc.
An abstract API for lease database.
const isc::log::MessageID DHCP6_RELEASE_NA_FAIL
static CfgMgr & instance()
returns a single instance of Configuration Manager
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 isc::log::MessageID DHCP6_DECLINE_FAIL_NO_LEASE
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.
const isc::log::MessageID DHCP6_RELEASE_NA_EXPIRED
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
the lease contains IPv6 prefix (for prefix delegation)
const isc::log::MessageID DHCP6_FLEX_ID
void appendRequestedOptions(const Pkt6Ptr &question, Pkt6Ptr &answer, const CfgOptionList &co_list)
Appends requested options to server's answer.
const isc::log::MessageID DHCP6_LEASE_PD_WITHOUT_DUID
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.
OptionPtr assignIA_NA(const isc::dhcp::Pkt6Ptr &query, AllocEngine::ClientContext6 &ctx, Option6IAPtr ia)
Processes IA_NA option (and assigns addresses if necessary).
const isc::log::MessageID DHCP6_DDNS_GENERATE_FQDN
OptionPtr extendIA_PD(const Pkt6Ptr &query, AllocEngine::ClientContext6 &ctx, Option6IAPtr ia)
Extends lifetime of the prefix.
const isc::log::MessageID DHCP6_PACKET_PROCESS_STD_EXCEPTION
OptionPtr extendIA_NA(const Pkt6Ptr &query, AllocEngine::ClientContext6 &ctx, Option6IAPtr ia)
Extends lifetime of the specific IA_NA option.
const isc::log::MessageID DHCP6_SUBNET_DATA
static SubnetSelector initSelector(const Pkt6Ptr &query)
Build selector from a client's message.
void evaluateClasses(const Pkt6Ptr &pkt, bool depend_on_known)
Evaluate classes.
const isc::log::MessageID DHCP6_HOOK_PACKET_SEND_DROP
static std::string duidToString(const OptionPtr &opt)
converts DUID to text Converts content of DUID option to a text representation, e.g.
boost::shared_ptr< Pool > PoolPtr
a pointer to either IPv4 or IPv6 Pool
const isc::log::MessageID DHCP6_ADD_GLOBAL_STATUS_CODE
boost::shared_ptr< NameChangeRequest > NameChangeRequestPtr
Defines a pointer to a NameChangeRequest.
const isc::log::MessageID DHCP6_DECLINE_FAIL_LEASE_WITHOUT_DUID
const isc::log::MessageID DHCP6_PACKET_RECEIVED
void processPacketBufferSend(hooks::CalloutHandlePtr &callout_handle, Pkt6Ptr &rsp)
Executes buffer6_send callout and sends the response.
int getExitValue()
Fetches the exit value.
DuidPtr get()
Returns current DUID.
const isc::log::MessageID DHCP6_HOOK_LEASE6_RELEASE_PD_SKIP
const isc::log::MessageID DHCP6_DDNS_GENERATED_FQDN_UPDATE_FAIL
const int DBGLVL_PKT_HANDLING
This debug level is reserved for logging the details of packet handling, such as dropping the packet ...
const_iterator cbegin() const
Iterators to the first element.
virtual std::string getLabel() const
Returns text representation of the primary packet identifiers.
const isc::log::MessageID DHCP6_PACKET_QUEUE_FULL
RAII object enabling copying options retrieved from the packet.
void sendRequest(dhcp_ddns::NameChangeRequestPtr &ncr)
Send the given NameChangeRequests to kea-dhcp-ddns.
const isc::log::MessageID DHCP6_LEASE_REUSE
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
const isc::log::MessageID DHCP6_PACKET_PROCESS_EXCEPTION
static StatsMgr & instance()
Statistics Manager accessor method.
std::vector< uint8_t > OptionBuffer
buffer types used in DHCP code.
Holds DUID (DHCPv6 Unique Identifier)
const char *const * dhcp6_config_report
const isc::log::MessageID DHCP6_PACKET_DROP_DHCP_DISABLED
Statistics Manager class.
The IOService class is a wrapper for the ASIO io_service class.
boost::shared_ptr< DdnsParams > DdnsParamsPtr
Defines a pointer for DdnsParams instances.
const isc::log::MessageID DHCP6_PACKET_OPTIONS_SKIPPED
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 isc::log::MessageID DHCP6_HOOK_LEASE6_RELEASE_NA_SKIP
const OptionCollection & getOptions() const
Returns all encapsulated options.
Subnet selector used to specify parameters used to select a subnet.
static std::string getDBVersion()
Class method to return extended version info This class method must be redeclared and redefined in de...
boost::shared_ptr< Option6IA > Option6IAPtr
A pointer to the Option6IA object.
This class represents Status Code option (13) from RFC 8415.
bool early_global_reservations_lookup_
Indicates if early global reservation is enabled.
const isc::log::MessageID DHCP6_RELEASE_PD
void conditionallySetReservedClientClasses(const Pkt6Ptr &pkt, const AllocEngine::ClientContext6 &ctx)
Assigns classes retrieved from host reservation database if they haven't been yet set...
void assignLeases(const Pkt6Ptr &question, Pkt6Ptr &answer, AllocEngine::ClientContext6 &ctx)
Assigns leases.
const isc::log::MessageID DHCP6_PD_LEASE_REUSE
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
const isc::log::MessageID DHCP6_PACKET_DROP_UNICAST
const isc::log::MessageID DHCP6_PROCESS_IA_NA_RELEASE
void queueNCR(const NameChangeType &chg_type, const Lease4Ptr &lease)
Creates name change request from the DHCPv4 lease.
const isc::log::MessageID DHCP6_SRV_UNLOAD_LIBRARIES_ERROR
boost::shared_ptr< Pkt6 > Pkt6Ptr
A pointer to Pkt6 packet.
ClientClassContainer::const_iterator const_iterator
Type of iterators.
const isc::log::MessageID DHCP6_NO_INTERFACES
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.
const isc::log::MessageID DHCP6_SHUTDOWN_REQUEST
const isc::log::MessageID DHCP6_PACKET_DROP_PARSE_FAIL
Pool information for IPv6 addresses and prefixes.
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.
const isc::log::MessageID DHCP6_RELEASE_NA
const isc::log::MessageID DHCP6_RELEASE_PD_FAIL
boost::shared_ptr< Option6IAPrefix > Option6IAPrefixPtr
Pointer to the Option6IAPrefix object.
const isc::log::MessageID DHCP6_CLASS_UNCONFIGURED
const isc::log::MessageID DHCP6_LEASE_NA_WITHOUT_DUID
Pkt6Ptr processSolicit(AllocEngine::ClientContext6 &ctx)
Processes incoming Solicit and returns response.
const char * DOCSIS3_CLASS_MODEM
DOCSIS3.0 compatible cable modem.
virtual std::string toText(int indent=0) const
Returns string representation of the option.
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.
const isc::log::MessageID DHCP6_RELEASE_PD_EXPIRED
const isc::log::MessageID DHCP6_CLASS_UNDEFINED
const isc::log::MessageID DHCP6_DDNS_RECEIVE_FQDN
std::map< SubnetID, ConstHostPtr > hosts_
Holds a map of hosts belonging to the client within different subnets.
const isc::log::MessageID DHCP6_HOOK_BUFFER_RCVD_DROP
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.
ConstHostPtr globalHost() const
Returns global host reservation if there is one.
void setStatusCode(boost::shared_ptr< Option6IA > &container, const OptionPtr &status)
A simple utility method that sets the status code.
void processPacketAndSendResponseNoThrow(Pkt6Ptr &query)
Process a single incoming DHCPv6 packet and sends the response.
const isc::log::MessageID DHCP6_PACKET_DROP_DROP_CLASS
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.
const isc::log::MessageID DHCP6_HOOK_DECLINE_SKIP
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).
const isc::log::MessageID DHCP6_HOOK_BUFFER_SEND_SKIP
void appendRequestedVendorOptions(const Pkt6Ptr &question, Pkt6Ptr &answer, AllocEngine::ClientContext6 &ctx, const CfgOptionList &co_list)
Appends requested vendor options to server's answer.
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.
const isc::log::MessageID DHCP6_QUERY_DATA
static int getHookIndexBuffer6Send()
Returns the index of the buffer6_send hook.
const isc::log::MessageID DHCP6_SUBNET_SELECTION_FAILED
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.
const isc::log::MessageID DHCP6_PACKET_DROP_SERVERID_MISMATCH
const isc::log::MessageID DHCP6_ADD_STATUS_CODE_FOR_IA
Flexible host identifier.
boost::shared_ptr< const Element > ConstElementPtr
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.
boost::shared_ptr< const Host > ConstHostPtr
Const pointer to the Host object.
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.
const isc::log::MessageID DHCP6_RELEASE_NA_FAIL_WRONG_IAID
Defines the Dhcp6to4Ipc class.
NetworkStatePtr network_state_
Holds information about disabled DHCP service and/or disabled subnet/network scopes.
const isc::log::MessageID DHCP6_HOOK_SUBNET6_SELECT_DROP
const isc::log::MessageID DHCP6_DECLINE_LEASE
std::vector< Resource > HintContainer
Container for client's hints.
const isc::log::MessageID DHCP6_BUFFER_RECEIVED
void addHint(const asiolink::IOAddress &prefix, const uint8_t prefix_len=128, const uint32_t preferred=0, const uint32_t valid=0)
Convenience method adding new hint.
const int DBG_DHCP6_DETAIL
Debug level used to trace detailed errors.
const isc::log::MessageID DHCP6_PACKET_RECEIVE_FAIL
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 addOption(OptionPtr opt)
Adds a sub-option.
void processClientFqdn(const Pkt6Ptr &question, const Pkt6Ptr &answer, AllocEngine::ClientContext6 &ctx)
Processes Client FQDN Option.
const isc::log::MessageID DHCP6_HOOK_DDNS_UPDATE
boost::shared_ptr< SharedNetwork6 > SharedNetwork6Ptr
Pointer to SharedNetwork6 object.
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 parked packets Clears the packet parking lots of all packets.
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.
const isc::log::MessageID DHCP6_PACKET_SEND_FAIL
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.
const isc::log::MessageID DHCP6_PROCESS_IA_PD_REQUEST
const isc::log::MessageID DHCP6_RELEASE_NA_DELETED
const isc::log::MessageID DHCP6_DDNS_FQDN_GENERATED
const isc::log::MessageID DHCP6_PACKET_SEND
void addValue(const std::string &name, const int64_t value)
Records incremental integer observation.
boost::shared_ptr< Option6PDExclude > Option6PDExcludePtr
Pointer to the Option6PDExclude object.
Client race avoidance RAII handler.
bool fake_allocation_
Indicates if this is a real or fake allocation.
uint16_t client_port_
UDP port number to which server sends all responses.
const isc::log::MessageID DHCP6_PROCESS_IA_PD_EXTEND
This is a base class for exceptions thrown from the DNS library module.
Defines the logger used by the top-level component of kea-lfc.
boost::shared_ptr< Option6StatusCode > Option6StatusCodePtr
Pointer to the isc::dhcp::Option6StatusCode.
const isc::log::MessageID DHCP6_RELEASE_NA_FAIL_WRONG_DUID
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.
const isc::log::MessageID DHCP6_RESPONSE_DATA
const isc::log::MessageID DHCP6_PACKET_DROP_DROP_CLASS2
const isc::log::MessageID DHCP6_HOOK_PACKET_RCVD_SKIP
const isc::log::MessageID DHCP6_HOOK_BUFFER_RCVD_SKIP
uint32_t iaid_
The IAID field from IA_NA or IA_PD that is being processed.
const char *const config_report[]
const isc::log::MessageID DHCP6_PACKET_PROCESS_FAIL
std::string toText() const
Convert the address to a string.
void checkDynamicSubnetChange(const Pkt6Ptr &question, Pkt6Ptr &answer, AllocEngine::ClientContext6 &ctx, const Subnet6Ptr orig_subnet)
Iterates over new leases, update stale DNS entries.
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)
const isc::log::MessageID DHCP6_DDNS_REMOVE_OLD_LEASE_FQDN
std::string getDomainName() const
Returns the domain-name in the text format.
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.
static const size_t MAX_DUID_LEN
maximum duid size As defined in RFC 8415, section 11.1
const std::vector< T > & getValues() const
Return collection of option values.
const isc::log::MessageID DHCP6_HOOK_LEASES6_COMMITTED_DROP
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.
boost::shared_ptr< ClientClassDefList > ClientClassDefListPtr
Defines a pointer to a ClientClassDefList.
const isc::log::MessageID DHCP6_PD_LEASE_RENEW
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.
OptionPtr assignIA_PD(const Pkt6Ptr &query, AllocEngine::ClientContext6 &ctx, boost::shared_ptr< Option6IA > ia)
Processes IA_PD option (and assigns prefixes if necessary).
isc::log::Logger hooks_logger("hooks")
Hooks Logger.
void processDhcp6QueryAndSendResponse(Pkt6Ptr &query, Pkt6Ptr &rsp)
Process a single incoming DHCPv6 query.
asiolink::IOServicePtr & getIOService()
Returns pointer to the IO service used by the server.
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.
static const uint32_t INFINITY_LFT
Infinity (means static, i.e. never expire)
Pkt6Ptr processRenew(AllocEngine::ClientContext6 &ctx)
Processes incoming Renew message.
const isc::log::MessageID DHCP6_PD_LEASE_ADVERT_FAIL
void stopD2()
Stops DHCP_DDNS client IO if DDNS updates are enabled.
#define DHCP6_OPTION_SPACE
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 ...
const isc::log::MessageID DHCP6_DECLINE_FAIL
std::list< std::list< std::string > > jsonPathsToRedact() const final override
Return a list of all paths that contain passwords or secrets for kea-dhcp6.
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
Iterators to the past the end element.
const isc::log::MessageID DHCP6_PROCESS_IA_NA_REQUEST
bool tryLock(Pkt4Ptr query, ContinuationPtr cont=ContinuationPtr())
Tries to acquires a client.
#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)
const isc::log::MessageID DHCP6_REQUIRED_OPTIONS_CHECK_FAIL
void processDhcp6Query(Pkt6Ptr &query, Pkt6Ptr &rsp)
Process a single incoming DHCPv6 query.
void createIAContext()
Creates new IA context.
void setPacketStatisticsDefaults()
This function sets statistics related to DHCPv6 packets processing to their initial values...
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.
const isc::log::MessageID DHCP6_DECLINE_FAIL_IAID_MISMATCH
const isc::log::MessageID DHCP6_DDNS_RESPONSE_FQDN_DATA
const isc::log::MessageID DHCP6_HOOK_LEASES6_COMMITTED_PARK
Pkt6Ptr processDecline(AllocEngine::ClientContext6 &ctx)
Process incoming Decline message.
void suspendUpdates()
Suspends sending requests.
const isc::log::MessageID DHCP6_LEASE_ADVERT
D2ClientMgr & getD2ClientMgr()
Fetches the DHCP-DDNS manager.
virtual bool deleteLease(const Lease4Ptr &lease)=0
Deletes an IPv4 lease.
void send(const Pkt6Ptr &pkt)
Send message over IPC.
const isc::log::MessageID DHCP6_BUFFER_WAIT_SIGNAL
void processDhcp4Query(const Pkt6Ptr &dhcp4_query)
Processes incoming DHCPv4-query message.
const isc::log::MessageID DHCP6_DECLINE_FAIL_DUID_MISMATCH
bool isClientClassBuiltIn(const ClientClass &client_class)
Check if a client class name is builtin.
const isc::log::MessageID DHCP6_HOOK_LEASES6_PARKING_LOT_FULL
Factory for generating DUIDs (DHCP Unique Identifiers).
void processPacketAndSendResponse(Pkt6Ptr &query)
Process a single incoming DHCPv6 packet and sends the response.
boost::shared_ptr< Subnet6 > Subnet6Ptr
A pointer to a Subnet6 object.
void insert(const ClientClass &class_name)
Insert an element.
void setTeeTimes(uint32_t preferred_lft, const Subnet6Ptr &subnet, Option6IAPtr &resp)
Sets the T1 and T2 timers in the outbound IA.
void sendResponseNoThrow(hooks::CalloutHandlePtr &callout_handle, Pkt6Ptr &query, Pkt6Ptr &rsp)
Process an unparked DHCPv6 packet and sends the response.
uint32_t getVendorId() const
Returns enterprise id.
IdentifierType
Type of the host identifier.
const isc::log::MessageID DHCP6_LEASE_ALLOC_FAIL
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.
const isc::log::MessageID DHCP6_PACKET_DROP_DROP_CLASS_EARLY
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.
Class that represents IAPREFIX option in DHCPv6.
isc::hooks::CalloutHandlePtr getCalloutHandle(const T &pktptr)
CalloutHandle Store.
const isc::log::MessageID EVAL_RESULT