An Overlay-based
Virtual Network Substrate
SpoVNet

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

Last change on this file since 8606 was 7532, checked in by Christoph Mayer, 14 years ago

-von außen konfigurierbare bootstrap module, -periodicbroadcast crash fix

File size: 15.7 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 <boost/foreach.hpp>
50
51#include "ariba/utility/messages.h"
52#include "ariba/utility/types.h"
53#include "ariba/utility/misc/Helper.h"
54#include "ariba/utility/misc/Demultiplexer.hpp"
55#include "ariba/utility/logging/Logging.h"
56#include "ariba/utility/system/Timer.h"
57
58#include "ariba/communication/EndpointDescriptor.h"
59#include "ariba/communication/BaseCommunication.h"
60#include "ariba/communication/CommunicationEvents.h"
61
62#include "ariba/overlay/modules/OverlayInterface.h"
63#include "ariba/overlay/modules/OverlayFactory.h"
64#include "ariba/overlay/modules/OverlayStructureEvents.h"
65#include "ariba/overlay/OverlayBootstrap.h"
66
67// forward declarations
68namespace ariba {
69  class NodeListener;
70  class CommunicationListener;
71  class SideportListener;
72}
73
74using std::vector;
75using std::list;
76using std::cout;
77using std::map;
78using std::make_pair;
79using std::pair;
80using std::find;
81using std::deque;
82
83// ariba interface
84using ariba::NodeListener;
85using ariba::SideportListener;
86using ariba::CommunicationListener;
87
88// overlay
89using ariba::overlay::OverlayBootstrap;
90
91// communication
92using ariba::communication::EndpointDescriptor;
93using ariba::communication::BaseCommunication;
94using ariba::communication::CommunicationEvents;
95
96// utilities
97using ariba::utility::NodeID;
98using ariba::utility::SpoVNetID;
99using ariba::utility::LinkID;
100using ariba::utility::Identifier;
101using ariba::utility::ServiceID;
102using ariba::utility::QoSParameterSet;
103using ariba::utility::SecurityParameterSet;
104using ariba::utility::Demultiplexer;
105using ariba::utility::MessageReceiver;
106using ariba::utility::MessageSender;
107using ariba::utility::seqnum_t;
108using ariba::utility::Timer;
109
110namespace ariba {
111namespace overlay {
112
113using namespace ariba::addressing;
114
115class LinkDescriptor;
116class OverlayMsg;
117class DHT;
118
119class BaseOverlay: public MessageReceiver,
120                public CommunicationEvents,
121                public OverlayStructureEvents,
122                protected Timer {
123
124        friend class OneHop;
125        friend class Chord;
126        friend class ariba::SideportListener;
127
128        use_logging_h( BaseOverlay );
129
130public:
131
132        /**
133         * Constructs an empty non-functional base overlay instance
134         */
135        BaseOverlay();
136
137        /**
138         * Destructs a base overlay instance
139         */
140        virtual ~BaseOverlay();
141
142        /**
143         * Starts the Base Overlay instance
144         */
145        void start(BaseCommunication& _basecomm, const NodeID& _nodeid);
146
147        /**
148         * Stops the Base Overlay instance
149         */
150        void stop();
151
152        /**
153         * Is the BaseOverlay instance started up yet
154         */
155        bool isStarted();
156
157        /// Tries to establish a direct or overlay link
158        const LinkID establishLink(     const EndpointDescriptor& ep,
159                const NodeID& node, const ServiceID& service );
160
161        /**
162         * Starts a link establishment procedure to the specfied node
163         * for the service with id service
164         *
165         * @param node Destination node id
166         * @param service Service to connect to
167         * @param linkid Link identifier to be used with this link
168         */
169        const LinkID establishLink(     const NodeID& remote,
170                const ServiceID& service = OverlayInterface::OVERLAY_SERVICE_ID );
171
172        /**
173         * Starts a link establishment procedure to the specified
174         * endpoint and to the specified service
175         */
176        const LinkID establishDirectLink( const EndpointDescriptor& endpoint,
177                const ServiceID& service = OverlayInterface::OVERLAY_SERVICE_ID );
178
179        /// drops a link
180        void dropLink( const LinkID& link );
181
182        /// sends a message over an existing link
183        seqnum_t sendMessage(const Message* message, const LinkID& link );
184
185        /// sends a message to a node and a specific service
186        seqnum_t sendMessage(const Message* message, const NodeID& remote,
187                const ServiceID& service = OverlayInterface::OVERLAY_SERVICE_ID);
188
189        /**
190         * Send out a message to all nodes that are known in the overlay structure.
191         * Depending on the structure of the overlay, this can be very different.
192         */
193        void broadcastMessage(Message* message, const ServiceID& service);
194
195        /**
196         * Returns the end-point descriptor of a link.
197         *
198         * @param link the link id of the requested end-point
199         * @return The end-point descriptor of the link's end-point
200         */
201        const EndpointDescriptor& getEndpointDescriptor(
202                const LinkID& link = LinkID::UNSPECIFIED) const;
203
204        /**
205         * Get a list of overlay neighbors.
206         *
207         * @return A list of overlay neighbors.
208         */
209        vector<NodeID> getOverlayNeighbors(bool deep = true) const;
210
211        /**
212         * Returns a end-endpoint descriptor of a overlay neighbor.
213         * If the node is not known -- an unspecified endpoint descriptor is
214         * returned.
215         *
216         * @param node The node identifer of a overlay neighbor.
217         * @return The end-point descriptor of the node or unspecified.
218         */
219        const EndpointDescriptor& getEndpointDescriptor(const NodeID& node) const;
220
221        // TODO: Doc
222        bool bind(CommunicationListener* listener, const ServiceID& sid);
223
224        // TODO: Doc
225        bool unbind(CommunicationListener* listener, const ServiceID& sid);
226
227        // TODO: Doc
228        bool bind(NodeListener* listener);
229
230        // TODO: Doc
231        bool unbind(NodeListener* listener);
232
233        // TODO: Doc
234        bool registerSidePort(SideportListener* _sideport);
235
236        // TODO: Doc
237        bool unregisterSidePort(SideportListener* _sideport);
238
239        /**
240         * Returns the own nodeID or the NodeID of the specified link
241         *
242         * @param lid The link identifier
243         * @return The NodeID of the link
244         */
245        const NodeID& getNodeID(const LinkID& lid = LinkID::UNSPECIFIED) const;
246
247        /**
248         * Return all Links for the specified remote nodeid, or all links when
249         * the node id given is set to unspecified
250         *
251         * @param nid The node id to request links for, or unspecified for all links
252         * @return a vector that contains all the link ids requested
253         */
254        vector<LinkID> getLinkIDs(const NodeID& nid = NodeID::UNSPECIFIED) const;
255
256        /**
257         * Join a existing sponaneous virtual network (spovnet).
258         *
259         * @param id A spovnet identifier
260         * @param boot A bootstrap node
261         */
262        void joinSpoVNet(const SpoVNetID& id, const EndpointDescriptor& boot = EndpointDescriptor::UNSPECIFIED());
263
264        /**
265         * Initiates a new spontaneous virtual network.
266         * This makes this BaseOverlay to the SpoVNet-Initiator.
267         *
268         * @param id The spovnet identifier
269         */
270        void createSpoVNet(const SpoVNetID& id, const OverlayParameterSet& param =
271                        OverlayParameterSet::DEFAULT, const SecurityParameterSet& sec =
272                        SecurityParameterSet::DEFAULT, const QoSParameterSet& qos =
273                        QoSParameterSet::DEFAULT);
274
275        /**
276         * Start the bootstrap modules
277         */
278        void startBootstrapModules(vector<pair<BootstrapManager::BootstrapType,string> > modules);
279
280        /**
281         * Stop the bootstrap modules
282         */
283        void stopBootstrapModules();
284
285        /**
286         * Let the node leave the SpoVNet.
287         */
288        void leaveSpoVNet();
289
290        /// put a value to the DHT with a ttl given in seconds
291        void dhtPut( const Data& key, const Data& value, int ttl = 0, bool replace = false, bool no_local_refresh = false);
292
293        /// removes a key value pair from the DHT
294        void dhtRemove( const Data& key, const Data& value );
295
296        /// removes all data stored at the given key
297        void dhtRemove( const Data& key );
298
299        /// requests data stored using key
300        void dhtGet( const Data& key, const ServiceID& service );
301
302protected:
303        /**
304         * @see ariba::communication::CommunicationEvents.h
305         */
306        virtual void onLinkUp(const LinkID& id, const address_v* local,
307                const address_v* remote);
308
309        /**
310         * @see ariba::communication::CommunicationEvents.h
311         */
312        virtual void onLinkDown(const LinkID& id, const address_v* local,
313                const address_v* remote);
314
315        /**
316         * @see ariba::communication::CommunicationEvents.h
317         */
318        virtual void onLinkChanged(const LinkID& id,
319                const address_v* oldlocal, const address_v* newlocal,
320                const address_v* oldremote, const address_v* newremote);
321
322        /**
323         * @see ariba::communication::CommunicationEvents.h
324         */
325        virtual void onLinkFail(const LinkID& id, const address_v* local,
326                const address_v* remote);
327
328        /**
329         * @see ariba::communication::CommunicationEvents.h
330         */
331        virtual void onLinkQoSChanged(const LinkID& id,
332                const address_v* local, const address_v* remote,
333                const QoSParameterSet& qos);
334
335        /**
336         * @see ariba::communication::CommunicationEvents.h
337         */
338        virtual bool onLinkRequest(const LinkID& id, const address_v* local,
339                const address_v* remote);
340
341        /**
342         * Processes a received message from BaseCommunication
343         *
344         * In case of a message routed by the overlay the source identifies
345         * the node the message came from!
346         */
347        virtual bool receiveMessage( const Message* message, const LinkID& link,
348                const NodeID& );
349
350        /**
351         * This method is called, when a new node joined the network
352         *
353         * @see OverlayStructureEvents.h
354         */
355        virtual void onNodeJoin(const NodeID& node);
356
357        /**
358         * Timer Event method
359         */
360        virtual void eventFunction();
361
362        //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
363
364        std::string getLinkHTMLInfo();
365
366private:
367        /// is the base overlay started yet
368        bool started;
369
370        /// The state of the BaseOverlay
371        typedef enum _BaseOverlayState {
372                BaseOverlayStateInvalid = 0,
373                BaseOverlayStateCompleted = 1,
374        } BaseOverlayState;
375
376        BaseOverlayState state;         ///< Current Base-Overlay state
377        BaseCommunication* bc;          ///< reference to the base communication
378        NodeID nodeId;                  ///< the node id of this node
379        SpoVNetID spovnetId;            ///< the spovnet id of the currently joined overlay
380        vector<LinkID> bootstrapLinks;  ///< the link id of the link to the initiator node
381        NodeID spovnetInitiator;        ///< The initiator node
382
383        /// the service id communication listeners
384        Demultiplexer<CommunicationListener*, ServiceID> communicationListeners;
385        CommunicationListener* getListener( const ServiceID& id );
386
387        /// the node listeners
388        typedef vector<NodeListener*> NodeListenerVector;
389        NodeListenerVector nodeListeners;
390
391        /// the sideport listener
392        SideportListener* sideport;
393
394        /// the used overlay structure
395        OverlayInterface* overlayInterface;
396
397        /// Bootstrapper for our spovnet
398        OverlayBootstrap overlayBootstrap;
399
400        // message handlers --------------------------------------------------------
401
402        /// demultiplexes a incoming message with link descriptor
403        bool handleMessage( const Message* message, LinkDescriptor* ld,
404                const LinkID bcLink = LinkID::UNSPECIFIED );
405
406        // handle data and signalling messages
407        bool handleData( OverlayMsg* msg, LinkDescriptor* ld );
408        bool handleSignaling( OverlayMsg* msg, LinkDescriptor* ld );
409
410        // handle join request / reply messages
411        bool handleJoinRequest( OverlayMsg* msg, const LinkID& bcLink );
412        bool handleJoinReply( OverlayMsg* msg, const LinkID& bcLink );
413
414        // handle DHT messages
415        bool handleDHTMessage( OverlayMsg* msg );
416
417        // handle link messages
418        bool handleLinkRequest( OverlayMsg* msg, LinkDescriptor* ld );
419        bool handleLinkReply( OverlayMsg* msg, LinkDescriptor* ld );
420        bool handleLinkUpdate( OverlayMsg* msg, LinkDescriptor* ld );
421        bool handleLinkDirect( OverlayMsg* msg, LinkDescriptor* ld );
422        bool handleLinkAlive( OverlayMsg* msg, LinkDescriptor* ld );
423
424
425        // link state handling -----------------------------------------------------
426
427        /// link state information counter
428        int counter;
429
430        /// The link mapping of the node
431        vector<LinkDescriptor*> links;
432
433        /// erases a link descriptor
434        void eraseDescriptor(const LinkID& link, bool communication = false);
435
436        /// returns a link descriptor for the given id
437        LinkDescriptor* getDescriptor(const LinkID& link,
438                        bool communication = false);
439
440        /// returns a link descriptor for the given id
441        const LinkDescriptor* getDescriptor(const LinkID& link,
442                        bool communication = false) const;
443
444        /// returns a auto-link descriptor for the given node and service id
445        LinkDescriptor* getAutoDescriptor(const NodeID& node, const ServiceID& service);
446
447        /// adds a new link descriptor or uses an existing one
448        LinkDescriptor* addDescriptor(const LinkID& link = LinkID::UNSPECIFIED);
449
450        /// stabilizes link information
451        void stabilizeLinks();
452
453        /// print the currently known links
454        void showLinks();
455
456        /// compares two arbitrary links to the same node
457        int compare( const LinkID& lhs, const LinkID& rhs );
458
459        // relay route management --------------------------------------------------
460
461        /// relay route definitions
462        class relay_route {
463        public:
464                NodeID  node;
465                LinkID  link;
466                uint8_t hops;
467                time_t  used;
468        };
469        vector<relay_route> relay_routes;
470
471        /// stabilize relay information
472        void stabilizeRelays();
473
474        /// refreshes relay information
475        void refreshRelayInformation( const OverlayMsg* message, LinkDescriptor* ld );
476
477        /// returns a known relay link
478        LinkDescriptor* getRelayLinkTo( const NodeID& remote );
479
480        /// removes relay link information
481        void removeRelayLink( const LinkID& link );
482
483        /// removes relay node information
484        void removeRelayNode( const NodeID& link );
485
486        // internal message delivery -----------------------------------------------
487
488        /// routes a message to its destination node
489        void route( OverlayMsg* message );
490
491        /// sends a raw message to another node, delivers it to the base overlay class
492        seqnum_t send( OverlayMsg* message, const NodeID& destination );
493
494        /// send a raw message using a link descriptor, delivers it to the base overlay class
495        seqnum_t send( OverlayMsg* message, LinkDescriptor* ld,
496                bool ignore_down = false );
497
498        /// send a message using a node id using overlay routing
499        /// sets necessary fields in the overlay message!
500        seqnum_t send_node( OverlayMsg* message, const NodeID& remote,
501                const ServiceID& service = OverlayInterface::OVERLAY_SERVICE_ID);
502
503        /// send a message using a node id using overlay routing using a link
504        /// sets necessary fields in the overlay message!
505        seqnum_t send_link( OverlayMsg* message, const LinkID& link,
506                bool ignore_down = false );
507
508        // distributed hashtable handling ------------------------------------------
509
510        DHT* dht;
511        DHT* localDHT;
512        int republishCounter;
513
514        void initDHT();
515        void destroyDHT();
516        void stabilizeDHT();
517        void dhtSend( OverlayMsg* msg, const NodeID& dest );
518
519        // misc --------------------------------------------------------------------
520
521        std::string debugInformation();
522
523        /**
524         * nodes with pending joines. TODO: should be cleaned every
525         * some seconds, add timestamps to each, and check on occasion
526         */
527        typedef vector<NodeID> JoiningNodes;
528        JoiningNodes joiningNodes;
529
530        void updateVisual();
531};
532
533}} // namespace ariba, overlay
534
535#endif /*BASEOVERLAY_H_*/
Note: See TracBrowser for help on using the repository browser.