Kea 2.5.8
lease_cmds.cc
Go to the documentation of this file.
1// Copyright (C) 2017-2024 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>
27#include <lease_parser.h>
28#include <lease_cmds_log.h>
29#include <stats/stats_mgr.h>
30#include <util/encode/encode.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
337 int
339
351 Parameters getParameters(bool v6, const ConstElementPtr& args);
352
370 Lease6Ptr getIPv6LeaseForDelete(const Parameters& parameters) const;
371
387 const IOAddress& lease_address,
388 const DuidPtr& duid,
389 const int control_result,
390 const std::string& error_message) const;
391
402 IOAddress getAddressParam(ConstElementPtr params, const std::string name,
403 short family = AF_INET) const;
404
408 static void updateStatsOnAdd(const Lease4Ptr& lease);
409
413 static void updateStatsOnAdd(const Lease6Ptr& lease);
414
419 static void updateStatsOnUpdate(const Lease4Ptr& existing,
420 const Lease4Ptr& lease);
421
426 static void updateStatsOnUpdate(const Lease6Ptr& existing,
427 const Lease6Ptr& lease);
428
432 static void updateStatsOnDelete(const Lease4Ptr& lease);
433
437 static void updateStatsOnDelete(const Lease6Ptr& lease);
438
447 static bool addOrUpdate4(Lease4Ptr lease, bool force_create);
448
457 static bool addOrUpdate6(Lease6Ptr lease, bool force_create);
458
463 inline static ConstElementPtr getExtendedInfo6(const Lease6Ptr& lease) {
464 ConstElementPtr user_context = lease->getContext();
465 if (!user_context || (user_context->getType() != Element::map)) {
466 return (ConstElementPtr());
467 }
468 ConstElementPtr isc = user_context->get("ISC");
469 if (!isc || (isc->getType() != Element::map)) {
470 return (ConstElementPtr());
471 }
472 return (isc->get("relay-info"));
473 }
474};
475
476void
478 if (!lease->stateExpiredReclaimed()) {
480 StatsMgr::generateName("subnet", lease->subnet_id_,
481 "assigned-addresses"),
482 static_cast<int64_t>(1));
483
484 PoolPtr pool;
485 auto const& subnet = CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getBySubnetId(lease->subnet_id_);
486 if (subnet) {
487 pool = subnet->getPool(Lease::TYPE_V4, lease->addr_, false);
488 if (pool) {
490 StatsMgr::generateName("subnet", subnet->getID(),
491 StatsMgr::generateName("pool", pool->getID(),
492 "assigned-addresses")),
493 static_cast<int64_t>(1));
494 }
495 }
496
497 if (lease->stateDeclined()) {
498 StatsMgr::instance().addValue("declined-addresses", static_cast<int64_t>(1));
499
501 StatsMgr::generateName("subnet", lease->subnet_id_,
502 "declined-addresses"),
503 static_cast<int64_t>(1));
504
505 if (pool) {
507 StatsMgr::generateName("subnet", subnet->getID(),
508 StatsMgr::generateName("pool", pool->getID(),
509 "declined-addresses")),
510 static_cast<int64_t>(1));
511 }
512 }
513 }
514}
515
516void
518 if (!lease->stateExpiredReclaimed()) {
520 StatsMgr::generateName("subnet", lease->subnet_id_,
521 lease->type_ == Lease::TYPE_NA ?
522 "assigned-nas" : "assigned-pds"),
523 static_cast<int64_t>(1));
524
525 PoolPtr pool;
526 auto const& subnet = CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getBySubnetId(lease->subnet_id_);
527 if (subnet) {
528 pool = subnet->getPool(lease->type_, lease->addr_, false);
529 if (pool) {
531 StatsMgr::generateName("subnet", subnet->getID(),
532 StatsMgr::generateName(lease->type_ == Lease::TYPE_NA ?
533 "pool" : "pd-pool", pool->getID(),
534 lease->type_ == Lease::TYPE_NA ?
535 "assigned-nas" : "assigned-pds")),
536 static_cast<int64_t>(1));
537 }
538 }
539
540 if (lease->stateDeclined()) {
541 StatsMgr::instance().addValue("declined-addresses", static_cast<int64_t>(1));
542
544 StatsMgr::generateName("subnet", lease->subnet_id_,
545 "declined-addresses"),
546 static_cast<int64_t>(1));
547
548 if (pool) {
550 StatsMgr::generateName("subnet", subnet->getID(),
551 StatsMgr::generateName("pool", pool->getID(),
552 "declined-addresses")),
553 static_cast<int64_t>(1));
554 }
555 }
556 }
557}
558
559void
561 const Lease4Ptr& lease) {
562 if (!existing->stateExpiredReclaimed()) {
563 ConstSubnet4Ptr subnet;
564 PoolPtr pool;
565
566 // old lease is non expired-reclaimed
567 if (existing->subnet_id_ != lease->subnet_id_) {
569 StatsMgr::generateName("subnet", existing->subnet_id_,
570 "assigned-addresses"),
571 static_cast<int64_t>(-1));
572
573 subnet = CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getBySubnetId(existing->subnet_id_);
574 if (subnet) {
575 pool = subnet->getPool(Lease::TYPE_V4, existing->addr_, false);
576 if (pool) {
578 StatsMgr::generateName("subnet", subnet->getID(),
579 StatsMgr::generateName("pool", pool->getID(),
580 "assigned-addresses")),
581 static_cast<int64_t>(-1));
582 }
583 }
584 }
585
586 if (existing->stateDeclined()) {
587 // old lease is declined
588 StatsMgr::instance().addValue("declined-addresses", static_cast<int64_t>(-1));
589
591 StatsMgr::generateName("subnet", existing->subnet_id_,
592 "declined-addresses"),
593 static_cast<int64_t>(-1));
594
595 if (pool) {
597 StatsMgr::generateName("subnet", subnet->getID(),
598 StatsMgr::generateName("pool", pool->getID(),
599 "declined-addresses")),
600 static_cast<int64_t>(-1));
601 }
602 }
603
604 pool.reset();
605
606 if (!lease->stateExpiredReclaimed()) {
607 // new lease is non expired-reclaimed
608 if (existing->subnet_id_ != lease->subnet_id_) {
610 StatsMgr::generateName("subnet", lease->subnet_id_,
611 "assigned-addresses"),
612 static_cast<int64_t>(1));
613
614 subnet = CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getBySubnetId(lease->subnet_id_);
615 if (subnet) {
616 pool = subnet->getPool(Lease::TYPE_V4, lease->addr_, false);
617 if (pool) {
619 StatsMgr::generateName("subnet", subnet->getID(),
620 StatsMgr::generateName("pool", pool->getID(),
621 "assigned-addresses")),
622 static_cast<int64_t>(1));
623 }
624 }
625 }
626
627 if (lease->stateDeclined()) {
628 // new lease is declined
629 StatsMgr::instance().addValue("declined-addresses", static_cast<int64_t>(1));
630
632 StatsMgr::generateName("subnet", lease->subnet_id_,
633 "declined-addresses"),
634 static_cast<int64_t>(1));
635
636 if (pool) {
638 StatsMgr::generateName("subnet", subnet->getID(),
639 StatsMgr::generateName("pool", pool->getID(),
640 "declined-addresses")),
641 static_cast<int64_t>(1));
642 }
643 }
644 }
645 } else {
646 // old lease is expired-reclaimed
647 if (!lease->stateExpiredReclaimed()) {
648 // new lease is non expired-reclaimed
650 StatsMgr::generateName("subnet", lease->subnet_id_,
651 "assigned-addresses"),
652 static_cast<int64_t>(1));
653
654 PoolPtr pool;
655 auto const& subnet = CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getBySubnetId(lease->subnet_id_);
656 if (subnet) {
657 pool = subnet->getPool(Lease::TYPE_V4, lease->addr_, false);
658 if (pool) {
660 StatsMgr::generateName("subnet", subnet->getID(),
661 StatsMgr::generateName("pool", pool->getID(),
662 "assigned-addresses")),
663 static_cast<int64_t>(1));
664 }
665 }
666
667 if (lease->stateDeclined()) {
668 // new lease is declined
669 StatsMgr::instance().addValue("declined-addresses", static_cast<int64_t>(1));
670
672 StatsMgr::generateName("subnet", lease->subnet_id_,
673 "declined-addresses"),
674 static_cast<int64_t>(1));
675
676 if (pool) {
678 StatsMgr::generateName("subnet", subnet->getID(),
679 StatsMgr::generateName("pool", pool->getID(),
680 "declined-addresses")),
681 static_cast<int64_t>(1));
682 }
683 }
684 }
685 }
686}
687
688void
690 const Lease6Ptr& lease) {
691 if (!existing->stateExpiredReclaimed()) {
692 ConstSubnet6Ptr subnet;
693 PoolPtr pool;
694
695 // old lease is non expired-reclaimed
696 if (existing->subnet_id_ != lease->subnet_id_) {
698 StatsMgr::generateName("subnet", existing->subnet_id_,
699 lease->type_ == Lease::TYPE_NA ?
700 "assigned-nas" : "assigned-pds"),
701 static_cast<int64_t>(-1));
702
703 subnet = CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getBySubnetId(existing->subnet_id_);
704 if (subnet) {
705 pool = subnet->getPool(existing->type_, existing->addr_, false);
706 if (pool) {
708 StatsMgr::generateName("subnet", subnet->getID(),
709 StatsMgr::generateName(existing->type_ == Lease::TYPE_NA ?
710 "pool" : "pd-pool", pool->getID(),
711 existing->type_ == Lease::TYPE_NA ?
712 "assigned-nas" : "assigned-pds")),
713 static_cast<int64_t>(-1));
714 }
715 }
716 }
717
718 if (existing->stateDeclined()) {
719 // old lease is declined
720 StatsMgr::instance().addValue("declined-addresses", static_cast<int64_t>(-1));
721
723 StatsMgr::generateName("subnet", existing->subnet_id_,
724 "declined-addresses"),
725 static_cast<int64_t>(-1));
726
727 if (pool) {
729 StatsMgr::generateName("subnet", subnet->getID(),
730 StatsMgr::generateName("pool", pool->getID(),
731 "declined-addresses")),
732 static_cast<int64_t>(-1));
733 }
734 }
735
736 pool.reset();
737
738 if (!lease->stateExpiredReclaimed()) {
739 // new lease is non expired-reclaimed
740 if (existing->subnet_id_ != lease->subnet_id_) {
742 StatsMgr::generateName("subnet", lease->subnet_id_,
743 lease->type_ == Lease::TYPE_NA ?
744 "assigned-nas" : "assigned-pds"),
745 static_cast<int64_t>(1));
746
747 subnet = CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getBySubnetId(lease->subnet_id_);
748 if (subnet) {
749 pool = subnet->getPool(lease->type_, lease->addr_, false);
750 if (pool) {
752 StatsMgr::generateName("subnet", subnet->getID(),
753 StatsMgr::generateName(lease->type_ == Lease::TYPE_NA ?
754 "pool" : "pd-pool", pool->getID(),
755 lease->type_ == Lease::TYPE_NA ?
756 "assigned-nas" : "assigned-pds")),
757 static_cast<int64_t>(1));
758 }
759 }
760 }
761
762 if (lease->stateDeclined()) {
763 // new lease is declined
764 StatsMgr::instance().addValue("declined-addresses", static_cast<int64_t>(1));
765
767 StatsMgr::generateName("subnet", lease->subnet_id_,
768 "declined-addresses"),
769 static_cast<int64_t>(1));
770
771 if (pool) {
773 StatsMgr::generateName("subnet", subnet->getID(),
774 StatsMgr::generateName("pool", pool->getID(),
775 "declined-addresses")),
776 static_cast<int64_t>(1));
777 }
778 }
779 }
780 } else {
781 // old lease is expired-reclaimed
782 if (!lease->stateExpiredReclaimed()) {
783 // new lease is non expired-reclaimed
785 StatsMgr::generateName("subnet", lease->subnet_id_,
786 lease->type_ == Lease::TYPE_NA ?
787 "assigned-nas" : "assigned-pds"),
788 static_cast<int64_t>(1));
789
790 PoolPtr pool;
791 auto const& subnet = CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getBySubnetId(lease->subnet_id_);
792 if (subnet) {
793 pool = subnet->getPool(lease->type_, lease->addr_, false);
794 if (pool) {
796 StatsMgr::generateName("subnet", subnet->getID(),
797 StatsMgr::generateName(lease->type_ == Lease::TYPE_NA ?
798 "pool" : "pd-pool", pool->getID(),
799 lease->type_ == Lease::TYPE_NA ?
800 "assigned-nas" : "assigned-pds")),
801 static_cast<int64_t>(1));
802 }
803 }
804
805 if (lease->stateDeclined()) {
806 // new lease is declined
807 StatsMgr::instance().addValue("declined-addresses", static_cast<int64_t>(1));
808
810 StatsMgr::generateName("subnet", lease->subnet_id_,
811 "declined-addresses"),
812 static_cast<int64_t>(1));
813
814 if (pool) {
816 StatsMgr::generateName("subnet", subnet->getID(),
817 StatsMgr::generateName("pool", pool->getID(),
818 "declined-addresses")),
819 static_cast<int64_t>(1));
820 }
821 }
822 }
823 }
824}
825
826void
828 if (!lease->stateExpiredReclaimed()) {
830 StatsMgr::generateName("subnet", lease->subnet_id_,
831 "assigned-addresses"),
832 static_cast<int64_t>(-1));
833
834 PoolPtr pool;
835 auto const& subnet = CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getBySubnetId(lease->subnet_id_);
836 if (subnet) {
837 pool = subnet->getPool(Lease::TYPE_V4, lease->addr_, false);
838 if (pool) {
840 StatsMgr::generateName("subnet", subnet->getID(),
841 StatsMgr::generateName("pool", pool->getID(),
842 "assigned-addresses")),
843 static_cast<int64_t>(-1));
844 }
845 }
846
847 if (lease->stateDeclined()) {
848 StatsMgr::instance().addValue("declined-addresses", static_cast<int64_t>(-1));
849
851 StatsMgr::generateName("subnet", lease->subnet_id_,
852 "declined-addresses"),
853 static_cast<int64_t>(-1));
854
855 if (pool) {
857 StatsMgr::generateName("subnet", subnet->getID(),
858 StatsMgr::generateName("pool", pool->getID(),
859 "declined-addresses")),
860 static_cast<int64_t>(-1));
861 }
862 }
863 }
864}
865
866void
868 if (!lease->stateExpiredReclaimed()) {
870 StatsMgr::generateName("subnet", lease->subnet_id_,
871 lease->type_ == Lease::TYPE_NA ?
872 "assigned-nas" : "assigned-pds"),
873 static_cast<int64_t>(-1));
874
875 PoolPtr pool;
876 auto const& subnet = CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getBySubnetId(lease->subnet_id_);
877 if (subnet) {
878 pool = subnet->getPool(lease->type_, lease->addr_, false);
879 if (pool) {
881 StatsMgr::generateName("subnet", subnet->getID(),
882 StatsMgr::generateName(lease->type_ == Lease::TYPE_NA ?
883 "pool" : "pd-pool", pool->getID(),
884 lease->type_ == Lease::TYPE_NA ?
885 "assigned-nas" : "assigned-pds")),
886 static_cast<int64_t>(-1));
887 }
888 }
889
890 if (lease->stateDeclined()) {
891 StatsMgr::instance().addValue("declined-addresses", static_cast<int64_t>(-1));
892
894 StatsMgr::generateName("subnet", lease->subnet_id_,
895 "declined-addresses"),
896 static_cast<int64_t>(-1));
897
898 if (pool) {
900 StatsMgr::generateName("subnet", subnet->getID(),
901 StatsMgr::generateName("pool", pool->getID(),
902 "declined-addresses")),
903 static_cast<int64_t>(-1));
904 }
905 }
906 }
907}
908
909bool
910LeaseCmdsImpl::addOrUpdate4(Lease4Ptr lease, bool force_create) {
911 Lease4Ptr existing = LeaseMgrFactory::instance().getLease4(lease->addr_);
912 if (force_create && !existing) {
913 // lease does not exist
914 if (!LeaseMgrFactory::instance().addLease(lease)) {
916 "lost race between calls to get and add");
917 }
919 return (true);
920 }
921 if (existing) {
922 // Update lease current expiration time with value received from the
923 // database. Some database backends reject operations on the lease if
924 // the current expiration time value does not match what is stored.
925 Lease::syncCurrentExpirationTime(*existing, *lease);
926 }
927 try {
929 } catch (const NoSuchLease&) {
930 isc_throw(LeaseCmdsConflict, "failed to update the lease with address "
931 << lease->addr_ << " either because the lease has been "
932 "deleted or it has changed in the database, in both cases a "
933 "retry might succeed");
934 }
935
936 LeaseCmdsImpl::updateStatsOnUpdate(existing, lease);
937 return (false);
938}
939
940bool
941LeaseCmdsImpl::addOrUpdate6(Lease6Ptr lease, bool force_create) {
942 Lease6Ptr existing =
943 LeaseMgrFactory::instance().getLease6(lease->type_, lease->addr_);
944 if (force_create && !existing) {
945 // lease does not exist
946 if (!LeaseMgrFactory::instance().addLease(lease)) {
948 "lost race between calls to get and add");
949 }
951 return (true);
952 }
953 if (existing) {
954 // Update lease current expiration time with value received from the
955 // database. Some database backends reject operations on the lease if
956 // the current expiration time value does not match what is stored.
957 Lease::syncCurrentExpirationTime(*existing, *lease);
958
959 // Check what is the action about extended info.
960 ConstElementPtr old_extended_info = getExtendedInfo6(existing);
961 ConstElementPtr extended_info = getExtendedInfo6(lease);
962 if ((!old_extended_info && !extended_info) ||
963 (old_extended_info && extended_info &&
964 (*old_extended_info == *extended_info))) {
965 // Leave the default Lease6::ACTION_IGNORE.
966 } else {
967 lease->extended_info_action_ = Lease6::ACTION_UPDATE;
968 }
969 }
970 try {
972 } catch (const NoSuchLease&) {
973 isc_throw(LeaseCmdsConflict, "failed to update the lease with address "
974 << lease->addr_ << " either because the lease has been "
975 "deleted or it has changed in the database, in both cases a "
976 "retry might succeed");
977 }
978
979 LeaseCmdsImpl::updateStatsOnUpdate(existing, lease);
980 return (false);
981}
982
983int
985 // Arbitrary defaulting to DHCPv4 or with other words extractCommand
986 // below is not expected to throw...
987 bool v4 = true;
988 stringstream resp;
989 string lease_address = "unknown";
990 try {
991 extractCommand(handle);
992 v4 = (cmd_name_ == "lease4-add");
993 if (!cmd_args_) {
994 isc_throw(isc::BadValue, "no parameters specified for the command");
995 }
996
998
999 // This parameter is ignored for the commands adding the lease.
1000 bool force_create = false;
1001 Lease4Ptr lease4;
1002 Lease6Ptr lease6;
1003 if (v4) {
1004 Lease4Parser parser;
1005 lease4 = parser.parse(config, cmd_args_, force_create);
1006 if (lease4) {
1007 lease_address = lease4->addr_.toText();
1008 bool success;
1009 if (!MultiThreadingMgr::instance().getMode()) {
1010 // Not multi-threading.
1011 success = LeaseMgrFactory::instance().addLease(lease4);
1012 } else {
1013 // Multi-threading, try to lock first to avoid a race.
1014 ResourceHandler4 resource_handler;
1015 if (resource_handler.tryLock4(lease4->addr_)) {
1016 success = LeaseMgrFactory::instance().addLease(lease4);
1017 } else {
1019 "ResourceBusy: IP address:" << lease4->addr_
1020 << " could not be added.");
1021 }
1022 }
1023
1024 if (!success) {
1025 isc_throw(LeaseCmdsConflict, "IPv4 lease already exists.");
1026 }
1027
1029 resp << "Lease for address " << lease4->addr_.toText()
1030 << ", subnet-id " << lease4->subnet_id_ << " added.";
1031 }
1032 } else {
1033 Lease6Parser parser;
1034 lease6 = parser.parse(config, cmd_args_, force_create);
1035 if (lease6) {
1036 lease_address = lease6->addr_.toText();
1037 bool success;
1038 if (!MultiThreadingMgr::instance().getMode()) {
1039 // Not multi-threading.
1040 success = LeaseMgrFactory::instance().addLease(lease6);
1041 } else {
1042 // Multi-threading, try to lock first to avoid a race.
1043 ResourceHandler resource_handler;
1044 if (resource_handler.tryLock(lease6->type_, lease6->addr_)) {
1045 success = LeaseMgrFactory::instance().addLease(lease6);
1046 } else {
1048 "ResourceBusy: IP address:" << lease6->addr_
1049 << " could not be added.");
1050 }
1051 }
1052
1053 if (!success) {
1054 isc_throw(LeaseCmdsConflict, "IPv6 lease already exists.");
1055 }
1056
1058 if (lease6->type_ == Lease::TYPE_NA) {
1059 resp << "Lease for address " << lease6->addr_.toText()
1060 << ", subnet-id " << lease6->subnet_id_ << " added.";
1061 } else {
1062 resp << "Lease for prefix " << lease6->addr_.toText()
1063 << "/" << static_cast<int>(lease6->prefixlen_)
1064 << ", subnet-id " << lease6->subnet_id_ << " added.";
1065 }
1066 }
1067 }
1068 } catch (const LeaseCmdsConflict& ex) {
1070 .arg(cmd_args_ ? cmd_args_->str() : "<no args>")
1071 .arg(ex.what());
1073 return (0);
1074
1075 } catch (const std::exception& ex) {
1077 .arg(cmd_args_ ? cmd_args_->str() : "<no args>")
1078 .arg(ex.what());
1079 setErrorResponse(handle, ex.what());
1080 return (1);
1081 }
1082
1085 .arg(lease_address);
1086 setSuccessResponse(handle, resp.str());
1087 return (0);
1088}
1089
1092 Parameters x;
1093
1094 if (!params || params->getType() != Element::map) {
1095 isc_throw(BadValue, "Parameters missing or are not a map.");
1096 }
1097
1098 if (params->contains("update-ddns")) {
1099 ConstElementPtr tmp = params->get("update-ddns");
1100 if (tmp->getType() != Element::boolean) {
1101 isc_throw(BadValue, "'update-ddns' is not a boolean");
1102 } else {
1103 x.updateDDNS = tmp->boolValue();
1104 }
1105 }
1106
1107 // We support several sets of parameters for leaseX-get/lease-del:
1108 // lease-get(type, address)
1109 // lease-get(type, subnet-id, identifier-type, identifier)
1110
1111 if (params->contains("type")) {
1112 string t = params->get("type")->stringValue();
1113 if (t == "IA_NA" || t == "0") {
1115 } else if (t == "IA_TA" || t == "1") {
1117 } else if (t == "IA_PD" || t == "2") {
1119 } else if (t == "V4" || t == "3") {
1121 } else {
1122 isc_throw(BadValue, "Invalid lease type specified: "
1123 << t << ", only supported values are: IA_NA, IA_TA,"
1124 << " IA_PD and V4");
1125 }
1126 }
1127
1128 ConstElementPtr tmp = params->get("ip-address");
1129 if (tmp) {
1130 if (tmp->getType() != Element::string) {
1131 isc_throw(BadValue, "'ip-address' is not a string.");
1132 }
1133
1134 x.addr = IOAddress(tmp->stringValue());
1135
1136 if ((v6 && !x.addr.isV6()) || (!v6 && !x.addr.isV4())) {
1137 stringstream txt;
1138 txt << "Invalid " << (v6 ? "IPv6" : "IPv4")
1139 << " address specified: " << tmp->stringValue();
1140 isc_throw(BadValue, txt.str());
1141 }
1142
1144 return (x);
1145 }
1146
1147 tmp = params->get("subnet-id");
1148 if (!tmp) {
1149 isc_throw(BadValue, "Mandatory 'subnet-id' parameter missing.");
1150 }
1151 if (tmp->getType() != Element::integer) {
1152 isc_throw(BadValue, "'subnet-id' parameter is not integer.");
1153 }
1154 x.subnet_id = tmp->intValue();
1155
1156 if (params->contains("iaid")) {
1157 x.iaid = params->get("iaid")->intValue();
1158 }
1159
1160 // No address specified. Ok, so it must be identifier based query.
1161 // "identifier-type": "duid",
1162 // "identifier": "aa:bb:cc:dd:ee:..."
1163
1164 ConstElementPtr type = params->get("identifier-type");
1165 ConstElementPtr ident = params->get("identifier");
1166 if (!type || type->getType() != Element::string) {
1167 isc_throw(BadValue, "No 'ip-address' provided"
1168 " and 'identifier-type' is either missing or not a string.");
1169 }
1170 if (!ident || ident->getType() != Element::string) {
1171 isc_throw(BadValue, "No 'ip-address' provided"
1172 " and 'identifier' is either missing or not a string.");
1173 }
1174
1175 // Got the parameters. Let's see if their values make sense.
1176 // Try to convert identifier-type
1177 x.query_type = Parameters::txtToType(type->stringValue());
1178
1179 switch (x.query_type) {
1181 HWAddr hw = HWAddr::fromText(ident->stringValue());
1182 x.hwaddr = HWAddrPtr(new HWAddr(hw));
1183 break;
1184 }
1186 x.client_id = ClientId::fromText(ident->stringValue());
1187 break;
1188 }
1189 case Parameters::TYPE_DUID: {
1190 DUID duid = DUID::fromText(ident->stringValue());
1191 x.duid = DuidPtr(new DUID(duid));
1192 break;
1193 }
1194 case Parameters::TYPE_ADDR: {
1195 // We should never get here. The address clause should have been caught
1196 // earlier.
1197 return (x);
1198 }
1199 default: {
1200 isc_throw(BadValue, "Identifier type " << type->stringValue() <<
1201 " is not supported.");
1202 }
1203 }
1204
1205 return (x);
1206}
1207
1208int
1210 Parameters p;
1211 Lease4Ptr lease4;
1212 Lease6Ptr lease6;
1213 bool v4 = true;
1214 try {
1215 extractCommand(handle);
1216 v4 = (cmd_name_ == "lease4-get");
1217 p = getParameters(!v4, cmd_args_);
1218 switch (p.query_type) {
1219 case Parameters::TYPE_ADDR: {
1220 // Query by address
1221 if (v4) {
1223 } else {
1225 }
1226 break;
1227 }
1229 if (v4) {
1230 if (!p.hwaddr) {
1231 isc_throw(InvalidParameter, "Program error: Query by hw-address "
1232 "requires hwaddr to be specified");
1233 }
1234
1236 } else {
1237 isc_throw(isc::InvalidParameter, "Query by hw-address is not allowed in v6.");
1238 }
1239 break;
1240
1242 if (!v4) {
1243 if (!p.duid) {
1244 isc_throw(InvalidParameter, "Program error: Query by duid "
1245 "requires duid to be specified");
1246 }
1247
1249 p.iaid, p.subnet_id);
1250 } else {
1251 isc_throw(InvalidParameter, "Query by duid is not allowed in v4.");
1252 }
1253 break;
1254
1256 if (v4) {
1257 if (!p.client_id) {
1258 isc_throw(InvalidParameter, "Program error: Query by client-id "
1259 "requires client-id to be specified");
1260 }
1261
1263 } else {
1264 isc_throw(isc::InvalidParameter, "Query by client-id is not allowed in v6.");
1265 }
1266 break;
1267
1268 default: {
1269 isc_throw(InvalidOperation, "Unknown query type: " << static_cast<int>(p.query_type));
1270 break;
1271 }
1272 }
1273 } catch (const std::exception& ex) {
1275 .arg(cmd_args_ ? cmd_args_->str() : "<no args>")
1276 .arg(ex.what());
1277 setErrorResponse(handle, ex.what());
1278 return (1);
1279 }
1280
1281 ElementPtr lease_json;
1282 if (v4 && lease4) {
1283 lease_json = lease4->toElement();
1285 "IPv4 lease found.", lease_json);
1286 setResponse(handle, response);
1287 } else if (!v4 && lease6) {
1288 lease_json = lease6->toElement();
1290 "IPv6 lease found.", lease_json);
1291 setResponse(handle, response);
1292 } else {
1293 // If we got here, the lease has not been found.
1294 setErrorResponse(handle, "Lease not found.", CONTROL_RESULT_EMPTY);
1295 }
1296
1297 return (0);
1298}
1299
1300int
1302 bool v4 = true;
1303 try {
1304 extractCommand(handle);
1305 v4 = (cmd_name_ == "lease4-get-all");
1306
1307 ElementPtr leases_json = Element::createList();
1308
1309 // The argument may contain a list of subnets for which leases should
1310 // be returned.
1311 if (cmd_args_) {
1312 ConstElementPtr subnets = cmd_args_->get("subnets");
1313 if (!subnets) {
1314 isc_throw(BadValue, "'subnets' parameter not specified");
1315 }
1316 if (subnets->getType() != Element::list) {
1317 isc_throw(BadValue, "'subnets' parameter must be a list");
1318 }
1319
1320 const std::vector<ElementPtr>& subnet_ids = subnets->listValue();
1321 for (auto const& subnet_id : subnet_ids) {
1322 if (subnet_id->getType() != Element::integer) {
1323 isc_throw(BadValue, "listed subnet identifiers must be numbers");
1324 }
1325
1326 if (v4) {
1327 Lease4Collection leases =
1328 LeaseMgrFactory::instance().getLeases4(subnet_id->intValue());
1329 for (auto const& lease : leases) {
1330 ElementPtr lease_json = lease->toElement();
1331 leases_json->add(lease_json);
1332 }
1333 } else {
1334 Lease6Collection leases =
1335 LeaseMgrFactory::instance().getLeases6(subnet_id->intValue());
1336 for (auto const& lease : leases) {
1337 ElementPtr lease_json = lease->toElement();
1338 leases_json->add(lease_json);
1339 }
1340 }
1341 }
1342
1343 } else {
1344 // There is no 'subnets' argument so let's return all leases.
1345 if (v4) {
1347 for (auto const& lease : leases) {
1348 ElementPtr lease_json = lease->toElement();
1349 leases_json->add(lease_json);
1350 }
1351 } else {
1353 for (auto const& lease : leases) {
1354 ElementPtr lease_json = lease->toElement();
1355 leases_json->add(lease_json);
1356 }
1357 }
1358 }
1359
1360 std::ostringstream s;
1361 s << leases_json->size()
1362 << " IPv" << (v4 ? "4" : "6")
1363 << " lease(s) found.";
1365 args->set("leases", leases_json);
1366 ConstElementPtr response =
1367 createAnswer(leases_json->size() > 0 ?
1370 s.str(), args);
1371 setResponse(handle, response);
1372
1373 } catch (const std::exception& ex) {
1374 setErrorResponse(handle, ex.what());
1375 return (CONTROL_RESULT_ERROR);
1376 }
1377
1378 return (0);
1379}
1380
1381int
1383 bool v4 = true;
1384 try {
1385 extractCommand(handle);
1386 v4 = (cmd_name_ == "lease4-get-page");
1387
1388 // arguments must always be present
1389 if (!cmd_args_) {
1390 isc_throw(BadValue, "no parameters specified for the " << cmd_name_
1391 << " command");
1392 }
1393
1394 // The 'from' argument denotes from which lease we should start the
1395 // results page. The results page excludes this lease.
1396 ConstElementPtr from = cmd_args_->get("from");
1397 if (!from) {
1398 isc_throw(BadValue, "'from' parameter not specified");
1399 }
1400
1401 // The 'from' argument is a string. It may contain a 'start' keyword or
1402 // an IP address.
1403 if (from->getType() != Element::string) {
1404 isc_throw(BadValue, "'from' parameter must be a string");
1405 }
1406
1407 boost::scoped_ptr<IOAddress> from_address;
1408 try {
1409 if (from->stringValue() == "start") {
1410 from_address.reset(new IOAddress(v4 ? "0.0.0.0" : "::"));
1411
1412 } else {
1413 // Conversion of a string to an IP address may throw.
1414 from_address.reset(new IOAddress(from->stringValue()));
1415 }
1416
1417 } catch (...) {
1418 isc_throw(BadValue, "'from' parameter value is neither 'start' keyword nor "
1419 "a valid IPv" << (v4 ? "4" : "6") << " address");
1420 }
1421
1422 // It must be either IPv4 address for lease4-get-page or IPv6 address for
1423 // lease6-get-page.
1424 if (v4 && (!from_address->isV4())) {
1425 isc_throw(BadValue, "'from' parameter value " << from_address->toText()
1426 << " is not an IPv4 address");
1427
1428 } else if (!v4 && from_address->isV4()) {
1429 isc_throw(BadValue, "'from' parameter value " << from_address->toText()
1430 << " is not an IPv6 address");
1431 }
1432
1433 // The 'limit' is a desired page size. It must always be present.
1434 ConstElementPtr page_limit = cmd_args_->get("limit");
1435 if (!page_limit) {
1436 isc_throw(BadValue, "'limit' parameter not specified");
1437 }
1438
1439 // The 'limit' must be a number.
1440 if (page_limit->getType() != Element::integer) {
1441 isc_throw(BadValue, "'limit' parameter must be a number");
1442 }
1443
1444 // Retrieve the desired page size.
1445 size_t page_limit_value = static_cast<size_t>(page_limit->intValue());
1446
1447 ElementPtr leases_json = Element::createList();
1448
1449 if (v4) {
1450 // Get page of IPv4 leases.
1451 Lease4Collection leases =
1452 LeaseMgrFactory::instance().getLeases4(*from_address,
1453 LeasePageSize(page_limit_value));
1454
1455 // Convert leases into JSON list.
1456 for (auto const& lease : leases) {
1457 ElementPtr lease_json = lease->toElement();
1458 leases_json->add(lease_json);
1459 }
1460
1461 } else {
1462 // Get page of IPv6 leases.
1463 Lease6Collection leases =
1464 LeaseMgrFactory::instance().getLeases6(*from_address,
1465 LeasePageSize(page_limit_value));
1466 // Convert leases into JSON list.
1467 for (auto const& lease : leases) {
1468 ElementPtr lease_json = lease->toElement();
1469 leases_json->add(lease_json);
1470 }
1471 }
1472
1473 // Prepare textual status.
1474 std::ostringstream s;
1475 s << leases_json->size()
1476 << " IPv" << (v4 ? "4" : "6")
1477 << " lease(s) found.";
1479
1480 // Put gathered data into arguments map.
1481 args->set("leases", leases_json);
1482 args->set("count", Element::create(static_cast<int64_t>(leases_json->size())));
1483
1484 // Create the response.
1485 ConstElementPtr response =
1486 createAnswer(leases_json->size() > 0 ?
1489 s.str(), args);
1490 setResponse(handle, response);
1491
1492 } catch (const std::exception& ex) {
1493 setErrorResponse(handle, ex.what());
1494 return (CONTROL_RESULT_ERROR);
1495 }
1496
1497 return (CONTROL_RESULT_SUCCESS);
1498}
1499
1500int
1502 try {
1503 extractCommand(handle);
1504
1505 // arguments must always be present
1506 if (!cmd_args_ || (cmd_args_->getType() != Element::map)) {
1507 isc_throw(BadValue, "Command arguments missing or a not a map.");
1508 }
1509
1510 // the hw-address parameter is mandatory.
1511 ConstElementPtr hw_address = cmd_args_->get("hw-address");
1512 if (!hw_address) {
1513 isc_throw(BadValue, "'hw-address' parameter not specified");
1514 }
1515
1516 // The 'hw-address' argument is a string.
1517 if (hw_address->getType() != Element::string) {
1518 isc_throw(BadValue, "'hw-address' parameter must be a string");
1519 }
1520
1521 HWAddr hwaddr = HWAddr::fromText(hw_address->stringValue());
1522
1523 Lease4Collection leases =
1525 ElementPtr leases_json = Element::createList();
1526 for (auto const& lease : leases) {
1527 ElementPtr lease_json = lease->toElement();
1528 leases_json->add(lease_json);
1529 }
1530
1531 std::ostringstream s;
1532 s << leases_json->size() << " IPv4 lease(s) found.";
1534 args->set("leases", leases_json);
1535 ConstElementPtr response =
1536 createAnswer(leases_json->size() > 0 ?
1539 s.str(), args);
1540 setResponse(handle, response);
1541
1542 } catch (const std::exception& ex) {
1543 setErrorResponse(handle, ex.what());
1544 return (CONTROL_RESULT_ERROR);
1545 }
1546
1547 return (0);
1548}
1549
1550int
1552 try {
1553 extractCommand(handle);
1554
1555 // arguments must always be present
1556 if (!cmd_args_ || (cmd_args_->getType() != Element::map)) {
1557 isc_throw(BadValue, "Command arguments missing or a not a map.");
1558 }
1559
1560 // the client-id parameter is mandatory.
1561 ConstElementPtr client_id = cmd_args_->get("client-id");
1562 if (!client_id) {
1563 isc_throw(BadValue, "'client-id' parameter not specified");
1564 }
1565
1566 // The 'client-id' argument is a string.
1567 if (client_id->getType() != Element::string) {
1568 isc_throw(BadValue, "'client-id' parameter must be a string");
1569 }
1570
1571 ClientIdPtr clientid = ClientId::fromText(client_id->stringValue());
1572
1573 Lease4Collection leases =
1575 ElementPtr leases_json = Element::createList();
1576 for (auto const& lease : leases) {
1577 ElementPtr lease_json = lease->toElement();
1578 leases_json->add(lease_json);
1579 }
1580
1581 std::ostringstream s;
1582 s << leases_json->size() << " IPv4 lease(s) found.";
1584 args->set("leases", leases_json);
1585 ConstElementPtr response =
1586 createAnswer(leases_json->size() > 0 ?
1589 s.str(), args);
1590 setResponse(handle, response);
1591
1592 } catch (const std::exception& ex) {
1593 setErrorResponse(handle, ex.what());
1594 return (CONTROL_RESULT_ERROR);
1595 }
1596
1597 return (0);
1598}
1599
1600int
1602 try {
1603 extractCommand(handle);
1604
1605 // arguments must always be present
1606 if (!cmd_args_ || (cmd_args_->getType() != Element::map)) {
1607 isc_throw(BadValue, "Command arguments missing or a not a map.");
1608 }
1609
1610 // the duid parameter is mandatory.
1611 ConstElementPtr duid = cmd_args_->get("duid");
1612 if (!duid) {
1613 isc_throw(BadValue, "'duid' parameter not specified");
1614 }
1615
1616 // The 'duid' argument is a string.
1617 if (duid->getType() != Element::string) {
1618 isc_throw(BadValue, "'duid' parameter must be a string");
1619 }
1620
1621 DUID duid_ = DUID::fromText(duid->stringValue());
1622
1623 Lease6Collection leases =
1625 ElementPtr leases_json = Element::createList();
1626 for (auto const& lease : leases) {
1627 ElementPtr lease_json = lease->toElement();
1628 leases_json->add(lease_json);
1629 }
1630
1631 std::ostringstream s;
1632 s << leases_json->size() << " IPv6 lease(s) found.";
1634 args->set("leases", leases_json);
1635 ConstElementPtr response =
1636 createAnswer(leases_json->size() > 0 ?
1639 s.str(), args);
1640 setResponse(handle, response);
1641
1642 } catch (const std::exception& ex) {
1643 setErrorResponse(handle, ex.what());
1644 return (CONTROL_RESULT_ERROR);
1645 }
1646
1647 return (0);
1648}
1649
1650int
1652 bool v4 = true;
1653 try {
1654 extractCommand(handle);
1655 v4 = (cmd_name_ == "lease4-get-by-hostname");
1656
1657 // arguments must always be present
1658 if (!cmd_args_ || (cmd_args_->getType() != Element::map)) {
1659 isc_throw(BadValue, "Command arguments missing or a not a map.");
1660 }
1661
1662 // the hostname parameter is mandatory.
1663 ConstElementPtr hostname = cmd_args_->get("hostname");
1664 if (!hostname) {
1665 isc_throw(BadValue, "'hostname' parameter not specified");
1666 }
1667
1668 // The 'hostname' argument is a string.
1669 if (hostname->getType() != Element::string) {
1670 isc_throw(BadValue, "'hostname' parameter must be a string");
1671 }
1672
1673 std::string hostname_ = hostname->stringValue();
1675 if (hostname_.empty()) {
1676 isc_throw(BadValue, "'hostname' parameter is empty");
1677 }
1678 boost::algorithm::to_lower(hostname_);
1679
1680 ElementPtr leases_json = Element::createList();
1681 if (v4) {
1682 Lease4Collection leases =
1684
1685 for (auto const& lease : leases) {
1686 ElementPtr lease_json = lease->toElement();
1687 leases_json->add(lease_json);
1688 }
1689 } else {
1690 Lease6Collection leases =
1692
1693 for (auto const& lease : leases) {
1694 ElementPtr lease_json = lease->toElement();
1695 leases_json->add(lease_json);
1696 }
1697 }
1698
1699 std::ostringstream s;
1700 s << leases_json->size()
1701 << " IPv" << (v4 ? "4" : "6")
1702 << " lease(s) found.";
1704 args->set("leases", leases_json);
1705 ConstElementPtr response =
1706 createAnswer(leases_json->size() > 0 ?
1709 s.str(), args);
1710 setResponse(handle, response);
1711
1712 } catch (const std::exception& ex) {
1713 setErrorResponse(handle, ex.what());
1714 return (CONTROL_RESULT_ERROR);
1715 }
1716
1717 return (0);
1718}
1719
1720int
1722 Parameters p;
1723 Lease4Ptr lease4;
1724 try {
1725 extractCommand(handle);
1726 p = getParameters(false, cmd_args_);
1727 switch (p.query_type) {
1728 case Parameters::TYPE_ADDR: {
1729 // If address was specified explicitly, let's use it as is.
1731 if (!lease4) {
1732 setErrorResponse(handle, "IPv4 lease not found.", CONTROL_RESULT_EMPTY);
1733 return (0);
1734 }
1735 break;
1736 }
1738 if (!p.hwaddr) {
1739 isc_throw(InvalidParameter, "Program error: Query by hw-address "
1740 "requires hwaddr to be specified");
1741 }
1742
1743 // Let's see if there's such a lease at all.
1745 if (!lease4) {
1746 setErrorResponse(handle, "IPv4 lease not found.", CONTROL_RESULT_EMPTY);
1747 return (0);
1748 }
1749 break;
1750 }
1752 if (!p.client_id) {
1753 isc_throw(InvalidParameter, "Program error: Query by client-id "
1754 "requires client-id to be specified");
1755 }
1756
1757 // Let's see if there's such a lease at all.
1759 if (!lease4) {
1760 setErrorResponse(handle, "IPv4 lease not found.", CONTROL_RESULT_EMPTY);
1761 return (0);
1762 }
1763 break;
1764 }
1765 case Parameters::TYPE_DUID: {
1766 isc_throw(InvalidParameter, "Delete by duid is not allowed in v4.");
1767 break;
1768 }
1769 default: {
1770 isc_throw(InvalidOperation, "Unknown query type: " << static_cast<int>(p.query_type));
1771 break;
1772 }
1773 }
1774
1775 if (LeaseMgrFactory::instance().deleteLease(lease4)) {
1776 setSuccessResponse(handle, "IPv4 lease deleted.");
1778 } else {
1779 setErrorResponse (handle, "IPv4 lease not found.", CONTROL_RESULT_EMPTY);
1780 }
1781
1782 // Queue an NCR to remove DNS if configured and the lease has it.
1783 if (p.updateDDNS) {
1784 queueNCR(CHG_REMOVE, lease4);
1785 }
1786
1787 } catch (const std::exception& ex) {
1789 .arg(cmd_args_ ? cmd_args_->str() : "<no args>")
1790 .arg(ex.what());
1791 setErrorResponse(handle, ex.what());
1792 return (1);
1793 }
1795 .arg(lease4->addr_.toText());
1796 return (0);
1797}
1798
1799int
1801 try {
1802 extractCommand(handle);
1803
1804 // Arguments are mandatory.
1805 if (!cmd_args_ || (cmd_args_->getType() != Element::map)) {
1806 isc_throw(BadValue, "Command arguments missing or a not a map.");
1807 }
1808
1809 // At least one of the 'deleted-leases' or 'leases' must be present.
1810 auto deleted_leases = cmd_args_->get("deleted-leases");
1811 auto leases = cmd_args_->get("leases");
1812
1813 if (!deleted_leases && !leases) {
1814 isc_throw(BadValue, "neither 'deleted-leases' nor 'leases' parameter"
1815 " specified");
1816 }
1817
1818 // Make sure that 'deleted-leases' is a list, if present.
1819 if (deleted_leases && (deleted_leases->getType() != Element::list)) {
1820 isc_throw(BadValue, "the 'deleted-leases' parameter must be a list");
1821 }
1822
1823 // Make sure that 'leases' is a list, if present.
1824 if (leases && (leases->getType() != Element::list)) {
1825 isc_throw(BadValue, "the 'leases' parameter must be a list");
1826 }
1827
1828 // Parse deleted leases without deleting them from the database
1829 // yet. If any of the deleted leases or new leases appears to be
1830 // malformed we can easily rollback.
1831 std::list<std::pair<Parameters, Lease6Ptr> > parsed_deleted_list;
1832 if (deleted_leases) {
1833 auto leases_list = deleted_leases->listValue();
1834
1835 // Iterate over leases to be deleted.
1836 for (auto const& lease_params : leases_list) {
1837 // Parsing the lease may throw and it means that the lease
1838 // information is malformed.
1839 Parameters p = getParameters(true, lease_params);
1840 auto lease = getIPv6LeaseForDelete(p);
1841 parsed_deleted_list.push_back(std::make_pair(p, lease));
1842 }
1843 }
1844
1845 // Parse new/updated leases without affecting the database to detect
1846 // any errors that should cause an error response.
1847 std::list<Lease6Ptr> parsed_leases_list;
1848 if (leases) {
1850
1851 // Iterate over all leases.
1852 auto leases_list = leases->listValue();
1853 for (auto const& lease_params : leases_list) {
1854
1855 Lease6Parser parser;
1856 bool force_update;
1857
1858 // If parsing the lease fails we throw, as it indicates that the
1859 // command is malformed.
1860 Lease6Ptr lease6 = parser.parse(config, lease_params, force_update);
1861 parsed_leases_list.push_back(lease6);
1862 }
1863 }
1864
1865 // Count successful deletions and updates.
1866 size_t success_count = 0;
1867
1868 ElementPtr failed_deleted_list;
1869 if (!parsed_deleted_list.empty()) {
1870
1871 // Iterate over leases to be deleted.
1872 for (auto const& lease_params_pair : parsed_deleted_list) {
1873
1874 // This part is outside of the try-catch because an exception
1875 // indicates that the command is malformed.
1876 Parameters p = lease_params_pair.first;
1877 auto lease = lease_params_pair.second;
1878
1879 try {
1880 if (lease) {
1881 // This may throw if the lease couldn't be deleted for
1882 // any reason, but we still want to proceed with other
1883 // leases.
1884 if (LeaseMgrFactory::instance().deleteLease(lease)) {
1885 ++success_count;
1887
1888 } else {
1889 // Lazy creation of the list of leases which failed to delete.
1890 if (!failed_deleted_list) {
1891 failed_deleted_list = Element::createList();
1892 }
1893
1894 // If the lease doesn't exist we also want to put it
1895 // on the list of leases which failed to delete. That
1896 // corresponds to the lease6-del command which returns
1897 // an error when the lease doesn't exist.
1898 failed_deleted_list->add(createFailedLeaseMap(p.lease_type,
1899 p.addr, p.duid,
1901 "lease not found"));
1902 }
1903 }
1904
1905 } catch (const std::exception& ex) {
1906 // Lazy creation of the list of leases which failed to delete.
1907 if (!failed_deleted_list) {
1908 failed_deleted_list = Element::createList();
1909 }
1910 failed_deleted_list->add(createFailedLeaseMap(p.lease_type,
1911 p.addr, p.duid,
1913 ex.what()));
1914 }
1915 }
1916 }
1917
1918 // Process leases to be added or/and updated.
1919 ElementPtr failed_leases_list;
1920 if (!parsed_leases_list.empty()) {
1922
1923 // Iterate over all leases.
1924 for (auto const& lease : parsed_leases_list) {
1925
1926 auto result = CONTROL_RESULT_SUCCESS;
1927 std::ostringstream text;
1928 try {
1929 if (!MultiThreadingMgr::instance().getMode()) {
1930 // Not multi-threading.
1931 addOrUpdate6(lease, true);
1932 } else {
1933 // Multi-threading, try to lock first to avoid a race.
1934 ResourceHandler resource_handler;
1935 if (resource_handler.tryLock(lease->type_, lease->addr_)) {
1936 addOrUpdate6(lease, true);
1937 } else {
1939 "ResourceBusy: IP address:" << lease->addr_
1940 << " could not be updated.");
1941 }
1942 }
1943
1944 ++success_count;
1945 } catch (const LeaseCmdsConflict& ex) {
1946 result = CONTROL_RESULT_CONFLICT;
1947 text << ex.what();
1948
1949 } catch (const std::exception& ex) {
1950 result = CONTROL_RESULT_ERROR;
1951 text << ex.what();
1952 }
1953 // Handle an error.
1954 if (result != CONTROL_RESULT_SUCCESS) {
1955 // Lazy creation of the list of leases which failed to add/update.
1956 if (!failed_leases_list) {
1957 failed_leases_list = Element::createList();
1958 }
1959 failed_leases_list->add(createFailedLeaseMap(lease->type_,
1960 lease->addr_,
1961 lease->duid_,
1962 result,
1963 text.str()));
1964 }
1965 }
1966 }
1967
1968 // Start preparing the response.
1969 ElementPtr args;
1970
1971 if (failed_deleted_list || failed_leases_list) {
1972 // If there are any failed leases, let's include them in the response.
1973 args = Element::createMap();
1974
1975 // failed-deleted-leases
1976 if (failed_deleted_list) {
1977 args->set("failed-deleted-leases", failed_deleted_list);
1978 }
1979
1980 // failed-leases
1981 if (failed_leases_list) {
1982 args->set("failed-leases", failed_leases_list);
1983 }
1984 }
1985
1986 // Send the success response and include failed leases.
1987 std::ostringstream resp_text;
1988 resp_text << "Bulk apply of " << success_count << " IPv6 leases completed.";
1989 auto answer = createAnswer(success_count > 0 ? CONTROL_RESULT_SUCCESS :
1990 CONTROL_RESULT_EMPTY, resp_text.str(), args);
1991 setResponse(handle, answer);
1992
1995 .arg(success_count);
1996
1997 } catch (const std::exception& ex) {
1998 // Unable to parse the command and similar issues.
2000 .arg(cmd_args_ ? cmd_args_->str() : "<no args>")
2001 .arg(ex.what());
2002 setErrorResponse(handle, ex.what());
2003 return (CONTROL_RESULT_ERROR);
2004 }
2005
2006 return (0);
2007}
2008
2009int
2011 Parameters p;
2012 Lease6Ptr lease6;
2014 try {
2015 extractCommand(handle);
2016 p = getParameters(true, cmd_args_);
2017
2018 switch (p.query_type) {
2019 case Parameters::TYPE_ADDR: {
2020 // If address was specified explicitly, let's use it as is.
2021
2022 // Let's see if there's such a lease at all.
2024 if (!lease6) {
2025 setErrorResponse(handle, "IPv6 lease not found.", CONTROL_RESULT_EMPTY);
2026 return (0);
2027 }
2028 break;
2029 }
2031 isc_throw(InvalidParameter, "Delete by hw-address is not allowed in v6.");
2032 break;
2033 }
2034 case Parameters::TYPE_DUID: {
2035 if (!p.duid) {
2036 isc_throw(InvalidParameter, "Program error: Query by duid "
2037 "requires duid to be specified");
2038 }
2039
2040 // Let's see if there's such a lease at all.
2042 p.iaid, p.subnet_id);
2043 if (!lease6) {
2044 setErrorResponse(handle, "IPv6 lease not found.", CONTROL_RESULT_EMPTY);
2045 return (0);
2046 }
2047 break;
2048 }
2049 default: {
2050 isc_throw(InvalidOperation, "Unknown query type: " << static_cast<int>(p.query_type));
2051 break;
2052 }
2053 }
2054
2055 if (LeaseMgrFactory::instance().deleteLease(lease6)) {
2056 setSuccessResponse(handle, "IPv6 lease deleted.");
2058 } else {
2059 setErrorResponse (handle, "IPv6 lease not found.", CONTROL_RESULT_EMPTY);
2060 }
2061
2062 // Queue an NCR to remove DNS if configured and the lease has it.
2063 if (p.updateDDNS) {
2064 queueNCR(CHG_REMOVE, lease6);
2065 }
2066
2067 } catch (const std::exception& ex) {
2069 .arg(cmd_args_ ? cmd_args_->str() : "<no args>")
2070 .arg(ex.what());
2071 setErrorResponse(handle, ex.what());
2072 return (1);
2073 }
2074
2076 .arg(lease6->addr_.toText());
2077 return (0);
2078}
2079
2080int
2082 try {
2083 extractCommand(handle);
2084
2085 // We need the lease to be specified.
2086 if (!cmd_args_) {
2087 isc_throw(isc::BadValue, "no parameters specified for lease4-update command");
2088 }
2089
2090 // Get the parameters specified by the user first.
2092 Lease4Ptr lease4;
2093 Lease4Parser parser;
2094 bool force_create = false;
2095
2096 // The parser does sanity checks (if the address is in scope, if
2097 // subnet-id is valid, etc)
2098 lease4 = parser.parse(config, cmd_args_, force_create);
2099 bool added = false;
2100 if (!MultiThreadingMgr::instance().getMode()) {
2101 // Not multi-threading.
2102 added = addOrUpdate4(lease4, force_create);
2103 } else {
2104 // Multi-threading, try to lock first to avoid a race.
2105 ResourceHandler4 resource_handler;
2106 if (resource_handler.tryLock4(lease4->addr_)) {
2107 added = addOrUpdate4(lease4, force_create);
2108 } else {
2110 "ResourceBusy: IP address:" << lease4->addr_
2111 << " could not be updated.");
2112 }
2113 }
2114
2115 if (added) {
2116 setSuccessResponse(handle, "IPv4 lease added.");
2117 } else {
2118 setSuccessResponse(handle, "IPv4 lease updated.");
2119 }
2122 .arg(lease4->addr_.toText());
2123
2124 } catch (const LeaseCmdsConflict& ex) {
2126 .arg(cmd_args_ ? cmd_args_->str() : "<no args>")
2127 .arg(ex.what());
2129 return (0);
2130
2131 } catch (const std::exception& ex) {
2133 .arg(cmd_args_ ? cmd_args_->str() : "<no args>")
2134 .arg(ex.what());
2135 setErrorResponse(handle, ex.what());
2136 return (1);
2137 }
2138
2139 return (0);
2140}
2141
2142int
2144 try {
2145 extractCommand(handle);
2146
2147 // We need the lease to be specified.
2148 if (!cmd_args_) {
2149 isc_throw(isc::BadValue, "no parameters specified for lease6-update command");
2150 }
2151
2152 // Get the parameters specified by the user first.
2154 Lease6Ptr lease6;
2155 Lease6Parser parser;
2156 bool force_create = false;
2157
2158 // The parser does sanity checks (if the address is in scope, if
2159 // subnet-id is valid, etc)
2160 lease6 = parser.parse(config, cmd_args_, force_create);
2161 bool added = false;
2162 if (!MultiThreadingMgr::instance().getMode()) {
2163 // Not multi-threading.
2164 added = addOrUpdate6(lease6, force_create);
2165 } else {
2166 // Multi-threading, try to lock first to avoid a race.
2167 ResourceHandler resource_handler;
2168 if (resource_handler.tryLock(lease6->type_, lease6->addr_)) {
2169 added = addOrUpdate6(lease6, force_create);
2170 } else {
2172 "ResourceBusy: IP address:" << lease6->addr_
2173 << " could not be updated.");
2174 }
2175 }
2176
2177 if (added) {
2178 setSuccessResponse(handle, "IPv6 lease added.");
2179 } else {
2180 setSuccessResponse(handle, "IPv6 lease updated.");
2181 }
2184 .arg(lease6->addr_.toText());
2185
2186 } catch (const LeaseCmdsConflict& ex) {
2188 .arg(cmd_args_ ? cmd_args_->str() : "<no args>")
2189 .arg(ex.what());
2191 return (0);
2192
2193 } catch (const std::exception& ex) {
2195 .arg(cmd_args_ ? cmd_args_->str() : "<no args>")
2196 .arg(ex.what());
2197 setErrorResponse(handle, ex.what());
2198 return (1);
2199 }
2200
2201 return (0);
2202}
2203
2204int
2206 try {
2207 extractCommand(handle);
2208
2209 SimpleParser parser;
2210 SubnetID id = 0;
2211
2212 size_t num = 0; // number of leases deleted
2213 stringstream ids; // a text with subnet-ids being wiped
2214
2215 // The subnet-id parameter is now optional.
2216 if (cmd_args_ && cmd_args_->contains("subnet-id")) {
2217 id = parser.getUint32(cmd_args_, "subnet-id");
2218 }
2219
2220 if (id) {
2221 // Wipe a single subnet.
2223 ids << " " << id;
2224
2225 auto observation = StatsMgr::instance().getObservation(
2226 StatsMgr::generateName("subnet", id, "declined-addresses"));
2227
2228 int64_t previous_declined = 0;
2229
2230 if (observation) {
2231 previous_declined = observation->getInteger().first;
2232 }
2233
2235 StatsMgr::generateName("subnet", id, "assigned-addresses"),
2236 static_cast<int64_t>(0));
2237
2239 StatsMgr::generateName("subnet", id, "declined-addresses"),
2240 static_cast<int64_t>(0));
2241
2242 auto const& sub = CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getBySubnetId(id);
2243 if (sub) {
2244 for (auto const& pool : sub->getPools(Lease::TYPE_V4)) {
2245 const std::string& name_aa(StatsMgr::generateName("subnet", sub->getID(),
2246 StatsMgr::generateName("pool", pool->getID(),
2247 "assigned-addresses")));
2248 if (!StatsMgr::instance().getObservation(name_aa)) {
2249 StatsMgr::instance().setValue(name_aa, static_cast<int64_t>(0));
2250 }
2251
2252 const std::string& name_da(StatsMgr::generateName("subnet", sub->getID(),
2253 StatsMgr::generateName("pool", pool->getID(),
2254 "declined-addresses")));
2255 if (!StatsMgr::instance().getObservation(name_da)) {
2256 StatsMgr::instance().setValue(name_da, static_cast<int64_t>(0));
2257 }
2258 }
2259 }
2260
2261 StatsMgr::instance().addValue("declined-addresses", -previous_declined);
2262 } else {
2263 // Wipe them all!
2265 ConstCfgSubnets4Ptr subnets = config->getCfgSubnets4();
2266 const Subnet4Collection* subs = subnets->getAll();
2267
2268 // Go over all subnets and wipe leases in each of them.
2269 for (auto const& sub : *subs) {
2270 num += LeaseMgrFactory::instance().wipeLeases4(sub->getID());
2271 ids << " " << sub->getID();
2273 StatsMgr::generateName("subnet", sub->getID(), "assigned-addresses"),
2274 static_cast<int64_t>(0));
2275
2277 StatsMgr::generateName("subnet", sub->getID(), "declined-addresses"),
2278 static_cast<int64_t>(0));
2279
2280 for (auto const& pool : sub->getPools(Lease::TYPE_V4)) {
2281 const std::string& name_aa(StatsMgr::generateName("subnet", sub->getID(),
2282 StatsMgr::generateName("pool", pool->getID(),
2283 "assigned-addresses")));
2284 if (!StatsMgr::instance().getObservation(name_aa)) {
2285 StatsMgr::instance().setValue(name_aa, static_cast<int64_t>(0));
2286 }
2287
2288 const std::string& name_da(StatsMgr::generateName("subnet", sub->getID(),
2289 StatsMgr::generateName("pool", pool->getID(),
2290 "declined-addresses")));
2291 if (!StatsMgr::instance().getObservation(name_da)) {
2292 StatsMgr::instance().setValue(name_da, static_cast<int64_t>(0));
2293 }
2294 }
2295 }
2296
2297 StatsMgr::instance().setValue("declined-addresses", static_cast<int64_t>(0));
2298 }
2299
2300 stringstream tmp;
2301 tmp << "Deleted " << num << " IPv4 lease(s) from subnet(s)" << ids.str();
2303 : CONTROL_RESULT_EMPTY, tmp.str());
2304 setResponse(handle, response);
2305 } catch (const std::exception& ex) {
2307 .arg(cmd_args_ ? cmd_args_->str() : "<no args>")
2308 .arg(ex.what());
2309 setErrorResponse(handle, ex.what());
2310 return (1);
2311 }
2312
2314 .arg(cmd_args_ ? cmd_args_->str() : "<no args>");
2315 return (0);
2316}
2317
2318int
2320 try {
2321 extractCommand(handle);
2322
2323 SimpleParser parser;
2324 SubnetID id = 0;
2325
2326 size_t num = 0; // number of leases deleted
2327 stringstream ids; // a text with subnet-ids being wiped
2328
2333
2334 // The subnet-id parameter is now optional.
2335 if (cmd_args_ && cmd_args_->contains("subnet-id")) {
2336 id = parser.getUint32(cmd_args_, "subnet-id");
2337 }
2338
2339 if (id) {
2340 // Wipe a single subnet.
2342 ids << " " << id;
2343
2344 auto observation = StatsMgr::instance().getObservation(
2345 StatsMgr::generateName("subnet", id, "declined-addresses"));
2346
2347 int64_t previous_declined = 0;
2348
2349 if (observation) {
2350 previous_declined = observation->getInteger().first;
2351 }
2352
2354 StatsMgr::generateName("subnet", id, "assigned-nas" ),
2355 static_cast<int64_t>(0));
2356
2358 StatsMgr::generateName("subnet", id, "assigned-pds"),
2359 static_cast<int64_t>(0));
2360
2362 StatsMgr::generateName("subnet", id, "declined-addresses"),
2363 static_cast<int64_t>(0));
2364
2365 auto const& sub = CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getBySubnetId(id);
2366 if (sub) {
2367 for (auto const& pool : sub->getPools(Lease::TYPE_NA)) {
2368 const std::string& name_anas(StatsMgr::generateName("subnet", sub->getID(),
2369 StatsMgr::generateName("pool", pool->getID(),
2370 "assigned-nas")));
2371 if (!StatsMgr::instance().getObservation(name_anas)) {
2372 StatsMgr::instance().setValue(name_anas, static_cast<int64_t>(0));
2373 }
2374
2375 const std::string& name_da(StatsMgr::generateName("subnet", sub->getID(),
2376 StatsMgr::generateName("pool", pool->getID(),
2377 "declined-addresses")));
2378 if (!StatsMgr::instance().getObservation(name_da)) {
2379 StatsMgr::instance().setValue(name_da, static_cast<int64_t>(0));
2380 }
2381 }
2382
2383 for (auto const& pool : sub->getPools(Lease::TYPE_PD)) {
2384 const std::string& name_apds(StatsMgr::generateName("subnet", sub->getID(),
2385 StatsMgr::generateName("pd-pool", pool->getID(),
2386 "assigned-pds")));
2387 if (!StatsMgr::instance().getObservation(name_apds)) {
2388 StatsMgr::instance().setValue(name_apds, static_cast<int64_t>(0));
2389 }
2390 }
2391 }
2392
2393 StatsMgr::instance().addValue("declined-addresses", -previous_declined);
2394 } else {
2395 // Wipe them all!
2397 ConstCfgSubnets6Ptr subnets = config->getCfgSubnets6();
2398 const Subnet6Collection* subs = subnets->getAll();
2399
2400 // Go over all subnets and wipe leases in each of them.
2401 for (auto const& sub : *subs) {
2402 num += LeaseMgrFactory::instance().wipeLeases6(sub->getID());
2403 ids << " " << sub->getID();
2405 StatsMgr::generateName("subnet", sub->getID(), "assigned-nas" ),
2406 static_cast<int64_t>(0));
2407
2409 StatsMgr::generateName("subnet", sub->getID(), "assigned-pds"),
2410 static_cast<int64_t>(0));
2411
2413 StatsMgr::generateName("subnet", sub->getID(), "declined-addresses"),
2414 static_cast<int64_t>(0));
2415
2416 for (auto const& pool : sub->getPools(Lease::TYPE_NA)) {
2417 const std::string& name_anas(StatsMgr::generateName("subnet", sub->getID(),
2418 StatsMgr::generateName("pool", pool->getID(),
2419 "assigned-nas")));
2420 if (!StatsMgr::instance().getObservation(name_anas)) {
2421 StatsMgr::instance().setValue(name_anas, static_cast<int64_t>(0));
2422 }
2423
2424 const std::string& name_da(StatsMgr::generateName("subnet", sub->getID(),
2425 StatsMgr::generateName("pool", pool->getID(),
2426 "declined-addresses")));
2427 if (!StatsMgr::instance().getObservation(name_da)) {
2428 StatsMgr::instance().setValue(name_da, static_cast<int64_t>(0));
2429 }
2430 }
2431
2432 for (auto const& pool : sub->getPools(Lease::TYPE_PD)) {
2433 const std::string& name_apds(StatsMgr::generateName("subnet", sub->getID(),
2434 StatsMgr::generateName("pd-pool", pool->getID(),
2435 "assigned-pds")));
2436 if (!StatsMgr::instance().getObservation(name_apds)) {
2437 StatsMgr::instance().setValue(name_apds, static_cast<int64_t>(0));
2438 }
2439 }
2440 }
2441
2442 StatsMgr::instance().setValue("declined-addresses", static_cast<int64_t>(0));
2443 }
2444
2445 stringstream tmp;
2446 tmp << "Deleted " << num << " IPv6 lease(s) from subnet(s)" << ids.str();
2448 : CONTROL_RESULT_EMPTY, tmp.str());
2449 setResponse(handle, response);
2450 } catch (const std::exception& ex) {
2452 .arg(cmd_args_ ? cmd_args_->str() : "<no args>")
2453 .arg(ex.what());
2454 setErrorResponse(handle, ex.what());
2455 return (1);
2456 }
2457
2459 .arg(cmd_args_ ? cmd_args_->str() : "<no args>");
2460 return (0);
2461}
2462
2465 Lease6Ptr lease6;
2466
2467 switch (parameters.query_type) {
2468 case Parameters::TYPE_ADDR: {
2469 // If address was specified explicitly, let's use it as is.
2470
2471 // Let's see if there's such a lease at all.
2472 lease6 = LeaseMgrFactory::instance().getLease6(parameters.lease_type,
2473 parameters.addr);
2474 if (!lease6) {
2475 lease6.reset(new Lease6());
2476 lease6->addr_ = parameters.addr;
2477 }
2478 break;
2479 }
2481 isc_throw(InvalidParameter, "Delete by hw-address is not allowed in v6.");
2482 break;
2483 }
2484 case Parameters::TYPE_DUID: {
2485 if (!parameters.duid) {
2486 isc_throw(InvalidParameter, "Program error: Query by duid "
2487 "requires duid to be specified");
2488 }
2489
2490 // Let's see if there's such a lease at all.
2491 lease6 = LeaseMgrFactory::instance().getLease6(parameters.lease_type,
2492 *parameters.duid,
2493 parameters.iaid,
2494 parameters.subnet_id);
2495 break;
2496 }
2497 default:
2498 isc_throw(InvalidOperation, "Unknown query type: "
2499 << static_cast<int>(parameters.query_type));
2500 }
2501
2502 return (lease6);
2503}
2504
2507 short family) const {
2508 ConstElementPtr param = params->get(name);
2509 if (!param) {
2510 isc_throw(BadValue, "'" << name << "' parameter is missing.");
2511 }
2512
2513 if (param->getType() != Element::string) {
2514 isc_throw(BadValue, "'" << name << "' is not a string.");
2515 }
2516
2517 IOAddress addr(0);
2518 try {
2519 addr = IOAddress(param->stringValue());
2520 } catch (const std::exception& ex) {
2521 isc_throw(BadValue, "'" << param->stringValue()
2522 << "' is not a valid IP address.");
2523 }
2524
2525 if (addr.getFamily() != family) {
2526 isc_throw(BadValue, "Invalid "
2527 << (family == AF_INET6 ? "IPv6" : "IPv4")
2528 << " address specified: " << param->stringValue());
2529 }
2530
2531 return (addr);
2532}
2533
2534int
2536 std::stringstream ss;
2537 int resp_code = CONTROL_RESULT_ERROR;
2538
2539 try {
2540 extractCommand(handle);
2541
2542 // Get the target lease address. Invalid value will throw.
2543 IOAddress addr = getAddressParam(cmd_args_, "ip-address", AF_INET);
2544
2545 if (!CfgMgr::instance().getD2ClientMgr().ddnsEnabled()) {
2546 ss << "DDNS updating is not enabled";
2547 resp_code = CONTROL_RESULT_CONFLICT;
2548 } else {
2549 // Find the lease.
2551 if (!lease) {
2552 ss << "No lease found for: " << addr.toText();
2553 resp_code = CONTROL_RESULT_EMPTY;
2554 } else if (lease->hostname_.empty()) {
2555 ss << "Lease for: " << addr.toText()
2556 << ", has no hostname, nothing to update";
2557 resp_code = CONTROL_RESULT_CONFLICT;
2558 } else if (!lease->fqdn_fwd_ && !lease->fqdn_rev_) {
2559 ss << "Neither forward nor reverse updates enabled for lease for: "
2560 << addr.toText();
2561 resp_code = CONTROL_RESULT_CONFLICT;
2562 } else {
2563 // We have a lease with a hostname and updates in at least
2564 // one direction enabled. Queue an NCR for it.
2565 queueNCR(CHG_ADD, lease);
2566 ss << "NCR generated for: " << addr.toText()
2567 << ", hostname: " << lease->hostname_;
2568 setSuccessResponse(handle, ss.str());
2570 return (0);
2571 }
2572 }
2573 } catch (const std::exception& ex) {
2574 ss << ex.what();
2575 }
2576
2578 setErrorResponse(handle, ss.str(), resp_code);
2579 return (resp_code == CONTROL_RESULT_EMPTY || resp_code == CONTROL_RESULT_CONFLICT ? 0 : 1);
2580}
2581
2582int
2584 std::stringstream ss;
2585 int resp_code = CONTROL_RESULT_ERROR;
2586
2587 try {
2588 extractCommand(handle);
2589
2590 // Get the target lease address. Invalid value will throw.
2591 IOAddress addr = getAddressParam(cmd_args_, "ip-address", AF_INET6);
2592
2593 if (!CfgMgr::instance().getD2ClientMgr().ddnsEnabled()) {
2594 ss << "DDNS updating is not enabled";
2595 resp_code = CONTROL_RESULT_CONFLICT;
2596 } else {
2597 // Find the lease.
2599 if (!lease) {
2600 ss << "No lease found for: " << addr.toText();
2601 resp_code = CONTROL_RESULT_EMPTY;
2602 } else if (lease->hostname_.empty()) {
2603 ss << "Lease for: " << addr.toText()
2604 << ", has no hostname, nothing to update";
2605 resp_code = CONTROL_RESULT_CONFLICT;
2606 } else if (!lease->fqdn_fwd_ && !lease->fqdn_rev_) {
2607 ss << "Neither forward nor reverse updates enabled for lease for: "
2608 << addr.toText();
2609 resp_code = CONTROL_RESULT_CONFLICT;
2610 } else {
2611 // We have a lease with a hostname and updates in at least
2612 // one direction enabled. Queue an NCR for it.
2613 queueNCR(CHG_ADD, lease);
2614 ss << "NCR generated for: " << addr.toText()
2615 << ", hostname: " << lease->hostname_;
2616 setSuccessResponse(handle, ss.str());
2618 return (0);
2619 }
2620 }
2621 } catch (const std::exception& ex) {
2622 ss << ex.what();
2623 }
2624
2626 setErrorResponse(handle, ss.str(), resp_code);
2627 return (resp_code == CONTROL_RESULT_EMPTY ? 0 : 1);
2628}
2629
2632 const IOAddress& lease_address,
2633 const DuidPtr& duid,
2634 const int control_result,
2635 const std::string& error_message) const {
2636 auto failed_lease_map = Element::createMap();
2637 failed_lease_map->set("type", Element::create(Lease::typeToText(lease_type)));
2638
2639 if (!lease_address.isV6Zero()) {
2640 failed_lease_map->set("ip-address", Element::create(lease_address.toText()));
2641
2642 } else if (duid) {
2643 failed_lease_map->set("duid", Element::create(duid->toText()));
2644 }
2645
2646 // Associate the result with the lease.
2647 failed_lease_map->set("result", Element::create(control_result));
2648 failed_lease_map->set("error-message", Element::create(error_message));
2649
2650 return (failed_lease_map);
2651}
2652
2653int
2655 bool v4 = true;
2656 try {
2657 extractCommand(handle);
2658 v4 = (cmd_name_ == "lease4-write");
2659
2660 if (!cmd_args_) {
2661 isc_throw(isc::BadValue, "no parameters specified for the command");
2662 }
2663
2664 ConstElementPtr file = cmd_args_->get("filename");
2665 if (!file) {
2666 isc_throw(BadValue, "'filename' parameter not specified");
2667 }
2668 if (file->getType() != Element::string) {
2669 isc_throw(BadValue, "'filename' parameter must be a string");
2670 }
2671 string filename = file->stringValue();
2672 if (filename.empty()) {
2673 isc_throw(BadValue, "'filename' parameter is empty");
2674 }
2675
2676 if (v4) {
2678 } else {
2680 }
2681 ostringstream s;
2682 s << (v4 ? "IPv4" : "IPv6")
2683 << " lease database into '"
2684 << filename << "'.";
2686 setResponse(handle, response);
2687 } catch (const std::exception& ex) {
2688 setErrorResponse(handle, ex.what());
2689 return (CONTROL_RESULT_ERROR);
2690 }
2691
2692 return (0);
2693}
2694
2695int
2697 return (impl_->leaseAddHandler(handle));
2698}
2699
2700int
2702 return (impl_->lease6BulkApplyHandler(handle));
2703}
2704
2705int
2707 return (impl_->leaseGetHandler(handle));
2708}
2709
2710int
2712 return (impl_->leaseGetAllHandler(handle));
2713}
2714
2715int
2717 return (impl_->leaseGetPageHandler(handle));
2718}
2719
2720int
2722 return (impl_->leaseGetByHwAddressHandler(handle));
2723}
2724
2725int
2727 return (impl_->leaseGetByClientIdHandler(handle));
2728}
2729
2730int
2732 return (impl_->leaseGetByDuidHandler(handle));
2733}
2734
2735int
2737 return (impl_->leaseGetByHostnameHandler(handle));
2738}
2739
2740int
2742 return (impl_->lease4DelHandler(handle));
2743}
2744
2745int
2747 return (impl_->lease6DelHandler(handle));
2748}
2749
2750int
2752 return (impl_->lease4UpdateHandler(handle));
2753}
2754
2755int
2757 return (impl_->lease6UpdateHandler(handle));
2758}
2759
2760int
2763 return (impl_->lease4WipeHandler(handle));
2764}
2765
2766int
2769 return (impl_->lease6WipeHandler(handle));
2770}
2771
2772int
2774 return (impl_->lease4ResendDdnsHandler(handle));
2775}
2776
2777int
2779 return (impl_->lease6ResendDdnsHandler(handle));
2780}
2781
2782int
2784 return (impl_->leaseWriteHandler(handle));
2785}
2786
2788}
2789
2790} // end of namespace lease_cmds
2791} // end of namespace isc
Exception thrown when a command failed due to a conflict.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
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
static ElementPtr create(const Position &pos=ZERO_POSITION())
Definition: data.cc:249
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
Definition: data.cc:304
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
Definition: data.cc:299
uint32_t getUint32(isc::data::ConstElementPtr scope, const std::string &name)
Returns a value converted to uint32_t.
static CfgMgr & instance()
returns a single instance of Configuration Manager
Definition: cfgmgr.cc:25
SrvConfigPtr getCurrentCfg()
Returns a pointer to the current configuration.
Definition: cfgmgr.cc:161
static ClientIdPtr fromText(const std::string &text)
Create client identifier from the textual format.
Definition: duid.cc:73
Holds DUID (DHCPv6 Unique Identifier)
Definition: duid.h:142
static DUID fromText(const std::string &text)
Create DUID from the textual format.
Definition: duid.cc:50
static TrackingLeaseMgr & 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.
virtual size_t wipeLeases6(const SubnetID &subnet_id)=0
Virtual method which removes specified leases.
virtual Lease4Collection getLeases4(SubnetID subnet_id) const =0
Returns all IPv4 leases for the particular subnet identifier.
virtual void writeLeases6(const std::string &filename)=0
Write V6 leases to a file.
virtual Lease4Ptr getLease4(const isc::asiolink::IOAddress &addr) const =0
Returns an IPv4 lease for specified IPv4 address.
virtual bool addLease(const Lease4Ptr &lease)=0
Adds an IPv4 lease.
virtual size_t wipeLeases4(const SubnetID &subnet_id)=0
Virtual method which removes specified leases.
virtual void updateLease4(const Lease4Ptr &lease4)=0
Updates IPv4 lease.
virtual void writeLeases4(const std::string &filename)=0
Write V4 leases to a file.
virtual Lease6Ptr getLease6(Lease::Type type, const isc::asiolink::IOAddress &addr) const =0
Returns existing IPv6 lease for a given IPv6 address.
virtual void updateLease6(const Lease6Ptr &lease6)=0
Updates IPv6 lease.
Wraps value holding size of the page with leases.
Definition: lease_mgr.h:46
Attempt to update lease that was not there.
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:30
Parser for Lease6 structure.
Definition: lease_parser.h:78
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:1721
IOAddress getAddressParam(ConstElementPtr params, const std::string name, short family=AF_INET) const
Definition: lease_cmds.cc:2506
static void updateStatsOnUpdate(const Lease4Ptr &existing, const Lease4Ptr &lease)
Update stats when updating lease.
Definition: lease_cmds.cc:560
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:2631
static bool addOrUpdate6(Lease6Ptr lease, bool force_create)
Add or update lease.
Definition: lease_cmds.cc:941
int lease6BulkApplyHandler(CalloutHandle &handle)
lease6-bulk-apply command handler
Definition: lease_cmds.cc:1800
int leaseGetByDuidHandler(hooks::CalloutHandle &handle)
lease6-get-by-duid command handler
Definition: lease_cmds.cc:1601
int lease6UpdateHandler(CalloutHandle &handle)
lease6-update handler
Definition: lease_cmds.cc:2143
int leaseGetPageHandler(hooks::CalloutHandle &handle)
lease4-get-page, lease6-get-page commands handler
Definition: lease_cmds.cc:1382
Lease6Ptr getIPv6LeaseForDelete(const Parameters &parameters) const
Convenience function fetching IPv6 address to be used to delete a lease.
Definition: lease_cmds.cc:2464
int leaseGetByHostnameHandler(hooks::CalloutHandle &handle)
lease4-get-by-hostname and lease6-get-by-hostname commands handler
Definition: lease_cmds.cc:1651
int lease6DelHandler(CalloutHandle &handle)
lease6-del command handler
Definition: lease_cmds.cc:2010
int leaseGetByHwAddressHandler(hooks::CalloutHandle &handle)
lease4-get-by-hw-address command handler
Definition: lease_cmds.cc:1501
static ConstElementPtr getExtendedInfo6(const Lease6Ptr &lease)
Get DHCPv6 extended info.
Definition: lease_cmds.cc:463
int leaseGetHandler(CalloutHandle &handle)
lease4-get, lease6-get command handler
Definition: lease_cmds.cc:1209
static bool addOrUpdate4(Lease4Ptr lease, bool force_create)
Add or update lease.
Definition: lease_cmds.cc:910
int lease6WipeHandler(CalloutHandle &handle)
lease6-wipe handler
Definition: lease_cmds.cc:2319
int leaseGetByClientIdHandler(hooks::CalloutHandle &handle)
lease4-get-by-client-id command handler
Definition: lease_cmds.cc:1551
int lease6ResendDdnsHandler(CalloutHandle &handle)
lease6-resend-ddns handler
Definition: lease_cmds.cc:2583
int leaseAddHandler(CalloutHandle &handle)
lease4-add, lease6-add command handler
Definition: lease_cmds.cc:984
int lease4ResendDdnsHandler(CalloutHandle &handle)
lease4-resend-ddns handler
Definition: lease_cmds.cc:2535
static void updateStatsOnAdd(const Lease4Ptr &lease)
Update stats when adding lease.
Definition: lease_cmds.cc:477
Parameters getParameters(bool v6, const ConstElementPtr &args)
Extracts parameters required for reservation-get and reservation-del.
Definition: lease_cmds.cc:1091
int lease4UpdateHandler(CalloutHandle &handle)
lease4-update handler
Definition: lease_cmds.cc:2081
int lease4WipeHandler(CalloutHandle &handle)
lease4-wipe handler
Definition: lease_cmds.cc:2205
int leaseGetAllHandler(CalloutHandle &handle)
lease4-get-all, lease6-get-all commands handler
Definition: lease_cmds.cc:1301
int leaseWriteHandler(CalloutHandle &handle)
lease4-write handler, lease6-write handler
Definition: lease_cmds.cc:2654
static void updateStatsOnDelete(const Lease4Ptr &lease)
Update stats when deleting lease.
Definition: lease_cmds.cc:827
int lease4ResendDdnsHandler(hooks::CalloutHandle &handle)
lease4-resend-ddns command handler
Definition: lease_cmds.cc:2773
int lease6WipeHandler(hooks::CalloutHandle &handle)
lease6-wipe handler
Definition: lease_cmds.cc:2767
int leaseGetPageHandler(hooks::CalloutHandle &handle)
lease4-get-page, lease6-get-page commands handler
Definition: lease_cmds.cc:2716
int lease6DelHandler(hooks::CalloutHandle &handle)
lease6-del command handler
Definition: lease_cmds.cc:2746
int leaseGetAllHandler(hooks::CalloutHandle &handle)
lease4-get-all, lease6-get-all commands handler
Definition: lease_cmds.cc:2711
int leaseGetByHostnameHandler(hooks::CalloutHandle &handle)
lease4-get-by-hostname and lease6-get-by-hostname commands handler
Definition: lease_cmds.cc:2736
int lease4DelHandler(hooks::CalloutHandle &handle)
lease4-del command handler
Definition: lease_cmds.cc:2741
int leaseWriteHandler(hooks::CalloutHandle &handle)
lease4-write handler, lease6-write handler
Definition: lease_cmds.cc:2783
int leaseAddHandler(hooks::CalloutHandle &handle)
lease4-add, lease6-add command handler
Definition: lease_cmds.cc:2696
int leaseGetByClientIdHandler(hooks::CalloutHandle &handle)
lease4-get-by-client-id command handler
Definition: lease_cmds.cc:2726
int lease4UpdateHandler(hooks::CalloutHandle &handle)
lease4-update handler
Definition: lease_cmds.cc:2751
int leaseGetHandler(hooks::CalloutHandle &handle)
lease4-get, lease6-get command handler
Definition: lease_cmds.cc:2706
int leaseGetByHwAddressHandler(hooks::CalloutHandle &handle)
lease4-get-by-hw-address command handler
Definition: lease_cmds.cc:2721
int lease6UpdateHandler(hooks::CalloutHandle &handle)
lease6-update handler
Definition: lease_cmds.cc:2756
int leaseGetByDuidHandler(hooks::CalloutHandle &handle)
lease6-get-by-duid command handler
Definition: lease_cmds.cc:2731
int lease6BulkApplyHandler(hooks::CalloutHandle &handle)
lease6-bulk-apply command handler
Definition: lease_cmds.cc:2701
int lease4WipeHandler(hooks::CalloutHandle &handle)
lease4-wipe handler
Definition: lease_cmds.cc:2761
int lease6ResendDdnsHandler(hooks::CalloutHandle &handle)
lease6-resend-ddns command handler
Definition: lease_cmds.cc:2778
ObservationPtr getObservation(const std::string &name) const
Returns an observation.
static StatsMgr & instance()
Statistics Manager accessor method.
static std::string generateName(const std::string &context, Type index, const std::string &stat_name)
Generates statistic name in a given context.
RAII class creating a critical section.
static MultiThreadingMgr & instance()
Returns a single instance of Multi Threading Manager.
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.
void setValue(const std::string &name, const int64_t value)
Records absolute integer observation.
void addValue(const std::string &name, const int64_t value)
Records incremental integer observation.
const isc::log::MessageID LEASE_CMDS_DEL4
const isc::log::MessageID LEASE_CMDS_WIPE4_FAILED
const isc::log::MessageID LEASE_CMDS_UPDATE6_FAILED
const isc::log::MessageID LEASE_CMDS_UPDATE4_FAILED
const isc::log::MessageID LEASE_CMDS_WIPE6_FAILED
const isc::log::MessageID LEASE_CMDS_UPDATE6_CONFLICT
const isc::log::MessageID LEASE_CMDS_UPDATE4_CONFLICT
const isc::log::MessageID LEASE_CMDS_RESEND_DDNS4_FAILED
const isc::log::MessageID LEASE_CMDS_DEL6
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_WIPE6
const isc::log::MessageID LEASE_CMDS_ADD6_CONFLICT
const isc::log::MessageID LEASE_CMDS_BULK_APPLY6_FAILED
const isc::log::MessageID LEASE_CMDS_UPDATE6
const isc::log::MessageID LEASE_CMDS_RESEND_DDNS4
const isc::log::MessageID LEASE_CMDS_GET6_FAILED
const isc::log::MessageID LEASE_CMDS_WIPE4
const isc::log::MessageID LEASE_CMDS_BULK_APPLY6
const isc::log::MessageID LEASE_CMDS_RESEND_DDNS6_FAILED
const isc::log::MessageID LEASE_CMDS_RESEND_DDNS6
const isc::log::MessageID LEASE_CMDS_GET4_FAILED
const isc::log::MessageID LEASE_CMDS_ADD4_CONFLICT
const isc::log::MessageID LEASE_CMDS_DEL4_FAILED
const isc::log::MessageID LEASE_CMDS_ADD6_FAILED
const isc::log::MessageID LEASE_CMDS_UPDATE4
const isc::log::MessageID LEASE_CMDS_DEL6_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
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
Definition: macros.h:26
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition: macros.h:14
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()
Creates a standard config/command level success answer message (i.e.
const int CONTROL_RESULT_CONFLICT
Status code indicating that the command was unsuccessful due to a conflict between the command argume...
const int CONTROL_RESULT_SUCCESS
Status code indicating a successful operation.
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:29
boost::shared_ptr< Element > ElementPtr
Definition: data.h:28
boost::shared_ptr< const SrvConfig > ConstSrvConfigPtr
Const pointer to the SrvConfig.
Definition: srv_config.h:1270
void queueNCR(const NameChangeType &chg_type, const Lease4Ptr &lease)
Creates name change request from the DHCPv4 lease.
boost::shared_ptr< const Subnet6 > ConstSubnet6Ptr
A const pointer to a Subnet6 object.
Definition: subnet.h:660
boost::shared_ptr< const Subnet4 > ConstSubnet4Ptr
A const pointer to a Subnet4 object.
Definition: subnet.h:495
boost::shared_ptr< DUID > DuidPtr
Definition: duid.h:136
boost::shared_ptr< Lease6 > Lease6Ptr
Pointer to a Lease6 structure.
Definition: lease.h:505
std::vector< Lease6Ptr > Lease6Collection
A collection of IPv6 leases.
Definition: lease.h:670
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:974
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
Definition: hwaddr.h:154
boost::shared_ptr< Pool > PoolPtr
a pointer to either IPv4 or IPv6 Pool
Definition: pool.h:483
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:903
uint32_t SubnetID
Defines unique IPv4 or IPv6 subnet identifier.
Definition: subnet_id.h:25
boost::shared_ptr< ClientId > ClientIdPtr
Shared pointer to a Client ID.
Definition: duid.h:216
boost::shared_ptr< const CfgSubnets4 > ConstCfgSubnets4Ptr
Const pointer.
Definition: cfg_subnets4.h:353
boost::shared_ptr< const CfgSubnets6 > ConstCfgSubnets6Ptr
Const pointer.
Definition: cfg_subnets6.h:351
std::vector< Lease4Ptr > Lease4Collection
A collection of IPv4 leases.
Definition: lease.h:497
boost::shared_ptr< Lease4 > Lease4Ptr
Pointer to a Lease4 structure.
Definition: lease.h:292
const int LEASE_CMDS_DBG_COMMAND_DATA
Logging level used to log successful commands.
isc::log::Logger lease_cmds_logger("lease-cmds-hooks")
Defines the logger used by the top-level component of kea-lfc.
Hardware type that represents information from DHCPv4 packet.
Definition: hwaddr.h:20
static HWAddr fromText(const std::string &text, const uint16_t htype=HTYPE_ETHER)
Creates instance of the hardware address from textual format.
Definition: hwaddr.cc:69
Structure that holds a lease for IPv6 address and/or prefix.
Definition: lease.h:513
@ ACTION_UPDATE
update extended info tables.
Definition: lease.h:553
a common structure for IPv4 and IPv6 leases
Definition: lease.h:31
Type
Type of lease or pool.
Definition: lease.h:46
@ TYPE_TA
the lease contains temporary IPv6 address
Definition: lease.h:48
@ TYPE_PD
the lease contains IPv6 prefix (for prefix delegation)
Definition: lease.h:49
@ TYPE_V4
IPv4 lease.
Definition: lease.h:50
@ TYPE_NA
the lease contains non-temporary IPv6 address
Definition: lease.h:47
static void syncCurrentExpirationTime(const Lease &from, Lease &to)
Sync lease current expiration time with new value from another lease, so that additional operations c...
Definition: lease.cc:310
static std::string typeToText(Type type)
returns text representation of a lease type
Definition: lease.cc:54