An Overlay-based
Virtual Network Substrate
SpoVNet

source: source/ariba/overlay/BaseOverlay.h @ 12060

Last change on this file since 12060 was 12060, checked in by hock@…, 9 years ago

Reintegrate branch: 20130111-hock-message_classes

improvements:

  • new message classes (reboost, zero-copy)
  • "fast path" for direct links (skip overlay layer)
  • link-properties accessible from the application
  • SystemQueue? can call boost::bind functions
  • protlib compatibility removed (32bit overhead saved in every message)
  • addressing2
  • AddressDiscovery? discoveres only addresses on which we're actually listening
  • ariba serialization usage reduced (sill used in OverlayMsg?)
  • Node::connect, easier and cleaner interface to start-up ariba from the application
  • ariba configs via JSON, XML, etc (boost::property_tree)
  • keep-alive overhead greatly reduced
  • (relayed) overlay links can actually be closed now
  • lost messages are detected in most cases
  • notification to the application when link is transformed into direct-link
  • overlay routing: send message to second best hop if it would be dropped otherwise
  • SequenceNumbers? (only mechanisms, so for: upward compatibility)
  • various small fixes


regressions:

  • bluetooth is not yet working again
  • bootstrap modules deactivated
  • liblog4xx is not working (use cout-logging)

This patch brings great performance and stability improvements at cost of backward compatibility.
Also bluetooth and the bootstrap modules have not been ported to the new interfaces, yet.

