Kea 2.2.0
lease_cmds.cc
Go to the documentation of this file.
1// Copyright (C) 2017-2021 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#include <config.h>
9#include <config/cmds_impl.h>
11#include <cc/data.h>
12#include <asiolink/io_address.h>
14#include <dhcpsrv/cfgmgr.h>
16#include <dhcpsrv/lease_mgr.h>
20#include <dhcpsrv/subnet_id.h>
22#include <dhcp/duid.h>
23#include <hooks/hooks.h>
25#include <lease_cmds.h>
26#include <lease_parser.h>
27#include <lease_cmds_log.h>
28#include <stats/stats_mgr.h>
29#include <util/encode/hex.h>
31#include <util/strutil.h>
32
33#include <boost/scoped_ptr.hpp>
34#include <boost/algorithm/string.hpp>
35#include <string>
36#include <sstream>
37
38using namespace isc::dhcp;
39using namespace isc::data;
40using namespace isc::dhcp_ddns;
41using namespace isc::config;
42using namespace isc::asiolink;
43using namespace isc::hooks;
44using namespace isc::stats;
45using namespace isc::util;
46using namespace std;
47
48namespace isc {
49namespace lease_cmds {
50
52class LeaseCmdsImpl : private CmdsImpl {
53public:
54
56 class Parameters {
57 public:
58
60 typedef enum {
66
69
72
75
78
81
91 static Type txtToType(const std::string& txt) {
92 if (txt == "address") {
93 return (Parameters::TYPE_ADDR);
94 } else if (txt == "hw-address") {
96 } else if (txt == "duid") {
97 return (Parameters::TYPE_DUID);
98 } else if (txt == "client-id") {
100 } else {
101 isc_throw(BadValue, "Incorrect identifier type: "
102 << txt << ", the only supported values are: "
103 "address, hw-address, duid");
104 }
105 }
106
109
112
114 uint32_t iaid;
115
118
121 : subnet_id(0), addr("::"), query_type(TYPE_ADDR),
122 lease_type(Lease::TYPE_NA), iaid(0), updateDDNS(false) {
123 }
124 };
125
126public:
127
136 int
138
148 int
150
159 int
161
173 int
175
191 int
193
203 int
205
215 int
217
227 int
229
240 int
242
251 int
253
262 int
264
273 int
275
284 int
286
295 int
297
306 int
308
318
328
340 Parameters getParameters(bool v6, const ConstElementPtr& args);
341
359 Lease6Ptr getIPv6LeaseForDelete(const Parameters& parameters) const;
360
376 const IOAddress& lease_address,
377 const DuidPtr& duid,
378 const int control_result,
379 const std::string& error_message) const;
380
391 IOAddress getAddressParam(ConstElementPtr params, const std::string name,
392 short family = AF_INET) const;
393
397 static void updateStatsOnAdd(const Lease4Ptr& lease);
398
402 static void updateStatsOnAdd(const Lease6Ptr& lease);
403
408 static void updateStatsOnUpdate(const Lease4Ptr& existing,
409 const Lease4Ptr& lease);
410
415 static void updateStatsOnUpdate(const Lease6Ptr& existing,
416 const Lease6Ptr& lease);
417
421 static void updateStatsOnDelete(const Lease4Ptr& lease);
422
426 static void updateStatsOnDelete(const Lease6Ptr& lease);
427
436 static bool addOrUpdate4(Lease4Ptr lease, bool force_create);
437
446 static bool addOrUpdate6(Lease6Ptr lease, bool force_create);
447};
448
449void
451 if (!lease->stateExpiredReclaimed()) {
452 StatsMgr::instance().addValue(
453 StatsMgr::generateName("subnet", lease->subnet_id_,
454 "assigned-addresses"),
455 int64_t(1));
456 if (lease->stateDeclined()) {
457 StatsMgr::instance().addValue("declined-addresses", int64_t(1));
458
459 StatsMgr::instance().addValue(
460 StatsMgr::generateName("subnet", lease->subnet_id_,
461 "declined-addresses"),
462 int64_t(1));
463 }
464 }
465}
466
467void
469 if (!lease->stateExpiredReclaimed()) {
470 StatsMgr::instance().addValue(
471 StatsMgr::generateName("subnet", lease->subnet_id_,
472 lease->type_ == Lease::TYPE_NA ?
473 "assigned-nas" : "assigned-pds"),
474 int64_t(1));
475 if (lease->stateDeclined()) {
476 StatsMgr::instance().addValue("declined-addresses", int64_t(1));
477
478 StatsMgr::instance().addValue(
479 StatsMgr::generateName("subnet", lease->subnet_id_,
480 "declined-addresses"),
481 int64_t(1));
482 }
483 }
484}
485
486void
488 const Lease4Ptr& lease) {
489 if (!existing->stateExpiredReclaimed()) {
490 // old lease is non expired-reclaimed
491 if (existing->subnet_id_ != lease->subnet_id_) {
492 StatsMgr::instance().addValue(
493 StatsMgr::generateName("subnet", existing->subnet_id_,
494 "assigned-addresses"),
495 int64_t(-1));
496 }
497 if (existing->stateDeclined()) {
498 // old lease is declined
499 StatsMgr::instance().addValue("declined-addresses", int64_t(-1));
500
501 StatsMgr::instance().addValue(
502 StatsMgr::generateName("subnet", existing->subnet_id_,
503 "declined-addresses"),
504 int64_t(-1));
505 }
506 if (!lease->stateExpiredReclaimed()) {
507 // new lease is non expired-reclaimed
508 if (existing->subnet_id_ != lease->subnet_id_) {
509 StatsMgr::instance().addValue(
510 StatsMgr::generateName("subnet", lease->subnet_id_,
511 "assigned-addresses"),
512 int64_t(1));
513 }
514 if (lease->stateDeclined()) {
515 // new lease is declined
516 StatsMgr::instance().addValue("declined-addresses", int64_t(1));
517
518 StatsMgr::instance().addValue(
519 StatsMgr::generateName("subnet", lease->subnet_id_,
520 "declined-addresses"),
521 int64_t(1));
522 }
523 }
524 } else {
525 // old lease is expired-reclaimed
526 if (!lease->stateExpiredReclaimed()) {
527 // new lease is non expired-reclaimed
528 StatsMgr::instance().addValue(
529 StatsMgr::generateName("subnet", lease->subnet_id_,
530 "assigned-addresses"),
531 int64_t(1));
532 if (lease->stateDeclined()) {
533 // new lease is declined
534 StatsMgr::instance().addValue("declined-addresses", int64_t(1));
535
536 StatsMgr::instance().addValue(
537 StatsMgr::generateName("subnet", lease->subnet_id_,
538 "declined-addresses"),
539 int64_t(1));
540 }
541 }
542 }
543}
544
545void
547 const Lease6Ptr& lease) {
548 if (!existing->stateExpiredReclaimed()) {
549 // old lease is non expired-reclaimed
550 if (existing->subnet_id_ != lease->subnet_id_) {
551 StatsMgr::instance().addValue(
552 StatsMgr::generateName("subnet", existing->subnet_id_,
553 lease->type_ == Lease::TYPE_NA ?
554 "assigned-nas" : "assigned-pds"),
555 int64_t(-1));
556 }
557 if (existing->stateDeclined()) {
558 // old lease is declined
559 StatsMgr::instance().addValue("declined-addresses", int64_t(-1));
560
561 StatsMgr::instance().addValue(
562 StatsMgr::generateName("subnet", existing->subnet_id_,
563 "declined-addresses"),
564 int64_t(-1));
565 }
566 if (!lease->stateExpiredReclaimed()) {
567 // new lease is non expired-reclaimed
568 if (existing->subnet_id_ != lease->subnet_id_) {
569 StatsMgr::instance().addValue(
570 StatsMgr::generateName("subnet", lease->subnet_id_,
571 lease->type_ == Lease::TYPE_NA ?
572 "assigned-nas" : "assigned-pds"),
573 int64_t(1));
574 }
575 if (lease->stateDeclined()) {
576 // new lease is declined
577 StatsMgr::instance().addValue("declined-addresses", int64_t(1));
578
579 StatsMgr::instance().addValue(
580 StatsMgr::generateName("subnet", lease->subnet_id_,
581 "declined-addresses"),
582 int64_t(1));
583 }
584 }
585 } else {
586 // old lease is expired-reclaimed
587 if (!lease->stateExpiredReclaimed()) {
588 // new lease is non expired-reclaimed
589 StatsMgr::instance().addValue(
590 StatsMgr::generateName("subnet", lease->subnet_id_,
591 lease->type_ == Lease::TYPE_NA ?
592 "assigned-nas" : "assigned-pds"),
593 int64_t(1));
594 if (lease->stateDeclined()) {
595 // new lease is declined
596 StatsMgr::instance().addValue("declined-addresses", int64_t(1));
597
598 StatsMgr::instance().addValue(
599 StatsMgr::generateName("subnet", lease->subnet_id_,
600 "declined-addresses"),
601 int64_t(1));
602 }
603 }
604 }
605}
606
607void
609 if (!lease->stateExpiredReclaimed()) {
610 StatsMgr::instance().addValue(
611 StatsMgr::generateName("subnet", lease->subnet_id_,
612 "assigned-addresses"),
613 int64_t(-1));
614 if (lease->stateDeclined()) {
615 StatsMgr::instance().addValue("declined-addresses", int64_t(-1));
616
617 StatsMgr::instance().addValue(
618 StatsMgr::generateName("subnet", lease->subnet_id_,
619 "declined-addresses"),
620 int64_t(-1));
621 }
622 }
623}
624
625void
627 if (!lease->stateExpiredReclaimed()) {
628 StatsMgr::instance().addValue(
629 StatsMgr::generateName("subnet", lease->subnet_id_,
630 lease->type_ == Lease::TYPE_NA ?
631 "assigned-nas" : "assigned-pds"),
632 int64_t(-1));
633 if (lease->stateDeclined()) {
634 StatsMgr::instance().addValue("declined-addresses", int64_t(-1));
635
636 StatsMgr::instance().addValue(
637 StatsMgr::generateName("subnet", lease->subnet_id_,
638 "declined-addresses"),
639 int64_t(-1));
640 }
641 }
642}
643
644bool
645LeaseCmdsImpl::addOrUpdate4(Lease4Ptr lease, bool force_create) {
646 Lease4Ptr existing = LeaseMgrFactory::instance().getLease4(lease->addr_);
647 if (force_create && !existing) {
648 // lease does not exist
649 if (!LeaseMgrFactory::instance().addLease(lease)) {
651 "lost race between calls to get and add");
652 }
654 return (true);
655 }
656 if (existing) {
657 // Update lease current expiration time with value received from the
658 // database. Some database backends reject operations on the lease if
659 // the current expiration time value does not match what is stored.
660 Lease::syncCurrentExpirationTime(*existing, *lease);
661 }
662 try {
663 LeaseMgrFactory::instance().updateLease4(lease);
664 } catch (const NoSuchLease&) {
665 isc_throw(InvalidOperation, "failed to update the lease with address "
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");
669 }
670
671 LeaseCmdsImpl::updateStatsOnUpdate(existing, lease);
672 return (false);
673}
674
675bool
676LeaseCmdsImpl::addOrUpdate6(Lease6Ptr lease, bool force_create) {
677 Lease6Ptr existing =
678 LeaseMgrFactory::instance().getLease6(lease->type_, lease->addr_);
679 if (force_create && !existing) {
680 // lease does not exist
681 if (!LeaseMgrFactory::instance().addLease(lease)) {
683 "lost race between calls to get and add");
684 }
686 return (true);
687 }
688 if (existing) {
689 // Update lease current expiration time with value received from the
690 // database. Some database backends reject operations on the lease if
691 // the current expiration time value does not match what is stored.
692 Lease::syncCurrentExpirationTime(*existing, *lease);
693 }
694 try {
695 LeaseMgrFactory::instance().updateLease6(lease);
696 } catch (const NoSuchLease&) {
697 isc_throw(InvalidOperation, "failed to update the lease with address "
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");
701 }
702
703 LeaseCmdsImpl::updateStatsOnUpdate(existing, lease);
704 return (false);
705}
706
707int
709 // Arbitrary defaulting to DHCPv4 or with other words extractCommand
710 // below is not expected to throw...
711 bool v4 = true;
712 string txt = "malformed command";
713
714 stringstream resp;
715 try {
716 extractCommand(handle);
717 v4 = (cmd_name_ == "lease4-add");
718
719 txt = "(missing parameters)";
720 if (!cmd_args_) {
721 isc_throw(isc::BadValue, "no parameters specified for the command");
722 }
723
724 txt = cmd_args_->str();
725
726 ConstSrvConfigPtr config = CfgMgr::instance().getCurrentCfg();
727
728 Lease4Ptr lease4;
729 Lease6Ptr lease6;
730 // This parameter is ignored for the commands adding the lease.
731 bool force_create = false;
732 if (v4) {
733 Lease4Parser parser;
734 lease4 = parser.parse(config, cmd_args_, force_create);
735 if (lease4) {
736 bool success;
737 if (!MultiThreadingMgr::instance().getMode()) {
738 // Not multi-threading.
739 success = LeaseMgrFactory::instance().addLease(lease4);
740 } else {
741 // Multi-threading, try to lock first to avoid a race.
742 ResourceHandler4 resource_handler;
743 if (resource_handler.tryLock4(lease4->addr_)) {
744 success = LeaseMgrFactory::instance().addLease(lease4);
745 } else {
747 "ResourceBusy: IP address:" << lease4->addr_
748 << " could not be added.");
749 }
750 }
751
752 if (!success) {
753 isc_throw(db::DuplicateEntry, "IPv4 lease already exists.");
754 }
755
757 resp << "Lease for address " << lease4->addr_.toText()
758 << ", subnet-id " << lease4->subnet_id_ << " added.";
759 }
760 } else {
761 Lease6Parser parser;
762 lease6 = parser.parse(config, cmd_args_, force_create);
763 if (lease6) {
764 bool success;
765 if (!MultiThreadingMgr::instance().getMode()) {
766 // Not multi-threading.
767 success = LeaseMgrFactory::instance().addLease(lease6);
768 } else {
769 // Multi-threading, try to lock first to avoid a race.
770 ResourceHandler resource_handler;
771 if (resource_handler.tryLock(lease6->type_, lease6->addr_)) {
772 success = LeaseMgrFactory::instance().addLease(lease6);
773 } else {
775 "ResourceBusy: IP address:" << lease6->addr_
776 << " could not be added.");
777 }
778 }
779
780 if (!success) {
781 isc_throw(db::DuplicateEntry, "IPv6 lease already exists.");
782 }
783
785 if (lease6->type_ == Lease::TYPE_NA) {
786 resp << "Lease for address " << lease6->addr_.toText()
787 << ", subnet-id " << lease6->subnet_id_ << " added.";
788 } else {
789 resp << "Lease for prefix " << lease6->addr_.toText()
790 << "/" << static_cast<int>(lease6->prefixlen_)
791 << ", subnet-id " << lease6->subnet_id_ << " added.";
792 }
793 }
794 }
795
796 } catch (const std::exception& ex) {
798 .arg(txt)
799 .arg(ex.what());
800 setErrorResponse(handle, ex.what());
801 return (1);
802 }
803
805 v4 ? LEASE_CMDS_ADD4 : LEASE_CMDS_ADD6).arg(txt);
806 setSuccessResponse(handle, resp.str());
807 return (0);
808}
809
812 Parameters x;
813
814 if (!params || params->getType() != Element::map) {
815 isc_throw(BadValue, "Parameters missing or are not a map.");
816 }
817
818 if (params->contains("update-ddns")) {
819 ConstElementPtr tmp = params->get("update-ddns");
820 if (tmp->getType() != Element::boolean) {
821 isc_throw(BadValue, "'update-ddns' is not a boolean");
822 } else {
823 x.updateDDNS = tmp->boolValue();
824 }
825 }
826
827 // We support several sets of parameters for leaseX-get/lease-del:
828 // lease-get(type, address)
829 // lease-get(type, subnet-id, identifier-type, identifier)
830
831 if (params->contains("type")) {
832 string t = params->get("type")->stringValue();
833 if (t == "IA_NA" || t == "0") {
834 x.lease_type = Lease::TYPE_NA;
835 } else if (t == "IA_TA" || t == "1") {
836 x.lease_type = Lease::TYPE_TA;
837 } else if (t == "IA_PD" || t == "2") {
838 x.lease_type = Lease::TYPE_PD;
839 } else if (t == "V4" || t == "3") {
840 x.lease_type = Lease::TYPE_V4;
841 } else {
842 isc_throw(BadValue, "Invalid lease type specified: "
843 << t << ", only supported values are: IA_NA, IA_TA,"
844 << " IA_PD and V4");
845 }
846 }
847
848 ConstElementPtr tmp = params->get("ip-address");
849 if (tmp) {
850 if (tmp->getType() != Element::string) {
851 isc_throw(BadValue, "'ip-address' is not a string.");
852 }
853
854 x.addr = IOAddress(tmp->stringValue());
855
856 if ((v6 && !x.addr.isV6()) || (!v6 && !x.addr.isV4())) {
857 stringstream txt;
858 txt << "Invalid " << (v6 ? "IPv6" : "IPv4")
859 << " address specified: " << tmp->stringValue();
860 isc_throw(BadValue, txt.str());
861 }
862
864 return (x);
865 }
866
867 tmp = params->get("subnet-id");
868 if (!tmp) {
869 isc_throw(BadValue, "Mandatory 'subnet-id' parameter missing.");
870 }
871 if (tmp->getType() != Element::integer) {
872 isc_throw(BadValue, "'subnet-id' parameter is not integer.");
873 }
874 x.subnet_id = tmp->intValue();
875
876 if (params->contains("iaid")) {
877 x.iaid = params->get("iaid")->intValue();
878 }
879
880 // No address specified. Ok, so it must be identifier based query.
881 // "identifier-type": "duid",
882 // "identifier": "aa:bb:cc:dd:ee:..."
883
884 ConstElementPtr type = params->get("identifier-type");
885 ConstElementPtr ident = params->get("identifier");
886 if (!type || type->getType() != Element::string) {
887 isc_throw(BadValue, "No 'ip-address' provided"
888 " and 'identifier-type' is either missing or not a string.");
889 }
890 if (!ident || ident->getType() != Element::string) {
891 isc_throw(BadValue, "No 'ip-address' provided"
892 " and 'identifier' is either missing or not a string.");
893 }
894
895 // Got the parameters. Let's see if their values make sense.
896 // Try to convert identifier-type
897 x.query_type = Parameters::txtToType(type->stringValue());
898
899 switch (x.query_type) {
901 HWAddr hw = HWAddr::fromText(ident->stringValue());
902 x.hwaddr = HWAddrPtr(new HWAddr(hw));
903 break;
904 }
906 x.client_id = ClientId::fromText(ident->stringValue());
907 break;
908 }
910 DUID duid = DUID::fromText(ident->stringValue());
911 x.duid = DuidPtr(new DUID(duid));
912 break;
913 }
915 // We should never get here. The address clause should have been caught
916 // earlier.
917 return (x);
918 }
919 default: {
920 isc_throw(BadValue, "Identifier type " << type->stringValue() <<
921 " is not supported.");
922 }
923 }
924
925 return (x);
926}
927
928int
930 Parameters p;
931 Lease4Ptr lease4;
932 Lease6Ptr lease6;
933 bool v4;
934 try {
935 extractCommand(handle);
936 v4 = (cmd_name_ == "lease4-get");
937
938 p = getParameters(!v4, cmd_args_);
939 switch (p.query_type) {
941 // Query by address
942 if (v4) {
943 lease4 = LeaseMgrFactory::instance().getLease4(p.addr);
944 } else {
945 lease6 = LeaseMgrFactory::instance().getLease6(p.lease_type, p.addr);
946 }
947 break;
948 }
950 if (v4) {
951 if (!p.hwaddr) {
952 isc_throw(InvalidParameter, "Program error: Query by hw-address "
953 "requires hwaddr to be specified");
954 }
955
956 lease4 = LeaseMgrFactory::instance().getLease4(*p.hwaddr, p.subnet_id);
957 } else {
958 isc_throw(isc::InvalidParameter, "Query by hw-address is not allowed in v6.");
959 }
960 break;
961
963 if (!v4) {
964 if (!p.duid) {
965 isc_throw(InvalidParameter, "Program error: Query by duid "
966 "requires duid to be specified");
967 }
968
969 lease6 = LeaseMgrFactory::instance().getLease6(p.lease_type, *p.duid,
970 p.iaid, p.subnet_id);
971 } else {
972 isc_throw(InvalidParameter, "Query by duid is not allowed in v4.");
973 }
974 break;
975
977 if (v4) {
978 if (!p.client_id) {
979 isc_throw(InvalidParameter, "Program error: Query by client-id "
980 "requires client-id to be specified");
981 }
982
983 lease4 = LeaseMgrFactory::instance().getLease4(*p.client_id, p.subnet_id);
984 } else {
985 isc_throw(isc::InvalidParameter, "Query by client-id is not allowed in v6.");
986 }
987 break;
988
989 default: {
990 isc_throw(InvalidOperation, "Unknown query type: " << static_cast<int>(p.query_type));
991 break;
992 }
993 }
994 } catch (const std::exception& ex) {
995 setErrorResponse(handle, ex.what());
996 return (1);
997 }
998
999 ElementPtr lease_json;
1000 if (v4 && lease4) {
1001 lease_json = lease4->toElement();
1003 "IPv4 lease found.", lease_json);
1004 setResponse(handle, response);
1005 } else if (!v4 && lease6) {
1006 lease_json = lease6->toElement();
1008 "IPv6 lease found.", lease_json);
1009 setResponse(handle, response);
1010 } else {
1011 // If we got here, the lease has not been found.
1012 setErrorResponse(handle, "Lease not found.", CONTROL_RESULT_EMPTY);
1013 }
1014
1015 return (0);
1016}
1017
1018int
1020 bool v4 = true;
1021 try {
1022 extractCommand(handle);
1023 v4 = (cmd_name_ == "lease4-get-all");
1024
1025 ElementPtr leases_json = Element::createList();
1026
1027 // The argument may contain a list of subnets for which leases should
1028 // be returned.
1029 if (cmd_args_) {
1030 ConstElementPtr subnets = cmd_args_->get("subnets");
1031 if (!subnets) {
1032 isc_throw(BadValue, "'subnets' parameter not specified");
1033 }
1034 if (subnets->getType() != Element::list) {
1035 isc_throw(BadValue, "'subnets' parameter must be a list");
1036 }
1037
1038 const std::vector<ElementPtr>& subnet_ids = subnets->listValue();
1039 for (auto subnet_id = subnet_ids.begin();
1040 subnet_id != subnet_ids.end();
1041 ++subnet_id) {
1042 if ((*subnet_id)->getType() != Element::integer) {
1043 isc_throw(BadValue, "listed subnet identifiers must be numbers");
1044 }
1045
1046 if (v4) {
1047 Lease4Collection leases =
1048 LeaseMgrFactory::instance().getLeases4((*subnet_id)->intValue());
1049 for (auto lease : leases) {
1050 ElementPtr lease_json = lease->toElement();
1051 leases_json->add(lease_json);
1052 }
1053 } else {
1054 Lease6Collection leases =
1055 LeaseMgrFactory::instance().getLeases6((*subnet_id)->intValue());
1056 for (auto lease : leases) {
1057 ElementPtr lease_json = lease->toElement();
1058 leases_json->add(lease_json);
1059 }
1060 }
1061 }
1062
1063 } else {
1064 // There is no 'subnets' argument so let's return all leases.
1065 if (v4) {
1066 Lease4Collection leases = LeaseMgrFactory::instance().getLeases4();
1067 for (auto lease : leases) {
1068 ElementPtr lease_json = lease->toElement();
1069 leases_json->add(lease_json);
1070 }
1071 } else {
1072 Lease6Collection leases = LeaseMgrFactory::instance().getLeases6();
1073 for (auto lease : leases) {
1074 ElementPtr lease_json = lease->toElement();
1075 leases_json->add(lease_json);
1076 }
1077 }
1078 }
1079
1080 std::ostringstream s;
1081 s << leases_json->size()
1082 << " IPv" << (v4 ? "4" : "6")
1083 << " lease(s) found.";
1084 ElementPtr args = Element::createMap();
1085 args->set("leases", leases_json);
1086 ConstElementPtr response =
1087 createAnswer(leases_json->size() > 0 ?
1090 s.str(), args);
1091 setResponse(handle, response);
1092
1093 } catch (const std::exception& ex) {
1094 setErrorResponse(handle, ex.what());
1095 return (CONTROL_RESULT_ERROR);
1096 }
1097
1098 return (0);
1099}
1100
1101int
1103 bool v4 = true;
1104 try {
1105 extractCommand(handle);
1106 v4 = (cmd_name_ == "lease4-get-page");
1107
1108 // arguments must always be present
1109 if (!cmd_args_) {
1110 isc_throw(BadValue, "no parameters specified for the " << cmd_name_
1111 << " command");
1112 }
1113
1114 // The 'from' argument denotes from which lease we should start the
1115 // results page. The results page excludes this lease.
1116 ConstElementPtr from = cmd_args_->get("from");
1117 if (!from) {
1118 isc_throw(BadValue, "'from' parameter not specified");
1119 }
1120
1121 // The 'from' argument is a string. It may contain a 'start' keyword or
1122 // an IP address.
1123 if (from->getType() != Element::string) {
1124 isc_throw(BadValue, "'from' parameter must be a string");
1125 }
1126
1127 boost::scoped_ptr<IOAddress> from_address;
1128 try {
1129 if (from->stringValue() == "start") {
1130 from_address.reset(new IOAddress(v4 ? "0.0.0.0" : "::"));
1131
1132 } else {
1133 // Conversion of a string to an IP address may throw.
1134 from_address.reset(new IOAddress(from->stringValue()));
1135 }
1136
1137 } catch (...) {
1138 isc_throw(BadValue, "'from' parameter value is neither 'start' keyword nor "
1139 "a valid IPv" << (v4 ? "4" : "6") << " address");
1140 }
1141
1142 // It must be either IPv4 address for lease4-get-page or IPv6 address for
1143 // lease6-get-page.
1144 if (v4 && (!from_address->isV4())) {
1145 isc_throw(BadValue, "'from' parameter value " << from_address->toText()
1146 << " is not an IPv4 address");
1147
1148 } else if (!v4 && from_address->isV4()) {
1149 isc_throw(BadValue, "'from' parameter value " << from_address->toText()
1150 << " is not an IPv6 address");
1151 }
1152
1153 // The 'limit' is a desired page size. It must always be present.
1154 ConstElementPtr page_limit = cmd_args_->get("limit");
1155 if (!page_limit) {
1156 isc_throw(BadValue, "'limit' parameter not specified");
1157 }
1158
1159 // The 'limit' must be a number.
1160 if (page_limit->getType() != Element::integer) {
1161 isc_throw(BadValue, "'limit' parameter must be a number");
1162 }
1163
1164 // Retrieve the desired page size.
1165 size_t page_limit_value = static_cast<size_t>(page_limit->intValue());
1166
1167 ElementPtr leases_json = Element::createList();
1168
1169 if (v4) {
1170 // Get page of IPv4 leases.
1171 Lease4Collection leases =
1172 LeaseMgrFactory::instance().getLeases4(*from_address,
1173 LeasePageSize(page_limit_value));
1174
1175 // Convert leases into JSON list.
1176 for (auto lease : leases) {
1177 ElementPtr lease_json = lease->toElement();
1178 leases_json->add(lease_json);
1179 }
1180
1181 } else {
1182 // Get page of IPv6 leases.
1183 Lease6Collection leases =
1184 LeaseMgrFactory::instance().getLeases6(*from_address,
1185 LeasePageSize(page_limit_value));
1186 // Convert leases into JSON list.
1187 for (auto lease : leases) {
1188 ElementPtr lease_json = lease->toElement();
1189 leases_json->add(lease_json);
1190 }
1191 }
1192
1193 // Prepare textual status.
1194 std::ostringstream s;
1195 s << leases_json->size()
1196 << " IPv" << (v4 ? "4" : "6")
1197 << " lease(s) found.";
1198 ElementPtr args = Element::createMap();
1199
1200 // Put gathered data into arguments map.
1201 args->set("leases", leases_json);
1202 args->set("count", Element::create(static_cast<int64_t>(leases_json->size())));
1203
1204 // Create the response.
1205 ConstElementPtr response =
1206 createAnswer(leases_json->size() > 0 ?
1209 s.str(), args);
1210 setResponse(handle, response);
1211
1212 } catch (const std::exception& ex) {
1213 setErrorResponse(handle, ex.what());
1214 return (CONTROL_RESULT_ERROR);
1215 }
1216
1217 return (CONTROL_RESULT_SUCCESS);
1218}
1219
1220int
1222 try {
1223 extractCommand(handle);
1224
1225 // arguments must always be present
1226 if (!cmd_args_ || (cmd_args_->getType() != Element::map)) {
1227 isc_throw(BadValue, "Command arguments missing or a not a map.");
1228 }
1229
1230 // the hw-address parameter is mandatory.
1231 ConstElementPtr hw_address = cmd_args_->get("hw-address");
1232 if (!hw_address) {
1233 isc_throw(BadValue, "'hw-address' parameter not specified");
1234 }
1235
1236 // The 'hw-address' argument is a string.
1237 if (hw_address->getType() != Element::string) {
1238 isc_throw(BadValue, "'hw-address' parameter must be a string");
1239 }
1240
1241 HWAddr hwaddr = HWAddr::fromText(hw_address->stringValue());
1242
1243 Lease4Collection leases =
1244 LeaseMgrFactory::instance().getLease4(hwaddr);
1245 ElementPtr leases_json = Element::createList();
1246 for (auto lease : leases) {
1247 ElementPtr lease_json = lease->toElement();
1248 leases_json->add(lease_json);
1249 }
1250
1251 std::ostringstream s;
1252 s << leases_json->size() << " IPv4 lease(s) found.";
1253 ElementPtr args = Element::createMap();
1254 args->set("leases", leases_json);
1255 ConstElementPtr response =
1256 createAnswer(leases_json->size() > 0 ?
1259 s.str(), args);
1260 setResponse(handle, response);
1261
1262 } catch (const std::exception& ex) {
1263 setErrorResponse(handle, ex.what());
1264 return (CONTROL_RESULT_ERROR);
1265 }
1266
1267 return (0);
1268}
1269
1270int
1272 try {
1273 extractCommand(handle);
1274
1275 // arguments must always be present
1276 if (!cmd_args_ || (cmd_args_->getType() != Element::map)) {
1277 isc_throw(BadValue, "Command arguments missing or a not a map.");
1278 }
1279
1280 // the client-id parameter is mandatory.
1281 ConstElementPtr client_id = cmd_args_->get("client-id");
1282 if (!client_id) {
1283 isc_throw(BadValue, "'client-id' parameter not specified");
1284 }
1285
1286 // The 'client-id' argument is a string.
1287 if (client_id->getType() != Element::string) {
1288 isc_throw(BadValue, "'client-id' parameter must be a string");
1289 }
1290
1291 ClientIdPtr clientid = ClientId::fromText(client_id->stringValue());
1292
1293 Lease4Collection leases =
1294 LeaseMgrFactory::instance().getLease4(*clientid);
1295 ElementPtr leases_json = Element::createList();
1296 for (auto lease : leases) {
1297 ElementPtr lease_json = lease->toElement();
1298 leases_json->add(lease_json);
1299 }
1300
1301 std::ostringstream s;
1302 s << leases_json->size() << " IPv4 lease(s) found.";
1303 ElementPtr args = Element::createMap();
1304 args->set("leases", leases_json);
1305 ConstElementPtr response =
1306 createAnswer(leases_json->size() > 0 ?
1309 s.str(), args);
1310 setResponse(handle, response);
1311
1312 } catch (const std::exception& ex) {
1313 setErrorResponse(handle, ex.what());
1314 return (CONTROL_RESULT_ERROR);
1315 }
1316
1317 return (0);
1318}
1319
1320int
1322 try {
1323 extractCommand(handle);
1324
1325 // arguments must always be present
1326 if (!cmd_args_ || (cmd_args_->getType() != Element::map)) {
1327 isc_throw(BadValue, "Command arguments missing or a not a map.");
1328 }
1329
1330 // the duid parameter is mandatory.
1331 ConstElementPtr duid = cmd_args_->get("duid");
1332 if (!duid) {
1333 isc_throw(BadValue, "'duid' parameter not specified");
1334 }
1335
1336 // The 'duid' argument is a string.
1337 if (duid->getType() != Element::string) {
1338 isc_throw(BadValue, "'duid' parameter must be a string");
1339 }
1340
1341 DUID duid_ = DUID::fromText(duid->stringValue());
1342
1343 Lease6Collection leases =
1344 LeaseMgrFactory::instance().getLeases6(duid_);
1345 ElementPtr leases_json = Element::createList();
1346 for (auto lease : leases) {
1347 ElementPtr lease_json = lease->toElement();
1348 leases_json->add(lease_json);
1349 }
1350
1351 std::ostringstream s;
1352 s << leases_json->size() << " IPv6 lease(s) found.";
1353 ElementPtr args = Element::createMap();
1354 args->set("leases", leases_json);
1355 ConstElementPtr response =
1356 createAnswer(leases_json->size() > 0 ?
1359 s.str(), args);
1360 setResponse(handle, response);
1361
1362 } catch (const std::exception& ex) {
1363 setErrorResponse(handle, ex.what());
1364 return (CONTROL_RESULT_ERROR);
1365 }
1366
1367 return (0);
1368}
1369
1370int
1372 bool v4;
1373 try {
1374 extractCommand(handle);
1375 v4 = (cmd_name_ == "lease4-get-by-hostname");
1376
1377 // arguments must always be present
1378 if (!cmd_args_ || (cmd_args_->getType() != Element::map)) {
1379 isc_throw(BadValue, "Command arguments missing or a not a map.");
1380 }
1381
1382 // the hostname parameter is mandatory.
1383 ConstElementPtr hostname = cmd_args_->get("hostname");
1384 if (!hostname) {
1385 isc_throw(BadValue, "'hostname' parameter not specified");
1386 }
1387
1388 // The 'hostname' argument is a string.
1389 if (hostname->getType() != Element::string) {
1390 isc_throw(BadValue, "'hostname' parameter must be a string");
1391 }
1392
1393 std::string hostname_ = hostname->stringValue();
1395 if (hostname_.empty()) {
1396 isc_throw(BadValue, "'hostname' parameter is empty");
1397 }
1398 boost::algorithm::to_lower(hostname_);
1399
1400 ElementPtr leases_json = Element::createList();
1401 if (v4) {
1402 Lease4Collection leases =
1403 LeaseMgrFactory::instance().getLeases4(hostname_);
1404
1405 for (auto lease : leases) {
1406 ElementPtr lease_json = lease->toElement();
1407 leases_json->add(lease_json);
1408 }
1409 } else {
1410 Lease6Collection leases =
1411 LeaseMgrFactory::instance().getLeases6(hostname_);
1412
1413 for (auto lease : leases) {
1414 ElementPtr lease_json = lease->toElement();
1415 leases_json->add(lease_json);
1416 }
1417 }
1418
1419 std::ostringstream s;
1420 s << leases_json->size()
1421 << " IPv" << (v4 ? "4" : "6")
1422 << " lease(s) found.";
1423 ElementPtr args = Element::createMap();
1424 args->set("leases", leases_json);
1425 ConstElementPtr response =
1426 createAnswer(leases_json->size() > 0 ?
1429 s.str(), args);
1430 setResponse(handle, response);
1431
1432 } catch (const std::exception& ex) {
1433 setErrorResponse(handle, ex.what());
1434 return (CONTROL_RESULT_ERROR);
1435 }
1436
1437 return (0);
1438}
1439
1440int
1442 Parameters p;
1443 Lease4Ptr lease4;
1444 try {
1445 extractCommand(handle);
1446 p = getParameters(false, cmd_args_);
1447
1448 switch (p.query_type) {
1449 case Parameters::TYPE_ADDR: {
1450 // If address was specified explicitly, let's use it as is.
1451 lease4 = LeaseMgrFactory::instance().getLease4(p.addr);
1452 if (!lease4) {
1453 setErrorResponse(handle, "IPv4 lease not found.", CONTROL_RESULT_EMPTY);
1454 return (0);
1455 }
1456 break;
1457 }
1459 if (!p.hwaddr) {
1460 isc_throw(InvalidParameter, "Program error: Query by hw-address "
1461 "requires hwaddr to be specified");
1462 }
1463
1464 // Let's see if there's such a lease at all.
1465 lease4 = LeaseMgrFactory::instance().getLease4(*p.hwaddr, p.subnet_id);
1466 if (!lease4) {
1467 setErrorResponse(handle, "IPv4 lease not found.", CONTROL_RESULT_EMPTY);
1468 return (0);
1469 }
1470 break;
1471 }
1473 if (!p.client_id) {
1474 isc_throw(InvalidParameter, "Program error: Query by client-id "
1475 "requires client-id to be specified");
1476 }
1477
1478 // Let's see if there's such a lease at all.
1479 lease4 = LeaseMgrFactory::instance().getLease4(*p.client_id, p.subnet_id);
1480 if (!lease4) {
1481 setErrorResponse(handle, "IPv4 lease not found.", CONTROL_RESULT_EMPTY);
1482 return (0);
1483 }
1484 break;
1485 }
1486 case Parameters::TYPE_DUID: {
1487 isc_throw(InvalidParameter, "Delete by duid is not allowed in v4.");
1488 break;
1489 }
1490 default: {
1491 isc_throw(InvalidOperation, "Unknown query type: " << static_cast<int>(p.query_type));
1492 break;
1493 }
1494 }
1495
1496 if (LeaseMgrFactory::instance().deleteLease(lease4)) {
1497 setSuccessResponse(handle, "IPv4 lease deleted.");
1499 } else {
1500 setErrorResponse (handle, "IPv4 lease not found.", CONTROL_RESULT_EMPTY);
1501 }
1502
1503 // Queue an NCR to remove DNS if configured and the lease has it.
1504 if (p.updateDDNS) {
1505 queueNCR(CHG_REMOVE, lease4);
1506 }
1507
1508 } catch (const std::exception& ex) {
1509 setErrorResponse(handle, ex.what());
1510 return (1);
1511 }
1512
1513 return (0);
1514}
1515
1516int
1518 try {
1519 extractCommand(handle);
1520
1521 // Arguments are mandatory.
1522 if (!cmd_args_ || (cmd_args_->getType() != Element::map)) {
1523 isc_throw(BadValue, "Command arguments missing or a not a map.");
1524 }
1525
1526 // At least one of the 'deleted-leases' or 'leases' must be present.
1527 auto deleted_leases = cmd_args_->get("deleted-leases");
1528 auto leases = cmd_args_->get("leases");
1529
1530 if (!deleted_leases && !leases) {
1531 isc_throw(BadValue, "neither 'deleted-leases' nor 'leases' parameter"
1532 " specified");
1533 }
1534
1535 // Make sure that 'deleted-leases' is a list, if present.
1536 if (deleted_leases && (deleted_leases->getType() != Element::list)) {
1537 isc_throw(BadValue, "the 'deleted-leases' parameter must be a list");
1538 }
1539
1540 // Make sure that 'leases' is a list, if present.
1541 if (leases && (leases->getType() != Element::list)) {
1542 isc_throw(BadValue, "the 'leases' parameter must be a list");
1543 }
1544
1545 // Parse deleted leases without deleting them from the database
1546 // yet. If any of the deleted leases or new leases appears to be
1547 // malformed we can easily rollback.
1548 std::list<std::pair<Parameters, Lease6Ptr> > parsed_deleted_list;
1549 if (deleted_leases) {
1550 auto leases_list = deleted_leases->listValue();
1551
1552 // Iterate over leases to be deleted.
1553 for (auto lease_params : leases_list) {
1554 // Parsing the lease may throw and it means that the lease
1555 // information is malformed.
1556 Parameters p = getParameters(true, lease_params);
1557 auto lease = getIPv6LeaseForDelete(p);
1558 parsed_deleted_list.push_back(std::make_pair(p, lease));
1559 }
1560 }
1561
1562 // Parse new/updated leases without affecting the database to detect
1563 // any errors that should cause an error response.
1564 std::list<Lease6Ptr> parsed_leases_list;
1565 if (leases) {
1566 ConstSrvConfigPtr config = CfgMgr::instance().getCurrentCfg();
1567
1568 // Iterate over all leases.
1569 auto leases_list = leases->listValue();
1570 for (auto lease_params : leases_list) {
1571
1572 Lease6Parser parser;
1573 bool force_update;
1574
1575 // If parsing the lease fails we throw, as it indicates that the
1576 // command is malformed.
1577 Lease6Ptr lease6 = parser.parse(config, lease_params, force_update);
1578 parsed_leases_list.push_back(lease6);
1579 }
1580 }
1581
1582 // Count successful deletions and updates.
1583 size_t success_count = 0;
1584
1585 ElementPtr failed_deleted_list;
1586 if (!parsed_deleted_list.empty()) {
1587
1588 // Iterate over leases to be deleted.
1589 for (auto lease_params_pair : parsed_deleted_list) {
1590
1591 // This part is outside of the try-catch because an exception
1592 // indicates that the command is malformed.
1593 Parameters p = lease_params_pair.first;
1594 auto lease = lease_params_pair.second;
1595
1596 try {
1597 if (lease) {
1598 // This may throw if the lease couldn't be deleted for
1599 // any reason, but we still want to proceed with other
1600 // leases.
1601 if (LeaseMgrFactory::instance().deleteLease(lease)) {
1602 ++success_count;
1604
1605 } else {
1606 // Lazy creation of the list of leases which failed to delete.
1607 if (!failed_deleted_list) {
1608 failed_deleted_list = Element::createList();
1609 }
1610
1611 // If the lease doesn't exist we also want to put it
1612 // on the list of leases which failed to delete. That
1613 // corresponds to the lease6-del command which returns
1614 // an error when the lease doesn't exist.
1615 failed_deleted_list->add(createFailedLeaseMap(p.lease_type,
1616 p.addr, p.duid,
1618 "lease not found"));
1619 }
1620 }
1621
1622 } catch (const std::exception& ex) {
1623 // Lazy creation of the list of leases which failed to delete.
1624 if (!failed_deleted_list) {
1625 failed_deleted_list = Element::createList();
1626 }
1627 failed_deleted_list->add(createFailedLeaseMap(p.lease_type,
1628 p.addr, p.duid,
1630 ex.what()));
1631 }
1632 }
1633 }
1634
1635 // Process leases to be added or/and updated.
1636 ElementPtr failed_leases_list;
1637 if (!parsed_leases_list.empty()) {
1638 ConstSrvConfigPtr config = CfgMgr::instance().getCurrentCfg();
1639
1640 // Iterate over all leases.
1641 for (auto lease : parsed_leases_list) {
1642
1643 try {
1644 if (!MultiThreadingMgr::instance().getMode()) {
1645 // Not multi-threading.
1646 addOrUpdate6(lease, true);
1647 } else {
1648 // Multi-threading, try to lock first to avoid a race.
1649 ResourceHandler resource_handler;
1650 if (resource_handler.tryLock(lease->type_, lease->addr_)) {
1651 addOrUpdate6(lease, true);
1652 } else {
1654 "ResourceBusy: IP address:" << lease->addr_
1655 << " could not be updated.");
1656 }
1657 }
1658
1659 ++success_count;
1660 } catch (const std::exception& ex) {
1661 // Lazy creation of the list of leases which failed to add/update.
1662 if (!failed_leases_list) {
1663 failed_leases_list = Element::createList();
1664 }
1665 failed_leases_list->add(createFailedLeaseMap(lease->type_,
1666 lease->addr_,
1667 lease->duid_,
1669 ex.what()));
1670 }
1671 }
1672 }
1673
1674 // Start preparing the response.
1675 ElementPtr args;
1676
1677 if (failed_deleted_list || failed_leases_list) {
1678 // If there are any failed leases, let's include them in the response.
1679 args = Element::createMap();
1680
1681 // failed-deleted-leases
1682 if (failed_deleted_list) {
1683 args->set("failed-deleted-leases", failed_deleted_list);
1684 }
1685
1686 // failed-leases
1687 if (failed_leases_list) {
1688 args->set("failed-leases", failed_leases_list);
1689 }
1690 }
1691
1692 // Send the success response and include failed leases.
1693 std::ostringstream resp_text;
1694 resp_text << "Bulk apply of " << success_count << " IPv6 leases completed.";
1695 auto answer = createAnswer(success_count > 0 ? CONTROL_RESULT_SUCCESS :
1696 CONTROL_RESULT_EMPTY, resp_text.str(), args);
1697 setResponse(handle, answer);
1698
1699 } catch (const std::exception& ex) {
1700 // Unable to parse the command and similar issues.
1701 setErrorResponse(handle, ex.what());
1702 return (CONTROL_RESULT_ERROR);
1703 }
1704
1705 return (CONTROL_RESULT_SUCCESS);
1706}
1707
1708int
1710 Parameters p;
1711 Lease6Ptr lease6;
1712 IOAddress addr(IOAddress::IPV6_ZERO_ADDRESS());
1713 try {
1714 extractCommand(handle);
1715 p = getParameters(true, cmd_args_);
1716
1717 switch (p.query_type) {
1718 case Parameters::TYPE_ADDR: {
1719 // If address was specified explicitly, let's use it as is.
1720
1721 // Let's see if there's such a lease at all.
1722 lease6 = LeaseMgrFactory::instance().getLease6(p.lease_type, p.addr);
1723 if (!lease6) {
1724 setErrorResponse(handle, "IPv6 lease not found.", CONTROL_RESULT_EMPTY);
1725 return (0);
1726 }
1727 break;
1728 }
1730 isc_throw(InvalidParameter, "Delete by hw-address is not allowed in v6.");
1731 break;
1732 }
1733 case Parameters::TYPE_DUID: {
1734 if (!p.duid) {
1735 isc_throw(InvalidParameter, "Program error: Query by duid "
1736 "requires duid to be specified");
1737 }
1738
1739 // Let's see if there's such a lease at all.
1740 lease6 = LeaseMgrFactory::instance().getLease6(p.lease_type, *p.duid,
1741 p.iaid, p.subnet_id);
1742 if (!lease6) {
1743 setErrorResponse(handle, "IPv6 lease not found.", CONTROL_RESULT_EMPTY);
1744 return (0);
1745 }
1746 break;
1747 }
1748 default: {
1749 isc_throw(InvalidOperation, "Unknown query type: " << static_cast<int>(p.query_type));
1750 break;
1751 }
1752 }
1753
1754 if (LeaseMgrFactory::instance().deleteLease(lease6)) {
1755 setSuccessResponse(handle, "IPv6 lease deleted.");
1757 } else {
1758 setErrorResponse (handle, "IPv6 lease not found.", CONTROL_RESULT_EMPTY);
1759 }
1760
1761 // Queue an NCR to remove DNS if configured and the lease has it.
1762 if (p.updateDDNS) {
1763 queueNCR(CHG_REMOVE, lease6);
1764 }
1765
1766 } catch (const std::exception& ex) {
1767 setErrorResponse(handle, ex.what());
1768 return (1);
1769 }
1770
1771 return (0);
1772}
1773
1774int
1776 try {
1777 extractCommand(handle);
1778
1779 // We need the lease to be specified.
1780 if (!cmd_args_) {
1781 isc_throw(isc::BadValue, "no parameters specified for lease4-update command");
1782 }
1783
1784 // Get the parameters specified by the user first.
1785 ConstSrvConfigPtr config = CfgMgr::instance().getCurrentCfg();
1786 Lease4Ptr lease4;
1787 Lease4Parser parser;
1788 bool force_create = false;
1789
1790 // The parser does sanity checks (if the address is in scope, if
1791 // subnet-id is valid, etc)
1792 lease4 = parser.parse(config, cmd_args_, force_create);
1793 bool added = false;
1794 if (!MultiThreadingMgr::instance().getMode()) {
1795 // Not multi-threading.
1796 added = addOrUpdate4(lease4, force_create);
1797 } else {
1798 // Multi-threading, try to lock first to avoid a race.
1799 ResourceHandler4 resource_handler;
1800 if (resource_handler.tryLock4(lease4->addr_)) {
1801 added = addOrUpdate4(lease4, force_create);
1802 } else {
1804 "ResourceBusy: IP address:" << lease4->addr_
1805 << " could not be updated.");
1806 }
1807 }
1808
1809 if (added) {
1810 setSuccessResponse(handle, "IPv4 lease added.");
1811 } else {
1812 setSuccessResponse(handle, "IPv4 lease updated.");
1813 }
1814 } catch (const std::exception& ex) {
1815 setErrorResponse(handle, ex.what());
1816 return (1);
1817 }
1818
1819 return (0);
1820}
1821
1822int
1824 try {
1825 extractCommand(handle);
1826
1827 // We need the lease to be specified.
1828 if (!cmd_args_) {
1829 isc_throw(isc::BadValue, "no parameters specified for lease6-update command");
1830 }
1831
1832 // Get the parameters specified by the user first.
1833 ConstSrvConfigPtr config = CfgMgr::instance().getCurrentCfg();
1834 Lease6Ptr lease6;
1835 Lease6Parser parser;
1836 bool force_create = false;
1837
1838 // The parser does sanity checks (if the address is in scope, if
1839 // subnet-id is valid, etc)
1840 lease6 = parser.parse(config, cmd_args_, force_create);
1841 bool added = false;
1842 if (!MultiThreadingMgr::instance().getMode()) {
1843 // Not multi-threading.
1844 added = addOrUpdate6(lease6, force_create);
1845 } else {
1846 // Multi-threading, try to lock first to avoid a race.
1847 ResourceHandler resource_handler;
1848 if (resource_handler.tryLock(lease6->type_, lease6->addr_)) {
1849 added = addOrUpdate6(lease6, force_create);
1850 } else {
1852 "ResourceBusy: IP address:" << lease6->addr_
1853 << " could not be updated.");
1854 }
1855 }
1856
1857 if (added) {
1858 setSuccessResponse(handle, "IPv6 lease added.");
1859 } else {
1860 setSuccessResponse(handle, "IPv6 lease updated.");
1861 }
1862 } catch (const std::exception& ex) {
1863 setErrorResponse(handle, ex.what());
1864 return (1);
1865 }
1866
1867 return (0);
1868}
1869
1870int
1872 try {
1873 extractCommand(handle);
1874
1875 SimpleParser parser;
1876 SubnetID id = 0;
1877
1878 size_t num = 0; // number of leases deleted
1879 stringstream ids; // a text with subnet-ids being wiped
1880
1881 // The subnet-id parameter is now optional.
1882 if (cmd_args_ && cmd_args_->contains("subnet-id")) {
1883 id = parser.getUint32(cmd_args_, "subnet-id");
1884 }
1885
1886 if (id) {
1887 // Wipe a single subnet.
1888 num = LeaseMgrFactory::instance().wipeLeases4(id);
1889 ids << " " << id;
1890
1891 auto observation = StatsMgr::instance().getObservation(
1892 StatsMgr::generateName("subnet", id, "declined-addresses"));
1893
1894 int64_t previous_declined = 0;
1895
1896 if (observation) {
1897 previous_declined = observation->getInteger().first;
1898 }
1899
1900 StatsMgr::instance().setValue(
1901 StatsMgr::generateName("subnet", id, "assigned-addresses"),
1902 int64_t(0));
1903
1904 StatsMgr::instance().setValue(
1905 StatsMgr::generateName("subnet", id, "declined-addresses"),
1906 int64_t(0));
1907
1908 StatsMgr::instance().addValue("declined-addresses", -previous_declined);
1909 } else {
1910 // Wipe them all!
1911 ConstSrvConfigPtr config = CfgMgr::instance().getCurrentCfg();
1912 ConstCfgSubnets4Ptr subnets = config->getCfgSubnets4();
1913 const Subnet4Collection * subs = subnets->getAll();
1914
1915 // Go over all subnets and wipe leases in each of them.
1916 for (auto sub : *subs) {
1917 num += LeaseMgrFactory::instance().wipeLeases4(sub->getID());
1918 ids << " " << sub->getID();
1919 StatsMgr::instance().setValue(
1920 StatsMgr::generateName("subnet", sub->getID(), "assigned-addresses"),
1921 int64_t(0));
1922
1923 StatsMgr::instance().setValue(
1924 StatsMgr::generateName("subnet", sub->getID(), "declined-addresses"),
1925 int64_t(0));
1926 }
1927
1928 StatsMgr::instance().setValue("declined-addresses", int64_t(0));
1929 }
1930
1931 stringstream tmp;
1932 tmp << "Deleted " << num << " IPv4 lease(s) from subnet(s)" << ids.str();
1934 : CONTROL_RESULT_EMPTY, tmp.str());
1935 setResponse(handle, response);
1936 } catch (const std::exception& ex) {
1937 setErrorResponse(handle, ex.what());
1938 return (1);
1939 }
1940
1941 return (0);
1942}
1943
1944int
1946 try {
1947 extractCommand(handle);
1948
1949 SimpleParser parser;
1950 SubnetID id = 0;
1951
1952 size_t num = 0; // number of leases deleted
1953 stringstream ids; // a text with subnet-ids being wiped
1954
1960
1961 // The subnet-id parameter is now optional.
1962 if (cmd_args_ && cmd_args_->contains("subnet-id")) {
1963 id = parser.getUint32(cmd_args_, "subnet-id");
1964 }
1965
1966 if (id) {
1967 // Wipe a single subnet.
1968 num = LeaseMgrFactory::instance().wipeLeases6(id);
1969 ids << " " << id;
1970
1971 auto observation = StatsMgr::instance().getObservation(
1972 StatsMgr::generateName("subnet", id, "declined-addresses"));
1973
1974 int64_t previous_declined = 0;
1975
1976 if (observation) {
1977 previous_declined = observation->getInteger().first;
1978 }
1979
1980 StatsMgr::instance().setValue(
1981 StatsMgr::generateName("subnet", id, "assigned-nas" ),
1982 int64_t(0));
1983
1984 StatsMgr::instance().setValue(
1985 StatsMgr::generateName("subnet", id, "assigned-pds"),
1986 int64_t(0));
1987
1988 StatsMgr::instance().setValue(
1989 StatsMgr::generateName("subnet", id, "declined-addresses"),
1990 int64_t(0));
1991
1992 StatsMgr::instance().addValue("declined-addresses", -previous_declined);
1993 } else {
1994 // Wipe them all!
1995 ConstSrvConfigPtr config = CfgMgr::instance().getCurrentCfg();
1996 ConstCfgSubnets6Ptr subnets = config->getCfgSubnets6();
1997 const Subnet6Collection * subs = subnets->getAll();
1998
1999 // Go over all subnets and wipe leases in each of them.
2000 for (auto sub : *subs) {
2001 num += LeaseMgrFactory::instance().wipeLeases6(sub->getID());
2002 ids << " " << sub->getID();
2003 StatsMgr::instance().setValue(
2004 StatsMgr::generateName("subnet", sub->getID(), "assigned-nas" ),
2005 int64_t(0));
2006
2007 StatsMgr::instance().setValue(
2008 StatsMgr::generateName("subnet", sub->getID(), "assigned-pds"),
2009 int64_t(0));
2010
2011 StatsMgr::instance().setValue(
2012 StatsMgr::generateName("subnet", sub->getID(), "declined-addresses"),
2013 int64_t(0));
2014 }
2015
2016 StatsMgr::instance().setValue("declined-addresses", int64_t(0));
2017 }
2018
2019 stringstream tmp;
2020 tmp << "Deleted " << num << " IPv6 lease(s) from subnet(s)" << ids.str();
2022 : CONTROL_RESULT_EMPTY, tmp.str());
2023 setResponse(handle, response);
2024 } catch (const std::exception& ex) {
2025 setErrorResponse(handle, ex.what());
2026 return (1);
2027 }
2028
2029 return (0);
2030}
2031
2034 Lease6Ptr lease6;
2035
2036 switch (parameters.query_type) {
2037 case Parameters::TYPE_ADDR: {
2038 // If address was specified explicitly, let's use it as is.
2039
2040 // Let's see if there's such a lease at all.
2041 lease6 = LeaseMgrFactory::instance().getLease6(parameters.lease_type,
2042 parameters.addr);
2043 if (!lease6) {
2044 lease6.reset(new Lease6());
2045 lease6->addr_ = parameters.addr;
2046 }
2047 break;
2048 }
2050 isc_throw(InvalidParameter, "Delete by hw-address is not allowed in v6.");
2051 break;
2052 }
2053 case Parameters::TYPE_DUID: {
2054 if (!parameters.duid) {
2055 isc_throw(InvalidParameter, "Program error: Query by duid "
2056 "requires duid to be specified");
2057 }
2058
2059 // Let's see if there's such a lease at all.
2060 lease6 = LeaseMgrFactory::instance().getLease6(parameters.lease_type,
2061 *parameters.duid,
2062 parameters.iaid,
2063 parameters.subnet_id);
2064 break;
2065 }
2066 default:
2067 isc_throw(InvalidOperation, "Unknown query type: "
2068 << static_cast<int>(parameters.query_type));
2069 }
2070
2071 return (lease6);
2072}
2073
2076 short family) const {
2077 ConstElementPtr param = params->get(name);
2078 if (!param) {
2079 isc_throw(BadValue, "'" << name << "' parameter is missing.");
2080 }
2081
2082 if (param->getType() != Element::string) {
2083 isc_throw(BadValue, "'" << name << "' is not a string.");
2084 }
2085
2086 IOAddress addr(0);
2087 try {
2088 addr = IOAddress(param->stringValue());
2089 } catch (const std::exception& ex) {
2090 isc_throw(BadValue, "'" << param->stringValue()
2091 << "' is not a valid IP address.");
2092 }
2093
2094 if (addr.getFamily() != family) {
2095 isc_throw(BadValue, "Invalid "
2096 << (family == AF_INET6 ? "IPv6" : "IPv4")
2097 << " address specified: " << param->stringValue());
2098 }
2099
2100 return (addr);
2101}
2102
2103int
2105 std::stringstream ss;
2106 int resp_code = CONTROL_RESULT_ERROR;
2107
2108 try {
2109 extractCommand(handle);
2110
2111 // Get the target lease address. Invalid value will throw.
2112 IOAddress addr = getAddressParam(cmd_args_, "ip-address", AF_INET);
2113
2114 if (!CfgMgr::instance().getD2ClientMgr().ddnsEnabled()) {
2115 ss << "DDNS updating is not enabled";
2116 } else {
2117 // Find the lease.
2118 Lease4Ptr lease = LeaseMgrFactory::instance().getLease4(addr);
2119 if (!lease) {
2120 ss << "No lease found for: " << addr.toText();
2121 resp_code = CONTROL_RESULT_EMPTY;
2122 } else if (lease->hostname_.empty()) {
2123 ss << "Lease for: " << addr.toText()
2124 << ", has no hostname, nothing to update";
2125 } else if (!lease->fqdn_fwd_ && !lease->fqdn_rev_) {
2126 ss << "Neither forward nor reverse updates enabled for lease for: "
2127 << addr.toText();
2128 } else {
2129 // We have a lease with a hostname and updates in at least
2130 // one direction enabled. Queue an NCR for it.
2131 queueNCR(CHG_ADD, lease);
2132 ss << "NCR generated for: " << addr.toText()
2133 << ", hostname: " << lease->hostname_;
2134 setSuccessResponse(handle, ss.str());
2136 return (0);
2137 }
2138 }
2139 } catch (const std::exception& ex) {
2140 ss << ex.what();
2141 }
2142
2144 setErrorResponse(handle, ss.str(), resp_code);
2145 return (resp_code == CONTROL_RESULT_EMPTY ? 0 : 1);
2146}
2147
2148int
2150 std::stringstream ss;
2151 int resp_code = CONTROL_RESULT_ERROR;
2152
2153 try {
2154 extractCommand(handle);
2155
2156 // Get the target lease address. Invalid value will throw.
2157 IOAddress addr = getAddressParam(cmd_args_, "ip-address", AF_INET6);
2158
2159 if (!CfgMgr::instance().getD2ClientMgr().ddnsEnabled()) {
2160 ss << "DDNS updating is not enabled";
2161 } else {
2162 // Find the lease.
2163 Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(Lease::TYPE_NA, addr);
2164 if (!lease) {
2165 ss << "No lease found for: " << addr.toText();
2166 resp_code = CONTROL_RESULT_EMPTY;
2167 } else if (lease->hostname_.empty()) {
2168 ss << "Lease for: " << addr.toText()
2169 << ", has no hostname, nothing to update";
2170 } else if (!lease->fqdn_fwd_ && !lease->fqdn_rev_) {
2171 ss << "Neither forward nor reverse updates enabled for lease for: "
2172 << addr.toText();
2173 } else {
2174 // We have a lease with a hostname and updates in at least
2175 // one direction enabled. Queue an NCR for it.
2176 queueNCR(CHG_ADD, lease);
2177 ss << "NCR generated for: " << addr.toText()
2178 << ", hostname: " << lease->hostname_;
2179 setSuccessResponse(handle, ss.str());
2181 return (0);
2182 }
2183 }
2184 } catch (const std::exception& ex) {
2185 ss << ex.what();
2186 }
2187
2189 setErrorResponse(handle, ss.str(), resp_code);
2190 return (resp_code == CONTROL_RESULT_EMPTY ? 0 : 1);
2191}
2192
2195 const IOAddress& lease_address,
2196 const DuidPtr& duid,
2197 const int control_result,
2198 const std::string& error_message) const {
2199 auto failed_lease_map = Element::createMap();
2200 failed_lease_map->set("type", Element::create(Lease::typeToText(lease_type)));
2201
2202 if (!lease_address.isV6Zero()) {
2203 failed_lease_map->set("ip-address", Element::create(lease_address.toText()));
2204
2205 } else if (duid) {
2206 failed_lease_map->set("duid", Element::create(duid->toText()));
2207 }
2208
2209 // Associate the result with the lease.
2210 failed_lease_map->set("result", Element::create(control_result));
2211 failed_lease_map->set("error-message", Element::create(error_message));
2212
2213 return (failed_lease_map);
2214}
2215
2216int
2218 return (impl_->leaseAddHandler(handle));
2219}
2220
2221int
2223 return (impl_->lease6BulkApplyHandler(handle));
2224}
2225
2226int
2228 return (impl_->leaseGetHandler(handle));
2229}
2230
2231int
2233 return (impl_->leaseGetAllHandler(handle));
2234}
2235
2236int
2238 return (impl_->leaseGetPageHandler(handle));
2239}
2240
2241int
2243 return (impl_->leaseGetByHwAddressHandler(handle));
2244}
2245
2246int
2248 return (impl_->leaseGetByClientIdHandler(handle));
2249}
2250
2251int
2253 return (impl_->leaseGetByDuidHandler(handle));
2254}
2255
2256int
2258 return (impl_->leaseGetByHostnameHandler(handle));
2259}
2260
2261int
2263 return (impl_->lease4DelHandler(handle));
2264}
2265
2266int
2268 return (impl_->lease6DelHandler(handle));
2269}
2270
2271int
2273 return (impl_->lease4UpdateHandler(handle));
2274}
2275
2276int
2278 return (impl_->lease6UpdateHandler(handle));
2279}
2280
2281int
2284 return (impl_->lease4WipeHandler(handle));
2285}
2286
2287int
2290 return (impl_->lease6WipeHandler(handle));
2291}
2292
2293int
2295 return (impl_->lease4ResendDdnsHandler(handle));
2296}
2297
2298int
2300 return (impl_->lease6ResendDdnsHandler(handle));
2301}
2302
2304 :impl_(new LeaseCmdsImpl()) {
2305}
2306
2307} // end of namespace lease_cmds
2308} // end of namespace isc
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
A generic exception that is thrown if a function is called in a prohibited way.
A generic exception that is thrown if a parameter given to a method or function is considered invalid...
Base class that command handler implementers may use for common tasks.
Definition: cmds_impl.h:21
std::string cmd_name_
Stores the command name extracted by a call to extractCommand.
Definition: cmds_impl.h:69
void setErrorResponse(hooks::CalloutHandle &handle, const std::string &text, int status=CONTROL_RESULT_ERROR)
Set the callout argument "response" to indicate an error.
Definition: cmds_impl.h:54
data::ConstElementPtr cmd_args_
Stores the command arguments extracted by a call to extractCommand.
Definition: cmds_impl.h:72
void extractCommand(hooks::CalloutHandle &handle)
Extracts the command name and arguments from a Callout handle.
Definition: cmds_impl.h:29
void setSuccessResponse(hooks::CalloutHandle &handle, const std::string &text)
Set the callout argument "response" to indicate success.
Definition: cmds_impl.h:43
void setResponse(hooks::CalloutHandle &handle, data::ConstElementPtr &response)
Set the callout argument "response" to the given response.
Definition: cmds_impl.h:64
uint32_t getUint32(isc::data::ConstElementPtr scope, const std::string &name)
Returns a value converted to uint32_t.
Database duplicate entry error.
Definition: db_exceptions.h:30
Holds DUID (DHCPv6 Unique Identifier)
Definition: duid.h:27
Wraps value holding size of the page with leases.
Definition: lease_mgr.h:44
Attempt to update lease that was not there.
Thrown by lock users when a resource lock cannot be obtained.
Resource race avoidance RAII handler for DHCPv4.
bool tryLock4(const asiolink::IOAddress &addr)
Tries to acquires a resource.
Resource race avoidance RAII handler.
bool tryLock(Lease::Type type, const asiolink::IOAddress &addr)
Tries to acquires a resource.
Per-packet callout handle.
Parser for Lease4 structure.
Definition: lease_parser.h:35
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.
Definition: lease_parser.cc:26
Parser for Lease6 structure.
Definition: lease_parser.h:76
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.
Parameters specified for lease commands.
Definition: lease_cmds.cc:56
uint32_t iaid
IAID identifier used for v6 leases.
Definition: lease_cmds.cc:114
HWAddrPtr hwaddr
Specifies hardware address (used when query_type is TYPE_HWADDR)
Definition: lease_cmds.cc:74
Lease::Type lease_type
Lease type (NA,TA or PD) used for v6 leases.
Definition: lease_cmds.cc:111
Type query_type
specifies parameter types
Definition: lease_cmds.cc:108
Type
specifies type of query (by IP addr, by hwaddr, by DUID)
Definition: lease_cmds.cc:60
@ TYPE_DUID
query by DUID (v6 only)
Definition: lease_cmds.cc:63
@ TYPE_CLIENT_ID
query by client identifier (v4 only).
Definition: lease_cmds.cc:64
@ TYPE_HWADDR
query by hardware address (v4 only)
Definition: lease_cmds.cc:62
@ TYPE_ADDR
query by IP address (either v4 or v6)
Definition: lease_cmds.cc:61
isc::dhcp::ClientIdPtr client_id
Specifies identifier value (used when query_type is TYPE_CLIENT_ID)
Definition: lease_cmds.cc:80
static Type txtToType(const std::string &txt)
Attempts to covert text to one of specified types.
Definition: lease_cmds.cc:91
bool updateDDNS
Indicates whether or not DNS should be updated.
Definition: lease_cmds.cc:117
IOAddress addr
Specifies IPv4/v6 address (used when query_type is TYPE_ADDR)
Definition: lease_cmds.cc:71
SubnetID subnet_id
Specifies subnet-id (always used)
Definition: lease_cmds.cc:68
isc::dhcp::DuidPtr duid
Specifies identifier value (used when query_type is TYPE_DUID)
Definition: lease_cmds.cc:77
Wrapper class around reservation command handlers.
Definition: lease_cmds.cc:52
int lease4DelHandler(CalloutHandle &handle)
lease4-del command handler
Definition: lease_cmds.cc:1441
IOAddress getAddressParam(ConstElementPtr params, const std::string name, short family=AF_INET) const
Definition: lease_cmds.cc:2075
static void updateStatsOnUpdate(const Lease4Ptr &existing, const Lease4Ptr &lease)
Update stats when updating lease.
Definition: lease_cmds.cc:487
ElementPtr createFailedLeaseMap(const Lease::Type &lease_type, const IOAddress &lease_address, const DuidPtr &duid, const int control_result, const std::string &error_message) const
Returns a map holding brief information about a lease which failed to be deleted, updated or added.
Definition: lease_cmds.cc:2194
static bool addOrUpdate6(Lease6Ptr lease, bool force_create)
Add or update lease.
Definition: lease_cmds.cc:676
int lease6BulkApplyHandler(CalloutHandle &handle)
lease6-bulk-apply command handler
Definition: lease_cmds.cc:1517
int leaseGetByDuidHandler(hooks::CalloutHandle &handle)
lease6-get-by-duid command handler
Definition: lease_cmds.cc:1321
int lease6UpdateHandler(CalloutHandle &handle)
lease6-update handler
Definition: lease_cmds.cc:1823
int leaseGetPageHandler(hooks::CalloutHandle &handle)
lease4-get-page, lease6-get-page commands handler
Definition: lease_cmds.cc:1102
Lease6Ptr getIPv6LeaseForDelete(const Parameters &parameters) const
Convenience function fetching IPv6 address to be used to delete a lease.
Definition: lease_cmds.cc:2033
int leaseGetByHostnameHandler(hooks::CalloutHandle &handle)
lease4-get-by-hostname and lease6-get-by-hostname commands handler
Definition: lease_cmds.cc:1371
int lease6DelHandler(CalloutHandle &handle)
lease6-del command handler
Definition: lease_cmds.cc:1709
int leaseGetByHwAddressHandler(hooks::CalloutHandle &handle)
lease4-get-by-hw-address command handler
Definition: lease_cmds.cc:1221
int leaseGetHandler(CalloutHandle &handle)
lease4-get, lease6-get command handler
Definition: lease_cmds.cc:929
static bool addOrUpdate4(Lease4Ptr lease, bool force_create)
Add or update lease.
Definition: lease_cmds.cc:645
int lease6WipeHandler(CalloutHandle &handle)
lease6-wipe handler
Definition: lease_cmds.cc:1945
int leaseGetByClientIdHandler(hooks::CalloutHandle &handle)
lease4-get-by-client-id command handler
Definition: lease_cmds.cc:1271
int lease6ResendDdnsHandler(CalloutHandle &handle)
lease6-resend-ddns handler
Definition: lease_cmds.cc:2149
int leaseAddHandler(CalloutHandle &handle)
lease4-add, lease6-add command handler
Definition: lease_cmds.cc:708
int lease4ResendDdnsHandler(CalloutHandle &handle)
lease4-resend-ddns handler
Definition: lease_cmds.cc:2104
static void updateStatsOnAdd(const Lease4Ptr &lease)
Update stats when adding lease.
Definition: lease_cmds.cc:450
Parameters getParameters(bool v6, const ConstElementPtr &args)
Extracts parameters required for reservation-get and reservation-del.
Definition: lease_cmds.cc:811
int lease4UpdateHandler(CalloutHandle &handle)
lease4-update handler
Definition: lease_cmds.cc:1775
int lease4WipeHandler(CalloutHandle &handle)
lease4-wipe handler
Definition: lease_cmds.cc:1871
int leaseGetAllHandler(CalloutHandle &handle)
lease4-get-all, lease6-get-all commands handler
Definition: lease_cmds.cc:1019
static void updateStatsOnDelete(const Lease4Ptr &lease)
Update stats when deleting lease.
Definition: lease_cmds.cc:608
int lease4ResendDdnsHandler(hooks::CalloutHandle &handle)
lease4-resend-ddns command handler
Definition: lease_cmds.cc:2294
int lease6WipeHandler(hooks::CalloutHandle &handle)
lease6-wipe handler
Definition: lease_cmds.cc:2288
int leaseGetPageHandler(hooks::CalloutHandle &handle)
lease4-get-page, lease6-get-page commands handler
Definition: lease_cmds.cc:2237
int lease6DelHandler(hooks::CalloutHandle &handle)
lease6-del command handler
Definition: lease_cmds.cc:2267
int leaseGetAllHandler(hooks::CalloutHandle &handle)
lease4-get-all, lease6-get-all commands handler
Definition: lease_cmds.cc:2232
int leaseGetByHostnameHandler(hooks::CalloutHandle &handle)
lease4-get-by-hostname and lease6-get-by-hostname commands handler
Definition: lease_cmds.cc:2257
int lease4DelHandler(hooks::CalloutHandle &handle)
lease4-del command handler
Definition: lease_cmds.cc:2262
int leaseAddHandler(hooks::CalloutHandle &handle)
lease4-add, lease6-add command handler
Definition: lease_cmds.cc:2217
int leaseGetByClientIdHandler(hooks::CalloutHandle &handle)
lease4-get-by-client-id command handler
Definition: lease_cmds.cc:2247
int lease4UpdateHandler(hooks::CalloutHandle &handle)
lease4-update handler
Definition: lease_cmds.cc:2272
int leaseGetHandler(hooks::CalloutHandle &handle)
lease4-get, lease6-get command handler
Definition: lease_cmds.cc:2227
int leaseGetByHwAddressHandler(hooks::CalloutHandle &handle)
lease4-get-by-hw-address command handler
Definition: lease_cmds.cc:2242
int lease6UpdateHandler(hooks::CalloutHandle &handle)
lease6-update handler
Definition: lease_cmds.cc:2277
int leaseGetByDuidHandler(hooks::CalloutHandle &handle)
lease6-get-by-duid command handler
Definition: lease_cmds.cc:2252
int lease6BulkApplyHandler(hooks::CalloutHandle &handle)
lease6-bulk-apply command handler
Definition: lease_cmds.cc:2222
int lease4WipeHandler(hooks::CalloutHandle &handle)
lease4-wipe handler
Definition: lease_cmds.cc:2282
int lease6ResendDdnsHandler(hooks::CalloutHandle &handle)
lease6-resend-ddns command handler
Definition: lease_cmds.cc:2299
RAII class creating a critical section.
This file contains several functions and constants that are used for handling commands and responses ...
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
const isc::log::MessageID LEASE_CMDS_RESEND_DDNS4_FAILED
const isc::log::MessageID LEASE_CMDS_ADD4_FAILED
const isc::log::MessageID LEASE_CMDS_ADD6
const isc::log::MessageID LEASE_CMDS_ADD4
const isc::log::MessageID LEASE_CMDS_RESEND_DDNS4
const isc::log::MessageID LEASE_CMDS_RESEND_DDNS6_FAILED
const isc::log::MessageID LEASE_CMDS_RESEND_DDNS6
const isc::log::MessageID LEASE_CMDS_ADD6_FAILED
An abstract API for lease database.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
Definition: macros.h:32
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
Definition: macros.h:20
const int CONTROL_RESULT_EMPTY
Status code indicating that the specified command was completed correctly, but failed to produce any ...
const int CONTROL_RESULT_ERROR
Status code indicating a general failure.
ConstElementPtr createAnswer(const int status_code, const std::string &text, const ConstElementPtr &arg)
const int CONTROL_RESULT_SUCCESS
Status code indicating a successful operation.
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:27
boost::shared_ptr< Element > ElementPtr
Definition: data.h:24
boost::shared_ptr< const SrvConfig > ConstSrvConfigPtr
Const pointer to the SrvConfig.
Definition: srv_config.h:1168
void queueNCR(const NameChangeType &chg_type, const Lease4Ptr &lease)
Creates name change request from the DHCPv4 lease.
boost::shared_ptr< DUID > DuidPtr
Definition: duid.h:20
boost::shared_ptr< Lease6 > Lease6Ptr
Pointer to a Lease6 structure.
Definition: lease.h:503
std::vector< Lease6Ptr > Lease6Collection
A collection of IPv6 leases.
Definition: lease.h:661
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.
Definition: subnet.h:964
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
Definition: hwaddr.h:154
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.
Definition: subnet.h:893
uint32_t SubnetID
Defines unique IPv4 or IPv6 subnet identifier.
Definition: subnet_id.h:24
boost::shared_ptr< ClientId > ClientIdPtr
Shared pointer to a Client ID.
Definition: duid.h:103
boost::shared_ptr< const CfgSubnets4 > ConstCfgSubnets4Ptr
Const pointer.
Definition: cfg_subnets4.h:336
boost::shared_ptr< const CfgSubnets6 > ConstCfgSubnets6Ptr
Const pointer.
Definition: cfg_subnets6.h:334
std::vector< Lease4Ptr > Lease4Collection
A collection of IPv4 leases.
Definition: lease.h:498
boost::shared_ptr< Lease4 > Lease4Ptr
Pointer to a Lease4 structure.
Definition: lease.h:284
isc::log::Logger lease_cmds_logger("lease-cmds-hooks")
Definition: edns.h:19
Defines the logger used by the top-level component of kea-lfc.
Hardware type that represents information from DHCPv4 packet.
Definition: hwaddr.h:20
Structure that holds a lease for IPv6 address and/or prefix.
Definition: lease.h:514
a common structure for IPv4 and IPv6 leases
Definition: lease.h:31
Type
Type of lease or pool.
Definition: lease.h:46