Kea 3.1.1
host_cache.cc
Go to the documentation of this file.
1// Copyright (C) 2020-2025 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
9#include <host_cache.h>
10#include <host_cache_impl.h>
11#include <host_cache_parsers.h>
12#include <host_cache_log.h>
14#include <dhcpsrv/cfgmgr.h>
15#include <util/encode/encode.h>
16#include <util/filesystem.h>
18#include <util/str.h>
19#include <string>
20#include <sstream>
21#include <fstream>
22
23using namespace std;
24using namespace isc::asiolink;
25using namespace isc::config;
26using namespace isc::data;
27using namespace isc::db;
28using namespace isc::dhcp;
29using namespace isc::util;
30using namespace isc::util::file;
31
32namespace isc {
33namespace host_cache {
34
35HostCache::HostCache() : impl_(new HostCacheImpl()), mutex_(new std::mutex) {
36}
37
39 impl_.reset();
40}
41
43 HCConfigParser parser;
44 parser.parse(*this, config);
45}
46
47void HostCache::setMaximum(size_t maximum) {
49 impl_->setMaximum(maximum);
50}
51
52size_t HostCache::getMaximum() const {
54 return (impl_->getMaximum());
55}
56
58HostCache::getAll(const Host::IdentifierType& /*identifier_type*/,
59 const uint8_t* /*identifier_begin*/,
60 const size_t /*identifier_len*/) const {
61 return (ConstHostCollection());
62}
63
65HostCache::getAll4(const dhcp::SubnetID& /*subnet_id*/) const {
66 return (ConstHostCollection());
67}
68
70HostCache::getAll6(const dhcp::SubnetID& /*subnet_id*/) const {
71 return (ConstHostCollection());
72}
73
75HostCache::getAllbyHostname(const std::string& /*hostname*/) const {
76 return (ConstHostCollection());
77}
78
80HostCache::getAllbyHostname4(const std::string& /*hostname*/,
81 const dhcp::SubnetID& /*subnet_id*/) const {
82 return (ConstHostCollection());
83}
84
86HostCache::getAllbyHostname6(const std::string& /*hostname*/,
87 const dhcp::SubnetID& /*subnet_id*/) const {
88 return (ConstHostCollection());
89}
90
93 size_t& /*source_index*/,
94 uint64_t /*lower_host_id*/,
95 const dhcp::HostPageSize& /*page_size*/) const {
96 return (ConstHostCollection());
97}
98
101 size_t& /*source_index*/,
102 uint64_t /*lower_host_id*/,
103 const dhcp::HostPageSize& /*page_size*/) const {
104 return (ConstHostCollection());
105}
106
108HostCache::getPage4(size_t& /*source_index*/,
109 uint64_t /*lower_host_id*/,
110 const dhcp:: HostPageSize& /*page_size*/) const {
111 return (ConstHostCollection());
112}
113
115HostCache::getPage6(size_t& /*source_index*/,
116 uint64_t /*lower_host_id*/,
117 const dhcp::HostPageSize& /*page_size*/) const {
118 return (ConstHostCollection());
119}
120
122HostCache::getAll4(const asiolink::IOAddress& /*address*/) const {
123 return (ConstHostCollection());
124}
125
128 const dhcp::Host::IdentifierType& identifier_type,
129 const uint8_t* identifier_begin,
130 const size_t identifier_len) const {
133 .arg("IPv4")
134 .arg(subnet_id)
135 .arg(Host::getIdentifierAsText(identifier_type, identifier_begin,
136 identifier_len));
137
138 ConstHostPtr host;
139 {
141 host = impl_->get4(subnet_id, identifier_type,
142 identifier_begin, identifier_len);
143 }
144 if (host) {
147 .arg(subnet_id)
148 .arg(Host::getIdentifierAsText(identifier_type, identifier_begin,
149 identifier_len))
150 .arg(host->toText());
151 }
152 return (host);
153}
154
157 const asiolink::IOAddress& address) const {
160 .arg(subnet_id)
161 .arg(address.toText());
162
163 // Must not specify address other than IPv4.
164 if (!address.isV4()) {
165 return (ConstHostPtr());
166 }
167 ConstHostPtr host;
168 {
170 host = impl_->get4(subnet_id, address);
171 }
172 if (host) {
175 .arg(subnet_id)
176 .arg(address.toText())
177 .arg(host->toText());
178 }
179 return (host);
180}
181
184 const asiolink::IOAddress& /*address*/) const {
185 return (ConstHostCollection());
186}
187
190 const dhcp::Host::IdentifierType& identifier_type,
191 const uint8_t* identifier_begin,
192 const size_t identifier_len) const {
195 .arg("IPv6")
196 .arg(subnet_id)
197 .arg(Host::getIdentifierAsText(identifier_type, identifier_begin,
198 identifier_len));
199
200 ConstHostPtr host;
201 {
203 host = impl_->get6(subnet_id, identifier_type,
204 identifier_begin, identifier_len);
205 }
206 if (host) {
209 .arg(subnet_id)
210 .arg(Host::getIdentifierAsText(identifier_type, identifier_begin,
211 identifier_len))
212 .arg(host->toText());
213 }
214 return (host);
215}
216
219 const uint8_t prefix_len) const {
222 .arg(prefix.toText())
223 .arg(static_cast<int>(prefix_len));
224
225 ConstHostPtr host;
226 {
228 host = impl_->get6(prefix, prefix_len);
229 }
230 if (host) {
233 .arg(prefix.toText())
234 .arg(static_cast<int>(prefix_len))
235 .arg(host->toText());
236 }
237 return (host);
238}
239
242 const asiolink::IOAddress& address) const {
245 .arg(subnet_id)
246 .arg(address.toText());
247
248 // Must not specify address other than IPv6.
249 if (!address.isV6()) {
250 return (ConstHostPtr());
251 }
252
253 ConstHostPtr host;
254 {
256 host = impl_->get6(subnet_id, address);
257 }
258 if (host) {
261 .arg(subnet_id)
262 .arg(address.toText())
263 .arg(host->toText());
264 }
265 return (host);
266}
267
270 const asiolink::IOAddress& /*address*/) const {
271 return (ConstHostCollection());
272}
273
275HostCache::getAll6(const IOAddress& /*address*/) const {
276 return (ConstHostCollection());
277}
278
279void
281 if (!host) {
282 return;
283 }
284
285 // At least one subnet ID must be used.
286 if (host->getIPv4SubnetID() == SUBNET_ID_UNUSED &&
287 host->getIPv6SubnetID() == SUBNET_ID_UNUSED) {
288 return;
289 }
290
291 bool ret;
292 {
294 ret = impl_->add(host);
295 }
296 if (ret) {
298 .arg(host->toText());
299 } else {
302 .arg(host->toText());
303 isc_throw(DuplicateEntry, "Host cache duplicate entry error");
304 }
305}
306
307bool
308HostCache::del(const SubnetID& subnet_id, const IOAddress& addr) {
309 string txt;
310 if (addr.isV4()) {
311 {
313 txt = impl_->del4(subnet_id, addr);
314 }
315 if (!txt.empty()) {
318 .arg(subnet_id)
319 .arg(addr.toText())
320 .arg(txt);
321 }
322 } else if (addr.isV6()) {
323 {
325 txt = impl_->del6(subnet_id, addr);
326 }
327 if (!txt.empty()) {
330 .arg(subnet_id)
331 .arg(addr.toText())
332 .arg(txt);
333 }
334 }
335 return (false);
336}
337
338bool
339HostCache::del4(const SubnetID& subnet_id,
340 const Host::IdentifierType& identifier_type,
341 const uint8_t* identifier_begin,
342 const size_t identifier_len) {
343 string txt;
344 {
346 txt = impl_->del4(subnet_id, identifier_type,
347 identifier_begin, identifier_len);
348 }
349 if (!txt.empty()) {
352 .arg(subnet_id)
353 .arg(Host::getIdentifierAsText(identifier_type,
354 identifier_begin,
355 identifier_len))
356 .arg(txt);
357 }
358 return (false);
359}
360
361bool
362HostCache::del6(const SubnetID& subnet_id,
363 const Host::IdentifierType& identifier_type,
364 const uint8_t* identifier_begin,
365 const size_t identifier_len) {
366 string txt;
367 {
369 txt = impl_->del6(subnet_id, identifier_type,
370 identifier_begin, identifier_len);
371 }
372 if (!txt.empty()) {
375 .arg(subnet_id)
376 .arg(Host::getIdentifierAsText(identifier_type,
377 identifier_begin,
378 identifier_len))
379 .arg(txt);
380 }
381 return (false);
382}
383
384void
387 impl_->update(host);
388}
389
390bool
392 // This backend does not support the mode in which multiple reservations
393 // for the same IP address are created. If selecting this mode is
394 // attempted this function returns false to indicate that this is
395 // not allowed.
396 return (unique);
397}
398
402 return (impl_->toElement());
403}
404
405size_t
406HostCache::insert(const ConstHostPtr& host, bool overwrite) {
408 return (impl_->insert(host, overwrite));
409}
410
411bool
414 return (impl_->remove(host));
415}
416
417void
418HostCache::flush(size_t count) {
420 if (count == 0) {
421 impl_->clear();
422 } else {
423 impl_->flush(count);
424 }
425}
426
427size_t
430 return (impl_->size());
431}
432
433size_t
436 return (impl_->capacity());
437}
438
441 const uint8_t* identifier_begin,
442 const size_t identifier_len) const {
444 return (impl_->get(identifier_type, identifier_begin, identifier_len));
445}
446
447int
449 size_t count;
450 try {
451 extractCommand(handle);
452
454 count = impl_->size();
455 } catch (const std::exception& ex) {
457 .arg(ex.what());
458 setErrorResponse(handle, ex.what());
459 return (1);
460 }
461
463 .arg(count);
464 ostringstream msg;
465 msg << count << " entries.";
467 result->set("size", Element::create(static_cast<int64_t>(count)));
468 ConstElementPtr response =
469 createAnswer(CONTROL_RESULT_SUCCESS, msg.str(), result);
470 setResponse(handle, response);
471 return (0);
472}
473
474int
477
478 try {
479 extractCommand(handle);
480
481 impl_->clear();
482 } catch (const std::exception& ex) {
484 .arg(ex.what());
485 setErrorResponse(handle, ex.what());
486 return (1);
487 }
488
490 setSuccessResponse(handle, "Cache cleared.");
491 return (0);
492}
493
494int
497
498 size_t how_many = 0;
499 size_t before = impl_->size();
500 string txt = "(missing parameters)";
501 try {
502 extractCommand(handle);
503 if (cmd_args_) {
504 txt = cmd_args_->str();
505 }
506
507 if (!cmd_args_) {
508 isc_throw(BadValue, "no parameters specified for the command");
509 }
510
511 int64_t val = cmd_args_->intValue();
512
513 if (val == 0) {
514 isc_throw(BadValue, "invalid (0) parameter: "
515 "please use cache-clear command");
516 }
517
518 if (val < 0) {
519 isc_throw(BadValue, "invalid (<0) parameter");
520 }
521
522 if (val > HCConfigParser::MAXIMUM) {
523 val = HCConfigParser::MAXIMUM + 1;
524 }
525
526 how_many = static_cast<size_t>(val);
527 impl_->flush(how_many);
528 } catch (const std::exception& ex) {
530 .arg(txt)
531 .arg(ex.what());
532 setErrorResponse(handle, ex.what());
533 return (1);
534 }
535
537 ostringstream msg;
538 msg << "Cache flushed (" << before - impl_->size() << " entries removed).";
539 setSuccessResponse(handle, msg.str());
540 return (0);
541}
542
543int
546
547 ConstElementPtr dump;
548 size_t count = 0;
549 try {
550 extractCommand(handle);
551
552 dump = impl_->toElement();
553 count = dump->size();
554 } catch (const std::exception& ex) {
556 .arg(ex.what());
557 setErrorResponse(handle, ex.what());
558 return (1);
559 }
560
562 .arg(count);
563 ostringstream msg;
564 msg << count << " entries returned.";
565 ConstElementPtr response =
567 msg.str(), dump);
568 setResponse(handle, response);
569 return (0);
570}
571
572int
574 Host::IdentifierType id_type;
575 vector<uint8_t> ident;
576 string txt = "(missing parameters)";
578 size_t count = 0;
579 try {
580 extractCommand(handle);
581 if (cmd_args_) {
582 txt = cmd_args_->str();
583 }
584
585 if (!cmd_args_) {
586 isc_throw(BadValue, "no parameters specified for the command");
587 }
588
589 if (cmd_args_->getType() != Element::map) {
590 isc_throw(BadValue, "invalid (not a map) parameter");
591 }
592
593 // Take parameters.
594 string ident_txt;
595 unsigned have_ident = 0;
596 auto& map = cmd_args_->mapValue();
597 for (auto const& cfg : map) {
598 if (cfg.first == "hw-address") {
599 id_type = Host::IDENT_HWADDR;
600 ++have_ident;
601 ident_txt = cfg.second->stringValue();
602 } else if (cfg.first == "duid") {
603 id_type= Host::IDENT_DUID;
604 ++have_ident;
605 ident_txt = cfg.second->stringValue();
606 } else if (cfg.first == "circuit-id") {
607 id_type= Host::IDENT_CIRCUIT_ID;
608 ++have_ident;
609 ident_txt = cfg.second->stringValue();
610 } else if (cfg.first == "client-id") {
611 id_type= Host::IDENT_CLIENT_ID;
612 ++have_ident;
613 ident_txt = cfg.second->stringValue();
614 } else if (cfg.first == "flex-id") {
615 id_type= Host::IDENT_FLEX;
616 ++have_ident;
617 ident_txt = cfg.second->stringValue();
618 } else {
620 "unknown parameter '" << cfg.first << "'");
621 }
622 }
623
624 // Decode parameters.
625 if (have_ident == 0) {
626 isc_throw(BadValue, "an identifier is required");
627 }
628 if (have_ident > 1) {
629 isc_throw(BadValue, "only one identifier can be specified");
630 }
631 if (ident_txt.empty()) {
632 isc_throw(BadValue, "invalid (empty) identifier");
633 }
634 try {
635 ident = util::str::quotedStringToBinary(ident_txt);
636 if (ident.empty()) {
637 util::str::decodeFormattedHexString(ident_txt, ident);
638 }
639 } catch (...) {
640 isc_throw(BadValue, "invalid identifier '" << ident_txt << "'");
641 }
642
643 // Get the entry list and build the result.
645 {
647 hosts = impl_->get(id_type, &ident[0], ident.size());
648 }
649 for (auto const& host : hosts) {
650 result->add(host_cache::toElement(host));
651 }
652 count = result->size();
653 } catch (const std::exception& ex) {
655 .arg(ex.what());
656 setErrorResponse(handle, ex.what());
657 return (1);
658 }
659
661 .arg(count);
662 ostringstream msg;
663 msg << count << " entries returned.";
664 ConstElementPtr response =
666 msg.str(), result);
667 setResponse(handle, response);
668 return (0);
669}
670
671int
673 string filename;
674 size_t count = 0;
675 size_t overwritten = 0;
676 string txt = "(missing parameters)";
677 try {
678 extractCommand(handle);
679 if (cmd_args_) {
680 txt = cmd_args_->str();
681 }
682
683 if (!cmd_args_) {
684 isc_throw(BadValue, "no parameters specified for the command");
685 }
686
687 if (cmd_args_->getType() == Element::map) {
688 HCEntryParser parser;
689 HostPtr entry = parser.parse(cmd_args_);
690
691 ++count;
692 try {
694 overwritten += impl_->insert(entry, true);
695 } catch (const std::exception& ex) {
697 "Insert host (" << entry->toText()
698 << ") failed: " << ex.what());
699 }
700 } else {
701 HCEntryListParser parser;
702 HostCollection entries = parser.parse(cmd_args_);
703
704 for (auto const& entry : entries) {
705 ++count;
706 try {
708 overwritten += impl_->insert(entry, true);
709 } catch (const std::exception& ex) {
710 isc_throw(BadValue, "Insert failed at " << count
711 << " host (" << entry->toText()
712 << "): " << ex.what());
713 }
714 }
715 }
716 } catch (const std::exception& ex) {
718 .arg(txt)
719 .arg(ex.what());
720 setErrorResponse(handle, ex.what());
721 return (1);
722 }
723
725 .arg(count)
726 .arg(overwritten);
727 ostringstream msg;
728 msg << count << " entries inserted (" << overwritten
729 << " overwritten by more recent entries).";
730 setSuccessResponse(handle, msg.str());
731 return (0);
732}
733
734int
737
738 ConstElementPtr dump;
739 string filename;
740 size_t count = 0;
741 string txt = "(missing parameters)";
742 try {
743 extractCommand(handle);
744 if (cmd_args_) {
745 txt = cmd_args_->str();
746 }
747
748 if (!cmd_args_) {
749 isc_throw(BadValue, "no parameters specified for the command");
750 }
751
752 if (cmd_args_->getType() != Element::string) {
753 isc_throw(BadValue, "invalid (not a string) parameter");
754 }
755
756 try {
757 filename = CfgMgr::instance().validatePath(cmd_args_->stringValue());
758 } catch (const SecurityWarn& ex) {
760 .arg(ex.what());
761 filename = cmd_args_->stringValue();
762 } catch (const std::exception& ex) {
763 isc_throw(BadValue, "parameter is invalid: " << ex.what());
764 }
765
766 ofstream out(filename, ios::trunc);
767 if (!out.good()) {
768 isc_throw(Unexpected, "Unable to open file '" << filename
769 << "' for writing.");
770 }
771
772 dump = impl_->toElement();
773 count = dump->size();
774 prettyPrint(dump, out);
775 out.close();
776 } catch (const std::exception& ex) {
778 .arg(txt)
779 .arg(ex.what());
780 setErrorResponse(handle, ex.what());
781 return (1);
782 }
783
785 .arg(count);
786 ostringstream msg;
787 msg << count << " entries dumped to '" << filename << "'.";
788 setSuccessResponse(handle, msg.str());
789 return (0);
790}
791
792int
795
796 string filename;
797 size_t count = 0;
798 size_t overwritten = 0;
799 string txt = "(missing parameters)";
800 try {
801 extractCommand(handle);
802 if (cmd_args_) {
803 txt = cmd_args_->str();
804 }
805
806 if (!cmd_args_) {
807 isc_throw(BadValue, "no parameters specified for the command");
808 }
809
810 if (cmd_args_->getType() != Element::string) {
811 isc_throw(BadValue, "invalid (not a string) parameter");
812 }
813
814 filename = cmd_args_->stringValue();
815 if (filename.empty()) {
816 isc_throw(BadValue, "invalid (empty string) parameter");
817 }
818
819 ConstElementPtr json = Element::fromJSONFile(filename);
820 if (!json) {
821 isc_throw(Unexpected, "No entries found.");
822 }
823 HCEntryListParser parser;
824 HostCollection entries = parser.parse(json);
825
826 for (auto const& entry : entries) {
827 ++count;
828 try {
829 overwritten += impl_->insert(entry, true);
830 } catch (const std::exception& ex) {
831 isc_throw(BadValue, "Insert failed at " << count
832 << " host ( " << entry->toText()
833 << "): " << ex.what());
834 }
835 }
836 } catch (const std::exception& ex) {
838 .arg(txt)
839 .arg(ex.what());
840 setErrorResponse(handle, ex.what());
841 return (1);
842 }
843
845 .arg(count)
846 .arg(overwritten);
847 ostringstream msg;
848 msg << count << " entries loaded from '" << filename << "' ("
849 << overwritten << " overwritten by more recent entries).";
850 setSuccessResponse(handle, msg.str());
851 return (0);
852}
853
854int
856 uint16_t family = AF_UNIX;
857 SubnetID subnet_id;
858 string addr_txt;
859 Host::IdentifierType id_type;
860 vector<uint8_t> ident;
861 string txt = "(missing parameters)";
862 string del_txt;
863 try {
864 extractCommand(handle);
865 if (cmd_args_) {
866 txt = cmd_args_->str();
867 }
868
869 if (!cmd_args_) {
870 isc_throw(BadValue, "no parameters specified for the command");
871 }
872
873 if (cmd_args_->getType() != Element::map) {
874 isc_throw(BadValue, "invalid (not a map) parameter");
875 }
876
877 // Take parameters.
878 string ident_txt;
879 bool have_ident = false;
880 bool valid = true;
881 auto& map = cmd_args_->mapValue();
882 for (auto const& cfg : map) {
883 if (cfg.first == "subnet-id") {
884 if (family != AF_UNIX) {
885 valid = false;
886 }
887 family = AF_UNSPEC;
888 subnet_id = static_cast<uint32_t>(cfg.second->intValue());
889 } else if (cfg.first == "subnet-id4") {
890 if (family != AF_UNIX) {
891 valid = false;
892 }
893 family = AF_INET;
894 subnet_id = static_cast<uint32_t>(cfg.second->intValue());
895 } else if (cfg.first == "subnet-id6") {
896 if (family != AF_UNIX) {
897 valid = false;
898 }
899 family = AF_INET6;
900 subnet_id = static_cast<uint32_t>(cfg.second->intValue());
901 } else if (cfg.first == "ip-address") {
902 addr_txt = cfg.second->stringValue();
903 } else if (cfg.first == "hw-address") {
904 id_type = Host::IDENT_HWADDR;
905 if (have_ident) {
906 valid = false;
907 }
908 have_ident = true;
909 ident_txt = cfg.second->stringValue();
910 } else if (cfg.first == "duid") {
911 id_type= Host::IDENT_DUID;
912 if (have_ident) {
913 valid = false;
914 }
915 have_ident = true;
916 ident_txt = cfg.second->stringValue();
917 } else if (cfg.first == "circuit-id") {
918 id_type= Host::IDENT_CIRCUIT_ID;
919 if (have_ident) {
920 valid = false;
921 }
922 have_ident = true;
923 ident_txt = cfg.second->stringValue();
924 } else if (cfg.first == "client-id") {
925 id_type= Host::IDENT_CLIENT_ID;
926 if (have_ident) {
927 valid = false;
928 }
929 have_ident = true;
930 ident_txt = cfg.second->stringValue();
931 } else if (cfg.first == "flex-id") {
932 id_type= Host::IDENT_FLEX;
933 if (have_ident) {
934 valid = false;
935 }
936 have_ident = true;
937 ident_txt = cfg.second->stringValue();
938 } else {
940 "unknown parameter '" << cfg.first << "'");
941 }
942 }
943
944 // Decode parameters.
945 IOAddress addr(0);
946 if (valid && !addr_txt.empty()) {
947 if (have_ident) {
948 valid = false;
949 }
950 if (family == AF_UNIX) {
951 isc_throw(BadValue, "subnet-id is required");
952 }
953 addr = IOAddress(addr_txt);
954 if (addr.isV4()) {
955 if (family == AF_INET6) {
956 valid = false;
957 }
958 if (addr.isV4Zero()) {
959 isc_throw(BadValue, "invalid ip-address '0.0.0.0'");
960 }
961 family = AF_INET;
962 } else if (addr.isV6()) {
963 if (family == AF_INET) {
964 valid = false;
965 }
966 if (addr.isV6Zero()) {
967 isc_throw(BadValue, "invalid ip-address '::'");
968 }
969 family = AF_INET6;
970 } else {
972 "invalid ip-address '" << addr_txt << "'");
973 }
974 } else if (valid) {
975 if (!have_ident) {
977 "either ip-address or an identifier is required");
978 }
979 if (ident_txt.empty()) {
980 isc_throw(BadValue, "invalid (empty) identifier");
981 }
982 if ((family != AF_INET) && (family != AF_INET6)) {
984 "either subnet-id4 or subnet-id6 is required");
985 }
986 try {
987 ident = util::str::quotedStringToBinary(ident_txt);
988 if (ident.empty()) {
989 util::str::decodeFormattedHexString(ident_txt, ident);
990 }
991 } catch (...) {
993 "invalid identifier '" << ident_txt << "'");
994 }
995 }
996
997 // Something is wrong?
998 if (!valid) {
999 isc_throw(BadValue, "inconsistent parameters");
1000 }
1001
1002 // Call del*().
1004 if (!addr_txt.empty()) {
1005 if (family == AF_INET) {
1006 del_txt = impl_->del4(subnet_id, addr);
1007 } else {
1008 del_txt = impl_->del6(subnet_id, addr);
1009 }
1010 } else if (family == AF_INET) {
1011 del_txt = impl_->del4(subnet_id, id_type, &ident[0], ident.size());
1012 } else {
1013 del_txt = impl_->del6(subnet_id, id_type, &ident[0], ident.size());
1014 }
1015 } catch (const std::exception& ex) {
1017 .arg(txt)
1018 .arg(ex.what());
1019 setErrorResponse(handle, ex.what());
1020 return (1);
1021 }
1022
1024 .arg(txt);
1025 if (!del_txt.empty()) {
1026 setSuccessResponse(handle, "Host removed.");
1027 } else {
1028 setErrorResponse(handle, "Host not removed (not found).",
1030 }
1031 return (0);
1032}
1033
1034} // end of namespace isc::host_cache
1035} // end of namespace isc
static ElementPtr create(const Position &pos=ZERO_POSITION())
Definition data.cc:249
static ElementPtr fromJSONFile(const std::string &file_name, bool preproc=false)
Reads contents of specified file and interprets it as JSON.
Definition data.cc:817
@ map
Definition data.h:147
@ string
Definition data.h:144
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
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 DHDP 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.
IdentifierType
Type of the host identifier.
Definition host.h:337
@ IDENT_FLEX
Flexible host identifier.
Definition host.h:342
@ IDENT_CLIENT_ID
Definition host.h:341
@ IDENT_CIRCUIT_ID
Definition host.h:340
std::string getIdentifierAsText() const
Returns host identifier in a textual form.
Definition host.cc:312
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:42
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:52
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:58
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:80
virtual ~HostCache()
Destructor.
Definition host_cache.cc:38
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:47
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:92
virtual dhcp::ConstHostCollection getAll6(const dhcp::SubnetID &subnet_id) const
Return all hosts in a DHCPv6 subnet.
Definition host_cache.cc:70
virtual dhcp::ConstHostCollection getAll4(const dhcp::SubnetID &subnet_id) const
Return all hosts in a DHCPv4 subnet.
Definition host_cache.cc:65
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:86
virtual dhcp::ConstHostCollection getAllbyHostname(const std::string &hostname) const
Return all hosts with a hostname.
Definition host_cache.cc:75
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:21
#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:1549
boost::shared_ptr< const Element > ConstElementPtr
Definition data.h:29
boost::shared_ptr< Element > ElementPtr
Definition data.h:28
boost::shared_ptr< Host > HostPtr
Pointer to the Host object.
Definition host.h:837
std::vector< ConstHostPtr > ConstHostCollection
Collection of the const Host objects.
Definition host.h:843
std::vector< HostPtr > HostCollection
Collection of the Host objects.
Definition host.h:846
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:840
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.