callout_handle.cc 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. // Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #include <hooks/callout_handle.h>
  15. #include <hooks/callout_manager.h>
  16. #include <hooks/library_handle.h>
  17. #include <hooks/server_hooks.h>
  18. #include <string>
  19. #include <utility>
  20. #include <vector>
  21. using namespace std;
  22. namespace isc {
  23. namespace hooks {
  24. // Constructor.
  25. CalloutHandle::CalloutHandle(const boost::shared_ptr<CalloutManager>& manager,
  26. const boost::shared_ptr<LibraryManagerCollection>& lmcoll)
  27. : lm_collection_(lmcoll), arguments_(), context_collection_(),
  28. manager_(manager), server_hooks_(ServerHooks::getServerHooks()),
  29. skip_(false) {
  30. // Call the "context_create" hook. We should be OK doing this - although
  31. // the constructor has not finished running, all the member variables
  32. // have been created.
  33. manager_->callCallouts(ServerHooks::CONTEXT_CREATE, *this);
  34. }
  35. // Destructor
  36. CalloutHandle::~CalloutHandle() {
  37. // Call the "context_destroy" hook. We should be OK doing this - although
  38. // the destructor is being called, all the member variables are still in
  39. // existence.
  40. manager_->callCallouts(ServerHooks::CONTEXT_DESTROY, *this);
  41. // Explicitly clear the argument and context objects. This should free up
  42. // all memory that could have been allocated by libraries that were loaded.
  43. arguments_.clear();
  44. context_collection_.clear();
  45. // Normal destruction of the remaining variables will include the
  46. // destruction of lm_collection_, an action that decrements the reference
  47. // count on the library manager collection (which holds the libraries that
  48. // could have allocated memory in the argument and context members.) When
  49. // that goes to zero, the libraries will be unloaded: at that point nothing
  50. // in the hooks framework will be pointing to memory in the libraries'
  51. // address space.
  52. //
  53. // It is possible that some other data structure in the server (the program
  54. // using the hooks library) still references the address space and attempts
  55. // to access it causing a segmentation fault. That issue is outside the
  56. // scope of this framework and is not addressed by it.
  57. }
  58. // Return the name of all argument items.
  59. vector<string>
  60. CalloutHandle::getArgumentNames() const {
  61. vector<string> names;
  62. for (ElementCollection::const_iterator i = arguments_.begin();
  63. i != arguments_.end(); ++i) {
  64. names.push_back(i->first);
  65. }
  66. return (names);
  67. }
  68. // Return the library handle allowing the callout to access the CalloutManager
  69. // registration/deregistration functions.
  70. LibraryHandle&
  71. CalloutHandle::getLibraryHandle() const {
  72. return (manager_->getLibraryHandle());
  73. }
  74. // Return the context for the currently pointed-to library. This version is
  75. // used by the "setContext()" method and creates a context for the current
  76. // library if it does not exist.
  77. CalloutHandle::ElementCollection&
  78. CalloutHandle::getContextForLibrary() {
  79. int libindex = manager_->getLibraryIndex();
  80. // Access a reference to the element collection for the given index,
  81. // creating a new element collection if necessary, and return it.
  82. return (context_collection_[libindex]);
  83. }
  84. // The "const" version of the above, used by the "getContext()" method. If
  85. // the context for the current library doesn't exist, throw an exception.
  86. const CalloutHandle::ElementCollection&
  87. CalloutHandle::getContextForLibrary() const {
  88. int libindex = manager_->getLibraryIndex();
  89. ContextCollection::const_iterator libcontext =
  90. context_collection_.find(libindex);
  91. if (libcontext == context_collection_.end()) {
  92. isc_throw(NoSuchCalloutContext, "unable to find callout context "
  93. "associated with the current library index (" << libindex <<
  94. ")");
  95. }
  96. // Return a reference to the context's element collection.
  97. return (libcontext->second);
  98. }
  99. // Return the name of all items in the context associated with the current]
  100. // library.
  101. vector<string>
  102. CalloutHandle::getContextNames() const {
  103. vector<string> names;
  104. const ElementCollection& elements = getContextForLibrary();
  105. for (ElementCollection::const_iterator i = elements.begin();
  106. i != elements.end(); ++i) {
  107. names.push_back(i->first);
  108. }
  109. return (names);
  110. }
  111. // Return name of current hook (the hook to which the current callout is
  112. // attached) or the empty string if not called within the context of a
  113. // callout.
  114. string
  115. CalloutHandle::getHookName() const {
  116. // Get the current hook index.
  117. int index = manager_->getHookIndex();
  118. // ... and look up the hook.
  119. string hook = "";
  120. try {
  121. hook = server_hooks_.getName(index);
  122. } catch (const NoSuchHook&) {
  123. // Hook index is invalid, so this methods probably called from outside
  124. // a callout being executed via a call to CalloutManager::callCallouts.
  125. // In this case, the empty string is returned.
  126. }
  127. return (hook);
  128. }
  129. } // namespace util
  130. } // namespace isc