]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[5458a] Code done, tests to do
authorFrancis Dupont <fdupont@isc.org>
Thu, 19 Apr 2018 23:09:31 +0000 (01:09 +0200)
committerFrancis Dupont <fdupont@isc.org>
Thu, 19 Apr 2018 23:09:31 +0000 (01:09 +0200)
16 files changed:
src/bin/dhcp4/tests/kea_controller_unittest.cc
src/bin/dhcp4/tests/shared_network_unittest.cc
src/bin/dhcp6/dhcp6_srv.cc
src/bin/dhcp6/dhcp6_srv.h
src/bin/dhcp6/dhcp6to4_ipc.cc
src/bin/dhcp6/tests/classify_unittests.cc
src/bin/dhcp6/tests/confirm_unittest.cc
src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
src/bin/dhcp6/tests/dhcp6_test_utils.h
src/bin/dhcp6/tests/fqdn_unittest.cc
src/bin/dhcp6/tests/hooks_unittest.cc
src/bin/dhcp6/tests/kea_controller_unittest.cc
src/bin/dhcp6/tests/shared_network_unittest.cc
src/lib/dhcpsrv/alloc_engine.cc
src/lib/dhcpsrv/alloc_engine.h
src/lib/dhcpsrv/tests/alloc_engine6_unittest.cc

index 8f72c247100d1d7ced6e9f983fe45ada45b8ee22..5b843fde7e389dd286be01b1fac0c822db0ff00f 100644 (file)
@@ -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();
index 47005f3f3a84003b4662a68a4ffb6a4158403da8..7afcbe2077f33545879334b420fb950bf3fe09d9 100644 (file)
@@ -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<IOAddress>(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());
     });
 
index 66d906fcbc94a8c3e67ea1d2bf84f60e44391723..38a7b96896000f48da6230e03eaf795514222ba1 100644 (file)
@@ -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<int64_t>(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<isc::dhcp::Option6IA>& container,
 
 bool
 Dhcpv6Srv::declineLease(const Pkt6Ptr& decline, const Lease6Ptr lease,
-                        boost::shared_ptr<Option6IA> ia_rsp,
-                        AllocEngine::ClientContext6& ctx) {
+                        boost::shared_ptr<Option6IA> 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
index 55e07e21d1e011c774fdc99fa4fffb31daf30afb..a032f986cf70bad705a308952c4531d44b2e02a6 100644 (file)
@@ -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.
index 8704288ad7709ee7b2742b1150ab2cdc7a51610d..ecde188d59ea87c9713b31288476ceff0fe9adb3 100644 (file)
@@ -13,6 +13,7 @@
 #include <dhcpsrv/cfgmgr.h>
 #include <dhcp6/dhcp6to4_ipc.h>
 #include <dhcp6/dhcp6_log.h>
+#include <dhcp6/ctrl_dhcp6_srv.h>
 #include <dhcp6/dhcp6_srv.h>
 #include <exceptions/exceptions.h>
 #include <hooks/callout_handle.h>
@@ -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
index d99b5fcd5face423682904e5bde03ee9fe3a7a25..962759bb1bc2b80cc826389d6131d36f387651bb 100644 (file)
@@ -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);
index ba8db9c61feb5322bfe4ae780944726e81688ba0..8d3a7ab5a6257ff7642b0f42c2f7f155585bdd29 100644 (file)
@@ -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
index b4d4a0dec8495024ce0be5b3e6900297e06b106f..f3893b7099cb2b098377925521aead9fcba47aff 100644 (file)
@@ -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);
index 52fe5a02a174bf2bbc9c1c4de84a8859b9edf310..17e7c5a2456a8393ff69ac51015db07b85401735 100644 (file)
@@ -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;
index 250f3d0b586d4dd2809d4667f82b90182494ea47..969cbe30022c68a820390b9988c95cdc3b589ae4 100644 (file)
@@ -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.
index a3ba0e2339c38113e6e1db0309be3215a576358b..e211869292b41978ac4b081765573bbdb6f9fa1a 100644 (file)
@@ -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<string> 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<string> 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<ControlledDhcpv6Srv> 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
index f737051307a5ae8a1025076e247e157bf6a4b61e..62ef1ba4fb99c80e445f623fc8fef4abbd6759b2 100644 (file)
@@ -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();
index b3081aa9a5c77c7cf267e7fcf837b2018aac8099..7ffe9fc24d9c5c067cae257e355d47afc612855d 100644 (file)
@@ -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<Lease6> 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());
index 58a778aab9a68e582509ba41851558bebbd60f10..b4c838d13a39ffc8f06403a88b882cad325137b7 100644 (file)
@@ -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);
             }
         }
 
index 69dca7972c008e3c9963561439980cf74298cfea..34330319024aa9d953707e68ae5604452e1fd6ed 100644 (file)
@@ -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.
index 0a8afebc32334a489c8cd674712d01f33af0d660..8f36ed97bfd0bfbcc8f1661c3234ccf994400410 100644 (file)
@@ -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);