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

📄 xorp_rip_main.cc

📁 RIP 协议实现
💻 CC
字号:
// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-// Copyright (c) 2001-2008 XORP, Inc.//// Permission is hereby granted, free of charge, to any person obtaining a// copy of this software and associated documentation files (the "Software")// to deal in the Software without restriction, subject to the conditions// listed in the XORP LICENSE file. These conditions include: you must// preserve this copyright notice, and you cannot mention the copyright// holders in advertising related to the Software without their permission.// The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This// notice is a summary of the XORP LICENSE file; the license in that file is// legally binding.#ident "$XORP: xorp/rip/xorp_rip_main.cc,v 1.20 2008/07/23 05:11:37 pavlin Exp $"#include "rip_module.h"#include "libxorp/xlog.h"#include "libxorp/eventloop.hh"#include "libxorp/ipv4.hh"#include "libxorp/ipv6.hh"#include "libxipc/finder_constants.hh"#include "libxipc/xrl_std_router.hh"#include "libfeaclient/ifmgr_xrl_mirror.hh"#include "rip/constants.hh"#include "rip/system.hh"#include "rip/xrl_config.hh"#include "rip/xrl_target_rip.hh"#include "rip/xrl_port_manager.hh"#include "rip/xrl_process_spy.hh"#include "rip/xrl_redist_manager.hh"#include "rip/xrl_rib_notifier.hh"#include "rip/xrl_target_rip.hh"#include "rip/xrl_target_ripng.hh"#ifdef HAVE_GETOPT_H#include <getopt.h>#endif/** * @short Class specialized to determine correct type of XrlTarget for * addresses of type A. */template <typename A>struct XrlTarget {};template <>struct XrlTarget<IPv4> {    typedef XrlRipTarget Type;    static const char* name() { return "rip"; }};template <>struct XrlTarget<IPv6> {    typedef XrlRipngTarget Type;    static const char* name() { return "ripng"; }};/** * Unary function class to build string containing ServiceBase objects * in a particular state. */class service_names_in {public:    service_names_in(ServiceStatus in_state, string& out)	: _st(in_state), _o(out)    {}    void operator() (const ServiceBase* sb) {	if (sb->status() != _st) return;	if (_o.empty() == false)	    _o += ", ";	_o += sb->service_name();    }protected:    ServiceStatus 	_st;    string& 		_o;};/** * Class to receive state changes of services used by RIP and update * status in the xrl interface accordingly. */template <typename A>class Service2XrlTargetStatus : public ServiceChangeObserverBase {protected:    void status_change(ServiceBase*, ServiceStatus, ServiceStatus)    {	update_status();    }public:    Service2XrlTargetStatus(typename XrlTarget<A>::Type& t)	: _t(t), _st(SERVICE_READY)    {}    ~Service2XrlTargetStatus()    {	while (_services.empty() == false) {	    _services.front()->unset_observer(this);	    _services.pop_front();	}    }    bool add_service(ServiceBase* sb)    {	if (sb->set_observer(this) == XORP_OK) {	    _services.push_back(sb);	    update_status();	    return true;	}	return false;    }    void remove_service(ServiceBase* sb)    {	list<ServiceBase*>::iterator i;	i = find(_services.begin(), _services.end(), sb);	if (i != _services.end()) {	    _services.erase(i);	}	sb->unset_observer(this);    }    void update_status()    {	// XXX This is particularly inefficient and not very good.	// Clear existing state mask and then fill with current	// service states.   This is then propagated to the XrlTarget.	_st = ServiceStatus(0u);	list<ServiceBase*>::const_iterator i;	for (i = _services.begin(); i != _services.end(); ++i) {	    ServiceBase *sb = *i;	    _st = ServiceStatus(_st | sb->status());	}	if (_st & SERVICE_FAILED) {	    string svcs;	    for_each(_services.begin(), _services.end(),		     service_names_in(SERVICE_FAILED, svcs));	    _t.set_status(PROC_FAILED, "Failure(s): " + svcs);	    return;	}	if (_st & SERVICE_SHUTTING_DOWN) {	    string svcs;	    for_each(_services.begin(), _services.end(),		     service_names_in(SERVICE_SHUTTING_DOWN, svcs));	    _t.set_status(PROC_SHUTDOWN, "Awaiting shutdown of: " + svcs);	    return;	}	if (_st & (SERVICE_STARTING | SERVICE_READY)) {	    string svcs;	    for_each(_services.begin(), _services.end(),		     service_names_in(SERVICE_STARTING, svcs));	    _t.set_status(PROC_STARTUP, "Awaiting start up of: " + svcs);	    return;	}	XLOG_ASSERT(_st == SERVICE_RUNNING);	_t.set_status(PROC_READY, "");    }    bool have_status(ServiceStatus st) { return _st & st; }protected:    typename XrlTarget<A>::Type&	_t;    list<ServiceBase*>			_services;    ServiceStatus			_st;};/** * Extract Host and port from either host string or host colon port string, eg * "host" or "<host>:<port>". * * @param host_colon_port string to be scanned [in]. * @param host host component of scanned string [out]. * @param port port component of scanned string [out]. * @return true on success, false if port value is invalid. */static boolparse_finder_args(const string& host_colon_port, string& host, uint16_t& port){    string::size_type sp = host_colon_port.find(":");    if (sp == string::npos) {	host = host_colon_port;	// Do not set port, by design it has default finder port value.    } else {	host = string(host_colon_port, 0, sp);	string s_port = string(host_colon_port, sp + 1, 14);	uint32_t t_port = atoi(s_port.c_str());	if (t_port == 0 || t_port > 65535) {	    XLOG_ERROR("Finder port %u is not in range 1--65535.\n",		       XORP_UINT_CAST(t_port));	    return false;	}	port = (uint16_t)t_port;    }    return true;}static voidusage(const char* name){    fprintf(stderr, "Usage: %s [options]\n", name);    fprintf(stderr, "Options:\n");    fprintf(stderr, "  -F <host>[:<port>]  Specify Finder host and port\n");    fprintf(stderr, "  -h                  Display this information\n");}/** * Class implementing RIP body. */template <typename A>class XorpRip{public:    typedef typename XrlTarget<A>::Type XrlTargetType;public:    XorpRip();    int main(int argc, char* const argv[]);protected:    void run(const string& finder_host, uint16_t finder_port);protected:    bool _stop_flag;};template <typename A>XorpRip<A>::XorpRip()    : _stop_flag(false){}template <typename A>voidXorpRip<A>::run(const string& finder_host, uint16_t finder_port){    XorpUnexpectedHandler catch_all(xorp_unexpected_handler);    try {	EventLoop		e;	System<A>		rip_system(e);	XrlStdRouter		xsr(e, XrlTarget<A>::name(),				    finder_host.c_str(), finder_port);	XrlProcessSpy		xps(xsr);	IfMgrXrlMirror 		ixm(e, xrl_fea_name(),				    FinderConstants::FINDER_DEFAULT_HOST(),				    FinderConstants::FINDER_DEFAULT_PORT());	XrlPortManager<A>	xpm(rip_system, xsr, ixm);	XrlRedistManager<A>	xrm(rip_system);	XrlTargetType xrlt(e, xsr, xps, xpm, xrm, _stop_flag, rip_system);	wait_until_xrl_router_is_ready(e, xsr);	Service2XrlTargetStatus<A> smon(xrlt);	// Start up process spy	xps.startup();	smon.add_service(&xps);	XrlRibNotifier<A> xn(e, rip_system.route_db().update_queue(), xsr);	xn.startup();	smon.add_service(&xn);	// Start up interface mirror	ixm.startup();	smon.add_service(&ixm);	// Start up xrl port manager	xpm.startup();	smon.add_service(&xpm);	// Start up xrl redist manager	xrm.startup();	smon.add_service(&xrm);	while ((_stop_flag == false)	       && (smon.have_status(SERVICE_FAILED) == false)	       && (xsr.failed() == false)) {	    e.run();	}	xps.shutdown();	xn.shutdown();	ixm.shutdown();	xpm.shutdown();	xrm.shutdown();	bool flag(false);	XorpTimer t = e.set_flag_after_ms(5000, &flag);	while (flag == false &&	       smon.have_status(		   ServiceStatus(~(SERVICE_FAILED | SERVICE_SHUTDOWN)))) {	    e.run();	}	smon.remove_service(&xps);	smon.remove_service(&xn);	smon.remove_service(&ixm);	smon.remove_service(&xpm);	rip_system.route_db().flush_routes();    } catch (...) {	xorp_catch_standard_exceptions();    }}template <typename A>intXorpRip<A>::main(int argc, char * const argv[]){    xlog_init(argv[0], NULL);    xlog_set_verbose(XLOG_VERBOSE_LOW);    xlog_level_set_verbose(XLOG_LEVEL_ERROR, XLOG_VERBOSE_HIGH);    xlog_add_default_output();    xlog_start();    string	finder_host = FinderConstants::FINDER_DEFAULT_HOST().str();    uint16_t	finder_port = FinderConstants::FINDER_DEFAULT_PORT();    bool	do_run 	    = true;    int ch;    while ((ch = getopt(argc, argv, "F:")) != -1) {	switch (ch) {	case 'F':	    do_run = parse_finder_args(optarg, finder_host, finder_port);	    break;	default:	    usage(argv[0]);	    do_run = false;	}    }    if (do_run)	run(finder_host, finder_port);    //    // Gracefully stop and exit xlog    //    xlog_stop();    xlog_exit();    return 0;}intmain(int argc, char* const argv[]){#if defined(INSTANTIATE_IPV4)    XorpRip<IPv4> xorp_rip;#elif defined(INSTANTIATE_IPV6)    XorpRip<IPv6> xorp_rip;#endif    return xorp_rip.main(argc, argv);}

⌨️ 快捷键说明

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