Kea 3.0.0
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>
17#include <util/str.h>
18#include <string>
19#include <sstream>
20#include <fstream>
21
22using namespace std;
23using namespace isc::asiolink;
24using namespace isc::config;
25using namespace isc::data;
26using namespace isc::db;
27using namespace isc::dhcp;
28using namespace isc::util;
29
30namespace isc {
31namespace host_cache {
32
33HostCache::HostCache() : impl_(new HostCacheImpl()), mutex_(new std::mutex) {
34}
35
37 impl_.reset();
38}
39
41 HCConfigParser parser;
42 parser.parse(*this, config);
43}
44
45void HostCache::setMaximum(size_t maximum) {
47 impl_->setMaximum(maximum);
48}
49
50size_t HostCache::getMaximum() const {
52 return (impl_->getMaximum());
53}
54
56HostCache::getAll(const Host::IdentifierType& /*identifier_type*/,
57 const uint8_t* /*identifier_begin*/,
58 const size_t /*identifier_len*/) const {
59 return (ConstHostCollection());
60}
61
63HostCache::getAll4(const dhcp::SubnetID& /*subnet_id*/) const {
64 return (ConstHostCollection());
65}
66
68HostCache::getAll6(const dhcp::SubnetID& /*subnet_id*/) const {
69 return (ConstHostCollection());
70}
71
73HostCache::getAllbyHostname(const std::string& /*hostname*/) const {
74 return (ConstHostCollection());
75}
76
78HostCache::getAllbyHostname4(const std::string& /*hostname*/,
79 const dhcp::SubnetID& /*subnet_id*/) const {
80 return (ConstHostCollection());
81}
82
84HostCache::getAllbyHostname6(const std::string& /*hostname*/,
85 const dhcp::SubnetID& /*subnet_id*/) const {
86 return (ConstHostCollection());
87}
88
91 size_t& /*source_index*/,
92 uint64_t /*lower_host_id*/,
93 const dhcp::HostPageSize& /*page_size*/) const {
94 return (ConstHostCollection());
95}
96
99 size_t& /*source_index*/,
100 uint64_t /*lower_host_id*/,
101 const dhcp::HostPageSize& /*page_size*/) const {
102 return (ConstHostCollection());
103}
104
106HostCache::getPage4(size_t& /*source_index*/,
107 uint64_t /*lower_host_id*/,
108 const dhcp:: HostPageSize& /*page_size*/) const {
109 return (ConstHostCollection());
110}
111
113HostCache::getPage6(size_t& /*source_index*/,
114 uint64_t /*lower_host_id*/,
115 const dhcp::HostPageSize& /*page_size*/) const {
116 return (ConstHostCollection());
117}
118
120HostCache::getAll4(const asiolink::IOAddress& /*address*/) const {
121 return (ConstHostCollection());
122}
123
126 const dhcp::Host::IdentifierType& identifier_type,
127 const uint8_t* identifier_begin,
128 const size_t identifier_len) const {
131 .arg("IPv4")
132 .arg(subnet_id)
133 .arg(Host::getIdentifierAsText(identifier_type, identifier_begin,
134 identifier_len));
135
136 ConstHostPtr host;
137 {
139 host = impl_->get4(subnet_id, identifier_type,
140 identifier_begin, identifier_len);
141 }
142 if (host) {
145 .arg(subnet_id)
146 .arg(Host::getIdentifierAsText(identifier_type, identifier_begin,
147 identifier_len))
148 .arg(host->toText());
149 }
150 return (host);
151}
152
155 const asiolink::IOAddress& address) const {
158 .arg(subnet_id)
159 .arg(address.toText());
160
161 // Must not specify address other than IPv4.
162 if (!address.isV4()) {
163 return (ConstHostPtr());
164 }
165 ConstHostPtr host;
166 {
168 host = impl_->get4(subnet_id, address);
169 }
170 if (host) {
173 .arg(subnet_id)
174 .arg(address.toText())
175 .arg(host->toText());
176 }
177 return (host);
178}
179
182 const asiolink::IOAddress& /*address*/) const {
183 return (ConstHostCollection());
184}
185
188 const dhcp::Host::IdentifierType& identifier_type,
189 const uint8_t* identifier_begin,
190 const size_t identifier_len) const {
193 .arg("IPv6")
194 .arg(subnet_id)
195 .arg(Host::getIdentifierAsText(identifier_type, identifier_begin,
196 identifier_len));
197
198 ConstHostPtr host;
199 {
201 host = impl_->get6(subnet_id, identifier_type,
202 identifier_begin, identifier_len);
203 }
204 if (host) {
207 .arg(subnet_id)
208 .arg(Host::getIdentifierAsText(identifier_type, identifier_begin,
209 identifier_len))
210 .arg(host->toText());
211 }
212 return (host);
213}
214
217 const uint8_t prefix_len) const {
220 .arg(prefix.toText())
221 .arg(static_cast<int>(prefix_len));
222
223 ConstHostPtr host;
224 {
226 host = impl_->get6(prefix, prefix_len);
227 }
228 if (host) {
231 .arg(prefix.toText())
232 .arg(static_cast<int>(prefix_len))
233 .arg(host->toText());
234 }
235 return (host);
236}
237
240 const asiolink::IOAddress& address) const {
243 .arg(subnet_id)
244 .arg(address.toText());
245
246 // Must not specify address other than IPv6.
247 if (!address.isV6()) {
248 return (ConstHostPtr());
249 }
250
251 ConstHostPtr host;
252 {
254 host = impl_->get6(subnet_id, address);
255 }
256 if (host) {
259 .arg(subnet_id)
260 .arg(address.toText())
261 .arg(host->toText());
262 }
263 return (host);
264}
265
268 const asiolink::IOAddress& /*address*/) const {
269 return (ConstHostCollection());
270}
271
273HostCache::getAll6(const IOAddress& /*address*/) const {
274 return (ConstHostCollection());
275}
276
277void
279 if (!host) {
280 return;
281 }
282
283 // At least one subnet ID must be used.
284 if (host->getIPv4SubnetID() == SUBNET_ID_UNUSED &&
285 host->getIPv6SubnetID() == SUBNET_ID_UNUSED) {
286 return;
287 }
288
289 bool ret;
290 {
292 ret = impl_->add(host);
293 }
294 if (ret) {
296 .arg(host->toText());
297 } else {
300 .arg(host->toText());
301 isc_throw(DuplicateEntry, "Host cache duplicate entry error");
302 }
303}
304
305bool
306HostCache::del(const SubnetID& subnet_id, const IOAddress& addr) {
307 string txt;
308 if (addr.isV4()) {
309 {
311 txt = impl_->del4(subnet_id, addr);
312 }
313 if (!txt.empty()) {
316 .arg(subnet_id)
317 .arg(addr.toText())
318 .arg(txt);
319 }
320 } else if (addr.isV6()) {
321 {
323 txt = impl_->del6(subnet_id, addr);
324 }
325 if (!txt.empty()) {
328 .arg(subnet_id)
329 .arg(addr.toText())
330 .arg(txt);
331 }
332 }
333 return (false);
334}
335
336bool
337HostCache::del4(const SubnetID& subnet_id,
338 const Host::IdentifierType& identifier_type,
339 const uint8_t* identifier_begin,
340 const size_t identifier_len) {
341 string txt;
342 {
344 txt = impl_->del4(subnet_id, identifier_type,
345 identifier_begin, identifier_len);
346 }
347 if (!txt.empty()) {
350 .arg(subnet_id)
351 .arg(Host::getIdentifierAsText(identifier_type,
352 identifier_begin,
353 identifier_len))
354 .arg(txt);
355 }
356 return (false);
357}
358
359bool
360HostCache::del6(const SubnetID& subnet_id,
361 const Host::IdentifierType& identifier_type,
362 const uint8_t* identifier_begin,
363 const size_t identifier_len) {
364 string txt;
365 {
367 txt = impl_->del6(subnet_id, identifier_type,
368 identifier_begin, identifier_len);
369 }
370 if (!txt.empty()) {
373 .arg(subnet_id)
374 .arg(Host::getIdentifierAsText(identifier_type,
375 identifier_begin,
376 identifier_len))
377 .arg(txt);
378 }
379 return (false);
380}
381
382void
385 impl_->update(host);
386}
387
388bool
390 // This backend does not support the mode in which multiple reservations
391 // for the same IP address are created. If selecting this mode is
392 // attempted this function returns false to indicate that this is
393 // not allowed.
394 return (unique);
395}
396
400 return (impl_->toElement());
401}
402
403size_t
404HostCache::insert(const ConstHostPtr& host, bool overwrite) {
406 return (impl_->insert(host, overwrite));
407}
408
409bool
412 return (impl_->remove(host));
413}
414
415void
416HostCache::flush(size_t count) {
418 if (count == 0) {
419 impl_->clear();
420 } else {
421 impl_->flush(count);
422 }
423}
424
425size_t
428 return (impl_->size());
429}
430
431size_t
434 return (impl_->capacity());
435}
436
439 const uint8_t* identifier_begin,
440 const size_t identifier_len) const {
442 return (impl_->get(identifier_type, identifier_begin, identifier_len));
443}
444
445int
447 size_t count;
448 try {
449 extractCommand(handle);
450
452 count = impl_->size();
453 } catch (const std::exception& ex) {
455 .arg(ex.what());
456 setErrorResponse(handle, ex.what());
457 return (1);
458 }
459
461 .arg(count);
462 ostringstream msg;
463 msg << count << " entries.";
465 result->set("size", Element::create(static_cast<int64_t>(count)));
466 ConstElementPtr response =
467 createAnswer(CONTROL_RESULT_SUCCESS, msg.str(), result);
468 setResponse(handle, response);
469 return (0);
470}
471
472int
475
476 try {
477 extractCommand(handle);
478
479 impl_->clear();
480 } catch (const std::exception& ex) {
482 .arg(ex.what());
483 setErrorResponse(handle, ex.what());
484 return (1);
485 }
486
488 setSuccessResponse(handle, "Cache cleared.");
489 return (0);
490}
491
492int
495
496 size_t how_many = 0;
497 size_t before = impl_->size();
498 string txt = "(missing parameters)";
499 try {
500 extractCommand(handle);
501 if (cmd_args_) {
502 txt = cmd_args_->str();
503 }
504
505 if (!cmd_args_) {
506 isc_throw(BadValue, "no parameters specified for the command");
507 }
508
509 int64_t val = cmd_args_->intValue();
510
511 if (val == 0) {
512 isc_throw(BadValue, "invalid (0) parameter: "
513 "please use cache-clear command");
514 }
515
516 if (val < 0) {
517 isc_throw(BadValue, "invalid (<0) parameter");
518 }
519
520 if (val > HCConfigParser::MAXIMUM) {
521 val = HCConfigParser::MAXIMUM + 1;
522 }
523
524 how_many = static_cast<size_t>(val);
525 impl_->flush(how_many);
526 } catch (const std::exception& ex) {
528 .arg(txt)
529 .arg(ex.what());
530 setErrorResponse(handle, ex.what());
531 return (1);
532 }
533
535 ostringstream msg;
536 msg << "Cache flushed (" << before - impl_->size() << " entries removed).";
537 setSuccessResponse(handle, msg.str());
538 return (0);
539}
540
541int
544
545 ConstElementPtr dump;
546 size_t count = 0;
547 try {
548 extractCommand(handle);
549
550 dump = impl_->toElement();
551 count = dump->size();
552 } catch (const std::exception& ex) {
554 .arg(ex.what());
555 setErrorResponse(handle, ex.what());
556 return (1);
557 }
558
560 .arg(count);
561 ostringstream msg;
562 msg << count << " entries returned.";
563 ConstElementPtr response =
565 msg.str(), dump);
566 setResponse(handle, response);
567 return (0);
568}
569
570int
572 Host::IdentifierType id_type;
573 vector<uint8_t> ident;
574 string txt = "(missing parameters)";
576 size_t count = 0;
577 try {
578 extractCommand(handle);
579 if (cmd_args_) {
580 txt = cmd_args_->str();
581 }
582
583 if (!cmd_args_) {
584 isc_throw(BadValue, "no parameters specified for the command");
585 }
586
587 if (cmd_args_->getType() != Element::map) {
588 isc_throw(BadValue, "invalid (not a map) parameter");
589 }
590
591 // Take parameters.
592 string ident_txt;
593 unsigned have_ident = 0;
594 auto& map = cmd_args_->mapValue();
595 for (auto const& cfg : map) {
596 if (cfg.first == "hw-address") {
597 id_type = Host::IDENT_HWADDR;
598 ++have_ident;
599 ident_txt = cfg.second->stringValue();
600 } else if (cfg.first == "duid") {
601 id_type= Host::IDENT_DUID;
602 ++have_ident;
603 ident_txt = cfg.second->stringValue();
604 } else if (cfg.first == "circuit-id") {
605 id_type= Host::IDENT_CIRCUIT_ID;
606 ++have_ident;
607 ident_txt = cfg.second->stringValue();
608 } else if (cfg.first == "client-id") {
609 id_type= Host::IDENT_CLIENT_ID;
610 ++have_ident;
611 ident_txt = cfg.second->stringValue();
612 } else if (cfg.first == "flex-id") {
613 id_type= Host::IDENT_FLEX;
614 ++have_ident;
615 ident_txt = cfg.second->stringValue();
616 } else {
618 "unknown parameter '" << cfg.first << "'");
619 }
620 }
621
622 // Decode parameters.
623 if (have_ident == 0) {
624 isc_throw(BadValue, "an identifier is required");
625 }
626 if (have_ident > 1) {
627 isc_throw(BadValue, "only one identifier can be specified");
628 }
629 if (ident_txt.empty()) {
630 isc_throw(BadValue, "invalid (empty) identifier");
631 }
632 try {
633 ident = util::str::quotedStringToBinary(ident_txt);
634 if (ident.empty()) {
635 util::str::decodeFormattedHexString(ident_txt, ident);
636 }
637 } catch (...) {
638 isc_throw(BadValue, "invalid identifier '" << ident_txt << "'");
639 }
640
641 // Get the entry list and build the result.
643 {
645 hosts = impl_->get(id_type, &ident[0], ident.size());
646 }
647 for (auto const& host : hosts) {
648 result->add(host_cache::toElement(host));
649 }
650 count = result->size();
651 } catch (const std::exception& ex) {
653 .arg(ex.what());
654 setErrorResponse(handle, ex.what());
655 return (1);
656 }
657
659 .arg(count);
660 ostringstream msg;
661 msg << count << " entries returned.";
662 ConstElementPtr response =
664 msg.str(), result);
665 setResponse(handle, response);
666 return (0);
667}
668
669int
671 string filename;
672 size_t count = 0;
673 size_t overwritten = 0;
674 string txt = "(missing parameters)";
675 try {
676 extractCommand(handle);
677 if (cmd_args_) {
678 txt = cmd_args_->str();
679 }
680
681 if (!cmd_args_) {
682 isc_throw(BadValue, "no parameters specified for the command");
683 }
684
685 if (cmd_args_->getType() == Element::map) {
686 HCEntryParser parser;
687 HostPtr entry = parser.parse(cmd_args_);
688
689 ++count;
690 try {
692 overwritten += impl_->insert(entry, true);
693 } catch (const std::exception& ex) {
695 "Insert host (" << entry->toText()
696 << ") failed: " << ex.what());
697 }
698 } else {
699 HCEntryListParser parser;
700 HostCollection entries = parser.parse(cmd_args_);
701
702 for (auto const& entry : entries) {
703 ++count;
704 try {
706 overwritten += impl_->insert(entry, true);
707 } catch (const std::exception& ex) {
708 isc_throw(BadValue, "Insert failed at " << count
709 << " host (" << entry->toText()
710 << "): " << ex.what());
711 }
712 }
713 }
714 } catch (const std::exception& ex) {
716 .arg(txt)
717 .arg(ex.what());
718 setErrorResponse(handle, ex.what());
719 return (1);
720 }
721
723 .arg(count)
724 .arg(overwritten);
725 ostringstream msg;
726 msg << count << " entries inserted (" << overwritten
727 << " overwritten by more recent entries).";
728 setSuccessResponse(handle, msg.str());
729 return (0);
730}
731
732int
735
736 ConstElementPtr dump;
737 string filename;
738 size_t count = 0;
739 string txt = "(missing parameters)";
740 try {
741 extractCommand(handle);
742 if (cmd_args_) {
743 txt = cmd_args_->str();
744 }
745
746 if (!cmd_args_) {
747 isc_throw(BadValue, "no parameters specified for the command");
748 }
749
750 if (cmd_args_->getType() != Element::string) {
751 isc_throw(BadValue, "invalid (not a string) parameter");
752 }
753
754 try {
755 filename = CfgMgr::instance().validatePath(cmd_args_->stringValue());
756 } catch (const std::exception& ex) {
757 isc_throw(BadValue, "parameter is invalid: " << ex.what());
758 }
759
760 ofstream out(filename, ios::trunc);
761 if (!out.good()) {
762 isc_throw(Unexpected, "Unable to open file '" << filename
763 << "' for writing.");
764 }
765
766 dump = impl_->toElement();
767 count = dump->size();
768 prettyPrint(dump, out);
769 out.close();
770 } catch (const std::exception& ex) {
772 .arg(txt)
773 .arg(ex.what());
774 setErrorResponse(handle, ex.what());
775 return (1);
776 }
777
779 .arg(count);
780 ostringstream msg;
781 msg << count << " entries dumped to '" << filename << "'.";
782 setSuccessResponse(handle, msg.str());
783 return (0);
784}
785
786int
789
790 string filename;
791 size_t count = 0;
792 size_t overwritten = 0;
793 string txt = "(missing parameters)";
794 try {
795 extractCommand(handle);
796 if (cmd_args_) {
797 txt = cmd_args_->str();
798 }
799
800 if (!cmd_args_) {
801 isc_throw(BadValue, "no parameters specified for the command");
802 }
803
804 if (cmd_args_->getType() != Element::string) {
805 isc_throw(BadValue, "invalid (not a string) parameter");
806 }
807
808 filename = cmd_args_->stringValue();
809 if (filename.empty()) {
810 isc_throw(BadValue, "invalid (empty string) parameter");
811 }
812
813 ConstElementPtr json = Element::fromJSONFile(filename);
814 if (!json) {
815 isc_throw(Unexpected, "No entries found.");
816 }
817 HCEntryListParser parser;
818 HostCollection entries = parser.parse(json);
819
820 for (auto const& entry : entries) {
821 ++count;
822 try {
823 overwritten += impl_->insert(entry, true);
824 } catch (const std::exception& ex) {
825 isc_throw(BadValue, "Insert failed at " << count
826 << " host ( " << entry->toText()
827 << "): " << ex.what());
828 }
829 }
830 } catch (const std::exception& ex) {
832 .arg(txt)
833 .arg(ex.what());
834 setErrorResponse(handle, ex.what());
835 return (1);
836 }
837
839 .arg(count)
840 .arg(overwritten);
841 ostringstream msg;
842 msg << count << " entries loaded from '" << filename << "' ("
843 << overwritten << " overwritten by more recent entries).";
844 setSuccessResponse(handle, msg.str());
845 return (0);
846}
847
848int
850 uint16_t family = AF_UNIX;
851 SubnetID subnet_id;
852 string addr_txt;
853 Host::IdentifierType id_type;
854 vector<uint8_t> ident;
855 string txt = "(missing parameters)";
856 string del_txt;
857 try {
858 extractCommand(handle);
859 if (cmd_args_) {
860 txt = cmd_args_->str();
861 }
862
863 if (!cmd_args_) {
864 isc_throw(BadValue, "no parameters specified for the command");
865 }
866
867 if (cmd_args_->getType() != Element::map) {
868 isc_throw(BadValue, "invalid (not a map) parameter");
869 }
870
871 // Take parameters.
872 string ident_txt;
873 bool have_ident = false;
874 bool valid = true;
875 auto& map = cmd_args_->mapValue();
876 for (auto const& cfg : map) {
877 if (cfg.first == "subnet-id") {
878 if (family != AF_UNIX) {
879 valid = false;
880 }
881 family = AF_UNSPEC;
882 subnet_id = static_cast<uint32_t>(cfg.second->intValue());
883 } else if (cfg.first == "subnet-id4") {
884 if (family != AF_UNIX) {
885 valid = false;
886 }
887 family = AF_INET;
888 subnet_id = static_cast<uint32_t>(cfg.second->intValue());
889 } else if (cfg.first == "subnet-id6") {
890 if (family != AF_UNIX) {
891 valid = false;
892 }
893 family = AF_INET6;
894 subnet_id = static_cast<uint32_t>(cfg.second->intValue());
895 } else if (cfg.first == "ip-address") {
896 addr_txt = cfg.second->stringValue();
897 } else if (cfg.first == "hw-address") {
898 id_type = Host::IDENT_HWADDR;
899 if (have_ident) {
900 valid = false;
901 }
902 have_ident = true;
903 ident_txt = cfg.second->stringValue();
904 } else if (cfg.first == "duid") {
905 id_type= Host::IDENT_DUID;
906 if (have_ident) {
907 valid = false;
908 }
909 have_ident = true;
910 ident_txt = cfg.second->stringValue();
911 } else if (cfg.first == "circuit-id") {
912 id_type= Host::IDENT_CIRCUIT_ID;
913 if (have_ident) {
914 valid = false;
915 }
916 have_ident = true;
917 ident_txt = cfg.second->stringValue();
918 } else if (cfg.first == "client-id") {
919 id_type= Host::IDENT_CLIENT_ID;
920 if (have_ident) {
921 valid = false;
922 }
923 have_ident = true;
924 ident_txt = cfg.second->stringValue();
925 } else if (cfg.first == "flex-id") {
926 id_type= Host::IDENT_FLEX;
927 if (have_ident) {
928 valid = false;
929 }
930 have_ident = true;
931 ident_txt = cfg.second->stringValue();
932 } else {
934 "unknown parameter '" << cfg.first << "'");
935 }
936 }
937
938 // Decode parameters.
939 IOAddress addr(0);
940 if (valid && !addr_txt.empty()) {
941 if (have_ident) {
942 valid = false;
943 }
944 if (family == AF_UNIX) {
945 isc_throw(BadValue, "subnet-id is required");
946 }
947 addr = IOAddress(addr_txt);
948 if (addr.isV4()) {
949 if (family == AF_INET6) {
950 valid = false;
951 }
952 if (addr.isV4Zero()) {
953 isc_throw(BadValue, "invalid ip-address '0.0.0.0'");
954 }
955 family = AF_INET;
956 } else if (addr.isV6()) {
957 if (family == AF_INET) {
958 valid = false;
959 }
960 if (addr.isV6Zero()) {
961 isc_throw(BadValue, "invalid ip-address '::'");
962 }
963 family = AF_INET6;
964 } else {
966 "invalid ip-address '" << addr_txt << "'");
967 }
968 } else if (valid) {
969 if (!have_ident) {
971 "either ip-address or an identifier is required");
972 }
973 if (ident_txt.empty()) {
974 isc_throw(BadValue, "invalid (empty) identifier");
975 }
976 if ((family != AF_INET) && (family != AF_INET6)) {
978 "either subnet-id4 or subnet-id6 is required");
979 }
980 try {
981 ident = util::str::quotedStringToBinary(ident_txt);
982 if (ident.empty()) {
983 util::str::decodeFormattedHexString(ident_txt, ident);
984 }
985 } catch (...) {
987 "invalid identifier '" << ident_txt << "'");
988 }
989 }
990
991 // Something is wrong?
992 if (!valid) {
993 isc_throw(BadValue, "inconsistent parameters");
994 }
995
996 // Call del*().
998 if (!addr_txt.empty()) {
999 if (family == AF_INET) {
1000 del_txt = impl_->del4(subnet_id, addr);
1001 } else {
1002 del_txt = impl_->del6(subnet_id, addr);
1003 }
1004 } else if (family == AF_INET) {
1005 del_txt = impl_->del4(subnet_id, id_type, &ident[0], ident.size());
1006 } else {
1007 del_txt = impl_->del6(subnet_id, id_type, &ident[0], ident.size());
1008 }
1009 } catch (const std::exception& ex) {
1011 .arg(txt)
1012 .arg(ex.what());
1013 setErrorResponse(handle, ex.what());
1014 return (1);
1015 }
1016
1018 .arg(txt);
1019 if (!del_txt.empty()) {
1020 setSuccessResponse(handle, "Host removed.");
1021 } else {
1022 setErrorResponse(handle, "Host not removed (not found).",
1024 }
1025 return (0);
1026}
1027
1028} // end of namespace isc::host_cache
1029} // 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...
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:40
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:50
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:56
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:78
virtual ~HostCache()
Destructor.
Definition host_cache.cc:36
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:45
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:90
virtual dhcp::ConstHostCollection getAll6(const dhcp::SubnetID &subnet_id) const
Return all hosts in a DHCPv6 subnet.
Definition host_cache.cc:68
virtual dhcp::ConstHostCollection getAll4(const dhcp::SubnetID &subnet_id) const
Return all hosts in a DHCPv4 subnet.
Definition host_cache.cc:63
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:84
virtual dhcp::ConstHostCollection getAllbyHostname(const std::string &hostname) const
Return all hosts with a hostname.
Definition host_cache.cc:73
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.
Definition host_cache.cc:98
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.
#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_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:1547
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_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.