|
IBR-DTNSuite 0.6
|
00001 /* 00002 * ConnectionManager.cpp 00003 * 00004 * Created on: 24.09.2009 00005 * Author: morgenro 00006 */ 00007 00008 #include "net/ConnectionManager.h" 00009 #include "net/UDPConvergenceLayer.h" 00010 #include "net/TCPConvergenceLayer.h" 00011 #include "net/BundleReceivedEvent.h" 00012 #include "core/NodeEvent.h" 00013 #include "core/BundleEvent.h" 00014 #include "ibrcommon/net/tcpserver.h" 00015 #include "core/BundleCore.h" 00016 #include "routing/RequeueBundleEvent.h" 00017 #include "net/ConnectionEvent.h" 00018 00019 #include "core/NodeEvent.h" 00020 #include "core/TimeEvent.h" 00021 00022 #include <iostream> 00023 #include <iomanip> 00024 #include <algorithm> 00025 #include <functional> 00026 #include <typeinfo> 00027 #include <ibrcommon/Logger.h> 00028 00029 using namespace dtn::core; 00030 00031 namespace dtn 00032 { 00033 namespace net 00034 { 00035 struct CompareNodeDestination: 00036 public std::binary_function< dtn::core::Node, dtn::data::EID, bool > { 00037 bool operator() ( const dtn::core::Node &node, const dtn::data::EID &destination ) const { 00038 return node.getEID() == destination; 00039 } 00040 }; 00041 00042 ConnectionManager::ConnectionManager() 00043 : _shutdown(false) 00044 { 00045 } 00046 00047 ConnectionManager::~ConnectionManager() 00048 { 00049 } 00050 00051 void ConnectionManager::componentUp() 00052 { 00053 bindEvent(TimeEvent::className); 00054 bindEvent(NodeEvent::className); 00055 bindEvent(ConnectionEvent::className); 00056 } 00057 00058 void ConnectionManager::componentDown() 00059 { 00060 { 00061 ibrcommon::MutexLock l(_cl_lock); 00062 // clear the list of convergence layers 00063 _cl.clear(); 00064 } 00065 00066 unbindEvent(NodeEvent::className); 00067 unbindEvent(TimeEvent::className); 00068 unbindEvent(ConnectionEvent::className); 00069 } 00070 00071 void ConnectionManager::raiseEvent(const dtn::core::Event *evt) 00072 { 00073 try { 00074 const NodeEvent &nodeevent = dynamic_cast<const NodeEvent&>(*evt); 00075 const Node &n = nodeevent.getNode(); 00076 00077 switch (nodeevent.getAction()) 00078 { 00079 case NODE_INFO_UPDATED: 00080 discovered(n); 00081 break; 00082 00083 case NODE_AVAILABLE: 00084 if (n.doConnectImmediately()) 00085 { 00086 // open the connection immediately 00087 open(n); 00088 } 00089 break; 00090 00091 default: 00092 break; 00093 } 00094 } catch (const std::bad_cast&) { } 00095 00096 try { 00097 const TimeEvent &timeevent = dynamic_cast<const TimeEvent&>(*evt); 00098 00099 if (timeevent.getAction() == TIME_SECOND_TICK) 00100 { 00101 check_discovered(); 00102 } 00103 } catch (const std::bad_cast&) { } 00104 00105 try { 00106 const ConnectionEvent &connection = dynamic_cast<const ConnectionEvent&>(*evt); 00107 00108 switch (connection.state) 00109 { 00110 case ConnectionEvent::CONNECTION_UP: 00111 { 00112 ibrcommon::MutexLock l(_node_lock); 00113 00114 // if this node was unknown before... 00115 if (!isNeighbor(connection.node)) 00116 { 00117 // announce the new node 00118 dtn::core::NodeEvent::raise(connection.node, dtn::core::NODE_AVAILABLE); 00119 } 00120 00121 _connected_nodes.insert(connection.node); 00122 break; 00123 } 00124 00125 case ConnectionEvent::CONNECTION_DOWN: 00126 { 00127 ibrcommon::MutexLock l(_node_lock); 00128 00129 // remove the node from the connected list 00130 _connected_nodes.erase(connection.node); 00131 00132 // if the node is unknown now ... 00133 if (!isNeighbor(connection.node)) 00134 { 00135 // announce the unavailable event 00136 dtn::core::NodeEvent::raise(connection.node, dtn::core::NODE_UNAVAILABLE); 00137 } 00138 break; 00139 } 00140 00141 default: 00142 break; 00143 } 00144 00145 } catch (const std::bad_cast&) { 00146 00147 } 00148 } 00149 00150 void ConnectionManager::addConnection(const dtn::core::Node &n) 00151 { 00152 ibrcommon::MutexLock l(_node_lock); 00153 _static_nodes.insert(n); 00154 dtn::core::NodeEvent::raise(n, dtn::core::NODE_AVAILABLE); 00155 } 00156 00157 void ConnectionManager::addConvergenceLayer(ConvergenceLayer *cl) 00158 { 00159 ibrcommon::MutexLock l(_cl_lock); 00160 _cl.insert( cl ); 00161 } 00162 00163 void ConnectionManager::discovered(const dtn::core::Node &node) 00164 { 00165 // ignore messages of ourself 00166 if (node.getEID() == dtn::core::BundleCore::local) return; 00167 00168 ibrcommon::MutexLock l(_node_lock); 00169 00170 // if this node was unknown before... 00171 if (!isNeighbor(node)) 00172 { 00173 // announce the new node 00174 dtn::core::NodeEvent::raise(node, dtn::core::NODE_AVAILABLE); 00175 } 00176 00177 _discovered_nodes.erase(node); 00178 _discovered_nodes.insert(node); 00179 } 00180 00181 void ConnectionManager::check_discovered() 00182 { 00183 ibrcommon::MutexLock l(_node_lock); 00184 00185 // search for outdated nodes 00186 std::set<dtn::core::Node>::iterator iter = _discovered_nodes.begin(); 00187 00188 while (iter != _discovered_nodes.end()) 00189 { 00190 dtn::core::Node n = (*iter); 00191 00192 // node is outdated -> remove it 00193 _discovered_nodes.erase( iter++ ); 00194 00195 if ( !n.decrementTimeout(1) ) 00196 { 00197 // if the node is unknown now ... 00198 if (!isNeighbor(n)) 00199 { 00200 // announce the unavailable event 00201 dtn::core::NodeEvent::raise(n, dtn::core::NODE_UNAVAILABLE); 00202 } 00203 } 00204 else 00205 { 00206 _discovered_nodes.insert(n); 00207 } 00208 } 00209 } 00210 00211 void ConnectionManager::open(const dtn::core::Node &node) 00212 { 00213 ibrcommon::MutexLock l(_cl_lock); 00214 00215 // search for the right cl 00216 for (std::set<ConvergenceLayer*>::iterator iter = _cl.begin(); iter != _cl.end(); iter++) 00217 { 00218 ConvergenceLayer *cl = (*iter); 00219 if (node.has(cl->getDiscoveryProtocol())) 00220 { 00221 cl->open(node); 00222 00223 // stop here, we queued the bundle already 00224 return; 00225 } 00226 } 00227 00228 throw ConnectionNotAvailableException(); 00229 } 00230 00231 void ConnectionManager::queue(const dtn::core::Node &node, const ConvergenceLayer::Job &job) 00232 { 00233 ibrcommon::MutexLock l(_cl_lock); 00234 00235 // search for the right cl 00236 for (std::set<ConvergenceLayer*>::iterator iter = _cl.begin(); iter != _cl.end(); iter++) 00237 { 00238 ConvergenceLayer *cl = (*iter); 00239 if (node.has(cl->getDiscoveryProtocol())) 00240 { 00241 cl->queue(node, job); 00242 00243 // stop here, we queued the bundle already 00244 return; 00245 } 00246 } 00247 00248 throw ConnectionNotAvailableException(); 00249 } 00250 00251 void ConnectionManager::queue(const ConvergenceLayer::Job &job) 00252 { 00253 try { 00254 ibrcommon::MutexLock l(_node_lock); 00255 dtn::core::Node match(job._destination); 00256 00257 if (IBRCOMMON_LOGGER_LEVEL >= 50) 00258 { 00259 IBRCOMMON_LOGGER_DEBUG(50) << "## static node list ##" << IBRCOMMON_LOGGER_ENDL; 00260 for (std::set<dtn::core::Node>::const_iterator iter = _static_nodes.begin(); iter != _static_nodes.end(); iter++) 00261 { 00262 const dtn::core::Node &n = (*iter); 00263 IBRCOMMON_LOGGER_DEBUG(50) << n.toString() << IBRCOMMON_LOGGER_ENDL; 00264 } 00265 } 00266 00267 if (IBRCOMMON_LOGGER_LEVEL >= 50) 00268 { 00269 IBRCOMMON_LOGGER_DEBUG(50) << "## dynamic node list ##" << IBRCOMMON_LOGGER_ENDL; 00270 for (std::set<dtn::core::Node>::const_iterator iter = _discovered_nodes.begin(); iter != _discovered_nodes.end(); iter++) 00271 { 00272 const dtn::core::Node &n = (*iter); 00273 IBRCOMMON_LOGGER_DEBUG(50) << n.toString() << IBRCOMMON_LOGGER_ENDL; 00274 } 00275 } 00276 00277 if (IBRCOMMON_LOGGER_LEVEL >= 50) 00278 { 00279 IBRCOMMON_LOGGER_DEBUG(50) << "## connected node list ##" << IBRCOMMON_LOGGER_ENDL; 00280 for (std::set<dtn::core::Node>::const_iterator iter = _connected_nodes.begin(); iter != _connected_nodes.end(); iter++) 00281 { 00282 const dtn::core::Node &n = (*iter); 00283 IBRCOMMON_LOGGER_DEBUG(50) << n.toString() << IBRCOMMON_LOGGER_ENDL; 00284 } 00285 } 00286 00287 IBRCOMMON_LOGGER_DEBUG(50) << "match for " << match.toString() << IBRCOMMON_LOGGER_ENDL; 00288 00289 try { 00290 // queue to a static node 00291 std::set<dtn::core::Node>::const_iterator iter = _static_nodes.find(match); 00292 00293 if (iter != _static_nodes.end()) 00294 { 00295 throw (*iter); 00296 } 00297 } catch (const std::exception&) { } 00298 00299 try { 00300 // queue to a dynamic discovered node 00301 std::set<dtn::core::Node>::const_iterator iter = _discovered_nodes.find(match); 00302 00303 if (iter != _discovered_nodes.end()) 00304 { 00305 throw (*iter); 00306 } 00307 } catch (const std::exception&) { } 00308 00309 try { 00310 // queue to a connected node 00311 std::set<dtn::core::Node>::const_iterator iter = _connected_nodes.find(match); 00312 00313 if (iter != _connected_nodes.end()) 00314 { 00315 throw (*iter); 00316 } 00317 } catch (const std::exception&) { } 00318 } catch (const dtn::core::Node &next) { 00319 IBRCOMMON_LOGGER_DEBUG(50) << "next hop: " << next.toString() << IBRCOMMON_LOGGER_ENDL; 00320 queue(next, job); 00321 return; 00322 } 00323 00324 throw NeighborNotAvailableException("No active connection to this neighbor available!"); 00325 } 00326 00327 void ConnectionManager::queue(const dtn::data::EID &eid, const dtn::data::BundleID &b) 00328 { 00329 queue( ConvergenceLayer::Job(eid, b) ); 00330 } 00331 00332 const std::set<dtn::core::Node> ConnectionManager::getNeighbors() 00333 { 00334 ibrcommon::MutexLock l(_node_lock); 00335 00336 std::set<dtn::core::Node> _nodes; 00337 00338 for (std::set<dtn::core::Node>::const_iterator iter = _static_nodes.begin(); iter != _static_nodes.end(); iter++) 00339 { 00340 _nodes.insert( *iter ); 00341 } 00342 00343 for (std::set<dtn::core::Node>::const_iterator iter = _discovered_nodes.begin(); iter != _discovered_nodes.end(); iter++) 00344 { 00345 _nodes.insert( *iter ); 00346 } 00347 00348 for (std::set<dtn::core::Node>::const_iterator iter = _connected_nodes.begin(); iter != _connected_nodes.end(); iter++) 00349 { 00350 _nodes.insert( *iter ); 00351 } 00352 00353 return _nodes; 00354 } 00355 00356 00357 bool ConnectionManager::isNeighbor(const dtn::core::Node &node) 00358 { 00359 // search for the node in all sets 00360 if (_static_nodes.find(node) != _static_nodes.end()) 00361 { 00362 return true; 00363 } 00364 00365 if (_discovered_nodes.find(node) != _discovered_nodes.end()) 00366 { 00367 return true; 00368 } 00369 00370 if (_connected_nodes.find(node) != _connected_nodes.end()) 00371 { 00372 return true; 00373 } 00374 00375 return false; 00376 } 00377 00378 const std::string ConnectionManager::getName() const 00379 { 00380 return "ConnectionManager"; 00381 } 00382 } 00383 }