Now creating session on receiving NDP adverts even if no one has specifically asked for one yet thus ensuring the routes are created and that the latecy on proxy solicitation is kept much lower

This commit is contained in:
John Sharratt 2017-07-02 22:38:23 +02:00
parent f6ef3fe494
commit 89130bf099
7 changed files with 101 additions and 42 deletions

View File

@ -599,6 +599,7 @@ int iface::poll_all()
continue;
}
bool found = false;
for (std::list<weak_ptr<session> >::iterator s_it = ifa->_sessions.begin();
s_it != ifa->_sessions.end(); s_it++) {
assert(!s_it->is_null());
@ -607,9 +608,18 @@ int iface::poll_all()
if ((sess->taddr() == taddr) && (sess->status() == session::WAITING || sess->status() == session::RENEWING)) {
sess->handle_advert(ifa);
found = true;
break;
}
}
if (found == false) {
if (ifa->owner()) {
ifa->owner()->handle_advert(saddr, taddr, ifa);
} else {
logger::debug() << "iface::poll_all - ignoring advert on proxy iface=" << ifa->name();
}
}
}
}
@ -709,4 +719,14 @@ const ptr<proxy>& iface::pr() const
return _pr;
}
void iface::owner(const ptr<proxy>& pr)
{
_owner = pr;
}
const ptr<proxy>& iface::owner() const
{
return _owner;
}
NDPPD_NS_END

View File

@ -70,6 +70,10 @@ public:
const ptr<proxy>& pr() const;
void owner(const ptr<proxy>& pr);
const ptr<proxy>& owner() const;
private:
static std::map<std::string, weak_ptr<iface> > _map;
@ -109,6 +113,8 @@ private:
weak_ptr<proxy> _pr;
weak_ptr<proxy> _owner;
// The link-layer address of this interface.
struct ether_addr hwaddr;

View File

