Commit 7415c74e authored by Marcin Siodelski's avatar Marcin Siodelski
Browse files

[master] Merge branch 'trac3715'

parents 3be57b28 7436a40a
......@@ -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,
......
......@@ -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_)) {
......
......@@ -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
......
// 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");
}
......
......@@ -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
......
// 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());
}
......
This diff is collapsed.
......@@ -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);
}
......
......@@ -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);
}
}
......
......@@ -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();
......
......@@ -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.
......
......@@ -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 {
......
// 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);
}
}
......
......@@ -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();
......
......@@ -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;