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

📄 peer.cc

📁 xorp源码hg
💻 CC
📖 第 1 页 / 共 4 页
字号:
// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-// Copyright (c) 2001-2007 International Computer Science Institute//// 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/bgp/harness/peer.cc,v 1.80 2007/02/16 22:45:25 pavlin Exp $"// #define DEBUG_LOGGING// #define DEBUG_PRINT_FUNCTION_NAME#include "bgp/bgp_module.h"#include "libxorp/debug.h"#include "libxorp/xlog.h"#include "libxorp/eventloop.hh"#include "libxorp/ipv4net.hh"#include "libxorp/utils.hh"#include "libproto/packet.hh"#include "libxipc/xrl_std_router.hh"#include "xrl/interfaces/test_peer_xif.hh"#include "bgp/local_data.hh"#include "bgp/packet.hh"#include "peer.hh"#include "bgppp.hh"Peer::~Peer(){    debug_msg("XXX Deleting peer %p\n", this);}Peer::Peer(EventLoop    *eventloop,	   XrlStdRouter *xrlrouter,	   const string& peername,	   const uint32_t genid,	   const string& target_hostname,	   const string& target_port)    : _eventloop(eventloop),      _xrlrouter(xrlrouter),      _peername(peername),      _genid(genid),      _target_hostname(target_hostname),      _target_port(target_port),      _up(true),      _busy(0),      _connected(false),      _session(false),      _passive(false),      _established(false),      _keepalive(false),      _as(AsNum::AS_INVALID), // XXX      _holdtime(0),      _ipv6(false){    debug_msg("XXX Creating peer %p\n", this);}Peer::Peer(const Peer& rhs)    : _as(AsNum::AS_INVALID) // XXX{    debug_msg("Copy constructor\n");    copy(rhs);}Peer::Peer&Peer::operator=(const Peer& rhs){    debug_msg("= operator\n");    if(&rhs == this)	return *this;    copy(rhs);        return *this;}voidPeer::copy(const Peer& rhs){    debug_msg("peername: %s\n", rhs._peername.c_str());    _eventloop = rhs._eventloop;    _xrlrouter = rhs._xrlrouter;    _peername = rhs._peername;    _genid = rhs._genid;    _target_hostname = rhs._target_hostname;    _target_port = rhs._target_port;    _up = rhs._up;    _busy = rhs._busy;    _session = rhs._session;    _passive = rhs._passive;    _keepalive = rhs._keepalive;    _established = rhs._established;    _as = rhs._as;    _holdtime = rhs._holdtime;    _ipv6 = rhs._ipv6;    _id = rhs._id;}Peer::PeerStatePeer::is_this_you(const string& peer_name) const{    debug_msg("is this you: %s %s\n", _peername.c_str(), peer_name.c_str());        if(_up && peer_name == _peername) {	debug_msg("Its me\n");	return Peer::YES_ITS_ME;    }    /*    ** If this peer has been down for ten minutes its a candidate to    ** be deleted. There should be no more activity on this peer.    */    if(!_up) {	TimeVal now;	_eventloop->current_time(now);	if(now - _shutdown_time > TimeVal(60 * 10, 0))	    return Peer::PLEASE_DELETE_ME;    }    return Peer::NO_ITS_NOT_ME;}Peer::PeerStatePeer::is_this_you(const string& peer_name, const uint32_t genid) const{    debug_msg("is this you: %s %s %u\n", _peername.c_str(), peer_name.c_str(),	      XORP_UINT_CAST(genid));        if(_up && peer_name == _peername && genid == _genid)	return Peer::YES_ITS_ME;    if(!_up)	return is_this_you("");    return Peer::NO_ITS_NOT_ME;}voidPeer::shutdown(){    XLOG_ASSERT(_up);	// We should only ever be shutdown once.    _up = false;    _eventloop->current_time(_shutdown_time);        /*    ** The corresponding test peer may have a tcp connection with a    ** bgp process. Attempt a disconnect.    */    _busy++;    XrlTestPeerV0p1Client test_peer(_xrlrouter);    if(!test_peer.send_reset(_peername.c_str(),			     callback(this, &Peer::xrl_callback, "reset")))	XLOG_FATAL("reset failed");}boolPeer::up() const{    return _up;}voidPeer::status(string& status){    status = _peername + " ";    status += _established ? "established" : "";    status += " ";    status += "sent: " + c_format("%u", XORP_UINT_CAST(_trie_sent.update_count())) + " ";    status += "received: " + c_format("%u", XORP_UINT_CAST(_trie_recv.update_count())) + " ";}boolPeer::pending(){    debug_msg("pending? : %s\n", (_session && !_established && !_passive)		  ? "true" : "false");//     if(_xrlrouter->pending())// 	return true;    if(_busy > 0)	return true;//     printf("%s: session: %d established: %d passive %d\n", // 	   _peername.c_str(), _session, _established, _passive);    if(_session && !_established && !_passive)	return true;    return false;}void Peer::listen(const string& /*line*/, const vector<string>& /*words*/)	throw(InvalidString){    /* Connect the test peer to the target BGP */    debug_msg("About to listen on: %s\n", _peername.c_str());    _busy += 3;    XrlTestPeerV0p1Client test_peer(_xrlrouter);    if(!test_peer.send_register(_peername.c_str(), _xrlrouter->name(), _genid,			callback(this, &Peer::xrl_callback, "register")))	XLOG_FATAL("send_register failed");    if(!test_peer.send_packetisation(_peername.c_str(), "bgp",			   callback(this, &Peer::xrl_callback,				    "packetisation")))	XLOG_FATAL("send_packetisation");    if(!test_peer.send_listen(_peername.c_str(),			   _target_hostname, atoi(_target_port.c_str()),			      callback(this, &Peer::xrl_callback, "listen")))	XLOG_FATAL("send_listen failed");}void Peer::connect(const string& /*line*/, const vector<string>& /*words*/)	throw(InvalidString){    /* Connect the test peer to the target BGP */    debug_msg("About to connect to: %s\n", _peername.c_str());    _busy += 3;    XrlTestPeerV0p1Client test_peer(_xrlrouter);    if(!test_peer.send_register(_peername.c_str(), _xrlrouter->name(), _genid,			callback(this, &Peer::xrl_callback, "register")))	XLOG_FATAL("send_register failed");    if(!test_peer.send_packetisation(_peername.c_str(), "bgp",		     callback(this, &Peer::xrl_callback, "packetisation")))	XLOG_FATAL("send_packetisation failed");    if(!test_peer.send_connect(_peername.c_str(),			   _target_hostname, atoi(_target_port.c_str()),			       callback(this, &Peer::xrl_callback_connected,					"connected")))	XLOG_FATAL("send_connect failed");}void Peer::disconnect(const string& /*line*/, const vector<string>& /*words*/)	throw(InvalidString){    /* Disconnect the test peer from the target BGP */    debug_msg("About to disconnect from: %s\n", _peername.c_str());    _busy++;    XrlTestPeerV0p1Client test_peer(_xrlrouter);    _session = false;    _established = false;    if(!test_peer.send_disconnect(_peername.c_str(),			  callback(this, &Peer::xrl_callback, "disconnect")))	XLOG_FATAL("send_disconnect failed");}/*** Form of command:** peer1 establish active <true/false> AS <asnum>***/voidPeer::establish(const string& line, const vector<string>& words)    throw(InvalidString){    debug_msg("About to establish a connection %s\n", _peername.c_str());    bool active = true;    _session = true;    /*    ** Parse the command line.    ** The arguments for this command come in pairs:    ** name value    */    uint16_t as = 0;    size_t size = words.size();    if(0 != (size % 2))	xorp_throw(InvalidString,		   c_format("Incorrect number of arguments:\n[%s]",			    line.c_str()));    for(size_t i = 2; i < words.size(); i += 2) {	debug_msg("name: %s value: %s\n",		  words[i].c_str(),		  words[i + 1].c_str());	if("active" == words[i]) {	    string aarg = words[i+1];	    if("true" == aarg)		active = true;	    else if("false" == aarg)		active = false;	    else		xorp_throw(InvalidString, 			   c_format("Illegal argument to active: <%s>\n[%s]",				    aarg.c_str(), line.c_str()));	} else if("AS" == words[i]) {	    as = atoi(words[i + 1].c_str());	} else if("keepalive" == words[i]) {	    string kaarg = words[i+1];	    if("true" == kaarg)		_keepalive = true;	    else if("false" == kaarg)		_keepalive = false;	    else		xorp_throw(InvalidString, 			   c_format("Illegal argument to keepalive: <%s>\n[%s]",				    kaarg.c_str(), line.c_str()));	} else if("holdtime" == words[i]) {	    _holdtime = atoi(words[i + 1].c_str());	} else if("id" == words[i]) {	    _id = IPv4(words[i + 1].c_str());	} else if("ipv6" == words[i]) {	    string ipv6arg = words[i+1];	    if("true" == ipv6arg)		_ipv6 = true;	    else if("false" == ipv6arg)		_ipv6 = false;	    else		xorp_throw(InvalidString, 			   c_format("Illegal argument to ipv6: <%s>\n[%s]",				    ipv6arg.c_str(), line.c_str()));	} else	    xorp_throw(InvalidString, 		       c_format("Illegal argument to establish: <%s>\n[%s]",				words[i].c_str(), line.c_str()));    }    if(0 == as)	xorp_throw(InvalidString,		   c_format("No AS number specified:\n[%s]", line.c_str()));    _as = AsNum(static_cast<uint16_t>(as));    if(!active) {	_passive = true;	listen(line, words);	return;    }    connect(line, words);    send_open();}voidPeer::send(const string& line, const vector<string>& words)    throw(InvalidString){    size_t size = words.size();    if(size < 3)	xorp_throw(InvalidString,		   c_format("Insufficient number of arguments:\n[%s]",			    line.c_str()));    const char PACKET[] = "packet";    const char DUMP[] = "dump";    if(PACKET == words[2]) {	send_packet(line, words);    } else if(DUMP == words[2]) {	send_dump(line, words);    } else {	xorp_throw(InvalidString,		   c_format(		   "Second argument should be %s or %s not <%s>\n[%s]",		   PACKET, DUMP, words[2].c_str(), line.c_str()));    }}/** * A corruption entry. * * The offset at which to corrupt a packet and the value with which to corrupt. */class Corrupt  { public:    Corrupt(uint32_t offset, uint8_t val) : _offset(offset), _val(val)    {}    uint32_t offset() const { return _offset; }    uint32_t val() const { return _val; } private:    uint32_t _offset;    uint8_t  _val;};/*** Form of command:** peer1 send packet update ...** peer1 send packet notify ...** peer1 send packet open ...** peer1 send packet keepalive** peer1 send packet corrupt offset byte offset byte ... update**							 notify**							 open**							 keepalive**** See the packet method for the rest of the commands*/voidPeer::send_packet(const string& line, const vector<string>& words)    throw(InvalidString){    size_t size = words.size();    uint32_t word = 3;    list<Corrupt> _corrupt;    if ("corrupt" == words[3]) {	word += 1;	// Pairs of offset byte should be in the stream until we reach	// packet.	while (word + 2 < size) {	    if (!xorp_isdigit(words[word][0])) {		xorp_throw(InvalidString,			   c_format("Should be an offset not %s\n[%s]",				    words[word].c_str(), line.c_str()));	    }	    if (!xorp_isdigit(words[word + 1][0])) {		xorp_throw(InvalidString,			   c_format("Should be a value not %s\n[%s]",				    words[word + 1].c_str(), line.c_str()));	    }	    _corrupt.push_back(Corrupt(atoi(words[word].c_str()),				       atoi(words[word+1].c_str())));	    word += 2;	    if (!xorp_isdigit(words[word][0]))		break;	}    }    const BGPPacket *pkt = Peer::packet(line, words, word);    size_t len;    uint8_t *buf = const_cast<uint8_t *>(pkt->encode(len));    delete pkt;    if (!_corrupt.empty()) {	list<Corrupt>::const_iterator i;	for (i = _corrupt.begin(); i != _corrupt.end(); i++) {	    if (i->offset() >= len)		xorp_throw(InvalidString,			   c_format("Offset %u larger than packet %u\n[%s]",				    i->offset(), XORP_UINT_CAST(len),				    line.c_str()));	    buf[i->offset()] = i->val();	}    }    /*    ** If this is an update message, save it in the sent trie.    */    const char update[] = "update";    if(update == words[3]) {	TimeVal tv;	_eventloop->current_time(tv);	try {	    _trie_sent.process_update_packet(tv, buf, len);	} catch(CorruptMessage& c) {

⌨️ 快捷键说明

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