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

📄 test_outputs.cc

📁 RIP 协议实现
💻 CC
📖 第 1 页 / 共 2 页
字号:
	: HorizonValidatorBase<A>(tpn, opn)    {}    bool valid_response(const RipPacket<A>* p)    {	IPNet<A> n;	A	 nh;	uint32_t cost;	uint32_t tag;	ResponseReader<A> rr(p);	while (rr.get(n, nh, cost, tag) == true) {	    this->_total_routes_seen++;	    if (this->_opn.find(n) == this->_opn.end()) {		verbose_log("Saw own or alien route with split horizon\n");		// ==> it's bogus		verbose_log("Failed Processing entry %u / %u %s cost %u\n",			    XORP_UINT_CAST(rr.packet_entry()),			    XORP_UINT_CAST(p->max_entries()),			    n.str().c_str(),			    XORP_UINT_CAST(cost));		return false;	    }	}	return true;    }    bool valid_in_sum() const    {	if (this->test_peer_routes_seen() != 0) {	    verbose_log("Test peer routes seen (%u) does not match expected "			"(%u)\n",			XORP_UINT_CAST(this->test_peer_routes_seen()),			XORP_UINT_CAST(0));	    return false;	}	verbose_log("total routes seen %u, test peer routes seen = %u\n",		    XORP_UINT_CAST(this->total_routes_seen()),		    XORP_UINT_CAST(this->test_peer_routes_seen()));	return this->total_routes_seen() == (uint32_t)this->_opn.size();    }};template <typename A>class PoisonReverseValidator : public HorizonValidatorBase<A> {public:    PoisonReverseValidator(const set<IPNet<A> >& tpn,			   const set<IPNet<A> >& opn)	: HorizonValidatorBase<A>(tpn, opn)    {}    bool valid_response(const RipPacket<A>* p)    {	IPNet<A> n;	A	 nh;	uint32_t cost;	uint32_t tag;	ResponseReader<A> rr(p);	while (rr.get(n, nh, cost, tag) == true) {	    this->_total_routes_seen++;	    if (this->_tpn.find(n) != this->_tpn.end() 		&& cost == RIP_INFINITY) {		this->_test_peer_routes_seen++;	    } else if (this->_opn.find(n) != this->_opn.end()) {		// No-op	    } else {		// Not a test peer net and not an other peer net		// ==> it's bogus		verbose_log("Failed Processing entry %u / %u %s cost %u\n",			    XORP_UINT_CAST(rr.packet_entry()),			    XORP_UINT_CAST(p->max_entries()),			    n.str().c_str(),			    XORP_UINT_CAST(cost));		return false;	    }	}	return true;    }    bool valid_in_sum() const    {	if (this->test_peer_routes_seen() != this->_tpn.size()) {	    verbose_log("Test routes seen (%u) does not match expected (%u)\n",			XORP_UINT_CAST(this->test_peer_routes_seen()),			XORP_UINT_CAST(this->_tpn.size()));	    return false;	}	verbose_log("total routes seen %u, test peer routes seen = %u\n",		    XORP_UINT_CAST(this->total_routes_seen()),		    XORP_UINT_CAST(this->test_peer_routes_seen()));	return this->test_peer_routes_seen() * 2 == this->total_routes_seen();    }};// ----------------------------------------------------------------------------// OutputTester//// This is a bit nasty, the OutputClass is either OutputUpdates or OutputTable// class.  These classes have the same methods and so it seems a waste to// write this code out twice.  OutputClass is only referenced in one location// so it's not rocket science to comprehend this.//static const IfMgrIfTree ift_dummy = IfMgrIfTree();template <typename A, typename OutputClass>class OutputTester{public:    OutputTester(const set<IPNet<A> >& test_peer_nets,		 const set<IPNet<A> >& other_peer_nets)	: _e(), _rip_system(_e), _pm(_rip_system, ift_dummy),	  _tpn(test_peer_nets), _opn(other_peer_nets)    {	_pm.test_port()->constants().set_expiry_secs(10);	_pm.test_port()->constants().set_deletion_secs(5);	_pm.test_port()->set_advertise_default_route(false);	_pm.other_port()->constants().set_expiry_secs(10);	_pm.other_port()->constants().set_deletion_secs(5);	_pm.test_port()->set_io_handler(new BlockedPortIO<A>(*_pm.test_port()),					true);	_pm.other_port()->set_io_handler(			new BlockedPortIO<A>(*_pm.other_port()), true);    }    ~OutputTester()    {	RouteDB<A>& rdb = _rip_system.route_db();	rdb.flush_routes();    }    int    run_test(RipHorizon horizon, HorizonValidatorBase<A>& validator)    {	string ifname, vifname;		// XXX: not set, because not needed	_pm.test_port()->set_horizon(horizon);	RouteDB<A>&    rdb = _rip_system.route_db();	PacketQueue<A> op_out;				      // Output pkt qu.	OutputClass    ou(_e, *_pm.test_port(), op_out, rdb); // Output pkt gen	ou.start();	verbose_log("Injecting routes from test peer.\n");	for (typename set<IPNet<A> >::const_iterator n = _tpn.begin();	     n != _tpn.end(); n++) {	    RouteEntryOrigin<A>* reo = _pm.test_peer();	    if (rdb.update_route(*n, A::ZERO(), ifname, vifname, 5u, 0u, reo,				 PolicyTags(), false) == false) {		verbose_log("Failed to add route for %s\n",			    n->str().c_str());		return 1;	    }	}	verbose_log("Injecting routes from other peer.\n");	for (typename set<IPNet<A> >::const_iterator n = this->_opn.begin();	     n != this->_opn.end(); n++) {	    RouteEntryOrigin<A>* reo = _pm.other_peer();	    if (rdb.update_route(*n, A::ZERO(), ifname, vifname, 5u, 0u, reo,				 PolicyTags(), false) == false) {		verbose_log("Failed to add route for %s\n",			    n->str().c_str());		return 1;	    }	}	bool timeout = false;	XorpTimer tot = _e.set_flag_after_ms(10000, &timeout);	ou.start();	while (ou.running() && timeout == false) {  	    _e.run();	}	verbose_log("%u bytes buffered in packet queue.\n",		    XORP_UINT_CAST(op_out.buffered_bytes()));	if (timeout) {	    verbose_log("Timed out!\n");	    return 1;	}	uint32_t cnt = 0;	while (op_out.empty() == false) {	    if (validator.valid_response(op_out.head()) == false) {		verbose_log("Failed on packet validation.\n");		return 1;	    }	    op_out.pop_head();	    cnt++;	}	if (validator.valid_in_sum() == false) {	    verbose_log("Not valid in sum.\n");	    return 1;	}	return 0;    }protected:    EventLoop		_e;    System<A>		_rip_system;    SpoofPortManager<A> _pm;    const set<IPNet<A> >& _tpn;    const set<IPNet<A> >& _opn;};/** * Print program info to output stream. * * @param stream the output stream the print the program info to. */static voidprint_program_info(FILE *stream){    fprintf(stream, "Name:          %s\n", program_name);    fprintf(stream, "Description:   %s\n", program_description);    fprintf(stream, "Version:       %s\n", program_version_id);    fprintf(stream, "Date:          %s\n", program_date);    fprintf(stream, "Copyright:     %s\n", program_copyright);    fprintf(stream, "Return:        %s\n", program_return_value);}/* * Print program usage information to the stderr. * * @param progname the name of the program. */static voidusage(const char* progname){    print_program_info(stderr);    fprintf(stderr, "usage: %s [-v] [-h]\n", progname);    fprintf(stderr, "       -h          : usage (this message)\n");    fprintf(stderr, "       -v          : verbose output\n");}// ----------------------------------------------------------------------------// Injected Network statetemplate <typename A>intrun_all_test_cases(){    int rval = 0;    static const uint32_t n_routes = 577;    // Make one large collection of unique nets    set<IPNet<A> > all_nets;    make_nets<A>(all_nets, 2 * n_routes);    set<IPNet<A> > tpn;	// networks associated with peer under test    set<IPNet<A> > opn;	// networks associated with other peer.    // Split large collection into nets for tpn and opn    for_each(all_nets.begin(), all_nets.end(), SplitNets<A>(tpn, opn));    //    // OutputUpdates class tests    //    {	verbose_log("=== IPv%u No Horizon updates test ===\n",		    XORP_UINT_CAST(A::ip_version()));	OutputTester<A, OutputUpdates<A> > tester(tpn, opn);	NoHorizonValidator<A> nohv(tpn, opn);	rval |= tester.run_test(NONE, nohv);	if (rval)	    return rval;    }    {	verbose_log("=== IPv%u Split Horizon updates test ===\n",		    XORP_UINT_CAST(A::ip_version()));	OutputTester<A, OutputUpdates<A> > tester(tpn, opn);	SplitHorizonValidator<A> shv(tpn, opn);	rval |= tester.run_test(SPLIT, shv);	if (rval)	    return rval;    }    {	verbose_log("=== IPv%u Split Horizon Poison Reverse test ===\n",		    XORP_UINT_CAST(A::ip_version()));	OutputTester<A, OutputUpdates<A> > tester(tpn, opn);	PoisonReverseValidator<A> prv(tpn, opn);	rval |= tester.run_test(SPLIT_POISON_REVERSE, prv);	if (rval)	    return rval;    }    //    // OutputTable class tests    //    {	verbose_log("=== IPv%u No Horizon table test ===\n",		    XORP_UINT_CAST(A::ip_version()));	OutputTester<A, OutputTable<A> > tester(tpn, opn);	NoHorizonValidator<A> nohv(tpn, opn);	rval |= tester.run_test(NONE, nohv);	if (rval)	    return rval;    }    {	verbose_log("=== IPv%u Split Horizon table test ===\n",		    XORP_UINT_CAST(A::ip_version()));	OutputTester<A, OutputTable<A> > tester(tpn, opn);	SplitHorizonValidator<A> shv(tpn, opn);	rval |= tester.run_test(SPLIT, shv);	if (rval)	    return rval;    }    {	verbose_log("=== IPv%u Split Horizon Poison Reverse table test ===\n",		    XORP_UINT_CAST(A::ip_version()));	OutputTester<A, OutputTable<A> > tester(tpn, opn);	PoisonReverseValidator<A> prv(tpn, opn);	rval |= tester.run_test(SPLIT_POISON_REVERSE, prv);    }    return rval;}intmain(int argc, char* const argv[]){    //    // Initialize and start xlog    //    xlog_init(argv[0], NULL);    xlog_set_verbose(XLOG_VERBOSE_LOW);         // Least verbose messages    // XXX: verbosity of the error messages temporary increased    xlog_level_set_verbose(XLOG_LEVEL_ERROR, XLOG_VERBOSE_HIGH);    xlog_add_default_output();    xlog_start();    int ch;    while ((ch = getopt(argc, argv, "hv")) != -1) {        switch (ch) {        case 'v':            set_verbose(true);            break;        case 'h':        case '?':        default:            usage(argv[0]);            xlog_stop();            xlog_exit();            if (ch == 'h')                return (0);            else                return (1);        }    }    argc -= optind;    argv += optind;    int rval = 0;    XorpUnexpectedHandler x(xorp_unexpected_handler);    try {	rval |= run_all_test_cases<IPv4>();	rval |= run_all_test_cases<IPv6>();    } catch (...) {        // Internal error        xorp_print_standard_exceptions();        rval = 2;    }    //    // Gracefully stop and exit xlog    //    xlog_stop();    xlog_exit();    return rval;}

⌨️ 快捷键说明

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