SharedNetwork4Ptr net = nets->at(0);
ASSERT_TRUE(net);
- auto classes = net->getClientClasses();
- EXPECT_TRUE(classes.contains("alpha"));
+ EXPECT_EQ("alpha", net->getClientClass());
// The first shared network has two subnets.
const Subnet4Collection * subs = net->getAllSubnets();
// shared-network level.
Subnet4Ptr s = checkSubnet(*subs, "192.0.1.0/24", 1, 2, 4);
ASSERT_TRUE(s);
- classes = s->getClientClasses();
- EXPECT_TRUE(classes.contains("alpha"));
+ EXPECT_EQ("alpha", s->getClientClass());
// For the second subnet, the values are overridden on subnet level.
// The value should not be inherited.
s = checkSubnet(*subs, "192.0.2.0/24", 1, 2, 4);
- classes = s->getClientClasses();
- EXPECT_TRUE(classes.contains("beta")); // beta defined on subnet level
- EXPECT_FALSE(classes.contains("alpha")); // alpha defined on shared-network level
+ EXPECT_EQ("beta", s->getClientClass()); // beta defined on subnet level
// Ok, now check the second shared network. It doesn't have anything defined
// on shared-network or subnet level, so everything should have default
EXPECT_EQ(1, subs->size());
s = checkSubnet(*subs, "192.0.3.0/24", 1, 2, 4);
- classes = s->getClientClasses();
- EXPECT_TRUE(classes.empty());
+ EXPECT_TRUE(s->getClientClass().empty());
}
}
// Let's check the first one.
SharedNetwork6Ptr net = nets->at(0);
ASSERT_TRUE(net);
-
- auto classes = net->getClientClasses();
- EXPECT_TRUE(classes.contains("alpha"));
+ EXPECT_EQ("alpha", net->getClientClass());
const Subnet6Collection * subs = net->getAllSubnets();
ASSERT_TRUE(subs);
// shared-network level.
Subnet6Ptr s = checkSubnet(*subs, "2001:db1::/48", 900, 1800, 3600, 7200);
ASSERT_TRUE(s);
- classes = s->getClientClasses();
- EXPECT_TRUE(classes.contains("alpha"));
+ EXPECT_EQ("alpha", s->getClientClass());
// For the second subnet, the values are overridden on subnet level.
// The value should not be inherited.
s = checkSubnet(*subs, "2001:db2::/48", 900, 1800, 3600, 7200);
ASSERT_TRUE(s);
- classes = s->getClientClasses();
- EXPECT_TRUE(classes.contains("beta")); // beta defined on subnet level
- EXPECT_FALSE(classes.contains("alpha")); // alpha defined on shared-network level
+ EXPECT_EQ("beta", s->getClientClass()); // beta defined on subnet level
// Ok, now check the second shared network. It doesn't have
// anything defined on shared-network or subnet level, so
// This subnet should derive its renew-timer from global scope.
s = checkSubnet(*subs, "2001:db3::/48", 900, 1800, 3600, 7200);
- classes = s->getClientClasses();
- EXPECT_TRUE(classes.empty());
+ EXPECT_TRUE(s->getClientClass().empty());
}
// Tests if rapid-commit is derived properly.
bool
Network::clientSupported(const isc::dhcp::ClientClasses& classes) const {
- if (white_list_.empty()) {
+ if (client_class_.empty()) {
// There is no class defined for this network, so we do
// support everyone.
return (true);
}
- for (ClientClasses::const_iterator it = white_list_.begin();
- it != white_list_.end(); ++it) {
- if (classes.contains(*it)) {
- return (true);
- }
- }
-
- return (false);
+ return (classes.contains(client_class_));
}
void
Network::allowClientClass(const isc::dhcp::ClientClass& class_name) {
- white_list_.insert(class_name);
+ client_class_ = class_name;
}
ElementPtr
map->set("relay", relay);
// Set client-class
- const ClientClasses& cclasses = getClientClasses();
- if (cclasses.size() > 1) {
- isc_throw(ToElementError, "client-class has too many items: "
- << cclasses.size());
- } else if (!cclasses.empty()) {
- map->set("client-class", Element::create(*cclasses.cbegin()));
+ const ClientClass& cclass = getClientClass();
+ if (!cclass.empty()) {
+ map->set("client-class", Element::create(cclass));
}
// Set renew-timer
/// @brief Constructor.
Network()
: iface_name_(), relay_(asiolink::IOAddress::IPV4_ZERO_ADDRESS()),
- white_list_(), t1_(0), t2_(0), valid_(0),
+ client_class_(""), t1_(0), t2_(0), valid_(0),
host_reservation_mode_(HR_ALL), cfg_option_(new CfgOption()) {
}
/// it is supported. On the other hand, client belonging to classes
/// "foobar" and "zyxxy" is not supported.
///
- /// @todo: Currently the logic is simple: client is supported if it belongs
- /// to any class mentioned in white_list_. We will eventually need a
- /// way to specify more fancy logic (e.g. to meet all classes, not just
- /// any)
+ /// @note: changed the planned white and black lists idea to a simple
+ /// client class name.
///
/// @param client_classes list of all classes the client belongs to
/// @return true if client can be supported, false otherwise
virtual bool
clientSupported(const isc::dhcp::ClientClasses& client_classes) const;
- /// @brief Adds class class_name to the list of supported classes
- ///
- /// Also see explanation note in @ref white_list_.
+ /// @brief Sets the supported class to class class_name
///
/// @param class_name client class to be supported by this subnet
void allowClientClass(const isc::dhcp::ClientClass& class_name);
- /// @brief returns the client class white list
+ /// @brief returns the client class
///
/// @note The returned reference is only valid as long as the object
/// returned it is valid.
///
- /// @return client classes @ref white_list_
- const isc::dhcp::ClientClasses& getClientClasses() const {
- return (white_list_);
+ /// @return client class @ref client_class_
+ const isc::dhcp::ClientClass& getClientClass() const {
+ return (client_class_);
}
/// @brief Return valid-lifetime for addresses in that prefix
/// If defined, only clients belonging to that class will be allowed to use
/// this particular network. The default value for this is an empty list,
/// which means that any client is allowed, regardless of its class.
- ///
- /// @todo This is just a single list of allowed classes. We'll also need
- /// to add a black-list (only classes on the list are rejected, the rest
- /// are allowed). Implementing this will require more fancy parser logic,
- /// so it may be a while until we support this.
- ClientClasses white_list_;
+ ClientClass client_class_;
/// @brief a Triplet (min/default/max) holding allowed renew timer values
Triplet<uint32_t> t1_;
Pool::Pool(Lease::Type type, const isc::asiolink::IOAddress& first,
const isc::asiolink::IOAddress& last)
:id_(getNextID()), first_(first), last_(last), type_(type),
- capacity_(0), cfg_option_(new CfgOption()), white_list_(),
+ capacity_(0), cfg_option_(new CfgOption()), client_class_(""),
known_clients_(SERVE_BOTH),
last_allocated_(first), last_allocated_valid_(false) {
}
bool Pool::clientSupported(const ClientClasses& classes,
bool known_client) const {
bool match = false;
- if (white_list_.empty()) {
+ if (client_class_.empty()) {
// There is no class defined for this pool, so we do
// support everyone.
match = true;
- } else {
-
- for (ClientClasses::const_iterator it = white_list_.begin();
- it != white_list_.end(); ++it) {
- if (classes.contains(*it)) {
- match = true;
- break;
- }
- }
+ } else if (classes.contains(client_class_)) {
+ match = true;
}
if (!match) {
}
void Pool::allowClientClass(const ClientClass& class_name) {
- white_list_.insert(class_name);
+ client_class_ = class_name;
}
std::string
map->set("option-data", opts->toElement());
// Set client-class
- const ClientClasses& cclasses = getClientClasses();
- if (cclasses.size() > 1) {
- isc_throw(ToElementError, "client-class has too many items: "
- << cclasses.size());
- } else if (!cclasses.empty()) {
- map->set("client-class", Element::create(*cclasses.cbegin()));
+ const ClientClass& cclass = getClientClass();
+ if (!cclass.empty()) {
+ map->set("client-class", Element::create(cclass));
}
// Set known-clients
/// @Checks whether this pool supports client that belongs to
/// specified classes.
///
- /// @todo: currently doing the same than network which
- /// is known to be improved.
- ///
/// @param client_classes list of all classes the client belongs to
/// @param known_client true if the client is known, i.e. has a
/// reservation
bool clientSupported(const ClientClasses& client_classes,
bool known_client) const;
- /// @brief Adds class class_name to the list of supported classes
+ /// @brief Sets the supported class to class class_name
///
/// @param class_name client class to be supported by this pool
void allowClientClass(const ClientClass& class_name);
- /// @brief returns the client class white list
+ /// @brief returns the client class
///
- /// @note Currently white list is empty or has one element
/// @note The returned reference is only valid as long as the object
/// returned is valid.
///
- /// @return client classes @ref white_list_
- const ClientClasses& getClientClasses() const {
- return (white_list_);
+ /// @return client class @ref client_class_
+ const ClientClass& getClientClass() const {
+ return (client_class_);
}
/// @brief Returns the value of known clients
/// @brief Optional definition of a client class
///
- /// @ref Network::white_list_
- ClientClasses white_list_;
+ /// @ref Network::client_class_
+ ClientClass client_class_;
/// @brief Value of known clients
KnownClients known_clients_;
ConstCfgOptionPtr opts = (*pool)->getCfgOption();
pool_map->set("option-data", opts->toElement());
// Set client-class
- const ClientClasses& cclasses = (*pool)->getClientClasses();
- if (cclasses.size() > 1) {
- isc_throw(ToElementError, "client-class has too many items: "
- << cclasses.size());
- } else if (!cclasses.empty()) {
- pool_map->set("client-class", Element::create(*cclasses.cbegin()));
+ const ClientClass& cclass = (*pool)->getClientClass();
+ if (!cclass.empty()) {
+ pool_map->set("client-class", Element::create(cclass));
}
// Set known-clients
Pool::KnownClients kc = (*pool)->getKnownClients();
ConstCfgOptionPtr opts = pdpool->getCfgOption();
pool_map->set("option-data", opts->toElement());
// Set client-class
- const ClientClasses& cclasses = pdpool->getClientClasses();
- if (cclasses.size() > 1) {
- isc_throw(ToElementError, "client-class has too many items: "
- << cclasses.size());
- } else if (!cclasses.empty()) {
- pool_map->set("client-class", Element::create(*cclasses.cbegin()));
+ const ClientClass& cclass = pdpool->getClientClass();
+ if (!cclass.empty()) {
+ pool_map->set("client-class", Element::create(cclass));
}
// Set known-clients
Pool::KnownClients kc = pdpool->getKnownClients();
three_classes.insert("baz");
// No class restrictions defined, any client should be supported
- EXPECT_EQ(0, pool->getClientClasses().size());
+ EXPECT_TRUE(pool->getClientClass().empty());
EXPECT_TRUE(pool->clientSupported(no_class, false));
EXPECT_TRUE(pool->clientSupported(foo_class, false));
EXPECT_TRUE(pool->clientSupported(bar_class, false));
// Let's allow only clients belonging to "bar" class.
pool->allowClientClass("bar");
- EXPECT_EQ(1, pool->getClientClasses().size());
+ EXPECT_EQ("bar", pool->getClientClass());
EXPECT_FALSE(pool->clientSupported(no_class, false));
EXPECT_FALSE(pool->clientSupported(foo_class, false));
EXPECT_TRUE(pool->clientSupported(three_classes, false));
}
-// This test checks that handling for multiple client-classes is valid.
-TEST(Pool4Test, clientClasses) {
- // Create a pool.
- Pool4Ptr pool(new Pool4(IOAddress("192.0.2.0"),
- IOAddress("192.0.2.255")));
-
- // This client does not belong to any class.
- isc::dhcp::ClientClasses no_class;
-
- // This client belongs to foo only.
- isc::dhcp::ClientClasses foo_class;
- foo_class.insert("foo");
-
- // This client belongs to bar only. I like that client.
- isc::dhcp::ClientClasses bar_class;
- bar_class.insert("bar");
-
- // No class restrictions defined, any client should be supported
- EXPECT_EQ(0, pool->getClientClasses().size());
- EXPECT_TRUE(pool->clientSupported(no_class, false));
- EXPECT_TRUE(pool->clientSupported(foo_class, false));
- EXPECT_TRUE(pool->clientSupported(bar_class, false));
-
- // Let's allow clients belonging to "bar" or "foo" class.
- pool->allowClientClass("bar");
- pool->allowClientClass("foo");
- EXPECT_EQ(2, pool->getClientClasses().size());
-
- // Class-less clients are to be rejected.
- EXPECT_FALSE(pool->clientSupported(no_class, false));
-
- // Clients in foo class should be accepted.
- EXPECT_TRUE(pool->clientSupported(foo_class, false));
-
- // Clients in bar class should be accepted as well.
- EXPECT_TRUE(pool->clientSupported(bar_class, false));
-}
-
// This test checks that handling for known-clients is valid.
TEST(Pool4Test, knownClients) {
// Create a pool.
three_classes.insert("baz");
// No class restrictions defined, any client should be supported
- EXPECT_EQ(0, pool.getClientClasses().size());
+ EXPECT_TRUE(pool.getClientClass().empty());
EXPECT_TRUE(pool.clientSupported(no_class, false));
EXPECT_TRUE(pool.clientSupported(foo_class, false));
EXPECT_TRUE(pool.clientSupported(bar_class, false));
// Let's allow only clients belonging to "bar" class.
pool.allowClientClass("bar");
- EXPECT_EQ(1, pool.getClientClasses().size());
+ EXPECT_EQ("bar", pool.getClientClass());
EXPECT_FALSE(pool.clientSupported(no_class, false));
EXPECT_FALSE(pool.clientSupported(foo_class, false));
EXPECT_TRUE(pool.clientSupported(three_classes, false));
}
-// This test checks that handling for multiple client-classes is valid.
-TEST(Pool6Test, clientClasses) {
- // Create a pool.
- Pool6 pool(Lease::TYPE_NA, IOAddress("2001:db8::1"),
- IOAddress("2001:db8::2"));
-
- // This client does not belong to any class.
- isc::dhcp::ClientClasses no_class;
-
- // This client belongs to foo only.
- isc::dhcp::ClientClasses foo_class;
- foo_class.insert("foo");
-
- // This client belongs to bar only. I like that client.
- isc::dhcp::ClientClasses bar_class;
- bar_class.insert("bar");
-
- // No class restrictions defined, any client should be supported
- EXPECT_EQ(0, pool.getClientClasses().size());
- EXPECT_TRUE(pool.clientSupported(no_class, false));
- EXPECT_TRUE(pool.clientSupported(foo_class, false));
- EXPECT_TRUE(pool.clientSupported(bar_class, false));
-
- // Let's allow clients belonging to "bar" or "foo" class.
- pool.allowClientClass("bar");
- pool.allowClientClass("foo");
- EXPECT_EQ(2, pool.getClientClasses().size());
-
- // Class-less clients are to be rejected.
- EXPECT_FALSE(pool.clientSupported(no_class, false));
-
- // Clients in foo class should be accepted.
- EXPECT_TRUE(pool.clientSupported(foo_class, false));
-
- // Clients in bar class should be accepted as well.
- EXPECT_TRUE(pool.clientSupported(bar_class, false));
-}
-
// This test checks that handling for known-clients is valid.
TEST(Pool6Test, knownClients) {
// Create a pool.
network = parser.parse(config_element);
ASSERT_TRUE(network);
- const ClientClasses classes = network->getClientClasses();
- ASSERT_EQ(1, classes.size());
- EXPECT_TRUE(classes.contains("alpha"));
+ EXPECT_EQ("alpha", network->getClientClass());
EXPECT_FALSE(network->getMatchClientId());
}
network = parser.parse(config_element);
ASSERT_TRUE(network);
- const ClientClasses classes = network->getClientClasses();
- ASSERT_EQ(1, classes.size());
- EXPECT_TRUE(classes.contains("alpha"));
+ EXPECT_EQ("alpha", network->getClientClass());
}
} // end of anonymous namespace
four_classes.insert("network");
// No class restrictions defined, any client should be supported
- EXPECT_EQ(0, subnet->getClientClasses().size());
+ EXPECT_TRUE(subnet->getClientClass().empty());
EXPECT_TRUE(subnet->clientSupported(no_class));
EXPECT_TRUE(subnet->clientSupported(foo_class));
EXPECT_TRUE(subnet->clientSupported(bar_class));
// Let's allow only clients belonging to "bar" class.
subnet->allowClientClass("bar");
- EXPECT_EQ(1, subnet->getClientClasses().size());
+ EXPECT_EQ("bar", subnet->getClientClass());
EXPECT_FALSE(subnet->clientSupported(no_class));
EXPECT_FALSE(subnet->clientSupported(foo_class));
EXPECT_TRUE(subnet->clientSupported(four_classes));
}
-// Tests whether Subnet4 object is able to store and process properly
-// information about allowed client classes (multiple classes allowed).
-TEST(Subnet4Test, clientClassesMultiple) {
- // Create the V4 subnet.
- Subnet4Ptr subnet(new Subnet4(IOAddress("192.0.2.0"), 8, 1, 2, 3));
-
- // This client does not belong to any class.
- isc::dhcp::ClientClasses no_class;
-
- // This client belongs to foo only.
- isc::dhcp::ClientClasses foo_class;
- foo_class.insert("foo");
-
- // This client belongs to bar only. I like that client.
- isc::dhcp::ClientClasses bar_class;
- bar_class.insert("bar");
-
- // No class restrictions defined, any client should be supported
- EXPECT_EQ(0, subnet->getClientClasses().size());
- EXPECT_TRUE(subnet->clientSupported(no_class));
- EXPECT_TRUE(subnet->clientSupported(foo_class));
- EXPECT_TRUE(subnet->clientSupported(bar_class));
-
- // Let's allow clients belonging to "bar" or "foo" class.
- subnet->allowClientClass("bar");
- subnet->allowClientClass("foo");
- EXPECT_EQ(2, subnet->getClientClasses().size());
-
- // Class-less clients are to be rejected.
- EXPECT_FALSE(subnet->clientSupported(no_class));
-
- // Clients in foo class should be accepted.
- EXPECT_TRUE(subnet->clientSupported(foo_class));
-
- // Clients in bar class should be accepted as well.
- EXPECT_TRUE(subnet->clientSupported(bar_class));
-}
-
TEST(Subnet4Test, addInvalidOption) {
// Create the V4 subnet.
Subnet4Ptr subnet(new Subnet4(IOAddress("192.0.2.0"), 8, 1, 2, 3));
four_classes.insert("network");
// No class restrictions defined, any client should be supported
- EXPECT_EQ(0, subnet->getClientClasses().size());
+ EXPECT_TRUE(subnet->getClientClass().empty());
EXPECT_TRUE(subnet->clientSupported(no_class));
EXPECT_TRUE(subnet->clientSupported(foo_class));
EXPECT_TRUE(subnet->clientSupported(bar_class));
// Let's allow only clients belonging to "bar" class.
subnet->allowClientClass("bar");
- EXPECT_EQ(1, subnet->getClientClasses().size());
+ EXPECT_EQ("bar", subnet->getClientClass());
EXPECT_FALSE(subnet->clientSupported(no_class));
EXPECT_FALSE(subnet->clientSupported(foo_class));
EXPECT_TRUE(subnet->clientSupported(four_classes));
}
-// Tests whether Subnet6 object is able to store and process properly
-// information about allowed client class (multiple classes allowed).
-TEST(Subnet6Test, clientClassesMultiple) {
- // Create the V6 subnet.
- Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8:1::"), 56, 1, 2, 3, 4));
-
- // This client does not belong to any class.
- isc::dhcp::ClientClasses no_class;
-
- // This client belongs to foo only.
- isc::dhcp::ClientClasses foo_class;
- foo_class.insert("foo");
-
- // This client belongs to bar only. I like that client.
- isc::dhcp::ClientClasses bar_class;
- bar_class.insert("bar");
-
- // No class restrictions defined, any client should be supported
- EXPECT_EQ(0, subnet->getClientClasses().size());
- EXPECT_TRUE(subnet->clientSupported(no_class));
- EXPECT_TRUE(subnet->clientSupported(foo_class));
- EXPECT_TRUE(subnet->clientSupported(bar_class));
-
- // Let's allow only clients belonging to "foo" or "bar" class.
- subnet->allowClientClass("foo");
- subnet->allowClientClass("bar");
- EXPECT_EQ(2, subnet->getClientClasses().size());
-
- // Class-less clients are to be rejected.
- EXPECT_FALSE(subnet->clientSupported(no_class));
-
- // Clients in foo class should be accepted.
- EXPECT_TRUE(subnet->clientSupported(foo_class));
-
- // Clients in bar class should be accepted as well.
- EXPECT_TRUE(subnet->clientSupported(bar_class));
-}
-
// Checks that it is not allowed to add invalid pools.
TEST(Subnet6Test, pool6Checks) {