nic_router: invalidate domains with same name

If two domains have the same name, invalidate (dissolve, destroy) them both.

Issue #2840
This commit is contained in:
Martin Stein 2018-06-01 21:45:18 +02:00 committed by Christian Helmuth
parent 8004d8757f
commit 410652d42a
3 changed files with 38 additions and 4 deletions

View File

@ -14,6 +14,9 @@
#ifndef _AVL_STRING_TREE_H_ #ifndef _AVL_STRING_TREE_H_
#define _AVL_STRING_TREE_H_ #define _AVL_STRING_TREE_H_
/* local includes */
#include <reference.h>
/* Genode includes */ /* Genode includes */
#include <util/avl_string.h> #include <util/avl_string.h>
#include <base/allocator.h> #include <base/allocator.h>
@ -44,7 +47,13 @@ class Net::Avl_string_tree : public Genode::Avl_tree<Genode::Avl_string_base>
public: public:
struct No_match : Genode::Exception { }; struct No_match : Genode::Exception { };
struct Name_not_unique : Genode::Exception
{
OBJECT &object;
Name_not_unique(OBJECT &object) : object(object) { }
};
OBJECT &find_by_name(NAME const &name) { return _find_by_name(name.string()); } OBJECT &find_by_name(NAME const &name) { return _find_by_name(name.string()); }
@ -72,7 +81,11 @@ class Net::Avl_string_tree : public Genode::Avl_tree<Genode::Avl_string_base>
} }
} }
void insert(OBJECT &object) { Tree::insert(&object); } void insert(OBJECT &object)
{
try { throw Name_not_unique(_find_by_name(static_cast<Node *>(&object)->name())); }
catch (No_match) { Tree::insert(&object); }
}
void remove(OBJECT &object) { Tree::remove(&object); } void remove(OBJECT &object) { Tree::remove(&object); }
}; };

View File

@ -35,6 +35,17 @@ Configuration::Configuration(Xml_node const node,
{ } { }
void Configuration::_invalid_domain(Domain &domain,
char const *reason)
{
if (_verbose) {
log("[", domain, "] invalid domain (", reason, ") "); }
_domains.remove(domain);
destroy(_alloc, &domain);
}
Configuration::Configuration(Env &env, Configuration::Configuration(Env &env,
Xml_node const node, Xml_node const node,
Allocator &alloc, Allocator &alloc,
@ -56,8 +67,15 @@ Configuration::Configuration(Env &env,
{ {
/* read domains */ /* read domains */
node.for_each_sub_node("domain", [&] (Xml_node const node) { node.for_each_sub_node("domain", [&] (Xml_node const node) {
try { _domains.insert(*new (_alloc) Domain(*this, node, _alloc)); } try {
catch (Domain::Invalid) { log("invalid domain"); } Domain &domain = *new (_alloc) Domain(*this, node, _alloc);
try { _domains.insert(domain); }
catch (Domain_tree::Name_not_unique exception) {
_invalid_domain(domain, "name not unique");
_invalid_domain(exception.object, "name not unique");
}
}
catch (Domain::Invalid) { log("[?] invalid domain"); }
}); });
/* do those parts of domain init that require the domain tree to be complete */ /* do those parts of domain init that require the domain tree to be complete */
List<Domain> invalid_domains; List<Domain> invalid_domains;

View File

@ -48,6 +48,9 @@ class Net::Configuration
Domain_tree _domains { }; Domain_tree _domains { };
Genode::Xml_node const _node; Genode::Xml_node const _node;
void _invalid_domain(Domain &domain,
char const *reason);
public: public:
enum { DEFAULT_REPORT_INTERVAL_SEC = 5 }; enum { DEFAULT_REPORT_INTERVAL_SEC = 5 };