xorp

peer_route_pair.hh

00001 // -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
00002 
00003 // Copyright (c) 2001-2011 XORP, Inc and Others
00004 //
00005 // This program is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License, Version 2, June
00007 // 1991 as published by the Free Software Foundation. Redistribution
00008 // and/or modification of this program under the terms of any other
00009 // version of the GNU General Public License is not permitted.
00010 // 
00011 // This program is distributed in the hope that it will be useful, but
00012 // WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details,
00014 // see the GNU General Public License, Version 2, a copy of which can be
00015 // found in the XORP LICENSE.gpl file.
00016 // 
00017 // XORP Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA;
00018 // http://xorp.net
00019 
00020 // $XORP: xorp/bgp/peer_route_pair.hh,v 1.21 2008/10/02 21:56:17 bms Exp $
00021 
00022 #ifndef __BGP_PEER_ROUTE_PAIR_HH__
00023 #define __BGP_PEER_ROUTE_PAIR_HH__
00024 
00025 
00026 
00027 #include "libxorp/xlog.h"
00028 #include "libxorp/timer.hh"
00029 
00030 #include "libxorp/timeval.hh"
00031 #include "libxorp/timer.hh"
00032 
00033 template<class A>
00034 class RouteQueueEntry;
00035 
00036 template<class A>
00037 class BGPRouteTable;
00038 
00039 template<class A>
00040 class PeerTableInfo {
00041 public:
00042     PeerTableInfo(BGPRouteTable<A> *init_route_table, 
00043           const PeerHandler *ph,
00044           uint32_t genid)
00045     {
00046     _route_table = init_route_table;
00047     _peer_handler = ph;
00048     _genid = genid;
00049     _is_ready = true;
00050     _has_queued_data = false;
00051     _waiting_for_get = false;
00052     TimerList::system_gettimeofday(&_wakeup_sent);
00053     }
00054     PeerTableInfo(const PeerTableInfo& other) {
00055     _route_table = other._route_table;
00056     _peer_handler = other._peer_handler;
00057     _genid = other._genid;
00058     _is_ready = other._is_ready;
00059     _has_queued_data = other._has_queued_data;
00060     _peer_number = other._peer_number;
00061     if (_has_queued_data) {
00062         _posn = other._posn;
00063     }
00064     _waiting_for_get = other._waiting_for_get;
00065     _wakeup_sent = other._wakeup_sent;
00066     }
00067     ~PeerTableInfo() {
00068     _wakeup_sent = TimeVal::ZERO();
00069     }
00070 
00071     BGPRouteTable<A> *route_table() const {
00072     return _route_table;
00073     }
00074     const PeerHandler* peer_handler() const {
00075     return _peer_handler;
00076     }
00077 
00078     void set_genid(uint32_t genid) {
00079     _genid = genid;
00080     }
00081 
00082     uint32_t genid() const {
00083     return _genid;
00084     }
00085 
00086     bool is_ready() const {return _is_ready;}
00087     void set_is_ready() {_is_ready = true;}
00088     void set_is_not_ready() {_is_ready = false;}
00089 
00090     bool has_queued_data() const {return _has_queued_data;}
00091     void set_has_queued_data(bool has_data) {_has_queued_data = has_data;}
00092     
00093     void set_queue_position(typename list<const RouteQueueEntry<A>*>::iterator posn) {
00094     _posn = posn;
00095     }
00096     typename list<const RouteQueueEntry<A>*>::iterator queue_position() const {
00097     return _posn;
00098     }
00099 
00100     // The following two functions are here to do a sanity check.  If
00101     // we sent a wakeup to a peer more than 20 minutes ago, and still
00102     // haven't received a get_next_message, then something has failed
00103     // badly, and we need to dump a core and diagnose what it is that
00104     // happened.
00105     void received_get() {
00106     if (_waiting_for_get)
00107         _waiting_for_get = false;
00108     }
00109     void wakeup_sent() {
00110     TimeVal now;
00111     TimerList::system_gettimeofday(&now);
00112     if (_waiting_for_get) {
00113         if ((now.sec() - _wakeup_sent.sec()) > 1200) {
00114         /* we sent a wakeup 20 minutes ago, and the peer still
00115            hasn't requested the data - something must have
00116            gone badly wrong */
00117         string s = "Peer seems to have permanently locked up\n";
00118         s += "Time now: " + now.str() + 
00119             ", time then: " + _wakeup_sent.str() + "\n";
00120         XLOG_FATAL("%s", s.c_str());
00121         }
00122     } else {
00123         XLOG_ASSERT(_wakeup_sent != TimeVal::ZERO());
00124         _wakeup_sent = now;
00125         _waiting_for_get = true;
00126     }
00127     }
00128     
00129     void peer_reset() { 
00130     _waiting_for_get = false;
00131    }
00132 
00133 private:
00134     BGPRouteTable<A> *_route_table; //the next table after
00135                                           //the fanout table
00136 
00137     const PeerHandler *_peer_handler;
00138 
00139     bool _has_queued_data; //there is data queued for this peer in the
00140                            //fanout table
00141 
00142     int _peer_number; //used to ensure consistency of ordering 
00143 
00144     uint32_t _genid;
00145 
00146     // this is set when downstream has requested a message be sent,
00147     // and we didn't have anything to send.  It indicates that a
00148     // message may be immediately sent downstream.
00149     bool _is_ready;
00150 
00151     typename list<const RouteQueueEntry<A>*>::iterator _posn; 
00152     /*the next item of data to send to this peer in the fanout table
00153       queue.  This only has meaning if _has_queued_data is true */
00154 
00155     bool _waiting_for_get;
00156     TimeVal _wakeup_sent;
00157 };
00158 
00159 #endif // __BGP_PEER_ROUTE_PAIR_HH__
 All Classes Namespaces Functions Variables Typedefs Enumerations