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

Last change on this file since 2473 was 2473, checked in by Christoph Mayer, 15 years ago

-einige fixes im ablauf des neuen interface
-einige fehlende funktionalität implementiert

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 " << 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
286ServiceInterface* BaseOverlay::unbind(const ServiceID& sid){
287
288 logging_debug( "unbinding service from 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 NULL;
293 }
294
295 ServiceInterface* iface = listenerMux.get( sid );
296 listenerMux.unregisterItem( sid );
297
298 return NULL; //iface;
299}
300
301void BaseOverlay::onLinkUp(const LinkID& id, const NetworkLocator* local, const NetworkLocator* remote){
302
303 logging_debug( "base overlay received linkup event " + id.toString() );
304 // TODO: updateOvlVis( getNodeID(id) );
305
306 //
307 // if we get up a link while we are in the
308 // join phase and this is the link that
309 // we have initiated towards the spovnet owner
310 // continue the join process by sending
311 // a join request message through the link
312 //
313
314 if( state == BaseOverlayStateJoinInitiated && id == initiatorLink){
315
316 logging_info( "join has been initiated by me and the link is now up. " <<
317 "sending out join request for spovnet " <<
318 spovnetId.toString() );
319
320 OverlayMsg overMsg( OverlayMsg::OverlayMessageTypeJoinRequest, nodeId );
321 JoinRequest joinmsg( spovnetId, nodeId );
322 overMsg.encapsulate( &joinmsg );
323
324 state = BaseOverlayStateJoinInitiated; // state remains in JoinInitiated
325 bc.sendMessage( id, &overMsg );
326
327 return;
328
329 } // if( state == BaseOverlayStateJoinInitiated && id == initiatorLink)
330
331 //
332 // otherwise this is a link initiated by a service
333 // then we exchange update messages to exchange the
334 // service id and node id for the link. in this case
335 // we should have a link mapping for this link. if
336 // we have no link mapping this link was initiated by
337 // the remote side.
338 //
339
340 LinkMapping::iterator i = linkMapping.find( id );
341
342 if( i == linkMapping.end() ){
343
344 LinkItem item (id, NodeID::UNSPECIFIED, ServiceID::UNSPECIFIED, NULL );
345 linkMapping.insert( make_pair(id, item) );
346
347 } else {
348
349 logging_debug( "sending out OverlayMessageTypeUpdate" <<
350 " for service " << i->second.service.toString() <<
351 " with local node id " << nodeId.toString() <<
352 " on link " << id.toString() );
353
354 OverlayMsg overMsg( OverlayMsg::OverlayMessageTypeUpdate, i->second.service, nodeId );
355 bc.sendMessage( id, &overMsg );
356
357 } // if( i == linkMapping.end() )
358
359 // the link is only valid for the service when we receive
360 // the OverlayMessageTypeUpdate from the remote node and
361 // have the nodeid and serviceid for the link!
362}
363
364void BaseOverlay::onLinkDown(const LinkID& id, const NetworkLocator* local, const NetworkLocator* remote){
365
366 logging_debug( "link went down " << id.toString() );
367
368 //
369 // tell the service that the link went
370 // down and remove the mapping
371 //
372
373 LinkMapping::iterator i = linkMapping.find( id );
374 if( i == linkMapping.end() ) {
375 // this can also be one of the baseoverlay links that
376 // no mapping is stored for. therefore we issue no warning
377 return;
378 }
379
380 if( i->second.interface != NULL )
381 i->second.interface->onLinkDown( id, nodeId, i->second.node );
382
383 linkMapping.erase( i );
384}
385
386void BaseOverlay::onLinkChanged(const LinkID& id, const NetworkLocator* oldlocal, const NetworkLocator* newlocal, const NetworkLocator* oldremote, const NetworkLocator* newremote){
387
388 logging_debug( "link changed " << id.toString() );
389
390 //
391 // tell the service that the link changed
392 //
393
394 LinkMapping::iterator i = linkMapping.find( id );
395 if( i == linkMapping.end() ) return;
396
397 if( i->second.interface != NULL )
398 i->second.interface->onLinkChanged( id, nodeId, i->second.node );
399}
400
401void BaseOverlay::onLinkFail(const LinkID& id, const NetworkLocator* local, const NetworkLocator* remote){
402
403 logging_debug( "link failed " << id.toString() );
404
405 //
406 // tell the service that the link failed
407 //
408
409 LinkMapping::iterator i = linkMapping.find( id );
410 if( i == linkMapping.end() ) return;
411
412 if( i->second.interface != NULL )
413 i->second.interface->onLinkFail( id, nodeId, i->second.node );
414}
415
416void BaseOverlay::onLinkQoSChanged(const LinkID& id, const NetworkLocator* local, const NetworkLocator* remote, const QoSParameterSet& qos) {
417
418 logging_debug( "link qos changed " << id.toString() );
419
420 //
421 // tell the service that the link qos has changed
422 //
423
424 LinkMapping::iterator i = linkMapping.find( id );
425 if( i == linkMapping.end() ) return;
426
427 if( i->second.interface != NULL )
428 i->second.interface->onLinkQoSChanged( id, nodeId, i->second.node, qos );
429}
430
431bool BaseOverlay::receiveMessage(const Message* message,
432 const LinkID& link, const NodeID& /*the nodeid is invalid in this case! removed var to prevent errors*/ ){
433
434 OverlayMsg* overlayMsg = ((Message*)message)->decapsulate<OverlayMsg>();
435 if( overlayMsg == NULL ) return false;
436
437 //
438 // handle user date that we forward to the
439 // appropriate service using the service id
440 // in the message. as we don't know the class
441 // of message that the service handles, we
442 // forward it as a pure Message*
443 //
444
445 if( overlayMsg->isType(OverlayMsg::OverlayMessageTypeData) ) {
446
447 logging_debug( "baseoverlay received message of type OverlayMessageTypeData" );
448
449 const ServiceID& service = overlayMsg->getService();
450 ServiceInterface* serviceListener = listenerMux.get( service );
451
452 logging_debug( "received data for service " << service.toString() );
453
454 if( serviceListener != NULL )
455 serviceListener->receiveMessage( overlayMsg, link, overlayMsg->getSourceNode() );
456
457 return true;
458
459 } // if( overlayMsg->isType(OverlayMsg::OverlayMessageTypeData) )
460
461 //
462 // handle spovnet instance join requests
463 //
464
465 else if( overlayMsg->isType(OverlayMsg::OverlayMessageTypeJoinRequest) &&
466 state == BaseOverlayStateInitiator){
467
468 logging_debug( "baseoverlay received message of type OverlayMessageTypeJoinRequest" );
469
470 JoinRequest* joinReq = overlayMsg->decapsulate<JoinRequest>();
471 logging_info( "received join request for spovnet " <<
472 joinReq->getSpoVNetID().toString() );
473
474 //
475 // make sure that the node actually wants to join
476 // the correct spovnet id that we administrate
477 //
478
479 if( joinReq->getSpoVNetID() != spovnetId ){
480 logging_error( "received join request for spovnet we don't handle " <<
481 joinReq->getSpoVNetID().toString() );
482 return false;
483 }
484
485 //
486 // only if all services allow the node to join it is allowed
487 // using the isJoinAllowed interface security policies can be
488 // implemented by higher layer services
489 //
490
491 bool allow = true;
492
493 BOOST_FOREACH( ServiceInterface* i, listenerMux.getOneList() ){
494 allow &= i->isJoinAllowed( overlayMsg->getSourceNode(), spovnetId );
495 }
496
497 logging_info( "sending back join reply for spovnet " <<
498 spovnetId.toString() << " to node " <<
499 overlayMsg->getSourceNode().toString() <<
500 ". result: " << (allow ? "allowed" : "denied") );
501
502 joiningNodes.push_back( overlayMsg->getSourceNode() );
503
504 //
505 // send back our spovnetid, default overlay parameters,
506 // join allow result, and ourself as the endpoint
507 // to bootstrap the overlay against
508 //
509
510 OverlayMsg retmsg( OverlayMsg::OverlayMessageTypeJoinReply, nodeId );
511 JoinReply replyMsg( spovnetId, OverlayParameterSet::DEFAULT,
512 allow, getEndpointDescriptor() );
513
514 retmsg.encapsulate(&replyMsg);
515 bc.sendMessage( link, &retmsg );
516
517 return true;
518
519 } // else if( overlayMsg->isType(OverlayMsg::OverlayMessageTypeJoinRequest) && state == BaseOverlayStateInitiator)
520
521 //
522 // handle replies to spovnet instance join requests
523 //
524
525 else if( overlayMsg->isType(OverlayMsg::OverlayMessageTypeJoinReply) &&
526 state == BaseOverlayStateJoinInitiated){
527
528 logging_debug( "baseoverlay received message of type OverlayMessageTypeJoinReply" );
529
530 JoinReply* replyMsg = overlayMsg->decapsulate<JoinReply>();
531 logging_info( "received spovnet join reply" );
532
533 //
534 // make sure that we actually wanted to get
535 // into the spovnet whose id is in the message
536 //
537
538 if( replyMsg->getSpoVNetID() != spovnetId ){
539 logging_error( "received spovnet join reply for spovnet " <<
540 replyMsg->getSpoVNetID().toString() <<
541 " but we wanted to join spovnet " <<
542 spovnetId.toString() );
543
544 // state does not change here, maybe
545 // the reply does come in later
546 return false;
547 }
548
549 //
550 // if we did not get access to the spovnet
551 // notify of the failure and
552 // close the link to the initiator
553 //
554
555 if( ! replyMsg->getJoinAllowed() ){
556
557 logging_warn( "our join request has been denied" );
558
559 bc.dropLink( initiatorLink );
560 initiatorLink = LinkID::UNSPECIFIED;
561 state = BaseOverlayStateInvalid;
562
563 // inform all registered services of the event
564 BOOST_FOREACH( ServiceInterface* i, listenerMux.getOneList() ){
565 i->onJoinFail( spovnetId );
566 }
567
568 return true;
569 }
570
571 logging_info( "join request has been accepted for spovnet " << spovnetId.toString() );
572
573 //
574 // if we did get access to the spovnet
575 // we try to create the overlay structure
576 // as given in the reply message
577 //
578
579 overlayInterface = OverlayFactory::create( *this, replyMsg->getParam(), nodeId, this );
580
581 if( overlayInterface == NULL ){
582 logging_error( "overlay structure not supported" );
583
584 bc.dropLink( initiatorLink );
585 initiatorLink = LinkID::UNSPECIFIED;
586 state = BaseOverlayStateInvalid;
587
588 // inform all registered services of the event
589 BOOST_FOREACH( ServiceInterface* i, listenerMux.getOneList() ){
590 i->onJoinFail( spovnetId );
591 }
592
593 return true;
594 }
595
596 //
597 // now start the join process for the overlay.
598 // the join process for the spovnet baseoverlay
599 // is now complete. we use the endpoint for
600 // overlay structure bootstrapping that the
601 // initiator provided in his reply message
602 //
603
604 state = BaseOverlayStateCompleted;
605 ovl.visChangeNodeColor( ovlId, nodeId, OvlVis::NODE_COLORS_GREEN);
606
607 overlayInterface->createOverlay();
608
609 // inform all registered services of the event
610 BOOST_FOREACH( ServiceInterface* i, listenerMux.getOneList() ){
611 i->onOverlayCreate( spovnetId );
612 }
613
614 overlayInterface->joinOverlay( replyMsg->getBootstrapEndpoint() );
615
616 // inform all registered services of the event
617 BOOST_FOREACH( ServiceInterface* i, listenerMux.getOneList() ){
618 i->onJoinSuccess( spovnetId );
619 }
620
621 return true;
622
623 } // else if( overlayMsg->isType(OverlayMsg::OverlayMessageTypeJoinReply) && state == BaseOverlayStateJoinInitiated)
624
625
626 //
627 // handle update messages for link establishment
628 //
629
630 else if( overlayMsg->isType(OverlayMsg::OverlayMessageTypeUpdate) ){
631
632 logging_debug( "baseoverlay received message of type OverlayMessageTypeUpdate" );
633
634 const NodeID& sourcenode = overlayMsg->getSourceNode();
635 const ServiceID& service = overlayMsg->getService();
636
637 //
638 // we should have a linkmapping for the link, otherwise
639 // we ignore update messages
640 //
641
642 LinkMapping::iterator i = linkMapping.find( link );
643 if( i == linkMapping.end() ){
644 logging_warn( "received overlay update message for link " <<
645 link.toString() << " for which we have no mapping" );
646 return false;
647 }
648
649 //
650 // update our link mapping information for this link
651 //
652
653 bool changed = ( i->second.node != sourcenode ) || ( i->second.service != service );
654
655 i->second.node = sourcenode;
656 i->second.service = service;
657
658 //
659 // if our link information changed, we send out an update, too
660 //
661
662 if( changed ){
663 OverlayMsg overMsg( OverlayMsg::OverlayMessageTypeUpdate, i->second.service, nodeId );
664 bc.sendMessage( link, &overMsg );
665 }
666
667 //
668 // set the correct listener service for the linkitem
669 // now we can tell the registered service of the linkup event
670 //
671
672 if( !listenerMux.contains( service ) ){
673 logging_warn( "linkup event for service that has not been registered" );
674 return false;
675 }
676
677 ServiceInterface* iface = listenerMux.get( service );
678 if( iface == NULL ){
679 logging_warn( "linkup event for service that has been registered with a NULL interface" );
680 return true;
681 }
682
683 i->second.interface = iface;
684 iface->onLinkUp( link, nodeId, sourcenode );
685
686 return true ;
687
688 } // else if( overlayMsg->isType(OverlayMsg::OverlayMessageTypeUpdate) )
689
690 //
691 // bye messages to say goodbye
692 //
693
694 else if( overlayMsg->isType(OverlayMsg::OverlayMessageTypeBye)){
695
696 logging_debug( "baseoverlay received message of type OverlayMessageTypeBye" );
697
698 logging_debug( "received bye message from " <<
699 overlayMsg->getSourceNode().toString() );
700
701 //
702 // if we are the initiator and receive a bye from a node
703 // the node just left. if we are a node and receive a bye
704 // from the initiator, we have to close, too.
705 //
706
707 if( overlayMsg->getSourceNode() == spovnetInitiator ){
708
709 bc.dropLink( initiatorLink );
710 initiatorLink = LinkID::UNSPECIFIED;
711 state = BaseOverlayStateInvalid;
712
713 logging_fatal( "initiator ended spovnet" );
714
715 // inform all registered services of the event
716 BOOST_FOREACH( ServiceInterface* i, listenerMux.getOneList() ){
717 i->onOverlayDestroy( spovnetId );
718 }
719
720 } else {
721
722 // a node that said goodbye and we are the initiator
723 // don't have to do much here, as the node also
724 // will go out of the overlay structure
725 logging_info( "node left " << overlayMsg->getSourceNode() );
726
727 // inform all registered services of the event
728 BOOST_FOREACH( ServiceInterface* i, listenerMux.getOneList() ){
729 i->onNodeLeave( overlayMsg->getSourceNode(), spovnetId );
730 }
731 }
732
733 return true;
734
735 } // else if( overlayMsg->isType(OverlayMsg::OverlayMessageTypeBye))
736
737 //
738 // something wrong ...
739 //
740
741 else {
742
743 logging_error( "received message in invalid state! don't know " <<
744 "what to do with this message of type " <<
745 overlayMsg->getType() );
746 return false;
747
748 } // else
749
750 return false;
751}
752
753void BaseOverlay::broadcastMessage(Message* message, const ServiceID& service){
754
755 logging_debug( "broadcasting message to all known nodes " <<
756 "in the overlay from service " + service.toString() );
757
758 OverlayInterface::NodeList nodes = overlayInterface->getKnownNodes();
759
760 OverlayInterface::NodeList::iterator i = nodes.begin();
761 OverlayInterface::NodeList::iterator iend = nodes.end();
762
763 for( ; i != iend; i++ ){
764 if( *i == nodeId) continue; // don't send to ourselfs
765 sendMessage( message, *i, service ); // TODO: sollte auto links aufbauen fÃŒr sowas
766 }
767}
768
769void BaseOverlay::updateOvlVis( const NodeID& n ) {
770 NodeID node = n;
771/* void visShowNodeBubble (
772 NETWORK_ID network,
773 NodeID& node,
774 string label
775 );
776*/
777 using namespace std;
778
779 if (node == nodeId || node.isUnspecified()) return;
780
781 // min/max
782 if ( node < min || min.isUnspecified() ) min = node;
783 if ( node > max || max.isUnspecified() ) max = node;
784
785 // successor
786 if ( succ.isUnspecified() || (node > nodeId && (succ < nodeId || (node-nodeId) < (succ-nodeId))) ) {
787 if (!succ.isUnspecified() && node != succ)
788 ovl.visDisconnect(ovlId, nodeId, succ, string(""));
789 succ = node;
790 ovl.visConnect(ovlId, nodeId, succ, string(""));
791 }
792
793 // set successor (circle-wrap)
794 if (succ.isUnspecified() && !min.isUnspecified()) {
795 succ = min;
796 ovl.visConnect(ovlId, nodeId, succ, string(""));
797 }
798}
799
800const NodeID& BaseOverlay::getNodeID(const LinkID& lid) const {
801
802 if( lid == LinkID::UNSPECIFIED ) return nodeId;
803
804 LinkMapping::const_iterator i = linkMapping.find( lid );
805 if( i == linkMapping.end() ) return NodeID::UNSPECIFIED;
806 else return i->second.node;
807}
808
809void BaseOverlay::incomingRouteMessage(Message* msg){
810 // gets handled as normal data message
811 // TODO: passt das so?
812 receiveMessage( msg, LinkID::UNSPECIFIED, NodeID::UNSPECIFIED );
813}
814
815void BaseOverlay::onNodeJoin(const NodeID& node){
816
817 JoiningNodes::iterator i = std::find( joiningNodes.begin(), joiningNodes.end(), node );
818 if( i == joiningNodes.end() ) return;
819
820 logging_info( "node has successfully joined baseoverlay and overlay structure "
821 << node.toString() );
822
823 BOOST_FOREACH( ServiceInterface* i, listenerMux.getOneList() ){
824 i->onNodeJoin( node, spovnetId );
825 }
826
827 joiningNodes.erase( i );
828}
829
830}} // namespace ariba, overlay
Note: See TracBrowser for help on using the repository browser.