⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 route_db.cc

📁 RIP 协议实现
💻 CC
📖 第 1 页 / 共 2 页
字号:
		    // such metric, then remove the "set_cost()" statement		    // below, and add "return true;" at the end of this block.		    //		    r->set_cost(RIP_INFINITY);		    set_deletion_timer(r);		    updated = true;		}    //		delete_route(r);	    }	}    } else {	// route from other origin	if (!accepted) {	    delete new_route;	    return false;	}	// this is "RIP's decision" -- where one route wins another.	// Source-match filtering should go here.	bool should_replace = false;	do {	    if (r->cost() > new_route->cost()) {		should_replace = true;		break;	    }	    if (r->cost() < new_route->cost())		break;		// XXX: the old route is better	    //	    // Same cost routes	    //	    if (new_route->cost() == RIP_INFINITY) {		//		// XXX: Don't update routes if both the old and the new		// costs are infinity.		//		break;	    }	    //	    // If the existing route is showing signs of timing out, it	    // may be better to switch to an equally-good alternative route	    // immediately, rather than waiting for the timeout to happen.	    // The heuristic is: if the route is at least halfway to the	    // expiration point, switch to the new route	    // (see RFC 2453 Section 3.9.2 and RFC 2080 Section 2.4.2).	    //	    TimeVal expiry_timeval = TimeVal::ZERO();	    if (r->origin() != NULL)		expiry_timeval = TimeVal(r->origin()->expiry_secs(), 0);	    	    if (expiry_timeval == TimeVal::ZERO())		break;		// XXX: the old route would never expire	    TimeVal remain;	    if (r->timer().time_remaining(remain) != true)		break;		// XXX: couldn't get the remaining time	    if (remain < (expiry_timeval / 2)) {		should_replace = true;		break;	    }	    break;	} while (false);	    	if (should_replace) {	    r->set_nexthop(new_route->nexthop());	    r->set_ifname(new_route->ifname());	    r->set_vifname(new_route->vifname());	    r->set_tag(new_route->tag());	    r->set_cost(new_route->cost());	    r->set_policytags(new_route->policytags());	    r->set_origin(o);	    set_expiry_timer(r);	    updated = true;	}    	delete new_route;    }    if (updated) {	_uq->push_back(r);    }    return updated;}template <typename A>voidRouteDB<A>::dump_routes(vector<ConstDBRouteEntry>& routes){    typename RouteContainer::iterator i = _routes.begin();    while (i != _routes.end()) {	routes.push_back(i->second);	++i;    }}template <typename A>voidRouteDB<A>::flush_routes(){    _uq->flush();    _routes.erase(_routes.begin(), _routes.end());}template <typename A>uint32_tRouteDB<A>::route_count() const{    return _routes.size();}template <typename A>const RouteEntry<A>*RouteDB<A>::find_route(const IPNet<A>& net) const{    typename RouteContainer::const_iterator ri = _routes.find(net);    if (ri == _routes.end())	return 0;    return ri->second.get();}template <typename A>UpdateQueue<A>&RouteDB<A>::update_queue(){    return *_uq;}template <typename A>const UpdateQueue<A>&RouteDB<A>::update_queue() const{    return *_uq;}template <typename A>typename RouteDB<A>::RouteContainer&RouteDB<A>::routes(){    return _routes;}// ----------------------------------------------------------------------------// RouteWalkertemplate <typename A>const typename RouteWalker<A>::Net RouteWalker<A>::NO_NET(~A::ZERO(), 0);template <typename A>RouteWalker<A>::RouteWalker(RouteDB<A>& rdb)    : _route_db(rdb), _state(STATE_RUNNING),      _last_visited(NO_NET),      _pos(rdb.routes().begin()){}template <typename A>RouteWalker<A>::~RouteWalker(){}template <typename A>const typename RouteWalker<A>::Route*RouteWalker<A>::next_route(){    if (state() != STATE_RUNNING) {	XLOG_ERROR("Calling RouteWalker::next_route() whilst not in "		   "STATE_RUNNING state.");	return 0;    }    if (++_pos == _route_db.routes().end()) {	return 0;    }    return _pos->second.get();}template <typename A>const typename RouteWalker<A>::Route*RouteWalker<A>::current_route(){    if (state() != STATE_RUNNING) {	XLOG_ERROR("Calling RouteWalker::next_route() whilst not in "		   "STATE_RUNNING state.");	return 0;    }    if (_pos == _route_db.routes().end()) {	return 0;    }    return _pos->second.get();}template <typename A>voidRouteWalker<A>::pause(uint32_t pause_ms){    if (state() == STATE_PAUSED)	return;    _state = STATE_PAUSED;    if (_pos == _route_db.routes().end()) {	_last_visited = NO_NET;	return;    }    // Check if route has a deletion timer and if so push it's expiry time    // back to maximize the chance of the route still being valid when    // resume is called.  Otherwise we have to do more work to find a good    // point to resume from.  We're advertising the route at infinity    // so advertising it once past it's original expiry is no big deal    XorpTimer t = _pos->second->timer();    if (t.scheduled() && _pos->second->cost() == RIP_INFINITY) {	TimeVal next_run;	_route_db.eventloop().current_time(next_run);	next_run += TimeVal(0, 1000 * pause_ms * 2); // factor of 2 == slack	if (t.expiry() <= next_run) {	    t.schedule_at(next_run);	    _pos->second->set_timer(t);	}    }    _last_visited = _pos->second->net();}template <typename A>voidRouteWalker<A>::resume(){    if (state() != STATE_PAUSED)	return;    _state = STATE_RUNNING;    if (_last_visited == NO_NET) {	_pos = _route_db.routes().end();	return;    }    _pos = _route_db.routes().find(_last_visited);    if (_pos == _route_db.routes().end()) {	// Node got deleted despite our pushing back it's timer (???)	_pos = _route_db.routes().upper_bound(_last_visited);    }}template <typename A>voidRouteWalker<A>::reset(){    _state = STATE_RUNNING;    _pos = _route_db.routes().begin();}template <typename A>voidRouteDB<A>::push_routes(){    debug_msg("[RIP] Push routes\n");    //    // Push the original routes from all peers    //    for (typename set<Peer<A>* >::iterator i = _peers.begin();	 i != _peers.end(); ++i) {	Peer<A>* peer = *i;	peer->push_routes();    }    // XXX may have got RIB route adds because of delete_route    // flush is probably not necessary...    debug_msg("[RIP] Pushing the RIB routes we have\n");       for (typename RouteContainerNoRef::iterator i = _rib_routes.begin();	i != _rib_routes.end(); ++i) {	Route* r = (*i).second;	debug_msg("[RIP] Pushing RIB route %s\n", r->net().str().c_str());		update_route(r->net(), r->nexthop(), r->ifname(), r->vifname(),		     r->cost(), r->tag(), _rib_origin, r->policytags(), true);    }}template <typename A>voidRouteDB<A>::add_rib_route(const Net& net, const Addr& nexthop,			  const string& ifname, const string& vifname,			  uint32_t cost, uint32_t tag, RouteOrigin* origin,			  const PolicyTags& policytags){    debug_msg("[RIP] adding RIB route %s\n",net.str().c_str());      _rib_origin = origin;             typename RouteContainerNoRef::iterator i = _rib_routes.find(net);    if (i != _rib_routes.end()) {	Route* prev = (*i).second;	delete prev;    }    //    // XXX: We are cheating here NULL origin so we don't get association.    //    RouteOrigin* no_origin = NULL;    Route* r = new Route(net, nexthop, ifname, vifname, cost, no_origin, tag,			 policytags);    _rib_routes[net] = r;}template <typename A>voidRouteDB<A>::delete_rib_route(const Net& net){    debug_msg("[RIP] deleting RIB route %s\n",net.str().c_str());    typename RouteContainerNoRef::iterator i = _rib_routes.find(net);    if (i == _rib_routes.end())	return;			// XXX: nothing to do    Route* r = (*i).second;    delete r;    _rib_routes.erase(i);}// ----------------------------------------------------------------------------// Instantiations#ifdef INSTANTIATE_IPV4template class RouteDB<IPv4>;template class RouteWalker<IPv4>;#endif#ifdef INSTANTIATE_IPV6template class RouteDB<IPv6>;template class RouteWalker<IPv6>;#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -