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>
91namespace ph = std::placeholders;
97 int hook_index_buffer6_receive_;
98 int hook_index_pkt6_receive_;
99 int hook_index_subnet6_select_;
100 int hook_index_leases6_committed_;
101 int hook_index_lease6_release_;
102 int hook_index_pkt6_send_;
103 int hook_index_buffer6_send_;
104 int hook_index_lease6_decline_;
105 int hook_index_host6_identifier_;
106 int hook_index_ddns6_update_;
110 hook_index_buffer6_receive_ = HooksManager::registerHook(
"buffer6_receive");
111 hook_index_pkt6_receive_ = HooksManager::registerHook(
"pkt6_receive");
112 hook_index_subnet6_select_ = HooksManager::registerHook(
"subnet6_select");
113 hook_index_leases6_committed_ = HooksManager::registerHook(
"leases6_committed");
114 hook_index_lease6_release_ = HooksManager::registerHook(
"lease6_release");
115 hook_index_pkt6_send_ = HooksManager::registerHook(
"pkt6_send");
116 hook_index_buffer6_send_ = HooksManager::registerHook(
"buffer6_send");
117 hook_index_lease6_decline_ = HooksManager::registerHook(
"lease6_decline");
118 hook_index_host6_identifier_ = HooksManager::registerHook(
"host6_identifier");
119 hook_index_ddns6_update_ = HooksManager::registerHook(
"ddns6_update");
141createStatusCode(
const Pkt6& pkt,
const uint16_t status_code,
142 const std::string& status_message) {
147 .arg(option_status->dataToText());
148 return (option_status);
166createStatusCode(
const Pkt6& pkt,
const Option6IA& ia,
const uint16_t status_code,
167 const std::string& status_message) {
173 .arg(option_status->dataToText());
174 return (option_status);
179std::set<std::string> dhcp6_statistics = {
181 "pkt6-solicit-received",
182 "pkt6-advertise-received",
183 "pkt6-request-received",
184 "pkt6-reply-received",
185 "pkt6-renew-received",
186 "pkt6-rebind-received",
187 "pkt6-decline-received",
188 "pkt6-release-received",
189 "pkt6-infrequest-received",
190 "pkt6-dhcpv4-query-received",
191 "pkt6-dhcpv4-response-received",
192 "pkt6-unknown-received",
194 "pkt6-advertise-sent",
196 "pkt6-dhcpv4-response-sent",
199 "v6-allocation-fail",
200 "v6-allocation-fail-shared-network",
201 "v6-allocation-fail-subnet",
202 "v6-allocation-fail-no-pools",
203 "v6-allocation-fail-classes"
214 : io_service_(new
IOService()), server_port_(server_port),
215 client_port_(client_port), serverid_(), shutdown_(true),
216 alloc_engine_(), name_change_reqs_(),
246 }
catch (
const std::exception &e) {
261 for (
auto it = dhcp6_statistics.begin(); it != dhcp6_statistics.end(); ++it) {
263 stats_mgr.
setValue((*it),
static_cast<int64_t
>(0));
273 }
catch (
const std::exception& ex) {
280 }
catch (
const std::exception& ex) {
290 HooksManager::prepareUnloadLibraries();
291 if (!HooksManager::unloadLibraries()) {
292 auto names = HooksManager::getLibraryNames();
294 if (!names.empty()) {
296 for (
size_t i = 1; i < names.size(); ++i) {
297 msg += std::string(
", ") + names[i];
327 if (
getServerID()->getData() != server_id->getData()){
329 .arg(pkt->getLabel())
341 switch (pkt->getType()) {
346 if (pkt->relay_info_.empty() && !pkt->getLocalAddr().isV6Multicast()) {
348 .arg(pkt->getLabel())
349 .arg(pkt->getName());
365 cfg->getIdentifierTypes()) {
382 if (HooksManager::calloutsPresent(
Hooks.hook_index_host6_identifier_)) {
386 std::vector<uint8_t> id;
395 callout_handle->setArgument(
"query6", ctx.
query_);
396 callout_handle->setArgument(
"id_type", type);
397 callout_handle->setArgument(
"id_value",
id);
400 HooksManager::callCallouts(
Hooks.hook_index_host6_identifier_,
403 callout_handle->getArgument(
"id_type", type);
404 callout_handle->getArgument(
"id_value",
id);
406 if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_CONTINUE) &&
429 ctx.
duid_ = query->getClientId();
449 if (global_host && !global_host->getClientClasses6().empty()) {
454 const ClientClasses& classes = global_host->getClientClasses6();
456 cclass != classes.
cend(); ++cclass) {
457 query->addClass(*cclass);
466 query->addClass(
"KNOWN");
468 .arg(query->getLabel())
475 if (query->inClass(
"DROP")) {
478 .arg(query->toText());
479 StatsMgr::instance().addValue(
"pkt6-receive-drop",
480 static_cast<int64_t
>(1));
485 ctx.
hosts_[SUBNET_ID_GLOBAL] = global_host;
522 ctx.
subnet_->getSharedNetwork(sn);
534 global_host && !global_host->getClientClasses6().empty()) ||
535 (!sn && current_host && !current_host->getClientClasses6().empty())) {
556 if (!ctx.
hosts_.empty()) {
557 pkt->addClass(
"KNOWN");
559 .arg(pkt->getLabel())
562 pkt->addClass(
"UNKNOWN");
564 .arg(pkt->getLabel())
572 if (pkt->inClass(
"DROP")) {
575 StatsMgr::instance().addValue(
"pkt6-receive-drop",
576 static_cast<int64_t
>(1));
588 while (__AFL_LOOP(fuzzer.maxLoopCount())) {
598 }
catch (
const std::exception& e) {
615 MultiThreadingMgr::instance().apply(
false, 0, 0);
628 uint32_t timeout = 1;
639 .arg(query->getRemoteAddr().toText())
640 .arg(query->getRemotePort())
641 .arg(query->getLocalAddr().toText())
642 .arg(query->getLocalPort())
643 .arg(query->getIface());
649 StatsMgr::instance().addValue(
"pkt6-received",
static_cast<int64_t
>(1));
665 }
catch (
const std::exception& e) {
678 .arg(query->getLabel());
681 if (MultiThreadingMgr::instance().getMode()) {
682 typedef function<void()> CallBack;
683 boost::shared_ptr<CallBack> call_back =
686 if (!MultiThreadingMgr::instance().getThreadPool().add(call_back)) {
699 }
catch (
const std::exception& e) {
721 bool skip_unpack =
false;
725 if (HooksManager::calloutsPresent(
Hooks.hook_index_buffer6_receive_)) {
738 callout_handle->setArgument(
"query6", query);
741 HooksManager::callCallouts(
Hooks.hook_index_buffer6_receive_, *callout_handle);
747 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
749 .arg(query->getRemoteAddr().toText())
750 .arg(query->getLocalAddr().toText())
751 .arg(query->getIface());
758 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
760 .arg(query->getRemoteAddr().toText())
761 .arg(query->getLocalAddr().toText())
762 .arg(query->getIface());
765 StatsMgr::instance().addValue(
"pkt6-receive-drop",
766 static_cast<int64_t
>(1));
770 callout_handle->getArgument(
"query6", query);
778 .arg(query->getRemoteAddr().toText())
779 .arg(query->getLocalAddr().toText())
780 .arg(query->getIface());
788 }
catch (
const std::exception &e) {
791 .arg(query->getRemoteAddr().toText())
792 .arg(query->getLocalAddr().toText())
793 .arg(query->getIface())
797 StatsMgr::instance().addValue(
"pkt6-parse-failed",
798 static_cast<int64_t
>(1));
799 StatsMgr::instance().addValue(
"pkt6-receive-drop",
800 static_cast<int64_t
>(1));
806 processStatsReceived(query);
813 StatsMgr::instance().addValue(
"pkt6-receive-drop",
static_cast<int64_t
>(1));
823 StatsMgr::instance().addValue(
"pkt6-receive-drop",
static_cast<int64_t
>(1));
831 .arg(query->getLabel())
832 .arg(query->getName())
833 .arg(
static_cast<int>(query->getType()))
834 .arg(query->getRemoteAddr())
835 .arg(query->getLocalAddr())
836 .arg(query->getIface());
838 .arg(query->getLabel())
839 .arg(query->toText());
844 if (HooksManager::calloutsPresent(
Hooks.hook_index_pkt6_receive_)) {
857 callout_handle->setArgument(
"query6", query);
860 HooksManager::callCallouts(
Hooks.hook_index_pkt6_receive_, *callout_handle);
865 if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) ||
866 (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP)) {
868 .arg(query->getLabel());
870 StatsMgr::instance().addValue(
"pkt6-receive-drop",
871 static_cast<int64_t
>(1));
875 callout_handle->getArgument(
"query6", query);
884 if (query->inClass(
"DROP")) {
886 .arg(query->toText());
887 StatsMgr::instance().addValue(
"pkt6-receive-drop",
888 static_cast<int64_t
>(1));
905 }
catch (
const std::exception& e) {
919 if (MultiThreadingMgr::instance().getMode() &&
929 if (!client_handler.
tryLock(query, cont)) {
959 switch (query->getType()) {
996 }
catch (
const std::exception& e) {
1006 .arg(query->getName())
1007 .arg(query->getRemoteAddr().toText())
1011 StatsMgr::instance().addValue(
"pkt6-receive-drop",
static_cast<int64_t
>(1));
1030 rsp->setRemoteAddr(query->getRemoteAddr());
1031 rsp->setLocalAddr(query->getLocalAddr());
1036 }
else if (rsp->relay_info_.empty()) {
1038 rsp->setRemotePort(DHCP6_CLIENT_PORT);
1042 rsp->setRemotePort(relay_port ? relay_port : DHCP6_SERVER_PORT);
1048 rsp->setLocalPort(DHCP6_SERVER_PORT);
1050 rsp->setIndex(query->getIndex());
1051 rsp->setIface(query->getIface());
1056 HooksManager::calloutsPresent(
Hooks.hook_index_leases6_committed_)) {
1080 std::shared_ptr<ScopedCalloutHandleState> callout_handle_state =
1081 std::make_shared<ScopedCalloutHandleState>(callout_handle);
1086 callout_handle->setArgument(
"query6", query);
1092 if (new_lease->reuseable_valid_lft_ == 0) {
1093 new_leases->push_back(new_lease);
1097 callout_handle->setArgument(
"leases6", new_leases);
1102 for (
auto const& iac : ctx.
ias_) {
1103 if (!iac.old_leases_.empty()) {
1104 for (
auto old_lease : iac.old_leases_) {
1106 deleted_leases->push_back(old_lease);
1109 bool in_new =
false;
1111 if ((new_lease->addr_ == old_lease->addr_) &&
1112 (new_lease->prefixlen_ == old_lease->prefixlen_)) {
1118 deleted_leases->push_back(old_lease);
1123 callout_handle->setArgument(
"deleted_leases6", deleted_leases);
1126 uint32_t parked_packet_limit = 0;
1130 parked_packet_limit = ppl->intValue();
1133 if (parked_packet_limit) {
1134 const auto& parking_lot = ServerHooks::getServerHooks().
1135 getParkingLotPtr(
"leases6_committed");
1136 if (parking_lot && (parking_lot->size() >= parked_packet_limit)) {
1140 .arg(parked_packet_limit)
1141 .arg(query->getLabel());
1143 static_cast<int64_t
>(1));
1153 HooksManager::park(
"leases6_committed", query,
1154 [
this, callout_handle, query, rsp, callout_handle_state]()
mutable {
1155 if (MultiThreadingMgr::instance().getMode()) {
1156 typedef function<void()> CallBack;
1157 boost::shared_ptr<CallBack> call_back =
1159 this, callout_handle, query, rsp));
1160 callout_handle_state->on_completion_ = [call_back]() {
1161 MultiThreadingMgr::instance().getThreadPool().add(call_back);
1171 HooksManager::callCallouts(
Hooks.hook_index_leases6_committed_,
1175 HooksManager::drop(
"leases6_committed", query);
1179 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_PARK) {
1181 .arg(query->getLabel());
1189 HooksManager::drop(
"leases6_committed", query);
1190 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
1192 .arg(query->getLabel());
1210 }
catch (
const std::exception& e) {
1226 bool skip_pack =
false;
1232 if (HooksManager::calloutsPresent(
Hooks.hook_index_pkt6_send_)) {
1244 callout_handle->setArgument(
"query6", query);
1247 callout_handle->setArgument(
"response6", rsp);
1250 HooksManager::callCallouts(
Hooks.hook_index_pkt6_send_, *callout_handle);
1257 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
1259 .arg(rsp->getLabel());
1264 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
1266 .arg(rsp->getLabel());
1275 }
catch (
const std::exception& e) {
1295 if (HooksManager::calloutsPresent(
Hooks.hook_index_buffer6_send_)) {
1307 callout_handle->setArgument(
"response6", rsp);
1310 HooksManager::callCallouts(
Hooks.hook_index_buffer6_send_,
1316 if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) ||
1317 (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP)) {
1320 .arg(rsp->getLabel());
1324 callout_handle->getArgument(
"response6", rsp);
1328 .arg(rsp->getLabel())
1329 .arg(rsp->getName())
1330 .arg(
static_cast<int>(rsp->getType()))
1331 .arg(rsp->getLocalAddr().isV6Zero() ?
"*" : rsp->getLocalAddr().toText())
1332 .arg(rsp->getLocalPort())
1333 .arg(rsp->getRemoteAddr())
1334 .arg(rsp->getRemotePort())
1335 .arg(rsp->getIface());
1338 .arg(
static_cast<int>(rsp->getType())).arg(rsp->toText());
1345 }
catch (
const std::exception& e) {
1361 tmp << hex << setw(2) << setfill('0') << static_cast<uint16_t>(*it);
1375 answer->addOption(clientid);
1380 if (!question->relay_info_.empty()) {
1381 answer->copyRelayInfo(question);
1399 co_list.push_back(ctx.
currentHost()->getCfgOption6());
1407 ctx.
subnet_->getPool(resource.getPrefixLength() == 128 ?
1409 resource.getAddress(),
1411 if (pool && !pool->getCfgOption()->empty()) {
1412 co_list.push_back(pool->getCfgOption());
1419 if (!ctx.
subnet_->getCfgOption()->empty()) {
1420 co_list.push_back(ctx.
subnet_->getCfgOption());
1425 ctx.
subnet_->getSharedNetwork(network);
1426 if (network && !network->getCfgOption()->empty()) {
1427 co_list.push_back(network->getCfgOption());
1434 cclass != classes.
cend(); ++cclass) {
1437 getClientClassDictionary()->findClass(*cclass);
1442 .arg(question->getLabel())
1449 if (ccdef->getCfgOption()->empty()) {
1454 co_list.push_back(ccdef->getCfgOption());
1468 if (co_list.empty()) {
1472 std::vector<uint16_t> requested_opts;
1476 boost::shared_ptr<OptionIntArray<uint16_t> > option_oro =
1477 boost::dynamic_pointer_cast<OptionIntArray<uint16_t> >
1478 (question->getOption(
D6O_ORO));
1482 requested_opts = option_oro->getValues();
1485 for (CfgOptionList::const_iterator copts = co_list.begin();
1486 copts != co_list.end(); ++copts) {
1494 for (OptionContainerPersistIndex::const_iterator desc = range.first;
1495 desc != range.second; ++desc) {
1497 if (desc->option_) {
1498 requested_opts.push_back(desc->option_->getType());
1503 for (uint16_t opt : requested_opts) {
1505 if (!answer->getOption(opt)) {
1507 for (CfgOptionList::const_iterator copts = co_list.begin();
1508 copts != co_list.end(); ++copts) {
1512 answer->addOption(desc.
option_);
1533 if (!ctx.
subnet_ || co_list.empty()) {
1537 uint32_t vendor_id = 0;
1544 vendor_id = vendor_rsp->getVendorId();
1550 if (vendor_id == 0) {
1551 vendor_req = boost::dynamic_pointer_cast<OptionVendor>(
1554 vendor_id = vendor_req->getVendorId();
1560 if (vendor_id == 0) {
1562 boost::dynamic_pointer_cast<OptionVendorClass>(
1565 vendor_id = vendor_class->getVendorId();
1571 if (vendor_id == 0) {
1575 std::vector<uint16_t> requested_opts;
1588 oro = boost::dynamic_pointer_cast<OptionUint16Array>(oro_generic);
1590 requested_opts = oro->getValues();
1596 for (CfgOptionList::const_iterator copts = co_list.begin();
1597 copts != co_list.end(); ++copts) {
1605 for (OptionContainerPersistIndex::const_iterator desc = range.first;
1606 desc != range.second; ++desc) {
1608 if (desc->option_) {
1609 requested_opts.push_back(desc->option_->getType());
1615 if (requested_opts.empty()) {
1628 for (uint16_t opt : requested_opts) {
1629 if (!vendor_rsp->getOption(opt)) {
1630 for (CfgOptionList::const_iterator copts = co_list.begin();
1631 copts != co_list.end(); ++copts) {
1634 vendor_rsp->addOption(desc.
option_);
1645 answer->addOption(vendor_rsp);
1652 switch (pkt->getType()) {
1674 .arg(
static_cast<int>(pkt->getType()))
1675 .arg(pkt->getIface());
1680 .arg(pkt->getName())
1681 .arg(pkt->getRemoteAddr().toText())
1687 StatsMgr::instance().addValue(
"pkt6-receive-drop",
static_cast<int64_t
>(1));
1697 if (client_ids.size() != 1) {
1699 << pkt->getName() <<
", but " << client_ids.size()
1706 if (client_ids.size() > 1) {
1708 <<
") client-id options received in " << pkt->getName());
1710 if (!client_ids.empty()) {
1723 if (!server_ids.empty()) {
1725 << server_ids.size() <<
" received in " << pkt->getName());
1730 if (server_ids.size() != 1) {
1732 << server_ids.size() <<
"), exactly 1 expected in message "
1739 if (server_ids.size() > 1) {
1741 <<
") server-id options received in " << pkt->getName());
1743 if (!server_ids.empty()) {
1756 uint16_t len = opt->len() - opt->getHeaderLen();
1759 << len <<
" byte(s). It must be at least 3 and no more than "
1769 getCfgSubnets6()->selectSubnet(selector);
1772 if (HooksManager::calloutsPresent(
Hooks.hook_index_subnet6_select_)) {
1785 callout_handle->setArgument(
"query6", question);
1786 callout_handle->setArgument(
"subnet6", subnet);
1791 callout_handle->setArgument(
"subnet6collection",
1793 getCfgSubnets6()->getAll());
1796 HooksManager::callCallouts(
Hooks.hook_index_subnet6_select_, *callout_handle);
1802 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
1804 .arg(question->getLabel());
1810 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
1812 .arg(question->getLabel());
1818 callout_handle->getArgument(
"subnet6", subnet);
1824 .arg(question->getLabel())
1825 .arg(subnet->getID());
1829 .arg(question->getLabel())
1830 .arg(subnet->toText());
1834 .arg(question->getLabel());
1859 for (
const auto& opt : question->options_) {
1860 switch (opt.second->getType()) {
1863 boost::dynamic_pointer_cast<
1866 answer->addOption(answer_opt);
1872 boost::dynamic_pointer_cast<
1875 answer->addOption(answer_opt);
1900 if (ddns_params->getEnableUpdates() &&
1910 .arg(question->getLabel());
1923 .arg(question->getLabel())
1924 .arg(fqdn->toText());
1943 *ddns_params,
true),
1953 ctx.
hostname_ = fqdn_resp->getDomainName();
1960 .arg(question->getLabel())
1961 .arg(fqdn_resp->toText());
1962 answer->addOption(fqdn_resp);
1966 if (HooksManager::calloutsPresent(
Hooks.hook_index_ddns6_update_)) {
1977 callout_handle->setArgument(
"query6", question);
1978 callout_handle->setArgument(
"response6", answer);
1979 callout_handle->setArgument(
"subnet6", subnet);
1980 callout_handle->setArgument(
"hostname", ctx.
hostname_);
1983 callout_handle->setArgument(
"ddns-params", ddns_params);
1986 HooksManager::callCallouts(
Hooks.hook_index_ddns6_update_, *callout_handle);
1989 string hook_hostname;
1990 bool hook_fwd_dns_update;
1991 bool hook_rev_dns_update;
1992 callout_handle->getArgument(
"hostname", hook_hostname);
1993 callout_handle->getArgument(
"fwd-update", hook_fwd_dns_update);
1994 callout_handle->getArgument(
"rev-update", hook_rev_dns_update);
2005 fqdn_resp = boost::dynamic_pointer_cast<Option6ClientFqdn>(answer->getOption(
D6O_CLIENT_FQDN));
2008 if (!(hook_fwd_dns_update || hook_rev_dns_update)) {
2035 <<
" encapsulating server's message must not be"
2036 <<
" NULL when creating DNS NameChangeRequest");
2049 bool do_fwd =
false;
2050 bool do_rev =
false;
2060 "client identifier is required when creating a new"
2061 " DNS NameChangeRequest");
2068 opt_fqdn->packDomainName(name_buf);
2069 const uint8_t* name_data =
static_cast<const uint8_t*
>(name_buf.
getData());
2072 std::vector<uint8_t> buf_vec(name_data, name_data + name_buf.
getLength());
2078 for (
auto answer_ia : answer->getOptions(
D6O_IA_NA)) {
2093 bool extended_only =
false;
2097 if ((*l)->addr_ == iaaddr->getAddress()) {
2102 ((*l)->hostname_ == opt_fqdn->getDomainName() &&
2103 (*l)->fqdn_fwd_ == do_fwd && (*l)->fqdn_rev_ == do_rev)) {
2104 extended_only =
true;
2116 if (!(do_fwd || do_rev) || (extended_only)) {
2131 opt_fqdn->getDomainName(),
2132 iaaddr->getAddress().toText(),
2152 getMACSources().get();
2154 for (CfgMACSources::const_iterator it = mac_sources.begin();
2155 it != mac_sources.end(); ++it) {
2156 hwaddr = pkt->getMAC(*it);
2167 boost::shared_ptr<Option6IA> ia) {
2173 boost::dynamic_pointer_cast<Option6IAAddr>(ia->getOption(
D6O_IAADDR));
2176 hint = hint_opt->getAddress();
2180 .arg(query->getLabel())
2182 .arg(hint_opt ? hint.
toText() :
"(no hint)");
2201 "Server could not select subnet for"
2224 if (!leases.empty()) {
2225 lease = *leases.begin();
2238 .arg(query->getLabel())
2239 .arg(lease->addr_.toText())
2240 .arg(ia->getIAID());
2241 }
else if (lease->reuseable_valid_lft_ == 0) {
2243 .arg(query->getLabel())
2244 .arg(lease->addr_.toText())
2248 lease->valid_lft_ = lease->reuseable_valid_lft_;
2249 lease->preferred_lft_ = lease->reuseable_preferred_lft_;
2251 .arg(query->getLabel())
2252 .arg(lease->addr_.toText())
2257 .arg(query->getLabel())
2259 .arg(lease->toText());
2262 setTeeTimes(lease->preferred_lft_, subnet, ia_rsp);
2265 lease->preferred_lft_,
2266 lease->valid_lft_));
2267 ia_rsp->addOption(addr);
2280 .arg(query->getLabel())
2281 .arg(ia->getIAID());
2283 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
2285 "Sorry, no address could be"
2294 boost::shared_ptr<Option6IA> ia) {
2301 boost::dynamic_pointer_cast<Option6IAPrefix>(ia->getOption(
D6O_IAPREFIX));
2304 hint = hint_opt->getAddress();
2308 .arg(query->getLabel())
2310 .arg(hint_opt ? hint.
toText() :
"(no hint)");
2327 "Sorry, no subnet available."));
2347 if (!leases.empty()) {
2351 uint32_t min_preferred_lft = (*leases.begin())->preferred_lft_;
2353 const bool pd_exclude_requested = requestedInORO(query,
D6O_PD_EXCLUDE);
2354 for (Lease6Collection::iterator l = leases.begin();
2355 l != leases.end(); ++l) {
2361 .arg(query->getLabel())
2362 .arg((*l)->addr_.toText())
2363 .arg(
static_cast<int>((*l)->prefixlen_))
2364 .arg(ia->getIAID());
2365 }
else if ((*l)->reuseable_valid_lft_ == 0) {
2367 .arg(query->getLabel())
2368 .arg((*l)->addr_.toText())
2369 .arg(
static_cast<int>((*l)->prefixlen_))
2373 (*l)->valid_lft_ = (*l)->reuseable_valid_lft_;
2374 (*l)->preferred_lft_ = (*l)->reuseable_preferred_lft_;
2376 .arg(query->getLabel())
2377 .arg((*l)->addr_.toText())
2378 .arg(
static_cast<int>((*l)->prefixlen_))
2384 if (((*l)->preferred_lft_ > 0) && (min_preferred_lft > (*l)->preferred_lft_)) {
2385 min_preferred_lft = (*l)->preferred_lft_;
2388 boost::shared_ptr<Option6IAPrefix>
2390 (*l)->prefixlen_, (*l)->preferred_lft_,
2392 ia_rsp->addOption(addr);
2394 if (pd_exclude_requested) {
2397 Pool6Ptr pool = boost::dynamic_pointer_cast<
2401 if (pd_exclude_option) {
2402 addr->addOption(pd_exclude_option);
2422 .arg(query->getLabel())
2423 .arg(ia->getIAID());
2425 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
2427 "Sorry, no prefixes could"
2436 boost::shared_ptr<Option6IA> ia) {
2439 .arg(query->getLabel())
2440 .arg(ia->getIAID());
2459 "Sorry, no known leases for this duid/iaid."));
2471 for (OptionCollection::const_iterator it = addrs.begin();
2472 it != addrs.end(); ++it) {
2476 Option6IAAddrPtr iaaddr = boost::dynamic_pointer_cast<Option6IAAddr>(it->second);
2503 uint32_t min_preferred_lft = std::numeric_limits<uint32_t>::max();
2506 for (Lease6Collection::iterator l = leases.begin(); l != leases.end(); ++l) {
2507 if ((*l)->reuseable_valid_lft_ == 0) {
2509 .arg(query->getLabel())
2510 .arg((*l)->addr_.toText())
2511 .arg(ia->getIAID());
2513 (*l)->valid_lft_ = (*l)->reuseable_valid_lft_;
2514 (*l)->preferred_lft_ = (*l)->reuseable_preferred_lft_;
2516 .arg(query->getLabel())
2517 .arg((*l)->addr_.toText())
2523 (*l)->addr_, (*l)->preferred_lft_, (*l)->valid_lft_));
2524 ia_rsp->addOption(iaaddr);
2527 if (((*l)->preferred_lft_ > 0) && (min_preferred_lft > (*l)->preferred_lft_)) {
2528 min_preferred_lft = (*l)->preferred_lft_;
2533 hints.erase(std::remove(hints.begin(), hints.end(), hint_type),
2544 if (
equalValues(query->getClientId(), (*l)->duid_)) {
2546 (*l)->addr_, 0, 0));
2547 ia_rsp->addOption(iaaddr);
2552 hints.erase(std::remove(hints.begin(), hints.end(), hint_type), hints.end());
2560 .arg(query->getLabel())
2561 .arg((*l)->toText())
2572 for (AllocEngine::HintContainer::const_iterator hint = hints.begin();
2573 hint != hints.end(); ++hint) {
2575 hint->getAddress(), 0, 0));
2576 ia_rsp->addOption(iaaddr);
2579 if (!leases.empty()) {
2585 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
2587 "Sorry, no addresses could be"
2588 " assigned at this time."));
2597 boost::shared_ptr<Option6IA> ia) {
2600 .arg(query->getLabel())
2601 .arg(ia->getIAID());
2618 "Sorry, no known PD leases"
2619 " for this duid/iaid."));
2639 " client sending Rebind to extend lifetime of the"
2640 " prefix (DUID=" << duid->toText() <<
", IAID="
2641 << ia->getIAID() <<
")");
2653 for (OptionCollection::const_iterator it = addrs.begin();
2654 it != addrs.end(); ++it) {
2688 const bool pd_exclude_requested = requestedInORO(query,
D6O_PD_EXCLUDE);
2692 uint32_t min_preferred_lft = std::numeric_limits<uint32_t>::max();
2694 for (Lease6Collection::iterator l = leases.begin(); l != leases.end(); ++l) {
2695 if ((*l)->reuseable_valid_lft_ == 0) {
2697 .arg(query->getLabel())
2698 .arg((*l)->addr_.toText())
2699 .arg(
static_cast<int>((*l)->prefixlen_))
2700 .arg(ia->getIAID());
2702 (*l)->valid_lft_ = (*l)->reuseable_valid_lft_;
2703 (*l)->preferred_lft_ = (*l)->reuseable_preferred_lft_;
2705 .arg(query->getLabel())
2706 .arg((*l)->addr_.toText())
2707 .arg(
static_cast<int>((*l)->prefixlen_))
2713 (*l)->addr_, (*l)->prefixlen_,
2714 (*l)->preferred_lft_, (*l)->valid_lft_));
2715 ia_rsp->addOption(prf);
2717 if (pd_exclude_requested) {
2720 Pool6Ptr pool = boost::dynamic_pointer_cast<
2725 if (pd_exclude_option) {
2726 prf->addOption(pd_exclude_option);
2732 if (((*l)->preferred_lft_ > 0) && ((*l)->preferred_lft_ < min_preferred_lft)) {
2733 min_preferred_lft = (*l)->preferred_lft_;
2738 hints.erase(std::remove(hints.begin(), hints.end(), hint_type),
2749 if (
equalValues(query->getClientId(), (*l)->duid_)) {
2751 (*l)->prefixlen_, 0, 0));
2752 ia_rsp->addOption(prefix);
2757 hints.erase(std::remove(hints.begin(), hints.end(), hint_type), hints.end());
2762 for (AllocEngine::HintContainer::const_iterator prefix = hints.begin();
2763 prefix != hints.end(); ++prefix) {
2768 if (!prefix->getAddress().isV6Zero()) {
2770 prefix->getAddress(),
2771 prefix->getPrefixLength(),
2773 ia_rsp->addOption(prefix_opt);
2777 if (!leases.empty()) {
2784 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
2786 "Sorry, no prefixes could be"
2787 " assigned at this time."));
2808 for (
const auto& opt : query->options_) {
2809 switch (opt.second->getType()) {
2812 boost::dynamic_pointer_cast<
2815 reply->addOption(answer_opt);
2822 boost::dynamic_pointer_cast<
2825 reply->addOption(answer_opt);
2860 for (
const auto& opt : release->options_) {
2862 switch (opt.second->getType()) {
2865 boost::dynamic_pointer_cast<Option6IA>(opt.second),
2868 reply->addOption(answer_opt);
2874 boost::dynamic_pointer_cast<Option6IA>(opt.second),
2877 reply->addOption(answer_opt);
2894 reply->addOption(createStatusCode(*release, general_status,
2895 "Summary status for all processed IA_NAs"));
2900 int& general_status, boost::shared_ptr<Option6IA> ia,
2904 .arg(query->getLabel())
2905 .arg(ia->getIAID());
2921 if (!release_addr) {
2923 "You did not include an address in your RELEASE"));
2929 release_addr->getAddress());
2936 "Sorry, no known leases for this duid/iaid, can't release."));
2942 if (!lease->duid_) {
2948 .arg(query->getLabel())
2949 .arg(release_addr->getAddress().toText());
2953 "Database consistency check failed when trying to RELEASE"));
2957 if (*duid != *(lease->duid_)) {
2961 .arg(query->getLabel())
2962 .arg(release_addr->getAddress().toText())
2963 .arg(lease->duid_->toText());
2967 "This address does not belong to you, you can't release it"));
2971 if (ia->getIAID() != lease->iaid_) {
2974 .arg(query->getLabel())
2975 .arg(release_addr->getAddress().toText())
2977 .arg(ia->getIAID());
2979 "This is your address, but you used wrong IAID"));
2989 if (HooksManager::calloutsPresent(
Hooks.hook_index_lease6_release_)) {
3002 callout_handle->deleteAllArguments();
3005 callout_handle->setArgument(
"query6", query);
3008 callout_handle->setArgument(
"lease6", lease);
3011 HooksManager::callCallouts(
Hooks.hook_index_lease6_release_, *callout_handle);
3016 if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) ||
3017 (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP)) {
3020 .arg(query->getLabel());
3025 bool success =
false;
3036 "Server failed to release a lease"));
3039 .arg(query->getLabel())
3040 .arg(lease->addr_.toText())
3049 .arg(query->getLabel())
3050 .arg(lease->addr_.toText())
3053 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
STATUS_Success,
3054 "Lease released. Thank you, please come again."));
3057 StatsMgr::instance().addValue(
3058 StatsMgr::generateName(
"subnet", lease->subnet_id_,
"assigned-nas"),
3059 static_cast<int64_t
>(-1));
3072 int& general_status, boost::shared_ptr<Option6IA> ia,
3087 boost::shared_ptr<Option6IAPrefix> release_prefix =
3088 boost::dynamic_pointer_cast<Option6IAPrefix>(ia->getOption(
D6O_IAPREFIX));
3089 if (!release_prefix) {
3091 "You did not include a prefix in your RELEASE"));
3097 release_prefix->getAddress());
3104 "Sorry, no known leases for this duid/iaid, can't release."));
3110 if (!lease->duid_) {
3115 .arg(query->getLabel())
3116 .arg(release_prefix->getAddress().toText())
3117 .arg(
static_cast<int>(release_prefix->getLength()));
3121 "Database consistency check failed when trying to RELEASE"));
3125 if (*duid != *(lease->duid_)) {
3128 .arg(query->getLabel())
3129 .arg(release_prefix->getAddress().toText())
3130 .arg(
static_cast<int>(release_prefix->getLength()))
3131 .arg(lease->duid_->toText());
3135 "This address does not belong to you, you can't release it"));
3139 if (ia->getIAID() != lease->iaid_) {
3142 .arg(query->getLabel())
3143 .arg(release_prefix->getAddress().toText())
3144 .arg(
static_cast<int>(release_prefix->getLength()))
3146 .arg(ia->getIAID());
3148 "This is your address, but you used wrong IAID"));
3158 if (HooksManager::calloutsPresent(
Hooks.hook_index_lease6_release_)) {
3171 callout_handle->setArgument(
"query6", query);
3174 callout_handle->setArgument(
"lease6", lease);
3177 HooksManager::callCallouts(
Hooks.hook_index_lease6_release_, *callout_handle);
3179 skip = callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP;
3183 bool success =
false;
3192 .arg(query->getLabel());
3200 "Server failed to release a lease"));
3203 .arg(query->getLabel())
3204 .arg(lease->addr_.toText())
3205 .arg(
static_cast<int>(lease->prefixlen_))
3213 .arg(query->getLabel())
3214 .arg(lease->addr_.toText())
3215 .arg(
static_cast<int>(lease->prefixlen_))
3218 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
STATUS_Success,
3219 "Lease released. Thank you, please come again."));
3222 StatsMgr::instance().addValue(
3223 StatsMgr::generateName(
"subnet", lease->subnet_id_,
"assigned-pds"),
3224 static_cast<int64_t
>(-1));
3239 if (opt_rapid_commit) {
3242 .arg(solicit->getLabel());
3247 response->addOption(opt_rapid_commit);
3266 if (MultiThreadingMgr::instance().getMode()) {
3285 updateReservedFqdn(ctx, response);
3304 if (MultiThreadingMgr::instance().getMode()) {
3323 updateReservedFqdn(ctx, reply);
3324 generateFqdn(reply, ctx);
3338 if (MultiThreadingMgr::instance().getMode()) {
3357 updateReservedFqdn(ctx, reply);
3358 generateFqdn(reply, ctx);
3372 if (MultiThreadingMgr::instance().getMode()) {
3391 updateReservedFqdn(ctx, reply);
3392 generateFqdn(reply, ctx);
3424 bool verified =
false;
3433 for (OptionCollection::const_iterator ia = ias.begin();
3434 ia != ias.end(); ++ia) {
3436 for (OptionCollection::const_iterator opt = opts.begin();
3437 opt != opts.end(); ++opt) {
3449 if (subnet && !subnet->inRange(iaaddr->getAddress())) {
3450 std::ostringstream status_msg;
3451 status_msg <<
"Address " << iaaddr->
getAddress()
3452 <<
" is not on link.";
3453 reply->addOption(createStatusCode(*confirm,
3461 " to the Option6IAAddrPtr. This is programming"
3462 " error and should be reported");
3479 "All addresses are on-link"));
3482 "No subnet selected"));
3558 for (
const auto& opt : decline->options_) {
3559 switch (opt.second->getType()) {
3562 boost::dynamic_pointer_cast<Option6IA>(opt.second),
3567 reply->addOption(answer_opt);
3588 int& general_status, boost::shared_ptr<Option6IA> ia,
3592 .arg(decline->getLabel())
3593 .arg(ia->getIAID());
3608 int total_addrs = 0;
3609 for (OptionCollection::const_iterator opt = opts.begin(); opt != opts.end();
3619 if (!decline_addr) {
3626 decline_addr->getAddress());
3631 .arg(decline->getLabel()).arg(decline_addr->getAddress().toText());
3639 "Server does not know about such an address."));
3647 if (!lease->duid_) {
3653 .arg(decline->getLabel())
3654 .arg(decline_addr->getAddress().toText());
3657 "Database consistency check failed when attempting Decline."));
3663 if (*duid != *(lease->duid_)) {
3667 .arg(decline->getLabel())
3668 .arg(decline_addr->getAddress().toText())
3669 .arg(lease->duid_->toText());
3672 "This address does not belong to you, you can't decline it"));
3678 if (ia->getIAID() != lease->iaid_) {
3681 .arg(decline->getLabel())
3682 .arg(lease->addr_.toText())
3686 "This is your address, but you used wrong IAID"));
3698 new_leases.push_back(lease);
3702 if (total_addrs == 0) {
3704 "No addresses sent in IA_NA"));
3717 container->addOption(status);
3722 boost::shared_ptr<Option6IA> ia_rsp) {
3733 if (HooksManager::calloutsPresent(
Hooks.hook_index_lease6_decline_)) {
3746 callout_handle->setArgument(
"query6", decline);
3749 callout_handle->setArgument(
"lease6", lease);
3752 HooksManager::callCallouts(
Hooks.hook_index_lease6_decline_,
3758 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
3760 .arg(decline->getLabel())
3761 .arg(decline->getIface())
3762 .arg(lease->addr_.toText());
3768 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
3770 .arg(decline->getLabel())
3771 .arg(decline->getIface())
3772 .arg(lease->addr_.toText());
3777 Lease6Ptr old_values = boost::make_shared<Lease6>(*lease);
3791 .arg(decline->getLabel())
3792 .arg(lease->addr_.toText())
3803 StatsMgr::instance().addValue(
3804 StatsMgr::generateName(
"subnet", lease->subnet_id_,
"declined-addresses"),
3805 static_cast<int64_t
>(1));
3808 StatsMgr::instance().addValue(
"declined-addresses",
static_cast<int64_t
>(1));
3811 .arg(lease->addr_.toText()).arg(lease->valid_lft_);
3813 ia_rsp->addOption(createStatusCode(*decline, *ia_rsp,
STATUS_Success,
3814 "Lease declined. Hopefully the next one will be better."));
3877 if (!vclass || vclass->getTuplesNum() == 0) {
3897 pkt->addClass(
"ALL");
3898 string classes =
"ALL ";
3912 for (ClientClassDefList::const_iterator it = defs_ptr->cbegin();
3913 it != defs_ptr->cend(); ++it) {
3921 if ((*it)->getRequired()) {
3925 if ((*it)->getDependOnKnown() != depend_on_known) {
3934 .arg((*it)->getName())
3937 pkt->addClass((*it)->getName());
3940 .arg((*it)->getName())
3945 .arg((*it)->getName())
3949 .arg((*it)->getName())
3950 .arg(
"get exception?");
3960 for (
auto def : *defs_ptr) {
3964 if (def->getMatchExpr()) {
3965 pkt->classes_.erase(def->getName());
3976 cclass != classes.
cend(); ++cclass) {
3977 pkt->addClass(*cclass);
3982 if (!classes.
empty()) {
3984 .arg(pkt->getLabel())
3994 ctx.
subnet_->getSharedNetwork(shared_network);
3995 if (shared_network) {
3997 if (host && (host->getIPv6SubnetID() != SUBNET_ID_GLOBAL)) {
4013 subnet->getSharedNetwork(network);
4015 const ClientClasses& to_add = network->getRequiredClasses();
4017 cclass != to_add.
cend(); ++cclass) {
4025 cclass != to_add.
cend(); ++cclass) {
4032 ctx.
subnet_->getPool(resource.getPrefixLength() == 128 ?
4034 resource.getAddress(),
4039 cclass != to_add.
cend(); ++cclass) {
4053 cclass != classes.
cend(); ++cclass) {
4076 pkt->addClass(*cclass);
4089 .arg(
"get exception?");
4099 " a message must not be NULL when updating reserved FQDN");
4110 std::string name = fqdn->getDomainName();
4122 if (new_name != name) {
4127 answer->addOption(fqdn);
4133Dhcpv6Srv::generateFqdn(
const Pkt6Ptr& answer,
4137 " a message must not be NULL when generating FQDN");
4148 if (!fqdn || !fqdn->getDomainName().empty()) {
4166 std::string generated_name =
4170 .arg(answer->getLabel())
4171 .arg(generated_name);
4188 lease->hostname_ = generated_name;
4189 lease->reuseable_valid_lft_ = 0;
4194 " for address " << addr <<
", so as it is impossible"
4195 " to update FQDN data. This is a programmatic error"
4196 " as the given address is now being handed to the"
4204 answer->addOption(fqdn);
4208 .arg(answer->getLabel())
4222 this, ph::_1, ph::_2));
4240 arg(result).arg((ncr ? ncr->toText() :
" NULL "));
4252 std::stringstream tmp;
4256 tmp << endl << EXTENDED_VERSION << endl;
4257 tmp <<
"linked with:" << endl;
4258 tmp << Logger::getVersion() << endl;
4259 tmp << CryptoLink::getVersion() << endl;
4260 tmp <<
"database:" << endl;
4277 if (query->relay_info_.empty()) {
4288 for (
int i = query->relay_info_.size(); i > 0 ; --i) {
4290 if (rsoo_container) {
4295 for (OptionCollection::const_iterator opt = rsoo.begin();
4296 opt != rsoo.end(); ++opt) {
4300 if (cfg_rsoo->enabled(opt->second->getType()) &&
4301 !rsp->getOption(opt->second->getType())) {
4302 rsp->addOption(opt->second);
4311 if (query->relay_info_.empty()) {
4319 return (query->getRemotePort());
4325void Dhcpv6Srv::processStatsReceived(
const Pkt6Ptr& query) {
4329 string stat_name =
"pkt6-unknown-received";
4330 switch (query->getType()) {
4332 stat_name =
"pkt6-solicit-received";
4336 stat_name =
"pkt6-advertise-received";
4339 stat_name =
"pkt6-request-received";
4342 stat_name =
"pkt6-confirm-received";
4345 stat_name =
"pkt6-renew-received";
4348 stat_name =
"pkt6-rebind-received";
4352 stat_name =
"pkt6-reply-received";
4355 stat_name =
"pkt6-release-received";
4358 stat_name =
"pkt6-decline-received";
4361 stat_name =
"pkt6-reconfigure-received";
4364 stat_name =
"pkt6-infrequest-received";
4367 stat_name =
"pkt6-dhcpv4-query-received";
4371 stat_name =
"pkt6-dhcpv4-response-received";
4377 StatsMgr::instance().addValue(stat_name,
static_cast<int64_t
>(1));
4382 StatsMgr::instance().addValue(
"pkt6-sent",
static_cast<int64_t
>(1));
4386 switch (response->getType()) {
4388 stat_name =
"pkt6-advertise-sent";
4391 stat_name =
"pkt6-reply-sent";
4394 stat_name =
"pkt6-dhcpv4-response-sent";
4401 StatsMgr::instance().addValue(stat_name,
static_cast<int64_t
>(1));
4405 return (
Hooks.hook_index_buffer6_send_);
4409Dhcpv6Srv::requestedInORO(
const Pkt6Ptr& query,
const uint16_t code)
const {
4411 boost::dynamic_pointer_cast<OptionUint16Array>(query->getOption(
D6O_ORO));
4414 const std::vector<uint16_t>& codes = oro->getValues();
4415 return (std::find(codes.begin(), codes.end(), code) != codes.end());
4423 HooksManager::clearParkingLots();
4430 uint32_t t2_time = 0;
4433 if (!subnet->getT2().unspecified()) {
4434 t2_time = subnet->getT2();
4435 }
else if (subnet->getCalculateTeeTimes()) {
4437 t2_time =
static_cast<uint32_t
>(round(subnet->getT2Percent() * preferred_lft));
4441 resp->setT2(t2_time);
4444 uint32_t t1_time = 0;
4447 if (!subnet->getT1().unspecified()) {
4448 t1_time = subnet->getT1();
4449 }
else if (subnet->getCalculateTeeTimes()) {
4451 t1_time =
static_cast<uint32_t
>(round(subnet->getT1Percent() * preferred_lft));
4455 if (t1_time < t2_time) {
4456 resp->setT1(t1_time);
4468 if ((!ctx.
subnet_) || (!orig_subnet) || (orig_subnet->getID() == ctx.
subnet_->getID())) {
4476 orig_subnet->getSharedNetwork(network);
4478 .arg(question->getLabel())
4479 .arg(orig_subnet->toText())
4481 .arg(network ? network->getName() :
"<no network?>");
4487 std::string prev_hostname = ctx.
hostname_;
4504 for (Lease6Collection::const_iterator l = ctx.
new_leases_.begin();
4509 (*l)->reuseable_valid_lft_ = 0;
4516 static std::list<std::list<std::string>>
const list({
4517 {
"config-control",
"config-databases",
"[]"},
4518 {
"hooks-libraries",
"[]",
"parameters",
"*"},
4520 {
"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 const size_t MAX_DUID_LEN
maximum duid size As defined in RFC 8415, section 11.1
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)
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 classifyByVendor(const Pkt6Ptr &pkt, std::string &classes)
Assign class using vendor-class-identifier option.
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.
Dhcpv6Srv(uint16_t server_port=DHCP6_SERVER_PORT, uint16_t client_port=0)
Default constructor.
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.
asiolink::IOServicePtr & getIOService()
Returns pointer to the IO service used by the server.
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 void destroy()
Destroy lease manager.
static LeaseMgr & instance()
Return current 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.
This class encapsulates DHCPv6 Vendor Class and DHCPv4 V-I Vendor Class options.
This class represents vendor-specific information option.
const OptionCollection & getOptions() const
Returns all encapsulated options.
OptionPtr getOption(uint16_t type) const
Returns shared_ptr to suboption of specific type.
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.
size_t getLength() const
Return the length of data written in the buffer.
const void * getData() const
Return a pointer to the head of the data stored 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
const char *const config_report[]
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
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_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
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
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 char *const * dhcp6_config_report
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
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
uint32_t calculateDdnsTtl(uint32_t lease_lft)
Calculates TTL for a DNS resource record based on lease life time.
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
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
const isc::log::MessageID DHCP6_HOOK_BUFFER_RCVD_SKIP
const isc::log::MessageID DHCP6_DECLINE_FAIL
bool evaluateBool(const Expression &expr, Pkt &pkt)
Evaluate a RPN expression for a v4 or v6 packet and return a true or false decision.
const isc::log::MessageID DHCP6_QUERY_DATA
const int DBG_DHCP6_DETAIL_DATA
This level is used to log the contents of packets received and sent.
boost::shared_ptr< const Host > ConstHostPtr
Const pointer to the Host object.
const isc::log::MessageID DHCP6_PACKET_DROP_DROP_CLASS
boost::shared_ptr< Lease6Collection > Lease6CollectionPtr
A shared pointer to the collection of IPv6 leases.
const isc::log::MessageID DHCP6_DECLINE_PROCESS_IA
const isc::log::MessageID DHCP6_PROCESS_IA_NA_REQUEST
OptionContainer::nth_index< 2 >::type OptionContainerPersistIndex
Type of the index #2 - option persistency flag.
isc::log::Logger lease6_logger(DHCP6_LEASE_LOGGER_NAME)
Logger for lease allocation logic.
const isc::log::MessageID DHCP6_CLASS_UNCONFIGURED
boost::shared_ptr< OptionVendorClass > OptionVendorClassPtr
Defines a pointer to the OptionVendorClass.
const isc::log::MessageID DHCP6_LEASE_NA_WITHOUT_DUID
const isc::log::MessageID DHCP6_HOOK_DECLINE_DROP
const isc::log::MessageID DHCP6_PROCESS_IA_PD_REQUEST
const isc::log::MessageID DHCP6_HOOK_SUBNET6_SELECT_SKIP
const isc::log::MessageID DHCP6_PD_LEASE_RENEW
const isc::log::MessageID DHCP6_CLASS_ASSIGNED
boost::shared_ptr< Pkt6 > Pkt6Ptr
A pointer to Pkt6 packet.
const isc::log::MessageID DHCP6_PROCESS_IA_NA_RELEASE
const isc::log::MessageID DHCP6_PACKET_DROP_DROP_CLASS_EARLY
const isc::log::MessageID DHCP6_LEASE_ADVERT
std::vector< uint8_t > OptionBuffer
buffer types used in DHCP code.
const isc::log::MessageID DHCP6_DECLINE_FAIL_DUID_MISMATCH
const isc::log::MessageID DHCP6_SRV_UNLOAD_LIBRARIES_ERROR
const isc::log::MessageID DHCP6_HOOK_LEASES6_COMMITTED_PARK
const isc::log::MessageID DHCP6_DECLINE_FAIL_NO_LEASE
const isc::log::MessageID DHCP6_RAPID_COMMIT
const isc::log::MessageID DHCP6_BUFFER_WAIT_SIGNAL
bool isClientClassBuiltIn(const ClientClass &client_class)
Check if a client class name is builtin.
boost::shared_ptr< Option6ClientFqdn > Option6ClientFqdnPtr
A pointer to the Option6ClientFqdn object.
const isc::log::MessageID DHCP6_PROCESS_IA_PD_EXTEND
const int DBG_DHCP6_BASIC
Debug level used to trace basic operations within the code.
isc::log::Logger dhcp6_logger(DHCP6_APP_LOGGER_NAME)
Base logger for DHCPv6 server.
const isc::log::MessageID DHCP6_SUBNET_SELECTED
const isc::log::MessageID DHCP6_CLASS_UNTESTABLE
const isc::log::MessageID DHCP6_RELEASE_NA_FAIL_WRONG_IAID
const isc::log::MessageID DHCP6_HOOK_BUFFER_RCVD_DROP
boost::shared_ptr< Option > OptionPtr
const isc::log::MessageID DHCP6_DDNS_CREATE_ADD_NAME_CHANGE_REQUEST
const isc::log::MessageID DHCP6_RELEASE_NA_FAIL_WRONG_DUID
const isc::log::MessageID DHCP6_ADD_STATUS_CODE_FOR_IA
isc::log::Logger options6_logger(DHCP6_OPTIONS_LOGGER_NAME)
Logger for options parser.
const isc::log::MessageID DHCP6_LEASE_DATA
const isc::log::MessageID DHCP6_HOOK_BUFFER_SEND_SKIP
const int DBG_DHCP6_DETAIL
Debug level used to trace detailed errors.
const isc::log::MessageID DHCP6_SUBNET_DYNAMICALLY_CHANGED
const isc::log::MessageID DHCP6_PACKET_QUEUE_FULL
const isc::log::MessageID DHCP6_PD_LEASE_ALLOC_FAIL
const isc::log::MessageID DHCP6_HOOK_LEASE6_RELEASE_PD_SKIP
const isc::log::MessageID DHCP6_RELEASE_PD
std::list< ConstCfgOptionPtr > CfgOptionList
Const pointer list.
const isc::log::MessageID DHCP6_DDNS_FQDN_GENERATED
const isc::log::MessageID DHCP6_PACKET_DROP_DHCP_DISABLED
boost::shared_ptr< Pool6 > Pool6Ptr
a pointer an IPv6 Pool
isc::log::Logger hooks_logger("hooks")
Hooks Logger.
boost::shared_ptr< CalloutHandle > CalloutHandlePtr
A shared pointer to a CalloutHandle object.
const int DBGLVL_TRACE_BASIC
Trace basic operations.
const int DBGLVL_PKT_HANDLING
This debug level is reserved for logging the details of packet handling, such as dropping the packet ...
bool equalValues(const T &ptr1, const T &ptr2)
This function checks if two pointers are non-null and values are equal.
Defines the logger used by the top-level component of kea-lfc.
This file provides the classes needed to embody, compose, and decompose DNS update requests that are ...
#define DHCP6_OPTION_SPACE
Lease6Collection old_leases_
A pointer to any old leases that the client had before update but are no longer valid after the updat...
Option6IAPtr ia_rsp_
A pointer to the IA_NA/IA_PD option to be sent in response.
Lease::Type type_
Lease type (IA or PD)
Lease6Collection changed_leases_
A pointer to any leases that have changed FQDN information.
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.
HintContainer hints_
Client's hints.
uint32_t iaid_
The IAID field from IA_NA or IA_PD that is being processed.
Context information for the DHCPv6 leases allocation.
IAContext & currentIA()
Returns IA specific context for the currently processed IA.
std::vector< IAContext > ias_
Container holding IA specific contexts.
void addHostIdentifier(const Host::IdentifierType &id_type, const std::vector< uint8_t > &identifier)
Convenience function adding host identifier into host_identifiers_ list.
bool fake_allocation_
Indicates if this is a real or fake allocation.
ConstHostPtr currentHost() const
Returns host from the most preferred subnet.
DuidPtr duid_
Client identifier.
Lease6Collection new_leases_
A collection of newly allocated leases.
HWAddrPtr hwaddr_
Hardware/MAC address (if available, may be NULL)
hooks::CalloutHandlePtr callout_handle_
Callout handle associated with the client's message.
Subnet6Ptr subnet_
Subnet selected for the client by the server.
ResourceContainer allocated_resources_
Holds addresses and prefixes allocated for all IAs.
bool rev_dns_update_
A boolean value which indicates that server takes responsibility for the reverse DNS Update for this ...
DdnsParamsPtr getDdnsParams()
Returns the set of DDNS behavioral parameters based on the selected subnet.
ConstHostPtr globalHost() const
Returns global host reservation if there is one.
Pkt6Ptr query_
A pointer to the client's message.
bool early_global_reservations_lookup_
Indicates if early global reservation is enabled.
std::string hostname_
Hostname.
void createIAContext()
Creates new IA context.
std::map< SubnetID, ConstHostPtr > hosts_
Holds a map of hosts belonging to the client within different subnets.
bool fwd_dns_update_
A boolean value which indicates that server takes responsibility for the forward DNS Update for this ...
static std::string lifetimeToText(uint32_t lifetime)
Print lifetime.
@ TYPE_PD
the lease contains IPv6 prefix (for prefix delegation)
@ TYPE_NA
the lease contains non-temporary IPv6 address
Subnet selector used to specify parameters used to select a subnet.