Kea 3.3.1
classify.cc
Go to the documentation of this file.
1// Copyright (C) 2014-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
9#include <cc/data.h>
10#include <dhcp/classify.h>
11#include <util/str.h>
12
13#include <boost/algorithm/string/classification.hpp>
14#include <boost/algorithm/string/constants.hpp>
15#include <boost/algorithm/string/split.hpp>
16
17namespace isc {
18namespace dhcp {
19
20using namespace isc::data;
21
22ClientClasses::ClientClasses(const std::string& class_names)
23 : container_() {
24 std::vector<std::string> split_text;
25 boost::split(split_text, class_names, boost::is_any_of(","),
26 boost::algorithm::token_compress_off);
27 for (size_t i = 0; i < split_text.size(); ++i) {
28 std::string trimmed = util::str::trim(split_text[i]);
29 // Ignore empty class names.
30 if (!trimmed.empty()) {
31 insert(ClientClass(trimmed));
32 }
33 }
34}
35
37 for (auto const& cclass : other) {
38 insert(cclass);
39 }
40}
41
42void
44 auto& idx = container_.get<ClassNameTag>();
45 auto it = idx.find(class_name);
46 if (it != idx.end()) {
47 static_cast<void>(idx.erase(it));
48 }
49}
50
51bool
53 auto const& idx = container_.get<ClassNameTag>();
54 return (idx.count(x) != 0);
55}
56
57bool
59 if (cclasses.size() > size()) {
60 for (const auto& cclass : *this) {
61 if (cclasses.contains(cclass)) {
62 return (true);
63 }
64 }
65 } else {
66 for (const auto& cclass : cclasses) {
67 if (contains(cclass)) {
68 return (true);
69 }
70 }
71 }
72
73 return (false);
74}
75
76std::string
77ClientClasses::toText(const std::string& separator) const {
78 std::stringstream s;
79 bool first = true;
80 for (auto const& class_it : *this) {
81 if (!first) {
82 s << separator;
83 } else {
84 first = false;
85 }
86 s << class_it;
87 }
88 return (s.str());
89}
90
94 for (auto const& c : container_) {
95 result->add(Element::create(c));
96 }
97 return (result);
98}
99
100void
102 if (cc_list) {
103 clear();
104 if (cc_list->getType() != Element::list) {
105 isc_throw(BadValue, "not a List element");
106 }
107
108 for (unsigned i = 0; i < cc_list->size(); ++i) {
109 auto cclass = cc_list->get(i);
110 if (cclass->getType() != Element::string) {
111 isc_throw(BadValue, "elements of list must be valid strings");
112 }
113
114 static_cast<void>(insert(cclass->stringValue()));
115 }
116 }
117}
118
119bool
121 return ((size() == other.size()) && std::equal(cbegin(), cend(), other.cbegin()));
122}
123
126 clear();
127 for (auto const& cclass : other) {
128 insert(cclass);
129 }
130
131 return (*this);
132}
133
134size_t
136 return (hash_value(client_classes));
137}
138
139size_t hash_value(const ClientClasses& client_classes) {
140 boost::hash<std::string> hasher;
141 return (hasher(client_classes.toText("+")));
142}
143
144const std::vector<bool> ClientClasses::CLIENT_CLASS_VALID_CHARACTERS = {
145 false, false, false, false, false, false, false, false,
146 false, false, false, false, false, false, false, false,
147 false, false, false, false, false, false, false, false,
148 false, false, false, false, false, false, false, false,
149 false, true, false, true, true, true, true, false,
150 false, false, true, true, false, true, true, true,
151 true, true, true, true, true, true, true, true,
152 true, true, true, false, false, false, false, true,
153 true, true, true, true, true, true, true, true,
154 true, true, true, true, true, true, true, true,
155 true, true, true, true, true, true, true, true,
156 true, true, true, false, false, false, true, true,
157 false, true, true, true, true, true, true, true,
158 true, true, true, true, true, true, true, true,
159 true, true, true, true, true, true, true, true,
160 true, true, true, false, true, false, true, false,
161};
162
163std::string
164ClientClasses::escape(const std::string& name, bool escape_escape /*= true*/) {
165 std::string output;
166 for (char const& c : name) {
167 uint8_t u = static_cast<uint8_t>(c);
168 if ((u < 128) && CLIENT_CLASS_VALID_CHARACTERS[u]) {
169 output.push_back(c);
170 if ((c == CLIENT_CLASS_ESCAPE) && escape_escape) {
171 output.push_back(CLIENT_CLASS_ESCAPE);
172 }
173 } else {
174 output.push_back(CLIENT_CLASS_ESCAPE);
175 output.append(util::str::byteToHex(u));
176 }
177 }
178 return (output);
179}
180
181} // end of namespace dhcp
182} // end of namespace isc
Defines elements for storing the names of client classes.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
static ElementPtr create(const Position &pos=ZERO_POSITION())
Create a NullElement.
Definition data.cc:300
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
Definition data.cc:350
Container for storing client class names.
Definition classify.h:111
bool equals(const ClientClasses &other) const
Compares two ClientClasses container for equality.
Definition classify.cc:120
void clear()
Clears containers.
Definition classify.h:228
static const std::vector< bool > CLIENT_CLASS_VALID_CHARACTERS
Valid character in a client class name boolean vector.
Definition classify.h:265
bool contains(const ClientClass &x) const
returns if class x belongs to the defined classes
Definition classify.cc:52
void insert(const ClientClass &class_name)
Insert an element.
Definition classify.h:161
static std::string escape(const std::string &name, bool escape_escape=true)
Escape a client class name.
Definition classify.cc:164
void erase(const ClientClass &class_name)
Erase element by name.
Definition classify.cc:43
ClientClasses & operator=(const ClientClasses &other)
Assigns the contents of on container to another.
Definition classify.cc:125
static constexpr char CLIENT_CLASS_ESCAPE
Escape character.
Definition classify.h:268
virtual isc::data::ElementPtr toElement() const
Returns all class names as an ElementPtr of type ListElement.
Definition classify.cc:92
void fromElement(isc::data::ConstElementPtr list)
Sets contents from a ListElement.
Definition classify.cc:101
bool intersects(const ClientClasses &cclasses) const
returns whether this container has at least one class in common with a given container.
Definition classify.cc:58
ClientClasses()
Default constructor.
Definition classify.h:119
std::string toText(const std::string &separator=", ") const
Returns all class names as text.
Definition classify.cc:77
const_iterator cbegin() const
Iterators to the first element.
Definition classify.h:185
const_iterator cend() const
Iterators to the past the end element.
Definition classify.h:200
size_t size() const
Returns the number of classes.
Definition classify.h:179
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::shared_ptr< const Element > ConstElementPtr
Definition data.h:30
boost::shared_ptr< Element > ElementPtr
Definition data.h:29
std::string ClientClass
Defines a single class name.
Definition classify.h:45
const std::string & byteToHex(uint8_t byte)
Converts a byte to a two hex digit string.
Definition str.cc:403
string trim(const string &input)
Trim leading and trailing spaces.
Definition str.cc:32
Defines the logger used by the top-level component of kea-lfc.
Tag for the name index.
Definition classify.h:51
size_t operator()(const ClientClasses &client_classes)
A hashing operator.
Definition classify.cc:135