An Overlay-based
Virtual Network Substrate
SpoVNet

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

Last change on this file since 6266 was 6266, checked in by mies, 14 years ago

added basic DHT functionality (untested)

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