12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- // Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
- //
- // Permission to use, copy, modify, and/or distribute this software for any
- // purpose with or without fee is hereby granted, provided that the above
- // copyright notice and this permission notice appear in all copies.
- //
- // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- // PERFORMANCE OF THIS SOFTWARE.
- #ifndef CALLOUT_HANDLE_STORE_H
- #define CALLOUT_HANDLE_STORE_H
- #include <hooks/hooks_manager.h>
- #include <hooks/callout_handle.h>
- namespace isc {
- namespace dhcp {
- /// @brief CalloutHandle Store
- ///
- /// When using the Hooks Framework, there is a need to associate an
- /// isc::hooks::CalloutHandle object with each request passing through the
- /// server. For the DHCP servers, the association is provided by this function.
- ///
- /// The DHCP servers process a single request at a time. At points where the
- /// CalloutHandle is required, the pointer to the current request (packet) is
- /// passed to this function. If the request is a new one, a pointer to
- /// the request is stored, a new CalloutHandle is allocated (and stored) and
- /// a pointer to the latter object returned to the caller. If the request
- /// matches the one stored, the pointer to the stored CalloutHandle is
- /// returned.
- ///
- /// A special case is a null pointer being passed. This has the effect of
- /// clearing the stored pointers to the packet being processed and
- /// CalloutHandle. As the stored pointers are shared pointers, clearing them
- /// removes one reference that keeps the pointed-to objects in existence.
- ///
- /// @note If the behaviour of the server changes so that multiple packets can
- /// be active at the same time, this simplistic approach will no longer
- /// be adequate and a more complicated structure (such as a map) will
- /// be needed.
- ///
- /// @param pktptr Pointer to the packet being processed. This is typically a
- /// Pkt4Ptr or Pkt6Ptr object. An empty pointer is passed to clear
- /// the stored pointers.
- ///
- /// @return Shared pointer to a CalloutHandle. This is the previously-stored
- /// CalloutHandle if pktptr points to a packet that has been seen
- /// before or a new CalloutHandle if it points to a new one. An empty
- /// pointer is returned if pktptr is itself an empty pointer.
- template <typename T>
- isc::hooks::CalloutHandlePtr getCalloutHandle(const T& pktptr) {
- // Stored data is declared static, so is initialized when first accessed
- static T stored_pointer; // Pointer to last packet seen
- static isc::hooks::CalloutHandlePtr stored_handle;
- // Pointer to stored handle
- if (pktptr) {
- // Pointer given, have we seen it before? (If we have, we don't need to
- // do anything as we will automatically return the stored handle.)
- if (pktptr != stored_pointer) {
- // Not seen before, so store the pointer passed to us and get a new
- // CalloutHandle. (The latter operation frees and probably deletes
- // (depending on other pointers) the stored one.)
- stored_pointer = pktptr;
- stored_handle = isc::hooks::HooksManager::createCalloutHandle();
- }
-
- } else {
- // Empty pointer passed, clear stored data
- stored_pointer.reset();
- stored_handle.reset();
- }
- return (stored_handle);
- }
- } // namespace shcp
- } // namespace isc
- #endif // CALLOUT_HANDLE_STORE_H
|