@ -204,6 +204,7 @@ static bool configure(ptr<conf>& cf)
if (!ifa || ifa.is_null() == true) {
return false;
}
ifa->owner(pr);
pr->add_rule(addr, ifa);
} else if (ru_cf->find("auto")) {

View File

@ -27,6 +27,8 @@
NDPPD_NS_BEGIN
static address all_nodes = address("ff02::1");
std::list<ptr<proxy> > proxy::_list;
proxy::proxy() :
@ -61,14 +63,8 @@ ptr<proxy> proxy::open(const std::string& ifname, bool promiscuous)
return create(ifa, promiscuous);
}
void proxy::handle_solicit(const address& saddr, const address& daddr,
const address& taddr)
ptr<session> proxy::find_or_create_session(const address& saddr, const address& daddr, const address& taddr, const ptr<iface>& receiver)
{
logger::debug()
<< "proxy::handle_solicit() ifa=" << ((_ifa) ? _ifa->name() : "null")
<< ", saddr=" << saddr.to_string()
<< ", taddr=" << taddr.to_string();
// Let's check this proxy's list of sessions to see if we can
// find one with the same target address.
@ -76,21 +72,7 @@ void proxy::handle_solicit(const address& saddr, const address& daddr,
sit != _sessions.end(); sit++) {
if ((*sit)->taddr() == taddr)
{
(*sit)->touch();
switch ((*sit)->status()) {
case session::WAITING:
case session::INVALID:
break;
case session::VALID:
case session::RENEWING:
(*sit)->send_advert();
}
return;
}
return (*sit);
}
// Since we couldn't find a session that matched, we'll try to find
@ -104,10 +86,13 @@ void proxy::handle_solicit(const address& saddr, const address& daddr,
logger::debug() << "checking " << ru->addr() << " against " << taddr;
if (!daddr.is_multicast() && ru->addr() != daddr) {
if (!daddr.is_multicast() && ru->addr() != daddr && daddr != taddr) {
continue;
}
if (receiver && ru->ifa() && receiver->name() != ru->ifa()->name())
continue;
if (ru->addr() == taddr) {
if (!se) {
se = session::create(_ptr, saddr, daddr, taddr, _autowire);
@ -129,14 +114,14 @@ void proxy::handle_solicit(const address& saddr, const address& daddr,
// This rule doesn't have an interface, and thus we'll consider
// it "static" and immediately send the response.
se->handle_advert();
return;
return se;
} else {
se->add_iface((*it)->ifa());
#ifdef WITH_ND_NETLINK
if (if_addr_find((*it)->ifa()->name(), &taddr.const_addr())) {
logger::debug() << "Sending NA out " << (*it)->ifa()->name();
se->add_iface(_ifa);
se->handle_advert(_ifa);
se->handle_advert();
}
#endif
}
@ -145,7 +130,44 @@ void proxy::handle_solicit(const address& saddr, const address& daddr,
if (se) {
_sessions.push_back(se);
se->send_solicit();
}
return se;
}
void proxy::handle_advert(const address& saddr, const address& taddr, const ptr<iface>& receiver)
{
logger::debug()
<< "proxy::handle_advert() proxy=" << (ifa() ? ifa()->name() : "null") << ", receiver=" << (receiver ? receiver->name() : "null")
<< ", saddr=" << saddr.to_string()
<< ", taddr=" << taddr.to_string();
ptr<session> se = find_or_create_session(saddr, all_nodes, taddr, receiver);
if (!se) return;
se->handle_advert(receiver);
}
void proxy::handle_solicit(const address& saddr, const address& daddr, const address& taddr)
{
logger::debug()
<< "proxy::handle_solicit() ifa=" << ((_ifa) ? _ifa->name() : "null")
<< ", saddr=" << saddr.to_string()
<< ", taddr=" << taddr.to_string();
ptr<session> se = find_or_create_session(saddr, daddr, taddr, ptr<iface>());
if (!se) return;
se->touch();
switch (se->status()) {
case session::WAITING:
case session::INVALID:
return;
case session::VALID:
case session::RENEWING:
se->send_advert();
}
}

View File

@ -34,8 +34,11 @@ public:
static ptr<proxy> open(const std::string& ifn, bool promiscuous);
void handle_solicit(const address& saddr, const address& daddr,
const address& taddr);
ptr<session> find_or_create_session(const address& saddr, const address& daddr, const address& taddr, const ptr<iface>& receiver);
void handle_advert(const address& saddr, const address& taddr, const ptr<iface>& receiver);
void handle_solicit(const address& saddr, const address& daddr, const address& taddr);
void remove_session(const ptr<session>& se);

View File

@ -106,12 +106,12 @@ ptr<session> session::create(const ptr<proxy>& pr, const address& saddr,
se->_autowire = auto_wire;
se->_wired = false;
se->_ttl = pr->timeout();
se->_touched = true;
se->_touched = false;
_sessions.push_back(se);
logger::debug()
<< "session::create() pr=" << logger::format("%x", (proxy* )pr) << ", slave=" << ((pr->ifa()) ? pr->ifa()->name() : "null") << ", saddr=" << saddr
<< "session::create() pr=" << logger::format("%x", (proxy* )pr) << ", proxy=" << ((pr->ifa()) ? pr->ifa()->name() : "null") << ", saddr=" << saddr
<< ", daddr=" << daddr << ", taddr=" << taddr << ", autowire=" << (auto_wire == true ? "yes" : "no") << " =" << logger::format("%x", (session* )se);
return se;
@ -139,7 +139,13 @@ void session::send_solicit()
void session::touch()
{
if (_touched == false)
{
_touched = true;
if (status() == session::WAITING || status() == session::INVALID)
send_solicit();
}
}
void session::send_advert()
@ -193,13 +199,14 @@ void session::handle_auto_unwire(const ptr<iface>& ifa)
void session::handle_advert(const ptr<iface>& ifa)
{
if (_autowire == true) {
if (_autowire == true && _status == WAITING) {
handle_auto_wire(ifa);
}
handle_advert();
}
void session::handle_advert()
{
logger::debug()