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

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

Changed Data to Message conversion constructor in Message to explicit
Fixed some general bugs in Data: operator<<
Fixed bug in DHTMessage: allow unspecified key/values
Added local DHT message delivery
Adapted sources to work with gcc 4.4.1

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 DHT* localDHT;
509
510 void stabilizeDHT();
511 void dhtSend( OverlayMsg* msg, const NodeID& dest );
512
513 // misc --------------------------------------------------------------------
514
515 /**
516 * nodes with pending joines. TODO: should be cleaned every
517 * some seconds, add timestamps to each, and check on occasion
518 */
519 typedef vector<NodeID> JoiningNodes;
520 JoiningNodes joiningNodes;
521};
522
523}} // namespace ariba, overlay
524
525#endif /*BASEOVERLAY_H_*/
Note: See TracBrowser for help on using the repository browser.