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

Last change on this file since 12524 was 12438, checked in by hock@…, 11 years ago

new callbacks in ariba::NodeListener:

  • onOverlayConnected
  • onOverlayDisconnected
File size: 18.0 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 /// »true« if we have neighbours, »false« otherwise
429 bool connected;
430
431 /// The state of the BaseOverlay
432 typedef enum _BaseOverlayState {
433 BaseOverlayStateInvalid = 0,
434 BaseOverlayStateCompleted = 1,
435 } BaseOverlayState;
436
437 BaseOverlayState state; ///< Current Base-Overlay state
438 BaseCommunication* bc; ///< reference to the base communication
439 NodeID nodeId; ///< the node id of this node
440 SpoVNetID spovnetId; ///< the spovnet id of the currently joined overlay
441 vector<LinkID> bootstrapLinks; ///< the link id of the link to the initiator node
442 NodeID spovnetInitiator; ///< The initiator node
443
444 /// the service id communication listeners
445 Demultiplexer<CommunicationListener*, ServiceID> communicationListeners;
446 CommunicationListener* getListener( const ServiceID& id );
447
448 /// the node listeners
449 typedef vector<NodeListener*> NodeListenerVector;
450 NodeListenerVector nodeListeners;
451
452 /// the sideport listener
453 SideportListener* sideport;
454
455 /// the used overlay structure
456 OverlayInterface* overlayInterface;
457
458 /// Bootstrapper for our spovnet
459 OverlayBootstrap overlayBootstrap;
460
461 // message handlers --------------------------------------------------------
462
463 /// demultiplexes a incoming message with link descriptor
464 bool handleMessage( reboost::shared_buffer_t message, LinkDescriptor* ld,
465 const LinkID bcLink = LinkID::UNSPECIFIED );
466
467 // handle data and signalling messages
468 bool handleData( reboost::shared_buffer_t message, OverlayMsg* msg, LinkDescriptor* ld );
469 bool handleLostMessage( reboost::shared_buffer_t message, OverlayMsg* msg );
470 bool handleSignaling( OverlayMsg* msg, LinkDescriptor* ld );
471
472 // handle join request / reply messages
473 bool handleJoinRequest( reboost::shared_buffer_t message, const NodeID& source, const LinkID& bcLink );
474 bool handleJoinReply( reboost::shared_buffer_t message, const LinkID& bcLink );
475
476 // handle link messages
477 bool handleLinkRequest( OverlayMsg* msg, LinkDescriptor* ld );
478 bool handleLinkReply( OverlayMsg* msg, reboost::shared_buffer_t sub_message, LinkDescriptor* ld );
479 bool handleLinkUpdate( OverlayMsg* msg, LinkDescriptor* ld );
480 bool handleLinkDirect( OverlayMsg* msg, LinkDescriptor* ld );
481 bool handleLinkAlive( OverlayMsg* msg, LinkDescriptor* ld );
482
483 // ping-pong over overlaypath/routing
484 bool handlePing( OverlayMsg* overlayMsg, LinkDescriptor* ld );
485 bool handlePong( OverlayMsg* overlayMsg, LinkDescriptor* ld );
486
487
488 // link state handling -----------------------------------------------------
489
490 /// link state information counter
491 int counter;
492
493 /// The link mapping of the node
494 vector<LinkDescriptor*> links;
495
496 /// erases a link descriptor
497 void eraseDescriptor(const LinkID& link, bool communication = false);
498
499 /// returns a link descriptor for the given id
500 LinkDescriptor* getDescriptor(const LinkID& link,
501 bool communication = false);
502
503 /// returns a link descriptor for the given id
504 const LinkDescriptor* getDescriptor(const LinkID& link,
505 bool communication = false) const;
506
507 /// returns a auto-link descriptor for the given node and service id
508 LinkDescriptor* getAutoDescriptor(const NodeID& node, const ServiceID& service);
509
510 /// adds a new link descriptor or uses an existing one
511 LinkDescriptor* addDescriptor(const LinkID& link = LinkID::UNSPECIFIED);
512
513 /// stabilizes link information
514 void stabilizeLinks();
515
516 /// print the currently known links
517 void showLinks();
518
519 /// compares two arbitrary links to the same node
520 int compare( const LinkID& lhs, const LinkID& rhs );
521
522 // relay route management --------------------------------------------------
523
524 /// relay route definitions
525 class relay_route {
526 public:
527 NodeID node;
528 LinkID link;
529 uint8_t hops;
530 time_t used;
531 };
532 vector<relay_route> relay_routes;
533
534 /// stabilize relay information
535 void stabilizeRelays();
536
537 /// refreshes relay information
538 void refreshRelayInformation( const OverlayMsg* message, LinkDescriptor* ld );
539
540 /// returns a known relay link
541 LinkDescriptor* getRelayLinkTo( const NodeID& remote );
542
543 /// removes relay link information
544 void removeRelayLink( const LinkID& link );
545
546 /// removes relay node information
547 void removeRelayNode( const NodeID& link );
548
549 // internal message delivery -----------------------------------------------
550
551 // Convert OverlayMessage into new format and give it down to BaseCommunication
552 seqnum_t send_overlaymessage_down( OverlayMsg* message, const LinkID& bc_link, uint8_t priority );
553
554
555 /// routes a message to its destination node
556 void route( OverlayMsg* message, const NodeID& last_hop = NodeID::UNSPECIFIED );
557
558 /// sends a raw message to another node, delivers it to the base overlay class
559 /// may throw "message_not_sent"-exception
560 seqnum_t send( OverlayMsg* message,
561 const NodeID& destination,
562 uint8_t priority,
563 const NodeID& last_hop = NodeID::UNSPECIFIED )
564 throw(message_not_sent);
565
566 /// send a raw message using a link descriptor, delivers it to the base overlay class
567 seqnum_t send( OverlayMsg* message,
568 LinkDescriptor* ld,
569 uint8_t priority ) throw(message_not_sent);
570
571 /// send a message using a node id using overlay routing
572 /// sets necessary fields in the overlay message!
573 /// may throw "message_not_sent"-exception
574 seqnum_t send_node( OverlayMsg* message, const NodeID& remote, uint8_t priority,
575 const ServiceID& service = OverlayInterface::OVERLAY_SERVICE_ID) throw(message_not_sent);
576
577 /// send a message using a node id using overlay routing using a link
578 /// sets necessary fields in the overlay message!
579 void send_link( OverlayMsg* message,
580 const LinkID& link,
581 uint8_t priority ) throw(message_not_sent);
582
583
584 /// sends a notification to a sender from whom we just dropped a message
585 void report_lost_message( const OverlayMsg* message );
586
587 // misc --------------------------------------------------------------------
588
589 std::string debugInformation();
590
591 /**
592 * nodes with pending joines. TODO: should be cleaned every
593 * some seconds, add timestamps to each, and check on occasion
594 */
595 typedef vector<NodeID> JoiningNodes;
596 JoiningNodes joiningNodes;
597
598 void updateVisual();
599};
600
601}} // namespace ariba, overlay
602
603#endif /*BASEOVERLAY_H_*/
Note: See TracBrowser for help on using the repository browser.