diff --git a/ndppd.conf-dist b/ndppd.conf-dist index 5608252..4ec1657 100644 --- a/ndppd.conf-dist +++ b/ndppd.conf-dist @@ -38,6 +38,19 @@ proxy eth0 { autowire no + # keepalive + # Controls whether ndppd will automatically attempt to keep routing + # sessions alive by actively sending out NDP Solicitations before the the + # session is expired. The the default value is yes. + + keepalive yes + + # retries + # Number of times a NDP Solicitation will be sent out before the daemon + # considers a route unreachable. The default value is 3 + + retries 3 + # promiscuous # Controls whether ndppd will put the proxy listening interface into promiscuous # mode and hence will react to inbound and outbound NDP commands. This is diff --git a/src/ndppd.cc b/src/ndppd.cc index a4e44e4..2d9d713 100644 --- a/src/ndppd.cc +++ b/src/ndppd.cc @@ -178,6 +178,16 @@ static bool configure(ptr& cf) pr->autowire(false); else pr->autowire(*x_cf); + + if (!(x_cf = pr_cf->find("keepalive"))) + pr->keepalive(true); + else + pr->keepalive(*x_cf); + + if (!(x_cf = pr_cf->find("retries"))) + pr->retries(3); + else + pr->retries(*x_cf); if (!(x_cf = pr_cf->find("ttl"))) pr->ttl(30000); diff --git a/src/proxy.cc b/src/proxy.cc index 226b581..4197232 100644 --- a/src/proxy.cc +++ b/src/proxy.cc @@ -32,7 +32,7 @@ static address all_nodes = address("ff02::1"); std::list > proxy::_list; proxy::proxy() : - _router(true), _ttl(30000), _deadtime(3000), _timeout(500), _autowire(false), _promiscuous(false) + _router(true), _ttl(30000), _deadtime(3000), _timeout(500), _autowire(false), _keepalive(true), _promiscuous(false), _retries(3) { } @@ -86,7 +86,7 @@ ptr proxy::find_or_create_session(const address& saddr, const address& { if ((*ad)->addr() == taddr && (*ad)->ifname() == receiver->name()) { - se = session::create(_ptr, saddr, daddr, taddr, _autowire); + se = session::create(_ptr, saddr, daddr, taddr, _autowire, _keepalive, _retries); if (se) { se->add_iface(receiver); _sessions.push_back(se); @@ -118,7 +118,7 @@ ptr proxy::find_or_create_session(const address& saddr, const address& if (ru->addr() == taddr) { if (!se) { - se = session::create(_ptr, saddr, daddr, taddr, _autowire); + se = session::create(_ptr, saddr, daddr, taddr, _autowire, _keepalive, _retries); } if (ru->is_auto()) { @@ -258,6 +258,26 @@ void proxy::autowire(bool val) _autowire = val; } +int proxy::retries() const +{ + return _retries; +} + +void proxy::retries(int val) +{ + _retries = val; +} + +bool proxy::keepalive() const +{ + return _keepalive; +} + +void proxy::keepalive(bool val) +{ + _keepalive = val; +} + int proxy::ttl() const { return _ttl; diff --git a/src/proxy.h b/src/proxy.h index c09212d..e7faffc 100644 --- a/src/proxy.h +++ b/src/proxy.h @@ -57,6 +57,14 @@ public: bool autowire() const; void autowire(bool val); + + int retries() const; + + void retries(int val); + + bool keepalive() const; + + void keepalive(bool val); int timeout() const; @@ -86,6 +94,10 @@ private: bool _router; bool _autowire; + + int _retries; + + bool _keepalive; int _ttl, _deadtime, _timeout; diff --git a/src/session.cc b/src/session.cc index 10e7130..317a31f 100644 --- a/src/session.cc +++ b/src/session.cc @@ -46,20 +46,41 @@ void session::update_all(int elapsed_time) case session::WAITING: logger::debug() << "session is now invalid [taddr=" << se->_taddr << "]"; - se->_status = session::INVALID; - se->_ttl = se->_pr->deadtime(); + + if (se->_fails < se->_retries) { + se->_ttl = se->_pr->timeout(); + se->_fails++; + + // Send another solicit + se->send_solicit(); + } else { + se->_status = session::INVALID; + se->_ttl = se->_pr->deadtime(); + } break; case session::RENEWING: logger::debug() << "session is became invalid [taddr=" << se->_taddr << "]"; - se->_pr->remove_session(se); + + if (se->_fails < se->_retries) { + se->_ttl = se->_pr->timeout(); + se->_fails++; + + // Send another solicit + se->send_solicit(); + } else { + se->_pr->remove_session(se); + } break; case session::VALID: - if (se->_touched == true) { + if (se->touched() == true || + se->keepalive() == true) + { logger::debug() << "session is renewing [taddr=" << se->_taddr << "]"; se->_status = session::RENEWING; se->_ttl = se->_pr->timeout(); + se->_fails = 0; se->_touched = false; // Send another solicit to make sure the route is still valid @@ -94,7 +115,7 @@ session::~session() } ptr session::create(const ptr& pr, const address& saddr, - const address& daddr, const address& taddr, bool auto_wire) + const address& daddr, const address& taddr, bool auto_wire, bool keepalive, int retries) { ptr se(new session()); @@ -104,6 +125,8 @@ ptr session::create(const ptr& pr, const address& saddr, se->_taddr = taddr; se->_daddr = daddr; se->_autowire = auto_wire; + se->_keepalive = keepalive; + se->_retries = retries; se->_wired = false; se->_ttl = pr->timeout(); se->_touched = false; @@ -112,7 +135,7 @@ ptr session::create(const ptr& pr, const address& saddr, logger::debug() << "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); + << ", daddr=" << daddr << ", taddr=" << taddr << " =" << logger::format("%x", (session* )se); return se; } @@ -214,6 +237,7 @@ void session::handle_advert() _status = VALID; _ttl = _pr->ttl(); + _fails = 0; send_advert(); } @@ -238,6 +262,21 @@ bool session::autowire() const return _autowire; } +bool session::keepalive() const +{ + return _keepalive; +} + +int session::retries() const +{ + return _retries; +} + +int session::fails() const +{ + return _fails; +} + bool session::wired() const { return _wired; diff --git a/src/session.h b/src/session.h index 6b6a6cc..fd2b82a 100644 --- a/src/session.h +++ b/src/session.h @@ -34,6 +34,8 @@ private: bool _autowire; + bool _keepalive; + bool _wired; bool _touched; @@ -45,6 +47,10 @@ private: // The remaining time in miliseconds the object will stay in the // interface's session array or cache. int _ttl; + + int _fails; + + int _retries; int _status; @@ -65,7 +71,7 @@ public: ~session(); static ptr create(const ptr& pr, const address& saddr, - const address& daddr, const address& taddr, bool autowire); + const address& daddr, const address& taddr, bool autowire, bool keepalive, int retries); void add_iface(const ptr& ifa); @@ -77,6 +83,12 @@ public: bool autowire() const; + int retries() const; + + int fails() const; + + bool keepalive() const; + bool wired() const; bool touched() const;