diff --git a/src/iface.cc b/src/iface.cc index 2e6b524..ff88fde 100644 --- a/src/iface.cc +++ b/src/iface.cc @@ -588,7 +588,7 @@ int iface::poll_all() const ptr sess = *s_it; - if ((sess->taddr() == taddr) && (sess->status() == session::WAITING)) { + if ((sess->taddr() == taddr) && (sess->status() == session::WAITING || sess->status() == session::RENEWING)) { sess->handle_advert(ifa); break; } diff --git a/src/proxy.cc b/src/proxy.cc index da71c36..ad709a6 100644 --- a/src/proxy.cc +++ b/src/proxy.cc @@ -72,6 +72,8 @@ void proxy::handle_solicit(const address& saddr, const address& daddr, for (std::list >::iterator sit = _sessions.begin(); sit != _sessions.end(); sit++) { + + (*sit)->touch(); if ((*sit)->taddr() == taddr) { switch ((*sit)->status()) { @@ -80,6 +82,7 @@ void proxy::handle_solicit(const address& saddr, const address& daddr, break; case session::VALID: + case session::RENEWING: (*sit)->send_advert(); } diff --git a/src/session.cc b/src/session.cc index 083b4db..c564bdf 100644 --- a/src/session.cc +++ b/src/session.cc @@ -48,6 +48,20 @@ void session::update_all(int elapsed_time) se->_status = session::INVALID; se->_ttl = se->_pr->deadtime(); break; + + case session::VALID: + if (se->_touched == true) { + logger::debug() << "session is renewing"; + se->_status = session::RENEWING; + se->_ttl = se->_pr->timeout(); + se->_touched = false; + + // Send another solicit to make sure the route is still valid + se->send_solicit(); + } else { + se->_pr->remove_session(se); + } + break; default: se->_pr->remove_session(se); @@ -82,6 +96,7 @@ ptr session::create(const ptr& pr, const address& saddr, se->_daddr = daddr; se->_autowire = auto_wire; se->_ttl = pr->timeout(); + se->_touched = true; _sessions.push_back(se); @@ -112,6 +127,11 @@ void session::send_solicit() } } +void session::touch() +{ + _touched = true; +} + void session::send_advert() { _pr->ifa()->write_advert(_saddr, _taddr, _pr->router()); @@ -197,6 +217,11 @@ bool session::autowire() const return _autowire; } +bool session::touched() const +{ + return _touched; +} + int session::status() const { return _status; diff --git a/src/session.h b/src/session.h index 27c57d5..b01d6c5 100644 --- a/src/session.h +++ b/src/session.h @@ -33,6 +33,8 @@ private: address _saddr, _daddr, _taddr; bool _autowire; + + bool _touched; // An array of interfaces this session is monitoring for // ND_NEIGHBOR_ADVERT on. @@ -49,9 +51,10 @@ private: public: enum { - WAITING, // Waiting for an advert response. - VALID, // Valid; - INVALID // Invalid; + WAITING, // Waiting for an advert response. + RENEWING, // Renewing; + VALID, // Valid; + INVALID // Invalid; }; static void update_all(int elapsed_time); @@ -71,6 +74,8 @@ public: const address& saddr() const; bool autowire() const; + + bool touched() const; int status() const; @@ -83,6 +88,8 @@ public: void handle_auto_wire(const ptr& ifa); void handle_auto_unwire(const ptr& ifa); + + void touch(); void send_advert();