8#include <kea_version.h>
66#include <boost/tokenizer.hpp>
67#include <boost/foreach.hpp>
68#include <boost/algorithm/string/erase.hpp>
69#include <boost/algorithm/string/join.hpp>
70#include <boost/algorithm/string/split.hpp>
93namespace ph = std::placeholders;
99 int hook_index_buffer6_receive_;
100 int hook_index_pkt6_receive_;
101 int hook_index_subnet6_select_;
102 int hook_index_leases6_committed_;
103 int hook_index_lease6_release_;
104 int hook_index_pkt6_send_;
105 int hook_index_buffer6_send_;
106 int hook_index_lease6_decline_;
107 int hook_index_host6_identifier_;
108 int hook_index_ddns6_update_;
143createStatusCode(
const Pkt6& pkt,
const uint16_t status_code,
144 const std::string& status_message) {
149 .arg(option_status->dataToText());
150 return (option_status);
168createStatusCode(
const Pkt6& pkt,
const Option6IA& ia,
const uint16_t status_code,
169 const std::string& status_message) {
175 .arg(option_status->dataToText());
176 return (option_status);
181std::set<std::string> dhcp6_statistics = {
183 "pkt6-solicit-received",
184 "pkt6-advertise-received",
185 "pkt6-request-received",
186 "pkt6-reply-received",
187 "pkt6-renew-received",
188 "pkt6-rebind-received",
189 "pkt6-decline-received",
190 "pkt6-release-received",
191 "pkt6-infrequest-received",
192 "pkt6-dhcpv4-query-received",
193 "pkt6-dhcpv4-response-received",
194 "pkt6-unknown-received",
196 "pkt6-advertise-sent",
198 "pkt6-dhcpv4-response-sent",
201 "v6-allocation-fail",
202 "v6-allocation-fail-shared-network",
203 "v6-allocation-fail-subnet",
204 "v6-allocation-fail-no-pools",
205 "v6-allocation-fail-classes",
206 "v6-ia-na-lease-reuses",
207 "v6-ia-pd-lease-reuses",
218 : io_service_(new
IOService()), server_port_(server_port),
219 client_port_(client_port), serverid_(), shutdown_(true),
220 alloc_engine_(), name_change_reqs_(),
250 }
catch (
const std::exception &e) {
265 for (
auto const& it : dhcp6_statistics) {
267 stats_mgr.setValue(it,
static_cast<int64_t
>(0));
277 }
catch (
const std::exception& ex) {
284 }
catch (
const std::exception& ex) {
298 if (!names.empty()) {
300 for (
size_t i = 1; i < names.size(); ++i) {
301 msg += std::string(
", ") + names[i];
307 io_service_->stopAndPoll();
333 if (
getServerID()->getData() != server_id->getData()){
335 .arg(pkt->getLabel())
347 switch (pkt->getType()) {
352 if (pkt->relay_info_.empty() && !pkt->getLocalAddr().isV6Multicast()) {
354 .arg(pkt->getLabel())
355 .arg(pkt->getName());
370 for (
auto const& id_type : cfg->getIdentifierTypes()) {
391 std::vector<uint8_t> id;
400 callout_handle->setArgument(
"query6", ctx.
query_);
401 callout_handle->setArgument(
"id_type", type);
402 callout_handle->setArgument(
"id_value",
id);
408 callout_handle->getArgument(
"id_type", type);
409 callout_handle->getArgument(
"id_value",
id);
415 .arg(ctx.
query_->getLabel())
435 ctx.
duid_ = query->getClientId();
462 if (global_host && !global_host->getClientClasses6().empty()) {
467 const ClientClasses& classes = global_host->getClientClasses6();
468 for (
auto const& cclass : classes) {
469 query->addClass(cclass);
478 query->addClass(
"KNOWN");
480 .arg(query->getLabel())
487 if (query->inClass(
"DROP")) {
490 .arg(query->makeLabel(query->getClientId(),
nullptr))
491 .arg(query->toText());
493 static_cast<int64_t
>(1));
498 ctx.
hosts_[SUBNET_ID_GLOBAL] = global_host;
532 ctx.
subnet_->getSharedNetwork(sn);
544 global_host && !global_host->getClientClasses6().empty()) ||
545 (!sn && current_host && !current_host->getClientClasses6().empty())) {
566 if (!ctx.
hosts_.empty()) {
567 ctx.
query_->addClass(
"KNOWN");
569 .arg(ctx.
query_->getLabel())
572 ctx.
query_->addClass(
"UNKNOWN");
574 .arg(ctx.
query_->getLabel())
583 .arg(ctx.
query_->getLabel())
584 .arg(classes.toText());
587 if (ctx.
query_->inClass(
"DROP")) {
589 .arg(ctx.
query_->makeLabel(ctx.
query_->getClientId(), 0))
590 .arg(ctx.
query_->toText());
592 static_cast<int64_t
>(1));
605 while (__AFL_LOOP(fuzzer.maxLoopCount())) {
617 }
catch (
const std::exception& e) {
648 uint32_t timeout = 1;
659 .arg(query->getRemoteAddr().toText())
660 .arg(query->getRemotePort())
661 .arg(query->getLocalAddr().toText())
662 .arg(query->getLocalPort())
663 .arg(query->getIface());
685 }
catch (
const std::exception& e) {
699 .arg(query->getLabel());
703 query->addPktEvent(
"mt_queued");
704 typedef function<void()> CallBack;
705 boost::shared_ptr<CallBack> call_back =
721 }
catch (
const std::exception& e) {
723 .arg(query->getLabel())
727 .arg(query->getLabel());
744 query->addPktEvent(
"process_started");
747 query->addClass(
"ALL");
749 bool skip_unpack =
false;
763 ScopedEnableOptionsCopy<Pkt6> query6_options_copy(query);
766 callout_handle->setArgument(
"query6", query);
777 .arg(query->getRemoteAddr().toText())
778 .arg(query->getLocalAddr().toText())
779 .arg(query->getIface());
788 .arg(query->getRemoteAddr().toText())
789 .arg(query->getLocalAddr().toText())
790 .arg(query->getIface());
800 callout_handle->getArgument(
"query6", query);
812 .arg(query->getRemoteAddr().toText())
813 .arg(query->getLocalAddr().toText())
814 .arg(query->getIface());
821 .arg(query->getLabel())
823 }
catch (
const std::exception &e) {
826 .arg(query->getLabel())
827 .arg(query->getRemoteAddr().toText())
828 .arg(query->getLocalAddr().toText())
829 .arg(query->getIface())
831 .arg(query->makeLabel(query->getClientId(),
nullptr));
835 static_cast<int64_t
>(1));
837 static_cast<int64_t
>(1));
844 .arg(query->getLabel());
847 processStatsReceived(query);
872 .arg(query->getLabel())
873 .arg(query->getName())
874 .arg(
static_cast<int>(query->getType()))
875 .arg(query->getRemoteAddr())
876 .arg(query->getLocalAddr())
877 .arg(query->getIface());
879 .arg(query->getLabel())
880 .arg(query->toText());
895 ScopedEnableOptionsCopy<Pkt6> query6_options_copy(query);
898 callout_handle->setArgument(
"query6", query);
909 .arg(query->getLabel());
918 callout_handle->getArgument(
"query6", query);
931 if (query->inClass(
"DROP")) {
933 .arg(query->makeLabel(query->getClientId(),
nullptr))
934 .arg(query->toText());
936 static_cast<int64_t
>(1));
953 }
catch (
const std::exception& e) {
955 .arg(query->getLabel())
959 .arg(query->getLabel());
979 if (!client_handler.tryLock(query, cont)) {
1020 }
catch (
const std::exception& e) {
1022 .arg(query->getLabel())
1026 .arg(query->getLabel());
1039 callout_handle->getContext(
"subnet6", ctx.
subnet_);
1059 switch (query->getType()) {
1096 }
catch (
const std::exception& e) {
1106 .arg(query->getLabel())
1107 .arg(query->getName())
1108 .arg(query->getRemoteAddr().toText())
1131 rsp->setRemoteAddr(query->getRemoteAddr());
1132 rsp->setLocalAddr(query->getLocalAddr());
1137 }
else if (rsp->relay_info_.empty()) {
1139 rsp->setRemotePort(DHCP6_CLIENT_PORT);
1143 rsp->setRemotePort(relay_port ? relay_port : DHCP6_SERVER_PORT);
1149 rsp->setLocalPort(DHCP6_SERVER_PORT);
1151 rsp->setIndex(query->getIndex());
1152 rsp->setIface(query->getIface());
1181 std::shared_ptr<ScopedCalloutHandleState> callout_handle_state =
1182 std::make_shared<ScopedCalloutHandleState>(callout_handle);
1184 ScopedEnableOptionsCopy<Pkt6> query6_options_copy(query);
1187 callout_handle->setArgument(
"query6", query);
1193 if (new_lease->reuseable_valid_lft_ == 0) {
1194 new_leases->push_back(new_lease);
1198 callout_handle->setArgument(
"leases6", new_leases);
1203 for (
auto const& iac : ctx.
ias_) {
1204 if (!iac.old_leases_.empty()) {
1205 for (
auto const& old_lease : iac.old_leases_) {
1207 deleted_leases->push_back(old_lease);
1210 bool in_new =
false;
1212 if ((new_lease->addr_ == old_lease->addr_) &&
1214 (new_lease->prefixlen_ == old_lease->prefixlen_))) {
1220 deleted_leases->push_back(old_lease);
1225 callout_handle->setArgument(
"deleted_leases6", deleted_leases);
1228 uint32_t parked_packet_limit = 0;
1232 parked_packet_limit = ppl->intValue();
1235 if (parked_packet_limit) {
1237 getParkingLotPtr(
"leases6_committed");
1238 if (parking_lot && (parking_lot->size() >= parked_packet_limit)) {
1242 .arg(parked_packet_limit)
1243 .arg(query->getLabel());
1245 static_cast<int64_t
>(1));
1257 [
this, callout_handle, query, rsp, callout_handle_state, subnet]()
mutable {
1259 typedef function<void()> CallBack;
1260 boost::shared_ptr<CallBack> call_back =
1262 this, callout_handle, query, rsp, subnet));
1263 callout_handle_state->on_completion_ = [call_back]() {
1284 .arg(query->getLabel());
1295 .arg(query->getLabel());
1315 }
catch (
const std::exception& e) {
1317 .arg(query->getLabel())
1321 .arg(query->getLabel());
1328 query->addPktEvent(
"process_completed");
1334 bool skip_pack =
false;
1349 ScopedEnableOptionsCopy<Pkt6> query_resp_options_copy(query, rsp);
1352 callout_handle->setArgument(
"query6", query);
1355 callout_handle->setArgument(
"response6", rsp);
1358 callout_handle->setArgument(
"subnet6", subnet);
1370 .arg(rsp->getLabel());
1377 .arg(rsp->getLabel());
1386 }
catch (
const std::exception& e) {
1388 .arg(query->getLabel())
1417 ScopedEnableOptionsCopy<Pkt6> response6_options_copy(rsp);
1420 callout_handle->setArgument(
"response6", rsp);
1433 .arg(rsp->getLabel());
1437 callout_handle->getArgument(
"response6", rsp);
1441 .arg(rsp->getLabel())
1442 .arg(rsp->getName())
1443 .arg(
static_cast<int>(rsp->getType()))
1444 .arg(rsp->getLocalAddr().isV6Zero() ?
"*" : rsp->getLocalAddr().toText())
1445 .arg(rsp->getLocalPort())
1446 .arg(rsp->getRemoteAddr())
1447 .arg(rsp->getRemotePort())
1448 .arg(rsp->getIface());
1451 .arg(rsp->getLabel())
1452 .arg(rsp->getName())
1453 .arg(
static_cast<int>(rsp->getType()))
1454 .arg(rsp->toText());
1460 }
catch (
const std::exception& e) {
1462 .arg(rsp->getLabel())
1474 for (
auto const& it : data) {
1478 tmp << hex << setw(2) << setfill('0') << static_cast<uint16_t>(it);
1492 answer->addOption(clientid);
1497 if (!question->relay_info_.empty()) {
1498 answer->copyRelayInfo(question);
1516 co_list.push_back(ctx.
currentHost()->getCfgOption6());
1524 ctx.
subnet_->getPool(resource.getPrefixLength() == 128 ?
1526 resource.getAddress(),
1528 if (pool && !pool->getCfgOption()->empty()) {
1529 co_list.push_back(pool->getCfgOption());
1534 if (!ctx.
subnet_->getCfgOption()->empty()) {
1535 co_list.push_back(ctx.
subnet_->getCfgOption());
1540 ctx.
subnet_->getSharedNetwork(network);
1541 if (network && !network->getCfgOption()->empty()) {
1542 co_list.push_back(network->getCfgOption());
1548 for (
auto const& cclass : classes) {
1551 getClientClassDictionary()->findClass(cclass);
1556 .arg(question->getLabel())
1563 if (ccdef->getCfgOption()->empty()) {
1568 co_list.push_back(ccdef->getCfgOption());
1581 if (co_list.empty()) {
1585 set<uint16_t> requested_opts;
1594 for (uint16_t code : option_oro->getValues()) {
1595 static_cast<void>(requested_opts.insert(code));
1599 set<uint16_t> cancelled_opts;
1603 for (
auto const& copts : co_list) {
1611 BOOST_FOREACH(
auto const& desc, prange) {
1614 uint16_t code = desc.option_->getType();
1615 static_cast<void>(requested_opts.insert(code));
1621 BOOST_FOREACH(
auto const& desc, crange) {
1624 uint16_t code = desc.option_->getType();
1625 static_cast<void>(cancelled_opts.insert(code));
1632 for (uint16_t opt : requested_opts) {
1634 if (cancelled_opts.count(opt) > 0) {
1642 if (!answer->getOption(opt)) {
1644 for (
auto const& copts : co_list) {
1648 answer->addOption(desc.option_);
1661 set<uint32_t> vendor_ids;
1665 vendor_class = boost::dynamic_pointer_cast<OptionVendorClass>(opt.second);
1667 uint32_t vendor_id = vendor_class->getVendorId();
1668 static_cast<void>(vendor_ids.insert(vendor_id));
1672 for (
auto const& copts : co_list) {
1674 if (!desc.option_) {
1678 boost::dynamic_pointer_cast<OptionVendorClass>(desc.option_);
1679 if (!vendor_class) {
1683 uint32_t vendor_id = vendor_class->getVendorId();
1684 if (vendor_ids.count(vendor_id) > 0) {
1688 answer->addOption(desc.option_);
1689 static_cast<void>(vendor_ids.insert(vendor_id));
1698 set<uint32_t> vendor_ids;
1702 vendor_opts = boost::dynamic_pointer_cast<OptionVendor>(opt.second);
1704 uint32_t vendor_id = vendor_opts->getVendorId();
1705 static_cast<void>(vendor_ids.insert(vendor_id));
1709 for (
auto const& copts : co_list) {
1711 if (!desc.option_) {
1715 boost::dynamic_pointer_cast<OptionVendor>(desc.option_);
1720 uint32_t vendor_id = vendor_opts->getVendorId();
1721 if (vendor_ids.count(vendor_id) > 0) {
1727 answer->addOption(vendor_opts);
1728 static_cast<void>(vendor_ids.insert(vendor_id));
1747 if (!ctx.
subnet_ || co_list.empty()) {
1751 set<uint32_t> vendor_ids;
1755 map<uint32_t, OptionVendorPtr> vendor_rsps;
1758 vendor_rsp = boost::dynamic_pointer_cast<OptionVendor>(opt.second);
1760 uint32_t vendor_id = vendor_rsp->getVendorId();
1761 vendor_rsps[vendor_id] = vendor_rsp;
1762 static_cast<void>(vendor_ids.insert(vendor_id));
1768 map<uint32_t, OptionVendorPtr> vendor_reqs;
1771 vendor_req = boost::dynamic_pointer_cast<OptionVendor>(opt.second);
1773 uint32_t vendor_id = vendor_req->getVendorId();
1774 vendor_reqs[vendor_id] = vendor_req;
1775 static_cast<void>(vendor_ids.insert(vendor_id));
1783 vendor_class = boost::dynamic_pointer_cast<OptionVendorClass>(opt.second);
1785 uint32_t vendor_id = vendor_class->getVendorId();
1786 static_cast<void>(vendor_ids.insert(vendor_id));
1792 if (vendor_ids.empty()) {
1796 map<uint32_t, set<uint16_t> > requested_opts;
1810 oro = boost::dynamic_pointer_cast<OptionUint16Array>(oro_generic);
1813 set<uint16_t> oro_req_opts;
1814 for (uint16_t code : oro->getValues()) {
1815 static_cast<void>(oro_req_opts.insert(code));
1821 map<uint32_t, set<uint16_t> > cancelled_opts;
1825 for (uint32_t vendor_id : vendor_ids) {
1826 for (
auto const& copts : co_list) {
1834 BOOST_FOREACH(
auto const& desc, prange) {
1835 if (!desc.option_) {
1839 uint16_t code = desc.option_->getType();
1840 static_cast<void>(requested_opts[vendor_id].insert(code));
1845 BOOST_FOREACH(
auto const& desc, crange) {
1846 if (!desc.option_) {
1850 uint16_t code = desc.option_->getType();
1851 static_cast<void>(cancelled_opts[vendor_id].insert(code));
1860 if (requested_opts[vendor_id].empty()) {
1867 if (vendor_rsps.count(vendor_id) > 0) {
1868 vendor_rsp = vendor_rsps[vendor_id];
1876 for (uint16_t opt : requested_opts[vendor_id]) {
1877 if (cancelled_opts[vendor_id].count(opt) > 0) {
1880 if (!vendor_rsp->getOption(opt)) {
1881 for (
auto const& copts : co_list) {
1884 vendor_rsp->addOption(desc.option_);
1894 if (added && (vendor_rsps.count(vendor_id) == 0)) {
1895 answer->addOption(vendor_rsp);
1903 switch (pkt->getType()) {
1925 .arg(pkt->getLabel())
1926 .arg(
static_cast<int>(pkt->getType()))
1927 .arg(pkt->getIface());
1932 .arg(pkt->getLabel())
1933 .arg(pkt->getName())
1934 .arg(pkt->getRemoteAddr().toText())
1949 if (client_ids.size() != 1) {
1951 << pkt->getName() <<
", but " << client_ids.size()
1958 if (client_ids.size() > 1) {
1960 <<
") client-id options received in " << pkt->getName());
1962 if (!client_ids.empty()) {
1975 if (!server_ids.empty()) {
1977 << server_ids.size() <<
" received in " << pkt->getName());
1982 if (server_ids.size() != 1) {
1984 << server_ids.size() <<
"), exactly 1 expected in message "
1991 if (server_ids.size() > 1) {
1993 <<
") server-id options received in " << pkt->getName());
1995 if (!server_ids.empty()) {
2008 uint16_t len = opt->len() - opt->getHeaderLen();
2021 getCfgSubnets6()->selectSubnet(selector);
2031 shared_ptr<ScopedCalloutHandleState> callout_handle_state(
2032 std::make_shared<ScopedCalloutHandleState>(callout_handle));
2035 ScopedEnableOptionsCopy<Pkt6> query6_options_copy(question);
2038 callout_handle->setArgument(
"query6", question);
2039 callout_handle->setArgument(
"subnet6", subnet);
2044 callout_handle->setArgument(
"subnet6collection",
2046 getCfgSubnets6()->getAll());
2048 auto const tpl(parkingLimitExceeded(
"subnet6_select"));
2049 bool const exceeded(get<0>(tpl));
2051 uint32_t
const limit(get<1>(tpl));
2056 .arg(question->getLabel());
2063 HooksManager::park(
"subnet6_select", question, [
this, question, callout_handle_state]() {
2065 boost::shared_ptr<function<void()>> callback(
2066 boost::make_shared<function<
void()>>([
this, question]()
mutable {
2069 callout_handle_state->on_completion_ = [callback]() {
2091 .arg(question->getLabel());
2104 .arg(question->getLabel());
2112 .arg(question->getLabel());
2118 callout_handle->getArgument(
"subnet6", subnet);
2124 .arg(question->getLabel())
2125 .arg(subnet->getID());
2129 .arg(question->getLabel())
2130 .arg(subnet->toText());
2134 .arg(question->getLabel());
2159 for (
auto const& opt : question->options_) {
2160 switch (opt.second->getType()) {
2163 boost::dynamic_pointer_cast<
2166 answer->addOption(answer_opt);
2172 boost::dynamic_pointer_cast<
2175 answer->addOption(answer_opt);
2200 if (ddns_params->getEnableUpdates() &&
2210 .arg(question->getLabel());
2223 .arg(question->getLabel())
2224 .arg(fqdn->toText());
2242 fqdn_resp->setDomainName(d2_mgr.qualifyName(ctx.
currentHost()->getHostname(),
2243 *ddns_params,
true),
2253 ctx.
hostname_ = fqdn_resp->getDomainName();
2260 .arg(question->getLabel())
2261 .arg(fqdn_resp->toText());
2262 answer->addOption(fqdn_resp);
2277 callout_handle->setArgument(
"query6", question);
2278 callout_handle->setArgument(
"response6", answer);
2279 callout_handle->setArgument(
"subnet6", subnet);
2280 callout_handle->setArgument(
"hostname", ctx.
hostname_);
2283 callout_handle->setArgument(
"ddns-params", ddns_params);
2289 string hook_hostname;
2290 bool hook_fwd_dns_update;
2291 bool hook_rev_dns_update;
2292 callout_handle->getArgument(
"hostname", hook_hostname);
2293 callout_handle->getArgument(
"fwd-update", hook_fwd_dns_update);
2294 callout_handle->getArgument(
"rev-update", hook_rev_dns_update);
2305 fqdn_resp = boost::dynamic_pointer_cast<Option6ClientFqdn>(answer->getOption(
D6O_CLIENT_FQDN));
2308 if (!(hook_fwd_dns_update || hook_rev_dns_update)) {
2335 <<
" encapsulating server's message must not be"
2336 <<
" NULL when creating DNS NameChangeRequest");
2349 bool do_fwd =
false;
2350 bool do_rev =
false;
2360 "client identifier is required when creating a new"
2361 " DNS NameChangeRequest");
2368 opt_fqdn->packDomainName(name_buf);
2369 const std::vector<uint8_t>& buf_vec = name_buf.getVector();
2375 for (
auto const& answer_ia : answer->getOptions(
D6O_IA_NA)) {
2390 bool extended_only =
false;
2393 if (l->addr_ == iaaddr->getAddress()) {
2398 (l->hostname_ == opt_fqdn->getDomainName() &&
2399 l->fqdn_fwd_ == do_fwd && l->fqdn_rev_ == do_rev)) {
2400 extended_only =
true;
2412 if (!(do_fwd || do_rev) || (extended_only)) {
2428 opt_fqdn->getDomainName(),
2429 iaaddr->getAddress().toText(),
2435 .arg(answer->getLabel())
2436 .arg(ncr->toText());
2452 getMACSources().get();
2454 for (
auto const& it : mac_sources) {
2455 hwaddr = pkt->getMAC(it);
2466 boost::shared_ptr<Option6IA> ia) {
2472 boost::dynamic_pointer_cast<Option6IAAddr>(ia->getOption(
D6O_IAADDR));
2475 hint = hint_opt->getAddress();
2480 .arg(query->getLabel())
2482 .arg(hint_opt ? hint.toText() :
"(no hint)");
2485 .arg(query->getLabel())
2487 .arg(hint_opt ? hint.toText() :
"(no hint)");
2507 "Server could not select subnet for"
2530 if (!leases.empty()) {
2531 lease = *leases.begin();
2544 .arg(query->getLabel())
2545 .arg(lease->addr_.toText())
2546 .arg(ia->getIAID());
2547 }
else if (lease->reuseable_valid_lft_ == 0) {
2549 .arg(query->getLabel())
2550 .arg(lease->addr_.toText())
2554 lease->valid_lft_ = lease->reuseable_valid_lft_;
2555 lease->preferred_lft_ = lease->reuseable_preferred_lft_;
2557 .arg(query->getLabel())
2558 .arg(lease->addr_.toText())
2565 "v6-ia-na-lease-reuses"),
2569 .arg(query->getLabel())
2571 .arg(lease->toText());
2574 setTeeTimes(lease->preferred_lft_, subnet, ia_rsp);
2577 lease->preferred_lft_,
2578 lease->valid_lft_));
2579 ia_rsp->addOption(addr);
2592 .arg(query->getLabel())
2593 .arg(ia->getIAID());
2595 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
2597 "Sorry, no address could be"
2606 boost::shared_ptr<Option6IA> ia) {
2613 boost::dynamic_pointer_cast<Option6IAPrefix>(ia->getOption(
D6O_IAPREFIX));
2616 hint = hint_opt->getAddress();
2621 .arg(query->getLabel())
2623 .arg(hint_opt ? hint.toText() :
"(no hint)");
2626 .arg(query->getLabel())
2628 .arg(hint_opt ? hint.toText() :
"(no hint)");
2646 "Sorry, no subnet available."));
2666 if (!leases.empty()) {
2670 uint32_t min_preferred_lft = (*leases.begin())->preferred_lft_;
2672 const bool pd_exclude_requested = requestedInORO(query,
D6O_PD_EXCLUDE);
2673 for (
auto const& l : leases) {
2679 .arg(query->getLabel())
2680 .arg(l->addr_.toText())
2681 .arg(
static_cast<int>(l->prefixlen_))
2682 .arg(ia->getIAID());
2683 }
else if (l->reuseable_valid_lft_ == 0) {
2685 .arg(query->getLabel())
2686 .arg(l->addr_.toText())
2687 .arg(
static_cast<int>(l->prefixlen_))
2691 l->valid_lft_ = l->reuseable_valid_lft_;
2692 l->preferred_lft_ = l->reuseable_preferred_lft_;
2694 .arg(query->getLabel())
2695 .arg(l->addr_.toText())
2696 .arg(
static_cast<int>(l->prefixlen_))
2703 "v6-ia-pd-lease-reuses"),
2708 if ((l->preferred_lft_ > 0) && (min_preferred_lft > l->preferred_lft_)) {
2709 min_preferred_lft = l->preferred_lft_;
2712 boost::shared_ptr<Option6IAPrefix>
2714 l->prefixlen_, l->preferred_lft_,
2716 ia_rsp->addOption(addr);
2718 if (pd_exclude_requested) {
2721 Pool6Ptr pool = boost::dynamic_pointer_cast<
2725 if (pd_exclude_option) {
2726 addr->addOption(pd_exclude_option);
2746 .arg(query->getLabel())
2747 .arg(ia->getIAID());
2749 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
2751 "Sorry, no prefixes could"
2760 boost::shared_ptr<Option6IA> ia) {
2763 .arg(query->getLabel())
2764 .arg(ia->getIAID());
2783 "Sorry, no known leases for this duid/iaid."));
2795 for (
auto const& it : addrs) {
2799 Option6IAAddrPtr iaaddr = boost::dynamic_pointer_cast<Option6IAAddr>(it.second);
2826 uint32_t min_preferred_lft = std::numeric_limits<uint32_t>::max();
2829 for (
auto const& l : leases) {
2830 if (l->reuseable_valid_lft_ == 0) {
2832 .arg(query->getLabel())
2833 .arg(l->addr_.toText())
2834 .arg(ia->getIAID());
2836 l->valid_lft_ = l->reuseable_valid_lft_;
2837 l->preferred_lft_ = l->reuseable_preferred_lft_;
2839 .arg(query->getLabel())
2840 .arg(l->addr_.toText())
2847 "v6-ia-na-lease-reuses"),
2852 l->addr_, l->preferred_lft_, l->valid_lft_));
2853 ia_rsp->addOption(iaaddr);
2856 if ((l->preferred_lft_ > 0) && (min_preferred_lft > l->preferred_lft_)) {
2857 min_preferred_lft = l->preferred_lft_;
2862 hints.erase(std::remove(hints.begin(), hints.end(), hint_type),
2872 if (
equalValues(query->getClientId(), l->duid_)) {
2875 ia_rsp->addOption(iaaddr);
2880 hints.erase(std::remove(hints.begin(), hints.end(), hint_type), hints.end());
2888 .arg(query->getLabel())
2900 for (
auto const& hint : hints) {
2902 hint.getAddress(), 0, 0));
2903 ia_rsp->addOption(iaaddr);
2906 if (!leases.empty()) {
2912 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
2914 "Sorry, no addresses could be"
2915 " assigned at this time."));
2924 boost::shared_ptr<Option6IA> ia) {
2927 .arg(query->getLabel())
2928 .arg(ia->getIAID());
2945 "Sorry, no known PD leases"
2946 " for this duid/iaid."));
2966 " client sending Rebind to extend lifetime of the"
2967 " prefix (DUID=" << duid->toText() <<
", IAID="
2968 << ia->getIAID() <<
")");
2980 for (
auto const& it : addrs) {
3014 const bool pd_exclude_requested = requestedInORO(query,
D6O_PD_EXCLUDE);
3018 uint32_t min_preferred_lft = std::numeric_limits<uint32_t>::max();
3020 for (
auto const& l : leases) {
3021 if (l->reuseable_valid_lft_ == 0) {
3023 .arg(query->getLabel())
3024 .arg(l->addr_.toText())
3025 .arg(
static_cast<int>(l->prefixlen_))
3026 .arg(ia->getIAID());
3028 l->valid_lft_ = l->reuseable_valid_lft_;
3029 l->preferred_lft_ = l->reuseable_preferred_lft_;
3031 .arg(query->getLabel())
3032 .arg(l->addr_.toText())
3033 .arg(
static_cast<int>(l->prefixlen_))
3040 "v6-ia-pd-lease-reuses"),
3045 l->addr_, l->prefixlen_,
3046 l->preferred_lft_, l->valid_lft_));
3047 ia_rsp->addOption(prf);
3049 if (pd_exclude_requested) {
3052 Pool6Ptr pool = boost::dynamic_pointer_cast<
3057 if (pd_exclude_option) {
3058 prf->addOption(pd_exclude_option);
3064 if ((l->preferred_lft_ > 0) && (l->preferred_lft_ < min_preferred_lft)) {
3065 min_preferred_lft = l->preferred_lft_;
3070 hints.erase(std::remove(hints.begin(), hints.end(), hint_type),
3080 if (
equalValues(query->getClientId(), l->duid_)) {
3082 l->prefixlen_, 0, 0));
3083 ia_rsp->addOption(prefix);
3088 hints.erase(std::remove(hints.begin(), hints.end(), hint_type), hints.end());
3093 for (
auto const& prefix : hints) {
3098 if (!prefix.getAddress().isV6Zero()) {
3100 prefix.getAddress(),
3101 prefix.getPrefixLength(),
3103 ia_rsp->addOption(prefix_opt);
3107 if (!leases.empty()) {
3114 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
3116 "Sorry, no prefixes could be"
3117 " assigned at this time."));
3138 for (
auto const& opt : query->options_) {
3139 switch (opt.second->getType()) {
3142 boost::dynamic_pointer_cast<
3145 reply->addOption(answer_opt);
3152 boost::dynamic_pointer_cast<
3155 reply->addOption(answer_opt);
3190 for (
auto const& opt : release->options_) {
3192 switch (opt.second->getType()) {
3195 boost::dynamic_pointer_cast<Option6IA>(opt.second),
3198 reply->addOption(answer_opt);
3204 boost::dynamic_pointer_cast<Option6IA>(opt.second),
3207 reply->addOption(answer_opt);
3224 reply->addOption(createStatusCode(*release, general_status,
3225 "Summary status for all processed IA_NAs"));
3230 int& general_status, boost::shared_ptr<Option6IA> ia,
3234 .arg(query->getLabel())
3235 .arg(ia->getIAID());
3251 if (!release_addr) {
3253 "You did not include an address in your RELEASE"));
3259 release_addr->getAddress());
3266 "Sorry, no known leases for this duid/iaid, can't release."));
3272 if (!lease->duid_) {
3278 .arg(query->getLabel())
3279 .arg(release_addr->getAddress().toText());
3283 "Database consistency check failed when trying to RELEASE"));
3287 if (*duid != *(lease->duid_)) {
3291 .arg(query->getLabel())
3292 .arg(release_addr->getAddress().toText())
3293 .arg(lease->duid_->toText());
3297 "This address does not belong to you, you can't release it"));
3301 if (ia->getIAID() != lease->iaid_) {
3304 .arg(query->getLabel())
3305 .arg(release_addr->getAddress().toText())
3307 .arg(ia->getIAID());
3309 "This is your address, but you used wrong IAID"));
3329 ScopedEnableOptionsCopy<Pkt6> query6_options_copy(query);
3332 callout_handle->deleteAllArguments();
3335 callout_handle->setArgument(
"query6", query);
3338 callout_handle->setArgument(
"lease6", lease);
3350 .arg(query->getLabel());
3355 bool success =
false;
3356 bool expired =
false;
3357 auto expiration_cfg =
CfgMgr::instance().getCurrentCfg()->getCfgExpiration();
3363 if (expiration_cfg->getFlushReclaimedTimerWaitTime() &&
3364 expiration_cfg->getHoldReclaimedTime() &&
3367 lease->valid_lft_ = 0;
3368 lease->preferred_lft_ = 0;
3388 "Server failed to release a lease"));
3391 .arg(query->getLabel())
3392 .arg(lease->addr_.toText())
3401 .arg(query->getLabel())
3402 .arg(lease->addr_.toText())
3405 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
STATUS_Success,
3406 "Lease released. Thank you, please come again."));
3410 .arg(query->getLabel())
3411 .arg(lease->addr_.toText())
3415 .arg(query->getLabel())
3416 .arg(lease->addr_.toText())
3428 static_cast<int64_t
>(-1));
3430 auto const& subnet =
CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getBySubnetId(lease->subnet_id_);
3432 auto const& pool = subnet->getPool(
Lease::TYPE_NA, lease->addr_,
false);
3437 static_cast<int64_t
>(-1));
3447 int& general_status, boost::shared_ptr<Option6IA> ia,
3462 boost::shared_ptr<Option6IAPrefix> release_prefix =
3463 boost::dynamic_pointer_cast<Option6IAPrefix>(ia->getOption(
D6O_IAPREFIX));
3464 if (!release_prefix) {
3466 "You did not include a prefix in your RELEASE"));
3472 release_prefix->getAddress());
3479 "Sorry, no known leases for this duid/iaid, can't release."));
3485 if (!lease->duid_) {
3490 .arg(query->getLabel())
3491 .arg(release_prefix->getAddress().toText())
3492 .arg(
static_cast<int>(release_prefix->getLength()));
3496 "Database consistency check failed when trying to RELEASE"));
3500 if (*duid != *(lease->duid_)) {
3503 .arg(query->getLabel())
3504 .arg(release_prefix->getAddress().toText())
3505 .arg(
static_cast<int>(release_prefix->getLength()))
3506 .arg(lease->duid_->toText());
3510 "This address does not belong to you, you can't release it"));
3514 if (ia->getIAID() != lease->iaid_) {
3517 .arg(query->getLabel())
3518 .arg(release_prefix->getAddress().toText())
3519 .arg(
static_cast<int>(release_prefix->getLength()))
3521 .arg(ia->getIAID());
3523 "This is your address, but you used wrong IAID"));
3543 ScopedEnableOptionsCopy<Pkt6> query6_options_copy(query);
3546 callout_handle->setArgument(
"query6", query);
3549 callout_handle->setArgument(
"lease6", lease);
3561 .arg(query->getLabel());
3566 bool success =
false;
3567 bool expired =
false;
3568 auto expiration_cfg =
CfgMgr::instance().getCurrentCfg()->getCfgExpiration();
3574 if (expiration_cfg->getFlushReclaimedTimerWaitTime() &&
3575 expiration_cfg->getHoldReclaimedTime() &&
3578 lease->valid_lft_ = 0;
3579 lease->preferred_lft_ = 0;
3599 "Server failed to release a lease"));
3602 .arg(query->getLabel())
3603 .arg(lease->addr_.toText())
3604 .arg(
static_cast<int>(lease->prefixlen_))
3612 .arg(query->getLabel())
3613 .arg(lease->addr_.toText())
3614 .arg(
static_cast<int>(lease->prefixlen_))
3617 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
STATUS_Success,
3618 "Lease released. Thank you, please come again."));
3622 .arg(query->getLabel())
3623 .arg(lease->addr_.toText())
3624 .arg(
static_cast<int>(lease->prefixlen_))
3628 .arg(query->getLabel())
3629 .arg(lease->addr_.toText())
3630 .arg(
static_cast<int>(lease->prefixlen_))
3637 static_cast<int64_t
>(-1));
3639 auto const& subnet =
CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getBySubnetId(lease->subnet_id_);
3641 auto const& pool = subnet->getPool(
Lease::TYPE_PD, lease->addr_,
false);
3646 static_cast<int64_t
>(-1));
3663 if (opt_rapid_commit) {
3666 .arg(solicit->getLabel());
3671 response->addOption(opt_rapid_commit);
3703 .arg(solicit->getLabel())
3704 .arg(solicit->getName())
3705 .arg(solicit->getClasses().toText());
3714 updateReservedFqdn(ctx, response);
3746 .arg(request->getLabel())
3747 .arg(request->getName())
3748 .arg(request->getClasses().toText());
3757 updateReservedFqdn(ctx, reply);
3758 generateFqdn(reply, ctx);
3785 .arg(renew->getLabel())
3786 .arg(renew->getName())
3787 .arg(renew->getClasses().toText());
3796 updateReservedFqdn(ctx, reply);
3797 generateFqdn(reply, ctx);
3824 .arg(rebind->getLabel())
3825 .arg(rebind->getName())
3826 .arg(rebind->getClasses().toText());
3835 updateReservedFqdn(ctx, reply);
3836 generateFqdn(reply, ctx);
3850 .arg(confirm->getLabel())
3851 .arg(confirm->getName())
3852 .arg(confirm->getClasses().toText());
3873 bool verified =
false;
3882 for (
auto const& ia : ias) {
3884 for (
auto const& opt : opts) {
3896 if (subnet && !subnet->inRange(iaaddr->getAddress())) {
3897 std::ostringstream status_msg;
3898 status_msg <<
"Address " << iaaddr->
getAddress()
3899 <<
" is not on link.";
3900 reply->addOption(createStatusCode(*confirm,
3908 " to the Option6IAAddrPtr. This is programming"
3909 " error and should be reported");
3926 "All addresses are on-link"));
3929 "No subnet selected"));
3943 .arg(release->getLabel())
3944 .arg(release->getName())
3945 .arg(release->getClasses().toText());
3974 .arg(decline->getLabel())
3975 .arg(decline->getName())
3976 .arg(decline->getClasses().toText());
4015 for (
auto const& opt : decline->options_) {
4016 switch (opt.second->getType()) {
4019 boost::dynamic_pointer_cast<Option6IA>(opt.second),
4024 reply->addOption(answer_opt);
4045 int& general_status, boost::shared_ptr<Option6IA> ia,
4049 .arg(decline->getLabel())
4050 .arg(ia->getIAID());
4065 int total_addrs = 0;
4066 for (
auto const& opt : opts) {
4075 if (!decline_addr) {
4082 decline_addr->getAddress());
4087 .arg(decline->getLabel()).arg(decline_addr->getAddress().toText());
4095 "Server does not know about such an address."));
4103 if (!lease->duid_) {
4109 .arg(decline->getLabel())
4110 .arg(decline_addr->getAddress().toText());
4113 "Database consistency check failed when attempting Decline."));
4119 if (*duid != *(lease->duid_)) {
4123 .arg(decline->getLabel())
4124 .arg(decline_addr->getAddress().toText())
4125 .arg(lease->duid_->toText());
4128 "This address does not belong to you, you can't decline it"));
4134 if (ia->getIAID() != lease->iaid_) {
4137 .arg(decline->getLabel())
4138 .arg(lease->addr_.toText())
4142 "This is your address, but you used wrong IAID"));
4154 new_leases.push_back(lease);
4158 if (total_addrs == 0) {
4160 "No addresses sent in IA_NA"));
4173 container->addOption(status);
4178 boost::shared_ptr<Option6IA> ia_rsp) {
4199 ScopedEnableOptionsCopy<Pkt6> query6_options_copy(decline);
4202 callout_handle->setArgument(
"query6", decline);
4205 callout_handle->setArgument(
"lease6", lease);
4216 .arg(decline->getLabel())
4217 .arg(decline->getIface())
4218 .arg(lease->addr_.toText());
4226 .arg(decline->getLabel())
4227 .arg(decline->getIface())
4228 .arg(lease->addr_.toText());
4233 Lease6Ptr old_values = boost::make_shared<Lease6>(*lease);
4247 .arg(decline->getLabel())
4248 .arg(lease->addr_.toText())
4261 static_cast<int64_t
>(1));
4263 auto const& subnet =
CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getBySubnetId(lease->subnet_id_);
4265 auto const& pool = subnet->getPool(
Lease::TYPE_NA, lease->addr_,
false);
4270 static_cast<int64_t
>(1));
4278 .arg(lease->addr_.toText()).arg(lease->valid_lft_);
4280 ia_rsp->addOption(createStatusCode(*decline, *ia_rsp,
STATUS_Success,
4281 "Lease declined. Hopefully the next one will be better."));
4294 .arg(inf_request->getLabel())
4295 .arg(inf_request->getName())
4296 .arg(inf_request->getClasses().toText());
4345void Dhcpv6Srv::classifyByVendor(
const Pkt6Ptr& pkt) {
4348 vclass = boost::dynamic_pointer_cast<OptionVendorClass>(opt.second);
4349 if (!vclass || vclass->getTuplesNum() == 0) {
4367 pkt->addClass(
"ALL");
4370 classifyByVendor(pkt);
4381 for (
auto const& it : *defs_ptr) {
4389 if (it->getRequired()) {
4393 if (it->getDependOnKnown() != depend_on_known) {
4396 it->test(pkt, expr_ptr);
4405 for (
auto const& def : *defs_ptr) {
4409 if (def->getMatchExpr()) {
4410 pkt->classes_.erase(def->getName());
4420 for (
auto const& cclass : classes) {
4421 pkt->addClass(cclass);
4431 ctx.
subnet_->getSharedNetwork(shared_network);
4432 if (shared_network) {
4434 if (host && (host->getIPv6SubnetID() != SUBNET_ID_GLOBAL)) {
4450 subnet->getSharedNetwork(network);
4452 const ClientClasses& to_add = network->getRequiredClasses();
4453 for (
auto const& cclass : to_add) {
4460 for (
auto const& cclass : to_add) {
4467 ctx.
subnet_->getPool(resource.getPrefixLength() == 128 ?
4469 resource.getAddress(),
4472 const ClientClasses& pool_to_add = pool->getRequiredClasses();
4473 for (
auto const& cclass : pool_to_add) {
4486 for (
auto const& cclass : classes) {
4506 .arg(pkt->getLabel())
4510 pkt->addClass(cclass);
4513 .arg(pkt->getLabel())
4519 .arg(pkt->getLabel())
4524 .arg(pkt->getLabel())
4526 .arg(
"get exception?");
4536 " a message must not be NULL when updating reserved FQDN");
4547 std::string name = fqdn->getDomainName();
4559 if (new_name != name) {
4564 answer->addOption(fqdn);
4570Dhcpv6Srv::generateFqdn(
const Pkt6Ptr& answer,
4574 " a message must not be NULL when generating FQDN");
4585 if (!fqdn || !fqdn->getDomainName().empty()) {
4599 if (!iaaddr || iaaddr->getValid() == 0) {
4605 std::string generated_name =
4609 .arg(answer->getLabel())
4610 .arg(generated_name);
4620 for (
auto const& l : ctx.new_leases_) {
4627 lease->hostname_ = generated_name;
4628 lease->reuseable_valid_lft_ = 0;
4633 " for address " << addr <<
", so as it is impossible"
4634 " to update FQDN data. This is a programmatic error"
4635 " as the given address is now being handed to the"
4643 answer->addOption(fqdn);
4647 .arg(answer->getLabel())
4656 if (d2_mgr.ddnsEnabled()) {
4661 this, ph::_1, ph::_2));
4668 if (d2_mgr.ddnsEnabled()) {
4671 d2_mgr.stopSender();
4680 arg(result).arg((ncr ? ncr->toText() :
" NULL "));
4689 std::stringstream tmp;
4693 tmp <<
" (" << EXTENDED_VERSION <<
")" << endl;
4694 tmp <<
"premium: " << PREMIUM_EXTENDED_VERSION << endl;
4695 tmp <<
"linked with:" << endl;
4698 tmp <<
"backends:" << endl;
4715 if (query->relay_info_.empty()) {
4726 for (
int i = query->relay_info_.size(); i > 0 ; --i) {
4728 if (rsoo_container) {
4733 for (
auto const& opt : rsoo) {
4737 if (cfg_rsoo->enabled(opt.second->getType()) &&
4738 !rsp->getOption(opt.second->getType())) {
4739 rsp->addOption(opt.second);
4748 if (query->relay_info_.empty()) {
4756 return (query->getRemotePort());
4762void Dhcpv6Srv::processStatsReceived(
const Pkt6Ptr& query) {
4766 string stat_name =
"pkt6-unknown-received";
4767 switch (query->getType()) {
4769 stat_name =
"pkt6-solicit-received";
4773 stat_name =
"pkt6-advertise-received";
4776 stat_name =
"pkt6-request-received";
4779 stat_name =
"pkt6-confirm-received";
4782 stat_name =
"pkt6-renew-received";
4785 stat_name =
"pkt6-rebind-received";
4789 stat_name =
"pkt6-reply-received";
4792 stat_name =
"pkt6-release-received";
4795 stat_name =
"pkt6-decline-received";
4798 stat_name =
"pkt6-reconfigure-received";
4801 stat_name =
"pkt6-infrequest-received";
4804 stat_name =
"pkt6-dhcpv4-query-received";
4808 stat_name =
"pkt6-dhcpv4-response-received";
4823 switch (response->getType()) {
4825 stat_name =
"pkt6-advertise-sent";
4828 stat_name =
"pkt6-reply-sent";
4831 stat_name =
"pkt6-dhcpv4-response-sent";
4842 return (
Hooks.hook_index_buffer6_send_);
4846Dhcpv6Srv::requestedInORO(
const Pkt6Ptr& query,
const uint16_t code)
const {
4848 boost::dynamic_pointer_cast<OptionUint16Array>(query->getOption(
D6O_ORO));
4851 const std::vector<uint16_t>& codes = oro->getValues();
4852 return (std::find(codes.begin(), codes.end(), code) != codes.end());
4858tuple<bool, uint32_t>
4859Dhcpv6Srv::parkingLimitExceeded(
string const& hook_label) {
4861 uint32_t parked_packet_limit(0);
4865 parked_packet_limit = ppl->intValue();
4868 if (parked_packet_limit) {
4872 if (parking_lot && parked_packet_limit <= parking_lot->size()) {
4873 return make_tuple(
true, parked_packet_limit);
4876 return make_tuple(
false, parked_packet_limit);
4889 uint32_t t2_time = 0;
4892 if (!subnet->getT2().unspecified()) {
4893 t2_time = subnet->getT2();
4894 }
else if (subnet->getCalculateTeeTimes()) {
4896 t2_time =
static_cast<uint32_t
>(round(subnet->getT2Percent() * preferred_lft));
4900 resp->setT2(t2_time);
4903 uint32_t t1_time = 0;
4906 if (!subnet->getT1().unspecified()) {
4907 t1_time = subnet->getT1();
4908 }
else if (subnet->getCalculateTeeTimes()) {
4910 t1_time =
static_cast<uint32_t
>(round(subnet->getT1Percent() * preferred_lft));
4914 if (t1_time < t2_time) {
4915 resp->setT1(t1_time);
4927 if ((!ctx.
subnet_) || (!orig_subnet) || (orig_subnet->getID() == ctx.
subnet_->getID())) {
4935 orig_subnet->getSharedNetwork(network);
4937 .arg(question->getLabel())
4938 .arg(orig_subnet->toText())
4940 .arg(network ? network->getName() :
"<no network?>");
4946 std::string prev_hostname = ctx.
hostname_;
4967 l->reuseable_valid_lft_ = 0;
4974 static std::list<std::list<std::string>>
const list({
4975 {
"config-control",
"config-databases",
"[]"},
4976 {
"hooks-libraries",
"[]",
"parameters",
"*"},
4978 {
"hosts-databases",
"[]"},
This is a base class for exceptions thrown from the DNS library module.
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.
static IOServiceMgr & instance()
Access the IOServiceMgr singleton instance.
The IOService class is a wrapper for the ASIO io_service class.
static std::string getVersion()
Get version string.
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
static CfgMgr & instance()
returns a single instance of Configuration Manager
static SubnetSelector initSelector(const Pkt6Ptr &query)
Build selector from a client's message.
Container for storing client class names.
void insert(const ClientClass &class_name)
Insert an element.
Client race avoidance RAII handler.
D2ClientMgr isolates Kea from the details of being a D2 client.
This exception is thrown when DHCP server hits the error which should result in discarding the messag...
Factory for generating DUIDs (DHCP Unique Identifiers).
DuidPtr get()
Returns current DUID.
Holds DUID (DHCPv6 Unique Identifier)
static constexpr size_t MIN_DUID_LEN
minimum duid size
static constexpr size_t MAX_DUID_LEN
maximum duid size
static Dhcp6to4Ipc & instance()
Returns pointer to the sole instance of Dhcp6to4Ipc.
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.
Pkt6Ptr processPacket(Pkt6Ptr query)
Process a single incoming DHCPv6 packet.
Pkt6Ptr processLocalizedQuery6(AllocEngine::ClientContext6 &ctx)
Process a localized incoming DHCPv6 query.
void processPacketAndSendResponseNoThrow(Pkt6Ptr query)
Process a single incoming DHCPv6 packet and sends the response.
OptionPtr extendIA_PD(const Pkt6Ptr &query, AllocEngine::ClientContext6 &ctx, Option6IAPtr ia)
Extends lifetime of the prefix.
void sendResponseNoThrow(hooks::CalloutHandlePtr &callout_handle, Pkt6Ptr query, Pkt6Ptr &rsp, Subnet6Ptr &subnet)
Process an unparked DHCPv6 packet and sends the response.
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.
void processLocalizedQuery6AndSendResponse(Pkt6Ptr query, AllocEngine::ClientContext6 &ctx)
Process a localized incoming DHCPv6 query.
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.
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.
void runOne()
Main server processing step.
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 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.
void processPacketAndSendResponse(Pkt6Ptr query)
Process a single incoming DHCPv6 packet and sends the response.
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 initContext0(const Pkt6Ptr &query, AllocEngine::ClientContext6 &ctx)
Initialize client context (first part).
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.
void initContext(AllocEngine::ClientContext6 &ctx, bool &drop)
Initializes client context for specified packet.
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.
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 processPacketPktSend(hooks::CalloutHandlePtr &callout_handle, Pkt6Ptr &query, Pkt6Ptr &rsp, Subnet6Ptr &subnet)
Executes pkt6_send callout.
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.
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.
Pkt6Ptr processDhcp6Query(Pkt6Ptr query)
Process a single incoming DHCPv6 query.
void processDhcp6QueryAndSendResponse(Pkt6Ptr query)
Process a single incoming DHCPv6 query.
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.
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.
static TrackingLeaseMgr & instance()
Return current lease manager.
static void destroy()
Destroy lease manager.
static std::string getDBVersion()
Class method to return extended version info This class method must be redeclared and redefined in de...
static std::string getDBVersion()
Local version of getDBVersion() class method.
Controls the 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.
This class represents Status Code option (13) from RFC 8415.
This class represents vendor-specific information option.
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.
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....
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.
@ NEXT_STEP_PARK
park the packet
@ NEXT_STEP_CONTINUE
continue normally
@ NEXT_STEP_DROP
drop the packet
@ NEXT_STEP_SKIP
skip the next processing step
static int registerHook(const std::string &name)
Register Hook.
static bool calloutsPresent(int index)
Are callouts present?
static std::vector< std::string > getLibraryNames()
Return list of loaded libraries.
static bool unloadLibraries()
Unload libraries.
static void park(const std::string &hook_name, T parked_object, std::function< void()> unpark_callback)
Park an object (packet).
static void callCallouts(int index, CalloutHandle &handle)
Calls the callouts for a given hook.
static void prepareUnloadLibraries()
Prepare the unloading of libraries.
static bool drop(const std::string &hook_name, T parked_object)
Removes parked object without calling a callback.
static void clearParkingLots()
Clears any parking packets.
Wrapper class around callout handle which automatically resets handle's state.
static ServerHooks & getServerHooks()
Return ServerHooks object.
static std::string getVersion()
Version.
int getExitValue()
Fetches the exit value.
Statistics Manager class.
static StatsMgr & instance()
Statistics Manager accessor method.
static std::string generateName(const std::string &context, Type index, const std::string &stat_name)
Generates statistic name in a given context.
RAII class creating a critical section.
static MultiThreadingMgr & instance()
Returns a single instance of Multi Threading Manager.
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
@ 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
OptionIntArray< uint16_t > OptionUint16Array
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
ConflictResolutionMode StringToConflictResolutionMode(const std::string &mode_str)
Function which converts string to ConflictResolutionMode enum values.
boost::shared_ptr< NameChangeRequest > NameChangeRequestPtr
Defines a pointer to a NameChangeRequest.
const isc::log::MessageID DHCP6_DDNS_REQUEST_SEND_FAILED
boost::shared_ptr< OptionVendor > OptionVendorPtr
Pointer to a vendor option.
const isc::log::MessageID DHCP6_PD_LEASE_ADVERT
const isc::log::MessageID DHCP6_BUFFER_RECEIVED
const isc::log::MessageID DHCP6_RELEASE_NA_DELETED
isc::log::Logger bad_packet6_logger(DHCP6_BAD_PACKET_LOGGER_NAME)
Logger for rejected packets.
const isc::log::MessageID DHCP6_PACKET_DROP_PARSE_FAIL
const isc::log::MessageID DHCP6_RELEASE_PD_DELETED
const isc::log::MessageID DHCP6_LEASE_ALLOC
const isc::log::MessageID DHCP6_FLEX_ID
boost::shared_ptr< Subnet > SubnetPtr
A generic pointer to either Subnet4 or Subnet6 object.
const isc::log::MessageID DHCP6_PACKET_PROCESS_EXCEPTION_MAIN
const isc::log::MessageID DHCP6_HOOK_PACKET_SEND_SKIP
uint32_t calculateDdnsTtl(uint32_t lease_lft, const util::Optional< double > &ddns_ttl_percent)
Calculates TTL for a DNS resource record based on lease life time.
const isc::log::MessageID DHCP6_SUBNET_SELECTION_FAILED
const isc::log::MessageID DHCP6_CLASS_UNDEFINED
const isc::log::MessageID DHCP6_PACKET_DROP_SERVERID_MISMATCH
const isc::log::MessageID DHCP6_HOOK_DECLINE_SKIP
const isc::log::MessageID DHCP6_PD_LEASE_REUSE
const isc::log::MessageID DHCP6_PACKET_DROP_UNICAST
const isc::log::MessageID DHCP6_LEASE_PD_WITHOUT_DUID
const isc::log::MessageID DHCP6_LEASE_ALLOC_FAIL
const isc::log::MessageID DHCP6_PACKET_SEND_FAIL
const isc::log::MessageID DHCP6_PACKET_PROCESS_EXCEPTION
void queueNCR(const NameChangeType &chg_type, const Lease4Ptr &lease)
Creates name change request from the DHCPv4 lease.
const isc::log::MessageID DHCP6_QUERY_LABEL
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
boost::shared_ptr< Lease6 > Lease6Ptr
Pointer to a Lease6 structure.
std::vector< Lease6Ptr > Lease6Collection
A collection of IPv6 leases.
const int DBG_DHCP6_HOOKS
Debug level used to trace hook related operations.
const isc::log::MessageID DHCP6_HOOK_LEASE6_RELEASE_NA_SKIP
ContinuationPtr makeContinuation(Continuation &&cont)
Continuation factory.
const int DBG_DHCP6_START
Debug level used to log information during server startup.
const isc::log::MessageID DHCP6_PD_LEASE_ALLOC
const isc::log::MessageID DHCP6_DDNS_GENERATE_FQDN
const isc::log::MessageID DHCP6_RELEASE_PD_EXPIRED
boost::shared_ptr< Option6IA > Option6IAPtr
A pointer to the Option6IA object.
boost::shared_ptr< Subnet6 > Subnet6Ptr
A pointer to a Subnet6 object.
const isc::log::MessageID DHCP6_DDNS_REMOVE_OLD_LEASE_FQDN
boost::shared_ptr< const CfgRSOO > ConstCfgRSOOPtr
Pointer to the const object.
boost::shared_ptr< const CfgHostOperations > ConstCfgHostOperationsPtr
Pointer to the const object.
std::multimap< unsigned int, OptionPtr > OptionCollection
A collection of DHCP (v4 or v6) options.
const isc::log::MessageID DHCP6_SUBNET_DATA
const isc::log::MessageID DHCP6_UNKNOWN_MSG_RECEIVED
boost::shared_ptr< ClientClassDef > ClientClassDefPtr
a pointer to an ClientClassDef
boost::shared_ptr< DdnsParams > DdnsParamsPtr
Defines a pointer for DdnsParams instances.
const isc::log::MessageID DHCP6_HOOK_SUBNET6_SELECT_DROP
const isc::log::MessageID DHCP6_ADD_GLOBAL_STATUS_CODE
boost::shared_ptr< Option6IAPrefix > Option6IAPrefixPtr
Pointer to the Option6IAPrefix object.
const isc::log::MessageID DHCP6_DDNS_RESPONSE_FQDN_DATA
const isc::log::MessageID DHCP6_RELEASE_NA
const isc::log::MessageID DHCP6_CLASSES_ASSIGNED
const isc::log::MessageID DHCP6_REQUIRED_OPTIONS_CHECK_FAIL
const isc::log::MessageID DHCP6_PROCESS_IA_NA_EXTEND
const isc::log::MessageID DHCP6_RELEASE_PD_FAIL
const isc::log::MessageID DHCP6_SRV_CONSTRUCT_ERROR
const isc::log::MessageID DHCP6_LEASE_RENEW
const char * DOCSIS3_CLASS_EROUTER
The class as specified in vendor-class option by the devices.
const isc::log::MessageID DHCP6_RELEASE_NA_FAIL
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
const isc::log::MessageID DHCP6_PACKET_PROCESS_STD_EXCEPTION
const isc::log::MessageID DHCP6_PACKET_RECEIVE_FAIL
const isc::log::MessageID DHCP6_PROCESS_IA_NA_SOLICIT
const isc::log::MessageID DHCP6_DECLINE_FAIL_IAID_MISMATCH
const isc::log::MessageID DHCP6_HOOK_SUBNET6_SELECT_PARK
OptionContainer::nth_index< 5 >::type OptionContainerCancelIndex
Type of the index #5 - option cancellation flag.
boost::shared_ptr< Option6StatusCode > Option6StatusCodePtr
Pointer to the isc::dhcp::Option6StatusCode.
std::pair< OptionContainerPersistIndex::const_iterator, OptionContainerPersistIndex::const_iterator > OptionContainerPersistRange
Pair of iterators to represent the range of options having the same persistency flag.
boost::shared_ptr< SharedNetwork6 > SharedNetwork6Ptr
Pointer to SharedNetwork6 object.
const isc::log::MessageID DHCP4_HOOK_SUBNET6_SELECT_PARKING_LOT_FULL
isc::log::Logger packet6_logger(DHCP6_PACKET_LOGGER_NAME)
Logger for processed packets.
const isc::log::MessageID DHCP6_DECLINE_LEASE
boost::shared_ptr< Expression > ExpressionPtr
const isc::log::MessageID DHCP6_LEASE_ADVERT_FAIL
const isc::log::MessageID DHCP6_HOOK_LEASES6_PARKING_LOT_FULL
const isc::log::MessageID DHCP6_PD_LEASE_ADVERT_FAIL
boost::shared_ptr< Pool > PoolPtr
a pointer to either IPv4 or IPv6 Pool
isc::hooks::CalloutHandlePtr getCalloutHandle(const T &pktptr)
CalloutHandle Store.
const isc::log::MessageID DHCP6_PACKET_PROCESS_FAIL
const isc::log::MessageID DHCP6_RELEASE_NA_EXPIRED
boost::shared_ptr< ClientClassDictionary > ClientClassDictionaryPtr
Defines a pointer to a ClientClassDictionary.
const isc::log::MessageID DHCP6_PACKET_RECEIVED
const isc::log::MessageID DHCP6_RESPONSE_DATA
const isc::log::MessageID DHCP6_DDNS_RECEIVE_FQDN
const isc::log::MessageID DHCP6_PACKET_OPTIONS_SKIPPED
const isc::log::MessageID DHCP6_NO_INTERFACES
const isc::log::MessageID DHCP6_RELEASE_PD_FAIL_WRONG_DUID
const isc::log::MessageID DHCP6_LEASE_REUSE
isc::log::Logger ddns6_logger(DHCP6_DDNS_LOGGER_NAME)
Logger for Hostname or FQDN processing.
boost::shared_ptr< Continuation > ContinuationPtr
Define the type of shared pointers to continuations.
boost::shared_ptr< OptionContainer > OptionContainerPtr
Pointer to the OptionContainer object.
boost::shared_ptr< ClientClassDefList > ClientClassDefListPtr
Defines a pointer to a ClientClassDefList.
const isc::log::MessageID DHCP6_HOOK_LEASES6_COMMITTED_DROP
const isc::log::MessageID DHCP6_HOOK_PACKET_SEND_DROP
const isc::log::MessageID DHCP6_DDNS_GENERATED_FQDN_UPDATE_FAIL
const isc::log::MessageID DHCP6_PACKET_DROP_DROP_CLASS2
boost::shared_ptr< Option6IAAddr > Option6IAAddrPtr
A pointer to the isc::dhcp::Option6IAAddr object.
const char * DOCSIS3_CLASS_MODEM
DOCSIS3.0 compatible cable modem.
const isc::log::MessageID DHCP6_SHUTDOWN_REQUEST
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_PROCESS_IA_PD_SOLICIT
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
std::pair< OptionContainerCancelIndex::const_iterator, OptionContainerCancelIndex::const_iterator > OptionContainerCancelRange
Pair of iterators to represent the range of options having the same cancellation flag.
const isc::log::MessageID DHCP6_CLASSES_ASSIGNED_AFTER_SUBNET_SELECTION
const isc::log::MessageID DHCP6_PACKET_PROCESS_STD_EXCEPTION_MAIN
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.
boost::shared_ptr< ParkingLot > ParkingLotPtr
Type of the pointer to the parking lot.
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 const uint32_t INFINITY_LFT
Infinity (means static, i.e. never expire)
static std::string lifetimeToText(uint32_t lifetime)
Print lifetime.
static const uint32_t STATE_RELEASED
Released lease held in the database for lease affinity.
@ 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.