2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-30 21:45:37 +00:00

[master] Merge branch 'trac3715'

This commit is contained in:
Marcin Siodelski
2015-03-13 18:04:43 +01:00
19 changed files with 274 additions and 357 deletions

View File

@@ -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,

View File

@@ -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_)) {

View File

@@ -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

View File

@@ -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");
}

View File

@@ -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

View File

@@ -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());
}

View File

@@ -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");
}

View File

@@ -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);
}

View File

@@ -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);
}
}

View File

@@ -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();

View File

@@ -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.

View File

@@ -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 {

View File

@@ -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);
}
}

View File

@@ -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();

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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");
}
}

View File

@@ -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");

View File

@@ -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) {