source: source/ariba/overlay/modules/onehop/OneHop.cpp@ 3705

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

-einige fixed bzgl. link management, fehlerhafte serialisierer, etc.

File size: 10.9 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#include "OneHop.h"
40#include "ariba/overlay/BaseOverlay.h"
41
42#include "ariba/overlay/modules/onehop/messages/OneHopMessage.h"
43#include "ariba/overlay/modules/onehop/messages/NodeListingRequest.h"
44#include "ariba/overlay/modules/onehop/messages/NodeListingReply.h"
45
46namespace ariba {
47namespace overlay {
48
49use_logging_cpp( OneHop );
50
51OneHop::OneHop(BaseOverlay& _baseoverlay, const NodeID& _nodeid, OverlayStructureEvents* _eventsReceiver)
52 : OverlayInterface( _baseoverlay, _nodeid, _eventsReceiver ),
53 state ( OneHopStateInvalid ),
54 bootstrapLink ( LinkID::UNSPECIFIED ),
55 pendingLinks ( 0 ) {
56
57 //
58 // insert us as the first node in the overlay
59 //
60 overlayNodes.insert( make_pair(_nodeid, LinkID::UNSPECIFIED) );
61
62 Timer::setInterval(5000);
63 Timer::start();
64}
65
66OneHop::~OneHop(){
67 Timer::stop();
68 deleteOverlay();
69}
70
71const EndpointDescriptor& OneHop::resolveNode(const NodeID& node){
72
73 OverlayNodeMapping::const_iterator i = overlayNodes.find( node );
74 if (i == overlayNodes.end()) return EndpointDescriptor::UNSPECIFIED;
75
76 const EndpointDescriptor& ep = baseoverlay.getEndpointDescriptor( i->second );
77
78 logging_debug( "resolved node " << node.toString() << " to endpoint " << ep.toString() );
79 return ep;
80}
81
82void OneHop::routeMessage(const NodeID& destnode, Message* msg){
83
84 // in the fullmesh overlay we know every other node
85 // so we also have a link to each other node
86
87 logging_debug( "routing message to node " << destnode.toString() );
88
89 OverlayNodeMapping::const_iterator i = overlayNodes.find( destnode );
90 if (i == overlayNodes.end()) {
91 logging_error( "not able to route message to node " << destnode.toString() );
92 return;
93 }
94 OneHopMessage onehopRoute( OneHopMessage::OneHopMessageTypeRoute );
95 onehopRoute.encapsulate(msg);
96
97 baseoverlay.sendMessage( &onehopRoute, i->second );
98}
99
100void OneHop::createOverlay() {
101 // don't need to bootstrap against ourselfs.
102 // the create and join process is completed now.
103 logging_info( "creating onehop overlay structure" );
104 state = OneHopStateCompleted;
105}
106
107void OneHop::deleteOverlay(){
108
109 logging_info( "deleting onehop overlay structure" );
110 state = OneHopStateInvalid;
111 pendingLinks = 0;
112}
113
114OverlayInterface::NodeList OneHop::getKnownNodes() const {
115
116 OverlayInterface::NodeList retlist;
117
118 OverlayNodeMapping::const_iterator i = overlayNodes.begin();
119 OverlayNodeMapping::const_iterator iend = overlayNodes.end();
120
121 for( ; i != iend; i++ )
122 retlist.push_back( i->first );
123
124 return retlist;
125}
126
127void OneHop::joinOverlay(const EndpointDescriptor& bootstrapEp){
128
129 logging_info( "joining onehop overlay structure through end-point " <<
130 (bootstrapEp == EndpointDescriptor::UNSPECIFIED ?
131 "local" : bootstrapEp.toString()) );
132
133 state = OneHopStateJoinInitiated;
134 pendingLinks = 0;
135
136 if( bootstrapEp == EndpointDescriptor::UNSPECIFIED ){
137
138 // we are the initiator and we are to bootstrap against
139 // ourselfs. in the onehop overlay this is not an issue
140 // and we can just ignore this call.
141
142 state = OneHopStateCompleted;
143 } else {
144 bootstrapLink = baseoverlay.establishLink( bootstrapEp,
145 OverlayInterface::OVERLAY_SERVICE_ID );
146 }
147}
148
149void OneHop::leaveOverlay(){
150
151 logging_info( "leaving onehop overlay structure" );
152
153 // set the state to invalid, this will prevent from
154 // handling onLinkDown events, as we are traversing the
155 // overlayNodes map and the onLinkDown function is called
156 // from the BaseOverlay and OneHop::onLinkDown will also
157 // try to access the overlayNodes structure.
158 state = OneHopStateInvalid;
159
160 //
161 // send leave messages to all nodes. the nodes
162 // will then drop the links
163 //
164
165 OverlayNodeMapping::iterator i = overlayNodes.begin();
166 OverlayNodeMapping::iterator iend = overlayNodes.end();
167
168 for( ; i != iend; i++){
169 if( i->first != nodeid && i->second != LinkID::UNSPECIFIED ){
170
171 OneHopMessage msg (OneHopMessage::OneHopMessageTypeLeave);
172 baseoverlay.sendMessage( &msg, i->second );
173 }
174 }
175
176 pendingLinks = 0;
177}
178
179
180void OneHop::onLinkDown(const LinkID& lnk, const NodeID& remote){
181
182 // don't handle when we are in state-invalid,
183 // see comment in OneHop::leaveOverlay
184 if( state == OneHopStateInvalid ) return;
185
186 // node went down, remove from overlay mapping
187 logging_debug( "link " << lnk.toString() << " to node " << remote.toString() << " went down, removing node" );
188
189 OverlayNodeMapping::iterator i = overlayNodes.begin();
190 OverlayNodeMapping::iterator iend = overlayNodes.end();
191
192 for( ; i != iend; i++ ){
193 if( i->second == lnk ){
194 overlayNodes.erase( i );
195 break;
196 }
197 }
198}
199
200void OneHop::onLinkUp(const LinkID& lnk, const NodeID& remote){
201
202 //
203 // as soon as a link goes up, we always request the node listing.
204 // and try to get connections to as much nodes as possible in a greedy way.
205 //
206
207 if( lnk != bootstrapLink ){
208 if( pendingLinks > 0 ) pendingLinks--;
209 if( pendingLinks == 0 ) state = OneHopStateCompleted;
210 }
211
212 logging_debug( "link is up, sending out node listing request" );
213
214 NodeListingRequest requestmsg;
215 OneHopMessage onemsg( OneHopMessage::OneHopMessageTypeListingRequest );
216 onemsg.encapsulate( &requestmsg );
217
218 state = OneHopStateJoinListingRequested;
219 baseoverlay.sendMessage( &onemsg, lnk );
220}
221
222void OneHop::onMessage(const DataMessage& msg, const NodeID& remote, const LinkID& lnk){
223
224 OneHopMessage* onemsg = msg.getMessage()->convert<OneHopMessage>();
225 if( onemsg == NULL ) return;
226
227 //
228 // handle node listing request
229 //
230
231 if( onemsg->isType( OneHopMessage::OneHopMessageTypeListingRequest ) ){
232
233 NodeListingRequest* request = onemsg->decapsulate<NodeListingRequest>();
234
235 logging_info( "onehop received node listing request from node " << remote.toString() );
236
237 //
238 // first, insert the nodes and the link into our mapping
239 //
240
241 overlayNodes.insert( make_pair(remote, lnk) );
242
243 //
244 // send back a message with all nodes
245 // and their current EndpointDescriptor
246 //
247
248 OneHopMessage onehopReply( OneHopMessage::OneHopMessageTypeListingReply );
249 NodeListingReply listingReply;
250
251 OverlayNodeMapping::iterator i = overlayNodes.begin();
252 OverlayNodeMapping::iterator iend = overlayNodes.end();
253
254 logging_debug( "sending out node listing reply with the following items" );
255
256 for( ; i != iend; i++ ){
257
258 const NodeID node = i->first;
259 const LinkID link = i->second;
260 const EndpointDescriptor& endpoint = baseoverlay.getEndpointDescriptor( link );
261
262 logging_debug( "node: " + node.toString() + ", endp: " + endpoint.toString());
263 listingReply.add( node, const_cast<EndpointDescriptor*>(new EndpointDescriptor(endpoint)) );
264 }
265
266 onehopReply.encapsulate( &listingReply );
267 baseoverlay.sendMessage( &onehopReply, lnk );
268
269 //
270 // now that we know the node, we can tell the baseoverlay
271 // that the node has joined our overlay structure
272 //
273
274 eventsReceiver->onNodeJoin( remote );
275
276 } // OneHopMessageTypeListingRequest
277
278 //
279 // handle node listing reply
280 //
281
282 if( onemsg->isType( OneHopMessage::OneHopMessageTypeListingReply) ){
283
284 NodeListingReply* reply = onemsg->decapsulate<NodeListingReply>();
285
286 logging_debug( "received node listing reply from node " << remote.toString()
287 << " with all overlay nodes. connecting to all of them" );
288
289 //
290 // get out all the EndpointDescriptors from the
291 // overlay nodes and connect to all nodes where
292 // we don't have a link yet
293 //
294
295 const NodeListingReply::NodeEndpointList& endpoints = reply->getList();
296 logging_debug( "received " << endpoints.size() << " nodes in listing" );
297 pendingLinks = 0;
298
299 NodeListingReply::NodeEndpointList::const_iterator i = endpoints.begin();
300 NodeListingReply::NodeEndpointList::const_iterator iend = endpoints.end();
301
302 for( ; i != iend; i++ ){
303
304 //
305 // don't connect to nodes that we already have
306 // a link to and don't connect to ourself
307 //
308
309 const NodeID& node = (*i).first;
310 if( overlayNodes.find(node) != overlayNodes.end() ) continue;
311 if( node == nodeid ) continue;
312
313 logging_debug( "building up link to node in overlay " << node.toString() );
314 const LinkID link = baseoverlay.establishLink( *((*i).second),
315 OverlayInterface::OVERLAY_SERVICE_ID );
316
317 overlayNodes.insert( make_pair(node, link) );
318 pendingLinks++;
319
320 } // for( ; i != iend; i++ )
321
322 } // OneHopMessageTypeListingReply
323
324 //
325 // handle node leaves
326 //
327
328 if( onemsg->isType(OneHopMessage::OneHopMessageTypeLeave) ){
329
330 logging_debug("received leave message from " <<
331 remote.toString() << " on link " << lnk.toString());
332
333 // drop the link to the node
334 baseoverlay.dropLink( lnk );
335
336 } // OneHopMessageTypeLeave
337
338 //
339 // handle kbr route messages
340 //
341
342 if( onemsg->isType( OneHopMessage::OneHopMessageTypeRoute) ){
343 logging_debug( "Route message arrived at destination node -> delegate to BaseOverlay" );
344 baseoverlay.incomingRouteMessage( onemsg );
345 } // OneHopMessageTypeRoute
346
347}
348
349void OneHop::eventFunction(){
350
351 logging_debug("<<<<<<<<<<<<<<<<onehop-table<<<<<<<<<<<<<<<<<<<");
352
353 OverlayNodeMapping::iterator i = overlayNodes.begin();
354 OverlayNodeMapping::iterator iend = overlayNodes.end();
355
356 for( ; i != iend; i++ ){
357
358 const NodeID node = i->first;
359 const LinkID link = i->second;
360 const EndpointDescriptor& endpoint = baseoverlay.getEndpointDescriptor( link );
361
362 logging_debug( "node: " << node.toString() <<
363 ", link_: " << link.toString() << ", endp: " << endpoint.toString());
364 }
365
366 logging_debug(">>>>>>>>>>>>>>>>>onehop-table>>>>>>>>>>>>>>>>>>>>>");
367
368}
369
370}} // namespace ariba, overlay
Note: See TracBrowser for help on using the repository browser.