From 0dbc3e288accafef1fca49378d38d939a9a799b5 Mon Sep 17 00:00:00 2001 From: Daniel Adolfsson Date: Tue, 7 Feb 2012 21:26:43 +0100 Subject: [PATCH] A couple of bugfixes * Fix a bug where pollfds would be changed while in the poll_all loop. This issue didn't exist before 'auto' was implemented. * Fix so 'auto' rules won't try to forward Neighbor Solicitation Packages through proxy's interface. * Some code cleanup. --- src/address.cc | 17 ++++++++++------- src/iface.cc | 14 +++++--------- src/iface.h | 2 +- src/proxy.cc | 17 ++++++++++------- src/route.cc | 21 +++++++++++++-------- 5 files changed, 39 insertions(+), 32 deletions(-) diff --git a/src/address.cc b/src/address.cc index 1097f63..23d1983 100644 --- a/src/address.cc +++ b/src/address.cc @@ -219,12 +219,12 @@ bool address::parse_string(const std::string& str) return false; } -* b++ =* p++; + *b++ =* p++; sz++; } -* b = '\0'; + *b = '\0'; if (inet_pton(AF_INET6, buf,& _addr) <= 0) { return false; @@ -245,24 +245,27 @@ bool address::parse_string(const std::string& str) if (*p++ != '/') return false; - while (*p && isspace(*p)) + while (*p && isspace(*p)) { p++; + } sz = 0; b = buf; while (*p) { - if (!isdigit(*p)) + if (!isdigit(*p)) { return false; + } - if (sz > 3) + if (sz > 3) { return false; + } -* b++ =* p++; + *b++ =* p++; sz++; } -* b = '\0'; + *b = '\0'; prefix(atoi(buf)); diff --git a/src/iface.cc b/src/iface.cc index afce06f..73eab99 100644 --- a/src/iface.cc +++ b/src/iface.cc @@ -169,7 +169,7 @@ ptr iface::open_pfd(const std::string& name) ifa->_pfd = fd; - fixup_pollfds(); + _map_dirty = true; return ifa; } @@ -273,7 +273,7 @@ ptr iface::open_ifd(const std::string& name) memcpy(&ifa->hwaddr, ifr.ifr_hwaddr.sa_data, sizeof(struct ether_addr)); - fixup_pollfds(); + _map_dirty = true; return ifa; } @@ -453,10 +453,6 @@ ssize_t iface::read_advert(address& saddr, address& taddr) void iface::fixup_pollfds() { - if (_map_dirty) { - clean(); - } - _pollfds.resize(_map.size()* 2); int i = 0; @@ -493,7 +489,7 @@ void iface::add_session(const ptr& se) _sessions.push_back(se); } -void iface::clean() +void iface::cleanup() { for (std::map >::iterator it = _map.begin(); it != _map.end(); it++) { @@ -501,14 +497,14 @@ void iface::clean() _map.erase(it); } } - - _map_dirty = false; } int iface::poll_all() { if (_map_dirty) { + cleanup(); fixup_pollfds(); + _map_dirty = false; } if (_pollfds.size() == 0) { diff --git a/src/iface.h b/src/iface.h index be4f050..efdd1ac 100644 --- a/src/iface.h +++ b/src/iface.h @@ -81,7 +81,7 @@ private: // Updates the array above. static void fixup_pollfds(); - static void clean(); + static void cleanup(); // Weak pointer so this object can reference itself. weak_ptr _ptr; diff --git a/src/proxy.cc b/src/proxy.cc index 062ae2b..2e0be92 100644 --- a/src/proxy.cc +++ b/src/proxy.cc @@ -94,7 +94,7 @@ void proxy::handle_solicit(const address& saddr, const address& daddr, for (std::list >::iterator it = _rules.begin(); it != _rules.end(); it++) { - ptr ru =* it; + ptr ru = *it; logger::debug() << "checking " << ru->addr() << " against " << taddr; @@ -104,13 +104,16 @@ void proxy::handle_solicit(const address& saddr, const address& daddr, } if (ru->is_auto()) { - ptr ifa = route::find_and_open(taddr); + ptr rt = route::find(taddr); - // If we could find a route matching our rule in /proc/net/ipv6_route, - // and it's not the same interface as the one pr (proxy) is using. - if (ifa && (ifa != ru->ifa())) { - se->add_iface(ifa); - continue; + if (rt->ifname() == _ifa->name()) { + logger::debug() << "skipping route since it's using interface " << rt->ifname(); + } else { + ptr ifa = rt->ifa(); + + if (ifa && (ifa != ru->ifa())) { + se->add_iface(ifa); + } } } else if (!ru->ifa()) { // This rule doesn't have an interface, and thus we'll consider diff --git a/src/route.cc b/src/route.cc index f27f030..9be838e 100644 --- a/src/route.cc +++ b/src/route.cc @@ -36,23 +36,27 @@ route::route(const address& addr, const std::string& ifname) : size_t route::hexdec(const char* str, unsigned char* buf, size_t size) { for (size_t i = 0; ; i++) { - if (i >= size) + if (i >= size) { return i; + } char c1 = tolower(str[i* 2]), c2 = tolower(str[i* 2 + 1]); - if (!isxdigit(c1) || !isxdigit(c2)) + if (!isxdigit(c1) || !isxdigit(c2)) { return i; + } - if ((c1 >= '0') && (c1 <= '9')) + if ((c1 >= '0') && (c1 <= '9')) { buf[i] = (c1 - '0') << 4; - else + } else { buf[i] = ((c1 - 'a') + 10) << 4; + } - if ((c2 >= '0') && (c2 <= '9')) + if ((c2 >= '0') && (c2 <= '9')) { buf[i] |= c2 - '0'; - else + } else { buf[i] |= (c2 - 'a') + 10; + } } } @@ -89,8 +93,9 @@ void route::load(const std::string& path) char buf[1024]; ifs.getline(buf, sizeof(buf)); - if (ifs.gcount() < 149) + if (ifs.gcount() < 149) { continue; + } address addr; @@ -127,7 +132,7 @@ void route::update(int elapsed_time) ptr route::create(const address& addr, const std::string& ifname) { ptr rt(new route(addr, ifname)); - logger::debug() << "route::create() addr=" << addr << ", ifname=" << ifname; + // logger::debug() << "route::create() addr=" << addr << ", ifname=" << ifname; _routes.push_back(rt); return rt; }