16 #include <boost/foreach.hpp>
27 ClientClassDef::ClientClassDef(
const std::string& name,
31 match_expr_(match_expr), required_(false), depend_on_known_(false),
33 valid_(), preferred_() {
50 match_expr_(
ExpressionPtr()), test_(rhs.test_), required_(rhs.required_),
51 depend_on_known_(rhs.depend_on_known_), cfg_option_(new
CfgOption()),
52 next_server_(rhs.next_server_), sname_(rhs.sname_),
53 filename_(rhs.filename_), valid_(rhs.valid_), preferred_(rhs.preferred_),
54 offer_lft_(rhs.offer_lft_) {
56 if (rhs.match_expr_) {
58 *match_expr_ = *(rhs.match_expr_);
61 if (rhs.cfg_option_def_) {
63 rhs.cfg_option_def_->copyTo(*cfg_option_def_);
66 if (rhs.cfg_option_) {
67 rhs.cfg_option_->copyTo(*cfg_option_);
91 match_expr_ = match_expr;
111 required_ = required;
116 return (depend_on_known_);
121 depend_on_known_ = depend_on_known;
126 return (cfg_option_def_);
131 cfg_option_def_ = cfg_option_def;
136 return (cfg_option_);
141 cfg_option_ = cfg_option;
168 .arg(
"get exception?");
186 if (!subclass.empty()) {
195 pkt->addSubClass(
getName(), value);
204 .arg(
"get exception?");
215 return ((name_ == other.name_) &&
216 ((!match_expr_ && !other.match_expr_) ||
217 (match_expr_ && other.match_expr_ &&
218 (*match_expr_ == *(other.match_expr_)))) &&
219 ((!cfg_option_ && !other.cfg_option_) ||
220 (cfg_option_ && other.cfg_option_ &&
221 (*cfg_option_ == *other.cfg_option_))) &&
222 ((!cfg_option_def_ && !other.cfg_option_def_) ||
223 (cfg_option_def_ && other.cfg_option_def_ &&
224 (*cfg_option_def_ == *other.cfg_option_def_))) &&
225 (required_ == other.required_) &&
226 (depend_on_known_ == other.depend_on_known_) &&
227 (next_server_ == other.next_server_) &&
228 (sname_ == other.sname_) &&
229 (filename_ == other.filename_));
241 if (!test_.empty()) {
249 if (cfg_option_def_ && (family == AF_INET)) {
250 result->set(
"option-def", cfg_option_def_->toElement());
253 result->set(
"option-data", cfg_option_->toElement());
255 if (family == AF_INET) {
266 result->set(
"offer-lifetime",
273 result->set(
"preferred-lifetime",
277 if (preferred_.
getMin() < preferred_.
get()) {
278 result->set(
"min-preferred-lifetime",
282 if (preferred_.
getMax() > preferred_.
get()) {
283 result->set(
"max-preferred-lifetime",
290 result->set(
"valid-lifetime",
294 result->set(
"min-valid-lifetime",
299 result->set(
"max-valid-lifetime",
310 auto const&
test = result->get(
"test");
312 result->set(
"template-test",
test);
313 result->remove(
"test");
321 os <<
"ClientClassDef:" << x.
getName();
345 const std::string& test,
347 bool depend_on_known,
352 const std::string& sname,
353 const std::string& filename,
364 cclass->setTest(test);
365 cclass->setRequired(required);
366 cclass->setDependOnKnown(depend_on_known);
367 cclass->setCfgOptionDef(cfg_option_def);
368 cclass->setContext(user_context),
369 cclass->setNextServer(next_server);
370 cclass->setSname(sname);
371 cclass->setFilename(filename);
372 cclass->setValid(valid);
373 cclass->setPreferred(preferred);
374 cclass->setOfferLft(offer_lft);
382 " - class definition cannot be null");
387 << class_def->getName() <<
" has already been defined");
390 list_->push_back(class_def);
391 (*map_)[class_def->getName()] = class_def;
396 ClientClassDefMap::iterator it = map_->find(name);
397 if (it != map_->end()) {
406 for (ClientClassDefList::iterator this_class = list_->begin();
407 this_class != list_->end(); ++this_class) {
408 if ((*this_class)->getName() == name) {
409 list_->erase(this_class);
422 for (ClientClassDefList::iterator this_class = list_->begin();
423 this_class != list_->end(); ++this_class) {
424 if ((*this_class)->getId() ==
id) {
425 map_->erase((*this_class)->getName());
426 list_->erase(this_class);
439 return (list_->empty());
444 std::string& dependent_class)
const {
447 for (ClientClassDefList::iterator this_class = list_->begin();
448 this_class != list_->end(); ++this_class) {
450 if ((*this_class)->dependOnClass(name)) {
451 dependent_class = (*this_class)->getName();
455 if ((*this_class)->getName() == name) {
465 if (list_->size() != other.list_->size()) {
469 ClientClassDefList::const_iterator this_class = list_->cbegin();
470 ClientClassDefList::const_iterator other_class = other.list_->cbegin();
471 while (this_class != list_->cend() &&
472 other_class != other.list_->cend()) {
473 if (!*this_class || !*other_class ||
474 **this_class != **other_class) {
487 std::queue<ExpressionPtr> expressions;
488 for (
auto c : *list_) {
489 if (!c->getTest().empty()) {
494 parser_type = EvalContext::PARSER_STRING;
497 EvalContext::acceptAll, parser_type);
498 expressions.push(match_expr);
503 for (
auto c : *list_) {
504 if (!c->getTest().empty()) {
505 c->setMatchExpr(expressions.front());
513 for (
auto c : *list_) {
516 if (!class_options || class_options->empty()) {
523 if (!c->getCfgOptionDef()) {
524 class_options->createOptions(external_defs);
534 c->getCfgOptionDef()->copyTo(*composite_defs);
541 external_defs->copyTo(*external_defs_copy);
542 composite_defs->merge(*external_defs_copy);
546 class_options->createOptions(composite_defs);
555 for (ClientClassDefList::const_iterator this_class = list_->begin();
556 this_class != list_->cend(); ++this_class) {
557 result->add((*this_class)->toElement());
567 for (
auto cclass : *(rhs.list_)) {
576 std::list<std::string>
584 "ALL",
"KNOWN",
"UNKNOWN",
"BOOTP"
593 std::list<std::string>
595 "VENDOR_CLASS_",
"HA_",
"AFTER_",
"EXTERNAL_"
600 for (std::list<std::string>::const_iterator bn =
builtinNames.cbegin();
602 if (client_class == *bn) {
607 for (std::list<std::string>::const_iterator bt =
builtinPrefixes.cbegin();
609 if (client_class.size() <= bt->size()) {
612 auto mis = std::mismatch(bt->cbegin(), bt->cend(), client_class.cbegin());
613 if (mis.first == bt->cend()) {
623 bool& depend_on_known,
628 if ((client_class ==
"KNOWN") || (client_class ==
"UNKNOWN")) {
629 depend_on_known =
true;
638 if (def->getDependOnKnown()) {
639 depend_on_known =
true;
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
This is a base class for exceptions thrown from the DNS library module.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
The IOAddress class represents an IP addresses (version agnostic)
std::string toText() const
Convert the address to a string.
static ElementPtr create(const Position &pos=ZERO_POSITION())
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
This class represents configuration element which is associated with database identifier,...
uint16_t getFamily() const
Returns address family.
static CfgMgr & instance()
returns a single instance of Configuration Manager
Represents option definitions used by the DHCP server.
Represents option data configuration for the DHCP server.
Embodies a single client class definition.
bool equals(const ClientClassDef &other) const
Compares two ClientClassDef objects for equality.
bool getRequired() const
Fetches the only if required flag.
void setCfgOption(const CfgOptionPtr &cfg_option)
Sets the class's option collection.
void setName(const std::string &name)
Sets the class's name.
bool dependOnClass(const std::string &name) const
Checks direct dependency.
bool getDependOnKnown() const
Fetches the depend on known flag aka use host flag.
void setRequired(bool required)
Sets the only if required flag.
virtual void test(PktPtr pkt, const ExpressionPtr &expr_ptr)
Test method which checks if the packet belongs to the class.
const CfgOptionDefPtr & getCfgOptionDef() const
Fetches the class's option definitions.
ClientClassDef(const std::string &name, const ExpressionPtr &match_expr, const CfgOptionPtr &options=CfgOptionPtr())
Constructor.
const ExpressionPtr & getMatchExpr() const
Fetches the class's match expression.
void setCfgOptionDef(const CfgOptionDefPtr &cfg_option_def)
Sets the class's option definition collection.
virtual ~ClientClassDef()
Destructor.
std::string getName() const
Fetches the class's name.
const CfgOptionPtr & getCfgOption() const
Fetches the class's option collection.
void setMatchExpr(const ExpressionPtr &match_expr)
Sets the class's match expression.
void setTest(const std::string &test)
Sets the class's original match expression.
virtual isc::data::ElementPtr toElement() const
Unparse a configuration object.
std::string getTest() const
Fetches the class's original match expression.
void setDependOnKnown(bool depend_on_known)
Sets the depend on known flag aka use host flag.
Maintains a list of ClientClassDef's.
ClientClassDefPtr findClass(const std::string &name) const
Fetches the class definition for a given class name.
bool equals(const ClientClassDictionary &other) const
Compares two ClientClassDictionary objects for equality.
void removeClass(const std::string &name)
Removes a given class definition from the dictionary.
bool empty() const
Checks if the class dictionary is empty.
bool dependOnClass(const std::string &name, std::string &dependent_class) const
Checks direct dependency.
ClientClassDictionary()
Constructor.
const ClientClassDefListPtr & getClasses() const
Fetches the dictionary's list of classes.
ClientClassDictionary & operator=(const ClientClassDictionary &rhs)
Copy assignment operator.
~ClientClassDictionary()
Destructor.
void createOptions(const CfgOptionDefPtr &cfg_option_def)
Iterates over the classes in the dictionary and recreates the options.
void addClass(const std::string &name, const ExpressionPtr &match_expr, const std::string &test, bool required, bool depend_on_known, const CfgOptionPtr &options, CfgOptionDefPtr defs=CfgOptionDefPtr(), isc::data::ConstElementPtr user_context=isc::data::ConstElementPtr(), asiolink::IOAddress next_server=asiolink::IOAddress("0.0.0.0"), const std::string &sname=std::string(), const std::string &filename=std::string(), const util::Triplet< uint32_t > &valid=util::Triplet< uint32_t >(), const util::Triplet< uint32_t > &preferred=util::Triplet< uint32_t >(), bool is_template=false, const util::Optional< uint32_t > &offer_lft=util::Optional< uint32_t >())
Adds a new class to the list.
virtual isc::data::ElementPtr toElement() const
Unparse a configuration object.
void initMatchExpr(uint16_t family)
Iterates over the classes in the dictionary and ensures that that match expressions are initialized.
Error that occurs when an attempt is made to add a duplicate class to a class dictionary.
Parser for a logical expression.
void parse(ExpressionPtr &expression, isc::data::ConstElementPtr expression_cfg, uint16_t family, isc::eval::EvalContext::CheckDefined check_defined=isc::eval::EvalContext::acceptAll, isc::eval::EvalContext::ParserType parser_type=isc::eval::EvalContext::PARSER_BOOL)
Parses an expression configuration element into an Expression.
static const std::string SPAWN_CLASS_PREFIX
This is a prefix added to the spawned class name.
TemplateClientClassDef(const std::string &name, const ExpressionPtr &match_expr, const CfgOptionPtr &options=CfgOptionPtr())
Constructor.
virtual void test(PktPtr pkt, const ExpressionPtr &expr_ptr) override
Test method which checks if the packet belongs to the class.
virtual isc::data::ElementPtr toElement() const override
Unparse a configuration object.
ParserType
Specifies what type of expression the parser is expected to see.
T get() const
Retrieves the encapsulated value.
void unspecified(bool unspecified)
Modifies the flag that indicates whether the value is specified or unspecified.
T get(T hint) const
Returns value with a hint.
T getMax() const
Returns a maximum allowed value.
T getMin() const
Returns a minimum allowed value.
Defines classes for storing client class definitions.
Parsers for client class definitions.
#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.
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
A wrapper interface for the ASIO library.
ElementPtr copy(ConstElementPtr from, int level)
Copy the data up to a nesting level.
boost::shared_ptr< const Element > ConstElementPtr
boost::shared_ptr< Element > ElementPtr
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
boost::shared_ptr< isc::dhcp::Pkt > PktPtr
A pointer to either Pkt4 or Pkt6 packet.
std::string ClientClass
Defines a single class name.
std::vector< ClientClassDefPtr > ClientClassDefList
Defines a list of ClientClassDefPtr's, using insert order.
boost::shared_ptr< CfgOption > CfgOptionPtr
Non-const pointer.
const isc::log::MessageID EVAL_RESULT
boost::shared_ptr< CfgOptionDef > CfgOptionDefPtr
Non-const pointer.
boost::shared_ptr< ClientClassDef > ClientClassDefPtr
a pointer to an ClientClassDef
std::string evaluateString(const Expression &expr, Pkt &pkt)
std::list< std::string > builtinPrefixes
The prefixes used to check if a class is BuiltIn class.
std::ostream & operator<<(std::ostream &os, const OpaqueDataTuple &tuple)
Inserts the OpaqueDataTuple as a string into stream.
const int DHCPSRV_DBG_TRACE_DETAIL
Additional information.
boost::shared_ptr< Expression > ExpressionPtr
boost::shared_ptr< ClientClassDictionary > ClientClassDictionaryPtr
Defines a pointer to a ClientClassDictionary.
boost::shared_ptr< ClientClassDefList > ClientClassDefListPtr
Defines a pointer to a ClientClassDefList.
bool evaluateBool(const Expression &expr, Pkt &pkt)
Evaluate a RPN expression for a v4 or v6 packet and return a true or false decision.
bool isClientClassDefined(ClientClassDictionaryPtr &class_dictionary, bool &depend_on_known, const ClientClass &client_class)
Check if a client class name is already defined, i.e.
std::vector< TokenPtr > Expression
This is a structure that holds an expression converted to RPN.
bool isClientClassBuiltIn(const ClientClass &client_class)
Check if a client class name is builtin.
bool dependOnClass(const TokenPtr &token, const std::string &name)
Checks dependency on a token.
std::list< std::string > builtinNames
List of classes for which test expressions cannot be defined.
std::unordered_map< std::string, ClientClassDefPtr > ClientClassDefMap
Defines a map of ClientClassDef's, keyed by the class name.
Defines the logger used by the top-level component of kea-lfc.
Abstract class for configuration Cfg_* classes.
Base class for user context.
void contextToElement(data::ElementPtr map) const
Merge unparse a user_context object.