From: Francis Dupont Date: Thu, 19 Apr 2018 23:09:31 +0000 (+0200) Subject: [5458a] Code done, tests to do X-Git-Tag: trac5488_base~2^2~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=04fb2e4289f691914a034a5940776b21851cea08;p=thirdparty%2Fkea.git [5458a] Code done, tests to do --- diff --git a/src/bin/dhcp4/tests/kea_controller_unittest.cc b/src/bin/dhcp4/tests/kea_controller_unittest.cc index 8f72c24710..5b843fde7e 100644 --- a/src/bin/dhcp4/tests/kea_controller_unittest.cc +++ b/src/bin/dhcp4/tests/kea_controller_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2014-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 @@ -91,7 +91,7 @@ public: /// @param timeout_ms Amount of time after which the method returns. void runTimersWithTimeout(const IOServicePtr& io_service, const long timeout_ms) { IntervalTimer timer(*io_service); - timer.setup([this, &io_service]() { + timer.setup([&io_service]() { io_service->stop(); }, timeout_ms, IntervalTimer::ONE_SHOT); io_service->run(); diff --git a/src/bin/dhcp4/tests/shared_network_unittest.cc b/src/bin/dhcp4/tests/shared_network_unittest.cc index 47005f3f3a..7afcbe2077 100644 --- a/src/bin/dhcp4/tests/shared_network_unittest.cc +++ b/src/bin/dhcp4/tests/shared_network_unittest.cc @@ -1311,7 +1311,7 @@ TEST_F(Dhcpv4SharedNetworkTest, poolInSharedNetworkShortage) { // the server has no more addresses to assign. Dhcp4Client client3(client1.getServer(), Dhcp4Client::SELECTING); client3.setIfaceName("eth1"); - testAssigned([this, &client3]() { + testAssigned([&client3]() { ASSERT_NO_THROW(client3.doDiscover()); Pkt4Ptr resp3 = client3.getContext().response_; ASSERT_FALSE(resp3); @@ -1447,7 +1447,7 @@ TEST_F(Dhcpv4SharedNetworkTest, hintWithinSharedNetwork) { // Asking for an address that is not in address pool should result in getting // an address from one of the subnets, but generally hard to tell from which one. - testAssigned([this, &client] { + testAssigned([&client] { ASSERT_NO_THROW(client.doDiscover(boost::shared_ptr(new IOAddress("10.0.0.23")))); }); @@ -1481,7 +1481,7 @@ TEST_F(Dhcpv4SharedNetworkTest, subnetInSharedNetworkSelectedByClass) { // Release the lease that the client has got, because we'll need this address // further in the test. - testAssigned([this, &client1] { + testAssigned([&client1] { ASSERT_NO_THROW(client1.doRelease()); }); @@ -1770,7 +1770,7 @@ TEST_F(Dhcpv4SharedNetworkTest, variousFieldsInReservation) { configure(NETWORKS_CONFIG[10], *client.getServer()); // Perform 4-way exchange. - testAssigned([this, &client] { + testAssigned([&client] { ASSERT_NO_THROW(client.doDORA()); }); Pkt4Ptr resp = client.getContext().response_; @@ -1816,7 +1816,7 @@ TEST_F(Dhcpv4SharedNetworkTest, sharedNetworkSelectionByInterface) { configure(NETWORKS_CONFIG[8], *client1.getServer()); // Perform 4-way exchange. - testAssigned([this, &client1] { + testAssigned([&client1] { ASSERT_NO_THROW(client1.doDORA()); }); Pkt4Ptr resp1 = client1.getContext().response_; @@ -1831,7 +1831,7 @@ TEST_F(Dhcpv4SharedNetworkTest, sharedNetworkSelectionByInterface) { client2.setIfaceName("eth0"); // Perform 4-way exchange. - testAssigned([this, &client2] { + testAssigned([&client2] { ASSERT_NO_THROW(client2.doDORA()); }); Pkt4Ptr resp2 = client2.getContext().response_; @@ -1853,7 +1853,7 @@ TEST_F(Dhcpv4SharedNetworkTest, sharedNetworkSelectionByRelay) { configure(NETWORKS_CONFIG[9], *client1.getServer()); // Perform 4-way exchange. - testAssigned([this, &client1] { + testAssigned([&client1] { ASSERT_NO_THROW(client1.doDORA()); }); Pkt4Ptr resp1 = client1.getContext().response_; @@ -1868,7 +1868,7 @@ TEST_F(Dhcpv4SharedNetworkTest, sharedNetworkSelectionByRelay) { client2.useRelay(true, IOAddress("192.1.2.3")); // Perform 4-way exchange. - testAssigned([this, &client2] { + testAssigned([&client2] { ASSERT_NO_THROW(client2.doDORA()); }); Pkt4Ptr resp2 = client2.getContext().response_; @@ -1892,7 +1892,7 @@ TEST_F(Dhcpv4SharedNetworkTest, matchClientId) { configure(NETWORKS_CONFIG[11], *client.getServer()); // Perform 4-way exchange. - testAssigned([this, &client] { + testAssigned([&client] { ASSERT_NO_THROW(client.doDORA()); }); Pkt4Ptr resp1 = client.getContext().response_; @@ -1909,7 +1909,7 @@ TEST_F(Dhcpv4SharedNetworkTest, matchClientId) { client.setState(Dhcp4Client::RENEWING); // Try to renew the lease with modified MAC address. - testAssigned([this, &client] { + testAssigned([&client] { ASSERT_NO_THROW(client.doRequest()); }); Pkt4Ptr resp2 = client.getContext().response_; @@ -1936,7 +1936,7 @@ TEST_F(Dhcpv4SharedNetworkTest, sharedNetworkSelectedByClass) { configure(NETWORKS_CONFIG[13], *client1.getServer()); // Simply send DHCPDISCOVER to avoid allocating a lease. - testAssigned([this, &client1] { + testAssigned([&client1] { ASSERT_NO_THROW(client1.doDiscover()); }); Pkt4Ptr resp1 = client1.getContext().response_; @@ -1969,7 +1969,7 @@ TEST_F(Dhcpv4SharedNetworkTest, customServerIdentifier) { // Configure DHCP server. ASSERT_NO_THROW(configure(NETWORKS_CONFIG[15], *client1.getServer())); - testAssigned([this, &client1] { + testAssigned([&client1] { ASSERT_NO_THROW(client1.doDORA()); }); @@ -1986,7 +1986,7 @@ TEST_F(Dhcpv4SharedNetworkTest, customServerIdentifier) { Dhcp4Client client2(client1.getServer(), Dhcp4Client::SELECTING); client2.setIfaceName("eth0"); - testAssigned([this, &client2] { + testAssigned([&client2] { ASSERT_NO_THROW(client2.doDORA()); }); @@ -2020,7 +2020,7 @@ TEST_F(Dhcpv4SharedNetworkTest, poolInSharedNetworkSelectedByClass) { // Release the lease that the client has got, because we'll need this address // further in the test. - testAssigned([this, &client1] { + testAssigned([&client1] { ASSERT_NO_THROW(client1.doRelease()); }); @@ -2079,7 +2079,7 @@ TEST_F(Dhcpv4SharedNetworkTest, poolInSubnetSelectedByClass) { // Release the lease that the client has got, because we'll need this address // further in the test. - testAssigned([this, &client1] { + testAssigned([&client1] { ASSERT_NO_THROW(client1.doRelease()); }); diff --git a/src/bin/dhcp6/dhcp6_srv.cc b/src/bin/dhcp6/dhcp6_srv.cc index 66d906fcbc..38a7b96896 100644 --- a/src/bin/dhcp6/dhcp6_srv.cc +++ b/src/bin/dhcp6/dhcp6_srv.cc @@ -498,7 +498,7 @@ void Dhcpv6Srv::run_one() { } void -Dhcpv6Srv::processPacket(Pkt6Ptr& query, Pkt6Ptr& rsp, bool allow_packet_park) { +Dhcpv6Srv::processPacket(Pkt6Ptr& query, Pkt6Ptr& rsp) { bool skip_unpack = false; // The packet has just been received so contains the uninterpreted wire @@ -651,46 +651,24 @@ Dhcpv6Srv::processPacket(Pkt6Ptr& query, Pkt6Ptr& rsp, bool allow_packet_park) { callout_handle->getArgument("query6", query); } - AllocEngine::ClientContext6Ptr ctx; - try { - NameChangeRequestPtr ncr; - switch (query->getType()) { case DHCPV6_SOLICIT: - rsp = processSolicit(query); - break; - - case DHCPV6_REQUEST: - rsp = processRequest(query, ctx); - break; - - case DHCPV6_RENEW: - rsp = processRenew(query, ctx); - break; - case DHCPV6_REBIND: - rsp = processRebind(query, ctx); - break; - case DHCPV6_CONFIRM: - rsp = processConfirm(query); + sanityCheck(query, MANDATORY, FORBIDDEN); break; + case DHCPV6_REQUEST: + case DHCPV6_RENEW: case DHCPV6_RELEASE: - rsp = processRelease(query, ctx); - break; - case DHCPV6_DECLINE: - rsp = processDecline(query, ctx); + sanityCheck(query, MANDATORY, MANDATORY); break; case DHCPV6_INFORMATION_REQUEST: - rsp = processInfRequest(query); - break; - case DHCPV6_DHCPV4_QUERY: - processDhcp4Query(query); + sanityCheck(query, OPTIONAL, OPTIONAL); break; default: @@ -713,6 +691,64 @@ Dhcpv6Srv::processPacket(Pkt6Ptr& query, Pkt6Ptr& rsp, bool allow_packet_park) { // Increase the statistic of dropped packets. StatsMgr::instance().addValue("pkt6-receive-drop", static_cast(1)); + return; + } + + if (query->getType() == DHCPV6_DHCPV4_QUERY) { + processDhcp4Query(query); + return; + } + + // Let's create a simplified client context here. + AllocEngine::ClientContext6 ctx; + bool drop = false; + initContext(query, ctx, drop); + + // Stop here if initContext decided to drop the packet. + if (drop) { + return; + } + + // Park point here. + + try { + switch (query->getType()) { + case DHCPV6_SOLICIT: + rsp = processSolicit(query, ctx); + break; + + case DHCPV6_REQUEST: + rsp = processRequest(query, ctx); + break; + + case DHCPV6_RENEW: + rsp = processRenew(query, ctx); + break; + + case DHCPV6_REBIND: + rsp = processRebind(query, ctx); + break; + + case DHCPV6_CONFIRM: + rsp = processConfirm(query, ctx); + break; + + case DHCPV6_RELEASE: + rsp = processRelease(query, ctx); + break; + + case DHCPV6_DECLINE: + rsp = processDecline(query, ctx); + break; + + case DHCPV6_INFORMATION_REQUEST: + rsp = processInfRequest(query, ctx); + break; + + default: + return; + } + } catch (const std::exception& e) { // Catch-all exception (at least for ones based on the isc Exception @@ -765,7 +801,8 @@ Dhcpv6Srv::processPacket(Pkt6Ptr& query, Pkt6Ptr& rsp, bool allow_packet_park) { bool packet_park = false; - if (ctx && HooksManager::calloutsPresent(Hooks.hook_index_leases6_committed_)) { + if (ctx.committed_ && + HooksManager::calloutsPresent(Hooks.hook_index_leases6_committed_)) { CalloutHandlePtr callout_handle = getCalloutHandle(query); // Delete all previous arguments @@ -780,15 +817,34 @@ Dhcpv6Srv::processPacket(Pkt6Ptr& query, Pkt6Ptr& rsp, bool allow_packet_park) { callout_handle->setArgument("query6", query); Lease6CollectionPtr new_leases(new Lease6Collection()); - if (ctx->new_lease_) { - new_leases->push_back(ctx->new_lease_); + if (!ctx.new_leases_.empty()) { + new_leases->assign(ctx.new_leases_.cbegin(), + ctx.new_leases_.cend()); } callout_handle->setArgument("leases6", new_leases); + // Two points: check only address? avoid duplicates in deleted_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_); + for (auto const iac : ctx.ias_) { + if (!iac.old_leases_.empty()) { + for (auto old_lease : iac.old_leases_) { + if (ctx.new_leases_.empty()) { + deleted_leases->push_back(old_lease); + continue; + } + bool in_new = false; + for (auto const new_lease : ctx.new_leases_) { + if ((new_lease->addr_ == old_lease->addr_) && + (new_lease->prefixlen_ == old_lease->prefixlen_)) { + in_new = true; + break; + } + } + if (in_new) { + continue; + } + deleted_leases->push_back(old_lease); + } } } callout_handle->setArgument("deleted_leases6", deleted_leases); @@ -803,8 +859,7 @@ Dhcpv6Srv::processPacket(Pkt6Ptr& query, Pkt6Ptr& rsp, bool allow_packet_park) { .arg(query->getLabel()); rsp.reset(); - } else if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_PARK) - && allow_packet_park) { + } else if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_PARK) { packet_park = true; } } @@ -2616,19 +2671,8 @@ Dhcpv6Srv::releaseIA_PD(const DuidPtr& duid, const Pkt6Ptr& query, Pkt6Ptr -Dhcpv6Srv::processSolicit(const Pkt6Ptr& solicit) { - - sanityCheck(solicit, MANDATORY, FORBIDDEN); - - // Let's create a simplified client context here. - AllocEngine::ClientContext6 ctx; - bool drop = false; - initContext(solicit, ctx, drop); - - // Stop here if initContext decided to drop the packet. - if (drop) { - return (Pkt6Ptr()); - } +Dhcpv6Srv::processSolicit(const Pkt6Ptr& solicit, + AllocEngine::ClientContext6& ctx) { Pkt6Ptr response(new Pkt6(DHCPV6_ADVERTISE, solicit->getTransid())); @@ -2673,21 +2717,7 @@ Dhcpv6Srv::processSolicit(const Pkt6Ptr& solicit) { Pkt6Ptr Dhcpv6Srv::processRequest(const Pkt6Ptr& request, - AllocEngine::ClientContext6Ptr& context) { - - sanityCheck(request, MANDATORY, MANDATORY); - - // Let's create a simplified client context here. - 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()); - } + AllocEngine::ClientContext6& ctx) { Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, request->getTransid())); @@ -2708,26 +2738,14 @@ Dhcpv6Srv::processRequest(const Pkt6Ptr& request, generateFqdn(reply); createNameChangeRequests(reply, ctx); + ctx.committed_ = true; + return (reply); } Pkt6Ptr Dhcpv6Srv::processRenew(const Pkt6Ptr& renew, - AllocEngine::ClientContext6Ptr& context) { - - sanityCheck(renew, MANDATORY, MANDATORY); - - // Let's create a simplified client context here. - 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()); - } + AllocEngine::ClientContext6& ctx) { Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, renew->getTransid())); @@ -2748,26 +2766,14 @@ Dhcpv6Srv::processRenew(const Pkt6Ptr& renew, generateFqdn(reply); createNameChangeRequests(reply, ctx); + ctx.committed_ = true; + return (reply); } Pkt6Ptr Dhcpv6Srv::processRebind(const Pkt6Ptr& rebind, - AllocEngine::ClientContext6Ptr& context) { - - sanityCheck(rebind, MANDATORY, FORBIDDEN); - - // Let's create a simplified client context here. - 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()); - } + AllocEngine::ClientContext6& ctx) { Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, rebind->getTransid())); @@ -2788,23 +2794,14 @@ Dhcpv6Srv::processRebind(const Pkt6Ptr& rebind, generateFqdn(reply); createNameChangeRequests(reply, ctx); + ctx.committed_ = true; + return (reply); } Pkt6Ptr -Dhcpv6Srv::processConfirm(const Pkt6Ptr& confirm) { - - sanityCheck(confirm, MANDATORY, FORBIDDEN); - - // Let's create a simplified client context here. - AllocEngine::ClientContext6 ctx; - bool drop = false; - initContext(confirm, ctx, drop); - - // Stop here if initContext decided to drop the packet. - if (drop) { - return (Pkt6Ptr()); - } +Dhcpv6Srv::processConfirm(const Pkt6Ptr& confirm, + AllocEngine::ClientContext6& ctx) { setReservedClientClasses(confirm, ctx); requiredClassify(confirm, ctx); @@ -2894,28 +2891,18 @@ Dhcpv6Srv::processConfirm(const Pkt6Ptr& confirm) { Pkt6Ptr Dhcpv6Srv::processRelease(const Pkt6Ptr& release, - AllocEngine::ClientContext6Ptr& context) { - - sanityCheck(release, MANDATORY, MANDATORY); - - // Let's create a simplified client context here. - 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()); - } + AllocEngine::ClientContext6& ctx) { setReservedClientClasses(release, ctx); requiredClassify(release, ctx); + // Create an empty Reply message. Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, release->getTransid())); + // Copy client options (client-id, also relay information if present) copyClientOptions(release, reply); + + // Get the configured option list CfgOptionList co_list; // buildCfgOptionList(release, ctx, co_list); appendDefaultOptions(release, reply, co_list); @@ -2925,27 +2912,14 @@ Dhcpv6Srv::processRelease(const Pkt6Ptr& release, /// @todo If client sent a release and we should remove outstanding /// DNS records. + ctx.committed_ = true; + return (reply); } Pkt6Ptr Dhcpv6Srv::processDecline(const Pkt6Ptr& decline, - AllocEngine::ClientContext6Ptr& context) { - - // Do sanity check. - sanityCheck(decline, MANDATORY, MANDATORY); - - // Let's create a simplified client context here. - 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()); - } + AllocEngine::ClientContext6& ctx) { setReservedClientClasses(decline, ctx); requiredClassify(decline, ctx); @@ -2964,12 +2938,12 @@ Dhcpv6Srv::processDecline(const Pkt6Ptr& decline, appendDefaultOptions(decline, reply, co_list); if (declineLeases(decline, reply, ctx)) { + ctx.committed_ = true; return (reply); } else { // declineLeases returns false only if the hooks set the next step // status to DROP. We'll just doing as requested. - context.reset(); return (Pkt6Ptr()); } } @@ -3120,7 +3094,7 @@ Dhcpv6Srv::declineIA(const Pkt6Ptr& decline, const DuidPtr& duid, } // Ok, all is good. Decline this lease. - if (!declineLease(decline, lease, ia_rsp, ctx)) { + if (!declineLease(decline, lease, ia_rsp)) { // declineLease returns false only when hook callouts set the next // step status to drop. We just propagate the bad news here. return (OptionPtr()); @@ -3147,8 +3121,7 @@ Dhcpv6Srv::setStatusCode(boost::shared_ptr& container, bool Dhcpv6Srv::declineLease(const Pkt6Ptr& decline, const Lease6Ptr lease, - boost::shared_ptr ia_rsp, - AllocEngine::ClientContext6& ctx) { + boost::shared_ptr ia_rsp) { // 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 @@ -3217,8 +3190,6 @@ 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_); @@ -3229,19 +3200,8 @@ Dhcpv6Srv::declineLease(const Pkt6Ptr& decline, const Lease6Ptr lease, } Pkt6Ptr -Dhcpv6Srv::processInfRequest(const Pkt6Ptr& inf_request) { - - sanityCheck(inf_request, OPTIONAL, OPTIONAL); - - // Let's create a simplified client context here. - AllocEngine::ClientContext6 ctx; - bool drop = false; - initContext(inf_request, ctx, drop); - - // Stop here if initContext decided to drop the packet. - if (drop) { - return (Pkt6Ptr()); - } +Dhcpv6Srv::processInfRequest(const Pkt6Ptr& inf_request, + AllocEngine::ClientContext6& ctx) { setReservedClientClasses(inf_request, ctx); requiredClassify(inf_request, ctx); @@ -3273,8 +3233,6 @@ Dhcpv6Srv::processInfRequest(const Pkt6Ptr& inf_request) { void Dhcpv6Srv::processDhcp4Query(const Pkt6Ptr& dhcp4_query) { - sanityCheck(dhcp4_query, OPTIONAL, OPTIONAL); - // flags are in transid // uint32_t flags = dhcp4_query->getTransid(); // do nothing with DHCPV4_QUERY_FLAGS_UNICAST @@ -3282,8 +3240,13 @@ Dhcpv6Srv::processDhcp4Query(const Pkt6Ptr& dhcp4_query) { // Get the DHCPv4 message option OptionPtr dhcp4_msg = dhcp4_query->getOption(D6O_DHCPV4_MSG); if (dhcp4_msg) { - // Forward the whole message to the DHCPv4 server via IPC - Dhcp6to4Ipc::instance().send(dhcp4_query); + try { + // Forward the whole message to the DHCPv4 server via IPC + Dhcp6to4Ipc::instance().send(dhcp4_query); + } catch (const std::exception&) { + // Assume the error was already logged + return; + } } // This method does not return anything as we always sent back diff --git a/src/bin/dhcp6/dhcp6_srv.h b/src/bin/dhcp6/dhcp6_srv.h index 55e07e21d1..a032f986cf 100644 --- a/src/bin/dhcp6/dhcp6_srv.h +++ b/src/bin/dhcp6/dhcp6_srv.h @@ -122,9 +122,7 @@ public: /// /// @param query A pointer to the packet to be processed. /// @param rsp A pointer to the response - /// @param allow_packet_park Indicates if parking a packet is allowed. - void processPacket(Pkt6Ptr& query, Pkt6Ptr& rsp, - bool allow_packet_park = true); + void processPacket(Pkt6Ptr& query, Pkt6Ptr& rsp); /// @brief Instructs the server to shut down. void shutdown(); @@ -219,9 +217,11 @@ protected: /// immediately. /// /// @param solicit Solicit message received from client + /// @param ctx Reference to client context /// /// @return Advertise, Reply message or NULL. - Pkt6Ptr processSolicit(const Pkt6Ptr& solicit); + Pkt6Ptr processSolicit(const Pkt6Ptr& solicit, + AllocEngine::ClientContext6& ctx); /// @brief Processes incoming Request and returns Reply response. /// @@ -232,21 +232,20 @@ protected: /// leases. /// /// @param request a message received from client - /// @param [out] context pointer to the client context where allocated - /// and deleted leases are stored. + /// @param ctx Reference to client context /// /// @return REPLY message or NULL Pkt6Ptr processRequest(const Pkt6Ptr& request, - AllocEngine::ClientContext6Ptr& context); + AllocEngine::ClientContext6& ctx); /// @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. + /// @param ctx Reference to client context + /// /// @return Reply message to be sent to the client. Pkt6Ptr processRenew(const Pkt6Ptr& renew, - AllocEngine::ClientContext6Ptr& context); + AllocEngine::ClientContext6& ctx); /// @brief Processes incoming Rebind message. /// @@ -257,11 +256,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. + /// @param ctx Reference to client context + /// /// @return Reply message to be sent to the client. Pkt6Ptr processRebind(const Pkt6Ptr& rebind, - AllocEngine::ClientContext6Ptr& context); + AllocEngine::ClientContext6& ctx); /// @brief Processes incoming Confirm message and returns Reply. /// @@ -283,19 +282,21 @@ protected: /// status code Success is returned. /// /// @param confirm Confirm message sent by a client. + /// @param ctx Reference to client context /// /// @return Reply message from the server or NULL pointer if Confirm /// message should be discarded by the server. - Pkt6Ptr processConfirm(const Pkt6Ptr& confirm); + Pkt6Ptr processConfirm(const Pkt6Ptr& confirm, + AllocEngine::ClientContext6& ctx); /// @brief Process incoming Release message. /// /// @param release message received from client - /// @param [out] context pointer to the client context where released - /// leases are stored. + /// @param ctx Reference to client context + /// /// @return Reply message to be sent to the client. Pkt6Ptr processRelease(const Pkt6Ptr& release, - AllocEngine::ClientContext6Ptr& context); + AllocEngine::ClientContext6& ctx); /// @brief Process incoming Decline message. /// @@ -304,20 +305,21 @@ protected: /// the client's message. Finally, it calls @ref declineLeases, where /// the actual address processing takes place. /// - /// @throw RFCViolation if Decline message is invalid (lacking mandatory - /// options) - /// /// @param decline message received from client - /// @param [out] context pointer to the client context where declined - /// leases are stored. + /// @param ctx Reference to client context + /// + /// @return Reply message to be sent to the client. Pkt6Ptr processDecline(const Pkt6Ptr& decline, - AllocEngine::ClientContext6Ptr& context); + AllocEngine::ClientContext6& ctx); /// @brief Processes incoming Information-request message. /// /// @param inf_request message received from client + /// @param ctx Reference to client context + /// /// @return Reply message to be sent to the client. - Pkt6Ptr processInfRequest(const Pkt6Ptr& inf_request); + Pkt6Ptr processInfRequest(const Pkt6Ptr& inf_request, + AllocEngine::ClientContext6& ctx); /// @brief Processes incoming DHCPv4-query message. /// @@ -327,6 +329,7 @@ protected: /// to the client once we get back DHCP4-REPLY from the DHCPv4 server. /// /// @param dhcp4_query message received from client + /// Does not throw void processDhcp4Query(const Pkt6Ptr& dhcp4_query); /// @brief Selects a subnet for a given client's packet. diff --git a/src/bin/dhcp6/dhcp6to4_ipc.cc b/src/bin/dhcp6/dhcp6to4_ipc.cc index 8704288ad7..ecde188d59 100644 --- a/src/bin/dhcp6/dhcp6to4_ipc.cc +++ b/src/bin/dhcp6/dhcp6to4_ipc.cc @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -99,9 +100,9 @@ void Dhcp6to4Ipc::handler() { } // Can't call the pkt6_send callout because we don't have the query - - ControlledDhcpv4Srv::getInstance()-> - processPacketBufferSend(getCalloutHandle(pkt), pkt); + CalloutHandlePtr callout_handle = getCalloutHandle(pkt); + ControlledDhcpv6Srv::getInstance()-> + processPacketBufferSend(callout_handle, pkt); } }; // namespace dhcp diff --git a/src/bin/dhcp6/tests/classify_unittests.cc b/src/bin/dhcp6/tests/classify_unittests.cc index d99b5fcd5f..962759bb1b 100644 --- a/src/bin/dhcp6/tests/classify_unittests.cc +++ b/src/bin/dhcp6/tests/classify_unittests.cc @@ -429,9 +429,19 @@ TEST_F(ClassifyTest, matchClassification) { EXPECT_TRUE(query3->inClass("router")); // Process queries - Pkt6Ptr response1 = srv.processSolicit(query1); - Pkt6Ptr response2 = srv.processSolicit(query2); - Pkt6Ptr response3 = srv.processSolicit(query3); + AllocEngine::ClientContext6 ctx1; + bool drop = false; + srv.initContext(query1, ctx1, drop); + ASSERT_FALSE(drop); + Pkt6Ptr response1 = srv.processSolicit(query1, ctx1); + AllocEngine::ClientContext6 ctx2; + srv.initContext(query2, ctx2, drop); + ASSERT_FALSE(drop); + Pkt6Ptr response2 = srv.processSolicit(query2, ctx2); + AllocEngine::ClientContext6 ctx3; + srv.initContext(query3, ctx3, drop); + ASSERT_FALSE(drop); + Pkt6Ptr response3 = srv.processSolicit(query3, ctx3); // Classification processing should add an ip-forwarding option OptionPtr opt1 = response1->getOption(2345); @@ -522,9 +532,19 @@ TEST_F(ClassifyTest, required) { EXPECT_FALSE(query3->inClass("router")); // Process queries - Pkt6Ptr response1 = srv.processSolicit(query1); - Pkt6Ptr response2 = srv.processSolicit(query2); - Pkt6Ptr response3 = srv.processSolicit(query3); + AllocEngine::ClientContext6 ctx1; + bool drop = false; + srv.initContext(query1, ctx1, drop); + ASSERT_FALSE(drop); + Pkt6Ptr response1 = srv.processSolicit(query1, ctx1); + AllocEngine::ClientContext6 ctx2; + srv.initContext(query2, ctx2, drop); + ASSERT_FALSE(drop); + Pkt6Ptr response2 = srv.processSolicit(query2, ctx2); + AllocEngine::ClientContext6 ctx3; + srv.initContext(query3, ctx3, drop); + ASSERT_FALSE(drop); + Pkt6Ptr response3 = srv.processSolicit(query3, ctx3); // Classification processing should do nothing OptionPtr opt1 = response1->getOption(2345); @@ -612,9 +632,19 @@ TEST_F(ClassifyTest, requiredClassification) { EXPECT_FALSE(query3->inClass("router")); // Process queries - Pkt6Ptr response1 = srv.processSolicit(query1); - Pkt6Ptr response2 = srv.processSolicit(query2); - Pkt6Ptr response3 = srv.processSolicit(query3); + AllocEngine::ClientContext6 ctx1; + bool drop = false; + srv.initContext(query1, ctx1, drop); + ASSERT_FALSE(drop); + Pkt6Ptr response1 = srv.processSolicit(query1, ctx1); + AllocEngine::ClientContext6 ctx2; + srv.initContext(query2, ctx2, drop); + ASSERT_FALSE(drop); + Pkt6Ptr response2 = srv.processSolicit(query2, ctx2); + AllocEngine::ClientContext6 ctx3; + srv.initContext(query3, ctx3, drop); + ASSERT_FALSE(drop); + Pkt6Ptr response3 = srv.processSolicit(query3, ctx3); // Classification processing should add an ip-forwarding option OptionPtr opt1 = response1->getOption(2345); @@ -688,7 +718,11 @@ TEST_F(ClassifyTest, subnetClassPriority) { EXPECT_TRUE(query->inClass("router")); // Process the query - Pkt6Ptr response = srv.processSolicit(query); + AllocEngine::ClientContext6 ctx; + bool drop = false; + srv.initContext(query, ctx, drop); + ASSERT_FALSE(drop); + Pkt6Ptr response = srv.processSolicit(query, ctx); // Processing should add an ip-forwarding option OptionPtr opt = response->getOption(2345); @@ -749,7 +783,11 @@ TEST_F(ClassifyTest, subnetGlobalPriority) { query->addOption(hostname); // Process the query - Pkt6Ptr response = srv.processSolicit(query); + AllocEngine::ClientContext6 ctx; + bool drop = false; + srv.initContext(query, ctx, drop); + ASSERT_FALSE(drop); + Pkt6Ptr response = srv.processSolicit(query, ctx); // Processing should add an ip-forwarding option OptionPtr opt = response->getOption(2345); @@ -819,7 +857,11 @@ TEST_F(ClassifyTest, classGlobalPriority) { EXPECT_TRUE(query->inClass("router")); // Process the query - Pkt6Ptr response = srv.processSolicit(query); + AllocEngine::ClientContext6 ctx; + bool drop = false; + srv.initContext(query, ctx, drop); + ASSERT_FALSE(drop); + Pkt6Ptr response = srv.processSolicit(query, ctx); // Processing should add an ip-forwarding option OptionPtr opt = response->getOption(2345); @@ -882,7 +924,11 @@ TEST_F(ClassifyTest, classGlobalPersistency) { query->addOption(hostname); // Process the query - Pkt6Ptr response = srv.processSolicit(query); + AllocEngine::ClientContext6 ctx; + bool drop = false; + srv.initContext(query, ctx, drop); + ASSERT_FALSE(drop); + Pkt6Ptr response = srv.processSolicit(query, ctx); // Processing should add an ip-forwarding option OptionPtr opt = response->getOption(2345); @@ -999,7 +1045,11 @@ TEST_F(ClassifyTest, clientClassifyPool) { // This discover does not belong to foo class, so it will not // be serviced srv.classifyPacket(query1); - Pkt6Ptr response1 = srv.processSolicit(query1); + AllocEngine::ClientContext6 ctx1; + bool drop = false; + srv.initContext(query1, ctx1, drop); + ASSERT_FALSE(drop); + Pkt6Ptr response1 = srv.processSolicit(query1, ctx1); ASSERT_TRUE(response1); OptionPtr ia_na1 = response1->getOption(D6O_IA_NA); ASSERT_TRUE(ia_na1); @@ -1010,7 +1060,10 @@ TEST_F(ClassifyTest, clientClassifyPool) { query2->addClass("bar"); // Still not supported, because it belongs to wrong class. srv.classifyPacket(query2); - Pkt6Ptr response2 = srv.processSolicit(query2); + AllocEngine::ClientContext6 ctx2; + srv.initContext(query2, ctx2, drop); + ASSERT_FALSE(drop); + Pkt6Ptr response2 = srv.processSolicit(query2, ctx2); ASSERT_TRUE(response2); OptionPtr ia_na2 = response2->getOption(D6O_IA_NA); ASSERT_TRUE(ia_na2); @@ -1021,7 +1074,10 @@ TEST_F(ClassifyTest, clientClassifyPool) { query3->addClass("foo"); // This time it should work srv.classifyPacket(query3); - Pkt6Ptr response3 = srv.processSolicit(query3); + AllocEngine::ClientContext6 ctx3; + srv.initContext(query3, ctx3, drop); + ASSERT_FALSE(drop); + Pkt6Ptr response3 = srv.processSolicit(query3, ctx3); ASSERT_TRUE(response3); OptionPtr ia_na3 = response3->getOption(D6O_IA_NA); ASSERT_TRUE(ia_na3); @@ -1306,9 +1362,19 @@ TEST_F(ClassifyTest, member) { EXPECT_TRUE(query3->inClass("barz")); // Process queries - Pkt6Ptr response1 = srv.processSolicit(query1); - Pkt6Ptr response2 = srv.processSolicit(query2); - Pkt6Ptr response3 = srv.processSolicit(query3); + AllocEngine::ClientContext6 ctx1; + bool drop = false; + srv.initContext(query1, ctx1, drop); + ASSERT_FALSE(drop); + Pkt6Ptr response1 = srv.processSolicit(query1, ctx1); + AllocEngine::ClientContext6 ctx2; + srv.initContext(query2, ctx2, drop); + ASSERT_FALSE(drop); + Pkt6Ptr response2 = srv.processSolicit(query2, ctx2); + AllocEngine::ClientContext6 ctx3; + srv.initContext(query3, ctx3, drop); + ASSERT_FALSE(drop); + Pkt6Ptr response3 = srv.processSolicit(query3, ctx3); // Classification processing should add an ip-forwarding option OptionPtr opt1 = response1->getOption(2345); diff --git a/src/bin/dhcp6/tests/confirm_unittest.cc b/src/bin/dhcp6/tests/confirm_unittest.cc index ba8db9c61f..8d3a7ab5a6 100644 --- a/src/bin/dhcp6/tests/confirm_unittest.cc +++ b/src/bin/dhcp6/tests/confirm_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2014-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 @@ -96,16 +96,19 @@ TEST_F(ConfirmTest, sanityCheck) { // A message with no client-id should fail Pkt6Ptr confirm = Pkt6Ptr(new Pkt6(DHCPV6_CONFIRM, 1234)); - EXPECT_THROW(srv.processConfirm(confirm), RFCViolation); + EXPECT_THROW(srv.sanityCheck(confirm, Dhcpv6Srv::MANDATORY, + Dhcpv6Srv::FORBIDDEN), RFCViolation); // A message with a single client-id should succeed OptionPtr clientid = generateClientId(); confirm->addOption(clientid); - EXPECT_NO_THROW(srv.processConfirm(confirm)); + EXPECT_NO_THROW(srv.sanityCheck(confirm, Dhcpv6Srv::MANDATORY, + Dhcpv6Srv::FORBIDDEN)); // A message with server-id present should fail confirm->addOption(srv.getServerID()); - EXPECT_THROW(srv.processConfirm(confirm), RFCViolation); + EXPECT_THROW(srv.sanityCheck(confirm, Dhcpv6Srv::MANDATORY, + Dhcpv6Srv::FORBIDDEN), RFCViolation); } // Test that directly connected client's Confirm message is processed and Reply diff --git a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc index b4d4a0dec8..f3893b7099 100644 --- a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc +++ b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc @@ -164,7 +164,11 @@ TEST_F(NakedDhcpv6SrvTest, SolicitNoSubnet) { sol->addOption(clientid); // Pass it to the server and get an advertise - Pkt6Ptr reply = srv.processSolicit(sol); + AllocEngine::ClientContext6 ctx; + bool drop = false; + srv.initContext(sol, ctx, drop); + ASSERT_FALSE(drop); + Pkt6Ptr reply = srv.processSolicit(sol, ctx); // check that we get the right NAK checkNakResponse(reply, DHCPV6_ADVERTISE, 1234, STATUS_NoAddrsAvail, @@ -385,7 +389,11 @@ TEST_F(Dhcpv6SrvTest, advertiseOptions) { sol->addOption(clientid); // Pass it to the server and get an advertise - Pkt6Ptr adv = srv_.processSolicit(sol); + AllocEngine::ClientContext6 ctx; + bool drop = false; + srv_.initContext(sol, ctx, drop); + ASSERT_FALSE(drop); + Pkt6Ptr adv = srv_.processSolicit(sol, ctx); // check if we get response at all ASSERT_TRUE(adv); @@ -409,7 +417,10 @@ TEST_F(Dhcpv6SrvTest, advertiseOptions) { sol->addOption(option_oro); // Need to process SOLICIT again after requesting new option. - adv = srv_.processSolicit(sol); + AllocEngine::ClientContext6 ctx2; + srv_.initContext(sol, ctx2, drop); + ASSERT_FALSE(drop); + adv = srv_.processSolicit(sol, ctx2); ASSERT_TRUE(adv); OptionPtr tmp = adv->getOption(D6O_NAME_SERVERS); @@ -470,7 +481,11 @@ TEST_F(Dhcpv6SrvTest, SolicitBasic) { sol->addOption(clientid); // Pass it to the server and get an advertise - Pkt6Ptr reply = srv.processSolicit(sol); + AllocEngine::ClientContext6 ctx; + bool drop = false; + srv.initContext(sol, ctx, drop); + ASSERT_FALSE(drop); + Pkt6Ptr reply = srv.processSolicit(sol, ctx); // check if we get response at all checkResponse(reply, DHCPV6_ADVERTISE, 1234); @@ -514,7 +529,11 @@ TEST_F(Dhcpv6SrvTest, pdSolicitBasic) { sol->addOption(clientid); // Pass it to the server and get an advertise - Pkt6Ptr reply = srv.processSolicit(sol); + AllocEngine::ClientContext6 ctx; + bool drop = false; + srv.initContext(sol, ctx, drop); + ASSERT_FALSE(drop); + Pkt6Ptr reply = srv.processSolicit(sol, ctx); // check if we get response at all checkResponse(reply, DHCPV6_ADVERTISE, 1234); @@ -567,7 +586,11 @@ TEST_F(Dhcpv6SrvTest, SolicitHint) { sol->addOption(clientid); // Pass it to the server and get an advertise - Pkt6Ptr reply = srv.processSolicit(sol); + AllocEngine::ClientContext6 ctx; + bool drop = false; + srv.initContext(sol, ctx, drop); + ASSERT_FALSE(drop); + Pkt6Ptr reply = srv.processSolicit(sol, ctx); // check if we get response at all checkResponse(reply, DHCPV6_ADVERTISE, 1234); @@ -620,7 +643,11 @@ TEST_F(Dhcpv6SrvTest, SolicitInvalidHint) { sol->addOption(clientid); // Pass it to the server and get an advertise - Pkt6Ptr reply = srv.processSolicit(sol); + AllocEngine::ClientContext6 ctx; + bool drop = false; + srv.initContext(sol, ctx, drop); + ASSERT_FALSE(drop); + Pkt6Ptr reply = srv.processSolicit(sol, ctx); // check if we get response at all checkResponse(reply, DHCPV6_ADVERTISE, 1234); @@ -678,9 +705,19 @@ TEST_F(Dhcpv6SrvTest, ManySolicits) { sol3->addOption(clientid3); // Pass it to the server and get an advertise - Pkt6Ptr reply1 = srv.processSolicit(sol1); - Pkt6Ptr reply2 = srv.processSolicit(sol2); - Pkt6Ptr reply3 = srv.processSolicit(sol3); + AllocEngine::ClientContext6 ctx1; + bool drop = false; + srv.initContext(sol1, ctx1, drop); + ASSERT_FALSE(drop); + Pkt6Ptr reply1 = srv.processSolicit(sol1, ctx1); + AllocEngine::ClientContext6 ctx2; + srv.initContext(sol2, ctx2, drop); + ASSERT_FALSE(drop); + Pkt6Ptr reply2 = srv.processSolicit(sol2, ctx2); + AllocEngine::ClientContext6 ctx3; + srv.initContext(sol3, ctx3, drop); + ASSERT_FALSE(drop); + Pkt6Ptr reply3 = srv.processSolicit(sol3, ctx3); // check if we get response at all checkResponse(reply1, DHCPV6_ADVERTISE, 1234); @@ -1685,7 +1722,11 @@ TEST_F(Dhcpv6SrvTest, prlPersistency) { sol->addOption(oro); // Let the server process it and generate a response. - Pkt6Ptr response = srv_.processSolicit(sol); + AllocEngine::ClientContext6 ctx; + bool drop = false; + srv_.initContext(sol, ctx, drop); + ASSERT_FALSE(drop); + Pkt6Ptr response = srv_.processSolicit(sol, ctx); // The server should add a subscriber-id option ASSERT_TRUE(response->getOption(D6O_SUBSCRIBER_ID)); @@ -1701,7 +1742,10 @@ TEST_F(Dhcpv6SrvTest, prlPersistency) { // Let the server process it again. This time the name-servers // option should be present. - response = srv_.processSolicit(sol); + AllocEngine::ClientContext6 ctx2; + srv_.initContext(sol, ctx2, drop); + ASSERT_FALSE(drop); + response = srv_.processSolicit(sol, ctx2); // Processing should add a subscriber-id option ASSERT_TRUE(response->getOption(D6O_SUBSCRIBER_ID)); @@ -1836,7 +1880,11 @@ TEST_F(Dhcpv6SrvTest, vendorOptionsORO) { sol->addOption(clientid); // Pass it to the server and get an advertise - Pkt6Ptr adv = srv_.processSolicit(sol); + AllocEngine::ClientContext6 ctx; + bool drop = false; + srv_.initContext(sol, ctx, drop); + ASSERT_FALSE(drop); + Pkt6Ptr adv = srv_.processSolicit(sol, ctx); // check if we get response at all ASSERT_TRUE(adv); @@ -1855,7 +1903,10 @@ TEST_F(Dhcpv6SrvTest, vendorOptionsORO) { sol->addOption(vendor); // Need to process SOLICIT again after requesting new option. - adv = srv_.processSolicit(sol); + AllocEngine::ClientContext6 ctx2; + srv_.initContext(sol, ctx2, drop); + ASSERT_FALSE(drop); + adv = srv_.processSolicit(sol, ctx2); ASSERT_TRUE(adv); // Check if there is vendor option response @@ -1925,7 +1976,11 @@ TEST_F(Dhcpv6SrvTest, vendorPersistentOptions) { sol->addOption(vendor); // Pass it to the server and get an advertise - Pkt6Ptr adv = srv_.processSolicit(sol); + AllocEngine::ClientContext6 ctx; + bool drop = false; + srv_.initContext(sol, ctx, drop); + ASSERT_FALSE(drop); + Pkt6Ptr adv = srv_.processSolicit(sol, ctx); // check if we get response at all ASSERT_TRUE(adv); diff --git a/src/bin/dhcp6/tests/dhcp6_test_utils.h b/src/bin/dhcp6/tests/dhcp6_test_utils.h index 52fe5a02a1..17e7c5a245 100644 --- a/src/bin/dhcp6/tests/dhcp6_test_utils.h +++ b/src/bin/dhcp6/tests/dhcp6_test_utils.h @@ -188,8 +188,8 @@ public: /// @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)); + AllocEngine::ClientContext6 ctx; + return (processRequest(request, ctx)); } /// @brief Processes incoming Renew message. @@ -197,8 +197,8 @@ public: /// @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)); + AllocEngine::ClientContext6 ctx; + return (processRenew(renew, ctx)); } /// @brief Processes incoming Rebind message. @@ -206,8 +206,8 @@ public: /// @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)); + AllocEngine::ClientContext6 ctx; + return (processRebind(rebind, ctx)); } /// @brief Processes incoming Release message. @@ -215,8 +215,8 @@ public: /// @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)); + AllocEngine::ClientContext6 ctx; + return (processRelease(release, ctx)); } /// @brief Processes incoming Decline message. @@ -224,8 +224,8 @@ public: /// @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)); + AllocEngine::ClientContext6 ctx; + return (processDecline(decline, ctx)); } using Dhcpv6Srv::processSolicit; diff --git a/src/bin/dhcp6/tests/fqdn_unittest.cc b/src/bin/dhcp6/tests/fqdn_unittest.cc index 250f3d0b58..969cbe3002 100644 --- a/src/bin/dhcp6/tests/fqdn_unittest.cc +++ b/src/bin/dhcp6/tests/fqdn_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 @@ -494,19 +494,23 @@ public: // For different client's message types we have to invoke different // functions to generate response. Pkt6Ptr reply; + AllocEngine::ClientContext6 ctx; + bool drop = false; + srv_->initContext(req, ctx, drop); + ASSERT_FALSE(drop); if (msg_type == DHCPV6_SOLICIT) { - ASSERT_NO_THROW(reply = srv_->processSolicit(req)); + ASSERT_NO_THROW(reply = srv_->processSolicit(req, ctx)); } else if (msg_type == DHCPV6_REQUEST) { - ASSERT_NO_THROW(reply = srv_->processRequest(req)); + ASSERT_NO_THROW(reply = srv_->processRequest(req, ctx)); } else if (msg_type == DHCPV6_RENEW) { - ASSERT_NO_THROW(reply = srv_->processRenew(req)); + ASSERT_NO_THROW(reply = srv_->processRenew(req, ctx)); } else if (msg_type == DHCPV6_RELEASE) { // For Release no lease will be acquired so we have to leave // function here. - ASSERT_NO_THROW(reply = srv_->processRelease(req)); + ASSERT_NO_THROW(reply = srv_->processRelease(req, ctx)); return; } else { // We are not interested in testing other message types. diff --git a/src/bin/dhcp6/tests/hooks_unittest.cc b/src/bin/dhcp6/tests/hooks_unittest.cc index a3ba0e2339..e211869292 100644 --- a/src/bin/dhcp6/tests/hooks_unittest.cc +++ b/src/bin/dhcp6/tests/hooks_unittest.cc @@ -954,7 +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_; +IOServicePtr HooksDhcpv6SrvTest::io_service_; string HooksDhcpv6SrvTest::callback_name_; Pkt6Ptr HooksDhcpv6SrvTest::callback_qry_pkt6_; Pkt6Ptr HooksDhcpv6SrvTest::callback_resp_pkt6_; @@ -1604,7 +1604,11 @@ TEST_F(HooksDhcpv6SrvTest, subnet6Select) { sol->addOption(clientid); // Pass it to the server and get an advertise - Pkt6Ptr adv = srv_->processSolicit(sol); + AllocEngine::ClientContext6 ctx; + bool drop = false; + srv_->initContext(sol, ctx, drop); + ASSERT_FALSE(drop); + Pkt6Ptr adv = srv_->processSolicit(sol, ctx); // Check if we get response at all ASSERT_TRUE(adv); @@ -1681,7 +1685,11 @@ TEST_F(HooksDhcpv6SrvTest, subnet6SselectChange) { sol->addOption(clientid); // Pass it to the server and get an advertise - Pkt6Ptr adv = srv_->processSolicit(sol); + AllocEngine::ClientContext6 ctx; + bool drop = false; + srv_->initContext(sol, ctx, drop); + ASSERT_FALSE(drop); + Pkt6Ptr adv = srv_->processSolicit(sol, ctx); // Check if we get response at all ASSERT_TRUE(adv); @@ -1731,6 +1739,47 @@ TEST_F(HooksDhcpv6SrvTest, subnet6SelectDrop) { ASSERT_EQ(0, srv_->fake_sent_.size()); } +// This test verifies that the leases6_committed hook point is not triggered +// for the SOLICIT. +TEST_F(HooksDhcpv6SrvTest, leases6CommittedSolicit) { + IfaceMgrTestConfig test_config(true); + + // Install leases6_committed callout + ASSERT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout( + "leases6_committed", leases6_committed_callout)); + + + Dhcp6Client client; + client.setInterface("eth1"); + ASSERT_NO_THROW(client.doSolicit()); + + // Make sure that we received a response + ASSERT_TRUE(client.getContext().response_); + + // Make sure that the callout wasn't called. + EXPECT_TRUE(callback_name_.empty()); +} + +// This test verifies that the leases6_committed hook point is not triggered +// for the INFREQUEST. +TEST_F(HooksDhcpv6SrvTest, leases6CommittedInfRequest) { + IfaceMgrTestConfig test_config(true); + + ASSERT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout( + "leases6_committed", leases6_committed_callout)); + + + Dhcp6Client client; + client.useRelay(); + ASSERT_NO_THROW(client.doInfRequest()); + + // Make sure that we received a response + ASSERT_TRUE(client.getContext().response_); + + // Make sure that the callout wasn't called. + EXPECT_TRUE(callback_name_.empty()); +} + // This test verifies that incoming (positive) RENEW can be handled properly, // and the lease6_renew callouts are triggered. TEST_F(HooksDhcpv6SrvTest, basicLease6Renew) { @@ -1997,6 +2046,191 @@ TEST_F(HooksDhcpv6SrvTest, skipLease6Renew) { EXPECT_NE(l->cltt_, time(NULL)); } +// This test verifies that the callout installed on the leases6_committed hook +// point is executed as a result of REQUEST message sent to allocate new +// lease or renew an existing lease. +TEST_F(HooksDhcpv6SrvTest, leases6CommittedRequest) { + IfaceMgrTestConfig test_config(true); + + ASSERT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout( + "leases6_committed", leases6_committed_callout)); + + + Dhcp6Client client; + client.setInterface("eth1"); + client.requestAddress(0xabca, IOAddress("2001:db8:1::28")); + ASSERT_NO_THROW(client.doSARR()); + + // Make sure that we received a response + ASSERT_TRUE(client.getContext().response_); + + // Check that the callback called is indeed the one we installed + EXPECT_EQ("leases6_committed", callback_name_); + + // Check if all expected parameters were really received + vector expected_argument_names; + expected_argument_names.push_back("query6"); + expected_argument_names.push_back("deleted_leases6"); + expected_argument_names.push_back("leases6"); + + sort(expected_argument_names.begin(), expected_argument_names.end()); + EXPECT_TRUE(callback_argument_names_ == expected_argument_names); + + // Newly allocated lease should be returned. + ASSERT_TRUE(callback_lease6_); + EXPECT_EQ("2001:db8:1::28", callback_lease6_->addr_.toText()); + + // Deleted lease must not be present, because it is a new allocation. + EXPECT_FALSE(callback_deleted_lease6_); + + // Pkt passed to a callout must be configured to copy retrieved options. + EXPECT_TRUE(callback_qry_options_copy_); + + resetCalloutBuffers(); + + // Renew the lease and make sure that the callout has been executed. + ASSERT_NO_THROW(client.doRenew()); + + // Make sure that we received a response + ASSERT_TRUE(client.getContext().response_); + + // Check that the callback called is indeed the one we installed + EXPECT_EQ("leases6_committed", callback_name_); + + // Renewed lease should be returned. + ASSERT_TRUE(callback_lease6_); + EXPECT_EQ("2001:db8:1::28", callback_lease6_->addr_.toText()); + + // Deleted lease must not be present, because it is a new allocation. + EXPECT_FALSE(callback_deleted_lease6_); + + // Pkt passed to a callout must be configured to copy retrieved options. + EXPECT_TRUE(callback_qry_options_copy_); + + resetCalloutBuffers(); + + // Let's try to renew again but force the client to request a different + // address. + client.requestAddress(0xabca, IOAddress("2001:db8:1::29")); + + ASSERT_NO_THROW(client.doRequest()); + + // Make sure that we received a response + ASSERT_TRUE(client.getContext().response_); + + // Check that the callback called is indeed the one we installed + EXPECT_EQ("leases6_committed", callback_name_); + + // New lease should be returned. + ASSERT_TRUE(callback_lease6_); + EXPECT_EQ("2001:db8:1::29", callback_lease6_->addr_.toText()); + + // The old lease should have been deleted. + ASSERT_TRUE(callback_deleted_lease6_); + EXPECT_EQ("2001:db8:1::28", callback_deleted_lease6_->addr_.toText()); + + // Pkt passed to a callout must be configured to copy retrieved options. + EXPECT_TRUE(callback_qry_options_copy_); + + resetCalloutBuffers(); + + // Now request an address that can't be allocated. The client should receive + // an error. + + client.requestAddress(0xabca, IOAddress("4000::2")); + //// client.ciaddr_ = IOAddress("10.0.0.1"); + + ASSERT_NO_THROW(client.doRequest()); + + // Make sure that we received a response + ASSERT_TRUE(client.getContext().response_); + + // Check that the callback called is indeed the one we installed + EXPECT_EQ("leases6_committed", callback_name_); + + EXPECT_FALSE(callback_lease6_); + EXPECT_FALSE(callback_deleted_lease6_); +} + +// This test verifies that it is possible to park a packet as a result of +// the leases6_committed callouts. +TEST_F(HooksDhcpv6SrvTest, leases6CommittedParkRequests) { + IfaceMgrTestConfig test_config(true); + + // This callout uses provided IO service object to post a function + // that unparks the packet. The packet is parked and can be unparked + // by simply calling IOService::poll. + ASSERT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout( + "leases6_committed", leases6_committed_park_callout)); + + // Create first client and perform DORA. + Dhcp6Client client1; + client1.setInterface("eth1"); + client1.requestAddress(0xabca, IOAddress("2001:db8:1::28")); + ASSERT_NO_THROW(client1.doSARR()); + + // We should be offered an address but the REPLY should not arrive + // at this point, because the packet is parked. + ASSERT_FALSE(client1.getContext().response_); + + // Check that the callback called is indeed the one we installed + EXPECT_EQ("leases6_committed", callback_name_); + + // Check if all expected parameters were really received + vector expected_argument_names; + expected_argument_names.push_back("query6"); + expected_argument_names.push_back("deleted_leases6"); + expected_argument_names.push_back("leases6"); + + sort(expected_argument_names.begin(), expected_argument_names.end()); + EXPECT_TRUE(callback_argument_names_ == expected_argument_names); + + // Newly allocated lease should be passed to the callout. + ASSERT_TRUE(callback_lease6_); + EXPECT_EQ("2001:db8:1::28", callback_lease6_->addr_.toText()); + + // Deleted lease must not be present, because it is a new allocation. + EXPECT_FALSE(callback_deleted_lease6_); + + // Pkt passed to a callout must be configured to copy retrieved options. + EXPECT_TRUE(callback_qry_options_copy_); + + // Reset all indicators because we'll be now creating a second client. + resetCalloutBuffers(); + + // Create the second client to test that it may communicate with the + // server while the previous packet is parked. + Dhcp6Client client2; + client2.setInterface("eth1"); + client2.requestAddress(0xabca, IOAddress("2001:db8:1::29")); + ASSERT_NO_THROW(client2.doSARR()); + + // The DHCPOFFER should have been returned but not DHCPACK, as this + // packet got parked too. + ASSERT_FALSE(client2.getContext().response_); + + // Check that the callback called is indeed the one we installed. + EXPECT_EQ("leases6_committed", callback_name_); + + // There should be now two actions scheduled on our IO service + // by the invoked callouts. They unpark both DHCPACK messages. + ASSERT_NO_THROW(io_service_->poll()); + + // Receive and check the first response. + ASSERT_NO_THROW(client1.receiveResponse()); + ASSERT_TRUE(client1.getContext().response_); + Pkt6Ptr rsp = client1.getContext().response_; + EXPECT_EQ(DHCPV6_REPLY, rsp->getType()); + //// EXPECT_EQ("2001:db8:1::28", rsp->getYiaddr().toText()); + + // Receive and check the second response. + ASSERT_NO_THROW(client2.receiveResponse()); + ASSERT_TRUE(client2.getContext().response_); + rsp = client2.getContext().response_; + EXPECT_EQ(DHCPV6_REPLY, rsp->getType()); + //// EXPECT_EQ("2001:db8:1::29", rsp->getYiaddr().toText()); +} + // This test verifies that incoming (positive) RELEASE can be handled properly, // that a REPLY is generated, that the response has status code and that the // lease is indeed removed from the database. @@ -2289,6 +2523,8 @@ TEST_F(HooksDhcpv6SrvTest, dropLease6Release) { ASSERT_TRUE(l); } +/// leases4CommittedRelease + // This test verifies that incoming (positive) REBIND can be handled properly, // and the lease6_rebind callouts are triggered. TEST_F(HooksDhcpv6SrvTest, basicLease6Rebind) { @@ -2543,6 +2779,8 @@ TEST_F(HooksDhcpv6SrvTest, skipLease6Rebind) { EXPECT_NE(l->cltt_, time(NULL)); } +/// leases4CommittedRebind + // This test checks that the basic decline hook (lease6_decline) is // triggered properly. TEST_F(HooksDhcpv6SrvTest, basicLease6Decline) { @@ -2686,6 +2924,8 @@ TEST_F(HooksDhcpv6SrvTest, lease6DeclineDrop) { EXPECT_EQ(Lease::STATE_DEFAULT, from_mgr->state_); } +/// leases4CommittedDecline + // Checks if callout installed on host6_identifier can generate an // identifier and whether that identifier is actually used. TEST_F(HooksDhcpv6SrvTest, host6Identifier) { @@ -2737,7 +2977,11 @@ TEST_F(HooksDhcpv6SrvTest, host6Identifier) { sol->addOption(clientid); // Pass it to the server and get an advertise - Pkt6Ptr adv = srv_->processSolicit(sol); + AllocEngine::ClientContext6 ctx; + bool drop = false; + srv_->initContext(sol, ctx, drop); + ASSERT_FALSE(drop); + Pkt6Ptr adv = srv_->processSolicit(sol, ctx); // Check if we get response at all ASSERT_TRUE(adv); @@ -2810,7 +3054,11 @@ TEST_F(HooksDhcpv6SrvTest, host6Identifier_hwaddr) { sol->addOption(clientid); // Pass it to the server and get an advertise - Pkt6Ptr adv = srv_->processSolicit(sol); + AllocEngine::ClientContext6 ctx; + bool drop = false; + srv_->initContext(sol, ctx, drop); + ASSERT_FALSE(drop); + Pkt6Ptr adv = srv_->processSolicit(sol, ctx); // Check if we get response at all ASSERT_TRUE(adv); @@ -2872,4 +3120,68 @@ TEST_F(LoadUnloadDhcpv6SrvTest, unloadLibraries) { } +// Checks if callouts installed on the dhcp6_srv_configured ared indeed called +// and all the necessary parameters are passed. +TEST_F(LoadUnloadDhcpv6SrvTest, Dhcpv6SrvConfigured) { + boost::shared_ptr srv(new ControlledDhcpv6Srv(0)); + + // Ensure no marker files to start with. + ASSERT_FALSE(checkMarkerFileExists(LOAD_MARKER_FILE)); + ASSERT_FALSE(checkMarkerFileExists(UNLOAD_MARKER_FILE)); + ASSERT_FALSE(checkMarkerFileExists(SRV_CONFIG_MARKER_FILE)); + + // Minimal valid configuration for the server. It includes the + // section which loads the callout library #3, which implements + // dhcp6_srv_configured callout. + std::string config_str = + "{" + " \"interfaces-config\": {" + " \"interfaces\": [ ]" + " }," + " \"preferred-lifetime\": 3000," + " \"rebind-timer\": 2000," + " \"renew-timer\": 1000," + " \"subnet6\": [ ]," + " \"valid-lifetime\": 4000," + " \"lease-database\": {" + " \"type\": \"memfile\"," + " \"persist\": false" + " }," + " \"hooks-libraries\": [" + " {" + " \"library\": \"" + std::string(CALLOUT_LIBRARY_3) + "\"" + " }" + " ]" + "}"; + + ConstElementPtr config = Element::fromJSON(config_str); + + // Configure the server. + ConstElementPtr answer; + ASSERT_NO_THROW(answer = srv->processConfig(config)); + + // Make sure there were no errors. + int status_code; + isc::config::parseAnswer(status_code, answer); + ASSERT_EQ(0, status_code); + + // The hook library should have been loaded. + EXPECT_TRUE(checkMarkerFile(LOAD_MARKER_FILE, "3")); + EXPECT_FALSE(checkMarkerFileExists(UNLOAD_MARKER_FILE)); + // The dhcp6_srv_configured should have been invoked and the provided + // parameters should be recorded. + EXPECT_TRUE(checkMarkerFile(SRV_CONFIG_MARKER_FILE, + "3io_contextjson_confignetwork_stateserver_config")); + + // Destroy the server, instance which should unload the libraries. + srv.reset(); + + // The server was destroyed, so the unload() function should now + // include the library number in its marker file. + EXPECT_TRUE(checkMarkerFile(LOAD_MARKER_FILE, "3")); + EXPECT_TRUE(checkMarkerFile(UNLOAD_MARKER_FILE, "3")); + EXPECT_TRUE(checkMarkerFile(SRV_CONFIG_MARKER_FILE, + "3io_contextjson_confignetwork_stateserver_config")); +} + } // end of anonymous namespace diff --git a/src/bin/dhcp6/tests/kea_controller_unittest.cc b/src/bin/dhcp6/tests/kea_controller_unittest.cc index f737051307..62ef1ba4fb 100644 --- a/src/bin/dhcp6/tests/kea_controller_unittest.cc +++ b/src/bin/dhcp6/tests/kea_controller_unittest.cc @@ -78,7 +78,7 @@ public: /// @param timeout_ms Amount of time after which the method returns. void runTimersWithTimeout(const IOServicePtr& io_service, const long timeout_ms) { IntervalTimer timer(*io_service); - timer.setup([this, &io_service]() { + timer.setup([&io_service]() { io_service->stop(); }, timeout_ms, IntervalTimer::ONE_SHOT); io_service->run(); diff --git a/src/bin/dhcp6/tests/shared_network_unittest.cc b/src/bin/dhcp6/tests/shared_network_unittest.cc index b3081aa9a5..7ffe9fc24d 100644 --- a/src/bin/dhcp6/tests/shared_network_unittest.cc +++ b/src/bin/dhcp6/tests/shared_network_unittest.cc @@ -1398,7 +1398,7 @@ public: IOAddress requested_address = exp_addr1.empty() ? IOAddress::IPV6_ZERO_ADDRESS() : IOAddress(exp_addr1); ASSERT_NO_THROW(client1.requestAddress(0xabca0, requested_address)); - testAssigned([this, &client1] { + testAssigned([&client1] { ASSERT_NO_THROW(client1.doSolicit()); }); @@ -1428,7 +1428,7 @@ public: // first subnet is already full (it's a really small subnet) and the second // subnet does not allow rapid-commit. ASSERT_NO_THROW(client2.requestAddress(0xabca0)); - testAssigned([this, &client2] { + testAssigned([&client2] { ASSERT_NO_THROW(client2.doSolicit()); }); @@ -1538,7 +1538,7 @@ TEST_F(Dhcpv6SharedNetworkTest, addressPoolInSharedNetworkShortage) { // Client #1 requests an address in first subnet within a shared network. ASSERT_NO_THROW(client1.requestAddress(0xabca0, IOAddress("2001:db8:1::20"))); - testAssigned([this, &client1] { + testAssigned([&client1] { ASSERT_NO_THROW(client1.doSARR()); }); ASSERT_TRUE(hasLeaseForAddress(client1, IOAddress("2001:db8:1::20"))); @@ -1548,7 +1548,7 @@ TEST_F(Dhcpv6SharedNetworkTest, addressPoolInSharedNetworkShortage) { Dhcp6Client client2(client1.getServer()); client2.setInterface("eth1"); ASSERT_NO_THROW(client2.requestAddress(0xabca0)); - testAssigned([this, &client2] { + testAssigned([&client2] { ASSERT_NO_THROW(client2.doSARR()); }); ASSERT_TRUE(hasLeaseForAddress(client2, IOAddress("2001:db8:2::20"))); @@ -1558,27 +1558,27 @@ TEST_F(Dhcpv6SharedNetworkTest, addressPoolInSharedNetworkShortage) { Dhcp6Client client3(client1.getServer()); client3.setInterface("eth1"); ASSERT_NO_THROW(client3.requestAddress(0xabca0)); - testAssigned([this, &client3] { + testAssigned([&client3] { ASSERT_NO_THROW(client3.doSolicit(true)); }); EXPECT_EQ(0, client3.getLeaseNum()); // Client #3 should be assigned an address if subnet 3 is selected for it. client3.setInterface("eth0"); - testAssigned([this, &client3] { + testAssigned([&client3] { ASSERT_NO_THROW(client3.doSolicit(true)); }); EXPECT_EQ(1, client3.getLeaseNum()); // Client #1 should be able to renew its lease. - testAssigned([this, &client1] { + testAssigned([&client1] { ASSERT_NO_THROW(client1.doRenew()); }); EXPECT_EQ(1, client1.getLeaseNum()); EXPECT_TRUE(hasLeaseForAddress(client1, IOAddress("2001:db8:1::20"))); // Client #2 should be able to renew its lease too. - testAssigned([this, &client2] { + testAssigned([&client2] { ASSERT_NO_THROW(client2.doRenew()); }); EXPECT_EQ(1, client2.getLeaseNum()); @@ -1598,7 +1598,7 @@ TEST_F(Dhcpv6SharedNetworkTest, sharedNetworkSelectedByRelay) { // Client #1 should be assigned an address from shared network. ASSERT_NO_THROW(client1.requestAddress(0xabca0)); - testAssigned([this, &client1] { + testAssigned([&client1] { ASSERT_NO_THROW(client1.doSARR()); }); ASSERT_TRUE(hasLeaseForAddress(client1, IOAddress("2001:db8:1::20"))); @@ -1608,7 +1608,7 @@ TEST_F(Dhcpv6SharedNetworkTest, sharedNetworkSelectedByRelay) { Dhcp6Client client2(client1.getServer()); client2.useRelay(true, IOAddress("3001::2")); ASSERT_NO_THROW(client2.requestAddress(0xabca0)); - testAssigned([this, &client2] { + testAssigned([&client2] { ASSERT_NO_THROW(client2.doSARR()); }); ASSERT_TRUE(hasLeaseForAddress(client2, IOAddress("2001:db8:2::20"))); @@ -1627,7 +1627,7 @@ TEST_F(Dhcpv6SharedNetworkTest, hintWithinSharedNetwork) { // Provide a hint to an existing address within first subnet. This address // should be offered out of this subnet. ASSERT_NO_THROW(client.requestAddress(0xabca, IOAddress("2001:db8:1::20"))); - testAssigned([this, &client] { + testAssigned([&client] { ASSERT_NO_THROW(client.doSolicit(true)); }); ASSERT_TRUE(hasLeaseForAddress(client, IOAddress("2001:db8:1::20"), @@ -1637,7 +1637,7 @@ TEST_F(Dhcpv6SharedNetworkTest, hintWithinSharedNetwork) { // the same shared network when we ask for it. client.clearRequestedIAs(); ASSERT_NO_THROW(client.requestAddress(0xabca, IOAddress("2001:db8:2::20"))); - testAssigned([this, &client] { + testAssigned([&client] { ASSERT_NO_THROW(client.doSolicit(true)); }); ASSERT_TRUE(hasLeaseForAddress(client, IOAddress("2001:db8:2::20"), @@ -1647,7 +1647,7 @@ TEST_F(Dhcpv6SharedNetworkTest, hintWithinSharedNetwork) { // an address from one of the subnets, but generally hard to tell from which one. client.clearRequestedIAs(); ASSERT_NO_THROW(client.requestAddress(0xabca, IOAddress("3002::123"))); - testAssigned([this, &client] { + testAssigned([&client] { ASSERT_NO_THROW(client.doSolicit(true)); }); std::vector leases = client.getLeasesByType(Lease::TYPE_NA); @@ -1673,14 +1673,14 @@ TEST_F(Dhcpv6SharedNetworkTest, subnetInSharedNetworkSelectedByClass) { // Client #1 requests an address in the restricted subnet but can't be assigned // this address because the client doesn't belong to a certain class. ASSERT_NO_THROW(client1.requestAddress(0xabca, IOAddress("2001:db8:1::20"))); - testAssigned([this, &client1] { + testAssigned([&client1] { ASSERT_NO_THROW(client1.doSARR()); }); ASSERT_TRUE(hasLeaseForAddress(client1, IOAddress("2001:db8:2::20"))); // Release the lease that the client has got, because we'll need this address // further in the test. - testAssigned([this, &client1] { + testAssigned([&client1] { ASSERT_NO_THROW(client1.doRelease()); }); @@ -1689,7 +1689,7 @@ TEST_F(Dhcpv6SharedNetworkTest, subnetInSharedNetworkSelectedByClass) { client1.addExtraOption(option1234); // This time, the allocation of the address provided as hint should be successful. - testAssigned([this, &client1] { + testAssigned([&client1] { ASSERT_NO_THROW(client1.doSARR()); }); ASSERT_TRUE(hasLeaseForAddress(client1, IOAddress("2001:db8:1::20"))); @@ -1698,7 +1698,7 @@ TEST_F(Dhcpv6SharedNetworkTest, subnetInSharedNetworkSelectedByClass) { Dhcp6Client client2(client1.getServer()); client2.setInterface("eth1"); ASSERT_NO_THROW(client2.requestAddress(0xabca0)); - testAssigned([this, &client2] { + testAssigned([&client2] { ASSERT_NO_THROW(client2.doSARR()); }); ASSERT_TRUE(hasLeaseForAddress(client2, IOAddress("2001:db8:2::20"))); @@ -1707,7 +1707,7 @@ TEST_F(Dhcpv6SharedNetworkTest, subnetInSharedNetworkSelectedByClass) { // subnet to which client2 now belongs. ASSERT_NO_FATAL_FAILURE(configure(NETWORKS_CONFIG[3], *client1.getServer())); - testAssigned([this, &client2] { + testAssigned([&client2] { ASSERT_NO_THROW(client2.doRenew()); }); EXPECT_EQ(0, client2.getLeaseNum()); @@ -1716,7 +1716,7 @@ TEST_F(Dhcpv6SharedNetworkTest, subnetInSharedNetworkSelectedByClass) { // get renewed. OptionPtr option1234_bis(new OptionUint16(Option::V6, 1234, 0x0002)); client2.addExtraOption(option1234_bis); - testAssigned([this, &client2] { + testAssigned([&client2] { ASSERT_NO_THROW(client2.doRenew()); }); EXPECT_EQ(1, client2.getLeaseNum()); @@ -1736,7 +1736,7 @@ TEST_F(Dhcpv6SharedNetworkTest, reservationInSharedNetwork) { // Client #1 should get his reserved address from the second subnet. ASSERT_NO_THROW(client1.requestAddress(0xabca, IOAddress("2001:db8:1::20"))); - testAssigned([this, &client1] { + testAssigned([&client1] { ASSERT_NO_THROW(client1.doSARR()); }); ASSERT_TRUE(hasLeaseForAddress(client1, IOAddress("2001:db8:2::28"))); @@ -1748,7 +1748,7 @@ TEST_F(Dhcpv6SharedNetworkTest, reservationInSharedNetwork) { // Client #2 should get its reserved address from the first subnet. ASSERT_NO_THROW(client2.requestAddress(0xabca, IOAddress("2001:db8:1::30"))); - testAssigned([this, &client2] { + testAssigned([&client2] { ASSERT_NO_THROW(client2.doSARR()); }); ASSERT_TRUE(hasLeaseForAddress(client2, IOAddress("2001:db8:1::28"))); @@ -1761,7 +1761,7 @@ TEST_F(Dhcpv6SharedNetworkTest, reservationInSharedNetwork) { // because its lease is now reserved for some other client. The client won't be // assigned a lease for which it has a reservation because another client holds // this lease. - testAssigned([this, &client1] { + testAssigned([&client1] { ASSERT_NO_THROW(client1.doRenew()); }); ASSERT_TRUE(client1.hasLeaseWithZeroLifetimeForAddress(IOAddress("2001:db8:2::28"))); @@ -1774,14 +1774,14 @@ TEST_F(Dhcpv6SharedNetworkTest, reservationInSharedNetwork) { } // Client #2 is now renewing its lease and should get its newly reserved address. - testAssigned([this, &client2] { + testAssigned([&client2] { ASSERT_NO_THROW(client2.doRenew()); }); ASSERT_TRUE(client2.hasLeaseWithZeroLifetimeForAddress(IOAddress("2001:db8:1::28"))); ASSERT_TRUE(hasLeaseForAddress(client2, IOAddress("2001:db8:2::28"))); // Same for client #1. - testAssigned([this, &client1] { + testAssigned([&client1] { ASSERT_NO_THROW(client1.doRenew()); }); ASSERT_TRUE(hasLeaseForAddress(client1, IOAddress("2001:db8:1::28"))); @@ -1803,7 +1803,7 @@ TEST_F(Dhcpv6SharedNetworkTest, reservationAccessRestrictedByClass) { // Assigned address should be allocated from the second subnet, because the // client doesn't belong to the "a-devices" class. ASSERT_NO_THROW(client.requestAddress(0xabca)); - testAssigned([this, &client] { + testAssigned([&client] { ASSERT_NO_THROW(client.doSARR()); }); ASSERT_TRUE(hasLeaseForAddress(client, IOAddress("2001:db8:2::16"))); @@ -1813,7 +1813,7 @@ TEST_F(Dhcpv6SharedNetworkTest, reservationAccessRestrictedByClass) { client.addExtraOption(option1234); // The client should now be assigned the reserved address from the first subnet. - testAssigned([this, &client] { + testAssigned([&client] { ASSERT_NO_THROW(client.doRenew()); }); ASSERT_TRUE(client.hasLeaseWithZeroLifetimeForAddress(IOAddress("2001:db8:2::16"))); @@ -1836,7 +1836,7 @@ TEST_F(Dhcpv6SharedNetworkTest, renewalRestrictedByClass) { // Client requests an address from the second subnet which should be successful. ASSERT_NO_THROW(client.requestAddress(0xabca, IOAddress("2001:db8:2::20"))); - testAssigned([this, &client] { + testAssigned([&client] { ASSERT_NO_THROW(client.doSARR()); }); ASSERT_TRUE(hasLeaseForAddress(client, IOAddress("2001:db8:2::20"))); @@ -1847,7 +1847,7 @@ TEST_F(Dhcpv6SharedNetworkTest, renewalRestrictedByClass) { // The client should not be able to renew the existing lease because it is now // prohibited by the classification. Instead, the client should get a lease from the // unrestricted subnet. - testAssigned([this, &client] { + testAssigned([&client] { ASSERT_NO_THROW(client.doRenew()); }); ASSERT_TRUE(client.hasLeaseWithZeroLifetimeForAddress(IOAddress("2001:db8:2::20"))); @@ -1875,7 +1875,7 @@ TEST_F(Dhcpv6SharedNetworkTest, optionsDerivation) { // Perform 4-way exchange and make sure we have been assigned address from the // subnet we wanted. - testAssigned([this, &client1] { + testAssigned([&client1] { ASSERT_NO_THROW(client1.doSARR()); }); ASSERT_TRUE(hasLeaseForAddress(client1, IOAddress("2001:db8:1::20"))); @@ -1907,7 +1907,7 @@ TEST_F(Dhcpv6SharedNetworkTest, optionsDerivation) { // Perform 4-way exchange and make sure we have been assigned address from the // subnet we wanted. - testAssigned([this, &client2] { + testAssigned([&client2] { ASSERT_NO_THROW(client2.doSARR()); }); ASSERT_TRUE(hasLeaseForAddress(client2, IOAddress("2001:db8:2::20"))); @@ -1934,7 +1934,7 @@ TEST_F(Dhcpv6SharedNetworkTest, optionsDerivation) { // Perform 4-way exchange and make sure we have been assigned address from the // subnet we wanted. - testAssigned([this, &client3] { + testAssigned([&client3] { ASSERT_NO_THROW(client3.doSARR()); }); ASSERT_TRUE(hasLeaseForAddress(client3, IOAddress("3000::1"))); @@ -1966,7 +1966,7 @@ TEST_F(Dhcpv6SharedNetworkTest, optionsFromSelectedSubnet) { // Send solicit without a hint. The client should be offerred an address from the // shared network. Depending on the subnet from which the address has been allocated // a specific value of the Name Servers option should be returned. - testAssigned([this, &client] { + testAssigned([&client] { ASSERT_NO_THROW(client.doSolicit(true)); }); @@ -1984,7 +1984,7 @@ TEST_F(Dhcpv6SharedNetworkTest, optionsFromSelectedSubnet) { client.clearRequestedIAs(); client.requestAddress(0xabca, IOAddress("2001:db8:2::20")); - testAssigned([this, &client] { + testAssigned([&client] { ASSERT_NO_THROW(client.doSolicit(true)); }); @@ -1992,7 +1992,7 @@ TEST_F(Dhcpv6SharedNetworkTest, optionsFromSelectedSubnet) { ASSERT_TRUE(client.hasOptionWithAddress(D6O_NAME_SERVERS, "5555::33")); // This time, let's do the 4-way exchange. - testAssigned([this, &client] { + testAssigned([&client] { ASSERT_NO_THROW(client.doSARR()); }); @@ -2000,7 +2000,7 @@ TEST_F(Dhcpv6SharedNetworkTest, optionsFromSelectedSubnet) { ASSERT_TRUE(client.hasOptionWithAddress(D6O_NAME_SERVERS, "5555::33")); // And renew the lease. - testAssigned([this, &client] { + testAssigned([&client] { ASSERT_NO_THROW(client.doRenew()); }); ASSERT_TRUE(client.hasLeaseForAddress(IOAddress("2001:db8:2::20"))); @@ -2022,7 +2022,7 @@ TEST_F(Dhcpv6SharedNetworkTest, sharedNetworkSelectionByInterface) { // Client #1 should be assigned an address from one of the two subnets // belonging to the first shared network. - testAssigned([this, &client1] { + testAssigned([&client1] { ASSERT_NO_THROW(client1.doSARR()); }); if (!hasLeaseForAddress(client1, IOAddress("2001:db8:1::20")) && @@ -2037,7 +2037,7 @@ TEST_F(Dhcpv6SharedNetworkTest, sharedNetworkSelectionByInterface) { // Client #2 should be assigned an address from one of the two subnets // belonging to the second shared network. - testAssigned([this, &client2] { + testAssigned([&client2] { ASSERT_NO_THROW(client2.doSARR()); }); if (!hasLeaseForAddress(client2, IOAddress("2001:db8:3::20")) && @@ -2059,7 +2059,7 @@ TEST_F(Dhcpv6SharedNetworkTest, sharedNetworkSelectionByRelay) { // Client #1 should be assigned an address from one of the two subnets // belonging to the first shared network. - testAssigned([this, &client1] { + testAssigned([&client1] { ASSERT_NO_THROW(client1.doSARR()); }); if (!hasLeaseForAddress(client1, IOAddress("2001:db8:1::20")) && @@ -2074,7 +2074,7 @@ TEST_F(Dhcpv6SharedNetworkTest, sharedNetworkSelectionByRelay) { // Client #2 should be assigned an address from one of the two subnets // belonging to the second shared network - testAssigned([this, &client2] { + testAssigned([&client2] { ASSERT_NO_THROW(client2.doSARR()); }); if (!hasLeaseForAddress(client2, IOAddress("2001:db8:3::20")) && @@ -2099,7 +2099,7 @@ TEST_F(Dhcpv6SharedNetworkTest, variousFieldsInReservation) { ASSERT_NO_FATAL_FAILURE(configure(NETWORKS_CONFIG[10], *client.getServer())); // Perform 4-way exchange. - testAssigned([this, &client] { + testAssigned([&client] { ASSERT_NO_THROW(client.doSARR()); }); @@ -2145,7 +2145,7 @@ TEST_F(Dhcpv6SharedNetworkTest, sharedNetworkSelectedByClass) { ASSERT_NO_FATAL_FAILURE(configure(NETWORKS_CONFIG[11], *client1.getServer())); // The client 1 should be offerred an address from the second subnet. - testAssigned([this, &client1] { + testAssigned([&client1] { ASSERT_NO_THROW(client1.doSolicit(true)); }); ASSERT_TRUE(hasLeaseForAddress(client1, IOAddress("2001:db8:2::20"), @@ -2161,7 +2161,7 @@ TEST_F(Dhcpv6SharedNetworkTest, sharedNetworkSelectedByClass) { client2.addExtraOption(option1234); // Client 2 should be offerred an address from the first subnet. - testAssigned([this, &client2] { + testAssigned([&client2] { ASSERT_NO_THROW(client2.doSolicit(true)); }); ASSERT_TRUE(hasLeaseForAddress(client2, IOAddress("2001:db8:1::20"), @@ -2185,7 +2185,7 @@ TEST_F(Dhcpv6SharedNetworkTest, assignmentsFromDifferentSubnets) { ASSERT_NO_FATAL_FAILURE(configure(NETWORKS_CONFIG[0], *client.getServer())); // 4-way exchange. - testAssigned([this, &client] { + testAssigned([&client] { ASSERT_NO_THROW(client.doSARR()); }); // The two addresses should come from different subnets. @@ -2196,7 +2196,7 @@ TEST_F(Dhcpv6SharedNetworkTest, assignmentsFromDifferentSubnets) { ASSERT_TRUE(hasLeaseForPrefixPool(client, IOAddress("5000::"), 96, 96)); // Try to renew. - testAssigned([this, &client] { + testAssigned([&client] { ASSERT_NO_THROW(client.doRenew()); }); ASSERT_TRUE(hasLeaseForAddress(client, IOAddress("2001:db8:1::20"))); @@ -2225,7 +2225,7 @@ TEST_F(Dhcpv6SharedNetworkTest, reservedAddressAndPrefix) { ASSERT_NO_FATAL_FAILURE(configure(NETWORKS_CONFIG[4], *client.getServer())); // 4-way exchange. - testAssigned([this, &client] { + testAssigned([&client] { ASSERT_NO_THROW(client.doSARR()); }); ASSERT_EQ(4, client.getLeaseNum()); @@ -2245,7 +2245,7 @@ TEST_F(Dhcpv6SharedNetworkTest, reservedAddressAndPrefix) { ASSERT_NE("1234::", leases_2222[0].addr_.toText()); // Try to renew and check this again. - testAssigned([this, &client] { + testAssigned([&client] { ASSERT_NO_THROW(client.doRenew()); }); ASSERT_EQ(4, client.getLeaseNum()); @@ -2277,7 +2277,7 @@ TEST_F(Dhcpv6SharedNetworkTest, relaySpecifiedForEachSubnet) { ASSERT_NO_FATAL_FAILURE(configure(NETWORKS_CONFIG[13], *client.getServer())); // 4-way exchange. - testAssigned([this, &client] { + testAssigned([&client] { ASSERT_NO_THROW(client.doSARR()); }); ASSERT_EQ(2, client.getLeaseNum()); @@ -2303,7 +2303,7 @@ TEST_F(Dhcpv6SharedNetworkTest, sharedNetworkSelectedByInterfaceId) { // Client #1 should be assigned an address from shared network. ASSERT_NO_THROW(client1.requestAddress(0xabca0)); - testAssigned([this, &client1] { + testAssigned([&client1] { ASSERT_NO_THROW(client1.doSARR()); }); ASSERT_TRUE(hasLeaseForAddress(client1, IOAddress("2001:db8:1::20"))); @@ -2314,7 +2314,7 @@ TEST_F(Dhcpv6SharedNetworkTest, sharedNetworkSelectedByInterfaceId) { client2.useRelay(true, IOAddress("3001::2")); client2.useInterfaceId("vlan1000"); ASSERT_NO_THROW(client2.requestAddress(0xabca0)); - testAssigned([this, &client2] { + testAssigned([&client2] { ASSERT_NO_THROW(client2.doSARR()); }); ASSERT_TRUE(hasLeaseForAddress(client2, IOAddress("2001:db8:2::20"))); @@ -2336,7 +2336,7 @@ TEST_F(Dhcpv6SharedNetworkTest, sharedNetworkSelectedByInterfaceIdInSubnet) { // Client #1 should be assigned an address from shared network. ASSERT_NO_THROW(client1.requestAddress(0xabca0)); - testAssigned([this, &client1] { + testAssigned([&client1] { ASSERT_NO_THROW(client1.doSARR()); }); ASSERT_TRUE(hasLeaseForAddress(client1, IOAddress("2001:db8:1::20"))); @@ -2347,7 +2347,7 @@ TEST_F(Dhcpv6SharedNetworkTest, sharedNetworkSelectedByInterfaceIdInSubnet) { client2.useRelay(true, IOAddress("3001::2")); client2.useInterfaceId("vlan1000"); ASSERT_NO_THROW(client2.requestAddress(0xabca0)); - testAssigned([this, &client2] { + testAssigned([&client2] { ASSERT_NO_THROW(client2.doSARR()); }); ASSERT_TRUE(hasLeaseForAddress(client2, IOAddress("2001:db8:2::20"))); @@ -2385,14 +2385,14 @@ TEST_F(Dhcpv6SharedNetworkTest, poolInSharedNetworkSelectedByClass) { // Client #1 requests an address in the restricted pool but can't be assigned // this address because the client doesn't belong to a certain class. ASSERT_NO_THROW(client1.requestAddress(0xabca, IOAddress("2001:db8:1::20"))); - testAssigned([this, &client1] { + testAssigned([&client1] { ASSERT_NO_THROW(client1.doSARR()); }); ASSERT_TRUE(hasLeaseForAddress(client1, IOAddress("2001:db8:1::50"))); // Release the lease that the client has got, because we'll need this address // further in the test. - testAssigned([this, &client1] { + testAssigned([&client1] { ASSERT_NO_THROW(client1.doRelease()); }); @@ -2401,7 +2401,7 @@ TEST_F(Dhcpv6SharedNetworkTest, poolInSharedNetworkSelectedByClass) { client1.addExtraOption(option1234); // This time, the allocation of the address provided as hint should be successful. - testAssigned([this, &client1] { + testAssigned([&client1] { ASSERT_NO_THROW(client1.doSARR()); }); ASSERT_TRUE(hasLeaseForAddress(client1, IOAddress("2001:db8:1::20"))); @@ -2410,7 +2410,7 @@ TEST_F(Dhcpv6SharedNetworkTest, poolInSharedNetworkSelectedByClass) { Dhcp6Client client2(client1.getServer()); client2.setInterface("eth1"); ASSERT_NO_THROW(client2.requestAddress(0xabca0)); - testAssigned([this, &client2] { + testAssigned([&client2] { ASSERT_NO_THROW(client2.doSARR()); }); ASSERT_TRUE(hasLeaseForAddress(client2, IOAddress("2001:db8:1::50"))); @@ -2419,7 +2419,7 @@ TEST_F(Dhcpv6SharedNetworkTest, poolInSharedNetworkSelectedByClass) { // pool to which client2 now belongs. ASSERT_NO_FATAL_FAILURE(configure(NETWORKS_CONFIG[20], *client1.getServer())); - testAssigned([this, &client2] { + testAssigned([&client2] { ASSERT_NO_THROW(client2.doRenew()); }); EXPECT_EQ(0, client2.getLeasesWithNonZeroLifetime().size()); @@ -2428,7 +2428,7 @@ TEST_F(Dhcpv6SharedNetworkTest, poolInSharedNetworkSelectedByClass) { // get renewed. OptionPtr option1234_bis(new OptionUint16(Option::V6, 1234, 0x0002)); client2.addExtraOption(option1234_bis); - testAssigned([this, &client2] { + testAssigned([&client2] { ASSERT_NO_THROW(client2.doRenew()); }); EXPECT_EQ(1, client2.getLeaseNum()); @@ -2448,14 +2448,14 @@ TEST_F(Dhcpv6SharedNetworkTest, poolInSubnetSelectedByClass) { // Client #1 requests an address in the restricted pool but can't be assigned // this address because the client doesn't belong to a certain class. ASSERT_NO_THROW(client1.requestAddress(0xabca, IOAddress("2001:db8:1::20"))); - testAssigned([this, &client1] { + testAssigned([&client1] { ASSERT_NO_THROW(client1.doSARR()); }); ASSERT_TRUE(hasLeaseForAddress(client1, IOAddress("2001:db8:1::50"))); // Release the lease that the client has got, because we'll need this address // further in the test. - testAssigned([this, &client1] { + testAssigned([&client1] { ASSERT_NO_THROW(client1.doRelease()); }); @@ -2464,7 +2464,7 @@ TEST_F(Dhcpv6SharedNetworkTest, poolInSubnetSelectedByClass) { client1.addExtraOption(option1234); // This time, the allocation of the address provided as hint should be successful. - testAssigned([this, &client1] { + testAssigned([&client1] { ASSERT_NO_THROW(client1.doSARR()); }); ASSERT_TRUE(hasLeaseForAddress(client1, IOAddress("2001:db8:1::20"))); @@ -2473,7 +2473,7 @@ TEST_F(Dhcpv6SharedNetworkTest, poolInSubnetSelectedByClass) { Dhcp6Client client2(client1.getServer()); client2.setInterface("eth1"); ASSERT_NO_THROW(client2.requestAddress(0xabca0)); - testAssigned([this, &client2] { + testAssigned([&client2] { ASSERT_NO_THROW(client2.doSARR()); }); ASSERT_TRUE(hasLeaseForAddress(client2, IOAddress("2001:db8:1::50"))); @@ -2482,7 +2482,7 @@ TEST_F(Dhcpv6SharedNetworkTest, poolInSubnetSelectedByClass) { // pool to which client2 now belongs. ASSERT_NO_FATAL_FAILURE(configure(NETWORKS_CONFIG[22], *client1.getServer())); - testAssigned([this, &client2] { + testAssigned([&client2] { ASSERT_NO_THROW(client2.doRenew()); }); EXPECT_EQ(0, client2.getLeasesWithNonZeroLifetime().size()); @@ -2491,7 +2491,7 @@ TEST_F(Dhcpv6SharedNetworkTest, poolInSubnetSelectedByClass) { // get renewed. OptionPtr option1234_bis(new OptionUint16(Option::V6, 1234, 0x0002)); client2.addExtraOption(option1234_bis); - testAssigned([this, &client2] { + testAssigned([&client2] { ASSERT_NO_THROW(client2.doRenew()); }); EXPECT_EQ(1, client2.getLeaseNum()); diff --git a/src/lib/dhcpsrv/alloc_engine.cc b/src/lib/dhcpsrv/alloc_engine.cc index 58a778aab9..b4c838d13a 100644 --- a/src/lib/dhcpsrv/alloc_engine.cc +++ b/src/lib/dhcpsrv/alloc_engine.cc @@ -429,8 +429,8 @@ namespace dhcp { AllocEngine::ClientContext6::ClientContext6() : query_(), fake_allocation_(false), subnet_(), host_subnet_(), duid_(), hwaddr_(), host_identifiers_(), hosts_(), fwd_dns_update_(false), - rev_dns_update_(false), hostname_(), callout_handle_(), - ias_() { + rev_dns_update_(false), committed_(false), hostname_(), + callout_handle_(), ias_() { } AllocEngine::ClientContext6::ClientContext6(const Subnet6Ptr& subnet, @@ -443,9 +443,9 @@ AllocEngine::ClientContext6::ClientContext6(const Subnet6Ptr& subnet, const CalloutHandlePtr& callout_handle) : query_(query), fake_allocation_(fake_allocation), subnet_(subnet), duid_(duid), hwaddr_(), host_identifiers_(), hosts_(), - fwd_dns_update_(fwd_dns), rev_dns_update_(rev_dns), + fwd_dns_update_(fwd_dns), rev_dns_update_(rev_dns), committed_(false), hostname_(hostname), callout_handle_(callout_handle), - allocated_resources_(), ias_() { + allocated_resources_(), new_leases_(), ias_() { // Initialize host identifiers. if (duid) { @@ -729,6 +729,7 @@ AllocEngine::allocateLeases6(ClientContext6& ctx) { // IAs. BOOST_FOREACH(Lease6Ptr lease, leases) { ctx.addAllocatedResource(lease->addr_, lease->prefixlen_); + ctx.new_leases_.push_back(lease); } return (leases); } @@ -1677,6 +1678,7 @@ AllocEngine::renewLeases6(ClientContext6& ctx) { // IAs. BOOST_FOREACH(Lease6Ptr lease, leases) { ctx.addAllocatedResource(lease->addr_, lease->prefixlen_); + ctx.new_leases_.push_back(lease); } } diff --git a/src/lib/dhcpsrv/alloc_engine.h b/src/lib/dhcpsrv/alloc_engine.h index 69dca7972c..3433031902 100644 --- a/src/lib/dhcpsrv/alloc_engine.h +++ b/src/lib/dhcpsrv/alloc_engine.h @@ -365,6 +365,10 @@ public: /// (if true). bool rev_dns_update_; + /// @brief A boolean value which indicates that server must + /// invoke the leases committed callout (if true). + bool committed_; + /// @brief Hostname. /// /// The server retrieves the hostname from the Client FQDN option, @@ -377,6 +381,9 @@ public: /// @brief Holds addresses and prefixes allocated for all IAs. ResourceContainer allocated_resources_; + /// @brief A collection of newly allocated leases. + Lease6Collection new_leases_; + //@} /// @brief Parameters pertaining to individual IAs. diff --git a/src/lib/dhcpsrv/tests/alloc_engine6_unittest.cc b/src/lib/dhcpsrv/tests/alloc_engine6_unittest.cc index 0a8afebc32..8f36ed97bf 100644 --- a/src/lib/dhcpsrv/tests/alloc_engine6_unittest.cc +++ b/src/lib/dhcpsrv/tests/alloc_engine6_unittest.cc @@ -35,6 +35,7 @@ TEST(ClientContext6Test, addHint) { // a context. TEST(ClientContext6Test, addAllocatedResource) { AllocEngine::ClientContext6 ctx; + ASSERT_FALSE(ctx.committed_); ctx.addAllocatedResource(IOAddress("2001:db8:1::1")); ctx.addAllocatedResource(IOAddress("3000:1::"), 64);