From: Francis Dupont Date: Thu, 12 Apr 2018 14:07:47 +0000 (+0200) Subject: [5458a] Checkpoint (dhcp6 to finish - lib to do) X-Git-Tag: trac5488_base~2^2~15 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3c1181b5e8ac8039bb55edddcf9abbfe4ef34efc;p=thirdparty%2Fkea.git [5458a] Checkpoint (dhcp6 to finish - lib to do) --- diff --git a/src/bin/dhcp6/ctrl_dhcp6_srv.cc b/src/bin/dhcp6/ctrl_dhcp6_srv.cc index f0d39bb6f9..1e93628868 100644 --- a/src/bin/dhcp6/ctrl_dhcp6_srv.cc +++ b/src/bin/dhcp6/ctrl_dhcp6_srv.cc @@ -689,6 +689,7 @@ ControlledDhcpv6Srv::processConfig(isc::data::ConstElementPtr config) { CalloutHandlePtr callout_handle = HooksManager::createCalloutHandle(); callout_handle->setArgument("io_context", srv->getIOService()); + // callout_handle->setArgument("network_state", srv->getNetworkState()); callout_handle->setArgument("json_config", config); callout_handle->setArgument("server_config", CfgMgr::instance().getStagingCfg()); diff --git a/src/bin/dhcp6/dhcp6_hooks.dox b/src/bin/dhcp6/dhcp6_hooks.dox index 45afd6cb38..ec54ed20c1 100644 --- a/src/bin/dhcp6/dhcp6_hooks.dox +++ b/src/bin/dhcp6/dhcp6_hooks.dox @@ -46,6 +46,26 @@ packet processing, but the exact order depends on the actual processing. Hook po that are not specific to packet processing (e.g. lease expiration) will be added to the end of this list. + @subsection dhcp6HooksDhcpv6SrvConfigured dhcp6_srv_configured + - @b Arguments: + - name: @b io_context, type: isc::asiolink::IOServicePtr, direction: in + - name: @b network_state, type: isc::dhcp::NetworkStatePtr, direction: in + - name: @b json_config, type: isc::data::ConstElementPtr, direction: in + - name: @b server_config, type: isc::dhcp::SrvConfigPtr, direction: in + + - @b Description: this callout is executed when the server has completed + its (re)configuration. The server provides received and parsed configuration + structures to the hook library. It also provides a pointer to the IOService + object which is used by the server to run asynchronous operations. The hooks + libraries can use this IOService object to schedule asynchronous tasks which + are triggered by the DHCP server's main loop. The hook library should hold the + provided pointer until the library is unloaded. The NetworkState object + provides access to the DHCP service state of the server and allows for + enabling and disabling the DHCP service from the hooks libraries. + + - Next step status: Status codes retured by the callouts installed on + this hook point are ignored. + @subsection dhcpv6HooksBuffer6Receive buffer6_receive - @b Arguments: @@ -266,6 +286,39 @@ to the end of this list. remain in the database until it expires. However, the server will send out the response back to the client as if it did. +@subsection dhcpv6Leases6Committed leases6_committed + + - @b Arguments: + - name: @b query6, type: isc::dhcp::Pkt6Ptr, direction: in + - name: @b leases6, type: isc::dhcp::Leases6CollectionPtr, direction: in + - name: @b deleted_leases6, type: isc::dhcp::Leases6CollectionPtr, direction: in + + - @b Description: this callout is executed when the server has + applied all lease changes as a result of DHCP message + processing. This includes writing new lease into the database, + releasing an old lease for this client or declining a lease. This + callout is executed only for the DHCP client messages which may + cause lease changes, i.e. REQUEST, RENEW, REBIND, RELEASE and + DECLINE. This callout is not executed for SOLICIT, CONFIRM and + INFORMATION REQUEST. If the callouts are executed as a result of + PREQUEST or RENEW message, it is possible that both leases + collections hold leases to be handled. This is the case when the + new lease allocation replaces an existing lease for the client. The + "deleted_leases6" object will hold a previous lease instance and + the "leases6" object will hold the new lease for this client. The + callouts should be prepared to handle such situation. When the + callout is executed as a result RELEASE or DECLINE, the callout + will typically receive only one lease (being released) in the + "deleted_leases6" object. Both leases collections are always + provided to the callouts, even though they may sometimes be empty. + + - Next step status: If any callout installed on the "leases6_committed" + sets the next step action to DROP the server will drop the processed query. + If it sets the next step action to PARK, the server will park the processed + packet (hold packet processing) until the hook libraries explicitly unpark + the packet after they are done performing asynchronous operations. + + @subsection dhcpv6HooksPkt6Send pkt6_send - @b Arguments: diff --git a/src/bin/dhcp6/dhcp6_messages.mes b/src/bin/dhcp6/dhcp6_messages.mes index da4320145b..28b3f13d6e 100644 --- a/src/bin/dhcp6/dhcp6_messages.mes +++ b/src/bin/dhcp6/dhcp6_messages.mes @@ -320,6 +320,14 @@ The server will skip the operation of moving the lease to the declined state and will continue processing the packet. In particular, it will send a REPLY message as if the decline actually took place. +% DHCP6_HOOK_LEASES6_COMMITTED_DROP %1: packet is dropped, because a callout set the next step to DROP +This debug message is printed when a callout installed on the leases6_committed +hook point sets the next step to DROP. + +% DHCP6_HOOK_LEASES6_COMMITTED_PARK %1: packet is parked, because a callout set the next step to PARK +This debug message is printed when a callout installed on the lease6_committed +hook point sets the next step to PARK. + % DHCP6_HOOK_LEASE6_RELEASE_NA_SKIP %1: DHCPv6 address lease was not released because a callout set the next step to SKIP This debug message is printed when a callout installed on the lease6_release hook point set the next step to SKIP. For this particular hook diff --git a/src/bin/dhcp6/dhcp6_srv.cc b/src/bin/dhcp6/dhcp6_srv.cc index 987280acab..66d906fcbc 100644 --- a/src/bin/dhcp6/dhcp6_srv.cc +++ b/src/bin/dhcp6/dhcp6_srv.cc @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -94,34 +93,40 @@ namespace { /// Structure that holds registered hook indexes struct Dhcp6Hooks { - int hook_index_buffer6_receive_;///< index for "buffer6_receive" hook point - int hook_index_pkt6_receive_; ///< index for "pkt6_receive" hook point - int hook_index_subnet6_select_; ///< index for "subnet6_select" hook point - int hook_index_lease6_release_; ///< index for "lease6_release" hook point - int hook_index_pkt6_send_; ///< index for "pkt6_send" hook point - int hook_index_buffer6_send_; ///< index for "buffer6_send" hook point - int hook_index_lease6_decline_; ///< index for "lease6_decline" hook point - int hook_index_host6_identifier_;///< index for "host6_identifier" hook point + int hook_index_buffer6_receive_; ///< index for "buffer6_receive" hook point + int hook_index_pkt6_receive_; ///< index for "pkt6_receive" hook point + int hook_index_subnet6_select_; ///< index for "subnet6_select" hook point + int hook_index_leases6_committed_;///< index for "leases6_committed" hook point + int hook_index_lease6_release_; ///< index for "lease6_release" hook point + int hook_index_pkt6_send_; ///< index for "pkt6_send" hook point + int hook_index_buffer6_send_; ///< index for "buffer6_send" hook point + int hook_index_lease6_decline_; ///< index for "lease6_decline" hook point + int hook_index_host6_identifier_; ///< index for "host6_identifier" hook point /// Constructor that registers hook points for DHCPv6 engine Dhcp6Hooks() { - hook_index_buffer6_receive_ = HooksManager::registerHook("buffer6_receive"); - hook_index_pkt6_receive_ = HooksManager::registerHook("pkt6_receive"); - hook_index_subnet6_select_ = HooksManager::registerHook("subnet6_select"); - hook_index_lease6_release_ = HooksManager::registerHook("lease6_release"); - hook_index_pkt6_send_ = HooksManager::registerHook("pkt6_send"); - hook_index_buffer6_send_ = HooksManager::registerHook("buffer6_send"); - hook_index_lease6_decline_ = HooksManager::registerHook("lease6_decline"); - hook_index_host6_identifier_= HooksManager::registerHook("host6_identifier"); + hook_index_buffer6_receive_ = HooksManager::registerHook("buffer6_receive"); + hook_index_pkt6_receive_ = HooksManager::registerHook("pkt6_receive"); + hook_index_subnet6_select_ = HooksManager::registerHook("subnet6_select"); + hook_index_leases6_committed_ = HooksManager::registerHook("leases6_committed"); + hook_index_lease6_release_ = HooksManager::registerHook("lease6_release"); + hook_index_pkt6_send_ = HooksManager::registerHook("pkt6_send"); + hook_index_buffer6_send_ = HooksManager::registerHook("buffer6_send"); + hook_index_lease6_decline_ = HooksManager::registerHook("lease6_decline"); + hook_index_host6_identifier_ = HooksManager::registerHook("host6_identifier"); } }; +} // end of anonymous namespace + // Declare a Hooks object. As this is outside any function or method, it // will be instantiated (and the constructor run) when the module is loaded. // As a result, the hook indexes will be defined before any method in this // module is called. Dhcp6Hooks Hooks; +namespace { + /// @brief Creates instance of the Status Code option. /// /// This variant of the function is used when the Status Code option @@ -488,55 +493,12 @@ void Dhcpv6Srv::run_one() { return; } - try { - - // Now all fields and options are constructed into output wire buffer. - // Option objects modification does not make sense anymore. Hooks - // can only manipulate wire buffer at this stage. - // Let's execute all callouts registered for buffer6_send - if (HooksManager::calloutsPresent(Hooks.hook_index_buffer6_send_)) { - CalloutHandlePtr callout_handle = getCalloutHandle(query); - - // Delete previously set arguments - callout_handle->deleteAllArguments(); - - // Enable copying options from the packet within hook library. - ScopedEnableOptionsCopy response6_options_copy(rsp); - - // Pass incoming packet as argument - callout_handle->setArgument("response6", rsp); - - // Call callouts - HooksManager::callCallouts(Hooks.hook_index_buffer6_send_, *callout_handle); - - // Callouts decided to skip the next processing step. The next - // processing step would to parse the packet, so skip at this - // stage means drop. - if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) || - (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP)) { - LOG_DEBUG(hooks_logger, DBG_DHCP6_HOOKS, DHCP6_HOOK_BUFFER_SEND_SKIP) - .arg(rsp->getLabel()); - return; - } - - callout_handle->getArgument("response6", rsp); - } - - LOG_DEBUG(packet6_logger, DBG_DHCP6_DETAIL_DATA, DHCP6_RESPONSE_DATA) - .arg(static_cast(rsp->getType())).arg(rsp->toText()); - - sendPacket(rsp); - - // Update statistics accordingly for sent packet. - processStatsSent(rsp); - - } catch (const std::exception& e) { - LOG_ERROR(packet6_logger, DHCP6_PACKET_SEND_FAIL).arg(e.what()); - } + CalloutHandlePtr callout_handle = getCalloutHandle(query); + processPacketBufferSend(callout_handle, rsp); } void -Dhcpv6Srv::processPacket(Pkt6Ptr& query, Pkt6Ptr& rsp) { +Dhcpv6Srv::processPacket(Pkt6Ptr& query, Pkt6Ptr& rsp, bool allow_packet_park) { bool skip_unpack = false; // The packet has just been received so contains the uninterpreted wire @@ -641,6 +603,9 @@ Dhcpv6Srv::processPacket(Pkt6Ptr& query, Pkt6Ptr& rsp) { return; } + // Assign this packet to a class, if possible + classifyPacket(query); + LOG_DEBUG(packet6_logger, DBG_DHCP6_BASIC_DATA, DHCP6_PACKET_RECEIVED) .arg(query->getLabel()) .arg(query->getName()) @@ -686,8 +651,7 @@ Dhcpv6Srv::processPacket(Pkt6Ptr& query, Pkt6Ptr& rsp) { callout_handle->getArgument("query6", query); } - // Assign this packet to a class, if possible - classifyPacket(query); + AllocEngine::ClientContext6Ptr ctx; try { NameChangeRequestPtr ncr; @@ -698,15 +662,15 @@ Dhcpv6Srv::processPacket(Pkt6Ptr& query, Pkt6Ptr& rsp) { break; case DHCPV6_REQUEST: - rsp = processRequest(query); + rsp = processRequest(query, ctx); break; case DHCPV6_RENEW: - rsp = processRenew(query); + rsp = processRenew(query, ctx); break; case DHCPV6_REBIND: - rsp = processRebind(query); + rsp = processRebind(query, ctx); break; case DHCPV6_CONFIRM: @@ -714,11 +678,11 @@ Dhcpv6Srv::processPacket(Pkt6Ptr& query, Pkt6Ptr& rsp) { break; case DHCPV6_RELEASE: - rsp = processRelease(query); + rsp = processRelease(query, ctx); break; case DHCPV6_DECLINE: - rsp = processDecline(query); + rsp = processDecline(query, ctx); break; case DHCPV6_INFORMATION_REQUEST: @@ -799,6 +763,88 @@ Dhcpv6Srv::processPacket(Pkt6Ptr& query, Pkt6Ptr& rsp) { rsp->setIndex(query->getIndex()); rsp->setIface(query->getIface()); + bool packet_park = false; + + if (ctx && HooksManager::calloutsPresent(Hooks.hook_index_leases6_committed_)) { + CalloutHandlePtr callout_handle = getCalloutHandle(query); + + // Delete all previous arguments + callout_handle->deleteAllArguments(); + + // Clear skip flag if it was set in previous callouts + callout_handle->setStatus(CalloutHandle::NEXT_STEP_CONTINUE); + + ScopedEnableOptionsCopy query6_options_copy(query); + + // Also pass the corresponding query packet as argument + callout_handle->setArgument("query6", query); + + Lease6CollectionPtr new_leases(new Lease6Collection()); + if (ctx->new_lease_) { + new_leases->push_back(ctx->new_lease_); + } + callout_handle->setArgument("leases6", new_leases); + + Lease6CollectionPtr deleted_leases(new Lease6Collection()); + if (ctx->old_lease_) { + if ((!ctx->new_lease_) || (ctx->new_lease_->addr_ != ctx->old_lease_->addr_)) { + deleted_leases->push_back(ctx->old_lease_); + } + } + callout_handle->setArgument("deleted_leases6", deleted_leases); + + // Call all installed callouts + HooksManager::callCallouts(Hooks.hook_index_leases6_committed_, + *callout_handle); + + if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) { + LOG_DEBUG(hooks_logger, DBG_DHCP6_HOOKS, + DHCP6_HOOK_LEASES6_COMMITTED_DROP) + .arg(query->getLabel()); + rsp.reset(); + + } else if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_PARK) + && allow_packet_park) { + packet_park = true; + } + } + + if (!rsp) { + return; + } + + // PARKING SPOT after leases6_committed hook point. + CalloutHandlePtr callout_handle = getCalloutHandle(query); + if (packet_park) { + LOG_DEBUG(hooks_logger, DBG_DHCP6_HOOKS, + DHCP6_HOOK_LEASES6_COMMITTED_PARK) + .arg(query->getLabel()); + + // Park the packet. The function we bind here will be executed when the hook + // library unparks the packet. + HooksManager::park("leases6_committed", query, + [this, callout_handle, query, rsp]() mutable { + processPacketPktSend(callout_handle, query, rsp); + processPacketBufferSend(callout_handle, rsp); + }); + + // If we have parked the packet, let's reset the pointer to the + // response to indicate to the caller that it should return, as + // the packet processing will continue via the callback. + rsp.reset(); + + } else { + processPacketPktSend(callout_handle, query, rsp); + } +} + +void +Dhcpv6Srv::processPacketPktSend(hooks::CalloutHandlePtr& callout_handle, + Pkt6Ptr& query, Pkt6Ptr& rsp) { + if (!rsp) { + return; + } + // Specifies if server should do the packing bool skip_pack = false; @@ -807,7 +853,6 @@ Dhcpv6Srv::processPacket(Pkt6Ptr& query, Pkt6Ptr& rsp) { // output wire data has not been prepared yet. // Execute all callouts registered for packet6_send if (HooksManager::calloutsPresent(Hooks.hook_index_pkt6_send_)) { - CalloutHandlePtr callout_handle = getCalloutHandle(query); // Enable copying options from the packets within hook library. ScopedEnableOptionsCopy query_resp_options_copy(query, rsp); @@ -855,6 +900,60 @@ Dhcpv6Srv::processPacket(Pkt6Ptr& query, Pkt6Ptr& rsp) { } } +void +Dhcpv6Srv::processPacketBufferSend(CalloutHandlePtr& callout_handle, + Pkt6Ptr& rsp) { + if (!rsp) { + return; + } + + try { + // Now all fields and options are constructed into output wire buffer. + // Option objects modification does not make sense anymore. Hooks + // can only manipulate wire buffer at this stage. + // Let's execute all callouts registered for buffer6_send + if (HooksManager::calloutsPresent(Hooks.hook_index_buffer6_send_)) { + + // Delete previously set arguments + callout_handle->deleteAllArguments(); + + // Enable copying options from the packet within hook library. + ScopedEnableOptionsCopy response6_options_copy(rsp); + + // Pass incoming packet as argument + callout_handle->setArgument("response6", rsp); + + // Call callouts + HooksManager::callCallouts(Hooks.hook_index_buffer6_send_, + *callout_handle); + + // Callouts decided to skip the next processing step. The next + // processing step would to parse the packet, so skip at this + // stage means drop. + if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) || + (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP)) { + LOG_DEBUG(hooks_logger, DBG_DHCP6_HOOKS, + DHCP6_HOOK_BUFFER_SEND_SKIP) + .arg(rsp->getLabel()); + return; + } + + callout_handle->getArgument("response6", rsp); + } + + LOG_DEBUG(packet6_logger, DBG_DHCP6_DETAIL_DATA, DHCP6_RESPONSE_DATA) + .arg(static_cast(rsp->getType())).arg(rsp->toText()); + + sendPacket(rsp); + + // Update statistics accordingly for sent packet. + processStatsSent(rsp); + + } catch (const std::exception& e) { + LOG_ERROR(packet6_logger, DHCP6_PACKET_SEND_FAIL).arg(e.what()); + } +} + std::string Dhcpv6Srv::duidToString(const OptionPtr& opt) { stringstream tmp; @@ -2516,7 +2615,6 @@ Dhcpv6Srv::releaseIA_PD(const DuidPtr& duid, const Pkt6Ptr& query, } - Pkt6Ptr Dhcpv6Srv::processSolicit(const Pkt6Ptr& solicit) { @@ -2574,17 +2672,20 @@ Dhcpv6Srv::processSolicit(const Pkt6Ptr& solicit) { } Pkt6Ptr -Dhcpv6Srv::processRequest(const Pkt6Ptr& request) { +Dhcpv6Srv::processRequest(const Pkt6Ptr& request, + AllocEngine::ClientContext6Ptr& context) { sanityCheck(request, MANDATORY, MANDATORY); // Let's create a simplified client context here. - AllocEngine::ClientContext6 ctx; + context.reset(new AllocEngine::ClientContext6()); + AllocEngine::ClientContext6& ctx = *context; bool drop = false; initContext(request, ctx, drop); // Stop here if initContext decided to drop the packet. if (drop) { + context.reset(); return (Pkt6Ptr()); } @@ -2611,17 +2712,20 @@ Dhcpv6Srv::processRequest(const Pkt6Ptr& request) { } Pkt6Ptr -Dhcpv6Srv::processRenew(const Pkt6Ptr& renew) { +Dhcpv6Srv::processRenew(const Pkt6Ptr& renew, + AllocEngine::ClientContext6Ptr& context) { sanityCheck(renew, MANDATORY, MANDATORY); // Let's create a simplified client context here. - AllocEngine::ClientContext6 ctx; + context.reset(new AllocEngine::ClientContext6()); + AllocEngine::ClientContext6& ctx = *context; bool drop = false; initContext(renew, ctx, drop); // Stop here if initContext decided to drop the packet. if (drop) { + context.reset(); return (Pkt6Ptr()); } @@ -2648,17 +2752,20 @@ Dhcpv6Srv::processRenew(const Pkt6Ptr& renew) { } Pkt6Ptr -Dhcpv6Srv::processRebind(const Pkt6Ptr& rebind) { +Dhcpv6Srv::processRebind(const Pkt6Ptr& rebind, + AllocEngine::ClientContext6Ptr& context) { sanityCheck(rebind, MANDATORY, FORBIDDEN); // Let's create a simplified client context here. - AllocEngine::ClientContext6 ctx; + context.reset(new AllocEngine::ClientContext6()); + AllocEngine::ClientContext6& ctx = *context; bool drop = false; initContext(rebind, ctx, drop); // Stop here if initContext decided to drop the packet. if (drop) { + context.reset(); return (Pkt6Ptr()); } @@ -2786,17 +2893,20 @@ Dhcpv6Srv::processConfirm(const Pkt6Ptr& confirm) { } Pkt6Ptr -Dhcpv6Srv::processRelease(const Pkt6Ptr& release) { +Dhcpv6Srv::processRelease(const Pkt6Ptr& release, + AllocEngine::ClientContext6Ptr& context) { sanityCheck(release, MANDATORY, MANDATORY); // Let's create a simplified client context here. - AllocEngine::ClientContext6 ctx; + context.reset(new AllocEngine::ClientContext6()); + AllocEngine::ClientContext6& ctx = *context; bool drop = false; initContext(release, ctx, drop); // Stop here if initContext decided to drop the packet. if (drop) { + context.reset(); return (Pkt6Ptr()); } @@ -2819,27 +2929,30 @@ Dhcpv6Srv::processRelease(const Pkt6Ptr& release) { } Pkt6Ptr -Dhcpv6Srv::processDecline(const Pkt6Ptr& decline) { +Dhcpv6Srv::processDecline(const Pkt6Ptr& decline, + AllocEngine::ClientContext6Ptr& context) { // Do sanity check. sanityCheck(decline, MANDATORY, MANDATORY); - // Create an empty Reply message. - Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, decline->getTransid())); - // Let's create a simplified client context here. - AllocEngine::ClientContext6 ctx; + context.reset(new AllocEngine::ClientContext6()); + AllocEngine::ClientContext6& ctx = *context; bool drop = false; initContext(decline, ctx, drop); // Stop here if initContext decided to drop the packet. if (drop) { + context.reset(); return (Pkt6Ptr()); } setReservedClientClasses(decline, ctx); requiredClassify(decline, ctx); + // Create an empty Reply message. + Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, decline->getTransid())); + // Copy client options (client-id, also relay information if present) copyClientOptions(decline, reply); @@ -2856,6 +2969,7 @@ Dhcpv6Srv::processDecline(const Pkt6Ptr& decline) { // declineLeases returns false only if the hooks set the next step // status to DROP. We'll just doing as requested. + context.reset(); return (Pkt6Ptr()); } } @@ -3006,7 +3120,7 @@ Dhcpv6Srv::declineIA(const Pkt6Ptr& decline, const DuidPtr& duid, } // Ok, all is good. Decline this lease. - if (!declineLease(decline, lease, ia_rsp)) { + if (!declineLease(decline, lease, ia_rsp, ctx)) { // declineLease returns false only when hook callouts set the next // step status to drop. We just propagate the bad news here. return (OptionPtr()); @@ -3033,7 +3147,8 @@ Dhcpv6Srv::setStatusCode(boost::shared_ptr& container, bool Dhcpv6Srv::declineLease(const Pkt6Ptr& decline, const Lease6Ptr lease, - boost::shared_ptr ia_rsp) { + boost::shared_ptr ia_rsp, + AllocEngine::ClientContext6& ctx) { // We do not want to decrease the assigned-nas at this time. While // technically a declined address is no longer allocated, the primary usage // of the assigned-addresses statistic is to monitor pool utilization. Most @@ -3102,6 +3217,8 @@ Dhcpv6Srv::declineLease(const Pkt6Ptr& decline, const Lease6Ptr lease, lease->decline(CfgMgr::instance().getCurrentCfg()->getDeclinePeriod()); LeaseMgrFactory::instance().updateLease6(lease); + ctx.new_lease_ = lease; + LOG_INFO(lease6_logger, DHCP6_DECLINE_LEASE).arg(decline->getLabel()) .arg(lease->addr_.toText()).arg(lease->valid_lft_); diff --git a/src/bin/dhcp6/dhcp6_srv.h b/src/bin/dhcp6/dhcp6_srv.h index 898bd0c195..55e07e21d1 100644 --- a/src/bin/dhcp6/dhcp6_srv.h +++ b/src/bin/dhcp6/dhcp6_srv.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -24,6 +25,7 @@ #include #include +#include #include #include @@ -120,7 +122,9 @@ public: /// /// @param query A pointer to the packet to be processed. /// @param rsp A pointer to the response - void processPacket(Pkt6Ptr& query, Pkt6Ptr& rsp); + /// @param allow_packet_park Indicates if parking a packet is allowed. + void processPacket(Pkt6Ptr& query, Pkt6Ptr& rsp, + bool allow_packet_park = true); /// @brief Instructs the server to shut down. void shutdown(); @@ -228,15 +232,21 @@ protected: /// leases. /// /// @param request a message received from client + /// @param [out] context pointer to the client context where allocated + /// and deleted leases are stored. /// /// @return REPLY message or NULL - Pkt6Ptr processRequest(const Pkt6Ptr& request); + Pkt6Ptr processRequest(const Pkt6Ptr& request, + AllocEngine::ClientContext6Ptr& context); /// @brief Processes incoming Renew message. /// /// @param renew message received from the client + /// @param [out] context pointer to the client context where allocated + /// and deleted leases are stored. /// @return Reply message to be sent to the client. - Pkt6Ptr processRenew(const Pkt6Ptr& renew); + Pkt6Ptr processRenew(const Pkt6Ptr& renew, + AllocEngine::ClientContext6Ptr& context); /// @brief Processes incoming Rebind message. /// @@ -247,8 +257,11 @@ protected: /// now. /// /// @param rebind message received from the client. + /// @param [out] context pointer to the client context where allocated + /// and deleted leases are stored. /// @return Reply message to be sent to the client. - Pkt6Ptr processRebind(const Pkt6Ptr& rebind); + Pkt6Ptr processRebind(const Pkt6Ptr& rebind, + AllocEngine::ClientContext6Ptr& context); /// @brief Processes incoming Confirm message and returns Reply. /// @@ -278,8 +291,11 @@ protected: /// @brief Process incoming Release message. /// /// @param release message received from client + /// @param [out] context pointer to the client context where released + /// leases are stored. /// @return Reply message to be sent to the client. - Pkt6Ptr processRelease(const Pkt6Ptr& release); + Pkt6Ptr processRelease(const Pkt6Ptr& release, + AllocEngine::ClientContext6Ptr& context); /// @brief Process incoming Decline message. /// @@ -292,7 +308,10 @@ protected: /// options) /// /// @param decline message received from client - Pkt6Ptr processDecline(const Pkt6Ptr& decline); + /// @param [out] context pointer to the client context where declined + /// leases are stored. + Pkt6Ptr processDecline(const Pkt6Ptr& decline, + AllocEngine::ClientContext6Ptr& context); /// @brief Processes incoming Information-request message. /// @@ -881,6 +900,13 @@ public: /// @return the index of the buffer6_send hook static int getHookIndexBuffer6Send(); + /// @brief Executes buffer6_send callout and sends the response. + /// + /// @param callout_handle pointer to the callout handle. + /// @param rsp pointer to a response. + void processPacketBufferSend(hooks::CalloutHandlePtr& callout_handle, + Pkt6Ptr& rsp); + protected: /// Server DUID (to be sent in server-identifier option) @@ -890,6 +916,14 @@ protected: /// initiate server shutdown procedure. volatile bool shutdown_; + /// @brief Executes pkt6_send callout. + /// + /// @param callout_handle pointer to the callout handle. + /// @param query Pointer to a query. + /// @param rsp Pointer to a response. + void processPacketPktSend(hooks::CalloutHandlePtr& callout_handle, + Pkt6Ptr& query, Pkt6Ptr& rsp); + /// @brief Allocation Engine. /// Pointer to the allocation engine that we are currently using /// It must be a pointer, because we will support changing engines diff --git a/src/bin/dhcp6/dhcp6to4_ipc.cc b/src/bin/dhcp6/dhcp6to4_ipc.cc index 454cbd19c6..8704288ad7 100644 --- a/src/bin/dhcp6/dhcp6to4_ipc.cc +++ b/src/bin/dhcp6/dhcp6to4_ipc.cc @@ -100,52 +100,8 @@ void Dhcp6to4Ipc::handler() { // Can't call the pkt6_send callout because we don't have the query - // Copied from Dhcpv6Srv::run_one() sending part - - try { - // Let's execute all callouts registered for buffer6_send - if (HooksManager::calloutsPresent(Dhcpv6Srv::getHookIndexBuffer6Send())) { - CalloutHandlePtr callout_handle = getCalloutHandle(pkt); - - // Delete previously set arguments - callout_handle->deleteAllArguments(); - - // Enable copying options from the packet within hook library. - ScopedEnableOptionsCopy response6_options_copy(pkt); - - // Pass incoming packet as argument - callout_handle->setArgument("response6", pkt); - - // Call callouts - HooksManager::callCallouts(Dhcpv6Srv::getHookIndexBuffer6Send(), - *callout_handle); - - // Callouts decided to skip the next processing step. The next - // processing step would to parse the packet, so skip at this - // stage means drop. - if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) || - (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP)) { - LOG_DEBUG(hooks_logger, DBG_DHCP6_HOOKS, DHCP6_HOOK_BUFFER_SEND_SKIP) - .arg(pkt->getLabel()); - return; - } - - callout_handle->getArgument("response6", pkt); - } - - LOG_DEBUG(packet6_logger, DBG_DHCP6_DETAIL_DATA, DHCP6_RESPONSE_DATA) - .arg(static_cast(pkt->getType())).arg(pkt->toText()); - - - // Forward packet to the client. - IfaceMgr::instance().send(pkt); - - // Update statistics accordingly for sent packet. - Dhcpv6Srv::processStatsSent(pkt); - - } catch (const std::exception& e) { - LOG_ERROR(packet6_logger, DHCP6_DHCP4O6_SEND_FAIL).arg(e.what()); - } + ControlledDhcpv4Srv::getInstance()-> + processPacketBufferSend(getCalloutHandle(pkt), pkt); } }; // namespace dhcp diff --git a/src/bin/dhcp6/tests/Makefile.am b/src/bin/dhcp6/tests/Makefile.am index 1171de0f49..70dfc4176b 100644 --- a/src/bin/dhcp6/tests/Makefile.am +++ b/src/bin/dhcp6/tests/Makefile.am @@ -57,7 +57,7 @@ if HAVE_GTEST # to unexpected errors. For this reason, the --enable-static-link option is # ignored for unit tests built here. -noinst_LTLIBRARIES = libco1.la libco2.la +noinst_LTLIBRARIES = libco1.la libco2.la libco3.la # -rpath /nowhere is a hack to trigger libtool to not create a # convenience archive, resulting in shared modules @@ -72,6 +72,11 @@ libco2_la_CXXFLAGS = $(AM_CXXFLAGS) libco2_la_CPPFLAGS = $(AM_CPPFLAGS) libco2_la_LDFLAGS = -avoid-version -export-dynamic -module -rpath /nowhere +libco3_la_SOURCES = callout_library_3.cc callout_library_common.h +libco3_la_CXXFLAGS = $(AM_CXXFLAGS) +libco3_la_CPPFLAGS = $(AM_CPPFLAGS) +libco3_la_LDFLAGS = -avoid-version -export-dynamic -module -rpath /nowhere + TESTS += dhcp6_unittests dhcp6_unittests_SOURCES = dhcp6_unittests.cc dhcp6_unittests_SOURCES += dhcp6_srv_unittest.cc diff --git a/src/bin/dhcp6/tests/callout_library_1.cc b/src/bin/dhcp6/tests/callout_library_1.cc index 866652c6f6..ffe05eba3f 100644 --- a/src/bin/dhcp6/tests/callout_library_1.cc +++ b/src/bin/dhcp6/tests/callout_library_1.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2013-2018 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 @@ -13,4 +13,4 @@ static const int LIBRARY_NUMBER = 1; #include -#include "callout_library_common.h" +#include diff --git a/src/bin/dhcp6/tests/callout_library_2.cc b/src/bin/dhcp6/tests/callout_library_2.cc index ae417a2969..5dc72c52d1 100644 --- a/src/bin/dhcp6/tests/callout_library_2.cc +++ b/src/bin/dhcp6/tests/callout_library_2.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2013-2018 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 @@ -13,4 +13,4 @@ static const int LIBRARY_NUMBER = 2; #include -#include "callout_library_common.h" +#include diff --git a/src/bin/dhcp6/tests/callout_library_3.cc b/src/bin/dhcp6/tests/callout_library_3.cc new file mode 100644 index 0000000000..3305ac1ce6 --- /dev/null +++ b/src/bin/dhcp6/tests/callout_library_3.cc @@ -0,0 +1,44 @@ +// Copyright (C) 2018 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/. + +/// @file +/// @brief Callout library for tesing execution of the dhcp6_srv_configured +/// hook point. +/// +static const int LIBRARY_NUMBER = 3; +#include +#include +#include + +using namespace isc::hooks; + +extern "C" { + +/// @brief Callout which appends library number and provided arguments to +/// the marker file for dhcp6_srv_configured callout. +/// +/// @param handle callout handle passed to the callout. +/// +/// @return 0 on success, 1 otherwise. +int +dhcp6_srv_configured(CalloutHandle& handle) { + // Append library number. + if (appendDigit(SRV_CONFIG_MARKER_FILE)) { + return (1); + } + + // Append argument names. + std::vector args = handle.getArgumentNames(); + for (auto arg = args.begin(); arg != args.end(); ++arg) { + if (appendArgument(SRV_CONFIG_MARKER_FILE, arg->c_str()) != 0) { + return (1); + } + } + + return (0); +} + +} diff --git a/src/bin/dhcp6/tests/callout_library_common.h b/src/bin/dhcp6/tests/callout_library_common.h index c3e3436591..36f459ab2e 100644 --- a/src/bin/dhcp6/tests/callout_library_common.h +++ b/src/bin/dhcp6/tests/callout_library_common.h @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2013-2018 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 @@ -17,6 +17,10 @@ /// can determine whether the load/unload functions have been run and, if so, /// in what order. /// +/// The additional marker file is created for the dhcp6_srv_configured hook +/// point. It records the library number and the names of the parameters +/// provided to the callout. +/// /// This file is the common library file for the tests. It will not compile /// by itself - it is included into each callout library which specifies the /// missing constant LIBRARY_NUMBER before the inclusion. @@ -53,6 +57,26 @@ appendDigit(const char* name) { return (0); } +/// @brief Append argument name passed to the callout to a marker file. +/// +/// @param file_name Name of the file to open. +/// @param parameter Parameter name. +/// +/// @return 0 on success, non-zero on error. +int appendArgument(const char* file_name, const char* argument) { + // Open the file and check if successful. + std::fstream file(file_name, std::fstream::out | std::fstream::app); + if (!file.good()) { + return (1); + } + + // Add the library number to it and close. + file << argument; + file.close(); + + return (0); +} + // Framework functions int version() { diff --git a/src/bin/dhcp6/tests/dhcp6_client.cc b/src/bin/dhcp6/tests/dhcp6_client.cc index 8ab931cd6c..32ed802f79 100644 --- a/src/bin/dhcp6/tests/dhcp6_client.cc +++ b/src/bin/dhcp6/tests/dhcp6_client.cc @@ -900,6 +900,16 @@ Dhcp6Client::receiveOneMsg() { return (msg); } +void +Dhcp6Client::receiveResponse() { + context_.response_ = receiveOneMsg(); + // If the server has responded, store the configuration received. + if (context_.response_) { + config_.clear(); + applyRcvdConfiguration(context_.response_); + } +} + void Dhcp6Client::sendMsg(const Pkt6Ptr& msg) { srv_->shutdown_ = false; @@ -944,7 +954,14 @@ Dhcp6Client::sendMsg(const Pkt6Ptr& msg) { } srv_->fakeReceive(msg_copy); - srv_->run(); + + try { + // Invoke run_one instead of run, because we want to avoid triggering + // IO service. + srv_->run_one(); + } catch (...) { + // Suppress errors, as the DHCPv6 server does. + } } void diff --git a/src/bin/dhcp6/tests/dhcp6_client.h b/src/bin/dhcp6/tests/dhcp6_client.h index 80ff2c37c1..4a2b86df8b 100644 --- a/src/bin/dhcp6/tests/dhcp6_client.h +++ b/src/bin/dhcp6/tests/dhcp6_client.h @@ -767,6 +767,15 @@ public: /// is incomplete. Please extend it when needed. void printConfiguration() const; + /// @brief Receives a response from the server. + /// + /// This method is useful to receive response from the server after + /// parking a packet. In this case, the packet is not received as a + /// result of initial exchange, e.g. @c doRequest. The test can call + /// this method to complete the transaction when it expects that the + /// packet has been unparked. + void receiveResponse(); + private: /// @brief Applies the new leases for the client. diff --git a/src/bin/dhcp6/tests/dhcp6_test_utils.h b/src/bin/dhcp6/tests/dhcp6_test_utils.h index 7b99db54b9..52fe5a02a1 100644 --- a/src/bin/dhcp6/tests/dhcp6_test_utils.h +++ b/src/bin/dhcp6/tests/dhcp6_test_utils.h @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2017 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2013-2018 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 @@ -183,6 +183,51 @@ public: isc::dhcp::LeaseMgrFactory::destroy(); } + /// @brief Processes incoming Request message. + /// + /// @param request a message received from client + /// @return REPLY message or NULL + Pkt6Ptr processRequest(const Pkt6Ptr& request) { + AllocEngine::ClientContext6Ptr context(new AllocEngine::ClientContext6()); + return (processRequest(request, context)); + } + + /// @brief Processes incoming Renew message. + /// + /// @param renew a message received from client + /// @return REPLY message or NULL + Pkt6Ptr processRenew(const Pkt6Ptr& renew) { + AllocEngine::ClientContext6Ptr context(new AllocEngine::ClientContext6()); + return (processRenew(renew, context)); + } + + /// @brief Processes incoming Rebind message. + /// + /// @param rebind a message received from client + /// @return REPLY message or NULL + Pkt6Ptr processRebind(const Pkt6Ptr& rebind) { + AllocEngine::ClientContext6Ptr context(new AllocEngine::ClientContext6()); + return (processRebind(rebind, context)); + } + + /// @brief Processes incoming Release message. + /// + /// @param release a message received from client + /// @return REPLY message or NULL + Pkt6Ptr processRelease(const Pkt6Ptr& release) { + AllocEngine::ClientContext6Ptr context(new AllocEngine::ClientContext6()); + return (processRelease(release, context)); + } + + /// @brief Processes incoming Decline message. + /// + /// @param decline a message received from client + /// @return REPLY message or NULL + Pkt6Ptr processDecline(const Pkt6Ptr& decline) { + AllocEngine::ClientContext6Ptr context(new AllocEngine::ClientContext6()); + return (processDecline(decline, context)); + } + using Dhcpv6Srv::processSolicit; using Dhcpv6Srv::processRequest; using Dhcpv6Srv::processRenew; diff --git a/src/bin/dhcp6/tests/hooks_unittest.cc b/src/bin/dhcp6/tests/hooks_unittest.cc index be61642d1f..a3ba0e2339 100644 --- a/src/bin/dhcp6/tests/hooks_unittest.cc +++ b/src/bin/dhcp6/tests/hooks_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2017 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2013-2018 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 @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -22,6 +23,7 @@ #include #include +#include #include #include #include @@ -53,16 +55,17 @@ TEST_F(Dhcpv6SrvTest, Hooks) { NakedDhcpv6Srv srv(0); // check if appropriate hooks are registered - int hook_index_buffer6_receive = -1; - int hook_index_buffer6_send = -1; - int hook_index_lease6_renew = -1; - int hook_index_lease6_release = -1; - int hook_index_lease6_rebind = -1; - int hook_index_lease6_decline = -1; - int hook_index_pkt6_received = -1; - int hook_index_select_subnet = -1; - int hook_index_pkt6_send = -1; - int hook_index_host6_identifier = -1; + int hook_index_buffer6_receive = -1; + int hook_index_buffer6_send = -1; + int hook_index_lease6_renew = -1; + int hook_index_lease6_release = -1; + int hook_index_lease6_rebind = -1; + int hook_index_lease6_decline = -1; + int hook_index_pkt6_received = -1; + int hook_index_select_subnet = -1; + int hook_index_leases6_committed = -1; + int hook_index_pkt6_send = -1; + int hook_index_host6_identifier = -1; // check if appropriate indexes are set EXPECT_NO_THROW(hook_index_buffer6_receive = ServerHooks::getServerHooks() @@ -81,22 +84,25 @@ TEST_F(Dhcpv6SrvTest, Hooks) { .getIndex("pkt6_receive")); EXPECT_NO_THROW(hook_index_select_subnet = ServerHooks::getServerHooks() .getIndex("subnet6_select")); - EXPECT_NO_THROW(hook_index_pkt6_send = ServerHooks::getServerHooks() + EXPECT_NO_THROW(hook_index_leases6_committed = ServerHooks::getServerHooks() + .getIndex("leases6_committed")); + EXPECT_NO_THROW(hook_index_pkt6_send = ServerHooks::getServerHooks() .getIndex("pkt6_send")); EXPECT_NO_THROW(hook_index_host6_identifier = ServerHooks::getServerHooks() .getIndex("host6_identifier")); - EXPECT_TRUE(hook_index_pkt6_received > 0); - EXPECT_TRUE(hook_index_select_subnet > 0); - EXPECT_TRUE(hook_index_pkt6_send > 0); - EXPECT_TRUE(hook_index_buffer6_receive > 0); - EXPECT_TRUE(hook_index_buffer6_send > 0); - EXPECT_TRUE(hook_index_lease6_renew > 0); - EXPECT_TRUE(hook_index_lease6_release > 0); - EXPECT_TRUE(hook_index_lease6_rebind > 0); - EXPECT_TRUE(hook_index_lease6_decline > 0); - EXPECT_TRUE(hook_index_host6_identifier > 0); + EXPECT_TRUE(hook_index_pkt6_received > 0); + EXPECT_TRUE(hook_index_select_subnet > 0); + EXPECT_TRUE(hook_index_leases6_committed > 0); + EXPECT_TRUE(hook_index_pkt6_send > 0); + EXPECT_TRUE(hook_index_buffer6_receive > 0); + EXPECT_TRUE(hook_index_buffer6_send > 0); + EXPECT_TRUE(hook_index_lease6_renew > 0); + EXPECT_TRUE(hook_index_lease6_release > 0); + EXPECT_TRUE(hook_index_lease6_rebind > 0); + EXPECT_TRUE(hook_index_lease6_decline > 0); + EXPECT_TRUE(hook_index_host6_identifier > 0); } /// @brief a class dedicated to Hooks testing in DHCPv6 server @@ -120,6 +126,8 @@ public: // Clear static buffers resetCalloutBuffers(); + io_service_ = boost::make_shared(); + // Reset the hook system in its original state HooksManager::unloadLibraries(); } @@ -750,6 +758,76 @@ public: return (lease6_decline_callout(callout_handle)); } + /// Test callback that stores values passed to leases6_committed. + static int + leases6_committed_callout(CalloutHandle& callout_handle) { + callback_name_ = string("leases6_committed"); + + callout_handle.getArgument("query6", callback_qry_pkt6_); + + Lease6CollectionPtr leases6; + callout_handle.getArgument("leases6", leases6); + if (leases6->size() > 0) { + callback_lease6_ = leases6->at(0); + } + + Lease6CollectionPtr deleted_leases6; + callout_handle.getArgument("deleted_leases6", deleted_leases6); + if (deleted_leases6->size() > 0) { + callback_deleted_lease6_ = deleted_leases6->at(0); + } + + callback_argument_names_ = callout_handle.getArgumentNames(); + sort(callback_argument_names_.begin(), callback_argument_names_.end()); + + if (callback_qry_pkt6_) { + callback_qry_options_copy_ = callback_qry_pkt6_->isCopyRetrievedOptions(); + } + + return (0); + } + + static void + leases6_committed_unpark(ParkingLotHandlePtr parking_lot, Pkt6Ptr query) { + parking_lot->unpark(query); + } + + /// Test callback which asks the server to park the packet. + static int + leases6_committed_park_callout(CalloutHandle& callout_handle) { + callback_name_ = string("leases6_committed"); + + callout_handle.getArgument("query6", callback_qry_pkt6_); + + io_service_->post(boost::bind(&HooksDhcpv6SrvTest::leases6_committed_unpark, + callout_handle.getParkingLotHandlePtr(), + callback_qry_pkt6_)); + + callout_handle.getParkingLotHandlePtr()->reference(callback_qry_pkt6_); + callout_handle.setStatus(CalloutHandle::NEXT_STEP_PARK); + + Lease6CollectionPtr leases6; + callout_handle.getArgument("leases6", leases6); + if (leases6->size() > 0) { + callback_lease6_ = leases6->at(0); + } + + Lease6CollectionPtr deleted_leases6; + callout_handle.getArgument("deleted_leases6", deleted_leases6); + if (deleted_leases6->size() > 0) { + callback_deleted_lease6_ = deleted_leases6->at(0); + } + + callback_argument_names_ = callout_handle.getArgumentNames(); + sort(callback_argument_names_.begin(), callback_argument_names_.end()); + + if (callback_qry_pkt6_) { + callback_qry_options_copy_ = callback_qry_pkt6_->isCopyRetrievedOptions(); + } + + return (0); + } + /// @brief Test host6_identifier by setting identifier to "foo" /// /// @param callout_handle handle passed by the hooks framework @@ -777,7 +855,7 @@ public: return (0); } - /// @brief Test host4_identifier callout by setting identifier to hwaddr + /// @brief Test host6_identifier callout by setting identifier to hwaddr /// /// This callout always returns fixed HWADDR: 00:01:02:03:04:05 /// @@ -814,6 +892,7 @@ public: callback_resp_pkt6_.reset(); callback_subnet6_.reset(); callback_lease6_.reset(); + callback_deleted_lease6_.reset(); callback_ia_na_.reset(); callback_subnet6collection_ = NULL; callback_argument_names_.clear(); @@ -824,6 +903,9 @@ public: /// Pointer to Dhcpv6Srv that is used in tests boost::scoped_ptr srv_; + /// Pointer to the IO service used in the tests. + static IOServicePtr io_service_; + // The following fields are used in testing pkt6_receive_callout /// String name of the received callout @@ -835,9 +917,12 @@ public: /// Server's response Pkt6 structure returned in the callout static Pkt6Ptr callback_resp_pkt6_; - /// Pointer to lease6 + /// Pointer to lease6 structure returned in the leases8_committed callout static Lease6Ptr callback_lease6_; + /// Pointer to lease6 structure returned in the leases8_committed callout + static Lease6Ptr callback_deleted_lease6_; + /// Pointer to IA_NA option being renewed or rebound static boost::shared_ptr callback_ia_na_; @@ -869,6 +954,7 @@ const uint32_t HooksDhcpv6SrvTest::override_valid_ = 1004; // The following fields are used in testing pkt6_receive_callout. // See fields description in the class for details +IOServicePtr HooksDhcpv4SrvTest::io_service_; string HooksDhcpv6SrvTest::callback_name_; Pkt6Ptr HooksDhcpv6SrvTest::callback_qry_pkt6_; Pkt6Ptr HooksDhcpv6SrvTest::callback_resp_pkt6_; @@ -876,6 +962,7 @@ Subnet6Ptr HooksDhcpv6SrvTest::callback_subnet6_; const Subnet6Collection* HooksDhcpv6SrvTest::callback_subnet6collection_; vector HooksDhcpv6SrvTest::callback_argument_names_; Lease6Ptr HooksDhcpv6SrvTest::callback_lease6_; +Lease6Ptr HooksDhcpv6SrvTest::callback_deleted_lease6_; boost::shared_ptr HooksDhcpv6SrvTest::callback_ia_na_; bool HooksDhcpv6SrvTest::callback_qry_options_copy_; bool HooksDhcpv6SrvTest::callback_resp_options_copy_; @@ -907,11 +994,13 @@ public: // Get rid of any marker files. static_cast(remove(LOAD_MARKER_FILE)); static_cast(remove(UNLOAD_MARKER_FILE)); + static_cast(remove(SRV_CONFIG_MARKER_FILE)); CfgMgr::instance().clear(); } }; + // Checks if callouts installed on buffer6_receive are indeed called and the // all necessary parameters are passed. // diff --git a/src/bin/dhcp6/tests/marker_file.h.in b/src/bin/dhcp6/tests/marker_file.h.in index d279aac10c..06f60d85ae 100644 --- a/src/bin/dhcp6/tests/marker_file.h.in +++ b/src/bin/dhcp6/tests/marker_file.h.in @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2017 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2013-2018 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 @@ -14,6 +14,7 @@ namespace { const char* const LOAD_MARKER_FILE = "@abs_builddir@/load_marker.txt"; const char* const UNLOAD_MARKER_FILE = "@abs_builddir@/unload_marker.txt"; +const char* const SRV_CONFIG_MARKER_FILE = "@abs_builddir@/srv_config_marker_file.txt"; } namespace isc { diff --git a/src/bin/dhcp6/tests/test_libraries.h.in b/src/bin/dhcp6/tests/test_libraries.h.in index 9a54fc65a2..e307d86c3b 100644 --- a/src/bin/dhcp6/tests/test_libraries.h.in +++ b/src/bin/dhcp6/tests/test_libraries.h.in @@ -19,6 +19,7 @@ namespace { // operation. const char* const CALLOUT_LIBRARY_1 = "@abs_builddir@/.libs/libco1.so"; const char* const CALLOUT_LIBRARY_2 = "@abs_builddir@/.libs/libco2.so"; +const char* const CALLOUT_LIBRARY_3 = "@abs_builddir@/.libs/libco3.so"; // Name of a library which is not present. const char* const NOT_PRESENT_LIBRARY = "@abs_builddir@/.libs/libnothere.so";