Browse Source

[master] Merge branch 'trac3715'

Marcin Siodelski 10 years ago
parent
commit
7415c74e38

+ 1 - 2
src/bin/dhcp6/dhcp6_srv.cc

@@ -621,8 +621,7 @@ Dhcpv6Srv::generateServerID() {
     const IfaceMgr::IfaceCollection& ifaces = IfaceMgr::instance().getIfaces();
 
     // Let's find suitable interface.
-    for (IfaceMgr::IfaceCollection::const_iterator iface = ifaces.begin();
-         iface != ifaces.end(); ++iface) {
+    BOOST_FOREACH(IfacePtr iface, ifaces) {
         // All the following checks could be merged into one multi-condition
         // statement, but let's keep them separated as perhaps one day
         // we will grow knobs to selectively turn them on or off. Also,

+ 1 - 1
src/bin/dhcp6/tests/config_parser_unittest.cc

@@ -96,7 +96,7 @@ public:
             ADD_FAILURE() << "No interfaces detected.";
         }
 
-        valid_iface_ = ifaces.begin()->getName();
+        valid_iface_ = (*ifaces.begin())->getName();
         bogus_iface_ = "nonexisting0";
 
         if (IfaceMgr::instance().getIface(bogus_iface_)) {

+ 1 - 1
src/bin/dhcp6/tests/dhcp6_test_utils.h

@@ -146,7 +146,7 @@ public:
             ADD_FAILURE() << "No interfaces detected.";
         }
 
-        valid_iface_ = ifaces.begin()->getName();
+        valid_iface_ = (*ifaces.begin())->getName();
     }
 
     // Generate IA_NA or IA_PD option with specified parameters

+ 13 - 21
src/bin/perfdhcp/test_control.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2012-2014 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2014,2015 Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -25,6 +25,9 @@
 #include "perf_pkt4.h"
 #include "perf_pkt6.h"
 
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/foreach.hpp>
+
 #include <fstream>
 #include <stdio.h>
 #include <stdlib.h>
@@ -33,8 +36,6 @@
 #include <signal.h>
 #include <sys/wait.h>
 
-#include <boost/date_time/posix_time/posix_time.hpp>
-
 using namespace std;
 using namespace boost::posix_time;
 using namespace isc;
@@ -57,7 +58,7 @@ TestControl::TestControlSocket::TestControlSocket(const int socket) :
 }
 
 TestControl::TestControlSocket::~TestControlSocket() {
-    Iface* iface = IfaceMgr::instance().getIface(ifindex_);
+    IfacePtr iface = IfaceMgr::instance().getIface(ifindex_);
     if (iface) {
         iface->delSocket(sockfd_);
     }
@@ -65,20 +66,11 @@ TestControl::TestControlSocket::~TestControlSocket() {
 
 void
 TestControl::TestControlSocket::initSocketData() {
-    const IfaceMgr::IfaceCollection& ifaces =
-        IfaceMgr::instance().getIfaces();
-    for (IfaceMgr::IfaceCollection::const_iterator it = ifaces.begin();
-         it != ifaces.end();
-         ++it) {
-        const Iface::SocketCollection& socket_collection =
-            it->getSockets();
-        for (Iface::SocketCollection::const_iterator s =
-                 socket_collection.begin();
-             s != socket_collection.end();
-             ++s) {
-            if (s->sockfd_ == sockfd_) {
-                ifindex_ = it->getIndex();
-                addr_ = s->addr_;
+    BOOST_FOREACH(IfacePtr iface, IfaceMgr::instance().getIfaces()) {
+        BOOST_FOREACH(SocketInfo s, iface->getSockets()) {
+            if (s.sockfd_ == sockfd_) {
+                ifindex_ = iface->getIndex();
+                addr_ = s.addr_;
                 return;
             }
         }
@@ -784,7 +776,7 @@ TestControl::openSocket() const {
             // If user specified interface name with '-l' the
             // IPV6_MULTICAST_IF has to be set.
             if ((ret >= 0)  && options.isInterface()) {
-                Iface* iface =
+                IfacePtr iface =
                     IfaceMgr::instance().getIface(options.getLocalName());
                 if (iface == NULL) {
                     isc_throw(Unexpected, "unknown interface "
@@ -2050,7 +2042,7 @@ TestControl::setDefaults4(const TestControlSocket& socket,
                           const Pkt4Ptr& pkt) {
     CommandOptions& options = CommandOptions::instance();
     // Interface name.
-    Iface* iface = IfaceMgr::instance().getIface(socket.ifindex_);
+    IfacePtr iface = IfaceMgr::instance().getIface(socket.ifindex_);
     if (iface == NULL) {
         isc_throw(BadValue, "unable to find interface with given index");
     }
@@ -2076,7 +2068,7 @@ TestControl::setDefaults6(const TestControlSocket& socket,
                           const Pkt6Ptr& pkt) {
     CommandOptions& options = CommandOptions::instance();
     // Interface name.
-    Iface* iface = IfaceMgr::instance().getIface(socket.ifindex_);
+    IfacePtr iface = IfaceMgr::instance().getIface(socket.ifindex_);
     if (iface == NULL) {
         isc_throw(BadValue, "unable to find interface with given index");
     }

+ 1 - 1
src/bin/perfdhcp/tests/command_options_unittest.cc

@@ -786,7 +786,7 @@ TEST_F(CommandOptionsTest, Interface) {
     // not fail this test.
     if (ifaces.size() > 0) {
         // Get the name of the interface we detected.
-        iface_name = ifaces.begin()->getName();
+        iface_name = (*ifaces.begin())->getName();
         // Use the name in the command parser.
         ASSERT_NO_THROW(process("perfdhcp -4 -l " + iface_name + " abc"));
         // We expect that command parser will detect that argument

+ 3 - 6
src/bin/perfdhcp/tests/test_control_unittest.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2012-2013 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2013,2015 Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -21,6 +21,7 @@
 #include <dhcp/iface_mgr.h>
 
 #include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/foreach.hpp>
 
 #include <cstddef>
 #include <stdint.h>
@@ -217,11 +218,7 @@ public:
     ///
     /// \return local loopback interface name.
     std::string getLocalLoopback() const {
-        const IfaceMgr::IfaceCollection& ifaces =
-            IfaceMgr::instance().getIfaces();
-        for (IfaceMgr::IfaceCollection::const_iterator iface = ifaces.begin();
-             iface != ifaces.end();
-             ++iface) {
+        BOOST_FOREACH(IfacePtr iface, IfaceMgr::instance().getIfaces()) {
             if (iface->flag_loopback_) {
                 return (iface->getName());
             }

+ 108 - 172
src/lib/dhcp/iface_mgr.cc

@@ -28,6 +28,8 @@
 #include <exceptions/exceptions.h>
 #include <util/io/pktinfo_utilities.h>
 
+#include <boost/foreach.hpp>
+
 #include <cstring>
 #include <errno.h>
 #include <fstream>
@@ -191,9 +193,8 @@ IfaceMgr::IfaceMgr()
 }
 
 void Iface::addUnicast(const isc::asiolink::IOAddress& addr) {
-    for (Iface::AddressCollection::const_iterator i = unicasts_.begin();
-         i != unicasts_.end(); ++i) {
-        if (i->get() == addr) {
+    BOOST_FOREACH(Address a, unicasts_) {
+        if (a.get() == addr) {
             isc_throw(BadValue, "Address " << addr
                       << " already defined on the " << name_ << " interface.");
         }
@@ -205,13 +206,11 @@ bool
 Iface::getAddress4(isc::asiolink::IOAddress& address) const {
     // Iterate over existing addresses assigned to the interface.
     // Try to find the one that is IPv4.
-    const AddressCollection& addrs = getAddresses();
-    for (AddressCollection::const_iterator addr = addrs.begin();
-         addr != addrs.end(); ++addr) {
+    BOOST_FOREACH(Address addr, getAddresses()) {
         // If address is IPv4, we assign it to the function argument
         // and return true.
-        if (addr->get().isV4()) {
-            address = addr->get();
+        if (addr.get().isV4()) {
+            address = addr.get();
             return (true);
         }
     }
@@ -221,10 +220,8 @@ Iface::getAddress4(isc::asiolink::IOAddress& address) const {
 
 bool
 Iface::hasAddress(const isc::asiolink::IOAddress& address) const {
-    const AddressCollection& addrs = getAddresses();
-    for (AddressCollection::const_iterator addr = addrs.begin();
-         addr != addrs.end(); ++addr) {
-        if (address == addr->get()) {
+    BOOST_FOREACH(Address addr, getAddresses()) {
+        if (address == addr.get()) {
             return (true);
         }
     }
@@ -233,7 +230,7 @@ Iface::hasAddress(const isc::asiolink::IOAddress& address) const {
 
 void
 Iface::addAddress(const isc::asiolink::IOAddress& addr) {
-    addrs_.push_back(OptionalValue<IOAddress>(addr, OptionalValueState(true)));
+    addrs_.push_back(Address(addr, OptionalValueState(true)));
 }
 
 void
@@ -260,9 +257,8 @@ Iface::setActive(const bool active) {
 unsigned int
 Iface::countActive4() const {
     uint16_t count = 0;
-    for (AddressCollection::const_iterator addr_it = addrs_.begin();
-         addr_it != addrs_.end(); ++addr_it) {
-        if (addr_it->get().isV4() && addr_it->isSpecified()) {
+    BOOST_FOREACH(Address addr, addrs_) {
+        if (addr.get().isV4() && addr.isSpecified()) {
             ++count;
         }
     }
@@ -270,16 +266,14 @@ Iface::countActive4() const {
 }
 
 void IfaceMgr::closeSockets() {
-    for (IfaceCollection::iterator iface = ifaces_.begin();
-         iface != ifaces_.end(); ++iface) {
+    BOOST_FOREACH(IfacePtr iface, ifaces_) {
         iface->closeSockets();
     }
 }
 
 void
 IfaceMgr::closeSockets(const uint16_t family) {
-    for (IfaceCollection::iterator iface = ifaces_.begin();
-         iface != ifaces_.end(); ++iface) {
+    BOOST_FOREACH(IfacePtr iface, ifaces_) {
         iface->closeSockets(family);
     }
 }
@@ -298,13 +292,11 @@ IfaceMgr::isDirectResponseSupported() const {
 
 void
 IfaceMgr::addExternalSocket(int socketfd, SocketCallback callback) {
-    for (SocketCallbackInfoContainer::iterator s = callbacks_.begin();
-         s != callbacks_.end(); ++s) {
-
+    BOOST_FOREACH(SocketCallbackInfo s, callbacks_) {
         // There's such a socket description there already.
         // Update the callback and we're done
-        if (s->socket_ == socketfd) {
-            s->callback_ = callback;
+        if (s.socket_ == socketfd) {
+            s.callback_ = callback;
             return;
         }
     }
@@ -372,13 +364,10 @@ IfaceMgr::setPacketFilter(const PktFilter6Ptr& packet_filter) {
 bool
 IfaceMgr::hasOpenSocket(const uint16_t family) const {
     // Iterate over all interfaces and search for open sockets.
-    for (IfaceCollection::const_iterator iface = ifaces_.begin();
-         iface != ifaces_.end(); ++iface) {
-        const Iface::SocketCollection& sockets = iface->getSockets();
-        for (Iface::SocketCollection::const_iterator sock = sockets.begin();
-             sock != sockets.end(); ++sock) {
+    BOOST_FOREACH(IfacePtr iface, ifaces_) {
+        BOOST_FOREACH(SocketInfo sock, iface->getSockets()) {
             // Check if the socket matches specified family.
-            if (sock->family_ == family) {
+            if (sock.family_ == family) {
                 // There is at least one socket open, so return.
                 return (true);
             }
@@ -391,24 +380,19 @@ IfaceMgr::hasOpenSocket(const uint16_t family) const {
 bool
 IfaceMgr::hasOpenSocket(const IOAddress& addr) const {
     // Iterate over all interfaces and search for open sockets.
-    for (IfaceCollection::const_iterator iface = ifaces_.begin();
-         iface != ifaces_.end(); ++iface) {
-        const Iface::SocketCollection& sockets = iface->getSockets();
-        for (Iface::SocketCollection::const_iterator sock = sockets.begin();
-             sock != sockets.end(); ++sock) {
+    BOOST_FOREACH(IfacePtr iface, ifaces_) {
+        BOOST_FOREACH(SocketInfo sock, iface->getSockets()) {
             // Check if the socket address matches the specified address or
             // if address is unspecified (in6addr_any).
-            if (sock->addr_ == addr) {
+            if (sock.addr_ == addr) {
                 return (true);
-            } else if (sock->addr_ == IOAddress("::")) {
+
+            } else if (sock.addr_ == IOAddress("::")) {
                 // Handle the case that the address is unspecified (any).
                 // In this case, we should check if the specified address
                 // belongs to any of the interfaces.
-                for (Iface::AddressCollection::const_iterator addr_it =
-                         iface->getAddresses().begin();
-                     addr_it != iface->getAddresses().end();
-                     ++addr_it) {
-                    if (addr == addr_it->get()) {
+                BOOST_FOREACH(Iface::Address a, iface->getAddresses()) {
+                    if (addr == a.get()) {
                         return (true);
                     }
                 }
@@ -439,21 +423,21 @@ void IfaceMgr::stubDetectIfaces() {
                   "Interface detection on this OS is not supported.");
     }
 
-    Iface iface(ifaceName, if_nametoindex(ifaceName.c_str()));
-    iface.flag_up_ = true;
-    iface.flag_running_ = true;
+    IfacePtr iface(new Iface(ifaceName, if_nametoindex(ifaceName.c_str())));
+    iface->flag_up_ = true;
+    iface->flag_running_ = true;
 
     // Note that we claim that this is not a loopback. iface_mgr tries to open a
     // socket on all interaces that are up, running and not loopback. As this is
     // the only interface we were able to detect, let's pretend this is a normal
     // interface.
-    iface.flag_loopback_ = false;
-    iface.flag_multicast_ = true;
-    iface.flag_broadcast_ = true;
-    iface.setHWType(HWTYPE_ETHERNET);
+    iface->flag_loopback_ = false;
+    iface->flag_multicast_ = true;
+    iface->flag_broadcast_ = true;
+    iface->setHWType(HWTYPE_ETHERNET);
 
-    iface.addAddress(IOAddress(v4addr));
-    iface.addAddress(IOAddress(v6addr));
+    iface->addAddress(IOAddress(v4addr));
+    iface->addAddress(IOAddress(v6addr));
     addInterface(iface);
 }
 
@@ -463,10 +447,7 @@ IfaceMgr::openSockets4(const uint16_t port, const bool use_bcast,
     int count = 0;
     int bcast_num = 0;
 
-    for (IfaceCollection::iterator iface = ifaces_.begin();
-         iface != ifaces_.end();
-         ++iface) {
-
+    BOOST_FOREACH(IfacePtr iface, ifaces_) {
         // If the interface is inactive, there is nothing to do. Simply
         // proceed to the next detected interface.
         if (iface->inactive4_) {
@@ -498,12 +479,9 @@ IfaceMgr::openSockets4(const uint16_t port, const bool use_bcast,
         }
 
         Iface::AddressCollection addrs = iface->getAddresses();
-        for (Iface::AddressCollection::iterator addr = addrs.begin();
-             addr != addrs.end();
-             ++addr) {
-
+        BOOST_FOREACH(Iface::Address addr, iface->getAddresses()) {
             // Skip non-IPv4 addresses and those that weren't selected..
-            if (!addr->get().isV4() || !addr->isSpecified()) {
+            if (!addr.get().isV4() || !addr.isSpecified()) {
                 continue;
             }
 
@@ -537,7 +515,7 @@ IfaceMgr::openSockets4(const uint16_t port, const bool use_bcast,
                     try {
                         // We haven't open any broadcast sockets yet, so we can
                         // open at least one more.
-                        openSocket(iface->getName(), *addr, port, true, true);
+                        openSocket(iface->getName(), addr.get(), port, true, true);
                     } catch (const Exception& ex) {
                         IFACEMGR_ERROR(SocketConfigError, error_handler,
                                        "failed to open socket on interface "
@@ -555,7 +533,7 @@ IfaceMgr::openSockets4(const uint16_t port, const bool use_bcast,
             } else {
                 try {
                     // Not broadcast capable, do not set broadcast flags.
-                    openSocket(iface->getName(), *addr, port, false, false);
+                    openSocket(iface->getName(), addr.get(), port, false, false);
                 } catch (const Exception& ex) {
                     IFACEMGR_ERROR(SocketConfigError, error_handler,
                                    "failed to open socket on interface "
@@ -577,10 +555,7 @@ IfaceMgr::openSockets6(const uint16_t port,
                        IfaceMgrErrorMsgCallback error_handler) {
     int count = 0;
 
-    for (IfaceCollection::iterator iface = ifaces_.begin();
-         iface != ifaces_.end();
-         ++iface) {
-
+    BOOST_FOREACH(IfacePtr iface, ifaces_) {
         if (iface->inactive6_) {
             continue;
 
@@ -607,12 +582,10 @@ IfaceMgr::openSockets6(const uint16_t port,
         }
 
         // Open unicast sockets if there are any unicast addresses defined
-        Iface::AddressCollection unicasts = iface->getUnicasts();
-        for (Iface::AddressCollection::iterator addr = unicasts.begin();
-             addr != unicasts.end(); ++addr) {
+        BOOST_FOREACH(Iface::Address addr, iface->getUnicasts()) {
 
             try {
-                openSocket(iface->getName(), *addr, port);
+                openSocket(iface->getName(), addr, port);
             } catch (const Exception& ex) {
                 IFACEMGR_ERROR(SocketConfigError, error_handler,
                                "Failed to open unicast socket on  interface "
@@ -625,13 +598,10 @@ IfaceMgr::openSockets6(const uint16_t port,
 
         }
 
-        Iface::AddressCollection addrs = iface->getAddresses();
-        for (Iface::AddressCollection::iterator addr = addrs.begin();
-             addr != addrs.end();
-             ++addr) {
+        BOOST_FOREACH(Iface::Address addr, iface->getAddresses()) {
 
             // Skip all but V6 addresses.
-            if (!addr->get().isV6()) {
+            if (!addr.get().isV6()) {
                 continue;
             }
 
@@ -640,14 +610,14 @@ IfaceMgr::openSockets6(const uint16_t port,
             // with interface with 2 global addresses, we would bind 3 sockets
             // (one for link-local and two for global). That would result in
             // getting each message 3 times.
-            if (!addr->get().isV6LinkLocal()){
+            if (!addr.get().isV6LinkLocal()){
                 continue;
             }
 
             // Run OS-specific function to open a socket capable of receiving
             // packets sent to All_DHCP_Relay_Agents_and_Servers multicast
             // address.
-            if (openMulticastSocket(*iface, *addr, port, error_handler)) {
+            if (openMulticastSocket(*iface, addr, port, error_handler)) {
                 ++count;
             }
 
@@ -658,10 +628,7 @@ IfaceMgr::openSockets6(const uint16_t port,
 
 void
 IfaceMgr::printIfaces(std::ostream& out /*= std::cout*/) {
-    for (IfaceCollection::const_iterator iface=ifaces_.begin();
-         iface!=ifaces_.end();
-         ++iface) {
-
+    BOOST_FOREACH(IfacePtr iface, ifaces_) {
         const Iface::AddressCollection& addrs = iface->getAddresses();
 
         out << "Detected interface " << iface->getFullName()
@@ -676,36 +643,31 @@ IfaceMgr::printIfaces(std::ostream& out /*= std::cout*/) {
             << ")" << endl;
         out << "  " << addrs.size() << " addr(s):";
 
-        for (Iface::AddressCollection::const_iterator addr = addrs.begin();
-             addr != addrs.end(); ++addr) {
-            out << "  " << addr->get().toText();
+        BOOST_FOREACH(Iface::Address addr, addrs) {
+            out << "  " << addr.get().toText();
         }
         out << endl;
     }
 }
 
-Iface*
+IfacePtr
 IfaceMgr::getIface(int ifindex) {
-    for (IfaceCollection::iterator iface=ifaces_.begin();
-         iface!=ifaces_.end();
-         ++iface) {
+    BOOST_FOREACH(IfacePtr iface, ifaces_) {
         if (iface->getIndex() == ifindex)
-            return (&(*iface));
+            return (iface);
     }
 
-    return (NULL); // not found
+    return (IfacePtr()); // not found
 }
 
-Iface*
+IfacePtr
 IfaceMgr::getIface(const std::string& ifname) {
-    for (IfaceCollection::iterator iface=ifaces_.begin();
-         iface!=ifaces_.end();
-         ++iface) {
+    BOOST_FOREACH(IfacePtr iface, ifaces_) {
         if (iface->getName() == ifname)
-            return (&(*iface));
+            return (iface);
     }
 
-    return (NULL); // not found
+    return (IfacePtr()); // not found
 }
 
 void
@@ -715,8 +677,7 @@ IfaceMgr::clearIfaces() {
 
 void
 IfaceMgr::clearUnicasts() {
-    for (IfaceCollection::iterator iface=ifaces_.begin();
-         iface!=ifaces_.end(); ++iface) {
+    BOOST_FOREACH(IfacePtr iface, ifaces_) {
         iface->clearUnicasts();
     }
 }
@@ -724,7 +685,7 @@ IfaceMgr::clearUnicasts() {
 int IfaceMgr::openSocket(const std::string& ifname, const IOAddress& addr,
                          const uint16_t port, const bool receive_bcast,
                          const bool send_bcast) {
-    Iface* iface = getIface(ifname);
+    IfacePtr iface = getIface(ifname);
     if (!iface) {
         isc_throw(BadValue, "There is no " << ifname << " interface present.");
     }
@@ -744,10 +705,7 @@ int IfaceMgr::openSocketFromIface(const std::string& ifname,
                                   const uint16_t port,
                                   const uint8_t family) {
     // Search for specified interface among detected interfaces.
-    for (IfaceCollection::iterator iface = ifaces_.begin();
-         iface != ifaces_.end();
-         ++iface) {
-
+    BOOST_FOREACH(IfacePtr iface, ifaces_) {
         if ((iface->getFullName() != ifname) &&
             (iface->getName() != ifname)) {
             continue;
@@ -788,24 +746,17 @@ int IfaceMgr::openSocketFromAddress(const IOAddress& addr,
                                     const uint16_t port) {
     // Search through detected interfaces and addresses to match
     // local address we got.
-    for (IfaceCollection::iterator iface = ifaces_.begin();
-         iface != ifaces_.end();
-         ++iface) {
-
-        Iface::AddressCollection addrs = iface->getAddresses();
-
-        for (Iface::AddressCollection::iterator addr_it = addrs.begin();
-             addr_it != addrs.end();
-             ++addr_it) {
+    BOOST_FOREACH(IfacePtr iface, ifaces_) {
+        BOOST_FOREACH(Iface::Address a, iface->getAddresses()) {
 
             // Local address must match one of the addresses
             // on detected interfaces. If it does, we have
             // address and interface detected so we can open
             // socket.
-            if (addr_it->get() == addr) {
+            if (a.get() == addr) {
                 // Open socket using local interface, address and port.
                 // This may cause isc::Unexpected exception.
-                return (openSocket(iface->getName(), *addr_it, port, false));
+                return (openSocket(iface->getName(), a, port, false));
             }
         }
     }
@@ -898,7 +849,7 @@ IfaceMgr::openSocket4(Iface& iface, const IOAddress& addr,
 
 bool
 IfaceMgr::send(const Pkt6Ptr& pkt) {
-    Iface* iface = getIface(pkt->getIface());
+    IfacePtr iface = getIface(pkt->getIface());
     if (!iface) {
         isc_throw(BadValue, "Unable to send DHCPv6 message. Invalid interface ("
                   << pkt->getIface() << ") specified.");
@@ -911,7 +862,7 @@ IfaceMgr::send(const Pkt6Ptr& pkt) {
 bool
 IfaceMgr::send(const Pkt4Ptr& pkt) {
 
-    Iface* iface = getIface(pkt->getIface());
+    IfacePtr iface = getIface(pkt->getIface());
     if (!iface) {
         isc_throw(BadValue, "Unable to send DHCPv4 message. Invalid interface ("
                   << pkt->getIface() << ") specified.");
@@ -930,7 +881,7 @@ IfaceMgr::receive4(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */) {
                   " one million microseconds");
     }
     const SocketInfo* candidate = 0;
-    IfaceCollection::iterator iface;
+    IfacePtr iface;
     fd_set sockets;
     int maxfd = 0;
 
@@ -939,19 +890,16 @@ IfaceMgr::receive4(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */) {
     /// @todo: marginal performance optimization. We could create the set once
     /// and then use its copy for select(). Please note that select() modifies
     /// provided set to indicated which sockets have something to read.
-    for (iface = ifaces_.begin(); iface != ifaces_.end(); ++iface) {
-
-        const Iface::SocketCollection& socket_collection = iface->getSockets();
-        for (Iface::SocketCollection::const_iterator s = socket_collection.begin();
-             s != socket_collection.end(); ++s) {
+    BOOST_FOREACH(iface, ifaces_) {
+        BOOST_FOREACH(SocketInfo s, iface->getSockets()) {
 
             // Only deal with IPv4 addresses.
-            if (s->addr_.isV4()) {
+            if (s.addr_.isV4()) {
 
                 // Add this socket to listening set
-                FD_SET(s->sockfd_, &sockets);
-                if (maxfd < s->sockfd_) {
-                    maxfd = s->sockfd_;
+                FD_SET(s.sockfd_, &sockets);
+                if (maxfd < s.sockfd_) {
+                    maxfd = s.sockfd_;
                 }
             }
         }
@@ -959,11 +907,10 @@ IfaceMgr::receive4(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */) {
 
     // if there are any callbacks for external sockets registered...
     if (!callbacks_.empty()) {
-        for (SocketCallbackInfoContainer::const_iterator s = callbacks_.begin();
-             s != callbacks_.end(); ++s) {
-            FD_SET(s->socket_, &sockets);
-            if (maxfd < s->socket_) {
-                maxfd = s->socket_;
+        BOOST_FOREACH(SocketCallbackInfo s, callbacks_) {
+            FD_SET(s.socket_, &sockets);
+            if (maxfd < s.socket_) {
+                maxfd = s.socket_;
             }
         }
     }
@@ -994,9 +941,8 @@ IfaceMgr::receive4(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */) {
     }
 
     // Let's find out which socket has the data
-    for (SocketCallbackInfoContainer::iterator s = callbacks_.begin();
-         s != callbacks_.end(); ++s) {
-        if (!FD_ISSET(s->socket_, &sockets)) {
+    BOOST_FOREACH(SocketCallbackInfo s, callbacks_) {
+        if (!FD_ISSET(s.socket_, &sockets)) {
             continue;
         }
 
@@ -1005,20 +951,18 @@ IfaceMgr::receive4(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */) {
         // Calling the external socket's callback provides its service
         // layer access without integrating any specific features
         // in IfaceMgr
-        if (s->callback_) {
-            s->callback_();
+        if (s.callback_) {
+            s.callback_();
         }
 
         return (Pkt4Ptr());
     }
 
     // Let's find out which interface/socket has the data
-    for (iface = ifaces_.begin(); iface != ifaces_.end(); ++iface) {
-        const Iface::SocketCollection& socket_collection = iface->getSockets();
-        for (Iface::SocketCollection::const_iterator s = socket_collection.begin();
-             s != socket_collection.end(); ++s) {
-            if (FD_ISSET(s->sockfd_, &sockets)) {
-                candidate = &(*s);
+    BOOST_FOREACH(iface, ifaces_) {
+        BOOST_FOREACH(SocketInfo s, iface->getSockets()) {
+            if (FD_ISSET(s.sockfd_, &sockets)) {
+                candidate = &(s);
                 break;
             }
         }
@@ -1052,19 +996,16 @@ Pkt6Ptr IfaceMgr::receive6(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */
     /// @todo: marginal performance optimization. We could create the set once
     /// and then use its copy for select(). Please note that select() modifies
     /// provided set to indicated which sockets have something to read.
-    IfaceCollection::const_iterator iface;
-    for (iface = ifaces_.begin(); iface != ifaces_.end(); ++iface) {
-        const Iface::SocketCollection& socket_collection = iface->getSockets();
-        for (Iface::SocketCollection::const_iterator s = socket_collection.begin();
-             s != socket_collection.end(); ++s) {
+    BOOST_FOREACH(IfacePtr iface, ifaces_) {
 
+        BOOST_FOREACH(SocketInfo s, iface->getSockets()) {
             // Only deal with IPv6 addresses.
-            if (s->addr_.isV6()) {
+            if (s.addr_.isV6()) {
 
                 // Add this socket to listening set
-                FD_SET(s->sockfd_, &sockets);
-                if (maxfd < s->sockfd_) {
-                    maxfd = s->sockfd_;
+                FD_SET(s.sockfd_, &sockets);
+                if (maxfd < s.sockfd_) {
+                    maxfd = s.sockfd_;
                 }
             }
         }
@@ -1072,13 +1013,11 @@ Pkt6Ptr IfaceMgr::receive6(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */
 
     // if there are any callbacks for external sockets registered...
     if (!callbacks_.empty()) {
-        for (SocketCallbackInfoContainer::const_iterator s = callbacks_.begin();
-             s != callbacks_.end(); ++s) {
-
+        BOOST_FOREACH(SocketCallbackInfo s, callbacks_) {
             // Add it to the set as well
-            FD_SET(s->socket_, &sockets);
-            if (maxfd < s->socket_) {
-                maxfd = s->socket_;
+            FD_SET(s.socket_, &sockets);
+            if (maxfd < s.socket_) {
+                maxfd = s.socket_;
             }
         }
     }
@@ -1109,9 +1048,8 @@ Pkt6Ptr IfaceMgr::receive6(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */
     }
 
     // Let's find out which socket has the data
-    for (SocketCallbackInfoContainer::iterator s = callbacks_.begin();
-         s != callbacks_.end(); ++s) {
-        if (!FD_ISSET(s->socket_, &sockets)) {
+    BOOST_FOREACH(SocketCallbackInfo s, callbacks_) {
+        if (!FD_ISSET(s.socket_, &sockets)) {
             continue;
         }
 
@@ -1120,20 +1058,18 @@ Pkt6Ptr IfaceMgr::receive6(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */
         // Calling the external socket's callback provides its service
         // layer access without integrating any specific features
         // in IfaceMgr
-        if (s->callback_) {
-            s->callback_();
+        if (s.callback_) {
+            s.callback_();
         }
 
         return (Pkt6Ptr());
     }
 
     // Let's find out which interface/socket has the data
-    for (iface = ifaces_.begin(); iface != ifaces_.end(); ++iface) {
-        const Iface::SocketCollection& socket_collection = iface->getSockets();
-        for (Iface::SocketCollection::const_iterator s = socket_collection.begin();
-             s != socket_collection.end(); ++s) {
-            if (FD_ISSET(s->sockfd_, &sockets)) {
-                candidate = &(*s);
+    BOOST_FOREACH(IfacePtr iface, ifaces_) {
+        BOOST_FOREACH(SocketInfo s, iface->getSockets()) {
+            if (FD_ISSET(s.sockfd_, &sockets)) {
+                candidate = &(s);
                 break;
             }
         }
@@ -1150,8 +1086,8 @@ Pkt6Ptr IfaceMgr::receive6(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */
 }
 
 uint16_t IfaceMgr::getSocket(const isc::dhcp::Pkt6& pkt) {
-    Iface* iface = getIface(pkt.getIface());
-    if (iface == NULL) {
+    IfacePtr iface = getIface(pkt.getIface());
+    if (!iface) {
         isc_throw(IfaceNotFound, "Tried to find socket for non-existent interface");
     }
 
@@ -1207,7 +1143,7 @@ uint16_t IfaceMgr::getSocket(const isc::dhcp::Pkt6& pkt) {
 
 SocketInfo
 IfaceMgr::getSocket(isc::dhcp::Pkt4 const& pkt) {
-    Iface* iface = getIface(pkt.getIface());
+    IfacePtr iface = getIface(pkt.getIface());
     if (iface == NULL) {
         isc_throw(IfaceNotFound, "Tried to find socket for non-existent interface");
     }

+ 17 - 10
src/lib/dhcp/iface_mgr.h

@@ -159,15 +159,21 @@ struct SocketInfo {
 /// returned by the OS kernel when the socket is opened. Hence, it is
 /// convenient to allocate the buffer when the socket is being opened and
 /// utilze it throughout the lifetime of the socket.
-class Iface {
+///
+/// In order to avoid potentially expensive copies of the @c Iface objects
+/// holding pre-allocated buffers and multiple containers, this class is
+/// noncopyable.
+class Iface : public boost::noncopyable {
 public:
 
     /// Maximum MAC address length (Infiniband uses 20 bytes)
     static const unsigned int MAX_MAC_LEN = 20;
 
+    /// @brief Address type.
+    typedef util::OptionalValue<asiolink::IOAddress> Address;
+
     /// Type that defines list of addresses
-    typedef
-    std::list<util::OptionalValue<asiolink::IOAddress> > AddressCollection;
+    typedef std::list<Address> AddressCollection;
 
     /// @brief Type that holds a list of socket information.
     ///
@@ -500,6 +506,8 @@ private:
     std::vector<uint8_t> read_buffer_;
 };
 
+typedef boost::shared_ptr<Iface> IfacePtr;
+
 /// @brief This type describes the callback function invoked when error occurs
 /// in the IfaceMgr.
 ///
@@ -543,8 +551,8 @@ public:
     //      2 maps (ifindex-indexed and name-indexed) and
     //      also hide it (make it public make tests easier for now)
 
-    /// Type that holds a list of interfaces.
-    typedef std::list<Iface> IfaceCollection;
+    /// Type that holds a list of pointers to interfaces.
+    typedef std::list<IfacePtr> IfaceCollection;
 
     /// IfaceMgr is a singleton class. This method returns reference
     /// to its sole instance.
@@ -582,14 +590,14 @@ public:
     /// @return true if direct response is supported.
     bool isDirectResponseSupported() const;
 
-    /// @brief Returns interfac specified interface index
+    /// @brief Returns interface specified interface index
     ///
     /// @param ifindex index of searched interface
     ///
     /// @return interface with requested index (or NULL if no such
     ///         interface is present)
     ///
-    Iface* getIface(int ifindex);
+    IfacePtr getIface(int ifindex);
 
     /// @brief Returns interface with specified interface name
     ///
@@ -597,8 +605,7 @@ public:
     ///
     /// @return interface with requested name (or NULL if no such
     ///         interface is present)
-    ///
-    Iface* getIface(const std::string& ifname);
+    IfacePtr getIface(const std::string& ifname);
 
     /// @brief Returns container with all interfaces.
     ///
@@ -1031,7 +1038,7 @@ public:
     /// @param iface reference to Iface object.
     /// @note This function must be public because it has to be callable
     /// from unit tests.
-    void addInterface(const Iface& iface) {
+    void addInterface(const IfacePtr& iface) {
         ifaces_.push_back(iface);
     }
 

+ 12 - 12
src/lib/dhcp/iface_mgr_bsd.cc

@@ -47,9 +47,9 @@ IfaceMgr::detectIfaces() {
         isc_throw(Unexpected, "Network interfaces detection failed.");
     }
 
-    typedef map<string, Iface> ifaceLst;
-    ifaceLst::iterator iface_iter;
-    ifaceLst ifaces;
+    typedef map<string, IfacePtr> IfaceLst;
+    IfaceLst::iterator iface_iter;
+    IfaceLst ifaces;
 
     // First lookup for getting interfaces ...
     for (ifptr = iflist; ifptr != 0; ifptr = ifptr->ifa_next) {
@@ -66,9 +66,9 @@ IfaceMgr::detectIfaces() {
             continue;
         }
 
-        Iface iface(ifname, ifindex);
-        iface.setFlags(ifptr->ifa_flags);
-        ifaces.insert(pair<string, Iface>(ifname, iface));
+        IfacePtr iface(new Iface(ifname, ifindex));
+        iface->setFlags(ifptr->ifa_flags);
+        ifaces.insert(pair<string, IfacePtr>(ifname, iface));
     }
 
     // Second lookup to get MAC and IP addresses
@@ -84,8 +84,8 @@ IfaceMgr::detectIfaces() {
                 reinterpret_cast<struct sockaddr_dl *>(ifptr->ifa_addr);
             ptr = reinterpret_cast<uint8_t *>(LLADDR(ldata));
 
-            iface_iter->second.setHWType(ldata->sdl_type);
-            iface_iter->second.setMac(ptr, ldata->sdl_alen);
+            iface_iter->second->setHWType(ldata->sdl_type);
+            iface_iter->second->setMac(ptr, ldata->sdl_alen);
         } else if(ifptr->ifa_addr->sa_family == AF_INET6) {
             // IPv6 Addr
             struct sockaddr_in6 * adata =
@@ -93,7 +93,7 @@ IfaceMgr::detectIfaces() {
             ptr = reinterpret_cast<uint8_t *>(&adata->sin6_addr);
 
             IOAddress a = IOAddress::fromBytes(AF_INET6, ptr);
-            iface_iter->second.addAddress(a);
+            iface_iter->second->addAddress(a);
         } else {
             // IPv4 Addr
             struct sockaddr_in * adata =
@@ -101,16 +101,16 @@ IfaceMgr::detectIfaces() {
             ptr = reinterpret_cast<uint8_t *>(&adata->sin_addr);
 
             IOAddress a = IOAddress::fromBytes(AF_INET, ptr);
-            iface_iter->second.addAddress(a);
+            iface_iter->second->addAddress(a);
         }
     }
 
     freeifaddrs(iflist);
 
     // Interfaces registering
-    for(ifaceLst::const_iterator iface_iter = ifaces.begin();
+    for(IfaceLst::const_iterator iface_iter = ifaces.begin();
         iface_iter != ifaces.end(); ++iface_iter) {
-        ifaces_.push_back(iface_iter->second);
+        addInterface(iface_iter->second);
     }
 }
 

+ 1 - 1
src/lib/dhcp/pkt.cc

@@ -257,7 +257,7 @@ Pkt::getMACFromIPv6(const isc::asiolink::IOAddress& addr) {
 
     // Let's get the interface this packet was received on. We need it to get
     // hardware type
-    Iface* iface = IfaceMgr::instance().getIface(iface_);
+    IfacePtr iface = IfaceMgr::instance().getIface(iface_);
     uint16_t hwtype = 0; // not specified
     if (iface) {
         hwtype = iface->getHWType();

+ 1 - 1
src/lib/dhcp/pkt6.cc

@@ -706,7 +706,7 @@ Pkt6::getMACFromRemoteIdRelayOption() {
 
         // Let's get the interface this packet was received on. We need it to get
         // the hardware type.
-        Iface* iface = IfaceMgr::instance().getIface(iface_);
+        IfacePtr iface = IfaceMgr::instance().getIface(iface_);
         uint16_t hwtype = 0; // not specified
 
         // If we get the interface HW type, great! If not, let's not panic.

+ 1 - 1
src/lib/dhcp/pkt_filter_inet6.cc

@@ -224,7 +224,7 @@ PktFilterInet6::receive(const SocketInfo& socket_info) {
     pkt->setRemotePort(ntohs(from.sin6_port));
     pkt->setIndex(ifindex);
 
-    Iface* received = IfaceMgr::instance().getIface(pkt->getIndex());
+    IfacePtr received = IfaceMgr::instance().getIface(pkt->getIndex());
     if (received) {
         pkt->setIface(received->getName());
     } else {

+ 31 - 35
src/lib/dhcp/tests/iface_mgr_test_config.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -19,6 +19,8 @@
 #include <dhcp/tests/pkt_filter_test_stub.h>
 #include <dhcp/tests/pkt_filter6_test_stub.h>
 
+#include <boost/foreach.hpp>
+
 using namespace isc::asiolink;
 
 namespace isc {
@@ -52,8 +54,8 @@ IfaceMgrTestConfig::~IfaceMgrTestConfig() {
 void
 IfaceMgrTestConfig::addAddress(const std::string& iface_name,
                                const IOAddress& address) {
-    Iface* iface = IfaceMgr::instance().getIface(iface_name);
-    if (iface == NULL) {
+    IfacePtr iface = IfaceMgr::instance().getIface(iface_name);
+    if (!iface) {
         isc_throw(isc::BadValue, "interface '" << iface_name
                   << "' doesn't exist");
     }
@@ -61,7 +63,7 @@ IfaceMgrTestConfig::addAddress(const std::string& iface_name,
 }
 
 void
-IfaceMgrTestConfig::addIface(const Iface& iface) {
+IfaceMgrTestConfig::addIface(const IfacePtr& iface) {
     IfaceMgr::instance().addInterface(iface);
 }
 
@@ -70,27 +72,27 @@ IfaceMgrTestConfig::addIface(const std::string& name, const int ifindex) {
     IfaceMgr::instance().addInterface(createIface(name, ifindex));
 }
 
-Iface
+IfacePtr
 IfaceMgrTestConfig::createIface(const std::string &name, const int ifindex) {
-    Iface iface(name, ifindex);
+    IfacePtr iface(new Iface(name, ifindex));
     if (name == "lo") {
-        iface.flag_loopback_ = true;
+        iface->flag_loopback_ = true;
         // Don't open sockets on the loopback interface.
-        iface.inactive4_ = true;
-        iface.inactive6_ = true;
+        iface->inactive4_ = true;
+        iface->inactive6_ = true;
     } else {
-        iface.inactive4_ = false;
-        iface.inactive6_ = false;
+        iface->inactive4_ = false;
+        iface->inactive6_ = false;
     }
-    iface.flag_multicast_ = true;
+    iface->flag_multicast_ = true;
     // On BSD systems, the SO_BINDTODEVICE option is not supported.
     // Therefore the IfaceMgr will throw an exception on attempt to
     // open sockets on more than one broadcast-capable interface at
     // the same time. In order to prevent this error, we mark all
     // interfaces broadcast-incapable for unit testing.
-    iface.flag_broadcast_ = false;
-    iface.flag_up_ = true;
-    iface.flag_running_ = true;
+    iface->flag_broadcast_ = false;
+    iface->flag_up_ = true;
+    iface->flag_running_ = true;
     return (iface);
 }
 
@@ -132,7 +134,7 @@ IfaceMgrTestConfig::setIfaceFlags(const std::string& name,
                                   const FlagRunning& running,
                                   const FlagInactive4& inactive4,
                                   const FlagInactive6& inactive6) {
-    Iface* iface = IfaceMgr::instance().getIface(name);
+    IfacePtr iface = IfaceMgr::instance().getIface(name);
     if (iface == NULL) {
         isc_throw(isc::BadValue, "interface '" << name << "' doesn't exist");
     }
@@ -146,15 +148,13 @@ IfaceMgrTestConfig::setIfaceFlags(const std::string& name,
 bool
 IfaceMgrTestConfig::socketOpen(const std::string& iface_name,
                                const int family) const {
-    Iface* iface = IfaceMgr::instance().getIface(iface_name);
+    IfacePtr iface = IfaceMgr::instance().getIface(iface_name);
     if (iface == NULL) {
         isc_throw(Unexpected, "No such interface '" << iface_name << "'");
     }
 
-    const Iface::SocketCollection& sockets = iface->getSockets();
-    for (Iface::SocketCollection::const_iterator sock = sockets.begin();
-         sock != sockets.end(); ++sock) {
-        if (sock->family_ == family) {
+    BOOST_FOREACH(SocketInfo sock, iface->getSockets()) {
+        if (sock.family_ == family) {
             return (true);
         }
     }
@@ -164,16 +164,14 @@ IfaceMgrTestConfig::socketOpen(const std::string& iface_name,
 bool
 IfaceMgrTestConfig::socketOpen(const std::string& iface_name,
                                const std::string& address) const {
-    Iface* iface = IfaceMgr::instance().getIface(iface_name);
-    if (iface == NULL) {
+    IfacePtr iface = IfaceMgr::instance().getIface(iface_name);
+    if (!iface) {
         isc_throw(Unexpected, "No such interface '" << iface_name << "'");
     }
 
-    const Iface::SocketCollection& sockets = iface->getSockets();
-    for (Iface::SocketCollection::const_iterator sock = sockets.begin();
-         sock != sockets.end(); ++sock) {
-        if ((sock->family_ == AF_INET) &&
-            (sock->addr_ == IOAddress(address))) {
+    BOOST_FOREACH(SocketInfo sock, iface->getSockets()) {
+        if ((sock.family_ == AF_INET) &&
+            (sock.addr_ == IOAddress(address))) {
             return (true);
         }
     }
@@ -182,16 +180,14 @@ IfaceMgrTestConfig::socketOpen(const std::string& iface_name,
 
 bool
 IfaceMgrTestConfig::unicastOpen(const std::string& iface_name) const {
-    Iface* iface = IfaceMgr::instance().getIface(iface_name);
-    if (iface == NULL) {
+    IfacePtr iface = IfaceMgr::instance().getIface(iface_name);
+    if (!iface) {
         isc_throw(Unexpected, "No such interface '" << iface_name << "'");
     }
 
-    const Iface::SocketCollection& sockets = iface->getSockets();
-    for (Iface::SocketCollection::const_iterator sock = sockets.begin();
-         sock != sockets.end(); ++sock) {
-        if ((!sock->addr_.isV6LinkLocal()) &&
-            (!sock->addr_.isV6Multicast())) {
+    BOOST_FOREACH(SocketInfo sock, iface->getSockets()) {
+        if ((!sock.addr_.isV6LinkLocal()) &&
+            (!sock.addr_.isV6Multicast())) {
             return (true);
         }
     }

+ 2 - 2
src/lib/dhcp/tests/iface_mgr_test_config.h

@@ -161,7 +161,7 @@ public:
     /// @brief Configures new interface for the @c IfaceMgr.
     ///
     /// @param iface Object encapsulating interface to be added.
-    void addIface(const Iface& iface);
+    void addIface(const IfacePtr& iface);
 
     /// @brief Configures new interface for the @c IfaceMgr.
     ///
@@ -188,7 +188,7 @@ public:
     /// @param ifindex An index of the interface to be created.
     ///
     /// @return An object representing interface.
-    static Iface createIface(const std::string& name, const int ifindex);
+    static IfacePtr createIface(const std::string& name, const int ifindex);
 
     /// @brief Creates a default (example) set of fake interfaces.
     void createIfaces();

+ 56 - 61
src/lib/dhcp/tests/iface_mgr_unittest.cc

@@ -24,6 +24,7 @@
 #include <dhcp/tests/pkt_filter6_test_utils.h>
 
 #include <boost/bind.hpp>
+#include <boost/foreach.hpp>
 #include <boost/scoped_ptr.hpp>
 #include <gtest/gtest.h>
 
@@ -228,20 +229,20 @@ public:
         ifaces_.clear();
 
         // local loopback
-        Iface lo = createIface("lo", 0);
-        lo.addAddress(IOAddress("127.0.0.1"));
-        lo.addAddress(IOAddress("::1"));
+        IfacePtr lo = createIface("lo", 0);
+        lo->addAddress(IOAddress("127.0.0.1"));
+        lo->addAddress(IOAddress("::1"));
         ifaces_.push_back(lo);
         // eth0
-        Iface eth0 = createIface("eth0", 1);
-        eth0.addAddress(IOAddress("10.0.0.1"));
-        eth0.addAddress(IOAddress("fe80::3a60:77ff:fed5:cdef"));
-        eth0.addAddress(IOAddress("2001:db8:1::1"));
+        IfacePtr eth0 = createIface("eth0", 1);
+        eth0->addAddress(IOAddress("10.0.0.1"));
+        eth0->addAddress(IOAddress("fe80::3a60:77ff:fed5:cdef"));
+        eth0->addAddress(IOAddress("2001:db8:1::1"));
         ifaces_.push_back(eth0);
         // eth1
-        Iface eth1 = createIface("eth1", 2);
-        eth1.addAddress(IOAddress("192.0.2.3"));
-        eth1.addAddress(IOAddress("fe80::3a60:77ff:fed5:abcd"));
+        IfacePtr eth1 = createIface("eth1", 2);
+        eth1->addAddress(IOAddress("192.0.2.3"));
+        eth1->addAddress(IOAddress("fe80::3a60:77ff:fed5:abcd"));
         ifaces_.push_back(eth1);
     }
 
@@ -263,26 +264,26 @@ public:
     /// @param ifindex An index of the interface to be created.
     ///
     /// @return An object representing interface.
-    static Iface createIface(const std::string& name, const int ifindex) {
-        Iface iface(name, ifindex);
+    static IfacePtr createIface(const std::string& name, const int ifindex) {
+        IfacePtr iface(new Iface(name, ifindex));
         if (name == "lo") {
-            iface.flag_loopback_ = true;
+            iface->flag_loopback_ = true;
             // Don't open sockets on loopback interface.
-            iface.inactive4_ = true;
-            iface.inactive6_ = true;
+            iface->inactive4_ = true;
+            iface->inactive6_ = true;
         } else {
-            iface.inactive4_ = false;
-            iface.inactive6_ = false;
+            iface->inactive4_ = false;
+            iface->inactive6_ = false;
         }
-        iface.flag_multicast_ = true;
+        iface->flag_multicast_ = true;
         // On BSD systems, the SO_BINDTODEVICE option is not supported.
         // Therefore the IfaceMgr will throw an exception on attempt to
         // open sockets on more than one broadcast-capable interface at
         // the same time. In order to prevent this error, we mark all
         // interfaces broadcast-incapable for unit testing.
-        iface.flag_broadcast_ = false;
-        iface.flag_up_ = true;
-        iface.flag_running_ = true;
+        iface->flag_broadcast_ = false;
+        iface->flag_up_ = true;
+        iface->flag_running_ = true;
         return (iface);
     }
 
@@ -294,8 +295,8 @@ public:
     ///
     /// @return true if there is a socket bound to the specified address.
     bool isBound(const std::string& iface_name, const std::string& addr) {
-        Iface* iface = getIface(iface_name);
-        if (iface == NULL) {
+        IfacePtr iface = getIface(iface_name);
+        if (!iface) {
             ADD_FAILURE() << "the interface " << iface_name << " doesn't exist";
             return (false);
         }
@@ -304,13 +305,11 @@ public:
              sock != sockets.end(); ++sock) {
             if (sock->addr_ == IOAddress(addr)) {
                 return (true);
+
             } else if ((sock->addr_ == IOAddress("::")) &&
                        (IOAddress(addr).isV6LinkLocal())) {
-                for (Iface::AddressCollection::const_iterator addr_it =
-                         iface->getAddresses().begin();
-                     addr_it != iface->getAddresses().end();
-                     ++addr_it) {
-                    if (addr_it->get() == IOAddress(addr)) {
+                BOOST_FOREACH(Iface::Address a, iface->getAddresses()) {
+                    if (a.get() == IOAddress(addr)) {
                         return (true);
                     }
                 }
@@ -332,12 +331,12 @@ public:
                        const bool inactive6) {
         for (IfaceMgr::IfaceCollection::iterator iface = ifaces_.begin();
              iface != ifaces_.end(); ++iface) {
-            if (iface->getName() == name) {
-                iface->flag_loopback_ = loopback;
-                iface->flag_up_ = up;
-                iface->flag_running_ = running;
-                iface->inactive4_ = inactive4;
-                iface->inactive6_ = inactive6;
+            if ((*iface)->getName() == name) {
+                (*iface)->flag_loopback_ = loopback;
+                (*iface)->flag_up_ = up;
+                (*iface)->flag_running_ = running;
+                (*iface)->inactive4_ = inactive4;
+                (*iface)->inactive6_ = inactive6;
             }
         }
     }
@@ -550,7 +549,7 @@ TEST_F(IfaceMgrTest, closeSockets) {
     // to create one and add.
     int ifindex = if_nametoindex(LOOPBACK);
     ASSERT_GT(ifindex, 0);
-    Iface lo_iface(LOOPBACK, ifindex);
+    IfacePtr lo_iface(new Iface(LOOPBACK, ifindex));
     iface_mgr->getIfacesLst().push_back(lo_iface);
 
     // Create set of V4 and V6 sockets on the loopback interface.
@@ -569,7 +568,7 @@ TEST_F(IfaceMgrTest, closeSockets) {
     }
 
     // At the end we should have 3 IPv4 and 3 IPv6 sockets open.
-    Iface* iface = iface_mgr->getIface(LOOPBACK);
+    IfacePtr iface = iface_mgr->getIface(LOOPBACK);
     ASSERT_TRUE(iface != NULL);
 
     int v4_sockets_count = getOpenSocketsCount(*iface, AF_INET);
@@ -632,8 +631,8 @@ TEST_F(IfaceMgrTest, ifaceGetAddress) {
 TEST_F(IfaceMgrTest, ifaceHasAddress) {
     IfaceMgrTestConfig config(true);
 
-    Iface* iface = IfaceMgr::instance().getIface("eth0");
-    ASSERT_FALSE(iface == NULL);
+    IfacePtr iface = IfaceMgr::instance().getIface("eth0");
+    ASSERT_TRUE(iface);
     EXPECT_TRUE(iface->hasAddress(IOAddress("10.0.0.1")));
     EXPECT_FALSE(iface->hasAddress(IOAddress("10.0.0.2")));
     EXPECT_TRUE(iface->hasAddress(IOAddress("fe80::3a60:77ff:fed5:cdef")));
@@ -649,10 +648,10 @@ TEST_F(IfaceMgrTest, getIface) {
     scoped_ptr<NakedIfaceMgr> ifacemgr(new NakedIfaceMgr());
 
     // Interface name, ifindex
-    Iface iface1("lo1", 100);
-    Iface iface2("eth9", 101);
-    Iface iface3("en3", 102);
-    Iface iface4("e1000g4", 103);
+    IfacePtr iface1(new Iface("lo1", 100));
+    IfacePtr iface2(new Iface("eth9", 101));
+    IfacePtr iface3(new Iface("en3", 102));
+    IfacePtr iface4(new Iface("e1000g4", 103));
     cout << "This test assumes that there are less than 100 network interfaces"
          << " in the tested system and there are no lo1, eth9, en3, e1000g4"
          << " or wifi15 interfaces present." << endl;
@@ -668,26 +667,26 @@ TEST_F(IfaceMgrTest, getIface) {
     for (IfaceMgr::IfaceCollection::iterator iface=ifacemgr->getIfacesLst().begin();
          iface != ifacemgr->getIfacesLst().end();
          ++iface) {
-        cout << "  " << iface->getFullName() << endl;
+        cout << "  " << (*iface)->getFullName() << endl;
     }
 
 
     // Check that interface can be retrieved by ifindex
-    Iface* tmp = ifacemgr->getIface(102);
-    ASSERT_TRUE(tmp != NULL);
+    IfacePtr tmp = ifacemgr->getIface(102);
+    ASSERT_TRUE(tmp);
 
     EXPECT_EQ("en3", tmp->getName());
     EXPECT_EQ(102, tmp->getIndex());
 
     // Check that interface can be retrieved by name
     tmp = ifacemgr->getIface("lo1");
-    ASSERT_TRUE(tmp != NULL);
+    ASSERT_TRUE(tmp);
 
     EXPECT_EQ("lo1", tmp->getName());
     EXPECT_EQ(100, tmp->getIndex());
 
     // Check that non-existing interfaces are not returned
-    EXPECT_EQ(static_cast<void*>(NULL), ifacemgr->getIface("wifi15") );
+    EXPECT_FALSE(ifacemgr->getIface("wifi15") );
 }
 
 TEST_F(IfaceMgrTest, clearIfaces) {
@@ -838,7 +837,7 @@ TEST_F(IfaceMgrTest, multipleSockets) {
 
     // Get loopback interface. If we don't find one we are unable to run
     // this test but we don't want to fail.
-    Iface* iface_ptr = ifacemgr->getIface(LOOPBACK);
+    IfacePtr iface_ptr = ifacemgr->getIface(LOOPBACK);
     if (iface_ptr == NULL) {
         cout << "Local loopback interface not found. Skipping test. " << endl;
         return;
@@ -2172,7 +2171,7 @@ TEST_F(IfaceMgrTest, socketInfo) {
 
     // Now let's test if IfaceMgr handles socket info properly
     scoped_ptr<NakedIfaceMgr> ifacemgr(new NakedIfaceMgr());
-    Iface* loopback = ifacemgr->getIface(LOOPBACK);
+    IfacePtr loopback = ifacemgr->getIface(LOOPBACK);
     ASSERT_TRUE(loopback);
     loopback->addSocket(sock1);
     loopback->addSocket(sock2);
@@ -2360,10 +2359,8 @@ checkIfAddrs(const Iface & iface, struct ifaddrs *& ifptr) {
 
             IOAddress addrv4 = IOAddress::fromBytes(AF_INET, p);
 
-            for (Iface::AddressCollection::const_iterator a =
-                     iface.getAddresses().begin();
-                 a != iface.getAddresses().end(); ++ a) {
-                if(a->get().isV4() && (a->get()) == addrv4) {
+            BOOST_FOREACH(Iface::Address a, iface.getAddresses()) {
+                if(a.get().isV4() && (a.get()) == addrv4) {
                     return (true);
                 }
             }
@@ -2377,10 +2374,8 @@ checkIfAddrs(const Iface & iface, struct ifaddrs *& ifptr) {
 
             IOAddress addrv6 = IOAddress::fromBytes(AF_INET6, p);
 
-            for(Iface::AddressCollection::const_iterator a =
-                    iface.getAddresses().begin();
-                a != iface.getAddresses().end(); ++ a) {
-                if (a->get().isV6() && (a->get() == addrv6)) {
+            BOOST_FOREACH(Iface::Address a, iface.getAddresses()) {
+                if (a.get().isV6() && (a.get() == addrv6)) {
                     return (true);
                 }
             }
@@ -2420,7 +2415,7 @@ TEST_F(IfaceMgrTest, detectIfaces) {
         // with the interface name held by IfaceMgr. Instead, we use the
         // index of the interface because the virtual interfaces have the
         // same indexes as the physical interfaces.
-        Iface* i = ifacemgr.getIface(if_nametoindex(ifptr->ifa_name));
+        IfacePtr i = ifacemgr.getIface(if_nametoindex(ifptr->ifa_name));
 
         // If the given interface was also detected by the IfaceMgr,
         // check that its properties are correct.
@@ -2819,7 +2814,7 @@ TEST_F(IfaceMgrTest, DISABLED_openUnicastSockets) {
     scoped_ptr<NakedIfaceMgr> ifacemgr(new NakedIfaceMgr());
 
     // Get the interface (todo: which interface)
-    Iface* iface = ifacemgr->getIface("eth0");
+    IfacePtr iface = ifacemgr->getIface("eth0");
     ASSERT_TRUE(iface);
     iface->inactive6_ = false;
 
@@ -2843,8 +2838,8 @@ TEST_F(IfaceMgrTest, DISABLED_openUnicastSockets) {
 TEST_F(IfaceMgrTest, unicastDuplicates) {
     NakedIfaceMgr ifacemgr;
 
-    Iface* iface = ifacemgr.getIface(LOOPBACK);
-    if (iface == NULL) {
+    IfacePtr iface = ifacemgr.getIface(LOOPBACK);
+    if (iface) {
         cout << "Local loopback interface not found. Skipping test. " << endl;
         return;
     }

+ 4 - 4
src/lib/dhcp/tests/pkt6_unittest.cc

@@ -926,7 +926,7 @@ TEST_F(Pkt6Test, getMACFromIPv6LinkLocal_direct) {
     Pkt6 pkt(DHCPV6_ADVERTISE, 1234);
 
     // Let's get the first interface
-    Iface* iface = IfaceMgr::instance().getIface(1);
+    IfacePtr iface = IfaceMgr::instance().getIface(1);
     ASSERT_TRUE(iface);
 
     // and set source interface data properly. getMACFromIPv6LinkLocal attempts
@@ -968,7 +968,7 @@ TEST_F(Pkt6Test, getMACFromIPv6LinkLocal_singleRelay) {
     ASSERT_EQ(1, pkt.relay_info_.size());
 
     // Let's get the first interface
-    Iface* iface = IfaceMgr::instance().getIface(1);
+    IfacePtr iface = IfaceMgr::instance().getIface(1);
     ASSERT_TRUE(iface);
 
     // and set source interface data properly. getMACFromIPv6LinkLocal attempts
@@ -1034,7 +1034,7 @@ TEST_F(Pkt6Test, getMACFromIPv6LinkLocal_multiRelay) {
     ASSERT_EQ(3, pkt.relay_info_.size());
 
     // Let's get the first interface
-    Iface* iface = IfaceMgr::instance().getIface(1);
+    IfacePtr iface = IfaceMgr::instance().getIface(1);
     ASSERT_TRUE(iface);
 
     // and set source interface data properly. getMACFromIPv6LinkLocal attempts
@@ -1253,7 +1253,7 @@ TEST_F(Pkt6Test, getMACFromRemoteIdRelayOption) {
     EXPECT_FALSE(pkt.getMAC(HWAddr::HWADDR_SOURCE_REMOTE_ID));
 
     // Let's get the first interface
-    Iface* iface = IfaceMgr::instance().getIface(1);
+    IfacePtr iface = IfaceMgr::instance().getIface(1);
     ASSERT_TRUE(iface);
 
     // and set source interface data properly. getMACFromIPv6LinkLocal attempts

+ 5 - 5
src/lib/dhcp/tests/pkt_filter6_test_utils.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2013-2014 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2015 Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -16,6 +16,8 @@
 #include <dhcp/pkt6.h>
 #include <dhcp/tests/pkt_filter6_test_utils.h>
 
+#include <boost/foreach.hpp>
+
 #include <arpa/inet.h>
 #include <netinet/in.h>
 #include <sys/socket.h>
@@ -185,10 +187,8 @@ PktFilter6Stub::openSocket(const Iface& iface, const isc::asiolink::IOAddress& a
                            const uint16_t port, const bool) {
     // Check if there is any other socket bound to the specified address
     // and port on this interface.
-    const Iface::SocketCollection& sockets = iface.getSockets();
-    for (Iface::SocketCollection::const_iterator socket = sockets.begin();
-         socket != sockets.end(); ++socket) {
-        if ((socket->addr_ == addr) && (socket->port_ == port)) {
+    BOOST_FOREACH(SocketInfo socket, iface.getSockets()) {
+        if ((socket.addr_ == addr) && (socket.port_ == port)) {
             isc_throw(SocketConfigError, "test socket bind error");
         }
     }

+ 15 - 20
src/lib/dhcpsrv/cfg_iface.cc

@@ -17,6 +17,7 @@
 #include <dhcpsrv/cfg_iface.h>
 #include <util/strutil.h>
 #include <boost/bind.hpp>
+#include <boost/foreach.hpp>
 #include <algorithm>
 
 using namespace isc::asiolink;
@@ -46,8 +47,7 @@ CfgIface::equals(const CfgIface& other) const {
 bool
 CfgIface::multipleAddressesPerInterfaceActive() const {
     const IfaceMgr::IfaceCollection& ifaces = IfaceMgr::instance().getIfaces();
-    for (IfaceMgr::IfaceCollection::const_iterator iface = ifaces.begin();
-         iface != ifaces.end(); ++iface) {
+    BOOST_FOREACH(IfacePtr iface, ifaces) {
         if (iface->countActive4() > 1) {
             return (true);
         }
@@ -88,7 +88,7 @@ CfgIface::openSockets(const uint16_t family, const uint16_t port,
     if (!wildcard_used_) {
         for (IfaceSet::const_iterator iface_name = iface_set_.begin();
              iface_name != iface_set_.end(); ++iface_name) {
-            Iface* iface = IfaceMgr::instance().getIface(*iface_name);
+            IfacePtr iface = IfaceMgr::instance().getIface(*iface_name);
             // This shouldn't really happen because we are checking the
             // names of interfaces when they are being added (use()
             // function). But, if someone has triggered detection of
@@ -113,7 +113,7 @@ CfgIface::openSockets(const uint16_t family, const uint16_t port,
     // for DHCPv4.
     for (ExplicitAddressMap::const_iterator unicast = address_map_.begin();
          unicast != address_map_.end(); ++unicast) {
-        Iface* iface = IfaceMgr::instance().getIface(unicast->first);
+        IfacePtr iface = IfaceMgr::instance().getIface(unicast->first);
         if (iface == NULL) {
             isc_throw(Unexpected,
                       "fail to open unicast socket on interface '"
@@ -172,20 +172,17 @@ CfgIface::reset() {
 void
 CfgIface::setState(const uint16_t family, const bool inactive,
                    const bool loopback_inactive) const {
-    IfaceMgr::IfaceCollection ifaces = IfaceMgr::instance().getIfaces();
-    for (IfaceMgr::IfaceCollection::iterator iface = ifaces.begin();
-         iface != ifaces.end(); ++iface) {
-        Iface* iface_ptr = IfaceMgr::instance().getIface(iface->getName());
-        bool iface_inactive = iface_ptr->flag_loopback_ ?
-            loopback_inactive : inactive;
+    const IfaceMgr::IfaceCollection& ifaces = IfaceMgr::instance().getIfaces();
+    BOOST_FOREACH(IfacePtr iface, ifaces) {
+        bool iface_inactive = iface->flag_loopback_ ? loopback_inactive : inactive;
         if (family == AF_INET) {
-            iface_ptr->inactive4_ = iface_inactive;
+            iface->inactive4_ = iface_inactive;
         } else {
-            iface_ptr->inactive6_ = iface_inactive;
+            iface->inactive6_ = iface_inactive;
         }
 
         // Activate/deactivate all addresses.
-        setIfaceAddrsState(family, !inactive, *iface_ptr);
+        setIfaceAddrsState(family, !inactive, *iface);
     }
 }
 
@@ -193,11 +190,9 @@ void
 CfgIface::setIfaceAddrsState(const uint16_t family, const bool active,
                              Iface& iface) const {
     // Activate/deactivate all addresses.
-    const Iface::AddressCollection addresses = iface.getAddresses();
-    for (Iface::AddressCollection::const_iterator addr_it =
-                 addresses.begin(); addr_it != addresses.end(); ++addr_it) {
-        if (addr_it->get().getFamily() == family) {
-            iface.setActive(addr_it->get(), active);
+    BOOST_FOREACH(Iface::Address addr, iface.getAddresses()) {
+        if (addr.get().getFamily() == family) {
+            iface.setActive(addr.get(), active);
         }
     }
 }
@@ -304,8 +299,8 @@ CfgIface::use(const uint16_t family, const std::string& iface_name) {
         }
 
         // Interface must exist.
-        Iface* iface = IfaceMgr::instance().getIface(name);
-        if (iface == NULL) {
+        IfacePtr iface = IfaceMgr::instance().getIface(name);
+        if (!iface) {
             isc_throw(NoSuchIface, "interface '" << name
                       << "' doesn't exist in the system");
 

+ 1 - 1
src/lib/dhcpsrv/cfg_subnets4.cc

@@ -91,7 +91,7 @@ CfgSubnets4::selectSubnet(const SubnetSelector& selector) const {
     // If local interface name is known, use the local address on this
     // interface.
     } else if (!selector.iface_name_.empty()) {
-        Iface* iface = IfaceMgr::instance().getIface(selector.iface_name_);
+        IfacePtr iface = IfaceMgr::instance().getIface(selector.iface_name_);
         // This should never happen in the real life. Hence we throw an
         // exception.
         if (iface == NULL) {