source: source/ariba/overlay/BaseOverlay.h

Last change on this file was 12769, checked in by hock@…, 10 years ago

made message_not_sent exception accessible from applications (and services)

File size: 17.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#ifdef ECLIPSE_PARSER
52 #define foreach(a, b) for(a : b)
53#else
54 #define foreach(a, b) BOOST_FOREACH(a, b)
55#endif
56
57#include "ariba/utility/messages.h"
58#include "ariba/utility/types.h"
59#include "ariba/utility/misc/Helper.h"
60#include "ariba/utility/misc/Demultiplexer.hpp"
61#include "ariba/utility/logging/Logging.h"
62#include "ariba/utility/system/Timer.h"
63
64#include "ariba/communication/EndpointDescriptor.h"
65#include "ariba/communication/BaseCommunication.h"
66#include "ariba/communication/CommunicationEvents.h"
67
68#include "ariba/overlay/modules/OverlayInterface.h"
69#include "ariba/overlay/modules/OverlayFactory.h"
70#include "ariba/overlay/modules/OverlayStructureEvents.h"
71#include "ariba/overlay/OverlayBootstrap.h"
72#include "ariba/overlay/SequenceNumber.h"
73#include "ariba/overlay/PublicExceptions.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
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; // DEPRECATED
132 friend class Chord;
133 friend class ariba::SideportListener;
134
135 use_logging_h( BaseOverlay );
136
137public:
138 /**
139 * Constructs an empty non-functional base overlay instance
140 */
141 BaseOverlay();
142
143 /**
144 * Destructs a base overlay instance
145 */
146 virtual ~BaseOverlay();
147
148 /**
149 * Starts the Base Overlay instance
150 */
151 void start(BaseCommunication* _basecomm, const NodeID& _nodeid);
152
153 /**
154 * Stops the Base Overlay instance
155 */
156 void stop();
157
158 /**
159 * Is the BaseOverlay instance started up yet
160 */
161 bool isStarted();
162
163 /// Tries to establish a direct or overlay link
164 const LinkID establishLink( const EndpointDescriptor& ep,
165 const NodeID& node, const ServiceID& service );
166
167 /**
168 * Starts a link establishment procedure to the specfied node
169 * for the service with id service
170 *
171 * @param node Destination node id
172 * @param service Service to connect to
173 * @param linkid Link identifier to be used with this link
174 */
175 const LinkID establishLink( const NodeID& remote,
176 const ServiceID& service = OverlayInterface::OVERLAY_SERVICE_ID );
177
178 /**
179 * Starts a link establishment procedure to the specified
180 * endpoint and to the specified service
181 */
182 const LinkID establishDirectLink( const EndpointDescriptor& endpoint,
183 const ServiceID& service = OverlayInterface::OVERLAY_SERVICE_ID );
184
185 /// drops a link
186 void dropLink( const LinkID& link );
187
188
189
190 /* +++++ Message sending +++++ */
191
192
193 /// sends a message over an existing link
194 const SequenceNumber& sendMessage(reboost::message_t message,
195 const LinkID& link,
196 uint8_t priority ) throw(message_not_sent);
197
198 /// sends a message to a node and a specific service
199 const SequenceNumber& sendMessage(reboost::message_t message,
200 const NodeID& remote,
201 uint8_t priority,
202 const ServiceID& service = OverlayInterface::OVERLAY_SERVICE_ID);
203
204
205 /**
206 * send a message to the closest directly known node to an address
207 *
208 * @return NodeID of the (closest) destination node;
209 */
210 NodeID sendMessageCloserToNodeID(reboost::message_t message, const NodeID& address,
211 uint8_t priority, const ServiceID& service = OverlayInterface::OVERLAY_SERVICE_ID);
212
213 /**
214 * Send out a message to all nodes that are known in the overlay structure.
215 * Depending on the structure of the overlay, this can be very different.
216 */
217 void broadcastMessage(reboost::message_t message, const ServiceID& service, uint8_t priority);
218
219
220 /* +++++ [Message sending] +++++ */
221
222
223
224 /**
225 * Returns the end-point descriptor of a link.
226 *
227 * @param link the link id of the requested end-point
228 * @return The end-point descriptor of the link's end-point
229 */
230 const EndpointDescriptor& getEndpointDescriptor(
231 const LinkID& link = LinkID::UNSPECIFIED) const;
232
233 /**
234 * Get a list of overlay neighbors.
235 *
236 * @return A list of overlay neighbors.
237 */
238 vector<NodeID> getOverlayNeighbors(bool deep = true) const;
239
240 /**
241 * Returns a end-endpoint descriptor of a overlay neighbor.
242 * If the node is not known -- an unspecified endpoint descriptor is
243 * returned.
244 *
245 * @param node The node identifer of a overlay neighbor.
246 * @return The end-point descriptor of the node or unspecified.
247 */
248 const EndpointDescriptor& getEndpointDescriptor(const NodeID& node) const;
249
250 // TODO: Doc
251 bool bind(CommunicationListener* listener, const ServiceID& sid);
252
253 // TODO: Doc
254 bool unbind(CommunicationListener* listener, const ServiceID& sid);
255
256 // TODO: Doc
257 bool bind(NodeListener* listener);
258
259 // TODO: Doc
260 bool unbind(NodeListener* listener);
261
262 // TODO: Doc
263 bool registerSidePort(SideportListener* _sideport);
264
265 // TODO: Doc
266 bool unregisterSidePort(SideportListener* _sideport);
267
268 /**
269 * Returns the own nodeID or the NodeID of the specified link
270 *
271 * @param lid The link identifier
272 * @return The NodeID of the link
273 */
274 const NodeID& getNodeID(const LinkID& lid = LinkID::UNSPECIFIED) const;
275
276 /**
277 * Return all Links for the specified remote nodeid, or all links when
278 * the node id given is set to unspecified
279 *
280 * @param nid The node id to request links for, or unspecified for all links
281 * @return a vector that contains all the link ids requested
282 */
283 vector<LinkID> getLinkIDs(const NodeID& nid = NodeID::UNSPECIFIED) const;
284
285 /**
286 * Join a existing sponaneous virtual network (spovnet).
287 *
288 * @param id A spovnet identifier
289 * @param boot A bootstrap node
290 */
291 void joinSpoVNet(const SpoVNetID& id, const EndpointDescriptor& boot = EndpointDescriptor::UNSPECIFIED());
292
293 /**
294 * Initiates a new spontaneous virtual network.
295 * This makes this BaseOverlay to the SpoVNet-Initiator.
296 *
297 * @param id The spovnet identifier
298 */
299 void createSpoVNet(const SpoVNetID& id, const OverlayParameterSet& param =
300 OverlayParameterSet::DEFAULT, const SecurityParameterSet& sec =
301 SecurityParameterSet::DEFAULT, const QoSParameterSet& qos =
302 QoSParameterSet::DEFAULT);
303
304 /**
305 * Start the bootstrap modules
306 */
307 void startBootstrapModules(vector<pair<BootstrapManager::BootstrapType,string> > modules);
308
309 /**
310 * Stop the bootstrap modules
311 */
312 void stopBootstrapModules();
313
314 /**
315 * Let the node leave the SpoVNet.
316 */
317 void leaveSpoVNet();
318
319
320 /* link status */
321 bool isLinkDirect(const ariba::LinkID& lnk) const;
322 int getHopCount(const ariba::LinkID& lnk) const;
323
324 bool isLinkVital(const LinkDescriptor* link) const;
325 bool isLinkDirectVital(const LinkDescriptor* link) const;
326
327protected:
328
329 /**
330 * @see ariba::communication::CommunicationEvents.h
331 */
332 virtual bool onLinkRequest(const LinkID& id,
333 const addressing2::EndpointPtr local,
334 const addressing2::EndpointPtr remote);
335
336 /**
337 * @see ariba::communication::CommunicationEvents.h
338 */
339 virtual void onLinkUp(const LinkID& id,
340 const addressing2::EndpointPtr local, const addressing2::EndpointPtr remote);
341
342 /**
343 * @see ariba::communication::CommunicationEvents.h
344 */
345 virtual void onLinkDown(const LinkID& id,
346 const addressing2::EndpointPtr local, const addressing2::EndpointPtr remote);
347
348 /**
349 * @see ariba::communication::CommunicationEvents.h
350 */
351 virtual void onLinkChanged(const LinkID& id,
352 const addressing2::EndpointPtr oldlocal, const addressing2::EndpointPtr newlocal,
353 const addressing2::EndpointPtr oldremote, const addressing2::EndpointPtr newremote);
354
355 /**
356 * @see ariba::communication::CommunicationEvents.h
357 *
358 * NOTE: Just calls onLinkDown (at the moment..)
359 */
360 virtual void onLinkFail(const LinkID& id,
361 const addressing2::EndpointPtr local, const addressing2::EndpointPtr remote);
362
363 /**
364 * @see ariba::communication::CommunicationEvents.h
365 */
366// virtual void onLinkQoSChanged(const LinkID& id,
367// const addressing2::EndpointPtr local, const addressing2::EndpointPtr remote,
368// const QoSParameterSet& qos);
369
370
371
372
373 /**
374 * Processes a received message from BaseCommunication
375 *
376 * In case of a message routed by the overlay the source identifies
377 * the node the message came from!
378 */
379 virtual bool receiveMessage( reboost::shared_buffer_t message,
380 const LinkID& link,
381 const NodeID&,
382 bool bypass_overlay );
383
384 /**
385 * This method is called, when a new node joined the network
386 *
387 * @see OverlayStructureEvents.h
388 */
389 virtual void onNodeJoin(const NodeID& node);
390
391 /**
392 * Timer Event method
393 */
394 virtual void eventFunction();
395
396 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
397
398 std::string getLinkHTMLInfo();
399
400
401private:
402 /// NOTE: "id" is an Overlay-LinkID
403 void __onLinkEstablishmentFailed(const LinkID& id);
404
405 /// called from typeLinkClose-handler
406 void __removeDroppedLink(const LinkID& link);
407
408private:
409 /// is the base overlay started yet
410 bool started;
411
412 /// »true« if we have neighbours, »false« otherwise
413 bool connected;
414
415 /// The state of the BaseOverlay
416 typedef enum _BaseOverlayState {
417 BaseOverlayStateInvalid = 0,
418 BaseOverlayStateCompleted = 1,
419 } BaseOverlayState;
420
421 BaseOverlayState state; ///< Current Base-Overlay state
422 BaseCommunication* bc; ///< reference to the base communication
423 NodeID nodeId; ///< the node id of this node
424 SpoVNetID spovnetId; ///< the spovnet id of the currently joined overlay
425 vector<LinkID> bootstrapLinks; ///< the link id of the link to the initiator node
426 NodeID spovnetInitiator; ///< The initiator node
427
428 /// the service id communication listeners
429 Demultiplexer<CommunicationListener*, ServiceID> communicationListeners;
430 CommunicationListener* getListener( const ServiceID& id );
431
432 /// the node listeners
433 typedef vector<NodeListener*> NodeListenerVector;
434 NodeListenerVector nodeListeners;
435
436 /// the sideport listener
437 SideportListener* sideport;
438
439 /// the used overlay structure
440 OverlayInterface* overlayInterface;
441
442 /// Bootstrapper for our spovnet
443 OverlayBootstrap overlayBootstrap;
444
445 // message handlers --------------------------------------------------------
446
447 /// demultiplexes a incoming message with link descriptor
448 bool handleMessage( reboost::shared_buffer_t message, LinkDescriptor* ld,
449 const LinkID bcLink = LinkID::UNSPECIFIED );
450
451 // handle data and signalling messages
452 bool handleData( reboost::shared_buffer_t message, OverlayMsg* msg, LinkDescriptor* ld );
453 bool handleLostMessage( reboost::shared_buffer_t message, OverlayMsg* msg );
454 bool handleSignaling( OverlayMsg* msg, LinkDescriptor* ld );
455
456 // handle join request / reply messages
457 bool handleJoinRequest( reboost::shared_buffer_t message, const NodeID& source, const LinkID& bcLink );
458 bool handleJoinReply( reboost::shared_buffer_t message, const LinkID& bcLink );
459
460 // handle link messages
461 bool handleLinkRequest( OverlayMsg* msg, LinkDescriptor* ld );
462 bool handleLinkReply( OverlayMsg* msg, reboost::shared_buffer_t sub_message, LinkDescriptor* ld );
463 bool handleLinkUpdate( OverlayMsg* msg, LinkDescriptor* ld );
464 bool handleLinkDirect( OverlayMsg* msg, LinkDescriptor* ld );
465 bool handleLinkAlive( OverlayMsg* msg, LinkDescriptor* ld );
466
467 // ping-pong over overlaypath/routing
468 bool handlePing( OverlayMsg* overlayMsg, LinkDescriptor* ld );
469 bool handlePong( OverlayMsg* overlayMsg, LinkDescriptor* ld );
470
471
472 // link state handling -----------------------------------------------------
473
474 /// link state information counter
475 int counter;
476
477 /// The link mapping of the node
478 vector<LinkDescriptor*> links;
479
480 /// erases a link descriptor
481 void eraseDescriptor(const LinkID& link, bool communication = false);
482
483 /// returns a link descriptor for the given id
484 LinkDescriptor* getDescriptor(const LinkID& link,
485 bool communication = false);
486
487 /// returns a link descriptor for the given id
488 const LinkDescriptor* getDescriptor(const LinkID& link,
489 bool communication = false) const;
490
491 /// returns a auto-link descriptor for the given node and service id
492 LinkDescriptor* getAutoDescriptor(const NodeID& node, const ServiceID& service);
493
494 /// adds a new link descriptor or uses an existing one
495 LinkDescriptor* addDescriptor(const LinkID& link = LinkID::UNSPECIFIED);
496
497 /// stabilizes link information
498 void stabilizeLinks();
499
500 /// print the currently known links
501 void showLinks();
502
503 /// compares two arbitrary links to the same node
504 int compare( const LinkID& lhs, const LinkID& rhs );
505
506 // relay route management --------------------------------------------------
507
508 /// relay route definitions
509 class relay_route {
510 public:
511 NodeID node;
512 LinkID link;
513 uint8_t hops;
514 time_t used;
515 };
516 vector<relay_route> relay_routes;
517
518 /// stabilize relay information
519 void stabilizeRelays();
520
521 /// refreshes relay information
522 void refreshRelayInformation( const OverlayMsg* message, LinkDescriptor* ld );
523
524 /// returns a known relay link
525 LinkDescriptor* getRelayLinkTo( const NodeID& remote );
526
527 /// removes relay link information
528 void removeRelayLink( const LinkID& link );
529
530 /// removes relay node information
531 void removeRelayNode( const NodeID& link );
532
533 // internal message delivery -----------------------------------------------
534
535 // Convert OverlayMessage into new format and give it down to BaseCommunication
536 seqnum_t send_overlaymessage_down( OverlayMsg* message, const LinkID& bc_link, uint8_t priority );
537
538
539 /// routes a message to its destination node
540 void route( OverlayMsg* message, const NodeID& last_hop = NodeID::UNSPECIFIED );
541
542 /// sends a raw message to another node, delivers it to the base overlay class
543 /// may throw "message_not_sent"-exception
544 seqnum_t send( OverlayMsg* message,
545 const NodeID& destination,
546 uint8_t priority,
547 const NodeID& last_hop = NodeID::UNSPECIFIED )
548 throw(message_not_sent);
549
550 /// send a raw message using a link descriptor, delivers it to the base overlay class
551 seqnum_t send( OverlayMsg* message,
552 LinkDescriptor* ld,
553 uint8_t priority ) throw(message_not_sent);
554
555 /// send a message using a node id using overlay routing
556 /// sets necessary fields in the overlay message!
557 /// may throw "message_not_sent"-exception
558 seqnum_t send_node( OverlayMsg* message, const NodeID& remote, uint8_t priority,
559 const ServiceID& service = OverlayInterface::OVERLAY_SERVICE_ID) throw(message_not_sent);
560
561 /// send a message using a node id using overlay routing using a link
562 /// sets necessary fields in the overlay message!
563 void send_link( OverlayMsg* message,
564 const LinkID& link,
565 uint8_t priority ) throw(message_not_sent);
566
567
568 /// sends a notification to a sender from whom we just dropped a message
569 void report_lost_message( const OverlayMsg* message );
570
571 // misc --------------------------------------------------------------------
572
573 std::string debugInformation();
574
575 /**
576 * nodes with pending joines. TODO: should be cleaned every
577 * some seconds, add timestamps to each, and check on occasion
578 */
579 typedef vector<NodeID> JoiningNodes;
580 JoiningNodes joiningNodes;
581
582 void updateVisual();
583};
584
585}} // namespace ariba, overlay
586
587#endif /*BASEOVERLAY_H_*/
Note: See TracBrowser for help on using the repository browser.