Fix a couple of memory leaks
This commit is contained in:
parent
6723f2f4b6
commit
7956724a8e
50
src/iface.cc
50
src/iface.cc
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
14
src/ndppd.cc
14
src/ndppd.cc
@ -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);
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
32
src/proxy.h
32
src/proxy.h
@ -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
|
||||||
|
56
src/ptr.h
56
src/ptr.h
@ -18,6 +18,7 @@
|
|||||||
#include <exception>
|
#include <exception>
|
||||||
|
|
||||||
#include "ndppd.h"
|
#include "ndppd.h"
|
||||||
|
#include "logger.h"
|
||||||
|
|
||||||
NDPPD_NS_BEGIN
|
NDPPD_NS_BEGIN
|
||||||
|
|
||||||
@ -50,16 +51,22 @@ 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)
|
||||||
{
|
{
|
||||||
@ -71,22 +78,38 @@ protected:
|
|||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user