callout_handle_store.h 3.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  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. #ifndef CALLOUT_HANDLE_STORE_H
  15. #define CALLOUT_HANDLE_STORE_H
  16. #include <hooks/hooks_manager.h>
  17. #include <hooks/callout_handle.h>
  18. namespace isc {
  19. namespace dhcp {
  20. /// @brief CalloutHandle Store
  21. ///
  22. /// When using the Hooks Framework, there is a need to associate an
  23. /// isc::hooks::CalloutHandle object with each request passing through the
  24. /// server. For the DHCP servers, the association is provided by this function.
  25. ///
  26. /// The DHCP servers process a single request at a time. At points where the
  27. /// CalloutHandle is required, the pointer to the current request (packet) is
  28. /// passed to this function. If the request is a new one, a pointer to
  29. /// the request is stored, a new CalloutHandle is allocated (and stored) and
  30. /// a pointer to the latter object returned to the caller. If the request
  31. /// matches the one stored, the pointer to the stored CalloutHandle is
  32. /// returned.
  33. ///
  34. /// A special case is a null pointer being passed. This has the effect of
  35. /// clearing the stored pointers to the packet being processed and
  36. /// CalloutHandle. As the stored pointers are shared pointers, clearing them
  37. /// removes one reference that keeps the pointed-to objects in existence.
  38. ///
  39. /// @note If the behaviour of the server changes so that multiple packets can
  40. /// be active at the same time, this simplistic approach will no longer
  41. /// be adequate and a more complicated structure (such as a map) will
  42. /// be needed.
  43. ///
  44. /// @param pktptr Pointer to the packet being processed. This is typically a
  45. /// Pkt4Ptr or Pkt6Ptr object. An empty pointer is passed to clear
  46. /// the stored pointers.
  47. ///
  48. /// @return Shared pointer to a CalloutHandle. This is the previously-stored
  49. /// CalloutHandle if pktptr points to a packet that has been seen
  50. /// before or a new CalloutHandle if it points to a new one. An empty
  51. /// pointer is returned if pktptr is itself an empty pointer.
  52. template <typename T>
  53. isc::hooks::CalloutHandlePtr getCalloutHandle(const T& pktptr) {
  54. // Stored data is declared static, so is initialized when first accessed
  55. static T stored_pointer; // Pointer to last packet seen
  56. static isc::hooks::CalloutHandlePtr stored_handle;
  57. // Pointer to stored handle
  58. if (pktptr) {
  59. // Pointer given, have we seen it before? (If we have, we don't need to
  60. // do anything as we will automatically return the stored handle.)
  61. if (pktptr != stored_pointer) {
  62. // Not seen before, so store the pointer passed to us and get a new
  63. // CalloutHandle. (The latter operation frees and probably deletes
  64. // (depending on other pointers) the stored one.)
  65. stored_pointer = pktptr;
  66. stored_handle = isc::hooks::HooksManager::createCalloutHandle();
  67. }
  68. } else {
  69. // Empty pointer passed, clear stored data
  70. stored_pointer.reset();
  71. stored_handle.reset();
  72. }
  73. return (stored_handle);
  74. }
  75. } // namespace shcp
  76. } // namespace isc
  77. #endif // CALLOUT_HANDLE_STORE_H