source: source/ariba/communication/BaseCommunication.cpp@ 2801

Last change on this file since 2801 was 2483, checked in by Christoph Mayer, 16 years ago

-autolinks impl. (funktioniert noch nicht komplett, macht aber im moment nichts schlechter)
-einige fixes im ablauf etc.

File size: 20.9 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 "BaseCommunication.h"
40
41#ifdef UNDERLAY_OMNET
42 #include "ariba/communication/modules/transport/omnet/AribaOmnetModule.h"
43 #include "ariba/communication/modules/network/omnet/OmnetNetworkProtocol.h"
44 #include "ariba/utility/system/StartupWrapper.h"
45
46 using ariba::communication::AribaOmnetModule;
47 using ariba::communication::OmnetNetworkProtocol;
48 using ariba::utility::StartupWrapper;
49#endif
50
51namespace ariba {
52namespace communication {
53
54use_logging_cpp(BaseCommunication);
55const BaseCommunication::LinkDescriptor BaseCommunication::LinkDescriptor::UNSPECIFIED;
56
57BaseCommunication::BaseCommunication(const NetworkLocator* _locallocator, const uint16_t _listenport)
58 : messageReceiver( NULL ), currentSeqnum( 0 ), listenport( _listenport ) {
59
60 logging_info( "starting up base communication and creating transports ..." );
61 logging_info( "using port " << listenport );
62
63#ifdef UNDERLAY_OMNET
64 AribaOmnetModule* module = StartupWrapper::getCurrentModule();
65 module->setServerPort( listenport );
66
67 transport = module;
68 network = new OmnetNetworkProtocol( module );
69#else
70 transport = new TCPTransport( listenport );
71 network = new IPv4NetworkProtocol();
72#endif
73
74 logging_debug( "searching for local locators ..." );
75
76 NetworkProtocol::NetworkLocatorSet locators = network->getAddresses();
77 NetworkProtocol::NetworkLocatorSet::iterator i = locators.begin();
78 NetworkProtocol::NetworkLocatorSet::iterator iend = locators.end();
79
80 //
81 // choose the first locator that is not localhost
82 //
83
84 bool foundLocator = false;
85
86 for( ; i != iend; i++){
87 logging_debug( "local locator found " << (*i)->toString() );
88 IPv4Locator* ipv4locator = dynamic_cast<IPv4Locator*>(*i);
89
90 // TODO: which locators are find to bind to?
91 // localhost is not too bad, works when testing locally
92 // with several instances. the manual override currently
93 // enables to use an arbitrary address, guess this is fine.
94 // so the manual override also can use ANY, LOCALHOST, BROADCAST
95
96 if( *ipv4locator != IPv4Locator::LOCALHOST &&
97 *ipv4locator != IPv4Locator::ANY &&
98 *ipv4locator != IPv4Locator::BROADCAST ){
99
100 ipv4locator->setPort(listenport);
101 localDescriptor.locator = ipv4locator;
102 localDescriptor.isUnspec = false;
103 logging_info( "binding to addr = " << ipv4locator->toString() );
104 foundLocator = true;
105 break;
106 }
107 } // for( ; i != iend; i++)
108
109
110 if( _locallocator != NULL ) {
111 if( localDescriptor.locator != NULL) delete localDescriptor.locator;
112 localDescriptor.locator = new IPv4Locator( IPv4Locator::fromString( _locallocator->toString()) );
113 localDescriptor.isUnspec = false;
114 logging_debug( "manual locator override, using locator=" <<
115 localDescriptor.locator->toString() );
116 foundLocator = true;
117 }
118
119 // if we found no local locator, exit using logging fatal
120 if( !foundLocator )
121 logging_fatal( "did not find a useable local locator!" );
122
123 transport->addMessageReceiver( this );
124 transport->start();
125
126#ifndef UNDERLAY_OMNET
127 //
128 // bind to the network change detection
129 //
130
131 networkMonitor.registerNotification( this );
132#endif
133
134 //
135 // base comm startup done
136 //
137
138 logging_info( "base communication started up" );
139}
140
141BaseCommunication::~BaseCommunication() {
142
143 logging_info( "stopping base communication and transport ..." );
144
145 transport->stop();
146 delete transport;
147 delete network;
148
149 logging_info( "base communication stopped" );
150}
151
152const LinkID BaseCommunication::establishLink(
153 const EndpointDescriptor& descriptor,
154 const QoSParameterSet& qos,
155 const SecurityParameterSet& sec){
156
157 logging_debug( "request to establish link" );
158
159 //
160 // just use the first locator in the endp descriptors
161 //
162
163 if( descriptor.locator == NULL ){
164 logging_error( "invalid destination endpoint" );
165 return LinkID::UNSPECIFIED;
166 }
167
168 if( localDescriptor.locator == NULL ){
169 logging_error( "invalid local endpoint" );
170 return LinkID::UNSPECIFIED;
171 }
172
173 const NetworkLocator* remote = descriptor.locator;
174 const NetworkLocator* local = localDescriptor.locator;
175
176 //
177 // create link and link descriptor
178 //
179
180 LinkID linkid = LinkID::create();
181
182 logging_debug( "creating new local descriptor entry with local link id " << linkid.toString() );
183 LinkDescriptor linkDescriptor( linkid, local, LinkID::UNSPECIFIED, remote, descriptor, false );
184 addLink( linkDescriptor );
185
186 //
187 // create a base msg with our link id and
188 // a request to open a link on the other side
189 //
190
191 logging_debug( "sending out base messages with request to open link to " << remote->toString() );
192 AribaBaseMsg baseMsg( remote, AribaBaseMsg::LINK_STATE_OPEN_REQUEST, linkid,
193 LinkID::UNSPECIFIED );
194 transport->sendMessage(&baseMsg);
195
196 return linkid;
197}
198
199void BaseCommunication::dropLink(const LinkID link) {
200
201 logging_debug( "starting to drop link " + link.toString() );
202
203 // see if we have the link
204 LinkDescriptor& descriptor = queryLocalLink( link );
205 if( descriptor.isUnspecified() ){
206 logging_error( "don't know the link you want to drop" );
207 return;
208 }
209
210 // warn if this link has some queued messages attached
211 if( descriptor.waitingmsg.size() > 0 ){
212 logging_warn( "dropping link " << link.toString() <<
213 " that has " << descriptor.waitingmsg.size() << " waiting messages" );
214 }
215
216 // create message to drop the link
217 logging_debug( "sending out link close request. for us, the link is closed now" );
218 AribaBaseMsg msg(
219 descriptor.remoteLocator,
220 AribaBaseMsg::LINK_STATE_CLOSE_REQUEST,
221 descriptor.localLink,
222 descriptor.remoteLink
223 );
224
225 // send message to drop the link
226 transport->sendMessage( &msg );
227
228 // tell the registered listeners
229 BOOST_FOREACH( CommunicationEvents* i, eventListener ){
230 i->onLinkDown( link, descriptor.localLocator, descriptor.remoteLocator );
231 }
232
233 // remove from map
234 removeLink(link);
235}
236
237seqnum_t BaseCommunication::sendMessage( const LinkID lid, const Message* message) {
238
239 logging_debug( "sending out message to link " << lid.toString() );
240
241 // query local link info
242 LinkDescriptor& linkDesc = queryLocalLink(lid);
243 if( linkDesc.isUnspecified() ){
244 logging_error( "don't know the link with id " << lid.toString() );
245 return -1;
246 }
247
248 // create message
249 AribaBaseMsg msg(
250 linkDesc.remoteLocator,
251 AribaBaseMsg::LINK_STATE_DATA,
252 linkDesc.localLink,
253 linkDesc.remoteLink
254 );
255
256 // encapsulate the payload message
257 msg.encapsulate( const_cast<Message*>(message) );
258
259 if( linkDesc.linkup ){
260
261 // send message
262 transport->sendMessage( &msg );
263 return ++currentSeqnum;
264
265 } else {
266
267 // queue message
268 logging_info( "link " << lid.toString() << " is not up yet, queueing message" );
269 linkDesc.waitingmsg.push_back( new Message(msg) ); // TODO ooooo
270
271 return 0;
272
273 } // if( linkDesc.linkup )
274}
275
276const EndpointDescriptor& BaseCommunication::getEndpointDescriptor(const LinkID link) const {
277
278 if( link == LinkID::UNSPECIFIED){
279 return localDescriptor;
280 } else {
281 LinkDescriptor& linkDesc = queryLocalLink(link);
282 if (linkDesc.isUnspecified()) return EndpointDescriptor::UNSPECIFIED;
283 return linkDesc.remoteEndpoint;
284 }
285}
286
287void BaseCommunication::registerMessageReceiver(MessageReceiver* _receiver) {
288 messageReceiver = _receiver;
289}
290
291void BaseCommunication::unregisterMessageReceiver(MessageReceiver* _receiver) {
292 messageReceiver = NULL;
293}
294
295void BaseCommunication::registerEventListener(CommunicationEvents* _events){
296
297 if( eventListener.find( _events ) == eventListener.end() )
298 eventListener.insert( _events );
299}
300
301void BaseCommunication::unregisterEventListener(CommunicationEvents* _events){
302
303 EventListenerSet::iterator i = eventListener.find( _events );
304 if( i != eventListener.end() )
305 eventListener.erase( i );
306}
307
308
309bool BaseCommunication::receiveMessage(const Message* message, const LinkID& link, const NodeID& node){
310
311 //
312 // these messages arrive from the Transport module
313 // and are incoming network messages. Unpack the
314 // AribaBaseMsg and handle control packets,
315 // deliver data packets to the overlay
316 //
317
318 AribaBaseMsg* spovmsg = ((Message*)message)->decapsulate<AribaBaseMsg>();
319 logging_debug( "receiving base comm message of type " << spovmsg->getTypeString() );
320
321 //
322 // deliver data to the overlays. we just give the
323 // inner packet to every registered overlay ...
324 //
325
326 if( spovmsg->getType() == AribaBaseMsg::LINK_STATE_DATA ){
327
328 logging_debug( "received data message, forwarding to overlay" );
329
330 //
331 // put the linkid as address into the message
332 // and sent it to the receiver
333 //
334
335 if( messageReceiver != NULL ) {
336 messageReceiver->receiveMessage(
337 spovmsg,
338 spovmsg->getRemoteLink(),
339 NodeID::UNSPECIFIED
340 );
341 }
342
343 } // LINK_STATE_DATA
344
345 //
346 // handle link open requests
347 //
348
349 else if( spovmsg->getType() == AribaBaseMsg::LINK_STATE_OPEN_REQUEST ){
350
351 logging_debug( "received link open request" );
352
353 //
354 // create a link context
355 //
356
357 // in an incoming packet the localLink is from
358 // the sender perspective local and from our
359 // perspective remote
360
361 logging_debug( "creating local link" );
362
363 LinkID localLink = LinkID::create();
364 LinkID remoteLink = spovmsg->getLocalLink();
365
366
367 const NetworkLocator* localLocator = dynamic_cast<const NetworkLocator*>(localDescriptor.locator);
368 const NetworkLocator* remoteLocator = dynamic_cast<const NetworkLocator*>(message->getSourceAddress());
369
370 logging_debug( "localLocator=" << localLocator->toString()
371 << " remoteLocator=" << remoteLocator->toString());
372
373 // ask the registered listeners if this link
374 // creation is fine. we will only allow the
375 // link if all of them agree
376
377 bool allowlink = true;
378 BOOST_FOREACH( CommunicationEvents* i, eventListener ){
379 allowlink &= i->onLinkRequest( localLink, localLocator, remoteLocator );
380 }
381
382 if( !allowlink ){
383 logging_warn( "overlay denied creation of link" );
384 return true;
385 }
386
387 //
388 // create and save the descriptor for the link
389 //
390
391 LinkDescriptor linkDescriptor(localLink, localLocator, remoteLink,
392 remoteLocator, EndpointDescriptor(remoteLocator), true);
393
394 logging_debug( "saving new link descriptor with " <<
395 "[local link " << localLink.toString() << "] " <<
396 "[local locator " << localLocator->toString() << "] " <<
397 "[remote link " << remoteLink.toString() << "] " <<
398 "[remote locator " << remoteLocator->toString() << "]" <<
399 "[link up true]" );
400
401 addLink( linkDescriptor );
402
403 //
404 // send out a link reply
405 //
406
407 logging_debug( "sending back link open reply for " <<
408 "[local link " << localLink.toString() << "] " <<
409 "[remote link " << remoteLink.toString() << "]" );
410
411 AribaBaseMsg reply(remoteLocator,
412 AribaBaseMsg::LINK_STATE_OPEN_REPLY,
413 localLink,
414 remoteLink);
415
416 transport->sendMessage( &reply );
417
418 //
419 // the link is now open
420 //
421
422 BOOST_FOREACH( CommunicationEvents* i, eventListener ){
423 i->onLinkUp( localLink, localLocator, remoteLocator );
424 }
425
426 } // LINK_STATE_OPEN_REQUEST
427
428 //
429 // handle link open replies
430 //
431
432 else if( spovmsg->getType() == AribaBaseMsg::LINK_STATE_OPEN_REPLY ){
433
434 logging_debug( "received link open reply for a link we initiated" );
435
436 // this is a reply to a link open request, so we have already
437 // a link mapping and can now set the remote link to valid
438 LinkDescriptor& linkDesc = queryLocalLink( spovmsg->getRemoteLink() );
439
440 if (linkDesc.isUnspecified()) {
441 logging_warn("Failed to find local link " << spovmsg->getRemoteLink().toString());
442 return false;
443 }
444
445 linkDesc.remoteLink = spovmsg->getLocalLink();
446 linkDesc.linkup = true;
447
448 logging_debug( "the link is now up with local link id " << spovmsg->getRemoteLink().toString() );
449
450 BOOST_FOREACH( CommunicationEvents* i, eventListener ){
451 i->onLinkUp( linkDesc.localLink, linkDesc.localLocator, linkDesc.remoteLocator );
452 }
453
454 if( linkDesc.waitingmsg.size() > 0 ){
455 logging_info( "sending out queued messages on link " << linkDesc.localLink.toString() );
456
457 BOOST_FOREACH( Message* msg, linkDesc.waitingmsg ){
458 sendMessage( linkDesc.localLink, msg );
459 delete msg;
460 }
461
462 linkDesc.waitingmsg.clear();
463 }
464
465 } // LINK_STATE_OPEN_REPLY
466
467 //
468 // handle link close requests
469 //
470
471 else if( spovmsg->getType() == AribaBaseMsg::LINK_STATE_CLOSE_REQUEST ){
472
473 const LinkID& localLink = spovmsg->getRemoteLink();
474 logging_debug( "received link close request for link " << localLink.toString() );
475
476 //
477 // the link is closed immediately, we
478 // don't need to send out a reply, so we
479 // delete the mapping and inform
480 //
481
482 LinkDescriptor& linkDesc = queryLocalLink( localLink );
483 if (linkDesc.isUnspecified()) {
484 logging_warn("Failed to find local link " << localLink.toString());
485 return false;
486 }
487
488 BOOST_FOREACH( CommunicationEvents* i, eventListener ){
489 i->onLinkDown( linkDesc.localLink, linkDesc.localLocator, linkDesc.remoteLocator );
490 }
491
492 removeLink( localLink );
493
494 } // LINK_STATE_CLOSE_REQUEST
495
496 //
497 // handle locator updates
498 //
499
500 else if( spovmsg->getType() == AribaBaseMsg::LINK_STATE_UPDATE ){
501
502 const LinkID& localLink = spovmsg->getRemoteLink();
503 logging_debug( "received link update for link " << localLink.toString() );
504
505 //
506 // find the link description
507 //
508
509 LinkDescriptor& linkDesc = queryLocalLink( localLink );
510 if (linkDesc.isUnspecified()) {
511 logging_warn("Failed to update local link " << localLink.toString());
512 return false;
513 }
514
515 //
516 // update the remote locator
517 //
518
519 const NetworkLocator* oldremote = linkDesc.remoteLocator;
520 linkDesc.remoteLocator = dynamic_cast<const NetworkLocator*>(message->getSourceAddress());
521
522 //
523 // inform the listeners (local link has _not_ changed!)
524 //
525
526 BOOST_FOREACH( CommunicationEvents* i, eventListener ){
527 i->onLinkChanged(
528 linkDesc.localLink, // linkid
529 linkDesc.localLocator, // old local
530 linkDesc.localLocator, // new local
531 oldremote, // old remote
532 linkDesc.remoteLocator // new remote
533 );
534 }
535
536 } // LINK_STATE_UPDATE
537
538 return true;
539}
540
541void BaseCommunication::addLink( const LinkDescriptor& link ) {
542 linkSet.push_back( link );
543}
544
545void BaseCommunication::removeLink( const LinkID& localLink ) {
546
547 LinkSet::iterator i = linkSet.begin();
548 LinkSet::iterator iend = linkSet.end();
549
550 for( ; i != iend; i++){
551 if( (*i).localLink != localLink) continue;
552
553 BOOST_FOREACH( Message* msg, i->waitingmsg ){
554 delete msg;
555 }
556
557 i->waitingmsg.clear();
558 linkSet.erase( i );
559
560 break;
561 }
562}
563
564BaseCommunication::LinkDescriptor& BaseCommunication::queryLocalLink( const LinkID& link ) const {
565 for (int i=0; i<linkSet.size();i++)
566 if (linkSet[i].localLink == link) return (LinkDescriptor&)linkSet[i];
567 return (LinkDescriptor&)LinkDescriptor::UNSPECIFIED;
568}
569
570BaseCommunication::LinkDescriptor& BaseCommunication::queryRemoteLink( const LinkID& link ) const {
571 for (int i=0; i<linkSet.size();i++)
572 if (linkSet[i].remoteLink == link) return (LinkDescriptor&)linkSet[i];
573 return (LinkDescriptor&)LinkDescriptor::UNSPECIFIED;
574}
575
576LinkIDs BaseCommunication::getLocalLinks( const EndpointDescriptor& ep ) const {
577 LinkIDs ids;
578
579 for (int i=0; i<linkSet.size(); i++){
580 if( ep == EndpointDescriptor::UNSPECIFIED ){
581 ids.push_back( linkSet[i].localLink );
582 } else {
583 if ( linkSet[i].remoteLocator == ep.locator )
584 ids.push_back( linkSet[i].localLink );
585 }
586 }
587
588 return ids;
589}
590
591void BaseCommunication::onNetworkChange(const NetworkChangeInterface::NetworkChangeInfo& info){
592
593#ifdef UNDERLAY_OMNET
594
595 // we have no mobility support for simulations
596 return
597
598#endif // UNDERLAY_OMNET
599
600 //
601 // we only care about address changes, not about interface changes
602 // as address changes are triggered by interface changes, we are safe here
603 //
604
605 if( info.type != NetworkChangeInterface::EventTypeAddressNew &&
606 info.type != NetworkChangeInterface::EventTypeAddressDelete ) return;
607
608 logging_info( "base communication is handling network address changes" );
609
610 //
611 // get all now available addresses
612 //
613
614 NetworkInformation networkInformation;
615 AddressInformation addressInformation;
616
617 NetworkInterfaceList interfaces = networkInformation.getInterfaces();
618 AddressList addresses;
619
620 for( NetworkInterfaceList::iterator i = interfaces.begin(); i != interfaces.end(); i++ ){
621 AddressList newaddr = addressInformation.getAddresses(*i);
622 addresses.insert( addresses.end(), newaddr.begin(), newaddr.end() );
623 }
624
625 //
626 // get current locators for the local endpoint
627 // TODO: this code is dublicate of the ctor code!!! cleanup!
628 //
629
630 NetworkProtocol::NetworkLocatorSet locators = network->getAddresses();
631 NetworkProtocol::NetworkLocatorSet::iterator i = locators.begin();
632 NetworkProtocol::NetworkLocatorSet::iterator iend = locators.end();
633
634 //
635 // remember the old local endpoint, in case it changes
636 //
637
638 EndpointDescriptor oldLocalDescriptor( localDescriptor );
639
640 //
641 // look for local locators that we can use in communication
642 //
643 // choose the first locator that is not localhost
644 //
645
646 bool foundLocator = false;
647 bool changedLocator = false;
648
649 for( ; i != iend; i++){
650 logging_debug( "local locator found " << (*i)->toString() );
651 IPv4Locator* ipv4locator = dynamic_cast<IPv4Locator*>(*i);
652
653 if( *ipv4locator != IPv4Locator::LOCALHOST &&
654 *ipv4locator != IPv4Locator::ANY &&
655 *ipv4locator != IPv4Locator::BROADCAST ){
656
657 ipv4locator->setPort( listenport );
658 changedLocator = *localDescriptor.locator != *ipv4locator;
659 localDescriptor.locator = ipv4locator;
660 logging_info( "binding to addr = " << ipv4locator->toString() );
661 foundLocator = true;
662 break;
663 }
664 } // for( ; i != iend; i++)
665
666 //
667 // if we found no locator, bind to localhost
668 //
669
670 if( !foundLocator ){
671 changedLocator = *localDescriptor.locator != IPv4Locator::LOCALHOST;
672 localDescriptor.locator = new IPv4Locator( IPv4Locator::LOCALHOST );
673 ((IPv4Locator*)(localDescriptor.locator))->setPort( listenport );
674 logging_info( "found no good local lcoator, binding to addr = " <<
675 localDescriptor.locator->toString() );
676 }
677
678 //
679 // if we have connections that have no more longer endpoints
680 // close these. they will be automatically built up again.
681 // also update the local locator in the linkset mapping
682 //
683
684 if( changedLocator ){
685
686 logging_debug( "local endp locator has changed to " << localDescriptor.toString() <<
687 ", resettings connections that end at old locator " <<
688 oldLocalDescriptor.toString());
689
690 LinkSet::iterator i = linkSet.begin();
691 LinkSet::iterator iend = linkSet.end();
692
693 for( ; i != iend; i++ ){
694
695 logging_debug( "checking connection for locator change: " <<
696 " local " << (*i).localLocator->toString() <<
697 " old " << oldLocalDescriptor.locator->toString() );
698
699 if( *((*i).localLocator) == *(oldLocalDescriptor.locator) ){
700
701 logging_debug("terminating connection to " << (*i).remoteLocator->toString() );
702 transport->terminate( oldLocalDescriptor.locator, (*i).remoteLocator );
703
704 (*i).localLocator = localDescriptor.locator;
705 }
706 } // for( ; i != iend; i++ )
707
708 // wait 500ms to give the sockets time to shut down
709 usleep( 500000 );
710
711 } else {
712
713 logging_debug( "locator has not changed, not resetting connections" );
714
715 }
716
717 //
718 // handle the connections that have no longer any
719 // valid locator. send update messages with the new
720 // locator, so the remote node updates its locator/link mapping
721 //
722
723 LinkSet::iterator iAffected = linkSet.begin();
724 LinkSet::iterator endAffected = linkSet.end();
725
726 for( ; iAffected != endAffected; iAffected++ ){
727 LinkDescriptor descr = *iAffected;
728 logging_debug( "sending out link locator update to " << descr.remoteLocator->toString() );
729
730 AribaBaseMsg updateMsg( descr.remoteLocator,
731 AribaBaseMsg::LINK_STATE_UPDATE,
732 descr.localLink, descr.remoteLink );
733
734 transport->sendMessage( &updateMsg );
735 }
736}
737
738}} // namespace ariba, communication
Note: See TracBrowser for help on using the repository browser.