Kea 3.3.3
host_cache.cc
Go to the documentation of this file.
1// Copyright (C) 2020-2026 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>
8
10#include <dhcpsrv/cfgmgr.h>
14#include <util/encode/encode.h>
15#include <util/filesystem.h>
17#include <util/str.h>
18
19#include <fstream>
20#include <sstream>
21#include <string>
22
23#include <host_cache_log.h>
24
25using namespace std;
26using namespace isc::asiolink;
27using namespace isc::config;
28using namespace isc::data;
29using namespace isc::db;
30using namespace isc::dhcp;
31using namespace isc::util;
32using namespace isc::util::file;
33
34namespace isc {
35namespace host_cache {
36
37HostCache::HostCache() : impl_(new HostCacheImpl()), mutex_(new std::mutex) {
38}
39
41 impl_.reset();
42}
43
45 HCConfigParser parser;
46 parser.parse(*this, config);
47}
48
49void HostCache::setMaximum(size_t maximum) {
51 impl_->setMaximum(maximum);
52}
53
54size_t HostCache::getMaximum() const {
56 return (impl_->getMaximum());
57}
58
60HostCache::getAll(const Host::IdentifierType& /*identifier_type*/,
61 const uint8_t* /*identifier_begin*/,
62 const size_t /*identifier_len*/) const {
63 return (ConstHostCollection());
64}
65
67HostCache::getAll4(const dhcp::SubnetID& /*subnet_id*/) const {
68 return (ConstHostCollection());
69}
70
72HostCache::getAll6(const dhcp::SubnetID& /*subnet_id*/) const {
73 return (ConstHostCollection());
74}
75
77HostCache::getAllbyHostname(const std::string& /*hostname*/) const {
78 return (ConstHostCollection());
79}
80
82HostCache::getAllbyHostname4(const std::string& /*hostname*/,
83 const dhcp::SubnetID& /*subnet_id*/) const {
84 return (ConstHostCollection());
85}
86
88HostCache::getAllbyHostname6(const std::string& /*hostname*/,
89 const dhcp::SubnetID& /*subnet_id*/) const {
90 return (ConstHostCollection());
91}
92
95 size_t& /*source_index*/,
96 uint64_t /*lower_host_id*/,
97 const dhcp::HostPageSize& /*page_size*/) const {
98 return (ConstHostCollection());
99}
100
103 size_t& /*source_index*/,
104 uint64_t /*lower_host_id*/,
105 const dhcp::HostPageSize& /*page_size*/) const {
106 return (ConstHostCollection());
107}
108
110HostCache::getPage4(size_t& /*source_index*/,
111 uint64_t /*lower_host_id*/,
112 const dhcp:: HostPageSize& /*page_size*/) const {
113 return (ConstHostCollection());
114}
115
117HostCache::getPage6(size_t& /*source_index*/,
118 uint64_t /*lower_host_id*/,
119 const dhcp::HostPageSize& /*page_size*/) const {
120 return (ConstHostCollection());
121}
122
124HostCache::getAll4(const asiolink::IOAddress& /*address*/) const {
125 return (ConstHostCollection());
126}
127
130 const dhcp::Host::IdentifierType& identifier_type,
131 const uint8_t* identifier_begin,
132 const size_t identifier_len) const {
135 .arg("IPv4")
136 .arg(subnet_id)
137 .arg(Host::getIdentifierAsText(identifier_type, identifier_begin,
138 identifier_len));
139
140 ConstHostPtr host;
141 {
143 host = impl_->get4(subnet_id, identifier_type,
144 identifier_begin, identifier_len);
145 }
146 if (host) {
149 .arg(subnet_id)
150 .arg(Host::getIdentifierAsText(identifier_type, identifier_begin,
151 identifier_len))
152 .arg(host->toText());
153 }
154 return (host);
155}
156
159 const asiolink::IOAddress& address) const {
162 .arg(subnet_id)
163 .arg(address.toText());
164
165 // Must not specify address other than IPv4.
166 if (!address.isV4()) {
167 return (ConstHostPtr());
168 }
169 ConstHostPtr host;
170 {
172 host = impl_->get4(subnet_id, address);
173 }
174 if (host) {
177 .arg(subnet_id)
178 .arg(address.toText())
179 .arg(host->toText());
180 }
181 return (host);
182}
183
186 const asiolink::IOAddress& /*address*/) const {
187 return (ConstHostCollection());
188}
189
192 const dhcp::Host::IdentifierType& identifier_type,
193 const uint8_t* identifier_begin,
194 const size_t identifier_len) const {
197 .arg("IPv6")
198 .arg(subnet_id)
199 .arg(Host::getIdentifierAsText(identifier_type, identifier_begin,
200 identifier_len));
201
202 ConstHostPtr host;
203 {
205 host = impl_->get6(subnet_id, identifier_type,
206 identifier_begin, identifier_len);
207 }
208 if (host) {
211 .arg(subnet_id)
212 .arg(Host::getIdentifierAsText(identifier_type, identifier_begin,
213 identifier_len))
214 .arg(host->toText());
215 }
216 return (host);
217}
218
221 const uint8_t prefix_len) const {
224 .arg(prefix.toText())
225 .arg(static_cast<int>(prefix_len));
226
227 ConstHostPtr host;
228 {
230 host = impl_->get6(prefix, prefix_len);
231 }
232 if (host) {
235 .arg(prefix.toText())
236 .arg(static_cast<int>(prefix_len))
237 .arg(host->toText());
238 }
239 return (host);
240}
241
244 const asiolink::IOAddress& address) const {
247 .arg(subnet_id)
248 .arg(address.toText());
249
250 // Must not specify address other than IPv6.
251 if (!address.isV6()) {
252 return (ConstHostPtr());
253 }
254
255 ConstHostPtr host;
256 {
258 host = impl_->get6(subnet_id, address);
259 }
260 if (host) {
263 .arg(subnet_id)
264 .arg(address.toText())
265 .arg(host->toText());
266 }
267 return (host);
268}
269
272 const asiolink::IOAddress& /*address*/) const {
273 return (ConstHostCollection());
274}
275
277HostCache::getAll6(const IOAddress& /*address*/) const {
278 return (ConstHostCollection());
279}
280
281void
283 if (!host) {
284 return;
285 }
286
287 // At least one subnet ID must be used.
288 if (host->getIPv4SubnetID() == SUBNET_ID_UNUSED &&
289 host->getIPv6SubnetID() == SUBNET_ID_UNUSED) {
290 return;
291 }
292
293 bool ret;
294 {
296 ret = impl_->add(host);
297 }
298 if (ret) {
300 .arg(host->toText());
301 } else {
304 .arg(host->toText());
305 isc_throw(DuplicateEntry, "Host cache duplicate entry error");
306 }
307}
308
309bool
310HostCache::del(const SubnetID& subnet_id, const IOAddress& addr) {
311 string txt;
312 if (addr.isV4()) {
313 {
315 txt = impl_->del4(subnet_id, addr);
316 }
317 if (!txt.empty()) {
320 .arg(subnet_id)
321 .arg(addr.toText())
322 .arg(txt);
323 }
324 } else if (addr.isV6()) {
325 {
327 txt = impl_->del6(subnet_id, addr);
328 }
329 if (!txt.empty()) {
332 .arg(subnet_id)
333 .arg(addr.toText())
334 .arg(txt);
335 }
336 }
337 return (false);
338}
339
340bool
341HostCache::del4(const SubnetID& subnet_id,
342 const Host::IdentifierType& identifier_type,
343 const uint8_t* identifier_begin,
344 const size_t identifier_len) {
345 string txt;
346 {
348 txt = impl_->del4(subnet_id, identifier_type,
349 identifier_begin, identifier_len);
350 }
351 if (!txt.empty()) {
354 .arg(subnet_id)
355 .arg(Host::getIdentifierAsText(identifier_type,
356 identifier_begin,
357 identifier_len))
358 .arg(txt);
359 }
360 return (false);
361}
362
363bool
364HostCache::del6(const SubnetID& subnet_id,
365 const Host::IdentifierType& identifier_type,
366 const uint8_t* identifier_begin,
367 const size_t identifier_len) {
368 string txt;
369 {
371 txt = impl_->del6(subnet_id, identifier_type,
372 identifier_begin, identifier_len);
373 }
374 if (!txt.empty()) {
377 .arg(subnet_id)
378 .arg(Host::getIdentifierAsText(identifier_type,
379 identifier_begin,
380 identifier_len))
381 .arg(txt);
382 }
383 return (false);
384}
385
386void
389 impl_->update(host);
390}
391
392bool
394 // This backend does not support the mode in which multiple reservations
395 // for the same IP address are created. If selecting this mode is
396 // attempted this function returns false to indicate that this is
397 // not allowed.
398 return (unique);
399}
400
404 return (impl_->toElement());
405}
406
407size_t
408HostCache::insert(const ConstHostPtr& host, bool overwrite) {
410 return (impl_->insert(host, overwrite));
411}
412
413bool
416 return (impl_->remove(host));
417}
418
419void
420HostCache::flush(size_t count) {
422 if (count == 0) {
423 impl_->clear();
424 } else {
425 impl_->flush(count);
426 }
427}
428
429size_t
432 return (impl_->size());
433}
434
435size_t
438 return (impl_->capacity());
439}
440
443 const uint8_t* identifier_begin,
444 const size_t identifier_len) const {
446 return (impl_->get(identifier_type, identifier_begin, identifier_len));
447}
448
449int
451 size_t count;
452 try {
453 extractCommand(handle);
454
456 count = impl_->size();
457 } catch (const std::exception& ex) {
459 .arg(ex.what());
460 setErrorResponse(handle, ex.what());
461 return (1);
462 }
463
465 .arg(count);
466 ostringstream msg;
467 msg << count << " entries.";
469 result->set("size", Element::create(static_cast<int64_t>(count)));
470 ConstElementPtr response =
471 createAnswer(CONTROL_RESULT_SUCCESS, msg.str(), result);
472 setResponse(handle, response);
473 return (0);
474}
475
476int
479
480 try {
481 extractCommand(handle);
482
483 impl_->clear();
484 } catch (const std::exception& ex) {
486 .arg(ex.what());
487 setErrorResponse(handle, ex.what());
488 return (1);
489 }
490
492 setSuccessResponse(handle, "Cache cleared.");
493 return (0);
494}
495
496int
499
500 size_t how_many = 0;
501 size_t before = impl_->size();
502 string txt = "(missing parameters)";
503 try {
504 extractCommand(handle);
505 if (cmd_args_) {
506 txt = cmd_args_->str();
507 }
508
509 if (!cmd_args_) {
510 isc_throw(BadValue, "no parameters specified for the command");
511 }
512
513 int64_t val = cmd_args_->intValue();
514
515 if (val == 0) {
516 isc_throw(BadValue, "invalid (0) parameter: "
517 "please use cache-clear command");
518 }
519
520 if (val < 0) {
521 isc_throw(BadValue, "invalid (<0) parameter");
522 }
523
524 if (val > HCConfigParser::MAXIMUM) {
525 val = HCConfigParser::MAXIMUM + 1;
526 }
527
528 how_many = static_cast<size_t>(val);
529 impl_->flush(how_many);
530 } catch (const std::exception& ex) {
532 .arg(txt)
533 .arg(ex.what());
534 setErrorResponse(handle, ex.what());
535 return (1);
536 }
537
539 ostringstream msg;
540 msg << "Cache flushed (" << before - impl_->size() << " entries removed).";
541 setSuccessResponse(handle, msg.str());
542 return (0);
543}
544
545int
548
549 ConstElementPtr dump;
550 size_t count = 0;
551 try {
552 extractCommand(handle);
553
554 dump = impl_->toElement();
555 count = dump->size();
556 } catch (const std::exception& ex) {
558 .arg(ex.what());
559 setErrorResponse(handle, ex.what());
560 return (1);
561 }
562
564 .arg(count);
565 ostringstream msg;
566 msg << count << " entries returned.";
567 ConstElementPtr response =
569 msg.str(), dump);
570 setResponse(handle, response);
571 return (0);
572}
573
574int
576 Host::IdentifierType id_type;
577 vector<uint8_t> ident;
578 string txt = "(missing parameters)";
580 size_t count = 0;
581 try {
582 extractCommand(handle);
583 if (cmd_args_) {
584 txt = cmd_args_->str();
585 }
586
587 if (!cmd_args_) {
588 isc_throw(BadValue, "no parameters specified for the command");
589 }
590
591 if (cmd_args_->getType() != Element::map) {
592 isc_throw(BadValue, "invalid (not a map) parameter");
593 }
594
595 // Take parameters.
596 string ident_txt;
597 unsigned have_ident = 0;
598 auto& map = cmd_args_->mapValue();
599 for (auto const& cfg : map) {
600 if (cfg.first == "hw-address") {
601 id_type = Host::IDENT_HWADDR;
602 ++have_ident;
603 ident_txt = cfg.second->stringValue();
604 } else if (cfg.first == "duid") {
605 id_type= Host::IDENT_DUID;
606 ++have_ident;
607 ident_txt = cfg.second->stringValue();
608 } else if (cfg.first == "circuit-id") {
609 id_type= Host::IDENT_CIRCUIT_ID;
610 ++have_ident;
611 ident_txt = cfg.second->stringValue();
612 } else if (cfg.first == "client-id") {
613 id_type= Host::IDENT_CLIENT_ID;
614 ++have_ident;
615 ident_txt = cfg.second->stringValue();
616 } else if (cfg.first == "flex-id") {
617 id_type= Host::IDENT_FLEX;
618 ++have_ident;
619 ident_txt = cfg.second->stringValue();
620 } else {
622 "unknown parameter '" << cfg.first << "'");
623 }
624 }
625
626 // Decode parameters.
627 if (have_ident == 0) {
628 isc_throw(BadValue, "an identifier is required");
629 }
630 if (have_ident > 1) {
631 isc_throw(BadValue, "only one identifier can be specified");
632 }
633 if (ident_txt.empty()) {
634 isc_throw(BadValue, "invalid (empty) identifier");
635 }
636 try {
637 ident = util::str::quotedStringToBinary(ident_txt);
638 if (ident.empty()) {
639 util::str::decodeFormattedHexString(ident_txt, ident);
640 }
641 } catch (...) {
642 isc_throw(BadValue, "invalid identifier '" << ident_txt << "'");
643 }
644
645 // Get the entry list and build the result.
647 if (!ident.empty()) {
649 hosts = impl_->get(id_type, &ident[0], ident.size());
650 }
651 for (auto const& host : hosts) {
652 result->add(host_cache::toElement(host));
653 }
654 count = result->size();
655 } catch (const std::exception& ex) {
657 .arg(ex.what());
658 setErrorResponse(handle, ex.what());
659 return (1);
660 }
661
663 .arg(count);
664 ostringstream msg;
665 msg << count << " entries returned.";
666 ConstElementPtr response =
668 msg.str(), result);
669 setResponse(handle, response);
670 return (0);
671}
672
673int
675 string filename;
676 size_t count = 0;
677 size_t overwritten = 0;
678 string txt = "(missing parameters)";
679 try {
680 extractCommand(handle);
681 if (cmd_args_) {
682 txt = cmd_args_->str();
683 }
684
685 if (!cmd_args_) {
686 isc_throw(BadValue, "no parameters specified for the command");
687 }
688
689 if (cmd_args_->getType() == Element::map) {
690 HCEntryParser parser;
691 HostPtr entry = parser.parse(cmd_args_);
692
693 ++count;
694 try {
696 overwritten += impl_->insert(entry, true);
697 } catch (const std::exception& ex) {
699 "Insert host (" << entry->toText()
700 << ") failed: " << ex.what());
701 }
702 } else {
703 HCEntryListParser parser;
704 HostCollection entries = parser.parse(cmd_args_);
705
706 for (auto const& entry : entries) {
707 ++count;
708 try {
710 overwritten += impl_->insert(entry, true);
711 } catch (const std::exception& ex) {
712 isc_throw(BadValue, "Insert failed at " << count
713 << " host (" << entry->toText()
714 << "): " << ex.what());
715 }
716 }
717 }
718 } catch (const std::exception& ex) {
720 .arg(txt)
721 .arg(ex.what());
722 setErrorResponse(handle, ex.what());
723 return (1);
724 }
725
727 .arg(count)
728 .arg(overwritten);
729 ostringstream msg;
730 msg << count << " entries inserted (" << overwritten
731 << " overwritten by more recent entries).";
732 setSuccessResponse(handle, msg.str());
733 return (0);
734}
735
736int
739
740 ConstElementPtr dump;
741 string filename;
742 size_t count = 0;
743 string txt = "(missing parameters)";
744 try {
745 extractCommand(handle);
746 if (cmd_args_) {
747 txt = cmd_args_->str();
748 }
749
750 if (!cmd_args_) {
751 isc_throw(BadValue, "no parameters specified for the command");
752 }
753
754 if (cmd_args_->getType() != Element::string) {
755 isc_throw(BadValue, "invalid (not a string) parameter");
756 }
757
758 try {
759 filename = CfgMgr::instance().validatePath(cmd_args_->stringValue());
760 } catch (const SecurityWarn& ex) {
762 .arg(ex.what());
763 filename = cmd_args_->stringValue();
764 } catch (const std::exception& ex) {
765 isc_throw(BadValue, "parameter is invalid: " << ex.what());
766 }
767
768 ofstream out(filename, ios::trunc);
769 if (!out.good()) {
770 isc_throw(Unexpected, "Unable to open file '" << filename
771 << "' for writing.");
772 }
773
774 dump = impl_->toElement();
775 count = dump->size();
776 prettyPrint(dump, out);
777 out.close();
778 } catch (const std::exception& ex) {
780 .arg(txt)
781 .arg(ex.what());
782 setErrorResponse(handle, ex.what());
783 return (1);
784 }
785
787 .arg(count);
788 ostringstream msg;
789 msg << count << " entries dumped to '" << filename << "'.";
790 setSuccessResponse(handle, msg.str());
791 return (0);
792}
793
794int
797
798 string filename;
799 size_t count = 0;
800 size_t overwritten = 0;
801 string txt = "(missing parameters)";
802 try {
803 extractCommand(handle);
804 if (cmd_args_) {
805 txt = cmd_args_->str();
806 }
807
808 if (!cmd_args_) {
809 isc_throw(BadValue, "no parameters specified for the command");
810 }
811
812 if (cmd_args_->getType() != Element::string) {
813 isc_throw(BadValue, "invalid (not a string) parameter");
814 }
815
816 filename = cmd_args_->stringValue();
817 if (filename.empty()) {
818 isc_throw(BadValue, "invalid (empty string) parameter");
819 }
820
821 ConstElementPtr json = Element::fromJSONFile(filename);
822 if (!json) {
823 isc_throw(Unexpected, "No entries found.");
824 }
825 HCEntryListParser parser;
826 HostCollection entries = parser.parse(json);
827
828 for (auto const& entry : entries) {
829 ++count;
830 try {
831 overwritten += impl_->insert(entry, true);
832 } catch (const std::exception& ex) {
833 isc_throw(BadValue, "Insert failed at " << count
834 << " host ( " << entry->toText()
835 << "): " << ex.what());
836 }
837 }
838 } catch (const std::exception& ex) {
840 .arg(txt)
841 .arg(ex.what());
842 setErrorResponse(handle, ex.what());
843 return (1);
844 }
845
847 .arg(count)
848 .arg(overwritten);
849 ostringstream msg;
850 msg << count << " entries loaded from '" << filename << "' ("
851 << overwritten << " overwritten by more recent entries).";
852 setSuccessResponse(handle, msg.str());
853 return (0);
854}
855
856int
858 uint16_t family = AF_UNIX;
859 SubnetID subnet_id;
860 string addr_txt;
861 Host::IdentifierType id_type;
862 vector<uint8_t> ident;
863 string txt = "(missing parameters)";
864 string del_txt;
865 try {
866 extractCommand(handle);
867 if (cmd_args_) {
868 txt = cmd_args_->str();
869 }
870
871 if (!cmd_args_) {
872 isc_throw(BadValue, "no parameters specified for the command");
873 }
874
875 if (cmd_args_->getType() != Element::map) {
876 isc_throw(BadValue, "invalid (not a map) parameter");
877 }
878
879 // Take parameters.
880 string ident_txt;
881 bool have_ident = false;
882 bool valid = true;
883 auto& map = cmd_args_->mapValue();
884 for (auto const& cfg : map) {
885 if (cfg.first == "subnet-id") {
886 if (family != AF_UNIX) {
887 valid = false;
888 }
889 family = AF_UNSPEC;
890 subnet_id = static_cast<uint32_t>(cfg.second->intValue());
891 } else if (cfg.first == "subnet-id4") {
892 if (family != AF_UNIX) {
893 valid = false;
894 }
895 family = AF_INET;
896 subnet_id = static_cast<uint32_t>(cfg.second->intValue());
897 } else if (cfg.first == "subnet-id6") {
898 if (family != AF_UNIX) {
899 valid = false;
900 }
901 family = AF_INET6;
902 subnet_id = static_cast<uint32_t>(cfg.second->intValue());
903 } else if (cfg.first == "ip-address") {
904 addr_txt = cfg.second->stringValue();
905 } else if (cfg.first == "hw-address") {
906 id_type = Host::IDENT_HWADDR;
907 if (have_ident) {
908 valid = false;
909 }
910 have_ident = true;
911 ident_txt = cfg.second->stringValue();
912 } else if (cfg.first == "duid") {
913 id_type= Host::IDENT_DUID;
914 if (have_ident) {
915 valid = false;
916 }
917 have_ident = true;
918 ident_txt = cfg.second->stringValue();
919 } else if (cfg.first == "circuit-id") {
920 id_type= Host::IDENT_CIRCUIT_ID;
921 if (have_ident) {
922 valid = false;
923 }
924 have_ident = true;
925 ident_txt = cfg.second->stringValue();
926 } else if (cfg.first == "client-id") {
927 id_type= Host::IDENT_CLIENT_ID;
928 if (have_ident) {
929 valid = false;
930 }
931 have_ident = true;
932 ident_txt = cfg.second->stringValue();
933 } else if (cfg.first == "flex-id") {
934 id_type= Host::IDENT_FLEX;
935 if (have_ident) {
936 valid = false;
937 }
938 have_ident = true;
939 ident_txt = cfg.second->stringValue();
940 } else {
942 "unknown parameter '" << cfg.first << "'");
943 }
944 }
945
946 // Decode parameters.
947 IOAddress addr(0);
948 if (valid && !addr_txt.empty()) {
949 if (have_ident) {
950 valid = false;
951 }
952 if (family == AF_UNIX) {
953 isc_throw(BadValue, "subnet-id is required");
954 }
955 addr = IOAddress(addr_txt);
956 if (addr.isV4()) {
957 if (family == AF_INET6) {
958 valid = false;
959 }
960 if (addr.isV4Zero()) {
961 isc_throw(BadValue, "invalid ip-address '0.0.0.0'");
962 }
963 family = AF_INET;
964 } else if (addr.isV6()) {
965 if (family == AF_INET) {
966 valid = false;
967 }
968 if (addr.isV6Zero()) {
969 isc_throw(BadValue, "invalid ip-address '::'");
970 }
971 family = AF_INET6;
972 } else {
974 "invalid ip-address '" << addr_txt << "'");
975 }
976 } else if (valid) {
977 if (!have_ident) {
979 "either ip-address or an identifier is required");
980 }
981 if (ident_txt.empty()) {
982 isc_throw(BadValue, "invalid (empty) identifier");
983 }
984 if ((family != AF_INET) && (family != AF_INET6)) {
986 "either subnet-id4 or subnet-id6 is required");
987 }
988 try {
989 ident = util::str::quotedStringToBinary(ident_txt);
990 if (ident.empty()) {
991 util::str::decodeFormattedHexString(ident_txt, ident);
992 }
993 } catch (...) {
995 "invalid identifier '" << ident_txt << "'");
996 }
997 }
998
999 // Something is wrong?
1000 if (!valid) {
1001 isc_throw(BadValue, "inconsistent parameters");
1002 }
1003
1004 // Call del*().
1006 if (!addr_txt.empty()) {
1007 if (family == AF_INET) {
1008 del_txt = impl_->del4(subnet_id, addr);
1009 } else {
1010 del_txt = impl_->del6(subnet_id, addr);
1011 }
1012 } else if (ident.empty()) {
1013 isc_throw(BadValue, "empty identifier");
1014 } else if (family == AF_INET) {
1015 del_txt = impl_->del4(subnet_id, id_type, &ident[0], ident.size());
1016 } else {
1017 del_txt = impl_->del6(subnet_id, id_type, &ident[0], ident.size());
1018 }
1019 } catch (const std::exception& ex) {
1021 .arg(txt)
1022 .arg(ex.what());
1023 setErrorResponse(handle, ex.what());
1024 return (1);
1025 }
1026
1028 .arg(txt);
1029 if (!del_txt.empty()) {
1030 setSuccessResponse(handle, "Host removed.");
1031 } else {
1032 setErrorResponse(handle, "Host not removed (not found).",
1034 }
1035 return (0);
1036}
1037
1038} // end of namespace isc::host_cache
1039} // end of namespace isc
static ElementPtr create(const Position &pos=ZERO_POSITION())
Create a NullElement.
Definition data.cc:300
@ map
Definition data.h:160
@ string
Definition data.h:157
static ElementPtr fromJSONFile(const std::string &file_name, bool preproc=false)
Reads contents of specified file and interprets it as JSON.
Definition data.cc:884
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
Definition data.cc:355
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
Definition data.cc:350
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 when an unexpected error condition occurs.
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
Database duplicate entry error.
std::string validatePath(const std::string data_path) const
Validates a file path against the supported directory for DHCP data.
Definition cfgmgr.cc:40
static CfgMgr & instance()
returns a single instance of Configuration Manager
Definition cfgmgr.cc:29
Wraps value holding size of the page with host reservations.
std::string getIdentifierAsText() const
Returns host identifier in a textual form.
Definition host.cc:319
IdentifierType
Type of the host identifier.
Definition host.h:340
@ IDENT_FLEX
Flexible host identifier.
Definition host.h:345
@ IDENT_CLIENT_ID
Definition host.h:344
@ IDENT_CIRCUIT_ID
Definition host.h:343
Per-packet callout handle.
Configuration parser for Host Cache.
static const int64_t MAXIMUM
Absolute maximum number of elements.
void parse(HostCache &hcref, const data::ConstElementPtr &config)
Parses Host Cache configuration.
dhcp::HostCollection parse(const data::ConstElementPtr &entry_list)
Parses Host Cache entries.
dhcp::HostPtr parse(const data::ConstElementPtr &entry)
Parses Host Cache entry.
Host Cache hooks library implementation.
virtual size_t size() const
Return the number of entries.
virtual void configure(const data::ConstElementPtr &config)
Parses configuration.
Definition host_cache.cc:44
virtual bool setIPReservationsUnique(const bool unique)
Controls whether IP reservations are unique or non-unique.
boost::shared_ptr< HostCacheImpl > impl_
Implementation.
Definition host_cache.h:674
virtual size_t getMaximum() const
Get maximum number of cached hosts.
Definition host_cache.cc:54
virtual void flush(size_t count)
Flush entries.
int cacheLoadHandler(hooks::CalloutHandle &handle)
cache-load command handler.
virtual dhcp::ConstHostCollection getAll(const dhcp::Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len) const
BaseHostDataSource methods.
Definition host_cache.cc:60
virtual bool del6(const dhcp::SubnetID &subnet_id, const dhcp::Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len)
Attempts to delete a host by (subnet-id6, identifier, identifier-type).
virtual bool del4(const dhcp::SubnetID &subnet_id, const dhcp::Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len)
Attempts to delete a host by (subnet-id4, identifier, identifier-type).
virtual dhcp::ConstHostCollection getAllbyHostname4(const std::string &hostname, const dhcp::SubnetID &subnet_id) const
Return all hosts with a hostname in a DHCPv4 subnet.
Definition host_cache.cc:82
virtual ~HostCache()
Destructor.
Definition host_cache.cc:40
void update(isc::dhcp::HostPtr const &host)
Implements isc::dhcp::BaseHostDataSource::update() for HostCache.
virtual dhcp::ConstHostPtr get6(const dhcp::SubnetID &subnet_id, const dhcp::Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len) const
Returns a host connected to the IPv6 subnet.
int cacheRemoveHandler(hooks::CalloutHandle &handle)
cache-remove command handler.
virtual size_t capacity() const
Return the maximum number of entries.
virtual void setMaximum(size_t maximum)
Set maximum number of cached hosts (0 means unbound).
Definition host_cache.cc:49
virtual void add(const dhcp::HostPtr &host)
Adds a new host to the collection.
int cacheInsertHandler(hooks::CalloutHandle &handle)
cache-insert command handler.
boost::scoped_ptr< std::mutex > mutex_
mutex
Definition host_cache.h:677
virtual bool del(const dhcp::SubnetID &subnet_id, const asiolink::IOAddress &addr)
Attempts to delete a host by (subnet-id, address).
virtual size_t insert(const dhcp::ConstHostPtr &host, bool overwrite)
Insert a host into the cache.
int cacheGetByIdHandler(hooks::CalloutHandle &handle)
cache-get-by-id command handler.
int cacheWriteHandler(hooks::CalloutHandle &handle)
cache-write command handler.
virtual dhcp::ConstHostCollection getPage4(const dhcp::SubnetID &subnet_id, size_t &source_index, uint64_t lower_host_id, const dhcp::HostPageSize &page_size) const
Return range of hosts in a DHCPv4 subnet.
Definition host_cache.cc:94
virtual dhcp::ConstHostCollection getAll6(const dhcp::SubnetID &subnet_id) const
Return all hosts in a DHCPv6 subnet.
Definition host_cache.cc:72
virtual dhcp::ConstHostCollection getAll4(const dhcp::SubnetID &subnet_id) const
Return all hosts in a DHCPv4 subnet.
Definition host_cache.cc:67
int cacheFlushHandler(hooks::CalloutHandle &handle)
cache-flush command handler.
virtual dhcp::ConstHostCollection getAllbyHostname6(const std::string &hostname, const dhcp::SubnetID &subnet_id) const
Return all hosts with a hostname in a DHCPv6 subnet.
Definition host_cache.cc:88
virtual dhcp::ConstHostCollection getAllbyHostname(const std::string &hostname) const
Return all hosts with a hostname.
Definition host_cache.cc:77
virtual dhcp::ConstHostCollection get(const dhcp::Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len) const
Return all hosts connected to any subnet for which reservations have been made using a specified iden...
int cacheSizeHandler(hooks::CalloutHandle &handle)
Command handlers.
virtual bool remove(const dhcp::HostPtr &host)
Remove a host from the cache.
virtual data::ElementPtr toElement() const
Returns the whole content of the cache as Element tree.
virtual dhcp::ConstHostCollection getPage6(const dhcp::SubnetID &subnet_id, size_t &source_index, uint64_t lower_host_id, const dhcp::HostPageSize &page_size) const
Return range of hosts in a DHCPv6 subnet.
virtual dhcp::ConstHostPtr get4(const dhcp::SubnetID &subnet_id, const dhcp::Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len) const
Returns a host connected to the IPv4 subnet.
int cacheGetHandler(hooks::CalloutHandle &handle)
cache-get command handler.
int cacheClearHandler(hooks::CalloutHandle &handle)
cache-clear command handler.
RAII class creating a critical section.
A generic exception that is thrown if a parameter given violates security check but enforcement is la...
Definition filesystem.h:22
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#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 ...
ConstElementPtr createAnswer()
Creates a standard config/command level success answer message (i.e.
const int CONTROL_RESULT_SUCCESS
Status code indicating a successful operation.
void prettyPrint(ConstElementPtr element, std::ostream &out, unsigned indent, unsigned step)
Pretty prints the data into stream.
Definition data.cc:1770
boost::shared_ptr< const Element > ConstElementPtr
Definition data.h:30
boost::shared_ptr< Element > ElementPtr
Definition data.h:29
boost::shared_ptr< Host > HostPtr
Pointer to the Host object.
Definition host.h:840
std::vector< ConstHostPtr > ConstHostCollection
Collection of the const Host objects.
Definition host.h:846
std::vector< HostPtr > HostCollection
Collection of the Host objects.
Definition host.h:849
uint32_t SubnetID
Defines unique IPv4 or IPv6 subnet identifier.
Definition subnet_id.h:25
boost::shared_ptr< const Host > ConstHostPtr
Const pointer to the Host object.
Definition host.h:843
const isc::log::MessageID HOST_CACHE_GET_ONE_SUBNET_ID_ADDRESS4_HOST
const isc::log::MessageID HOST_CACHE_ADD_DUPLICATE
const isc::log::MessageID HOST_CACHE_COMMAND_REMOVE_FAILED
const isc::log::MessageID HOST_CACHE_COMMAND_CLEAR_FAILED
const isc::log::MessageID HOST_CACHE_COMMAND_GET_BY_ID
const isc::log::MessageID HOST_CACHE_COMMAND_FLUSH
const isc::log::MessageID HOST_CACHE_COMMAND_LOAD_FAILED
const isc::log::MessageID HOST_CACHE_COMMAND_GET
const isc::log::MessageID HOST_CACHE_ADD
const int HOST_CACHE_DBG_RESULTS
Records the results of the lookups.
const isc::log::MessageID HOST_CACHE_COMMAND_INSERT
const isc::log::MessageID HOST_CACHE_COMMAND_WRITE_FAILED
const isc::log::MessageID HOST_CACHE_DEL_SUBNET_ID_IDENTIFIER4
const isc::log::MessageID HOST_CACHE_GET_ONE_SUBNET_ID_IDENTIFIER_HOST
const isc::log::MessageID HOST_CACHE_COMMAND_SIZE_FAILED
const isc::log::MessageID HOST_CACHE_COMMAND_FLUSH_FAILED
const isc::log::MessageID HOST_CACHE_COMMAND_LOAD
const isc::log::MessageID HOST_CACHE_GET_ONE_SUBNET_ID_IDENTIFIER
const isc::log::MessageID HOST_CACHE_DEL_SUBNET_ID_ADDRESS4
const isc::log::MessageID HOST_CACHE_GET_ONE_PREFIX
const isc::log::MessageID HOST_CACHE_COMMAND_GET_BY_ID_FAILED
const isc::log::MessageID HOST_CACHE_DEL_SUBNET_ID_ADDRESS6
const isc::log::MessageID HOST_CACHE_GET_ONE_PREFIX_HOST
const isc::log::MessageID HOST_CACHE_COMMAND_CLEAR
const isc::log::MessageID HOST_CACHE_GET_ONE_SUBNET_ID_ADDRESS6
const isc::log::MessageID HOST_CACHE_COMMAND_SIZE
const isc::log::MessageID HOST_CACHE_GET_ONE_SUBNET_ID_ADDRESS4
const isc::log::MessageID HOST_CACHE_COMMAND_REMOVE
const isc::log::MessageID HOST_CACHE_GET_ONE_SUBNET_ID_ADDRESS6_HOST
const isc::log::MessageID HOST_CACHE_COMMAND_GET_FAILED
ElementPtr toElement(const ConstHostPtr &host)
Unparse a host cache entry.
Definition entry.cc:25
const isc::log::MessageID HOST_CACHE_COMMAND_WRITE
const int HOST_CACHE_DBG_TRACE
Host Cache hooks library logging levels.
const isc::log::MessageID HOST_CACHE_COMMAND_INSERT_FAILED
const isc::log::MessageID HOST_CACHE_PATH_SECURITY_WARNING
const isc::log::MessageID HOST_CACHE_DEL_SUBNET_ID_IDENTIFIER6
isc::log::Logger host_cache_logger("host-cache-hooks")
Host Cache Logger.
void decodeFormattedHexString(const string &hex_string, vector< uint8_t > &binary)
Converts a formatted string of hexadecimal digits into a vector.
Definition str.cc:212
vector< uint8_t > quotedStringToBinary(const string &quoted_string)
Converts a string in quotes into vector.
Definition str.cc:139
Defines the logger used by the top-level component of kea-lfc.
RAII lock object to protect the code in the same scope with a mutex.