123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- // Copyright (C) 2013-2017 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/.
- #include <exceptions/exceptions.h>
- #include <hooks/hooks_log.h>
- #include <hooks/server_hooks.h>
- #include <utility>
- #include <vector>
- using namespace std;
- using namespace isc;
- namespace isc {
- namespace hooks {
- // Constructor - register the pre-defined hooks and check that the indexes
- // assigned to them are as expected.
- //
- // Note that there are no logging messages here or in registerHooks(). The
- // recommended way to initialize hook names is to use static initialization.
- // Here, a static object is declared in a file outside of any function or
- // method. As a result, it is instantiated and its constructor run before the
- // program starts. By putting calls to ServerHooks::registerHook() in there,
- // hooks names are already registered when the program runs. However, at that
- // point, the logging system is not initialized, so messages are unable to
- // be output.
- ServerHooks::ServerHooks() {
- initialize();
- }
- // Register a hook. The index assigned to the hook is the current number
- // of entries in the collection, so ensuring that hook indexes are unique
- // and non-negative.
- int
- ServerHooks::registerHook(const string& name) {
- // Determine index for the new element and insert.
- int index = hooks_.size();
- pair<HookCollection::iterator, bool> result =
- hooks_.insert(make_pair(name, index));
- if (!result.second) {
- // There's a problem with hook libraries that need to be linked with
- // libdhcpsrv. For example host_cmds hook library requires host
- // parser, so it needs to be linked with libdhcpsrv. However, when
- // unit-tests are started, the hook points are not registered.
- // When the library is loaded new hook points are registered.
- // This causes issues in the hooks framework, especially when
- // LibraryManager::unloadLibrary() iterates through all hooks
- // and then calls deregisterAllCallouts. This method gets
- // hook_index that is greater than number of elements in
- // hook_vector_ and then we have a read past the array boundary.
- /// @todo: See ticket 5251 and 5208 for details.
- return (getIndex(name));
- // New element was not inserted because an element with the same name
- // already existed.
- //isc_throw(DuplicateHook, "hook with name " << name <<
- // " is already registered");
- }
- // Element was inserted, so add to the inverse hooks collection.
- inverse_hooks_[index] = name;
- // ... and return numeric index.
- return (index);
- }
- // Set ServerHooks object to initial state.
- void
- ServerHooks::initialize() {
- // Clear out the name->index and index->name maps.
- hooks_.clear();
- inverse_hooks_.clear();
- // Register the pre-defined hooks.
- int create = registerHook("context_create");
- int destroy = registerHook("context_destroy");
- // Check registration went as expected.
- if ((create != CONTEXT_CREATE) || (destroy != CONTEXT_DESTROY)) {
- isc_throw(Unexpected, "pre-defined hook indexes are not as expected. "
- "context_create: expected = " << CONTEXT_CREATE <<
- ", actual = " << create <<
- ". context_destroy: expected = " << CONTEXT_DESTROY <<
- ", actual = " << destroy);
- }
- }
- // Reset ServerHooks object to initial state.
- void
- ServerHooks::reset() {
- // Clear all hooks then initialize the pre-defined ones.
- initialize();
- // Log a warning - although this is done during testing, it should never be
- // seen in a production system.
- LOG_WARN(hooks_logger, HOOKS_HOOK_LIST_RESET);
- }
- // Find the name associated with a hook index.
- std::string
- ServerHooks::getName(int index) const {
- // Get iterator to matching element.
- InverseHookCollection::const_iterator i = inverse_hooks_.find(index);
- if (i == inverse_hooks_.end()) {
- isc_throw(NoSuchHook, "hook index " << index << " is not recognized");
- }
- return (i->second);
- }
- // Find the index associated with a hook name.
- int
- ServerHooks::getIndex(const string& name) const {
- // Get iterator to matching element.
- HookCollection::const_iterator i = hooks_.find(name);
- if (i == hooks_.end()) {
- isc_throw(NoSuchHook, "hook name " << name << " is not recognized");
- }
- return (i->second);
- }
- // Return vector of hook names. The names are not sorted - it is up to the
- // caller to perform sorting if required.
- vector<string>
- ServerHooks::getHookNames() const {
- vector<string> names;
- HookCollection::const_iterator i;
- for (i = hooks_.begin(); i != hooks_.end(); ++i) {
- names.push_back(i->first);
- }
- return (names);
- }
- // Return global ServerHooks object
- ServerHooks&
- ServerHooks::getServerHooks() {
- return (*getServerHooksPtr());
- }
- ServerHooksPtr
- ServerHooks::getServerHooksPtr() {
- static ServerHooksPtr hooks(new ServerHooks());
- return (hooks);
- }
- } // namespace util
- } // namespace isc
|