source: source/ariba/overlay/BaseOverlay.cpp@ 2390

Last change on this file since 2390 was 2390, checked in by mies, 16 years ago
File size: 24.5 KB
Line 
1// [Licence]
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// [Licence]
38
39#include "BaseOverlay.h"
40
41#include "ariba/utility/misc/OvlVis.h"
42using ariba::utility::OvlVis;
43
44namespace ariba {
45namespace overlay {
46
47use_logging_cpp(BaseOverlay);
48
49BaseOverlay::BaseOverlay( BaseCommunication& _basecomm, const NodeID& _nodeid )
50 : bc( _basecomm ), nodeId( _nodeid ), spovnetId( SpoVNetID::UNSPECIFIED), overlayInterface( NULL ),
51 initiatorLink( LinkID::UNSPECIFIED ), state( BaseOverlayStateInvalid ) {
52
53 logging_info("creating base overlay");
54
55 bc.registerMessageReceiver( this );
56 bc.registerEventListener( this );
57
58 ovl.visCreate( ovlId, nodeId, string(""), string("") );
59 ovl.visChangeNodeColor(ovlId, nodeId, OvlVis::NODE_COLORS_GREY);
60
61// if (Identifier(Configuration::instance().read<unsigned long>("BASE_nodeid")) ==
62// Identifier(Configuration::instance().read<unsigned long>("SOURCE"))) {
63// ovl.visChangeNodeIcon(ovlId, nodeId, OvlVis::ICON_ID_CAMERA);
64// } else if (Identifier(Configuration::instance().read<unsigned long>("BASE_nodeid")) ==
65// Identifier(Configuration::instance().read<unsigned long>("MR_A"))) {
66// ovl.visChangeNodeIcon(ovlId, nodeId, OvlVis::ICON_ID_CHARACTER_A);
67// } else if (Identifier(Configuration::instance().read<unsigned long>("BASE_nodeid")) ==
68// Identifier(Configuration::instance().read<unsigned long>("MR_W"))) {
69// ovl.visChangeNodeIcon(ovlId, nodeId, OvlVis::ICON_ID_CHARACTER_W);
70// }
71}
72
73BaseOverlay::~BaseOverlay() {
74
75 logging_info("deleting base overlay");
76
77 bc.unregisterMessageReceiver( this );
78 bc.unregisterEventListener( this );
79}
80
81void BaseOverlay::joinSpoVNet(const SpoVNetID& id, const EndpointDescriptor& bootstrapEp){
82
83 ovl.visShowNodeBubble ( ovlId, nodeId, "joining..." );
84 logging_info( "starting to join spovnet " << id.toString() << "...");
85
86 //
87 // contact the spovnet initiator and request
88 // to join. if the join is granted we will
89 // receive further information on the structure
90 // of the overlay that is used in the spovnet
91 //
92 // but first, we have to establish a link to the initiator...
93 //
94
95 spovnetId = id;
96 state = BaseOverlayStateJoinInitiated;
97
98 initiatorLink = bc.establishLink( bootstrapEp );
99}
100
101void BaseOverlay::leaveSpoVNet(){
102
103 logging_info( "leaving spovnet " << spovnetId );
104
105 // first, leave the overlay interface
106 overlayInterface->leaveOverlay();
107
108 if( state != BaseOverlayStateInitiator ){
109
110 // then, leave the spovnet baseoverlay
111 OverlayMsg overMsg( OverlayMsg::OverlayMessageTypeBye, nodeId );
112 bc.sendMessage( initiatorLink, &overMsg );
113
114 // drop the link and set to correct state
115 bc.dropLink( initiatorLink );
116 initiatorLink = LinkID::UNSPECIFIED;
117 }
118
119 state = BaseOverlayStateInvalid;
120 ovl.visShutdown( ovlId, nodeId, string("") );
121
122 // inform all registered services of the event
123 BOOST_FOREACH( ServiceInterface* i, listenerMux.getOneList() ){
124 i->onOverlayDestroy( spovnetId );
125 }
126}
127
128void BaseOverlay::createSpoVNet(const SpoVNetID& id, const OverlayParameterSet& param, const SecurityParameterSet& sec, const QoSParameterSet& qos){
129
130 //
131 // set the state that we are an initiator,
132 // this way incoming messages are handled correctly
133 //
134
135 logging_info("creating spovnet " + id.toString());
136
137 spovnetId = id;
138 state = BaseOverlayStateInitiator;
139
140 overlayInterface = OverlayFactory::create( *this, param, nodeId, this );
141 if( overlayInterface == NULL ){
142 logging_fatal( "overlay structure not supported" );
143 state = BaseOverlayStateInvalid;
144 return;
145 }
146
147 //
148 // create the overlay
149 // and bootstrap against ourselfs
150 //
151
152 overlayInterface->createOverlay();
153 overlayInterface->joinOverlay();
154
155 ovl.visChangeNodeIcon ( ovlId, nodeId, OvlVis::ICON_ID_CAMERA );
156 ovl.visChangeNodeColor( ovlId, nodeId, OvlVis::NODE_COLORS_GREEN);
157
158 // inform all registered services of the event
159 BOOST_FOREACH( ServiceInterface* i, listenerMux.getOneList() ){
160 i->onOverlayCreate( spovnetId );
161 }
162}
163
164const EndpointDescriptor& BaseOverlay::getEndpointDescriptor(const LinkID& link) const {
165
166 return bc.getEndpointDescriptor( link );
167}
168
169const EndpointDescriptor& BaseOverlay::getEndpointDescriptor(const NodeID& node) const {
170
171 if( node == nodeId || node == NodeID::UNSPECIFIED )
172 return bc.getEndpointDescriptor();
173
174 if( overlayInterface == NULL ){
175 logging_error( "overlay interface not set, cannot resolve endpoint" );
176 return EndpointDescriptor::UNSPECIFIED;
177 }
178
179 // TODO: if this is not a onehop overlay the operation will go asynchronously
180 return overlayInterface->resolveNode( node );
181}
182
183const LinkID BaseOverlay::establishLink(const NodeID& node, const ServiceID& service){
184
185 // TODO: if this is not a onehop overlay the operation will go asynchronously
186 const EndpointDescriptor& endpoint = overlayInterface->resolveNode( node );
187 if( endpoint == EndpointDescriptor::UNSPECIFIED ){
188 logging_error( "could not resolve node to endpoint. unable to establish link" );
189 return LinkID::UNSPECIFIED;
190 }
191
192 logging_debug( "baseoverlay called to establish link between node " <<
193 node.toString() << " on endpoint " << endpoint.toString() <<
194 " for service " << service.toString() );
195
196 return establishLink( endpoint, service );
197}
198
199const LinkID BaseOverlay::establishLink(const EndpointDescriptor& ep, const ServiceID& service){
200
201 if( !listenerMux.contains( service ) ){
202 logging_error( "no registered listener on serviceid " << service.toString() );
203 return LinkID::UNSPECIFIED;
204 }
205
206 ServiceInterface* receiver = listenerMux.get( service );
207 const LinkID link = bc.establishLink( ep );
208
209 LinkItem item (link, NodeID::UNSPECIFIED, service, receiver);
210 linkMapping.insert( make_pair(link, item) );
211
212 return link;
213}
214
215void BaseOverlay::dropLink(const LinkID& link){
216
217 logging_debug( "baseoverlay dropping link " << link.toString() );
218 LinkMapping::iterator i = linkMapping.find( link );
219
220 if( i == linkMapping.end() ){
221 logging_warn( "can't drop link, mapping unknown " << link.toString() );
222 return;
223 }
224
225 linkMapping.erase( i );
226
227 LinkItem item = i->second;
228 bc.dropLink( link );
229
230 if( item.interface != NULL )
231 item.interface->onLinkDown( spovnetId, nodeId, item.node );
232}
233
234seqnum_t BaseOverlay::sendMessage(const Message* message, const LinkID& link ){
235
236 logging_debug( "baseoverlay is sending message on link " << link.toString() );
237
238 LinkMapping::iterator i = linkMapping.find( link );
239 if( i == linkMapping.end() ){
240 logging_error( "could not send message. link not found " << link.toString() );
241 return -1;
242 }
243
244 OverlayMsg overmsg( OverlayMsg::OverlayMessageTypeData, i->second.service, nodeId );
245 overmsg.encapsulate( const_cast<Message*>(message) );
246
247 return bc.sendMessage( link, &overmsg );
248}
249
250seqnum_t BaseOverlay::sendMessage(const Message* message, const NodeID& node, const ServiceID& service){
251
252 LinkID link = LinkID::UNSPECIFIED;
253
254 LinkMapping::iterator i = linkMapping.begin();
255 LinkMapping::iterator iend = linkMapping.end();
256
257 for( ; i != iend; i++ ){
258 if( i->second.node == node && i->second.service == service ){
259 link = i->second.link;
260 break;
261 }
262 }
263
264 if( link == LinkID::UNSPECIFIED ){
265 logging_error( "no link could be found to send message to node " <<
266 node.toString() << " for service " << service.toString() );
267 return -1;
268 }
269
270 return sendMessage( message, link );
271}
272
273bool BaseOverlay::bind(ServiceInterface* service, const ServiceID& sid) {
274
275 logging_debug( "binding service on serviceid " << sid.toString() );
276
277 if( listenerMux.contains( sid ) ){
278 logging_error( "some service already registered for service id " << sid.toString() );
279 return false;
280 }
281
282 listenerMux.registerItem( service, sid );
283 return true;
284}
285
286bool BaseOverlay::unbind(ServiceInterface* service, const ServiceID& sid){
287
288 logging_debug( "unbinding service on serviceid " << sid.toString() );
289
290 if( !listenerMux.contains( sid ) ){
291 logging_warn( "cannot unbind service. no service registered on service id " << sid.toString() );
292 return false;
293 }
294
295 listenerMux.unregisterItem( service );
296 return true;
297}
298
299void BaseOverlay::onLinkUp(const LinkID& id, const NetworkLocator* local, const NetworkLocator* remote){
300
301 logging_debug( "base overlay received linkup event " + id.toString() );
302 // TODO: updateOvlVis( getNodeID(id) );
303
304 //
305 // if we get up a link while we are in the
306 // join phase and this is the link that
307 // we have initiated towards the spovnet owner
308 // continue the join process by sending
309 // a join request message through the link
310 //
311
312 if( state == BaseOverlayStateJoinInitiated && id == initiatorLink){
313
314 logging_info( "join has been initiated by me and the link is now up. " <<
315 "sending out join request for spovnet " <<
316 spovnetId.toString() );
317
318 OverlayMsg overMsg( OverlayMsg::OverlayMessageTypeJoinRequest, nodeId );
319 JoinRequest joinmsg( spovnetId, nodeId );
320 overMsg.encapsulate( &joinmsg );
321
322 state = BaseOverlayStateJoinInitiated; // state remains in JoinInitiated
323 bc.sendMessage( id, &overMsg );
324
325 return;
326
327 } // if( state == BaseOverlayStateJoinInitiated && id == initiatorLink)
328
329 //
330 // otherwise this is a link initiated by a service
331 // then we exchange update messages to exchange the
332 // service id and node id for the link. in this case
333 // we should have a link mapping for this link. if
334 // we have no link mapping this link was initiated by
335 // the remote side.
336 //
337
338 LinkMapping::iterator i = linkMapping.find( id );
339
340 if( i == linkMapping.end() ){
341
342 LinkItem item (id, NodeID::UNSPECIFIED, ServiceID::UNSPECIFIED, NULL );
343 linkMapping.insert( make_pair(id, item) );
344
345 } else {
346
347 logging_debug( "sending out OverlayMessageTypeUpdate" <<
348 " for service " << i->second.service.toString() <<
349 " with local node id " << nodeId.toString() <<
350 " on link " << id.toString() );
351
352 OverlayMsg overMsg( OverlayMsg::OverlayMessageTypeUpdate, i->second.service, nodeId );
353 bc.sendMessage( id, &overMsg );
354
355 } // if( i == linkMapping.end() )
356
357 // the link is only valid for the service when we receive
358 // the OverlayMessageTypeUpdate from the remote node and
359 // have the nodeid and serviceid for the link!
360}
361
362void BaseOverlay::onLinkDown(const LinkID& id, const NetworkLocator* local, const NetworkLocator* remote){
363
364 logging_debug( "link went down " << id.toString() );
365
366 //
367 // tell the service that the link went
368 // down and remove the mapping
369 //
370
371 LinkMapping::iterator i = linkMapping.find( id );
372 if( i == linkMapping.end() ) {
373 // this can also be one of the baseoverlay links that
374 // no mapping is stored for. therefore we issue no warning
375 return;
376 }
377
378 if( i->second.interface != NULL )
379 i->second.interface->onLinkDown( id, nodeId, i->second.node );
380
381 linkMapping.erase( i );
382}
383
384void BaseOverlay::onLinkChanged(const LinkID& id, const NetworkLocator* oldlocal, const NetworkLocator* newlocal, const NetworkLocator* oldremote, const NetworkLocator* newremote){
385
386 logging_debug( "link changed " << id.toString() );
387
388 //
389 // tell the service that the link changed
390 //
391
392 LinkMapping::iterator i = linkMapping.find( id );
393 if( i == linkMapping.end() ) return;
394
395 if( i->second.interface != NULL )
396 i->second.interface->onLinkChanged( id, nodeId, i->second.node );
397}
398
399void BaseOverlay::onLinkFail(const LinkID& id, const NetworkLocator* local, const NetworkLocator* remote){
400
401 logging_debug( "link failed " << id.toString() );
402
403 //
404 // tell the service that the link failed
405 //
406
407 LinkMapping::iterator i = linkMapping.find( id );
408 if( i == linkMapping.end() ) return;
409
410 if( i->second.interface != NULL )
411 i->second.interface->onLinkFail( id, nodeId, i->second.node );
412}
413
414void BaseOverlay::onLinkQoSChanged(const LinkID& id, const NetworkLocator* local, const NetworkLocator* remote, const QoSParameterSet& qos) {
415
416 logging_debug( "link qos changed " << id.toString() );
417
418 //
419 // tell the service that the link qos has changed
420 //
421
422 LinkMapping::iterator i = linkMapping.find( id );
423 if( i == linkMapping.end() ) return;
424
425 if( i->second.interface != NULL )
426 i->second.interface->onLinkQoSChanged( id, nodeId, i->second.node, qos );
427}
428
429bool BaseOverlay::receiveMessage(const Message* message,
430 const LinkID& link, const NodeID& /*the nodeid is invalid in this case! removed var to prevent errors*/ ){
431
432 OverlayMsg* overlayMsg = ((Message*)message)->decapsulate<OverlayMsg>();
433 if( overlayMsg == NULL ) return false;
434
435 //
436 // handle user date that we forward to the
437 // appropriate service using the service id
438 // in the message. as we don't know the class
439 // of message that the service handles, we
440 // forward it as a pure Message*
441 //
442
443 if( overlayMsg->isType(OverlayMsg::OverlayMessageTypeData) ) {
444
445 logging_debug( "baseoverlay received message of type OverlayMessageTypeData" );
446
447 const ServiceID& service = overlayMsg->getService();
448 ServiceInterface* serviceListener = listenerMux.get( service );
449
450 logging_debug( "received data for service " << service.toString() );
451
452 if( serviceListener != NULL )
453 serviceListener->receiveMessage( overlayMsg, link, overlayMsg->getSourceNode() );
454
455 return true;
456
457 } // if( overlayMsg->isType(OverlayMsg::OverlayMessageTypeData) )
458
459 //
460 // handle spovnet instance join requests
461 //
462
463 else if( overlayMsg->isType(OverlayMsg::OverlayMessageTypeJoinRequest) &&
464 state == BaseOverlayStateInitiator){
465
466 logging_debug( "baseoverlay received message of type OverlayMessageTypeJoinRequest" );
467
468 JoinRequest* joinReq = overlayMsg->decapsulate<JoinRequest>();
469 logging_info( "received join request for spovnet " <<
470 joinReq->getSpoVNetID().toString() );
471
472 //
473 // make sure that the node actually wants to join
474 // the correct spovnet id that we administrate
475 //
476
477 if( joinReq->getSpoVNetID() != spovnetId ){
478 logging_error( "received join request for spovnet we don't handle " <<
479 joinReq->getSpoVNetID().toString() );
480 return false;
481 }
482
483 //
484 // only if all services allow the node to join it is allowed
485 // using the isJoinAllowed interface security policies can be
486 // implemented by higher layer services
487 //
488
489 bool allow = true;
490
491 BOOST_FOREACH( ServiceInterface* i, listenerMux.getOneList() ){
492 allow &= i->isJoinAllowed( overlayMsg->getSourceNode(), spovnetId );
493 }
494
495 logging_info( "sending back join reply for spovnet " <<
496 spovnetId.toString() << " to node " <<
497 overlayMsg->getSourceNode().toString() <<
498 ". result: " << (allow ? "allowed" : "denied") );
499
500 joiningNodes.push_back( overlayMsg->getSourceNode() );
501
502 //
503 // send back our spovnetid, default overlay parameters,
504 // join allow result, and ourself as the endpoint
505 // to bootstrap the overlay against
506 //
507
508 OverlayMsg retmsg( OverlayMsg::OverlayMessageTypeJoinReply, nodeId );
509 JoinReply replyMsg( spovnetId, OverlayParameterSet::DEFAULT,
510 allow, getEndpointDescriptor() );
511
512 retmsg.encapsulate(&replyMsg);
513 bc.sendMessage( link, &retmsg );
514
515 return true;
516
517 } // else if( overlayMsg->isType(OverlayMsg::OverlayMessageTypeJoinRequest) && state == BaseOverlayStateInitiator)
518
519 //
520 // handle replies to spovnet instance join requests
521 //
522
523 else if( overlayMsg->isType(OverlayMsg::OverlayMessageTypeJoinReply) &&
524 state == BaseOverlayStateJoinInitiated){
525
526 logging_debug( "baseoverlay received message of type OverlayMessageTypeJoinReply" );
527
528 JoinReply* replyMsg = overlayMsg->decapsulate<JoinReply>();
529 logging_info( "received spovnet join reply" );
530
531 //
532 // make sure that we actually wanted to get
533 // into the spovnet whose id is in the message
534 //
535
536 if( replyMsg->getSpoVNetID() != spovnetId ){
537 logging_error( "received spovnet join reply for spovnet " <<
538 replyMsg->getSpoVNetID().toString() <<
539 " but we wanted to join spovnet " <<
540 spovnetId.toString() );
541
542 // state does not change here, maybe
543 // the reply does come in later
544 return false;
545 }
546
547 //
548 // if we did not get access to the spovnet
549 // notify of the failure and
550 // close the link to the initiator
551 //
552
553 if( ! replyMsg->getJoinAllowed() ){
554
555 logging_warn( "our join request has been denied" );
556
557 bc.dropLink( initiatorLink );
558 initiatorLink = LinkID::UNSPECIFIED;
559 state = BaseOverlayStateInvalid;
560
561 // inform all registered services of the event
562 BOOST_FOREACH( ServiceInterface* i, listenerMux.getOneList() ){
563 i->onJoinFail( spovnetId );
564 }
565
566 return true;
567 }
568
569 logging_info( "join request has been accepted for spovnet " << spovnetId.toString() );
570
571 //
572 // if we did get access to the spovnet
573 // we try to create the overlay structure
574 // as given in the reply message
575 //
576
577 overlayInterface = OverlayFactory::create( *this, replyMsg->getParam(), nodeId, this );
578
579 if( overlayInterface == NULL ){
580 logging_error( "overlay structure not supported" );
581
582 bc.dropLink( initiatorLink );
583 initiatorLink = LinkID::UNSPECIFIED;
584 state = BaseOverlayStateInvalid;
585
586 // inform all registered services of the event
587 BOOST_FOREACH( ServiceInterface* i, listenerMux.getOneList() ){
588 i->onJoinFail( spovnetId );
589 }
590
591 return true;
592 }
593
594 //
595 // now start the join process for the overlay.
596 // the join process for the spovnet baseoverlay
597 // is now complete. we use the endpoint for
598 // overlay structure bootstrapping that the
599 // initiator provided in his reply message
600 //
601
602 state = BaseOverlayStateCompleted;
603 ovl.visChangeNodeColor( ovlId, nodeId, OvlVis::NODE_COLORS_GREEN);
604
605 overlayInterface->createOverlay();
606
607 // inform all registered services of the event
608 BOOST_FOREACH( ServiceInterface* i, listenerMux.getOneList() ){
609 i->onOverlayCreate( spovnetId );
610 }
611
612 overlayInterface->joinOverlay( replyMsg->getBootstrapEndpoint() );
613
614 // inform all registered services of the event
615 BOOST_FOREACH( ServiceInterface* i, listenerMux.getOneList() ){
616 i->onJoinSuccess( spovnetId );
617 }
618
619 return true;
620
621 } // else if( overlayMsg->isType(OverlayMsg::OverlayMessageTypeJoinReply) && state == BaseOverlayStateJoinInitiated)
622
623
624 //
625 // handle update messages for link establishment
626 //
627
628 else if( overlayMsg->isType(OverlayMsg::OverlayMessageTypeUpdate) ){
629
630 logging_debug( "baseoverlay received message of type OverlayMessageTypeUpdate" );
631
632 const NodeID& sourcenode = overlayMsg->getSourceNode();
633 const ServiceID& service = overlayMsg->getService();
634
635 //
636 // we should have a linkmapping for the link, otherwise
637 // we ignore update messages
638 //
639
640 LinkMapping::iterator i = linkMapping.find( link );
641 if( i == linkMapping.end() ){
642 logging_warn( "received overlay update message for link " <<
643 link.toString() << " for which we have no mapping" );
644 return false;
645 }
646
647 //
648 // update our link mapping information for this link
649 //
650
651 bool changed = ( i->second.node != sourcenode ) || ( i->second.service != service );
652
653 i->second.node = sourcenode;
654 i->second.service = service;
655
656 //
657 // if our link information changed, we send out an update, too
658 //
659
660 if( changed ){
661 OverlayMsg overMsg( OverlayMsg::OverlayMessageTypeUpdate, i->second.service, nodeId );
662 bc.sendMessage( link, &overMsg );
663 }
664
665 //
666 // set the correct listener service for the linkitem
667 // now we can tell the registered service of the linkup event
668 //
669
670 if( !listenerMux.contains( service ) ){
671 logging_warn( "linkup event for service that has not been registered" );
672 return false;
673 }
674
675 ServiceInterface* iface = listenerMux.get( service );
676 if( iface == NULL ){
677 logging_warn( "linkup event for service that has been registered with a NULL interface" );
678 return true;
679 }
680
681 i->second.interface = iface;
682 iface->onLinkUp( link, nodeId, sourcenode );
683
684 return true ;
685
686 } // else if( overlayMsg->isType(OverlayMsg::OverlayMessageTypeUpdate) )
687
688 //
689 // bye messages to say goodbye
690 //
691
692 else if( overlayMsg->isType(OverlayMsg::OverlayMessageTypeBye)){
693
694 logging_debug( "baseoverlay received message of type OverlayMessageTypeBye" );
695
696 logging_debug( "received bye message from " <<
697 overlayMsg->getSourceNode().toString() );
698
699 //
700 // if we are the initiator and receive a bye from a node
701 // the node just left. if we are a node and receive a bye
702 // from the initiator, we have to close, too.
703 //
704
705 if( overlayMsg->getSourceNode() == spovnetInitiator ){
706
707 bc.dropLink( initiatorLink );
708 initiatorLink = LinkID::UNSPECIFIED;
709 state = BaseOverlayStateInvalid;
710
711 logging_fatal( "initiator ended spovnet" );
712
713 // inform all registered services of the event
714 BOOST_FOREACH( ServiceInterface* i, listenerMux.getOneList() ){
715 i->onOverlayDestroy( spovnetId );
716 }
717
718 } else {
719
720 // a node that said goodbye and we are the initiator
721 // don't have to do much here, as the node also
722 // will go out of the overlay structure
723 logging_info( "node left " << overlayMsg->getSourceNode() );
724
725 // inform all registered services of the event
726 BOOST_FOREACH( ServiceInterface* i, listenerMux.getOneList() ){
727 i->onNodeLeave( overlayMsg->getSourceNode(), spovnetId );
728 }
729 }
730
731 return true;
732
733 } // else if( overlayMsg->isType(OverlayMsg::OverlayMessageTypeBye))
734
735 //
736 // something wrong ...
737 //
738
739 else {
740
741 logging_error( "received message in invalid state! don't know " <<
742 "what to do with this message of type " <<
743 overlayMsg->getType() );
744 return false;
745
746 } // else
747
748 return false;
749}
750
751void BaseOverlay::broadcastMessage(Message* message, const ServiceID& service){
752
753 logging_debug( "broadcasting message to all known nodes " <<
754 "in the overlay from service " + service.toString() );
755
756 OverlayInterface::NodeList nodes = overlayInterface->getKnownNodes();
757
758 OverlayInterface::NodeList::iterator i = nodes.begin();
759 OverlayInterface::NodeList::iterator iend = nodes.end();
760
761 for( ; i != iend; i++ ){
762 if( *i == nodeId) continue; // don't send to ourselfs
763 sendMessage( message, *i, service ); // TODO: sollte auto links aufbauen fÃŒr sowas
764 }
765}
766
767void BaseOverlay::updateOvlVis( const NodeID& n ) {
768 NodeID node = n;
769/* void visShowNodeBubble (
770 NETWORK_ID network,
771 NodeID& node,
772 string label
773 );
774*/
775 using namespace std;
776
777 if (node == nodeId || node.isUnspecified()) return;
778
779 // min/max
780 if ( node < min || min.isUnspecified() ) min = node;
781 if ( node > max || max.isUnspecified() ) max = node;
782
783 // successor
784 if ( succ.isUnspecified() || (node > nodeId && (succ < nodeId || (node-nodeId) < (succ-nodeId))) ) {
785 if (!succ.isUnspecified() && node != succ)
786 ovl.visDisconnect(ovlId, nodeId, succ, string(""));
787 succ = node;
788 ovl.visConnect(ovlId, nodeId, succ, string(""));
789 }
790
791 // set successor (circle-wrap)
792 if (succ.isUnspecified() && !min.isUnspecified()) {
793 succ = min;
794 ovl.visConnect(ovlId, nodeId, succ, string(""));
795 }
796}
797
798const NodeID& BaseOverlay::getNodeID(const LinkID& lid) const {
799
800 if( lid == LinkID::UNSPECIFIED ) return nodeId;
801
802 LinkMapping::const_iterator i = linkMapping.find( lid );
803 if( i == linkMapping.end() ) return NodeID::UNSPECIFIED;
804 else return i->second.node;
805}
806
807void BaseOverlay::incomingRouteMessage(Message* msg){
808 // gets handled as normal data message
809 // TODO: passt das so?
810 receiveMessage( msg, LinkID::UNSPECIFIED, NodeID::UNSPECIFIED );
811}
812
813void BaseOverlay::onNodeJoin(const NodeID& node){
814
815 JoiningNodes::iterator i = std::find( joiningNodes.begin(), joiningNodes.end(), node );
816 if( i == joiningNodes.end() ) return;
817
818 logging_info( "node has successfully joined baseoverlay and overlay structure "
819 << node.toString() );
820
821 BOOST_FOREACH( ServiceInterface* i, listenerMux.getOneList() ){
822 i->onNodeJoin( node, spovnetId );
823 }
824
825 joiningNodes.erase( i );
826}
827
828}} // namespace ariba, overlay
Note: See TracBrowser for help on using the repository browser.