File size: 17.9 KB
Line 
1// [License]
2// The Ariba-Underlay Copyright
3//
4// Copyright (c) 2008-2009, Institute of Telematics, UniversitÀt Karlsruhe (TH)
5//
6// Institute of Telematics
7// UniversitÀt Karlsruhe (TH)
8// Zirkel 2, 76128 Karlsruhe
9// Germany
10//
11// Redistribution and use in source and binary forms, with or without
12// modification, are permitted provided that the following conditions are
13// met:
14//
15// 1. Redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer.
17// 2. Redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution.
20//
21// THIS SOFTWARE IS PROVIDED BY THE INSTITUTE OF TELEMATICS ``AS IS'' AND
22// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ARIBA PROJECT OR
25// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32//
33// The views and conclusions contained in the software and documentation
34// are those of the authors and should not be interpreted as representing
35// official policies, either expressed or implied, of the Institute of
36// Telematics.
37// [License]
38
39#ifndef BASEOVERLAY_H_
40#define BASEOVERLAY_H_
41
42#include <map>
43#include <iostream>
44#include <algorithm>
45#include <ctime>
46#include <list>
47#include <vector>
48#include <deque>
49#include <stdexcept>
50#include <boost/foreach.hpp>
51
52#ifdef ECLIPSE_PARSER
53    #define foreach(a, b) for(a : b)
54#else
55    #define foreach(a, b) BOOST_FOREACH(a, b)
56#endif
57
58#include "ariba/utility/messages.h"
59#include "ariba/utility/types.h"
60#include "ariba/utility/misc/Helper.h"
61#include "ariba/utility/misc/Demultiplexer.hpp"
62#include "ariba/utility/logging/Logging.h"
63#include "ariba/utility/system/Timer.h"
64
65#include "ariba/communication/EndpointDescriptor.h"
66#include "ariba/communication/BaseCommunication.h"
67#include "ariba/communication/CommunicationEvents.h"
68
69#include "ariba/overlay/modules/OverlayInterface.h"
70#include "ariba/overlay/modules/OverlayFactory.h"
71#include "ariba/overlay/modules/OverlayStructureEvents.h"
72#include "ariba/overlay/OverlayBootstrap.h"
73#include "ariba/overlay/SequenceNumber.h"
74
75// forward declarations
76namespace ariba {
77  class NodeListener;
78  class CommunicationListener;
79  class SideportListener;
80}
81
82using std::vector;
83using std::list;
84using std::map;
85using std::make_pair;
86using std::pair;
87using std::find;
88using std::deque;
89
90// ariba interface
91using ariba::NodeListener;
92using ariba::SideportListener;
93using ariba::CommunicationListener;
94
95// overlay
96using ariba::overlay::OverlayBootstrap;
97
98// communication
99using ariba::communication::EndpointDescriptor;
100using ariba::communication::BaseCommunication;
101using ariba::communication::CommunicationEvents;
102
103// transport
104//using ariba::transport::system_priority;
105
106// utilities
107using ariba::utility::NodeID;
108using ariba::utility::SpoVNetID;
109using ariba::utility::LinkID;
110using ariba::utility::Identifier;
111using ariba::utility::ServiceID;
112using ariba::utility::QoSParameterSet;
113using ariba::utility::SecurityParameterSet;
114using ariba::utility::Demultiplexer;
115using ariba::utility::MessageReceiver;
116using ariba::utility::seqnum_t;
117using ariba::utility::Timer;
118
119namespace ariba {
120namespace overlay {
121
122
123
124class message_not_sent: public std::runtime_error
125{
126public:
127    /** Takes a character string describing the error.  */
128    explicit message_not_sent(const string& __arg)  :
129        std::runtime_error(__arg)
130    {
131    }
132   
133    virtual ~message_not_sent() throw() {}
134};
135
136
137
138class LinkDescriptor;
139class OverlayMsg;
140class DHT;
141
142class BaseOverlay: public MessageReceiver,
143                public CommunicationEvents,
144                public OverlayStructureEvents,
145                protected Timer {
146
147//      friend class OneHop;  // DEPRECATED
148        friend class Chord;
149        friend class ariba::SideportListener;
150
151        use_logging_h( BaseOverlay );
152
153public:
154        /**
155         * Constructs an empty non-functional base overlay instance
156         */
157        BaseOverlay();
158
159        /**
160         * Destructs a base overlay instance
161         */
162        virtual ~BaseOverlay();
163
164        /**
165         * Starts the Base Overlay instance
166         */
167        void start(BaseCommunication* _basecomm, const NodeID& _nodeid);
168
169        /**
170         * Stops the Base Overlay instance
171         */
172        void stop();
173
174        /**
175         * Is the BaseOverlay instance started up yet
176         */
177        bool isStarted();
178
179        /// Tries to establish a direct or overlay link
180        const LinkID establishLink(     const EndpointDescriptor& ep,
181                const NodeID& node, const ServiceID& service );
182
183        /**
184         * Starts a link establishment procedure to the specfied node
185         * for the service with id service
186         *
187         * @param node Destination node id
188         * @param service Service to connect to
189         * @param linkid Link identifier to be used with this link
190         */
191        const LinkID establishLink(     const NodeID& remote,
192                const ServiceID& service = OverlayInterface::OVERLAY_SERVICE_ID );
193
194        /**
195         * Starts a link establishment procedure to the specified
196         * endpoint and to the specified service
197         */
198        const LinkID establishDirectLink( const EndpointDescriptor& endpoint,
199                const ServiceID& service = OverlayInterface::OVERLAY_SERVICE_ID );
200
201        /// drops a link
202        void dropLink( const LinkID& link );
203
204       
205       
206        /* +++++ Message sending +++++ */
207       
208       
209        /// sends a message over an existing link
210        const SequenceNumber& sendMessage(reboost::message_t message,
211                const LinkID& link,
212                uint8_t priority ) throw(message_not_sent);
213
214        /// sends a message to a node and a specific service
215    const SequenceNumber& sendMessage(reboost::message_t message,
216                const NodeID& remote,
217                uint8_t priority,
218                const ServiceID& service = OverlayInterface::OVERLAY_SERVICE_ID);
219
220
221    /**
222     *  send a message to the closest directly known node to an address
223     * 
224     *  @return NodeID of the (closest) destination node;
225     */
226        NodeID sendMessageCloserToNodeID(reboost::message_t message, const NodeID& address,
227                uint8_t priority, const ServiceID& service = OverlayInterface::OVERLAY_SERVICE_ID);
228       
229        /**
230         * Send out a message to all nodes that are known in the overlay structure.
231         * Depending on the structure of the overlay, this can be very different.
232         */
233        void broadcastMessage(reboost::message_t message, const ServiceID& service, uint8_t priority);
234
235       
236        /* +++++ [Message sending] +++++ */
237       
238       
239       
240        /**
241         * Returns the end-point descriptor of a link.
242         *
243         * @param link the link id of the requested end-point
244         * @return The end-point descriptor of the link's end-point
245         */
246        const EndpointDescriptor& getEndpointDescriptor(
247                const LinkID& link = LinkID::UNSPECIFIED) const;
248
249        /**
250         * Get a list of overlay neighbors.
251         *
252         * @return A list of overlay neighbors.
253         */
254        vector<NodeID> getOverlayNeighbors(bool deep = true) const;
255
256        /**
257         * Returns a end-endpoint descriptor of a overlay neighbor.
258         * If the node is not known -- an unspecified endpoint descriptor is
259         * returned.
260         *
261         * @param node The node identifer of a overlay neighbor.
262         * @return The end-point descriptor of the node or unspecified.
263         */
264        const EndpointDescriptor& getEndpointDescriptor(const NodeID& node) const;
265
266        // TODO: Doc
267        bool bind(CommunicationListener* listener, const ServiceID& sid);
268
269        // TODO: Doc
270        bool unbind(CommunicationListener* listener, const ServiceID& sid);
271
272        // TODO: Doc
273        bool bind(NodeListener* listener);
274
275        // TODO: Doc
276        bool unbind(NodeListener* listener);
277
278        // TODO: Doc
279        bool registerSidePort(SideportListener* _sideport);
280
281        // TODO: Doc
282        bool unregisterSidePort(SideportListener* _sideport);
283
284        /**
285         * Returns the own nodeID or the NodeID of the specified link
286         *
287         * @param lid The link identifier
288         * @return The NodeID of the link
289         */
290        const NodeID& getNodeID(const LinkID& lid = LinkID::UNSPECIFIED) const;
291
292        /**
293         * Return all Links for the specified remote nodeid, or all links when
294         * the node id given is set to unspecified
295         *
296         * @param nid The node id to request links for, or unspecified for all links
297         * @return a vector that contains all the link ids requested
298         */
299        vector<LinkID> getLinkIDs(const NodeID& nid = NodeID::UNSPECIFIED) const;
300
301        /**
302         * Join a existing sponaneous virtual network (spovnet).
303         *
304         * @param id A spovnet identifier
305         * @param boot A bootstrap node
306         */
307        void joinSpoVNet(const SpoVNetID& id, const EndpointDescriptor& boot = EndpointDescriptor::UNSPECIFIED());
308
309        /**
310         * Initiates a new spontaneous virtual network.
311         * This makes this BaseOverlay to the SpoVNet-Initiator.
312         *
313         * @param id The spovnet identifier
314         */
315        void createSpoVNet(const SpoVNetID& id, const OverlayParameterSet& param =
316                        OverlayParameterSet::DEFAULT, const SecurityParameterSet& sec =
317                        SecurityParameterSet::DEFAULT, const QoSParameterSet& qos =
318                        QoSParameterSet::DEFAULT);
319
320        /**
321         * Start the bootstrap modules
322         */
323        void startBootstrapModules(vector<pair<BootstrapManager::BootstrapType,string> > modules);
324
325        /**
326         * Stop the bootstrap modules
327         */
328        void stopBootstrapModules();
329
330        /**
331         * Let the node leave the SpoVNet.
332         */
333        void leaveSpoVNet();
334       
335       
336        /* link status */
337        bool isLinkDirect(const ariba::LinkID& lnk) const;
338        int getHopCount(const ariba::LinkID& lnk) const;
339
340    bool isLinkVital(const LinkDescriptor* link) const;
341    bool isLinkDirectVital(const LinkDescriptor* link) const;
342
343protected:
344
345    /**
346     * @see ariba::communication::CommunicationEvents.h
347     */
348    virtual bool onLinkRequest(const LinkID& id,
349            const addressing2::EndpointPtr local,
350            const addressing2::EndpointPtr remote);
351
352    /**
353     * @see ariba::communication::CommunicationEvents.h
354     */
355    virtual void onLinkUp(const LinkID& id,
356            const addressing2::EndpointPtr local, const addressing2::EndpointPtr remote);
357
358    /**
359     * @see ariba::communication::CommunicationEvents.h
360     */
361    virtual void onLinkDown(const LinkID& id,
362            const addressing2::EndpointPtr local, const addressing2::EndpointPtr remote);
363
364    /**
365     * @see ariba::communication::CommunicationEvents.h
366     */
367    virtual void onLinkChanged(const LinkID& id,
368        const addressing2::EndpointPtr oldlocal,  const addressing2::EndpointPtr newlocal,
369        const addressing2::EndpointPtr oldremote, const addressing2::EndpointPtr newremote);
370
371    /**
372     * @see ariba::communication::CommunicationEvents.h
373     *
374     * NOTE: Just calls onLinkDown (at the moment..)
375     */
376    virtual void onLinkFail(const LinkID& id,
377            const addressing2::EndpointPtr local, const addressing2::EndpointPtr remote);
378
379    /**
380     * @see ariba::communication::CommunicationEvents.h
381     */
382//    virtual void onLinkQoSChanged(const LinkID& id,
383//            const addressing2::EndpointPtr local, const addressing2::EndpointPtr remote,
384//            const QoSParameterSet& qos);
385
386       
387       
388       
389        /**
390         * Processes a received message from BaseCommunication
391         *
392         * In case of a message routed by the overlay the source identifies
393         * the node the message came from!
394         */
395        virtual bool receiveMessage( reboost::shared_buffer_t message,
396                const LinkID& link,
397                const NodeID&,
398                bool bypass_overlay );
399
400        /**
401         * This method is called, when a new node joined the network
402         *
403         * @see OverlayStructureEvents.h
404         */
405        virtual void onNodeJoin(const NodeID& node);
406
407        /**
408         * Timer Event method
409         */
410        virtual void eventFunction();
411
412        //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
413
414        std::string getLinkHTMLInfo();
415
416
417private:
418        /// NOTE: "id" is an Overlay-LinkID
419        void __onLinkEstablishmentFailed(const LinkID& id);
420       
421        /// called from typeLinkClose-handler
422    void __removeDroppedLink(const LinkID& link);
423       
424private:
425        /// is the base overlay started yet
426        bool started;
427
428        /// The state of the BaseOverlay
429        typedef enum _BaseOverlayState {
430                BaseOverlayStateInvalid = 0,
431                BaseOverlayStateCompleted = 1,
432        } BaseOverlayState;
433
434        BaseOverlayState state;         ///< Current Base-Overlay state
435        BaseCommunication* bc;          ///< reference to the base communication
436        NodeID nodeId;                  ///< the node id of this node
437        SpoVNetID spovnetId;            ///< the spovnet id of the currently joined overlay
438        vector<LinkID> bootstrapLinks;  ///< the link id of the link to the initiator node
439        NodeID spovnetInitiator;        ///< The initiator node
440
441        /// the service id communication listeners
442        Demultiplexer<CommunicationListener*, ServiceID> communicationListeners;
443        CommunicationListener* getListener( const ServiceID& id );
444
445        /// the node listeners
446        typedef vector<NodeListener*> NodeListenerVector;
447        NodeListenerVector nodeListeners;
448
449        /// the sideport listener
450        SideportListener* sideport;
451
452        /// the used overlay structure
453        OverlayInterface* overlayInterface;
454
455        /// Bootstrapper for our spovnet
456        OverlayBootstrap overlayBootstrap;
457
458        // message handlers --------------------------------------------------------
459
460        /// demultiplexes a incoming message with link descriptor
461        bool handleMessage( reboost::shared_buffer_t message, LinkDescriptor* ld,
462                const LinkID bcLink = LinkID::UNSPECIFIED );
463
464        // handle data and signalling messages
465        bool handleData( reboost::shared_buffer_t message, OverlayMsg* msg, LinkDescriptor* ld );
466        bool handleLostMessage( reboost::shared_buffer_t message, OverlayMsg* msg );
467        bool handleSignaling( OverlayMsg* msg, LinkDescriptor* ld );
468
469        // handle join request / reply messages
470        bool handleJoinRequest( reboost::shared_buffer_t message, const NodeID& source, const LinkID& bcLink );
471        bool handleJoinReply( reboost::shared_buffer_t message, const LinkID& bcLink );
472
473        // handle link messages
474        bool handleLinkRequest( OverlayMsg* msg, LinkDescriptor* ld );
475        bool handleLinkReply( OverlayMsg* msg, reboost::shared_buffer_t sub_message, LinkDescriptor* ld );
476        bool handleLinkUpdate( OverlayMsg* msg, LinkDescriptor* ld );
477        bool handleLinkDirect( OverlayMsg* msg, LinkDescriptor* ld );
478        bool handleLinkAlive( OverlayMsg* msg, LinkDescriptor* ld );
479   
480    // ping-pong over overlaypath/routing
481    bool handlePing( OverlayMsg* overlayMsg, LinkDescriptor* ld );
482    bool handlePong( OverlayMsg* overlayMsg, LinkDescriptor* ld );
483
484
485        // link state handling -----------------------------------------------------
486
487        /// link state information counter
488        int counter;
489
490        /// The link mapping of the node
491        vector<LinkDescriptor*> links;
492
493        /// erases a link descriptor
494        void eraseDescriptor(const LinkID& link, bool communication = false);
495
496        /// returns a link descriptor for the given id
497        LinkDescriptor* getDescriptor(const LinkID& link,
498                        bool communication = false);
499
500        /// returns a link descriptor for the given id
501        const LinkDescriptor* getDescriptor(const LinkID& link,
502                        bool communication = false) const;
503
504        /// returns a auto-link descriptor for the given node and service id
505        LinkDescriptor* getAutoDescriptor(const NodeID& node, const ServiceID& service);
506
507        /// adds a new link descriptor or uses an existing one
508        LinkDescriptor* addDescriptor(const LinkID& link = LinkID::UNSPECIFIED);
509
510        /// stabilizes link information
511        void stabilizeLinks();
512
513        /// print the currently known links
514        void showLinks();
515
516        /// compares two arbitrary links to the same node
517        int compare( const LinkID& lhs, const LinkID& rhs );
518
519        // relay route management --------------------------------------------------
520
521        /// relay route definitions
522        class relay_route {
523        public:
524                NodeID  node;
525                LinkID  link;
526                uint8_t hops;
527                time_t  used;
528        };
529        vector<relay_route> relay_routes;
530
531        /// stabilize relay information
532        void stabilizeRelays();
533
534        /// refreshes relay information
535        void refreshRelayInformation( const OverlayMsg* message, LinkDescriptor* ld );
536
537        /// returns a known relay link
538        LinkDescriptor* getRelayLinkTo( const NodeID& remote );
539
540        /// removes relay link information
541        void removeRelayLink( const LinkID& link );
542
543        /// removes relay node information
544        void removeRelayNode( const NodeID& link );
545
546        // internal message delivery -----------------------------------------------
547
548    // Convert OverlayMessage into new format and give it down to BaseCommunication
549    seqnum_t send_overlaymessage_down( OverlayMsg* message, const LinkID& bc_link, uint8_t priority );
550
551   
552        /// routes a message to its destination node
553        void route( OverlayMsg* message, const NodeID& last_hop = NodeID::UNSPECIFIED );
554       
555        /// sends a raw message to another node, delivers it to the base overlay class
556        /// may throw "message_not_sent"-exception
557        seqnum_t send( OverlayMsg* message,
558                   const NodeID& destination,
559                   uint8_t priority,
560                const NodeID& last_hop = NodeID::UNSPECIFIED )
561    throw(message_not_sent);
562
563        /// send a raw message using a link descriptor, delivers it to the base overlay class
564        seqnum_t send( OverlayMsg* message,
565                LinkDescriptor* ld,
566                uint8_t priority ) throw(message_not_sent);
567
568        /// send a message using a node id using overlay routing
569        /// sets necessary fields in the overlay message!
570        /// may throw "message_not_sent"-exception
571        seqnum_t send_node( OverlayMsg* message, const NodeID& remote, uint8_t priority,
572                const ServiceID& service = OverlayInterface::OVERLAY_SERVICE_ID) throw(message_not_sent);
573
574        /// send a message using a node id using overlay routing using a link
575        /// sets necessary fields in the overlay message!
576        void send_link( OverlayMsg* message,
577                const LinkID& link,
578                uint8_t priority ) throw(message_not_sent);
579
580       
581        /// sends a notification to a sender from whom we just dropped a message
582        void report_lost_message( const OverlayMsg* message );
583       
584        // misc --------------------------------------------------------------------
585
586        std::string debugInformation();
587
588        /**
589         * nodes with pending joines. TODO: should be cleaned every
590         * some seconds, add timestamps to each, and check on occasion
591         */
592        typedef vector<NodeID> JoiningNodes;
593        JoiningNodes joiningNodes;
594
595        void updateVisual();
596};
597
598}} // namespace ariba, overlay
599
600#endif /*BASEOVERLAY_H_*/
Note: See TracBrowser for help on using the repository browser.