Refactor source

- Change coding style

- Switch from own implementation of smart pointers to std::smart_ptr
  and std::weak_ptr
This commit is contained in:
Daniel Adolfsson 2012-01-28 20:25:57 +01:00
parent 6fda405a59
commit bc70f587ef
18 changed files with 988 additions and 1289 deletions

View File

@ -1,7 +1,7 @@
ifdef DEBUG ifdef DEBUG
CXXFLAGS ?= -g -DDEBUG CXXFLAGS ?= -g -std=c++0x -DDEBUG
else else
CXXFLAGS ?= -O3 CXXFLAGS ?= -O3 -std=c++0x
endif endif
PREFIX ?= /usr/local PREFIX ?= /usr/local

View File

@ -32,15 +32,7 @@ __NDPPD_NS_BEGIN
address::address() address::address()
{ {
_addr.s6_addr32[0] = 0; reset();
_addr.s6_addr32[1] = 0;
_addr.s6_addr32[2] = 0;
_addr.s6_addr32[3] = 0;
_mask.s6_addr32[0] = 0xffffffff;
_mask.s6_addr32[1] = 0xffffffff;
_mask.s6_addr32[2] = 0xffffffff;
_mask.s6_addr32[3] = 0xffffffff;
} }
address::address(const address& addr) address::address(const address& addr)
@ -58,34 +50,12 @@ address::address(const address& addr)
address::address(const std::string& str) address::address(const std::string& str)
{ {
if(!parse_string(str)) parse_string(str);
{
_addr.s6_addr32[0] = 0;
_addr.s6_addr32[1] = 0;
_addr.s6_addr32[2] = 0;
_addr.s6_addr32[3] = 0;
_mask.s6_addr32[0] = 0xffffffff;
_mask.s6_addr32[1] = 0xffffffff;
_mask.s6_addr32[2] = 0xffffffff;
_mask.s6_addr32[3] = 0xffffffff;
}
} }
address::address(const char *str) address::address(const char *str)
{ {
if(!parse_string(str)) parse_string(str);
{
_addr.s6_addr32[0] = 0;
_addr.s6_addr32[1] = 0;
_addr.s6_addr32[2] = 0;
_addr.s6_addr32[3] = 0;
_mask.s6_addr32[0] = 0xffffffff;
_mask.s6_addr32[1] = 0xffffffff;
_mask.s6_addr32[2] = 0xffffffff;
_mask.s6_addr32[3] = 0xffffffff;
}
} }
address::address(const in6_addr& addr) address::address(const in6_addr& addr)
@ -140,13 +110,25 @@ bool address::operator!=(const address& addr) const
((_addr.s6_addr32[3] ^ addr._addr.s6_addr32[3]) & _mask.s6_addr32[3])); ((_addr.s6_addr32[3] ^ addr._addr.s6_addr32[3]) & _mask.s6_addr32[3]));
} }
void address::reset()
{
_addr.s6_addr32[0] = 0;
_addr.s6_addr32[1] = 0;
_addr.s6_addr32[2] = 0;
_addr.s6_addr32[3] = 0;
_mask.s6_addr32[0] = 0xffffffff;
_mask.s6_addr32[1] = 0xffffffff;
_mask.s6_addr32[2] = 0xffffffff;
_mask.s6_addr32[3] = 0xffffffff;
}
int address::prefix() const int address::prefix() const
{ {
if (!_mask.s6_addr[0]) if (!_mask.s6_addr[0])
return 0; return 0;
for(int p = 0; p < 128; p++) for (int p = 0; p < 128; p++) {
{
int byi = p / 8, bii = 7 - (p % 8); int byi = p / 8, bii = 7 - (p % 8);
if (!(_mask.s6_addr[byi] & (1 << bii))) if (!(_mask.s6_addr[byi] & (1 << bii)))
return p; return p;
@ -165,8 +147,7 @@ void address::prefix(int pf)
_mask.s6_addr32[2] = 0; _mask.s6_addr32[2] = 0;
_mask.s6_addr32[3] = 0; _mask.s6_addr32[3] = 0;
while(pf--) while (pf--) {
{
int byi = pf / 8, bii = 7 - (pf % 8); int byi = pf / 8, bii = 7 - (pf % 8);
_mask.s6_addr[byi] |= 1 << bii; _mask.s6_addr[byi] |= 1 << bii;
} }
@ -197,13 +178,14 @@ bool address::parse_string(const std::string& str)
sz = 0; sz = 0;
b = buf; b = buf;
reset();
const char *p = str.c_str(); const char *p = str.c_str();
while (*p && isspace(*p)) while (*p && isspace(*p))
p++; p++;
while(*p) while (*p) {
{
if ((*p == '/') || isspace(*p)) if ((*p == '/') || isspace(*p))
break; break;
@ -226,8 +208,7 @@ bool address::parse_string(const std::string& str)
while (*p && isspace(*p)) while (*p && isspace(*p))
p++; p++;
if(*p == '\0') if (*p == '\0') {
{
_mask.s6_addr32[0] = 0xffffffff; _mask.s6_addr32[0] = 0xffffffff;
_mask.s6_addr32[1] = 0xffffffff; _mask.s6_addr32[1] = 0xffffffff;
_mask.s6_addr32[2] = 0xffffffff; _mask.s6_addr32[2] = 0xffffffff;
@ -244,8 +225,7 @@ bool address::parse_string(const std::string& str)
sz = 0; sz = 0;
b = buf; b = buf;
while(*p) while (*p) {
{
if (!isdigit(*p)) if (!isdigit(*p))
return false; return false;

View File

@ -51,6 +51,8 @@ public:
bool operator!=(const address& addr) const; bool operator!=(const address& addr) const;
void reset();
const std::string to_string() const; const std::string to_string() const;
bool parse_string(const std::string& str); bool parse_string(const std::string& str);

View File

@ -50,18 +50,16 @@ bool conf::setup(cfg_t *cfg)
{ {
int i; int i;
for(i = 0; i < cfg_size(cfg, "proxy"); i++) for (i = 0; i < cfg_size(cfg, "proxy"); i++) {
{
cfg_t *proxy_cfg = cfg_getnsec(cfg, "proxy", i); cfg_t *proxy_cfg = cfg_getnsec(cfg, "proxy", i);
if(proxy_cfg) if (proxy_cfg) {
{
cfg_t *rule_cfg; cfg_t *rule_cfg;
int i2; int i2;
strong_ptr<proxy> pr = proxy::open(cfg_title(proxy_cfg)); std::shared_ptr<proxy> pr = proxy::open(cfg_title(proxy_cfg));
if(pr.is_null()) if (!pr)
continue; continue;
pr->router(cfg_getbool(proxy_cfg, "router")); pr->router(cfg_getbool(proxy_cfg, "router"));
@ -70,8 +68,7 @@ bool conf::setup(cfg_t *cfg)
pr->timeout(cfg_getint(proxy_cfg, "timeout")); pr->timeout(cfg_getint(proxy_cfg, "timeout"));
for(i2 = 0; i2 < cfg_size(proxy_cfg, "rule"); i2++) for (i2 = 0; i2 < cfg_size(proxy_cfg, "rule"); i2++) {
{
cfg_t *rule_cfg; cfg_t *rule_cfg;
if (!(rule_cfg = cfg_getnsec(proxy_cfg, "rule", i2))) if (!(rule_cfg = cfg_getnsec(proxy_cfg, "rule", i2)))
@ -81,8 +78,7 @@ bool conf::setup(cfg_t *cfg)
std::string ifname(cfg_getstr(rule_cfg, "iface")); std::string ifname(cfg_getstr(rule_cfg, "iface"));
if(ifname.empty()) if (ifname.empty()) {
{
if (addr.prefix() <= 120) if (addr.prefix() <= 120)
NCE("Static rule prefix /%d <= 120 - is this what you want?", addr.prefix()); NCE("Static rule prefix /%d <= 120 - is this what you want?", addr.prefix());
@ -134,8 +130,7 @@ bool conf::load(const std::string& path)
cfg_set_validate_func(cfg, "proxy|rule", &validate_rule); cfg_set_validate_func(cfg, "proxy|rule", &validate_rule);
switch(cfg_parse(cfg, path.c_str())) switch (cfg_parse(cfg, path.c_str())) {
{
case CFG_SUCCESS: case CFG_SUCCESS:
break; break;

View File

@ -42,7 +42,7 @@
__NDPPD_NS_BEGIN __NDPPD_NS_BEGIN
std::map<std::string, strong_ptr<iface> > iface::_map; std::map<std::string, std::shared_ptr<iface> > iface::_map;
std::vector<struct pollfd> iface::_pollfds; std::vector<struct pollfd> iface::_pollfds;
@ -58,43 +58,38 @@ iface::~iface()
if (_ifd >= 0) if (_ifd >= 0)
close(_ifd); close(_ifd);
if(_pfd >= 0) if (_pfd >= 0) {
{
allmulti(_prev_allmulti); allmulti(_prev_allmulti);
close(_pfd); close(_pfd);
} }
} }
strong_ptr<iface> iface::open_pfd(const std::string& name) std::shared_ptr<iface> iface::open_pfd(const std::string& name)
{ {
int fd; int fd;
std::map<std::string, strong_ptr<iface> >::iterator it = _map.find(name); std::map<std::string, std::shared_ptr<iface> >::iterator it = _map.find(name);
strong_ptr<iface> ifa; std::shared_ptr<iface> ifa;
if(it != _map.end()) if (it != _map.end()) {
{
if (it->second->_pfd >= 0) if (it->second->_pfd >= 0)
return it->second; return it->second;
ifa = it->second; ifa = it->second;
} } else {
else
{
// We need an _ifs, so let's set one up. // We need an _ifs, so let's set one up.
ifa = open_ifd(name); ifa = open_ifd(name);
} }
if(ifa.is_null()) if (!ifa)
return strong_ptr<iface>(); return std::shared_ptr<iface>();
// Create a socket. // Create a socket.
if((fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IPV6))) < 0) if ((fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IPV6))) < 0) {
{
ERR("Unable to create socket"); ERR("Unable to create socket");
return strong_ptr<iface>(); return std::shared_ptr<iface>();
} }
// Bind to the specified interface. // Bind to the specified interface.
@ -105,29 +100,26 @@ strong_ptr<iface> iface::open_pfd(const std::string& name)
lladdr.sll_family = AF_PACKET; lladdr.sll_family = AF_PACKET;
lladdr.sll_protocol = htons(ETH_P_IPV6); lladdr.sll_protocol = htons(ETH_P_IPV6);
if(!(lladdr.sll_ifindex = if_nametoindex(name.c_str()))) if (!(lladdr.sll_ifindex = if_nametoindex(name.c_str()))) {
{
close(fd); close(fd);
ERR("Failed to bind to interface '%s'", name.c_str()); ERR("Failed to bind to interface '%s'", name.c_str());
return strong_ptr<iface>(); return std::shared_ptr<iface>();
} }
if(bind(fd, (struct sockaddr *)&lladdr, sizeof(struct sockaddr_ll)) < 0) if (bind(fd, (struct sockaddr *)&lladdr, sizeof(struct sockaddr_ll)) < 0) {
{
close(fd); close(fd);
ERR("Failed to bind to interface '%s'", name.c_str()); ERR("Failed to bind to interface '%s'", name.c_str());
return strong_ptr<iface>(); return std::shared_ptr<iface>();
} }
// Switch to non-blocking mode. // Switch to non-blocking mode.
int on = 1; int on = 1;
if(ioctl(fd, FIONBIO, (char *)&on) < 0) if (ioctl(fd, FIONBIO, (char *)&on) < 0) {
{
close(fd); close(fd);
ERR("Failed to switch to non-blocking on interface '%s'", name.c_str()); ERR("Failed to switch to non-blocking on interface '%s'", name.c_str());
return strong_ptr<iface>(); return std::shared_ptr<iface>();
} }
// Set up filter. // Set up filter.
@ -160,10 +152,9 @@ strong_ptr<iface> iface::open_pfd(const std::string& name)
fprog.filter = (struct sock_filter *)filter; fprog.filter = (struct sock_filter *)filter;
fprog.len = 8; fprog.len = 8;
if(setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &fprog, sizeof(fprog)) < 0) if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &fprog, sizeof(fprog)) < 0) {
{
ERR("Failed to set filter"); ERR("Failed to set filter");
return strong_ptr<iface>(); return std::shared_ptr<iface>();
} }
// Set up an instance of 'iface'. // Set up an instance of 'iface'.
@ -175,21 +166,20 @@ strong_ptr<iface> iface::open_pfd(const std::string& name)
return ifa; return ifa;
} }
strong_ptr<iface> iface::open_ifd(const std::string& name) std::shared_ptr<iface> iface::open_ifd(const std::string& name)
{ {
int fd; int fd;
std::map<std::string, strong_ptr<iface> >::iterator it = _map.find(name); std::map<std::string, std::shared_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;
// Create a socket. // Create a socket.
if((fd = socket(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) if ((fd = socket(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) {
{
ERR("Unable to create socket"); ERR("Unable to create socket");
return strong_ptr<iface>(); return std::shared_ptr<iface>();
} }
// Bind to the specified interface. // Bind to the specified interface.
@ -200,11 +190,10 @@ strong_ptr<iface> iface::open_ifd(const std::string& name)
strncpy(ifr.ifr_name, name.c_str(), IFNAMSIZ - 1); strncpy(ifr.ifr_name, name.c_str(), IFNAMSIZ - 1);
ifr.ifr_name[IFNAMSIZ - 1] = '\0'; ifr.ifr_name[IFNAMSIZ - 1] = '\0';
if(setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) < 0) if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) < 0) {
{
close(fd); close(fd);
ERR("Failed to bind to interface '%s'", name.c_str()); ERR("Failed to bind to interface '%s'", name.c_str());
return strong_ptr<iface>(); return std::shared_ptr<iface>();
} }
// Detect the link-layer address. // Detect the link-layer address.
@ -213,11 +202,10 @@ strong_ptr<iface> iface::open_ifd(const std::string& name)
strncpy(ifr.ifr_name, name.c_str(), IFNAMSIZ - 1); strncpy(ifr.ifr_name, name.c_str(), IFNAMSIZ - 1);
ifr.ifr_name[IFNAMSIZ - 1] = '\0'; ifr.ifr_name[IFNAMSIZ - 1] = '\0';
if(ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) {
{
close(fd); close(fd);
ERR("Failed to detect link-layer address for interface '%s'", name.c_str()); ERR("Failed to detect link-layer address for interface '%s'", name.c_str());
return strong_ptr<iface>(); return std::shared_ptr<iface>();
} }
DBG("fd=%d, hwaddr=%s", fd, ether_ntoa((const struct ether_addr *)&ifr.ifr_hwaddr.sa_data)); DBG("fd=%d, hwaddr=%s", fd, ether_ntoa((const struct ether_addr *)&ifr.ifr_hwaddr.sa_data));
@ -226,29 +214,26 @@ strong_ptr<iface> iface::open_ifd(const std::string& name)
int hops = 255; int hops = 255;
if(setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &hops, sizeof(hops)) < 0) if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &hops, sizeof(hops)) < 0) {
{
close(fd); close(fd);
ERR("iface::open_ifd() failed IPV6_MULTICAST_HOPS"); ERR("iface::open_ifd() failed IPV6_MULTICAST_HOPS");
return strong_ptr<iface>(); return std::shared_ptr<iface>();
} }
if(setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &hops, sizeof(hops)) < 0) if (setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &hops, sizeof(hops)) < 0) {
{
close(fd); close(fd);
ERR("iface::open_ifd() failed IPV6_UNICAST_HOPS"); ERR("iface::open_ifd() failed IPV6_UNICAST_HOPS");
return strong_ptr<iface>(); return std::shared_ptr<iface>();
} }
// Switch to non-blocking mode. // Switch to non-blocking mode.
int on = 1; int on = 1;
if(ioctl(fd, FIONBIO, (char *)&on) < 0) if (ioctl(fd, FIONBIO, (char *)&on) < 0) {
{
close(fd); close(fd);
ERR("Failed to switch to non-blocking on interface '%s'", name.c_str()); ERR("Failed to switch to non-blocking on interface '%s'", name.c_str());
return strong_ptr<iface>(); return std::shared_ptr<iface>();
} }
// Set up filter. // Set up filter.
@ -257,27 +242,22 @@ strong_ptr<iface> iface::open_ifd(const std::string& name)
ICMP6_FILTER_SETBLOCKALL(&filter); ICMP6_FILTER_SETBLOCKALL(&filter);
ICMP6_FILTER_SETPASS(ND_NEIGHBOR_ADVERT, &filter); ICMP6_FILTER_SETPASS(ND_NEIGHBOR_ADVERT, &filter);
if(setsockopt(fd, IPPROTO_ICMPV6, ICMP6_FILTER, &filter, sizeof(filter)) < 0) if (setsockopt(fd, IPPROTO_ICMPV6, ICMP6_FILTER, &filter, sizeof(filter)) < 0) {
{
ERR("Failed to set filter"); ERR("Failed to set filter");
return strong_ptr<iface>(); return std::shared_ptr<iface>();
} }
// Set up an instance of 'iface'. // Set up an instance of 'iface'.
strong_ptr<iface> ifa; std::shared_ptr<iface> ifa;
if(it == _map.end())
{
ifa = new iface();
if (it == _map.end()) {
ifa.reset(new iface());
ifa->_name = name; ifa->_name = name;
ifa->_ptr = ifa; ifa->_ptr = ifa;
_map[name] = ifa; _map[name] = ifa;
} } else {
else
{
ifa = it->second; ifa = it->second;
} }
@ -476,9 +456,8 @@ void iface::fixup_pollfds()
DBG("iface::fixup_pollfds() _map.size()=%d", _map.size()); DBG("iface::fixup_pollfds() _map.size()=%d", _map.size());
for(std::map<std::string, strong_ptr<iface> >::iterator it = _map.begin(); for (std::map<std::string, std::shared_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;
_pollfds[i].revents = 0; _pollfds[i].revents = 0;
@ -491,20 +470,25 @@ void iface::fixup_pollfds()
} }
} }
void iface::remove_session(const strong_ptr<session>& se) void iface::remove_session(const std::shared_ptr<session>& se)
{ {
_sessions.remove(se); for (std::list<std::weak_ptr<session> >::iterator it = _sessions.begin();
it != _sessions.end(); it++) {
if (it->lock() == se) {
_sessions.erase(it);
break;
}
}
} }
void iface::add_session(const strong_ptr<session>& se) void iface::add_session(const std::shared_ptr<session>& se)
{ {
_sessions.push_back(se); _sessions.push_back(se);
} }
int iface::poll_all() int iface::poll_all()
{ {
if(_pollfds.size() == 0) if (_pollfds.size() == 0) {
{
::sleep(1); ::sleep(1);
return 0; return 0;
} }
@ -519,13 +503,12 @@ int iface::poll_all()
if (len == 0) if (len == 0)
return 0; return 0;
std::map<std::string, strong_ptr<iface> >::iterator i_it = _map.begin(); std::map<std::string, std::shared_ptr<iface> >::iterator i_it = _map.begin();
int i = 0; int i = 0;
for (std::vector<struct pollfd>::iterator f_it = _pollfds.begin(); for (std::vector<struct pollfd>::iterator f_it = _pollfds.begin();
f_it != _pollfds.end(); f_it++) f_it != _pollfds.end(); f_it++) {
{
assert(i_it != _map.end()); assert(i_it != _map.end());
if (i && !(i % 2)) if (i && !(i % 2))
@ -536,14 +519,12 @@ int iface::poll_all()
if (!(f_it->revents & POLLIN)) if (!(f_it->revents & POLLIN))
continue; continue;
strong_ptr<iface> ifa = i_it->second; std::shared_ptr<iface> ifa = i_it->second;
address saddr, daddr, taddr; address saddr, daddr, taddr;
if(is_pfd) if (is_pfd) {
{ if (ifa->read_solicit(saddr, daddr, taddr) < 0) {
if(ifa->read_solicit(saddr, daddr, taddr) < 0)
{
ERR("Failed to read from interface '%s'", ifa->_name.c_str()); ERR("Failed to read from interface '%s'", ifa->_name.c_str());
continue; continue;
} }
@ -552,21 +533,17 @@ int iface::poll_all()
continue; continue;
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)
{
ERR("Failed to read from interface '%s'", ifa->_name.c_str()); ERR("Failed to read from interface '%s'", ifa->_name.c_str());
continue; continue;
} }
for(std::list<weak_ptr<session> >::iterator s_it = ifa->_sessions.begin(); for (std::list<std::weak_ptr<session> >::iterator s_it = ifa->_sessions.begin();
s_it != ifa->_sessions.end(); s_it++) s_it != ifa->_sessions.end(); s_it++) {
{ const std::shared_ptr<session> sess = s_it->lock();
if(((*s_it)->taddr() == taddr) && ((*s_it)->status() == session::WAITING)) if ((sess->taddr() == taddr) && (sess->status() == session::WAITING)) {
{ sess->handle_advert();
(*s_it)->handle_advert();
break; break;
} }
} }
@ -611,12 +588,12 @@ const std::string& iface::name() const
return _name; return _name;
} }
void iface::pr(const strong_ptr<proxy>& pr) void iface::pr(const std::shared_ptr<proxy>& pr)
{ {
_pr = pr; _pr = pr;
} }
const strong_ptr<proxy>& iface::pr() const const std::shared_ptr<proxy>& iface::pr() const
{ {
return _pr; return _pr;
} }

View File

@ -35,9 +35,9 @@ class iface
{ {
private: private:
// Weak pointer so this object can reference itself. // Weak pointer so this object can reference itself.
weak_ptr<iface> _ptr; std::weak_ptr<iface> _ptr;
static std::map<std::string, strong_ptr<iface> > _map; static std::map<std::string, std::shared_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,9 +61,9 @@ private:
// An array of sessions that are monitoring this interface for // An array of sessions that are monitoring this interface for
// ND_NEIGHBOR_ADVERT messages. // ND_NEIGHBOR_ADVERT messages.
std::list<weak_ptr<session> > _sessions; std::list<std::weak_ptr<session> > _sessions;
strong_ptr<proxy> _pr; std::shared_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;
@ -80,9 +80,9 @@ public:
// Destructor. // Destructor.
~iface(); ~iface();
static strong_ptr<iface> open_ifd(const std::string& name); static std::shared_ptr<iface> open_ifd(const std::string& name);
static strong_ptr<iface> open_pfd(const std::string& name); static std::shared_ptr<iface> open_pfd(const std::string& name);
static int poll_all(); static int poll_all();
@ -106,13 +106,13 @@ public:
const std::string& name() const; const std::string& name() const;
// Adds a session to be monitored for ND_NEIGHBOR_ADVERT messages. // Adds a session to be monitored for ND_NEIGHBOR_ADVERT messages.
void add_session(const strong_ptr<session>& se); void add_session(const std::shared_ptr<session>& se);
void remove_session(const strong_ptr<session>& se); void remove_session(const std::shared_ptr<session>& se);
void pr(const strong_ptr<proxy>& pr); void pr(const std::shared_ptr<proxy>& pr);
const strong_ptr<proxy>& pr() const; const std::shared_ptr<proxy>& pr() const;
}; };
__NDPPD_NS_END __NDPPD_NS_END

View File

@ -60,8 +60,7 @@ void log::printf(int level, const char *fmt, ...)
va_start(args, fmt); va_start(args, fmt);
if(vsnprintf(buf, sizeof(buf), fmt, args) > 0) if (vsnprintf(buf, sizeof(buf), fmt, args) > 0) {
{
puts(level, buf); puts(level, buf);
} }
@ -73,8 +72,7 @@ void log::syslog(bool sl)
if (sl == _syslog) if (sl == _syslog)
return; return;
if(_syslog = sl) if (_syslog = sl) {
{
#ifdef DEBUG #ifdef DEBUG
setlogmask(LOG_UPTO(LOG_DEBUG)); setlogmask(LOG_UPTO(LOG_DEBUG));
openlog("ndppd", LOG_CONS | LOG_NDELAY | LOG_PERROR | LOG_PID, LOG_USER); openlog("ndppd", LOG_CONS | LOG_NDELAY | LOG_PERROR | LOG_PID, LOG_USER);

View File

@ -55,8 +55,7 @@ int main(int argc, char *argv[], char *env[])
std::string pidfile; std::string pidfile;
bool daemon = false; bool daemon = false;
while(1) while (1) {
{
int c, opt; int c, opt;
static struct option long_options[] = static struct option long_options[] =
@ -71,8 +70,7 @@ int main(int argc, char *argv[], char *env[])
if (c == -1) if (c == -1)
break; break;
switch(c) switch (c) {
{
case 'c': case 'c':
config_path = optarg; config_path = optarg;
break; break;
@ -87,19 +85,16 @@ int main(int argc, char *argv[], char *env[])
} }
} }
if(daemon) if (daemon) {
{
log::syslog(true); log::syslog(true);
if(daemonize() < 0) if (daemonize() < 0) {
{
ERR("Failed to daemonize process"); ERR("Failed to daemonize process");
return 1; return 1;
} }
} }
if(!pidfile.empty()) if (!pidfile.empty()) {
{
std::ofstream pf; std::ofstream pf;
pf.open(pidfile.c_str(), std::ios::out | std::ios::trunc); pf.open(pidfile.c_str(), std::ios::out | std::ios::trunc);
pf << getpid() << std::endl; pf << getpid() << std::endl;
@ -117,8 +112,7 @@ int main(int argc, char *argv[], char *env[])
gettimeofday(&t1, 0); gettimeofday(&t1, 0);
while(iface::poll_all() >= 0) while (iface::poll_all() >= 0) {
{
int elapsed_time; int elapsed_time;
gettimeofday(&t2, 0); gettimeofday(&t2, 0);

View File

@ -17,6 +17,7 @@
#define __NDPPD_H #define __NDPPD_H
#include <netinet/ip6.h> #include <netinet/ip6.h>
#include <memory>
#define __NDPPD_NS_BEGIN namespace ndppd { #define __NDPPD_NS_BEGIN namespace ndppd {
#define __NDPPD_NS_END } #define __NDPPD_NS_END }
@ -26,7 +27,6 @@
#include <assert.h> #include <assert.h>
#include "log.h" #include "log.h"
#include "ptr.h"
#include "conf.h" #include "conf.h"
#include "address.h" #include "address.h"

View File

@ -31,9 +31,9 @@ proxy::proxy() :
{ {
} }
strong_ptr<proxy> proxy::create(const strong_ptr<iface>& ifa) std::shared_ptr<proxy> proxy::create(const std::shared_ptr<iface>& ifa)
{ {
strong_ptr<proxy> pr(new proxy()); std::shared_ptr<proxy> pr(new proxy());
pr->_ptr = pr; pr->_ptr = pr;
pr->_ifa = ifa; pr->_ifa = ifa;
@ -44,12 +44,12 @@ strong_ptr<proxy> proxy::create(const strong_ptr<iface>& ifa)
return pr; return pr;
} }
strong_ptr<proxy> proxy::open(const std::string& ifname) std::shared_ptr<proxy> proxy::open(const std::string& ifname)
{ {
strong_ptr<iface> ifa = iface::open_pfd(ifname); std::shared_ptr<iface> ifa = iface::open_pfd(ifname);
if(ifa.is_null()) if (!ifa)
return strong_ptr<proxy>(); return std::shared_ptr<proxy>();
return create(ifa); return create(ifa);
} }
@ -63,13 +63,11 @@ void proxy::handle_solicit(const address& saddr, const address& daddr,
// Let's check this proxy's list of sessions to see if we can // Let's check this proxy's list of sessions to see if we can
// find one with the same target address. // find one with the same target address.
for(std::list<strong_ptr<session> >::iterator sit = _sessions.begin(); for (std::list<std::shared_ptr<session> >::iterator sit = _sessions.begin();
sit != _sessions.end(); sit++) sit != _sessions.end(); sit++) {
{
if((*sit)->taddr() == taddr) if ((*sit)->taddr() == taddr) {
{ switch ((*sit)->status()) {
switch((*sit)->status())
{
case session::WAITING: case session::WAITING:
case session::INVALID: case session::INVALID:
break; break;
@ -85,23 +83,20 @@ void proxy::handle_solicit(const address& saddr, const address& daddr,
// Since we couldn't find a session that matched, we'll try to find // Since we couldn't find a session that matched, we'll try to find
// a matching rule instead, and then set up a new session. // a matching rule instead, and then set up a new session.
strong_ptr<session> se; std::shared_ptr<session> se;
for(std::list<strong_ptr<rule> >::iterator it = _rules.begin(); for (std::list<std::shared_ptr<rule> >::iterator it = _rules.begin();
it != _rules.end(); it++) it != _rules.end(); it++) {
{ std::shared_ptr<rule> ru = *it;
strong_ptr<rule> ru = *it;
DBG("comparing %s against %s", DBG("comparing %s against %s",
ru->addr().to_string().c_str(), taddr.to_string().c_str()); ru->addr().to_string().c_str(), taddr.to_string().c_str());
if(ru->addr() == taddr) if (ru->addr() == taddr) {
{ if (!se)
if(se.is_null()) se = session::create(_ptr.lock(), saddr, daddr, taddr);
se = session::create(_ptr, saddr, daddr, taddr);
if(ru->ifa().is_null()) if (!ru->ifa()) {
{
// This rule doesn't have an interface, and thus we'll consider // This rule doesn't have an interface, and thus we'll consider
// it "static" and immediately send the response. // it "static" and immediately send the response.
@ -113,33 +108,32 @@ void proxy::handle_solicit(const address& saddr, const address& daddr,
} }
} }
if(se) if (se) {
{
_sessions.push_back(se); _sessions.push_back(se);
se->send_solicit(); se->send_solicit();
} }
} }
strong_ptr<rule> proxy::add_rule(const address& addr, const strong_ptr<iface>& ifa) std::shared_ptr<rule> proxy::add_rule(const address& addr, const std::shared_ptr<iface>& ifa)
{ {
strong_ptr<rule> ru(rule::create(_ptr, addr, ifa)); std::shared_ptr<rule> ru(rule::create(_ptr.lock(), addr, ifa));
_rules.push_back(ru); _rules.push_back(ru);
return ru; return ru;
} }
strong_ptr<rule> proxy::add_rule(const address& addr) std::shared_ptr<rule> proxy::add_rule(const address& addr)
{ {
strong_ptr<rule> ru(rule::create(_ptr, addr)); std::shared_ptr<rule> ru(rule::create(_ptr.lock(), addr));
_rules.push_back(ru); _rules.push_back(ru);
return ru; return ru;
} }
void proxy::remove_session(const strong_ptr<session>& se) void proxy::remove_session(const std::shared_ptr<session>& se)
{ {
_sessions.remove(se); _sessions.remove(se);
} }
const strong_ptr<iface>& proxy::ifa() const const std::shared_ptr<iface>& proxy::ifa() const
{ {
return _ifa; return _ifa;
} }

View File

@ -32,13 +32,13 @@ class rule;
class proxy class proxy
{ {
private: private:
weak_ptr<proxy> _ptr; std::weak_ptr<proxy> _ptr;
strong_ptr<iface> _ifa; std::shared_ptr<iface> _ifa;
std::list<strong_ptr<rule> > _rules; std::list<std::shared_ptr<rule> > _rules;
std::list<strong_ptr<session> > _sessions; std::list<std::shared_ptr<session> > _sessions;
bool _router; bool _router;
@ -47,20 +47,20 @@ private:
proxy(); proxy();
public: public:
static strong_ptr<proxy> create(const strong_ptr<iface>& ifa); static std::shared_ptr<proxy> create(const std::shared_ptr<iface>& ifa);
static strong_ptr<proxy> open(const std::string& ifn); static std::shared_ptr<proxy> open(const std::string& ifn);
void handle_solicit(const address& saddr, const address& daddr, void handle_solicit(const address& saddr, const address& daddr,
const address& taddr); const address& taddr);
void remove_session(const strong_ptr<session>& se); void remove_session(const std::shared_ptr<session>& se);
strong_ptr<rule> add_rule(const address& addr, const strong_ptr<iface>& ifa); std::shared_ptr<rule> add_rule(const address& addr, const std::shared_ptr<iface>& ifa);
strong_ptr<rule> add_rule(const address& addr); std::shared_ptr<rule> add_rule(const address& addr);
const strong_ptr<iface>& ifa() const; const std::shared_ptr<iface>& ifa() const;
bool router() const; bool router() const;

243
src/ptr.h
View File

@ -1,243 +0,0 @@
// ndppd - NDP Proxy Daemon
// Copyright (C) 2011 Daniel Adolfsson <daniel@priv.nu>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef __NDPPD_PTR_H
#define __NDPPD_PTR_H
#include <stdlib.h>
__NDPPD_NS_BEGIN
// This template class simplifies the usage of pointers. It's basically
// a reference-counting smart pointer that supports both weak and
// strong references.
template <typename T>
class ptr
{
protected:
struct ref
{
public:
T* p;
int n_strong;
int n_weak;
};
ref *_ref;
bool _strong;
void acquire(T* p)
{
if(_ref)
release();
if(p)
{
_ref = new ref;
_ref->p = p;
_ref->n_strong = _strong ? 1 : 0;
_ref->n_weak = _strong ? 0 : 1;
}
}
void acquire(const ptr<T>& p)
{
if(_ref)
release();
if(p._ref && p._ref->n_strong)
{
_ref = p._ref;
if(_strong)
_ref->n_strong++;
else
_ref->n_weak++;
}
}
void release()
{
if(!_ref)
return;
if(_strong)
{
// Assert _ref->n_strong > 0.
if(_ref->n_strong == 1)
{
delete _ref->p;
_ref->p = 0;
}
_ref->n_strong--;
}
else
{
_ref->n_weak--;
}
if(!_ref->n_weak && !_ref->n_strong)
delete _ref;
_ref = 0;
}
ptr(bool strong) :
_strong(strong), _ref(0)
{
}
ptr(bool strong, T* p) :
_strong(strong), _ref(0)
{
if(p)
acquire(p);
}
ptr(bool strong, const ptr<T>& p) :
_strong(strong), _ref(0)
{
acquire(p);
}
virtual ~ptr()
{
if(_ref)
release();
}
public:
void operator=(T* p)
{
acquire(p);
}
void operator=(const ptr<T>& p)
{
acquire(p);
}
bool operator==(const ptr<T>& other) const
{
return other._ref == _ref;
}
bool operator!=(const ptr<T>& other) const
{
return other._ref != _ref;
}
bool is_null() const
{
return !((_ref != 0) && (_ref->p != 0));
}
T& operator*() const
{
return *_ref.p;
}
T* operator->() const
{
return _ref ? _ref->p : 0;
}
operator T*() const
{
return _ref->p;
}
operator bool() const
{
return !is_null();
}
bool is_strong() const
{
return _strong;
}
bool is_weak() const
{
return !_strong;
}
void reset(T *p = 0)
{
acquire(p);
}
};
template <typename T>
class weak_ptr;
template <typename T>
class strong_ptr : public ptr<T>
{
public:
strong_ptr() : ptr<T>(true)
{
}
strong_ptr(T* p) : ptr<T>(true, p)
{
}
strong_ptr(const ptr<T>& p) : ptr<T>(true, p)
{
}
strong_ptr(const strong_ptr<T>& p) : ptr<T>(true, p)
{
}
strong_ptr(const weak_ptr<T>& p) : ptr<T>(true, p)
{
}
};
template <typename T>
class weak_ptr : public ptr<T>
{
public:
weak_ptr() : ptr<T>(false)
{
}
weak_ptr(T* p) : ptr<T>(false, p)
{
}
weak_ptr(const ptr<T>& p) : ptr<T>(false, p)
{
}
weak_ptr(const strong_ptr<T>& p) : ptr<T>(false, p)
{
}
weak_ptr(const weak_ptr<T>& p) : ptr<T>(false, p)
{
}
};
__NDPPD_NS_END
#endif // __NDPPD_PTR_H

View File

@ -28,9 +28,9 @@ rule::rule()
{ {
} }
strong_ptr<rule> rule::create(const strong_ptr<proxy>& pr, const address& addr, const strong_ptr<iface>& ifa) std::shared_ptr<rule> rule::create(const std::shared_ptr<proxy>& pr, const address& addr, const std::shared_ptr<iface>& ifa)
{ {
strong_ptr<rule> ru(new rule()); std::shared_ptr<rule> ru(new rule());
ru->_ptr = ru; ru->_ptr = ru;
ru->_pr = pr; ru->_pr = pr;
ru->_ifa = ifa; ru->_ifa = ifa;
@ -42,9 +42,9 @@ strong_ptr<rule> rule::create(const strong_ptr<proxy>& pr, const address& addr,
return ru; return ru;
} }
strong_ptr<rule> rule::create(const strong_ptr<proxy>& pr, const address& addr) std::shared_ptr<rule> rule::create(const std::shared_ptr<proxy>& pr, const address& addr)
{ {
strong_ptr<rule> ru(new rule()); std::shared_ptr<rule> ru(new rule());
ru->_ptr = ru; ru->_ptr = ru;
ru->_pr = pr; ru->_pr = pr;
ru->_addr = addr; ru->_addr = addr;
@ -60,7 +60,7 @@ const address& rule::addr() const
return _addr; return _addr;
} }
strong_ptr<iface> rule::ifa() const std::shared_ptr<iface> rule::ifa() const
{ {
return _ifa; return _ifa;
} }

View File

@ -32,24 +32,24 @@ class proxy;
class rule class rule
{ {
private: private:
weak_ptr<rule> _ptr; std::weak_ptr<rule> _ptr;
strong_ptr<proxy> _pr; std::shared_ptr<proxy> _pr;
strong_ptr<iface> _ifa; std::shared_ptr<iface> _ifa;
address _addr; address _addr;
rule(); rule();
public: public:
static strong_ptr<rule> create(const strong_ptr<proxy>& pr, const address& addr, const strong_ptr<iface>& ifa); static std::shared_ptr<rule> create(const std::shared_ptr<proxy>& pr, const address& addr, const std::shared_ptr<iface>& ifa);
static strong_ptr<rule> create(const strong_ptr<proxy>& pr, const address& addr); static std::shared_ptr<rule> create(const std::shared_ptr<proxy>& pr, const address& addr);
const address& addr() const; const address& addr() const;
strong_ptr<iface> ifa() const; std::shared_ptr<iface> ifa() const;
bool is_static() const; bool is_static() const;

View File

@ -22,20 +22,18 @@
__NDPPD_NS_BEGIN __NDPPD_NS_BEGIN
std::list<weak_ptr<session> > session::_sessions; std::list<std::weak_ptr<session> > session::_sessions;
void session::update_all(int elapsed_time) void session::update_all(int elapsed_time)
{ {
for(std::list<weak_ptr<session> >::iterator it = _sessions.begin(); for (std::list<std::weak_ptr<session> >::iterator it = _sessions.begin();
it != _sessions.end(); ) it != _sessions.end(); ) {
{ std::shared_ptr<session> se = (*it++).lock();
strong_ptr<session> se = *it++;
if ((se->_ttl -= elapsed_time) >= 0) if ((se->_ttl -= elapsed_time) >= 0)
continue; continue;
switch(se->_status) switch (se->_status) {
{
case session::WAITING: case session::WAITING:
DBG("session is now invalid"); DBG("session is now invalid");
se->_status = session::INVALID; se->_status = session::INVALID;
@ -52,19 +50,24 @@ session::~session()
{ {
DBG("session::~session() this=%x", this); DBG("session::~session() this=%x", this);
_sessions.remove(_ptr); for (std::list<std::weak_ptr<session> >::iterator it = _sessions.begin();
it != _sessions.end(); it++) {
for(std::list<strong_ptr<iface> >::iterator it = _ifaces.begin(); if (it->lock() == _ptr.lock()) {
it != _ifaces.end(); it++) _sessions.erase(it);
{ break;
(*it)->remove_session(_ptr);
} }
} }
strong_ptr<session> session::create(const strong_ptr<proxy>& pr, const address& saddr, for (std::list<std::shared_ptr<iface> >::iterator it = _ifaces.begin();
it != _ifaces.end(); it++) {
(*it)->remove_session(_ptr.lock());
}
}
std::shared_ptr<session> session::create(const std::shared_ptr<proxy>& pr, const address& saddr,
const address& daddr, const address& taddr) const address& daddr, const address& taddr)
{ {
strong_ptr<session> se(new session()); std::shared_ptr<session> se(new session());
se->_ptr = se; se->_ptr = se;
se->_pr = pr; se->_pr = pr;
@ -82,12 +85,12 @@ strong_ptr<session> session::create(const strong_ptr<proxy>& pr, const address&
return se; return se;
} }
void session::add_iface(const strong_ptr<iface>& ifa) void session::add_iface(const std::shared_ptr<iface>& ifa)
{ {
if (std::find(_ifaces.begin(), _ifaces.end(), ifa) != _ifaces.end()) if (std::find(_ifaces.begin(), _ifaces.end(), ifa) != _ifaces.end())
return; return;
ifa->add_session(_ptr); ifa->add_session(_ptr.lock());
_ifaces.push_back(ifa); _ifaces.push_back(ifa);
} }
@ -95,9 +98,8 @@ void session::send_solicit()
{ {
DBG("session::send_solicit() (%d)", _ifaces.size()); DBG("session::send_solicit() (%d)", _ifaces.size());
for(std::list<strong_ptr<iface> >::iterator it = _ifaces.begin(); for (std::list<std::shared_ptr<iface> >::iterator it = _ifaces.begin();
it != _ifaces.end(); it++) it != _ifaces.end(); it++) {
{
DBG(" - %s", (*it)->name().c_str()); DBG(" - %s", (*it)->name().c_str());
(*it)->write_solicit(_taddr); (*it)->write_solicit(_taddr);
} }

View File

@ -28,15 +28,15 @@ class iface;
class session class session
{ {
private: private:
weak_ptr<session> _ptr; std::weak_ptr<session> _ptr;
strong_ptr<proxy> _pr; std::shared_ptr<proxy> _pr;
address _saddr, _daddr, _taddr; address _saddr, _daddr, _taddr;
// An array of interfaces this session is monitoring for // An array of interfaces this session is monitoring for
// ND_NEIGHBOR_ADVERT on. // ND_NEIGHBOR_ADVERT on.
std::list<strong_ptr<iface> > _ifaces; std::list<std::shared_ptr<iface> > _ifaces;
// The remaining time in miliseconds the object will stay in the // The remaining time in miliseconds the object will stay in the
// interface's session array or cache. // interface's session array or cache.
@ -44,7 +44,7 @@ private:
int _status; int _status;
static std::list<weak_ptr<session> > _sessions; static std::list<std::weak_ptr<session> > _sessions;
public: public:
enum enum
@ -59,10 +59,10 @@ public:
// Destructor. // Destructor.
~session(); ~session();
static strong_ptr<session> create(const strong_ptr<proxy>& pr, const address& saddr, static std::shared_ptr<session> create(const std::shared_ptr<proxy>& pr, const address& saddr,
const address& daddr, const address& taddr); const address& daddr, const address& taddr);
void add_iface(const strong_ptr<iface>& ifa); void add_iface(const std::shared_ptr<iface>& ifa);
const address& taddr() const; const address& taddr() const;