8#include <kea_version.h>
114#include <boost/algorithm/string/erase.hpp>
115#include <boost/algorithm/string/join.hpp>
116#include <boost/algorithm/string/split.hpp>
117#include <boost/foreach.hpp>
118#include <boost/tokenizer.hpp>
132namespace ph = std::placeholders;
138 int hook_index_buffer6_receive_;
139 int hook_index_pkt6_receive_;
140 int hook_index_subnet6_select_;
141 int hook_index_leases6_committed_;
142 int hook_index_lease6_release_;
143 int hook_index_pkt6_send_;
144 int hook_index_buffer6_send_;
145 int hook_index_lease6_decline_;
146 int hook_index_host6_identifier_;
147 int hook_index_ddns6_update_;
182createStatusCode(
const Pkt6& pkt,
const uint16_t status_code,
183 const std::string& status_message) {
188 .arg(option_status->dataToText());
189 return (option_status);
207createStatusCode(
const Pkt6& pkt,
const Option6IA& ia,
const uint16_t status_code,
208 const std::string& status_message) {
214 .arg(option_status->dataToText());
215 return (option_status);
220std::set<std::string> dhcp6_statistics = {
222 "pkt6-solicit-received",
223 "pkt6-advertise-received",
224 "pkt6-request-received",
225 "pkt6-reply-received",
226 "pkt6-renew-received",
227 "pkt6-rebind-received",
228 "pkt6-decline-received",
229 "pkt6-release-received",
230 "pkt6-infrequest-received",
231 "pkt6-dhcpv4-query-received",
232 "pkt6-dhcpv4-response-received",
233 "pkt6-unknown-received",
235 "pkt6-advertise-sent",
237 "pkt6-dhcpv4-response-sent",
240 "v6-allocation-fail",
241 "v6-allocation-fail-shared-network",
242 "v6-allocation-fail-subnet",
243 "v6-allocation-fail-no-pools",
244 "v6-allocation-fail-classes",
245 "v6-ia-na-lease-reuses",
246 "v6-ia-pd-lease-reuses",
257 : io_service_(new
IOService()), server_port_(server_port),
258 client_port_(client_port), serverid_(), shutdown_(true),
259 alloc_engine_(), name_change_reqs_(),
289 }
catch (
const std::exception &e) {
305 for (
auto const& it : dhcp6_statistics) {
307 stats_mgr.setValue(it,
static_cast<int64_t
>(0));
317 }
catch (
const std::exception& ex) {
324 }
catch (
const std::exception& ex) {
343 if (!names.empty()) {
345 for (
size_t i = 1; i < names.size(); ++i) {
346 msg += std::string(
", ") + names[i];
352 io_service_->stopAndPoll();
378 if (
getServerID()->getData() != server_id->getData()){
380 .arg(pkt->getLabel())
392 switch (pkt->getType()) {
397 if (pkt->relay_info_.empty() && !pkt->getLocalAddr().isV6Multicast()) {
399 .arg(pkt->getLabel())
400 .arg(pkt->getName());
415 for (
auto const& id_type : cfg->getIdentifierTypes()) {
436 std::vector<uint8_t> id;
445 callout_handle->setArgument(
"query6", ctx.
query_);
446 callout_handle->setArgument(
"id_type", type);
447 callout_handle->setArgument(
"id_value",
id);
453 callout_handle->getArgument(
"id_type", type);
454 callout_handle->getArgument(
"id_value",
id);
460 .arg(ctx.
query_->getLabel())
480 ctx.
duid_ = query->getClientId();
507 if (global_host && !global_host->getClientClasses6().empty()) {
512 const ClientClasses& classes = global_host->getClientClasses6();
513 for (
auto const& cclass : classes) {
514 query->addClass(cclass);
523 query->addClass(
"KNOWN");
525 .arg(query->getLabel())
532 if (query->inClass(
"DROP")) {
535 .arg(query->makeLabel(query->getClientId(),
nullptr))
536 .arg(query->toText());
538 static_cast<int64_t
>(1));
543 ctx.
hosts_[SUBNET_ID_GLOBAL] = global_host;
577 ctx.
subnet_->getSharedNetwork(sn);
589 global_host && !global_host->getClientClasses6().empty()) ||
590 (!sn && current_host && !current_host->getClientClasses6().empty())) {
611 if (!ctx.
hosts_.empty()) {
612 ctx.
query_->addClass(
"KNOWN");
614 .arg(ctx.
query_->getLabel())
617 ctx.
query_->addClass(
"UNKNOWN");
619 .arg(ctx.
query_->getLabel())
628 .arg(ctx.
query_->getLabel())
629 .arg(classes.toText());
632 if (ctx.
query_->inClass(
"DROP")) {
634 .arg(ctx.
query_->makeLabel(ctx.
query_->getClientId(), 0))
635 .arg(ctx.
query_->toText());
637 static_cast<int64_t
>(1));
649 const char*
interface = getenv(
"KEA_AFL_INTERFACE");
651 isc_throw(FuzzInitFail,
"no fuzzing interface has been set");
655 const char* address = getenv(
"KEA_AFL_ADDRESS");
657 isc_throw(FuzzInitFail,
"no fuzzing address has been set");
665 while (__AFL_LOOP(fuzzer.maxLoopCount())) {
678 }
catch (
const std::exception& e) {
709 uint32_t timeout = 1;
720 .arg(query->getRemoteAddr().toText())
721 .arg(query->getRemotePort())
722 .arg(query->getLocalAddr().toText())
723 .arg(query->getLocalPort())
724 .arg(query->getIface());
746 }
catch (
const std::exception& e) {
760 .arg(query->getLabel());
764 query->addPktEvent(
"mt_queued");
765 typedef function<void()> CallBack;
766 boost::shared_ptr<CallBack> call_back =
782 }
catch (
const std::exception& e) {
784 .arg(query->getLabel())
788 .arg(query->getLabel());
805 query->addPktEvent(
"process_started");
808 query->addClass(
"ALL");
810 bool skip_unpack =
false;
824 ScopedEnableOptionsCopy<Pkt6> query6_options_copy(query);
827 callout_handle->setArgument(
"query6", query);
838 .arg(query->getRemoteAddr().toText())
839 .arg(query->getLocalAddr().toText())
840 .arg(query->getIface());
849 .arg(query->getRemoteAddr().toText())
850 .arg(query->getLocalAddr().toText())
851 .arg(query->getIface());
861 callout_handle->getArgument(
"query6", query);
873 .arg(query->getRemoteAddr().toText())
874 .arg(query->getLocalAddr().toText())
875 .arg(query->getIface());
882 .arg(query->getLabel())
884 }
catch (
const std::exception &e) {
887 .arg(query->getLabel())
888 .arg(query->getRemoteAddr().toText())
889 .arg(query->getLocalAddr().toText())
890 .arg(query->getIface())
892 .arg(query->makeLabel(query->getClientId(),
nullptr));
896 static_cast<int64_t
>(1));
898 static_cast<int64_t
>(1));
905 .arg(query->getLabel());
908 processStatsReceived(query);
933 .arg(query->getLabel())
934 .arg(query->getName())
935 .arg(
static_cast<int>(query->getType()))
936 .arg(query->getRemoteAddr())
937 .arg(query->getLocalAddr())
938 .arg(query->getIface());
940 .arg(query->getLabel())
941 .arg(query->toText());
956 ScopedEnableOptionsCopy<Pkt6> query6_options_copy(query);
959 callout_handle->setArgument(
"query6", query);
970 .arg(query->getLabel());
979 callout_handle->getArgument(
"query6", query);
992 if (query->inClass(
"DROP")) {
994 .arg(query->makeLabel(query->getClientId(),
nullptr))
995 .arg(query->toText());
997 static_cast<int64_t
>(1));
1014 }
catch (
const std::exception& e) {
1016 .arg(query->getLabel())
1020 .arg(query->getLabel());
1040 if (!client_handler.tryLock(query, cont)) {
1081 }
catch (
const std::exception& e) {
1083 .arg(query->getLabel())
1087 .arg(query->getLabel());
1100 callout_handle->getContext(
"subnet6", ctx.
subnet_);
1120 switch (query->getType()) {
1157 }
catch (
const std::exception& e) {
1167 .arg(query->getLabel())
1168 .arg(query->getName())
1169 .arg(query->getRemoteAddr().toText())
1192 rsp->setRemoteAddr(query->getRemoteAddr());
1193 rsp->setLocalAddr(query->getLocalAddr());
1198 }
else if (rsp->relay_info_.empty()) {
1200 rsp->setRemotePort(DHCP6_CLIENT_PORT);
1204 rsp->setRemotePort(relay_port ? relay_port : DHCP6_SERVER_PORT);
1210 rsp->setLocalPort(DHCP6_SERVER_PORT);
1212 rsp->setIndex(query->getIndex());
1213 rsp->setIface(query->getIface());
1242 std::shared_ptr<ScopedCalloutHandleState> callout_handle_state =
1243 std::make_shared<ScopedCalloutHandleState>(callout_handle);
1245 ScopedEnableOptionsCopy<Pkt6> query6_options_copy(query);
1248 callout_handle->setArgument(
"query6", query);
1254 if (new_lease->reuseable_valid_lft_ == 0) {
1255 new_leases->push_back(new_lease);
1259 callout_handle->setArgument(
"leases6", new_leases);
1264 for (
auto const& iac : ctx.
ias_) {
1265 if (!iac.old_leases_.empty()) {
1266 for (
auto const& old_lease : iac.old_leases_) {
1268 deleted_leases->push_back(old_lease);
1271 bool in_new =
false;
1273 if ((new_lease->addr_ == old_lease->addr_) &&
1275 (new_lease->prefixlen_ == old_lease->prefixlen_))) {
1281 deleted_leases->push_back(old_lease);
1286 callout_handle->setArgument(
"deleted_leases6", deleted_leases);
1289 uint32_t parked_packet_limit = 0;
1293 parked_packet_limit = ppl->intValue();
1296 if (parked_packet_limit) {
1298 getParkingLotPtr(
"leases6_committed");
1299 if (parking_lot && (parking_lot->size() >= parked_packet_limit)) {
1303 .arg(parked_packet_limit)
1304 .arg(query->getLabel());
1306 static_cast<int64_t
>(1));
1318 [
this, callout_handle, query, rsp, callout_handle_state, subnet]()
mutable {
1320 typedef function<void()> CallBack;
1321 boost::shared_ptr<CallBack> call_back =
1323 this, callout_handle, query, rsp, subnet));
1324 callout_handle_state->on_completion_ = [call_back]() {
1345 .arg(query->getLabel());
1356 .arg(query->getLabel());
1377 }
catch (
const std::exception& e) {
1379 .arg(query->getLabel())
1383 .arg(query->getLabel());
1391 query->addPktEvent(
"process_completed");
1397 bool skip_pack =
false;
1412 ScopedEnableOptionsCopy<Pkt6> query_resp_options_copy(query, rsp);
1415 callout_handle->setArgument(
"query6", query);
1418 callout_handle->setArgument(
"response6", rsp);
1421 callout_handle->setArgument(
"subnet6", subnet);
1433 .arg(rsp->getLabel());
1440 .arg(rsp->getLabel());
1450 }
catch (
const std::exception& e) {
1452 .arg(query->getLabel())
1481 ScopedEnableOptionsCopy<Pkt6> response6_options_copy(rsp);
1484 callout_handle->setArgument(
"response6", rsp);
1497 .arg(rsp->getLabel());
1501 callout_handle->getArgument(
"response6", rsp);
1505 .arg(rsp->getLabel())
1506 .arg(rsp->getName())
1507 .arg(
static_cast<int>(rsp->getType()))
1508 .arg(rsp->getLocalAddr().isV6Zero() ?
"*" : rsp->getLocalAddr().toText())
1509 .arg(rsp->getLocalPort())
1510 .arg(rsp->getRemoteAddr())
1511 .arg(rsp->getRemotePort())
1512 .arg(rsp->getIface());
1515 .arg(rsp->getLabel())
1516 .arg(rsp->getName())
1517 .arg(
static_cast<int>(rsp->getType()))
1518 .arg(rsp->toText());
1524 }
catch (
const std::exception& e) {
1526 .arg(rsp->getLabel())
1538 for (
auto const& it : data) {
1542 tmp << hex << setw(2) << setfill('0') << static_cast<uint16_t>(it);
1556 answer->addOption(clientid);
1561 if (!question->relay_info_.empty()) {
1562 answer->copyRelayInfo(question);
1580 co_list.push_back(ctx.
currentHost()->getCfgOption6());
1588 ctx.
subnet_->getPool(resource.getPrefixLength() == 128 ?
1590 resource.getAddress(),
1592 if (pool && !pool->getCfgOption()->empty()) {
1593 co_list.push_back(pool->getCfgOption());
1598 if (!ctx.
subnet_->getCfgOption()->empty()) {
1599 co_list.push_back(ctx.
subnet_->getCfgOption());
1604 ctx.
subnet_->getSharedNetwork(network);
1605 if (network && !network->getCfgOption()->empty()) {
1606 co_list.push_back(network->getCfgOption());
1612 for (
auto const& cclass : classes) {
1615 getClientClassDictionary()->findClass(cclass);
1620 .arg(question->getLabel())
1627 if (ccdef->getCfgOption()->empty()) {
1632 co_list.push_back(ccdef->getCfgOption());
1645 if (co_list.empty()) {
1649 set<uint16_t> requested_opts;
1658 for (uint16_t code : option_oro->getValues()) {
1659 static_cast<void>(requested_opts.insert(code));
1663 set<uint16_t> cancelled_opts;
1667 for (
auto const& copts : co_list) {
1675 BOOST_FOREACH(
auto const& desc, prange) {
1678 uint16_t code = desc.option_->getType();
1679 static_cast<void>(requested_opts.insert(code));
1685 BOOST_FOREACH(
auto const& desc, crange) {
1688 uint16_t code = desc.option_->getType();
1689 static_cast<void>(cancelled_opts.insert(code));
1694 const auto& cclasses = question->getClasses();
1697 for (uint16_t opt : requested_opts) {
1699 if (cancelled_opts.count(opt) > 0) {
1707 if (!answer->getOption(opt)) {
1709 for (
auto const& copts : co_list) {
1712 if (desc.option_ && desc.allowedForClientClasses(cclasses)) {
1713 answer->addOption(desc.option_);
1726 set<uint32_t> vendor_ids;
1730 vendor_class = boost::dynamic_pointer_cast<OptionVendorClass>(opt.second);
1732 uint32_t vendor_id = vendor_class->getVendorId();
1733 static_cast<void>(vendor_ids.insert(vendor_id));
1737 for (
auto const& copts : co_list) {
1740 if (!desc.option_ || !desc.allowedForClientClasses(cclasses)) {
1744 boost::dynamic_pointer_cast<OptionVendorClass>(desc.option_);
1745 if (!vendor_class) {
1749 uint32_t vendor_id = vendor_class->getVendorId();
1750 if (vendor_ids.count(vendor_id) > 0) {
1754 answer->addOption(desc.option_);
1755 static_cast<void>(vendor_ids.insert(vendor_id));
1764 set<uint32_t> vendor_ids;
1768 vendor_opts = boost::dynamic_pointer_cast<OptionVendor>(opt.second);
1770 uint32_t vendor_id = vendor_opts->getVendorId();
1771 static_cast<void>(vendor_ids.insert(vendor_id));
1775 for (
auto const& copts : co_list) {
1778 if (!desc.option_ || !desc.allowedForClientClasses(cclasses)) {
1782 boost::dynamic_pointer_cast<OptionVendor>(desc.option_);
1787 uint32_t vendor_id = vendor_opts->getVendorId();
1788 if (vendor_ids.count(vendor_id) > 0) {
1794 answer->addOption(vendor_opts);
1795 static_cast<void>(vendor_ids.insert(vendor_id));
1814 if (!ctx.
subnet_ || co_list.empty()) {
1818 set<uint32_t> vendor_ids;
1822 map<uint32_t, OptionVendorPtr> vendor_rsps;
1825 vendor_rsp = boost::dynamic_pointer_cast<OptionVendor>(opt.second);
1827 uint32_t vendor_id = vendor_rsp->getVendorId();
1828 vendor_rsps[vendor_id] = vendor_rsp;
1829 static_cast<void>(vendor_ids.insert(vendor_id));
1835 map<uint32_t, OptionVendorPtr> vendor_reqs;
1838 vendor_req = boost::dynamic_pointer_cast<OptionVendor>(opt.second);
1840 uint32_t vendor_id = vendor_req->getVendorId();
1841 vendor_reqs[vendor_id] = vendor_req;
1842 static_cast<void>(vendor_ids.insert(vendor_id));
1850 vendor_class = boost::dynamic_pointer_cast<OptionVendorClass>(opt.second);
1852 uint32_t vendor_id = vendor_class->getVendorId();
1853 static_cast<void>(vendor_ids.insert(vendor_id));
1859 if (vendor_ids.empty()) {
1863 map<uint32_t, set<uint16_t> > requested_opts;
1877 oro = boost::dynamic_pointer_cast<OptionUint16Array>(oro_generic);
1880 set<uint16_t> oro_req_opts;
1881 for (uint16_t code : oro->getValues()) {
1882 static_cast<void>(oro_req_opts.insert(code));
1888 map<uint32_t, set<uint16_t> > cancelled_opts;
1889 const auto& cclasses = question->getClasses();
1893 for (uint32_t vendor_id : vendor_ids) {
1894 for (
auto const& copts : co_list) {
1902 BOOST_FOREACH(
auto const& desc, prange) {
1903 if (!desc.option_) {
1907 uint16_t code = desc.option_->getType();
1908 static_cast<void>(requested_opts[vendor_id].insert(code));
1913 BOOST_FOREACH(
auto const& desc, crange) {
1914 if (!desc.option_) {
1918 uint16_t code = desc.option_->getType();
1919 static_cast<void>(cancelled_opts[vendor_id].insert(code));
1928 if (requested_opts[vendor_id].empty()) {
1935 if (vendor_rsps.count(vendor_id) > 0) {
1936 vendor_rsp = vendor_rsps[vendor_id];
1944 for (uint16_t opt : requested_opts[vendor_id]) {
1945 if (cancelled_opts[vendor_id].count(opt) > 0) {
1948 if (!vendor_rsp->getOption(opt)) {
1949 for (
auto const& copts : co_list) {
1952 if (desc.option_ && desc.allowedForClientClasses(cclasses)) {
1953 vendor_rsp->addOption(desc.option_);
1963 if (added && (vendor_rsps.count(vendor_id) == 0)) {
1964 answer->addOption(vendor_rsp);
1972 switch (pkt->getType()) {
1994 .arg(pkt->getLabel())
1995 .arg(
static_cast<int>(pkt->getType()))
1996 .arg(pkt->getIface());
2001 .arg(pkt->getLabel())
2002 .arg(pkt->getName())
2003 .arg(pkt->getRemoteAddr().toText())
2018 if (client_ids.size() != 1) {
2020 << pkt->getName() <<
", but " << client_ids.size()
2027 if (client_ids.size() > 1) {
2029 <<
") client-id options received in " << pkt->getName());
2031 if (!client_ids.empty()) {
2044 if (!server_ids.empty()) {
2046 << server_ids.size() <<
" received in " << pkt->getName());
2051 if (server_ids.size() != 1) {
2053 << server_ids.size() <<
"), exactly 1 expected in message "
2060 if (server_ids.size() > 1) {
2062 <<
") server-id options received in " << pkt->getName());
2064 if (!server_ids.empty()) {
2077 uint16_t len = opt->len() - opt->getHeaderLen();
2090 getCfgSubnets6()->selectSubnet(selector);
2100 shared_ptr<ScopedCalloutHandleState> callout_handle_state(
2101 std::make_shared<ScopedCalloutHandleState>(callout_handle));
2104 ScopedEnableOptionsCopy<Pkt6> query6_options_copy(question);
2107 callout_handle->setArgument(
"query6", question);
2108 callout_handle->setArgument(
"subnet6", subnet);
2113 callout_handle->setArgument(
"subnet6collection",
2115 getCfgSubnets6()->getAll());
2117 auto const tpl(parkingLimitExceeded(
"subnet6_select"));
2118 bool const exceeded(get<0>(tpl));
2120 uint32_t
const limit(get<1>(tpl));
2125 .arg(question->getLabel());
2132 HooksManager::park(
"subnet6_select", question, [
this, question, callout_handle_state]() {
2134 boost::shared_ptr<function<void()>> callback(
2135 boost::make_shared<function<
void()>>([
this, question]()
mutable {
2138 callout_handle_state->on_completion_ = [callback]() {
2160 .arg(question->getLabel());
2173 .arg(question->getLabel());
2181 .arg(question->getLabel());
2187 callout_handle->getArgument(
"subnet6", subnet);
2193 .arg(question->getLabel())
2194 .arg(subnet->getID());
2198 .arg(question->getLabel())
2199 .arg(subnet->toText());
2203 .arg(question->getLabel());
2228 for (
auto const& opt : question->options_) {
2229 switch (opt.second->getType()) {
2232 boost::dynamic_pointer_cast<
2235 answer->addOption(answer_opt);
2241 boost::dynamic_pointer_cast<
2244 answer->addOption(answer_opt);
2269 if (ddns_params->getEnableUpdates() &&
2279 .arg(question->getLabel());
2292 .arg(question->getLabel())
2293 .arg(fqdn->toText());
2311 fqdn_resp->setDomainName(d2_mgr.qualifyName(ctx.
currentHost()->getHostname(),
2312 *ddns_params,
true),
2322 ctx.
hostname_ = fqdn_resp->getDomainName();
2329 .arg(question->getLabel())
2330 .arg(fqdn_resp->toText());
2331 answer->addOption(fqdn_resp);
2346 callout_handle->setArgument(
"query6", question);
2347 callout_handle->setArgument(
"response6", answer);
2348 callout_handle->setArgument(
"subnet6", subnet);
2349 callout_handle->setArgument(
"hostname", ctx.
hostname_);
2352 callout_handle->setArgument(
"ddns-params", ddns_params);
2358 string hook_hostname;
2359 bool hook_fwd_dns_update;
2360 bool hook_rev_dns_update;
2361 callout_handle->getArgument(
"hostname", hook_hostname);
2362 callout_handle->getArgument(
"fwd-update", hook_fwd_dns_update);
2363 callout_handle->getArgument(
"rev-update", hook_rev_dns_update);
2374 fqdn_resp = boost::dynamic_pointer_cast<Option6ClientFqdn>(answer->getOption(
D6O_CLIENT_FQDN));
2377 if (!(hook_fwd_dns_update || hook_rev_dns_update)) {
2404 <<
" encapsulating server's message must not be"
2405 <<
" NULL when creating DNS NameChangeRequest");
2418 bool do_fwd =
false;
2419 bool do_rev =
false;
2429 "client identifier is required when creating a new"
2430 " DNS NameChangeRequest");
2437 opt_fqdn->packDomainName(name_buf);
2438 const std::vector<uint8_t>& buf_vec = name_buf.getVector();
2460 bool extended_only =
false;
2462 IOAddress ia_address = iaaddr->getAddress();
2463 for (
auto const& l : ia_ctx.reused_leases_) {
2464 if (l->addr_ == ia_address) {
2465 extended_only =
true;
2470 if (extended_only) {
2477 for (
auto const& l : ia_ctx.changed_leases_) {
2479 if (l->addr_ == ia_address) {
2483 if ((l->reuseable_valid_lft_ > 0) ||
2485 (l->hostname_ == opt_fqdn->getDomainName() &&
2486 l->fqdn_fwd_ == do_fwd && l->fqdn_rev_ == do_rev))) {
2487 extended_only =
true;
2499 if (!(do_fwd || do_rev) || (extended_only)) {
2515 opt_fqdn->getDomainName(),
2516 iaaddr->getAddress().toText(),
2522 .arg(answer->getLabel())
2523 .arg(ncr->toText());
2539 getMACSources().get();
2541 for (
auto const& it : mac_sources) {
2542 hwaddr = pkt->getMAC(it);
2558 BOOST_FOREACH(
auto const& resv, resvs) {
2559 if ((resv.second.getPrefix() == lease->addr_) &&
2560 (resv.second.getPrefixLen() == lease->prefixlen_)) {
2561 return (resv.second.getPDExclude());
2568 Pool6Ptr pool = boost::dynamic_pointer_cast<Pool6>(
2571 return (pool->getPrefixExcludeOption());
2579 boost::shared_ptr<Option6IA> ia) {
2585 boost::dynamic_pointer_cast<Option6IAAddr>(ia->getOption(
D6O_IAADDR));
2588 hint = hint_opt->getAddress();
2593 .arg(query->getLabel())
2595 .arg(hint_opt ? hint.toText() :
"(no hint)");
2598 .arg(query->getLabel())
2600 .arg(hint_opt ? hint.toText() :
"(no hint)");
2620 "Server could not select subnet for"
2643 if (!leases.empty()) {
2644 lease = *leases.begin();
2658 .arg(query->getLabel())
2659 .arg(lease->addr_.toText())
2660 .arg(ia->getIAID());
2661 }
else if (lease->reuseable_valid_lft_ == 0) {
2663 .arg(query->getLabel())
2664 .arg(lease->addr_.toText())
2668 lease->valid_lft_ = lease->reuseable_valid_lft_;
2669 lease->preferred_lft_ = lease->reuseable_preferred_lft_;
2672 .arg(query->getLabel())
2673 .arg(lease->addr_.toText())
2680 "v6-ia-na-lease-reuses"),
2684 .arg(query->getLabel())
2686 .arg(lease->toText());
2689 setTeeTimes(lease->preferred_lft_, subnet, ia_rsp);
2692 lease->preferred_lft_,
2693 lease->valid_lft_));
2694 ia_rsp->addOption(addr);
2707 .arg(query->getLabel())
2708 .arg(ia->getIAID());
2710 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
2712 "Sorry, no address could be"
2721 boost::shared_ptr<Option6IA> ia) {
2728 boost::dynamic_pointer_cast<Option6IAPrefix>(ia->getOption(
D6O_IAPREFIX));
2731 hint = hint_opt->getAddress();
2736 .arg(query->getLabel())
2738 .arg(hint_opt ? hint.toText() :
"(no hint)");
2741 .arg(query->getLabel())
2743 .arg(hint_opt ? hint.toText() :
"(no hint)");
2761 "Sorry, no subnet available."));
2782 if (!leases.empty()) {
2786 uint32_t min_preferred_lft = (*leases.begin())->preferred_lft_;
2788 const bool pd_exclude_requested = requestedInORO(query,
D6O_PD_EXCLUDE);
2789 for (
auto const& l : leases) {
2795 .arg(query->getLabel())
2796 .arg(l->addr_.toText())
2797 .arg(
static_cast<int>(l->prefixlen_))
2798 .arg(ia->getIAID());
2799 }
else if (l->reuseable_valid_lft_ == 0) {
2801 .arg(query->getLabel())
2802 .arg(l->addr_.toText())
2803 .arg(
static_cast<int>(l->prefixlen_))
2807 l->valid_lft_ = l->reuseable_valid_lft_;
2808 l->preferred_lft_ = l->reuseable_preferred_lft_;
2810 .arg(query->getLabel())
2811 .arg(l->addr_.toText())
2812 .arg(
static_cast<int>(l->prefixlen_))
2819 "v6-ia-pd-lease-reuses"),
2824 if ((l->preferred_lft_ > 0) && (min_preferred_lft > l->preferred_lft_)) {
2825 min_preferred_lft = l->preferred_lft_;
2828 boost::shared_ptr<Option6IAPrefix>
2830 l->prefixlen_, l->preferred_lft_,
2832 ia_rsp->addOption(addr);
2834 if (pd_exclude_requested) {
2836 if (pd_exclude_option) {
2837 addr->addOption(pd_exclude_option);
2856 .arg(query->getLabel())
2857 .arg(ia->getIAID());
2859 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
2861 "Sorry, no prefixes could"
2870 boost::shared_ptr<Option6IA> ia) {
2873 .arg(query->getLabel())
2874 .arg(ia->getIAID());
2893 "Sorry, no known leases for this duid/iaid."));
2905 for (
auto const& it : addrs) {
2909 Option6IAAddrPtr iaaddr = boost::dynamic_pointer_cast<Option6IAAddr>(it.second);
2936 uint32_t min_preferred_lft = std::numeric_limits<uint32_t>::max();
2939 for (
auto const& l : leases) {
2940 if (l->reuseable_valid_lft_ == 0) {
2942 .arg(query->getLabel())
2943 .arg(l->addr_.toText())
2944 .arg(ia->getIAID());
2946 l->valid_lft_ = l->reuseable_valid_lft_;
2947 l->preferred_lft_ = l->reuseable_preferred_lft_;
2949 .arg(query->getLabel())
2950 .arg(l->addr_.toText())
2957 "v6-ia-na-lease-reuses"),
2962 l->addr_, l->preferred_lft_, l->valid_lft_));
2963 ia_rsp->addOption(iaaddr);
2966 if ((l->preferred_lft_ > 0) && (min_preferred_lft > l->preferred_lft_)) {
2967 min_preferred_lft = l->preferred_lft_;
2972 hints.erase(std::remove(hints.begin(), hints.end(), hint_type),
2982 if (
equalValues(query->getClientId(), l->duid_)) {
2985 ia_rsp->addOption(iaaddr);
2990 hints.erase(std::remove(hints.begin(), hints.end(), hint_type), hints.end());
2998 .arg(query->getLabel())
3010 for (
auto const& hint : hints) {
3012 hint.getAddress(), 0, 0));
3013 ia_rsp->addOption(iaaddr);
3016 if (!leases.empty()) {
3022 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
3024 "Sorry, no addresses could be"
3025 " assigned at this time."));
3034 boost::shared_ptr<Option6IA> ia) {
3037 .arg(query->getLabel())
3038 .arg(ia->getIAID());
3055 "Sorry, no known PD leases"
3056 " for this duid/iaid."));
3076 " client sending Rebind to extend lifetime of the"
3077 " prefix (DUID=" << duid->toText() <<
", IAID="
3078 << ia->getIAID() <<
")");
3090 for (
auto const& it : addrs) {
3124 const bool pd_exclude_requested = requestedInORO(query,
D6O_PD_EXCLUDE);
3128 uint32_t min_preferred_lft = std::numeric_limits<uint32_t>::max();
3130 for (
auto const& l : leases) {
3131 if (l->reuseable_valid_lft_ == 0) {
3133 .arg(query->getLabel())
3134 .arg(l->addr_.toText())
3135 .arg(
static_cast<int>(l->prefixlen_))
3136 .arg(ia->getIAID());
3138 l->valid_lft_ = l->reuseable_valid_lft_;
3139 l->preferred_lft_ = l->reuseable_preferred_lft_;
3141 .arg(query->getLabel())
3142 .arg(l->addr_.toText())
3143 .arg(
static_cast<int>(l->prefixlen_))
3150 "v6-ia-pd-lease-reuses"),
3155 l->addr_, l->prefixlen_,
3156 l->preferred_lft_, l->valid_lft_));
3157 ia_rsp->addOption(prf);
3159 if (pd_exclude_requested) {
3161 if (pd_exclude_option) {
3162 prf->addOption(pd_exclude_option);
3167 if ((l->preferred_lft_ > 0) && (l->preferred_lft_ < min_preferred_lft)) {
3168 min_preferred_lft = l->preferred_lft_;
3173 hints.erase(std::remove(hints.begin(), hints.end(), hint_type),
3183 if (
equalValues(query->getClientId(), l->duid_)) {
3185 l->prefixlen_, 0, 0));
3186 ia_rsp->addOption(prefix);
3191 hints.erase(std::remove(hints.begin(), hints.end(), hint_type), hints.end());
3196 for (
auto const& prefix : hints) {
3201 if (!prefix.getAddress().isV6Zero()) {
3203 prefix.getAddress(),
3204 prefix.getPrefixLength(),
3206 ia_rsp->addOption(prefix_opt);
3210 if (!leases.empty()) {
3217 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
3219 "Sorry, no prefixes could be"
3220 " assigned at this time."));
3241 for (
auto const& opt : query->options_) {
3242 switch (opt.second->getType()) {
3245 boost::dynamic_pointer_cast<
3248 reply->addOption(answer_opt);
3255 boost::dynamic_pointer_cast<
3258 reply->addOption(answer_opt);
3293 for (
auto const& opt : release->options_) {
3295 switch (opt.second->getType()) {
3298 boost::dynamic_pointer_cast<Option6IA>(opt.second),
3301 reply->addOption(answer_opt);
3307 boost::dynamic_pointer_cast<Option6IA>(opt.second),
3310 reply->addOption(answer_opt);
3327 reply->addOption(createStatusCode(*release, general_status,
3328 "Summary status for all processed IA_NAs"));
3333 int& general_status, boost::shared_ptr<Option6IA> ia,
3337 .arg(query->getLabel())
3338 .arg(ia->getIAID());
3354 if (!release_addr) {
3356 "You did not include an address in your RELEASE"));
3362 release_addr->getAddress());
3369 "Sorry, no known leases for this duid/iaid, can't release."));
3375 if (!lease->duid_) {
3381 .arg(query->getLabel())
3382 .arg(release_addr->getAddress().toText());
3386 "Database consistency check failed when trying to RELEASE"));
3390 if (*duid != *(lease->duid_)) {
3394 .arg(query->getLabel())
3395 .arg(release_addr->getAddress().toText())
3396 .arg(lease->duid_->toText());
3400 "This address does not belong to you, you can't release it"));
3404 if (ia->getIAID() != lease->iaid_) {
3407 .arg(query->getLabel())
3408 .arg(release_addr->getAddress().toText())
3410 .arg(ia->getIAID());
3412 "This is your address, but you used wrong IAID"));
3432 ScopedEnableOptionsCopy<Pkt6> query6_options_copy(query);
3435 callout_handle->deleteAllArguments();
3438 callout_handle->setArgument(
"query6", query);
3441 callout_handle->setArgument(
"lease6", lease);
3453 .arg(query->getLabel());
3458 bool success =
false;
3459 bool expired =
false;
3460 auto expiration_cfg =
CfgMgr::instance().getCurrentCfg()->getCfgExpiration();
3466 if (expiration_cfg->getFlushReclaimedTimerWaitTime() &&
3467 expiration_cfg->getHoldReclaimedTime() &&
3470 lease->valid_lft_ = 0;
3471 lease->preferred_lft_ = 0;
3491 "Server failed to release a lease"));
3494 .arg(query->getLabel())
3495 .arg(lease->addr_.toText())
3504 .arg(query->getLabel())
3505 .arg(lease->addr_.toText())
3508 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
STATUS_Success,
3509 "Lease released. Thank you, please come again."));
3513 .arg(query->getLabel())
3514 .arg(lease->addr_.toText())
3518 .arg(query->getLabel())
3519 .arg(lease->addr_.toText())
3531 static_cast<int64_t
>(-1));
3533 auto const& subnet =
CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getBySubnetId(lease->subnet_id_);
3535 auto const& pool = subnet->getPool(
Lease::TYPE_NA, lease->addr_,
false);
3540 static_cast<int64_t
>(-1));
3550 int& general_status, boost::shared_ptr<Option6IA> ia,
3565 boost::shared_ptr<Option6IAPrefix> release_prefix =
3566 boost::dynamic_pointer_cast<Option6IAPrefix>(ia->getOption(
D6O_IAPREFIX));
3567 if (!release_prefix) {
3569 "You did not include a prefix in your RELEASE"));
3575 release_prefix->getAddress());
3582 "Sorry, no known leases for this duid/iaid, can't release."));
3588 if (!lease->duid_) {
3593 .arg(query->getLabel())
3594 .arg(release_prefix->getAddress().toText())
3595 .arg(
static_cast<int>(release_prefix->getLength()));
3599 "Database consistency check failed when trying to RELEASE"));
3603 if (*duid != *(lease->duid_)) {
3606 .arg(query->getLabel())
3607 .arg(release_prefix->getAddress().toText())
3608 .arg(
static_cast<int>(release_prefix->getLength()))
3609 .arg(lease->duid_->toText());
3613 "This address does not belong to you, you can't release it"));
3617 if (ia->getIAID() != lease->iaid_) {
3620 .arg(query->getLabel())
3621 .arg(release_prefix->getAddress().toText())
3622 .arg(
static_cast<int>(release_prefix->getLength()))
3624 .arg(ia->getIAID());
3626 "This is your address, but you used wrong IAID"));
3646 ScopedEnableOptionsCopy<Pkt6> query6_options_copy(query);
3649 callout_handle->setArgument(
"query6", query);
3652 callout_handle->setArgument(
"lease6", lease);
3664 .arg(query->getLabel());
3669 bool success =
false;
3670 bool expired =
false;
3671 auto expiration_cfg =
CfgMgr::instance().getCurrentCfg()->getCfgExpiration();
3677 if (expiration_cfg->getFlushReclaimedTimerWaitTime() &&
3678 expiration_cfg->getHoldReclaimedTime() &&
3681 lease->valid_lft_ = 0;
3682 lease->preferred_lft_ = 0;
3702 "Server failed to release a lease"));
3705 .arg(query->getLabel())
3706 .arg(lease->addr_.toText())
3707 .arg(
static_cast<int>(lease->prefixlen_))
3715 .arg(query->getLabel())
3716 .arg(lease->addr_.toText())
3717 .arg(
static_cast<int>(lease->prefixlen_))
3720 ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
STATUS_Success,
3721 "Lease released. Thank you, please come again."));
3725 .arg(query->getLabel())
3726 .arg(lease->addr_.toText())
3727 .arg(
static_cast<int>(lease->prefixlen_))
3731 .arg(query->getLabel())
3732 .arg(lease->addr_.toText())
3733 .arg(
static_cast<int>(lease->prefixlen_))
3740 static_cast<int64_t
>(-1));
3742 auto const& subnet =
CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getBySubnetId(lease->subnet_id_);
3744 auto const& pool = subnet->getPool(
Lease::TYPE_PD, lease->addr_,
false);
3749 static_cast<int64_t
>(-1));
3766 if (opt_rapid_commit) {
3769 .arg(solicit->getLabel());
3774 response->addOption(opt_rapid_commit);
3807 .arg(solicit->getLabel())
3808 .arg(solicit->getName())
3809 .arg(solicit->getClasses().toText());
3818 updateReservedFqdn(ctx, response);
3851 .arg(request->getLabel())
3852 .arg(request->getName())
3853 .arg(request->getClasses().toText());
3862 updateReservedFqdn(ctx, reply);
3863 generateFqdn(reply, ctx);
3891 .arg(renew->getLabel())
3892 .arg(renew->getName())
3893 .arg(renew->getClasses().toText());
3902 updateReservedFqdn(ctx, reply);
3903 generateFqdn(reply, ctx);
3931 .arg(rebind->getLabel())
3932 .arg(rebind->getName())
3933 .arg(rebind->getClasses().toText());
3942 updateReservedFqdn(ctx, reply);
3943 generateFqdn(reply, ctx);
3958 .arg(confirm->getLabel())
3959 .arg(confirm->getName())
3960 .arg(confirm->getClasses().toText());
3981 bool verified =
false;
3990 for (
auto const& ia : ias) {
3992 for (
auto const& opt : opts) {
4004 if (subnet && !subnet->inRange(iaaddr->getAddress())) {
4005 std::ostringstream status_msg;
4006 status_msg <<
"Address " << iaaddr->
getAddress()
4007 <<
" is not on link.";
4008 reply->addOption(createStatusCode(*confirm,
4016 " to the Option6IAAddrPtr. This is programming"
4017 " error and should be reported");
4034 "All addresses are on-link"));
4037 "No subnet selected"));
4052 .arg(release->getLabel())
4053 .arg(release->getName())
4054 .arg(release->getClasses().toText());
4084 .arg(decline->getLabel())
4085 .arg(decline->getName())
4086 .arg(decline->getClasses().toText());
4125 for (
auto const& opt : decline->options_) {
4126 switch (opt.second->getType()) {
4129 boost::dynamic_pointer_cast<Option6IA>(opt.second),
4134 reply->addOption(answer_opt);
4155 int& general_status, boost::shared_ptr<Option6IA> ia,
4159 .arg(decline->getLabel())
4160 .arg(ia->getIAID());
4175 int total_addrs = 0;
4176 for (
auto const& opt : opts) {
4185 if (!decline_addr) {
4192 decline_addr->getAddress());
4197 .arg(decline->getLabel()).arg(decline_addr->getAddress().toText());
4205 "Server does not know about such an address."));
4213 if (!lease->duid_) {
4219 .arg(decline->getLabel())
4220 .arg(decline_addr->getAddress().toText());
4223 "Database consistency check failed when attempting Decline."));
4229 if (*duid != *(lease->duid_)) {
4233 .arg(decline->getLabel())
4234 .arg(decline_addr->getAddress().toText())
4235 .arg(lease->duid_->toText());
4238 "This address does not belong to you, you can't decline it"));
4244 if (ia->getIAID() != lease->iaid_) {
4247 .arg(decline->getLabel())
4248 .arg(lease->addr_.toText())
4252 "This is your address, but you used wrong IAID"));
4264 new_leases.push_back(lease);
4268 if (total_addrs == 0) {
4270 "No addresses sent in IA_NA"));
4283 container->addOption(status);
4288 boost::shared_ptr<Option6IA> ia_rsp) {
4309 ScopedEnableOptionsCopy<Pkt6> query6_options_copy(decline);
4312 callout_handle->setArgument(
"query6", decline);
4315 callout_handle->setArgument(
"lease6", lease);
4326 .arg(decline->getLabel())
4327 .arg(decline->getIface())
4328 .arg(lease->addr_.toText());
4336 .arg(decline->getLabel())
4337 .arg(decline->getIface())
4338 .arg(lease->addr_.toText());
4343 Lease6Ptr old_values = boost::make_shared<Lease6>(*lease);
4357 .arg(decline->getLabel())
4358 .arg(lease->addr_.toText())
4371 static_cast<int64_t
>(1));
4373 auto const& subnet =
CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getBySubnetId(lease->subnet_id_);
4375 auto const& pool = subnet->getPool(
Lease::TYPE_NA, lease->addr_,
false);
4380 static_cast<int64_t
>(1));
4388 .arg(lease->addr_.toText()).arg(lease->valid_lft_);
4390 ia_rsp->addOption(createStatusCode(*decline, *ia_rsp,
STATUS_Success,
4391 "Lease declined. Hopefully the next one will be better."));
4405 .arg(inf_request->getLabel())
4406 .arg(inf_request->getName())
4407 .arg(inf_request->getClasses().toText());
4456void Dhcpv6Srv::classifyByVendor(
const Pkt6Ptr& pkt) {
4459 vclass = boost::dynamic_pointer_cast<OptionVendorClass>(opt.second);
4460 if (!vclass || vclass->getTuplesNum() == 0) {
4478 pkt->addClass(
"ALL");
4481 classifyByVendor(pkt);
4492 for (
auto const& it : *defs_ptr) {
4500 if (it->getAdditional()) {
4504 if (it->getDependOnKnown() != depend_on_known) {
4507 it->test(pkt, expr_ptr);
4516 for (
auto const& def : *defs_ptr) {
4520 if (def->getMatchExpr()) {
4521 pkt->classes_.erase(def->getName());
4531 for (
auto const& cclass : classes) {
4532 pkt->addClass(cclass);
4542 ctx.
subnet_->getSharedNetwork(shared_network);
4543 if (shared_network) {
4545 if (host && (host->getIPv6SubnetID() != SUBNET_ID_GLOBAL)) {
4564 ctx.
subnet_->getPool(resource.getPrefixLength() == 128 ?
4566 resource.getAddress(),
4569 const ClientClasses& pool_to_add = pool->getAdditionalClasses();
4570 for (
auto const& cclass : pool_to_add) {
4577 const ClientClasses& to_add = subnet->getAdditionalClasses();
4578 for (
auto const& cclass : to_add) {
4584 subnet->getSharedNetwork(network);
4586 const ClientClasses& net_to_add = network->getAdditionalClasses();
4587 for (
auto const& cclass : net_to_add) {
4597 for (
auto const& cclass : classes) {
4612 pkt->addClass(cclass);
4620 .arg(pkt->getLabel())
4622 .arg(status ?
"true" :
"false");
4625 pkt->addClass(cclass);
4629 .arg(pkt->getLabel())
4641 " a message must not be NULL when updating reserved FQDN");
4652 std::string name = fqdn->getDomainName();
4664 if (new_name != name) {
4669 answer->addOption(fqdn);
4675Dhcpv6Srv::generateFqdn(
const Pkt6Ptr& answer,
4679 " a message must not be NULL when generating FQDN");
4690 if (!fqdn || !fqdn->getDomainName().empty()) {
4704 if (!iaaddr || iaaddr->getValid() == 0) {
4710 std::string generated_name =
4714 .arg(answer->getLabel())
4715 .arg(generated_name);
4725 for (
auto const& l : ctx.new_leases_) {
4732 lease->hostname_ = generated_name;
4733 lease->reuseable_valid_lft_ = 0;
4738 " for address " << addr <<
", so as it is impossible"
4739 " to update FQDN data. This is a programmatic error"
4740 " as the given address is now being handed to the"
4748 answer->addOption(fqdn);
4752 .arg(answer->getLabel())
4761 if (d2_mgr.ddnsEnabled()) {
4766 this, ph::_1, ph::_2));
4773 if (d2_mgr.ddnsEnabled()) {
4776 d2_mgr.stopSender();
4785 arg(result).arg((ncr ? ncr->toText() :
" NULL "));
4794 std::stringstream tmp;
4798 tmp <<
" (" << EXTENDED_VERSION <<
")" << endl;
4799 tmp <<
"premium: " << PREMIUM_EXTENDED_VERSION << endl;
4800 tmp <<
"linked with:" << endl;
4805 tmp << endl <<
"lease backends:";
4807 tmp << endl <<
"- " <<
version;
4812 tmp << endl <<
"host backends:";
4814 tmp << endl <<
"- " <<
version;
4825 if (query->relay_info_.empty()) {
4836 for (
int i = query->relay_info_.size(); i > 0 ; --i) {
4838 if (rsoo_container) {
4843 for (
auto const& opt : rsoo) {
4847 if (cfg_rsoo->enabled(opt.second->getType()) &&
4848 !rsp->getOption(opt.second->getType())) {
4849 rsp->addOption(opt.second);
4858 if (query->relay_info_.empty()) {
4866 return (query->getRemotePort());
4872void Dhcpv6Srv::processStatsReceived(
const Pkt6Ptr& query) {
4876 string stat_name =
"pkt6-unknown-received";
4877 switch (query->getType()) {
4879 stat_name =
"pkt6-solicit-received";
4883 stat_name =
"pkt6-advertise-received";
4886 stat_name =
"pkt6-request-received";
4889 stat_name =
"pkt6-confirm-received";
4892 stat_name =
"pkt6-renew-received";
4895 stat_name =
"pkt6-rebind-received";
4899 stat_name =
"pkt6-reply-received";
4902 stat_name =
"pkt6-release-received";
4905 stat_name =
"pkt6-decline-received";
4908 stat_name =
"pkt6-reconfigure-received";
4911 stat_name =
"pkt6-infrequest-received";
4914 stat_name =
"pkt6-dhcpv4-query-received";
4918 stat_name =
"pkt6-dhcpv4-response-received";
4933 switch (response->getType()) {
4935 stat_name =
"pkt6-advertise-sent";
4938 stat_name =
"pkt6-reply-sent";
4941 stat_name =
"pkt6-dhcpv4-response-sent";
4952 return (
Hooks.hook_index_buffer6_send_);
4956Dhcpv6Srv::requestedInORO(
const Pkt6Ptr& query,
const uint16_t code)
const {
4958 boost::dynamic_pointer_cast<OptionUint16Array>(query->getOption(
D6O_ORO));
4961 const std::vector<uint16_t>& codes = oro->getValues();
4962 return (std::find(codes.begin(), codes.end(), code) != codes.end());
4968tuple<bool, uint32_t>
4969Dhcpv6Srv::parkingLimitExceeded(
string const& hook_label) {
4971 uint32_t parked_packet_limit(0);
4975 parked_packet_limit = ppl->intValue();
4978 if (parked_packet_limit) {
4982 if (parking_lot && parked_packet_limit <= parking_lot->size()) {
4983 return make_tuple(
true, parked_packet_limit);
4986 return make_tuple(
false, parked_packet_limit);
4997 char const*
const rotate(getenv(
"KEA_DHCP6_FUZZING_ROTATE_PORT"));
5001 while (!locker.lock()) {
5002 this_thread::sleep_for(1s);
5005 port_file.open(
"/tmp/port6.txt", ios::in);
5008 getline(port_file, line);
5020 port_file.open(
"/tmp/port6.txt", ios::out | ios::trunc);
5021 port_file << to_string(port) << endl;
5036 uint32_t t2_time = 0;
5039 if (!subnet->getT2().unspecified()) {
5040 t2_time = subnet->getT2();
5041 }
else if (subnet->getCalculateTeeTimes()) {
5043 t2_time =
static_cast<uint32_t
>(round(subnet->getT2Percent() * preferred_lft));
5047 resp->setT2(t2_time);
5050 uint32_t t1_time = 0;
5053 if (!subnet->getT1().unspecified()) {
5054 t1_time = subnet->getT1();
5055 }
else if (subnet->getCalculateTeeTimes()) {
5057 t1_time =
static_cast<uint32_t
>(round(subnet->getT1Percent() * preferred_lft));
5061 if (t1_time < t2_time) {
5062 resp->setT1(t1_time);
5074 if ((!ctx.
subnet_) || (!orig_subnet) || (orig_subnet->getID() == ctx.
subnet_->getID())) {
5082 orig_subnet->getSharedNetwork(network);
5084 .arg(question->getLabel())
5085 .arg(orig_subnet->toText())
5087 .arg(network ? network->getName() :
"<no network?>");
5093 std::string prev_hostname = ctx.
hostname_;
5114 l->reuseable_valid_lft_ = 0;
5121 static std::list<std::list<std::string>>
const list({
5122 {
"config-control",
"config-databases",
"[]"},
5123 {
"hooks-libraries",
"[]",
"parameters",
"*"},
5125 {
"hosts-databases",
"[]"},
int version()
returns Kea hooks version.
Defines elements for storing the names of client classes.
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 HttpCommandMgr & instance()
HttpCommandMgr is a singleton 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 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 evaluateAdditionalClasses(const Pkt6Ptr &pkt, AllocEngine::ClientContext6 &ctx)
Evaluates classes in the additional classes lists.
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.
uint16_t getServerPort() const
Get UDP port on which server should listen.
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.
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 setTeeTimes(uint32_t preferred_lft, const ConstSubnet6Ptr &subnet, Option6IAPtr &resp)
Sets the T1 and T2 timers in the outbound IA.
void conditionallySetReservedClientClasses(const Pkt6Ptr &pkt, const AllocEngine::ClientContext6 &ctx)
Assigns classes retrieved from host reservation database if they haven't been yet set.
void checkDynamicSubnetChange(const Pkt6Ptr &question, Pkt6Ptr &answer, AllocEngine::ClientContext6 &ctx, const ConstSubnet6Ptr orig_subnet)
Iterates over new leases, update stale DNS entries.
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 initContext(AllocEngine::ClientContext6 &ctx, bool &drop)
Initializes client context for specified packet.
Pkt6Ptr processRequest(AllocEngine::ClientContext6 &ctx)
Processes incoming Request and returns Reply response.
void sendResponseNoThrow(hooks::CalloutHandlePtr &callout_handle, Pkt6Ptr query, Pkt6Ptr &rsp, ConstSubnet6Ptr &subnet)
Process an unparked DHCPv6 packet and sends the 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 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.
void processPacketPktSend(hooks::CalloutHandlePtr &callout_handle, Pkt6Ptr &query, Pkt6Ptr &rsp, ConstSubnet6Ptr &subnet)
Executes pkt6_send callout.
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.
isc::dhcp::ConstSubnet6Ptr selectSubnet(const Pkt6Ptr &question, bool &drop)
Selects a subnet for a given client's packet.
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....
OptionPtr getPDExclude(const AllocEngine::ClientContext6 &ctx, const Lease6Ptr &lease)
Return the PD exclude option to include.
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.
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.
static std::list< std::string > getDBVersions()
Return extended version info for registered backends.
static void create()
Creates new instance of the HostMgr.
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 std::list< std::string > getDBVersions()
Return extended version info for registered backends.
static void destroy()
Destroy lease manager.
static void splitNtpServerOptions6(isc::dhcp::OptionCollection &options)
Split NTP server option to one suboption per instance.
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.
Represents a DHCPv6 packet.
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.
File-based Interprocess Sync Class.
Interprocess Sync Locker Class.
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.
Defines classes for storing client class definitions.
Defines the D2ClientConfig class.
Defines the D2ClientMgr class.
@ 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
When a message is logged with DEBUG severity, the debug level associated with the message is also spe...
#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_ADDITIONAL_CLASS_NO_TEST
const isc::log::MessageID DHCP6_ADDITIONAL_CLASS_EVAL_RESULT
const isc::log::MessageID DHCP6_RELEASE_PD_DELETED
const isc::log::MessageID DHCP6_LEASE_ALLOC
const isc::log::MessageID DHCP6_FLEX_ID
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_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_ADDITIONAL_CLASS_UNDEFINED
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
const isc::log::MessageID DHCP6_BUFFER_UNPACK
boost::shared_ptr< const Subnet6 > ConstSubnet6Ptr
A const pointer to a Subnet6 object.
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
const isc::log::MessageID DHCP6_ADDITIONAL_CLASS_EVAL_ERROR
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.
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
std::pair< IPv6ResrvIterator, IPv6ResrvIterator > IPv6ResrvRange
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< const Subnet > ConstSubnetPtr
A generic pointer to either const Subnet4 or const Subnet6 object.
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_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 defines abstract classes for exchanging NameChangeRequests.
This file provides the classes needed to embody, compose, and decompose DNS update requests that are ...
Standard implementation of read-write mutexes with writer preference using C++11 mutex and condition ...
#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)
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.
Lease6Collection reused_leases_
Set of leases marked for reuse by lease caching.
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.
std::vector< IAContext > & getIAContexts()
HWAddrPtr hwaddr_
Hardware/MAC address (if available, may be NULL)
hooks::CalloutHandlePtr callout_handle_
Callout handle associated with the client's message.
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.
ConstSubnet6Ptr subnet_
Subnet selected for the client by the server.
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_DEFAULT
A lease in the default state.
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.