From 040eee1aa49b49df4698d83a05af57c220127fd1 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 4 May 2024 13:36:04 +0200 Subject: Adding upstream version 2.2.0. Signed-off-by: Daniel Baumann --- src/lib/dhcp/classify.h | 171 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 src/lib/dhcp/classify.h (limited to 'src/lib/dhcp/classify.h') diff --git a/src/lib/dhcp/classify.h b/src/lib/dhcp/classify.h new file mode 100644 index 0000000..5cf675c --- /dev/null +++ b/src/lib/dhcp/classify.h @@ -0,0 +1,171 @@ +// Copyright (C) 2014-2022 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef CLASSIFY_H +#define CLASSIFY_H + +#include + +#include +#include +#include +#include +#include + +#include + +/// @file classify.h +/// +/// @brief Defines elements for storing the names of client classes +/// +/// This file defines common elements used to track the client classes +/// that may be associated with a given packet. In order to minimize the +/// exposure of the DHCP library to server side concepts such as client +/// classification the classes herein provide a mechanism to maintain lists +/// of class names, rather than the classes they represent. It is the +/// upper layers' prerogative to use these names as they see fit. +/// +/// @todo This file should be moved to dhcpsrv eventually as the classification +/// is server side concept. Client has no notion of classifying incoming server +/// messages as it usually talks to only one server. That move is not possible +/// yet, as the Pkt4 and Pkt6 classes have server-side implementation, even +/// though they reside in the dhcp directory. + +namespace isc { + +namespace dhcp { + + /// @brief Defines a single class name. + typedef std::string ClientClass; + + /// @brief Tag for the sequence index. + struct ClassSequenceTag { }; + + /// @brief Tag for the name index. + struct ClassNameTag { }; + + /// @brief the client class multi-index. + typedef boost::multi_index_container< + ClientClass, + boost::multi_index::indexed_by< + // First index is the sequence one. + boost::multi_index::sequenced< + boost::multi_index::tag + >, + // Second index is the name hash one. + boost::multi_index::hashed_unique< + boost::multi_index::tag, + boost::multi_index::identity + > + > + > ClientClassContainer; + + /// @brief Container for storing client class names + /// + /// Both a list to iterate on it in insert order and unordered + /// set of names for existence. + class ClientClasses { + public: + + /// @brief Type of iterators + typedef ClientClassContainer::const_iterator const_iterator; + typedef ClientClassContainer::iterator iterator; + + /// @brief Default constructor. + ClientClasses() : container_() { + } + + /// @brief Constructor from comma separated values. + /// + /// @param class_names A string containing a client classes separated + /// with commas. The class names are trimmed before insertion to the set. + ClientClasses(const ClientClass& class_names); + + /// @brief Insert an element. + /// + /// @param class_name The name of the class to insert + void insert(const ClientClass& class_name) { + static_cast(container_.push_back(class_name)); + } + + /// @brief Erase element by name. + /// + /// @param class_name The name of the class to erase. + void erase(const ClientClass& class_name); + + /// @brief Check if classes is empty. + bool empty() const { + return (container_.empty()); + } + + /// @brief Returns the number of classes. + /// + /// @note; in C++ 11 list size complexity is constant so + /// there is no advantage to use the set part. + size_t size() const { + return (container_.size()); + } + + /// @brief Iterators to the first element. + /// @{ + const_iterator cbegin() const { + return (container_.cbegin()); + } + const_iterator begin() const { + return (container_.begin()); + } + iterator begin() { + return (container_.begin()); + } + /// @} + + /// @brief Iterators to the past the end element. + /// @{ + const_iterator cend() const { + return (container_.cend()); + } + const_iterator end() const { + return (container_.end()); + } + iterator end() { + return (container_.end()); + } + /// @} + + /// @brief returns if class x belongs to the defined classes + /// + /// @param x client class to be checked + /// @return true if x belongs to the classes + bool contains(const ClientClass& x) const; + + /// @brief Clears containers. + void clear() { + container_.clear(); + } + + /// @brief Returns all class names as text + /// + /// @param separator Separator to be used between class names. The + /// default separator comprises comma sign followed by space + /// character. + /// + /// @return the string representation of all classes + std::string toText(const std::string& separator = ", ") const; + + /// @brief Returns all class names as an ElementPtr of type ListElement + /// + /// @return the list + isc::data::ElementPtr toElement() const; + + private: + /// @brief container part + ClientClassContainer container_; + }; +} + +} + +#endif /* CLASSIFY_H */ -- cgit v1.2.3