33 #include <boost/scoped_ptr.hpp>
34 #include <boost/algorithm/string.hpp>
49 namespace lease_cmds {
92 if (txt ==
"address") {
93 return (Parameters::TYPE_ADDR);
94 }
else if (txt ==
"hw-address") {
95 return (Parameters::TYPE_HWADDR);
96 }
else if (txt ==
"duid") {
97 return (Parameters::TYPE_DUID);
98 }
else if (txt ==
"client-id") {
99 return (Parameters::TYPE_CLIENT_ID);
102 << txt <<
", the only supported values are: "
103 "address, hw-address, duid");
121 : subnet_id(0), addr(
"::"), query_type(TYPE_ADDR),
122 lease_type(
Lease::TYPE_NA), iaid(0), updateDDNS(false) {
359 Lease6Ptr getIPv6LeaseForDelete(
const Parameters& parameters)
const;
378 const int control_result,
379 const std::string& error_message)
const;
392 short family = AF_INET)
const;
397 static void updateStatsOnAdd(
const Lease4Ptr& lease);
402 static void updateStatsOnAdd(
const Lease6Ptr& lease);
408 static void updateStatsOnUpdate(
const Lease4Ptr& existing,
415 static void updateStatsOnUpdate(
const Lease6Ptr& existing,
421 static void updateStatsOnDelete(
const Lease4Ptr& lease);
426 static void updateStatsOnDelete(
const Lease6Ptr& lease);
436 static bool addOrUpdate4(
Lease4Ptr lease,
bool force_create);
446 static bool addOrUpdate6(
Lease6Ptr lease,
bool force_create);
450 LeaseCmdsImpl::updateStatsOnAdd(
const Lease4Ptr& lease) {
451 if (!lease->stateExpiredReclaimed()) {
452 StatsMgr::instance().addValue(
453 StatsMgr::generateName(
"subnet", lease->subnet_id_,
454 "assigned-addresses"),
456 if (lease->stateDeclined()) {
457 StatsMgr::instance().addValue(
"declined-addresses", int64_t(1));
459 StatsMgr::instance().addValue(
460 StatsMgr::generateName(
"subnet", lease->subnet_id_,
461 "declined-addresses"),
468 LeaseCmdsImpl::updateStatsOnAdd(
const Lease6Ptr& lease) {
469 if (!lease->stateExpiredReclaimed()) {
470 StatsMgr::instance().addValue(
471 StatsMgr::generateName(
"subnet", lease->subnet_id_,
473 "assigned-nas" :
"assigned-pds"),
475 if (lease->stateDeclined()) {
476 StatsMgr::instance().addValue(
"declined-addresses", int64_t(1));
478 StatsMgr::instance().addValue(
479 StatsMgr::generateName(
"subnet", lease->subnet_id_,
480 "declined-addresses"),
487 LeaseCmdsImpl::updateStatsOnUpdate(
const Lease4Ptr& existing,
489 if (!existing->stateExpiredReclaimed()) {
491 if (existing->subnet_id_ != lease->subnet_id_) {
492 StatsMgr::instance().addValue(
493 StatsMgr::generateName(
"subnet", existing->subnet_id_,
494 "assigned-addresses"),
497 if (existing->stateDeclined()) {
499 StatsMgr::instance().addValue(
"declined-addresses", int64_t(-1));
501 StatsMgr::instance().addValue(
502 StatsMgr::generateName(
"subnet", existing->subnet_id_,
503 "declined-addresses"),
506 if (!lease->stateExpiredReclaimed()) {
508 if (existing->subnet_id_ != lease->subnet_id_) {
509 StatsMgr::instance().addValue(
510 StatsMgr::generateName(
"subnet", lease->subnet_id_,
511 "assigned-addresses"),
514 if (lease->stateDeclined()) {
516 StatsMgr::instance().addValue(
"declined-addresses", int64_t(1));
518 StatsMgr::instance().addValue(
519 StatsMgr::generateName(
"subnet", lease->subnet_id_,
520 "declined-addresses"),
526 if (!lease->stateExpiredReclaimed()) {
528 StatsMgr::instance().addValue(
529 StatsMgr::generateName(
"subnet", lease->subnet_id_,
530 "assigned-addresses"),
532 if (lease->stateDeclined()) {
534 StatsMgr::instance().addValue(
"declined-addresses", int64_t(1));
536 StatsMgr::instance().addValue(
537 StatsMgr::generateName(
"subnet", lease->subnet_id_,
538 "declined-addresses"),
546 LeaseCmdsImpl::updateStatsOnUpdate(
const Lease6Ptr& existing,
548 if (!existing->stateExpiredReclaimed()) {
550 if (existing->subnet_id_ != lease->subnet_id_) {
551 StatsMgr::instance().addValue(
552 StatsMgr::generateName(
"subnet", existing->subnet_id_,
554 "assigned-nas" :
"assigned-pds"),
557 if (existing->stateDeclined()) {
559 StatsMgr::instance().addValue(
"declined-addresses", int64_t(-1));
561 StatsMgr::instance().addValue(
562 StatsMgr::generateName(
"subnet", existing->subnet_id_,
563 "declined-addresses"),
566 if (!lease->stateExpiredReclaimed()) {
568 if (existing->subnet_id_ != lease->subnet_id_) {
569 StatsMgr::instance().addValue(
570 StatsMgr::generateName(
"subnet", lease->subnet_id_,
572 "assigned-nas" :
"assigned-pds"),
575 if (lease->stateDeclined()) {
577 StatsMgr::instance().addValue(
"declined-addresses", int64_t(1));
579 StatsMgr::instance().addValue(
580 StatsMgr::generateName(
"subnet", lease->subnet_id_,
581 "declined-addresses"),
587 if (!lease->stateExpiredReclaimed()) {
589 StatsMgr::instance().addValue(
590 StatsMgr::generateName(
"subnet", lease->subnet_id_,
592 "assigned-nas" :
"assigned-pds"),
594 if (lease->stateDeclined()) {
596 StatsMgr::instance().addValue(
"declined-addresses", int64_t(1));
598 StatsMgr::instance().addValue(
599 StatsMgr::generateName(
"subnet", lease->subnet_id_,
600 "declined-addresses"),
608 LeaseCmdsImpl::updateStatsOnDelete(
const Lease4Ptr& lease) {
609 if (!lease->stateExpiredReclaimed()) {
610 StatsMgr::instance().addValue(
611 StatsMgr::generateName(
"subnet", lease->subnet_id_,
612 "assigned-addresses"),
614 if (lease->stateDeclined()) {
615 StatsMgr::instance().addValue(
"declined-addresses", int64_t(-1));
617 StatsMgr::instance().addValue(
618 StatsMgr::generateName(
"subnet", lease->subnet_id_,
619 "declined-addresses"),
626 LeaseCmdsImpl::updateStatsOnDelete(
const Lease6Ptr& lease) {
627 if (!lease->stateExpiredReclaimed()) {
628 StatsMgr::instance().addValue(
629 StatsMgr::generateName(
"subnet", lease->subnet_id_,
631 "assigned-nas" :
"assigned-pds"),
633 if (lease->stateDeclined()) {
634 StatsMgr::instance().addValue(
"declined-addresses", int64_t(-1));
636 StatsMgr::instance().addValue(
637 StatsMgr::generateName(
"subnet", lease->subnet_id_,
638 "declined-addresses"),
645 LeaseCmdsImpl::addOrUpdate4(
Lease4Ptr lease,
bool force_create) {
647 if (force_create && !existing) {
651 "lost race between calls to get and add");
653 LeaseCmdsImpl::updateStatsOnAdd(lease);
666 << lease->addr_ <<
" either because the lease has been "
667 "deleted or it has changed in the database, in both cases a "
668 "retry might succeed");
671 LeaseCmdsImpl::updateStatsOnUpdate(existing, lease);
676 LeaseCmdsImpl::addOrUpdate6(
Lease6Ptr lease,
bool force_create) {
679 if (force_create && !existing) {
683 "lost race between calls to get and add");
685 LeaseCmdsImpl::updateStatsOnAdd(lease);
698 << lease->addr_ <<
" either because the lease has been "
699 "deleted or it has changed in the database, in both cases a "
700 "retry might succeed");
703 LeaseCmdsImpl::updateStatsOnUpdate(existing, lease);
712 string txt =
"malformed command";
716 extractCommand(handle);
717 v4 = (cmd_name_ ==
"lease4-add");
719 txt =
"(missing parameters)";
724 txt = cmd_args_->str();
731 bool force_create =
false;
734 lease4 = parser.
parse(config, cmd_args_, force_create);
738 if (MultiThreadingMgr::instance().getMode() &&
739 !MultiThreadingMgr::instance().isInCriticalSection()) {
744 use_cs = !resource_handler.
tryLock4(lease4->addr_);
761 LeaseCmdsImpl::updateStatsOnAdd(lease4);
762 resp <<
"Lease for address " << lease4->addr_.toText()
763 <<
", subnet-id " << lease4->subnet_id_ <<
" added.";
768 lease6 = parser.
parse(config, cmd_args_, force_create);
772 if (MultiThreadingMgr::instance().getMode() &&
773 !MultiThreadingMgr::instance().isInCriticalSection()) {
778 use_cs = !resource_handler.
tryLock(lease6->type_,
796 LeaseCmdsImpl::updateStatsOnAdd(lease6);
798 resp <<
"Lease for address " << lease6->addr_.toText()
799 <<
", subnet-id " << lease6->subnet_id_ <<
" added.";
801 resp <<
"Lease for prefix " << lease6->addr_.toText()
802 <<
"/" <<
static_cast<int>(lease6->prefixlen_)
803 <<
", subnet-id " << lease6->subnet_id_ <<
" added.";
808 }
catch (
const std::exception& ex) {
812 setErrorResponse(handle, ex.what());
818 setSuccessResponse(handle, resp.str());
826 if (!params || params->getType() != Element::map) {
830 if (params->contains(
"update-ddns")) {
832 if (tmp->getType() != Element::boolean) {
843 if (params->contains(
"type")) {
844 string t = params->get(
"type")->stringValue();
845 if (t ==
"IA_NA" || t ==
"0") {
847 }
else if (t ==
"IA_TA" || t ==
"1") {
849 }
else if (t ==
"IA_PD" || t ==
"2") {
851 }
else if (t ==
"V4" || t ==
"3") {
855 << t <<
", only supported values are: IA_NA, IA_TA,"
862 if (tmp->getType() != Element::string) {
870 txt <<
"Invalid " << (v6 ?
"IPv6" :
"IPv4")
871 <<
" address specified: " << tmp->stringValue();
879 tmp = params->get(
"subnet-id");
883 if (tmp->getType() != Element::integer) {
888 if (params->contains(
"iaid")) {
889 x.
iaid = params->get(
"iaid")->intValue();
898 if (!type || type->getType() != Element::string) {
900 " and 'identifier-type' is either missing or not a string.");
902 if (!ident || ident->getType() != Element::string) {
904 " and 'identifier' is either missing or not a string.");
909 x.
query_type = Parameters::txtToType(type->stringValue());
912 case Parameters::TYPE_HWADDR: {
917 case Parameters::TYPE_CLIENT_ID: {
921 case Parameters::TYPE_DUID: {
926 case Parameters::TYPE_ADDR: {
933 " is not supported.");
947 extractCommand(handle);
948 v4 = (cmd_name_ ==
"lease4-get");
950 p = getParameters(!v4, cmd_args_);
952 case Parameters::TYPE_ADDR: {
961 case Parameters::TYPE_HWADDR:
965 "requires hwaddr to be specified");
974 case Parameters::TYPE_DUID:
978 "requires duid to be specified");
988 case Parameters::TYPE_CLIENT_ID:
992 "requires client-id to be specified");
1006 }
catch (
const std::exception& ex) {
1007 setErrorResponse(handle, ex.what());
1013 lease_json = lease4->toElement();
1015 "IPv4 lease found.", lease_json);
1016 setResponse(handle, response);
1017 }
else if (!v4 && lease6) {
1018 lease_json = lease6->toElement();
1020 "IPv6 lease found.", lease_json);
1021 setResponse(handle, response);
1034 extractCommand(handle);
1035 v4 = (cmd_name_ ==
"lease4-get-all");
1037 ElementPtr leases_json = Element::createList();
1046 if (subnets->getType() != Element::list) {
1050 const std::vector<ElementPtr>& subnet_ids = subnets->listValue();
1051 for (
auto subnet_id = subnet_ids.begin();
1052 subnet_id != subnet_ids.end();
1054 if ((*subnet_id)->getType() != Element::integer) {
1061 for (
auto lease : leases) {
1063 leases_json->add(lease_json);
1068 for (
auto lease : leases) {
1070 leases_json->add(lease_json);
1079 for (
auto lease : leases) {
1081 leases_json->add(lease_json);
1085 for (
auto lease : leases) {
1087 leases_json->add(lease_json);
1092 std::ostringstream s;
1093 s << leases_json->size()
1094 <<
" IPv" << (v4 ?
"4" :
"6")
1095 <<
" lease(s) found.";
1097 args->set(
"leases", leases_json);
1103 setResponse(handle, response);
1105 }
catch (
const std::exception& ex) {
1106 setErrorResponse(handle, ex.what());
1117 extractCommand(handle);
1118 v4 = (cmd_name_ ==
"lease4-get-page");
1135 if (from->getType() != Element::string) {
1139 boost::scoped_ptr<IOAddress> from_address;
1141 if (from->stringValue() ==
"start") {
1142 from_address.reset(
new IOAddress(v4 ?
"0.0.0.0" :
"::"));
1146 from_address.reset(
new IOAddress(from->stringValue()));
1151 "a valid IPv" << (v4 ?
"4" :
"6") <<
" address");
1156 if (v4 && (!from_address->isV4())) {
1158 <<
" is not an IPv4 address");
1160 }
else if (!v4 && from_address->isV4()) {
1162 <<
" is not an IPv6 address");
1172 if (page_limit->getType() != Element::integer) {
1177 size_t page_limit_value =
static_cast<size_t>(page_limit->intValue());
1179 ElementPtr leases_json = Element::createList();
1188 for (
auto lease : leases) {
1190 leases_json->add(lease_json);
1199 for (
auto lease : leases) {
1201 leases_json->add(lease_json);
1206 std::ostringstream s;
1207 s << leases_json->size()
1208 <<
" IPv" << (v4 ?
"4" :
"6")
1209 <<
" lease(s) found.";
1213 args->set(
"leases", leases_json);
1214 args->set(
"count", Element::create(static_cast<int64_t>(leases_json->size())));
1222 setResponse(handle, response);
1224 }
catch (
const std::exception& ex) {
1225 setErrorResponse(handle, ex.what());
1235 extractCommand(handle);
1238 if (!cmd_args_ || (cmd_args_->getType() != Element::map)) {
1249 if (hw_address->getType() != Element::string) {
1257 ElementPtr leases_json = Element::createList();
1258 for (
auto lease : leases) {
1260 leases_json->add(lease_json);
1263 std::ostringstream s;
1264 s << leases_json->size() <<
" IPv4 lease(s) found.";
1266 args->set(
"leases", leases_json);
1272 setResponse(handle, response);
1274 }
catch (
const std::exception& ex) {
1275 setErrorResponse(handle, ex.what());
1285 extractCommand(handle);
1288 if (!cmd_args_ || (cmd_args_->getType() != Element::map)) {
1299 if (client_id->getType() != Element::string) {
1307 ElementPtr leases_json = Element::createList();
1308 for (
auto lease : leases) {
1310 leases_json->add(lease_json);
1313 std::ostringstream s;
1314 s << leases_json->size() <<
" IPv4 lease(s) found.";
1316 args->set(
"leases", leases_json);
1322 setResponse(handle, response);
1324 }
catch (
const std::exception& ex) {
1325 setErrorResponse(handle, ex.what());
1335 extractCommand(handle);
1338 if (!cmd_args_ || (cmd_args_->getType() != Element::map)) {
1349 if (duid->getType() != Element::string) {
1357 ElementPtr leases_json = Element::createList();
1358 for (
auto lease : leases) {
1360 leases_json->add(lease_json);
1363 std::ostringstream s;
1364 s << leases_json->size() <<
" IPv6 lease(s) found.";
1366 args->set(
"leases", leases_json);
1372 setResponse(handle, response);
1374 }
catch (
const std::exception& ex) {
1375 setErrorResponse(handle, ex.what());
1386 extractCommand(handle);
1387 v4 = (cmd_name_ ==
"lease4-get-by-hostname");
1390 if (!cmd_args_ || (cmd_args_->getType() != Element::map)) {
1401 if (hostname->getType() != Element::string) {
1405 std::string hostname_ = hostname->stringValue();
1407 if (hostname_.empty()) {
1410 boost::algorithm::to_lower(hostname_);
1412 ElementPtr leases_json = Element::createList();
1417 for (
auto lease : leases) {
1419 leases_json->add(lease_json);
1425 for (
auto lease : leases) {
1427 leases_json->add(lease_json);
1431 std::ostringstream s;
1432 s << leases_json->size()
1433 <<
" IPv" << (v4 ?
"4" :
"6")
1434 <<
" lease(s) found.";
1436 args->set(
"leases", leases_json);
1442 setResponse(handle, response);
1444 }
catch (
const std::exception& ex) {
1445 setErrorResponse(handle, ex.what());
1457 extractCommand(handle);
1458 p = getParameters(
false, cmd_args_);
1461 case Parameters::TYPE_ADDR: {
1470 case Parameters::TYPE_HWADDR: {
1473 "requires hwaddr to be specified");
1484 case Parameters::TYPE_CLIENT_ID: {
1487 "requires client-id to be specified");
1498 case Parameters::TYPE_DUID: {
1509 setSuccessResponse(handle,
"IPv4 lease deleted.");
1510 LeaseCmdsImpl::updateStatsOnDelete(lease4);
1520 }
catch (
const std::exception& ex) {
1521 setErrorResponse(handle, ex.what());
1531 extractCommand(handle);
1534 if (!cmd_args_ || (cmd_args_->getType() != Element::map)) {
1539 auto deleted_leases = cmd_args_->get(
"deleted-leases");
1540 auto leases = cmd_args_->get(
"leases");
1542 if (!deleted_leases && !leases) {
1548 if (deleted_leases && (deleted_leases->getType() != Element::list)) {
1553 if (leases && (leases->getType() != Element::list)) {
1560 std::list<std::pair<Parameters, Lease6Ptr> > parsed_deleted_list;
1561 if (deleted_leases) {
1562 auto leases_list = deleted_leases->listValue();
1565 for (
auto lease_params : leases_list) {
1568 Parameters p = getParameters(
true, lease_params);
1569 auto lease = getIPv6LeaseForDelete(p);
1570 parsed_deleted_list.push_back(std::make_pair(p, lease));
1576 std::list<Lease6Ptr> parsed_leases_list;
1581 auto leases_list = leases->listValue();
1582 for (
auto lease_params : leases_list) {
1589 Lease6Ptr lease6 = parser.
parse(config, lease_params, force_update);
1590 parsed_leases_list.push_back(lease6);
1595 size_t success_count = 0;
1598 if (!parsed_deleted_list.empty()) {
1601 for (
auto lease_params_pair : parsed_deleted_list) {
1606 auto lease = lease_params_pair.second;
1615 LeaseCmdsImpl::updateStatsOnDelete(lease);
1619 if (!failed_deleted_list) {
1620 failed_deleted_list = Element::createList();
1627 failed_deleted_list->add(createFailedLeaseMap(p.
lease_type,
1630 "lease not found"));
1634 }
catch (
const std::exception& ex) {
1636 if (!failed_deleted_list) {
1637 failed_deleted_list = Element::createList();
1639 failed_deleted_list->add(createFailedLeaseMap(p.
lease_type,
1649 if (!parsed_leases_list.empty()) {
1653 for (
auto lease : parsed_leases_list) {
1656 if (MultiThreadingMgr::instance().getMode() &&
1657 !MultiThreadingMgr::instance().isInCriticalSection()) {
1658 bool use_cs =
false;
1662 use_cs = !resource_handler.
tryLock(lease->type_,
1665 addOrUpdate6(lease,
true);
1671 addOrUpdate6(lease,
true);
1675 addOrUpdate6(lease,
true);
1680 }
catch (
const std::exception& ex) {
1682 if (!failed_leases_list) {
1683 failed_leases_list = Element::createList();
1685 failed_leases_list->add(createFailedLeaseMap(lease->type_,
1697 if (failed_deleted_list || failed_leases_list) {
1699 args = Element::createMap();
1702 if (failed_deleted_list) {
1703 args->set(
"failed-deleted-leases", failed_deleted_list);
1707 if (failed_leases_list) {
1708 args->set(
"failed-deleted-leases", failed_leases_list);
1713 std::ostringstream resp_text;
1714 resp_text <<
"Bulk apply of " << success_count <<
" IPv6 leases completed.";
1717 setResponse(handle, answer);
1719 }
catch (
const std::exception& ex) {
1721 setErrorResponse(handle, ex.what());
1734 extractCommand(handle);
1735 p = getParameters(
true, cmd_args_);
1738 case Parameters::TYPE_ADDR: {
1749 case Parameters::TYPE_HWADDR: {
1753 case Parameters::TYPE_DUID: {
1756 "requires duid to be specified");
1775 setSuccessResponse(handle,
"IPv6 lease deleted.");
1776 LeaseCmdsImpl::updateStatsOnDelete(lease6);
1786 }
catch (
const std::exception& ex) {
1787 setErrorResponse(handle, ex.what());
1797 extractCommand(handle);
1808 bool force_create =
false;
1812 lease4 = parser.
parse(config, cmd_args_, force_create);
1814 if (MultiThreadingMgr::instance().getMode() &&
1815 !MultiThreadingMgr::instance().isInCriticalSection()) {
1816 bool use_cs =
false;
1820 use_cs = !resource_handler.
tryLock4(lease4->addr_);
1822 added = addOrUpdate4(lease4, force_create);
1828 added = addOrUpdate4(lease4, force_create);
1832 added = addOrUpdate4(lease4, force_create);
1835 setSuccessResponse(handle,
"IPv4 lease added.");
1837 setSuccessResponse(handle,
"IPv4 lease updated.");
1839 }
catch (
const std::exception& ex) {
1840 setErrorResponse(handle, ex.what());
1850 extractCommand(handle);
1861 bool force_create =
false;
1865 lease6 = parser.
parse(config, cmd_args_, force_create);
1867 if (MultiThreadingMgr::instance().getMode() &&
1868 !MultiThreadingMgr::instance().isInCriticalSection()) {
1869 bool use_cs =
false;
1873 use_cs = !resource_handler.
tryLock(lease6->type_,
1876 added = addOrUpdate6(lease6, force_create);
1882 added = addOrUpdate6(lease6, force_create);
1886 added = addOrUpdate6(lease6, force_create);
1889 setSuccessResponse(handle,
"IPv6 lease added.");
1891 setSuccessResponse(handle,
"IPv6 lease updated.");
1893 }
catch (
const std::exception& ex) {
1894 setErrorResponse(handle, ex.what());
1904 extractCommand(handle);
1913 if (cmd_args_ && cmd_args_->contains(
"subnet-id")) {
1914 id = parser.
getUint32(cmd_args_,
"subnet-id");
1922 auto observation = StatsMgr::instance().getObservation(
1923 StatsMgr::generateName(
"subnet",
id,
"declined-addresses"));
1925 int64_t previous_declined = 0;
1928 previous_declined = observation->getInteger().first;
1931 StatsMgr::instance().setValue(
1932 StatsMgr::generateName(
"subnet",
id,
"assigned-addresses"),
1935 StatsMgr::instance().setValue(
1936 StatsMgr::generateName(
"subnet",
id,
"declined-addresses"),
1939 StatsMgr::instance().addValue(
"declined-addresses", -previous_declined);
1947 for (
auto sub : *subs) {
1949 ids <<
" " << sub->getID();
1950 StatsMgr::instance().setValue(
1951 StatsMgr::generateName(
"subnet", sub->getID(),
"assigned-addresses"),
1954 StatsMgr::instance().setValue(
1955 StatsMgr::generateName(
"subnet", sub->getID(),
"declined-addresses"),
1959 StatsMgr::instance().setValue(
"declined-addresses", int64_t(0));
1963 tmp <<
"Deleted " << num <<
" IPv4 lease(s) from subnet(s)" << ids.str();
1966 setResponse(handle, response);
1967 }
catch (
const std::exception& ex) {
1968 setErrorResponse(handle, ex.what());
1978 extractCommand(handle);
1993 if (cmd_args_ && cmd_args_->contains(
"subnet-id")) {
1994 id = parser.
getUint32(cmd_args_,
"subnet-id");
2002 auto observation = StatsMgr::instance().getObservation(
2003 StatsMgr::generateName(
"subnet",
id,
"declined-addresses"));
2005 int64_t previous_declined = 0;
2008 previous_declined = observation->getInteger().first;
2011 StatsMgr::instance().setValue(
2012 StatsMgr::generateName(
"subnet",
id,
"assigned-nas" ),
2015 StatsMgr::instance().setValue(
2016 StatsMgr::generateName(
"subnet",
id,
"assigned-pds"),
2019 StatsMgr::instance().setValue(
2020 StatsMgr::generateName(
"subnet",
id,
"declined-addresses"),
2023 StatsMgr::instance().addValue(
"declined-addresses", -previous_declined);
2031 for (
auto sub : *subs) {
2033 ids <<
" " << sub->getID();
2034 StatsMgr::instance().setValue(
2035 StatsMgr::generateName(
"subnet", sub->getID(),
"assigned-nas" ),
2038 StatsMgr::instance().setValue(
2039 StatsMgr::generateName(
"subnet", sub->getID(),
"assigned-pds"),
2042 StatsMgr::instance().setValue(
2043 StatsMgr::generateName(
"subnet", sub->getID(),
"declined-addresses"),
2047 StatsMgr::instance().setValue(
"declined-addresses", int64_t(0));
2051 tmp <<
"Deleted " << num <<
" IPv6 lease(s) from subnet(s)" << ids.str();
2054 setResponse(handle, response);
2055 }
catch (
const std::exception& ex) {
2056 setErrorResponse(handle, ex.what());
2064 LeaseCmdsImpl::getIPv6LeaseForDelete(
const Parameters& parameters)
const {
2068 case Parameters::TYPE_ADDR: {
2075 lease6.reset(
new Lease6());
2076 lease6->addr_ = parameters.
addr;
2080 case Parameters::TYPE_HWADDR: {
2084 case Parameters::TYPE_DUID: {
2085 if (!parameters.
duid) {
2087 "requires duid to be specified");
2107 short family)
const {
2113 if (param->getType() != Element::string) {
2120 }
catch (
const std::exception& ex) {
2122 <<
"' is not a valid IP address.");
2127 << (family == AF_INET6 ?
"IPv6" :
"IPv4")
2128 <<
" address specified: " << param->stringValue());
2136 std::stringstream ss;
2140 extractCommand(handle);
2143 IOAddress addr = getAddressParam(cmd_args_,
"ip-address", AF_INET);
2146 ss <<
"DDNS updating is not enabled";
2151 ss <<
"No lease found for: " << addr.
toText();
2153 }
else if (lease->hostname_.empty()) {
2154 ss <<
"Lease for: " << addr.
toText()
2155 <<
", has no hostname, nothing to update";
2156 }
else if (!lease->fqdn_fwd_ && !lease->fqdn_rev_) {
2157 ss <<
"Neither forward nor reverse updates enabled for lease for: "
2163 ss <<
"NCR generated for: " << addr.
toText()
2164 <<
", hostname: " << lease->hostname_;
2165 setSuccessResponse(handle, ss.str());
2170 }
catch (
const std::exception& ex) {
2175 setErrorResponse(handle, ss.str(), resp_code);
2181 std::stringstream ss;
2185 extractCommand(handle);
2188 IOAddress addr = getAddressParam(cmd_args_,
"ip-address", AF_INET6);
2191 ss <<
"DDNS updating is not enabled";
2196 ss <<
"No lease found for: " << addr.
toText();
2198 }
else if (lease->hostname_.empty()) {
2199 ss <<
"Lease for: " << addr.
toText()
2200 <<
", has no hostname, nothing to update";
2201 }
else if (!lease->fqdn_fwd_ && !lease->fqdn_rev_) {
2202 ss <<
"Neither forward nor reverse updates enabled for lease for: "
2208 ss <<
"NCR generated for: " << addr.
toText()
2209 <<
", hostname: " << lease->hostname_;
2210 setSuccessResponse(handle, ss.str());
2215 }
catch (
const std::exception& ex) {
2220 setErrorResponse(handle, ss.str(), resp_code);
2228 const int control_result,
2229 const std::string& error_message)
const {
2230 auto failed_lease_map = Element::createMap();
2234 failed_lease_map->set(
"ip-address", Element::create(lease_address.
toText()));
2237 failed_lease_map->set(
"duid", Element::create(duid->toText()));
2241 failed_lease_map->set(
"result", Element::create(control_result));
2242 failed_lease_map->set(
"error-message", Element::create(error_message));
2244 return (failed_lease_map);
2251 return (impl_->leaseAddHandler(handle));
2256 return (impl_->lease6BulkApplyHandler(handle));
2261 return (impl_->leaseGetHandler(handle));
2266 return (impl_->leaseGetAllHandler(handle));
2271 return (impl_->leaseGetPageHandler(handle));
2276 return (impl_->leaseGetByHwAddressHandler(handle));
2281 return (impl_->leaseGetByClientIdHandler(handle));
2286 return (impl_->leaseGetByDuidHandler(handle));
2291 return (impl_->leaseGetByHostnameHandler(handle));
2296 return (impl_->lease4DelHandler(handle));
2301 return (impl_->lease6DelHandler(handle));
2306 return (impl_->lease4UpdateHandler(handle));
2311 return (impl_->lease6UpdateHandler(handle));
2317 return (impl_->lease4WipeHandler(handle));
2323 return (impl_->lease6WipeHandler(handle));
2328 return (impl_->lease4ResendDdnsHandler(handle));
2333 return (impl_->lease6ResendDdnsHandler(handle));
2336 LeaseCmds::LeaseCmds()
RAII class creating a critical section.
boost::shared_ptr< DUID > DuidPtr
virtual void updateLease4(const Lease4Ptr &lease4)=0
Updates IPv4 lease.
const isc::log::MessageID LEASE_CMDS_ADD6_FAILED
const isc::log::MessageID LEASE_CMDS_ADD4_FAILED
Parameters()
Default constructor.
static ClientIdPtr fromText(const std::string &text)
Create client identifier from the textual format.
Parser for Lease4 structure.
HWAddrPtr hwaddr
Specifies hardware address (used when query_type is TYPE_HWADDR)
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
ConstElementPtr createAnswer(const int status_code, const std::string &text, const ConstElementPtr &arg)
const int CONTROL_RESULT_SUCCESS
Status code indicating a successful operation.
virtual size_t wipeLeases4(const SubnetID &subnet_id)=0
Virtual method which removes specified leases.
A generic exception that is thrown if a parameter given to a method or function is considered invalid...
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
static std::string typeToText(Type type)
returns text representation of a lease type
virtual isc::dhcp::Lease6Ptr parse(isc::dhcp::ConstSrvConfigPtr &cfg, const isc::data::ConstElementPtr &lease_info, bool &force_create)
Parses Element tree and tries to convert to Lease4.
An abstract API for lease database.
static CfgMgr & instance()
returns a single instance of Configuration Manager
Attempt to update lease that was not there.
const isc::log::MessageID LEASE_CMDS_RESEND_DDNS6_FAILED
std::vector< Lease4Ptr > Lease4Collection
A collection of IPv4 leases.
const isc::log::MessageID LEASE_CMDS_RESEND_DDNS4
Resource race avoidance RAII handler for DHCPv4.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
the lease contains IPv6 prefix (for prefix delegation)
const int CONTROL_RESULT_ERROR
Status code indicating a general failure.
boost::shared_ptr< Element > ElementPtr
SrvConfigPtr getCurrentCfg()
Returns a pointer to the current configuration.
static DUID fromText(const std::string &text)
Create DUID from the textual format.
Type query_type
specifies parameter types
SubnetID subnet_id
Specifies subnet-id (always used)
const isc::log::MessageID LEASE_CMDS_ADD4
bool isV4() const
Convenience function to check for an IPv4 address.
boost::shared_ptr< const CfgSubnets4 > ConstCfgSubnets4Ptr
Const pointer.
Holds DUID (DHCPv6 Unique Identifier)
Resource race avoidance RAII handler.
const int CONTROL_RESULT_EMPTY
Status code indicating that the specified command was completed correctly, but failed to produce any ...
static const IOAddress & IPV6_ZERO_ADDRESS()
Returns an IPv6 zero address.
bool tryLock(Lease::Type type, const asiolink::IOAddress &addr)
Tries to acquires a resource.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
isc::log::Logger lease_cmds_logger("lease-cmds-hooks")
void queueNCR(const NameChangeType &chg_type, const Lease4Ptr &lease)
Creates name change request from the DHCPv4 lease.
boost::shared_ptr< const SrvConfig > ConstSrvConfigPtr
Const pointer to the SrvConfig.
const isc::log::MessageID LEASE_CMDS_RESEND_DDNS4_FAILED
static void syncCurrentExpirationTime(const Lease &from, Lease &to)
Sync lease current expiration time with new value from another lease, so that additional operations c...
boost::multi_index_container< Subnet4Ptr, boost::multi_index::indexed_by< boost::multi_index::ordered_unique< boost::multi_index::tag< SubnetSubnetIdIndexTag >, boost::multi_index::const_mem_fun< Subnet, SubnetID,&Subnet::getID > >, boost::multi_index::ordered_unique< boost::multi_index::tag< SubnetPrefixIndexTag >, boost::multi_index::const_mem_fun< Subnet, std::string,&Subnet::toText > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< SubnetServerIdIndexTag >, boost::multi_index::const_mem_fun< Network4, asiolink::IOAddress,&Network4::getServerId > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< SubnetModificationTimeIndexTag >, boost::multi_index::const_mem_fun< data::BaseStampedElement, boost::posix_time::ptime,&data::BaseStampedElement::getModificationTime > > >> Subnet4Collection
A collection of Subnet4 objects.
boost::shared_ptr< Lease4 > Lease4Ptr
Pointer to a Lease4 structure.
Per-packet callout handle.
Wrapper class around reservation command handlers.
boost::shared_ptr< const CfgSubnets6 > ConstCfgSubnets6Ptr
Const pointer.
Parser for Lease6 structure.
boost::shared_ptr< const Element > ConstElementPtr
Structure that holds a lease for IPv6 address and/or prefix.
bool isV6Zero() const
Convenience function to check if it is an IPv4 zero address.
std::vector< Lease6Ptr > Lease6Collection
A collection of IPv6 leases.
virtual Lease6Ptr getLease6(Lease::Type type, const isc::asiolink::IOAddress &addr) const =0
Returns existing IPv6 lease for a given IPv6 address.
virtual Lease4Collection getLeases4(SubnetID subnet_id) const =0
Returns all IPv4 leases for the particular subnet identifier.
IOAddress addr
Specifies IPv4/v6 address (used when query_type is TYPE_ADDR)
boost::shared_ptr< ClientId > ClientIdPtr
Shared pointer to a Client ID.
the lease contains temporary IPv6 address
Type
specifies type of query (by IP addr, by hwaddr, by DUID)
uint32_t getUint32(isc::data::ConstElementPtr scope, const std::string &name)
Returns a value converted to uint32_t.
the lease contains non-temporary IPv6 address
boost::multi_index_container< Subnet6Ptr, boost::multi_index::indexed_by< boost::multi_index::ordered_unique< boost::multi_index::tag< SubnetSubnetIdIndexTag >, boost::multi_index::const_mem_fun< Subnet, SubnetID,&Subnet::getID > >, boost::multi_index::ordered_unique< boost::multi_index::tag< SubnetPrefixIndexTag >, boost::multi_index::const_mem_fun< Subnet, std::string,&Subnet::toText > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< SubnetModificationTimeIndexTag >, boost::multi_index::const_mem_fun< data::BaseStampedElement, boost::posix_time::ptime,&data::BaseStampedElement::getModificationTime > > >> Subnet6Collection
A collection of Subnet6 objects.
Lease::Type lease_type
Lease type (NA,TA or PD) used for v6 leases.
query by IP address (either v4 or v6)
Defines the logger used by the top-level component of kea-dhcp-ddns.
This file contains several functions and constants that are used for handling commands and responses ...
bool updateDDNS
Indicates whether or not DNS should be updated.
Base class that command handler implementers may use for common tasks.
a common structure for IPv4 and IPv6 leases
static HWAddr fromText(const std::string &text, const uint16_t htype=HTYPE_ETHER)
Creates instance of the hardware address from textual format.
Type
Type of lease or pool.
A generic exception that is thrown if a function is called in a prohibited way.
std::string toText() const
Convert the address to a string.
Parameters specified for lease commands.
Hardware type that represents information from DHCPv4 packet.
static Type txtToType(const std::string &txt)
Attempts to covert text to one of specified types.
virtual bool addLease(const Lease4Ptr &lease)=0
Adds an IPv4 lease.
query by hardware address (v4 only)
virtual size_t wipeLeases6(const SubnetID &subnet_id)=0
Virtual method which removes specified leases.
bool isV6() const
Convenience function to check for an IPv6 address.
virtual Lease4Ptr getLease4(const isc::asiolink::IOAddress &addr) const =0
Returns an IPv4 lease for specified IPv4 address.
const isc::log::MessageID LEASE_CMDS_ADD6
virtual bool deleteLease(const Lease4Ptr &lease)=0
Deletes an IPv4 lease.
isc::dhcp::DuidPtr duid
Specifies identifier value (used when query_type is TYPE_DUID)
Wraps value holding size of the page with leases.
The IOAddress class represents an IP addresses (version agnostic)
virtual isc::dhcp::Lease4Ptr parse(isc::dhcp::ConstSrvConfigPtr &cfg, const isc::data::ConstElementPtr &lease_info, bool &force_create)
Parses Element tree and tries to convert to Lease4.
static LeaseMgr & instance()
Return current lease manager.
virtual Lease6Collection getLeases6(Lease::Type type, const DUID &duid, uint32_t iaid) const =0
Returns existing IPv6 leases for a given DUID+IA combination.
boost::shared_ptr< Lease6 > Lease6Ptr
Pointer to a Lease6 structure.
short getFamily() const
Returns the address family.
virtual void updateLease6(const Lease6Ptr &lease6)=0
Updates IPv6 lease.
Database duplicate entry error.
const isc::log::MessageID LEASE_CMDS_RESEND_DDNS6
uint32_t SubnetID
Unique identifier for a subnet (both v4 and v6)
isc::dhcp::ClientIdPtr client_id
Specifies identifier value (used when query_type is TYPE_CLIENT_ID)
uint32_t iaid
IAID identifier used for v6 leases.
bool tryLock4(const asiolink::IOAddress &addr)
Tries to acquires a resource.