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

View File

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

View File

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

View File

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

View File

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

View File

@ -29,21 +29,6 @@ class iface;
class rule; class rule;
class proxy { 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: public:
static ptr<proxy> create(const ptr<iface>& ifa); static ptr<proxy> create(const ptr<iface>& ifa);
@ -71,6 +56,23 @@ public:
int ttl() const; int ttl() const;
void ttl(int val); 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 NDPPD_NS_END

View File

@ -18,6 +18,7 @@
#include <exception> #include <exception>
#include "ndppd.h" #include "ndppd.h"
#include "logger.h"
NDPPD_NS_BEGIN NDPPD_NS_BEGIN
@ -50,43 +51,65 @@ protected:
void acquire(ptr_ref* ref) void acquire(ptr_ref* ref)
{ {
if (_ref) if (_ref) {
release(); release();
}
if (ref && !ref->sc) {
throw new invalid_pointer;
}
if (_ref = ref) { if (_ref = ref) {
if (_weak) if (_weak) {
_ref->wc++; _ref->wc++;
else } else {
_ref->sc++; _ref->sc++;
} }
} }
}
void acquire(void* ptr) void acquire(void* ptr)
{ {
_ref = new ptr_ref(); _ref = new ptr_ref();
_ref->ptr = (T* )ptr; _ref->ptr = (T*)ptr;
_ref->wc = !!_weak; _ref->wc = !!_weak;
_ref->sc = !_weak; _ref->sc = !_weak;
} }
void release() void release()
{ {
if (!_ref) if (!_ref) {
return; 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; delete _ref;
}
_ref = 0; _ref = 0;
} }
@ -196,8 +219,9 @@ public:
T* get_pointer() const T* get_pointer() const
{ {
if (!_ref || !_ref->ptr) if (!_ref || !_ref->ptr) {
throw new invalid_pointer; throw new invalid_pointer;
}
return static_cast<T* >(_ref->ptr); return static_cast<T* >(_ref->ptr);
} }

View File

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

View File

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

View File

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