Fix a couple of memory leaks

This commit is contained in:
Daniel Adolfsson 2012-02-03 22:25:00 +01:00
parent 6723f2f4b6
commit 7956724a8e
10 changed files with 119 additions and 62 deletions

View File

@ -42,12 +42,12 @@
NDPPD_NS_BEGIN
std::map<std::string, ptr<iface> > iface::_map;
std::map<std::string, weak_ptr<iface> > iface::_map;
std::vector<struct pollfd> iface::_pollfds;
iface::iface() :
_ifd(-1), _pfd(-1)
_ifd(-1), _pfd(-1), _name("")
{
}
@ -59,16 +59,20 @@ iface::~iface()
close(_ifd);
if (_pfd >= 0) {
if (_prev_allmulti >= 0) {
allmulti(_prev_allmulti);
}
close(_pfd);
}
_map.erase(_name);
}
ptr<iface> iface::open_pfd(const std::string& name)
{
int fd;
int fd = 0;
std::map<std::string, ptr<iface> >::iterator it = _map.find(name);
std::map<std::string, weak_ptr<iface> >::iterator it = _map.find(name);
ptr<iface> ifa;
@ -124,10 +128,7 @@ ptr<iface> iface::open_pfd(const std::string& name)
// Set up filter.
struct sock_fprog fprog;
static const struct sock_filter filter[] =
{
static struct sock_filter filter[] = {
// Load the ether_type.
BPF_STMT(BPF_LD | BPF_H | BPF_ABS,
offsetof(struct ether_header, ether_type)),
@ -149,14 +150,19 @@ ptr<iface> iface::open_pfd(const std::string& name)
BPF_STMT(BPF_RET | BPF_K, 0)
};
fprog.filter = (struct sock_filter* )filter;
fprog.len = 8;
static struct sock_fprog fprog = {
8,
filter
};
if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &fprog, sizeof(fprog)) < 0) {
logger::error() << "Failed to set filter";
return ptr<iface>();
}
// Eh. Allmulti.
ifa->_prev_allmulti = ifa->allmulti(1);
// Set up an instance of 'iface'.
ifa->_pfd = fd;
@ -170,7 +176,7 @@ ptr<iface> iface::open_ifd(const std::string& name)
{
int fd;
std::map<std::string, ptr<iface> >::iterator it = _map.find(name);
std::map<std::string, weak_ptr<iface> >::iterator it = _map.find(name);
if ((it != _map.end()) && it->second->_ifd)
return it->second;
@ -451,7 +457,7 @@ void iface::fixup_pollfds()
logger::debug() << "iface::fixup_pollfds() _map.size()=" << _map.size();
for (std::map<std::string, ptr<iface> >::iterator it = _map.begin();
for (std::map<std::string, weak_ptr<iface> >::iterator it = _map.begin();
it != _map.end(); it++) {
_pollfds[i].fd = it->second->_ifd;
_pollfds[i].events = POLLIN;
@ -498,7 +504,7 @@ int iface::poll_all()
if (len == 0)
return 0;
std::map<std::string, ptr<iface> >::iterator i_it = _map.begin();
std::map<std::string, weak_ptr<iface> >::iterator i_it = _map.begin();
int i = 0;
@ -530,7 +536,9 @@ int iface::poll_all()
continue;
}
if (ifa->_pr) {
ifa->_pr->handle_solicit(saddr, daddr, taddr);
}
} else {
if (ifa->read_advert(saddr, taddr) < 0) {
logger::error() << "Failed to read from interface '%s'", ifa->_name.c_str();
@ -560,23 +568,29 @@ int iface::allmulti(int state)
state = !!state;
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, _name.c_str(), IFNAMSIZ);
if (ioctl(_pfd, SIOCGIFFLAGS,& ifr) < 0)
if (ioctl(_pfd, SIOCGIFFLAGS, &ifr) < 0) {
return -1;
}
int old_state = !!(ifr.ifr_flags & IFF_ALLMULTI);
if (state == old_state)
if (state == old_state) {
return old_state;
}
if (state)
if (state) {
ifr.ifr_flags |= IFF_ALLMULTI;
else
} else {
ifr.ifr_flags &= ~IFF_ALLMULTI;
}
if (ioctl(_pfd, SIOCSIFFLAGS,& ifr) < 0)
if (ioctl(_pfd, SIOCSIFFLAGS, &ifr) < 0) {
return -1;
}
return old_state;
}

View File

@ -35,7 +35,7 @@ private:
// Weak pointer so this object can reference itself.
weak_ptr<iface> _ptr;
static std::map<std::string, ptr<iface> > _map;
static std::map<std::string, weak_ptr<iface> > _map;
// An array of objects used with ::poll.
static std::vector<struct pollfd> _pollfds;
@ -61,7 +61,7 @@ private:
// ND_NEIGHBOR_ADVERT messages.
std::list<weak_ptr<session> > _sessions;
ptr<proxy> _pr;
weak_ptr<proxy> _pr;
// The link-layer address of this interface.
struct ether_addr hwaddr;

View File

@ -55,12 +55,12 @@ const logger::pri_name logger::_pri_names[] = {
};
logger::logger(int pri) :
_pri(pri)
_pri(pri), _force_log(false)
{
}
logger::logger(const logger& l) :
_pri(l._pri) //, _ss(l._ss.str())
_pri(l._pri), _force_log(false)
{
_ss << l._ss.rdbuf();
}

View File

@ -14,6 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <cstdlib>
#include <csignal>
#include <iostream>
#include <fstream>
@ -128,8 +129,19 @@ bool configure(const std::string& path)
return true;
}
bool running = true;
void exit_ndppd(int sig)
{
logger::error() << "Shutting down...";
running = 0;
}
int main(int argc, char* argv[], char* env[])
{
signal(SIGINT, exit_ndppd);
signal(SIGTERM, exit_ndppd);
std::string config_path("/etc/ndppd.conf");
std::string pidfile;
std::string verbosity;
@ -208,7 +220,7 @@ int main(int argc, char* argv[], char* env[])
gettimeofday(&t1, 0);
while (iface::poll_all() >= 0) {
while (running && (iface::poll_all() >= 0)) {
int elapsed_time;
gettimeofday(&t2, 0);

View File

@ -27,6 +27,8 @@
NDPPD_NS_BEGIN
std::list<ptr<proxy> > proxy::_list;
proxy::proxy() :
_router(true), _ttl(30000), _timeout(500)
{
@ -38,6 +40,8 @@ ptr<proxy> proxy::create(const ptr<iface>& ifa)
pr->_ptr = pr;
pr->_ifa = ifa;
_list.push_back(pr);
ifa->pr(pr);
logger::debug() << "proxy::create() if=" << ifa->name();

View File

@ -29,21 +29,6 @@ class iface;
class rule;
class proxy {
private:
weak_ptr<proxy> _ptr;
ptr<iface> _ifa;
std::list<ptr<rule> > _rules;
std::list<ptr<session> > _sessions;
bool _router;
int _ttl, _timeout;
proxy();
public:
static ptr<proxy> create(const ptr<iface>& ifa);
@ -71,6 +56,23 @@ public:
int ttl() const;
void ttl(int val);
private:
static std::list<ptr<proxy> > _list;
weak_ptr<proxy> _ptr;
ptr<iface> _ifa;
std::list<ptr<rule> > _rules;
std::list<ptr<session> > _sessions;
bool _router;
int _ttl, _timeout;
proxy();
};
NDPPD_NS_END

View File

@ -18,6 +18,7 @@
#include <exception>
#include "ndppd.h"
#include "logger.h"
NDPPD_NS_BEGIN
@ -50,16 +51,22 @@ protected:
void acquire(ptr_ref* ref)
{
if (_ref)
if (_ref) {
release();
}
if (ref && !ref->sc) {
throw new invalid_pointer;
}
if (_ref = ref) {
if (_weak)
if (_weak) {
_ref->wc++;
else
} else {
_ref->sc++;
}
}
}
void acquire(void* ptr)
{
@ -71,22 +78,38 @@ protected:
void release()
{
if (!_ref)
if (!_ref) {
return;
if (_weak)
_ref->wc--;
else
_ref->sc--;
if (!_ref->sc && _ref->ptr) {
T* ptr = static_cast<T* >(_ref->ptr);
_ref->ptr = 0;
delete ptr;
}
if (!_ref->sc && !_ref->wc)
//logger::debug()
// << "ptr::release() _ref=" << logger::format("%x", _ref)
// << ", _ref->wc=" << _ref->wc << ", _ref->sc=" << _ref->sc
// << ", _weak=" << (_weak ? "yes" : "no");
if (_weak) {
assert(_ref->wc > 0);
_ref->wc--;
} else {
assert(_ref->sc > 0);
if (!--_ref->sc && _ref->ptr) {
T* ptr = _ref->ptr;
_ref->ptr = 0;
_ref->wc++;
delete ptr;
_ref->wc--;
}
}
/*if (!_weak && !_ref->sc && _ref->ptr) {
T* ptr = (T*)(_ref->ptr);
_ref->ptr = 0;
delete ptr;
}*/
if (!_ref->sc && !_ref->wc) {
delete _ref;
}
_ref = 0;
}
@ -196,8 +219,9 @@ public:
T* get_pointer() const
{
if (!_ref || !_ref->ptr)
if (!_ref || !_ref->ptr) {
throw new invalid_pointer;
}
return static_cast<T* >(_ref->ptr);
}

View File

@ -150,6 +150,7 @@ const std::string& route::ifname() const
ptr<iface> route::ifa()
{
if (!_ifa) {
logger::debug() << "router::ifa() opening interface '" << _ifname << "'";
return _ifa = iface::open_ifd(_ifname);
}

View File

@ -45,7 +45,7 @@ public:
private:
weak_ptr<rule> _ptr;
ptr<proxy> _pr;
weak_ptr<proxy> _pr;
ptr<iface> _ifa;

View File

@ -96,11 +96,11 @@ void session::add_iface(const ptr<iface>& ifa)
void session::send_solicit()
{
logger::debug() << "session::send_solicit() (" << _ifaces.size() << ")";
logger::debug() << "session::send_solicit() (_ifaces.size() = " << _ifaces.size() << ")";
for (std::list<ptr<iface> >::iterator it = _ifaces.begin();
it != _ifaces.end(); it++) {
logger::debug() << " - %s" << (*it)->name();
logger::debug() << " - " << (*it)->name();
(*it)->write_solicit(_taddr);
}
}