![]() |
User Manual, Developers Guide and API Documentation |
![]() |
00001 /******************************************************************************* 00002 * This file is part of openWNS (open Wireless Network Simulator) 00003 * _____________________________________________________________________________ 00004 * 00005 * Copyright (C) 2004-2007 00006 * Chair of Communication Networks (ComNets) 00007 * Kopernikusstr. 16, D-52074 Aachen, Germany 00008 * phone: ++49-241-80-27910, 00009 * fax: ++49-241-80-22242 00010 * email: info@openwns.org 00011 * www: http://www.openwns.org 00012 * _____________________________________________________________________________ 00013 * 00014 * openWNS is free software; you can redistribute it and/or modify it under the 00015 * terms of the GNU Lesser General Public License version 2 as published by the 00016 * Free Software Foundation; 00017 * 00018 * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY 00019 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 00020 * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 00021 * details. 00022 * 00023 * You should have received a copy of the GNU Lesser General Public License 00024 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00025 * 00026 ******************************************************************************/ 00027 00028 #include <TCP/Service.hpp> 00029 #include <TCP/Connection.hpp> 00030 #include <TCP/UpperConvergence.hpp> 00031 #include <TCP/LowerConvergence.hpp> 00032 #include <TCP/ConnectionHandler.hpp> 00033 #include <TCP/HandshakeStrategyInterface.hpp> 00034 #include <TCP/FlowHandler.hpp> 00035 #include <TCP/FlowIDBuilder.hpp> 00036 00037 #include <WNS/service/tl/PortPool.hpp> 00038 #include <WNS/service/tl/DataHandler.hpp> 00039 #include <WNS/service/tl/FlowID.hpp> 00040 00041 #include <WNS/module/Base.hpp> 00042 #include <WNS/service/dll/FlowEstablishmentAndRelease.hpp> 00043 00044 using namespace tcp; 00045 00046 Service::Service(UpperConvergence* _upperConvergence, 00047 LowerConvergence* _lowerConvergence, 00048 wns::ldk::FlowSeparator* _flowSeparator, 00049 const wns::pyconfig::View& _pyco, 00050 tcp::FlowHandler* _tcpFlowHandler, 00051 wns::service::dll::FlowEstablishmentAndRelease* _fear, 00052 wns::ldk::ControlServiceRegistry* _csr) : 00053 wns::ldk::ControlService(_csr), 00054 removeDelay(2), 00055 ipService(NULL), 00056 dns(NULL), 00057 flowIDToConnectionHandler(), 00058 listeners(), 00059 portPool(_pyco.get<simTimeType>("portUnbindDelay")), 00060 logger(_pyco.get("logger")), 00061 pyco(_pyco), 00062 upperConvergence(_upperConvergence), 00063 lowerConvergence(_lowerConvergence), 00064 flowSeparator(_flowSeparator), 00065 flowEstablishmentAndRelease(_fear), 00066 tcpFlowHandler(_tcpFlowHandler) 00067 { 00068 upperConvergence->setTLService(this); 00069 } 00070 00071 Service::~Service() 00072 { 00073 } 00074 00075 void 00076 Service::listenOnPort( 00077 wns::service::tl::Port _port, 00078 wns::service::tl::ConnectionHandler* _ch) 00079 { 00080 assure(_port >= 0 && _port <= 65535, "Valid port number are: 0-65535 (is " << _port << ")"); 00081 assure(_ch, "No valid ConnectionHandler provided (is NULL)"); 00082 assure(portPool.isAvailable(_port), "Port already bound (is " << _port << ")"); 00083 00084 portPool.bind(_port); 00085 listeners.insert(_port, _ch); 00086 00087 MESSAGE_SINGLE(NORMAL, logger, "Listening on port " << _port << ": " << listeners.knows(_port)); 00088 } 00089 00090 void 00091 Service::stopListenOnPort(const wns::service::tl::Port _port) 00092 { 00093 assure(listeners.knows(_port), "Not currently listening on port."); 00094 00095 MESSAGE_SINGLE(NORMAL, logger, "Stopping listenOnPort for port " << _port); 00096 listeners.erase(_port); 00097 portPool.unbind(_port); 00098 } 00099 00100 void 00101 Service::openConnection( 00102 wns::service::tl::Port _dstPort, 00103 wns::service::nl::FQDN _source, 00104 wns::service::nl::FQDN _dstAddress, 00105 wns::service::qos::QoSClass _qosClass, 00106 wns::service::tl::ConnectionHandler* _ch) 00107 { 00108 assure(_dstPort >= 0 && _dstPort <= 65535, "Valid port numbers are: 0-65535 (is " << _dstPort << ")"); 00109 assure(_ch, "No valid ConnectionHandler provided (is NULL)"); 00110 assure(dns, "No DNS service is set"); 00111 00112 wns::service::tl::Port srcPort = portPool.suggestPort(); 00113 portPool.bind(srcPort); 00114 00115 wns::service::nl::Address source = dns->lookup(_source); 00116 wns::service::nl::Address destination = dns->lookup(_dstAddress); 00117 wns::service::tl::FlowID flowID(source, srcPort, destination, _dstPort); 00118 00119 flowIDToConnectionHandler.insert(flowID, _ch); 00120 00121 assure(!flowIDToConnections.knows(flowID), "Connection already created for flowID " << flowID); 00122 MESSAGE_SINGLE(NORMAL, logger, "TCP OpenConnection called for: " << flowID); 00123 00124 if(flowEstablishmentAndRelease == NULL) 00125 { 00126 openConnectionContinue(flowID, 0); 00127 } 00128 else 00129 { 00130 MESSAGE_SINGLE(NORMAL, logger, "Triggering FlowEstablishment at Layer2 for FlowID: " <<flowID); 00131 flowEstablishmentAndRelease->establishFlow(flowID,_qosClass); 00132 } 00133 } 00134 00135 void 00136 Service::openConnectionContinue(wns::service::tl::FlowID flowID, wns::service::dll::FlowID dllFlowID) 00137 { 00138 Connection* connection = new Connection( 00139 flowID, upperConvergence, this->pyco.get<wns::pyconfig::View>("connection")); 00140 00141 lowerConvergence->mapFlowID(flowID, dllFlowID); 00142 00143 assure(!flowIDToConnections.knows(flowID), "There is already a Connection for flowID "<< flowID); 00144 flowIDToConnections.insert(flowID, connection); 00145 00146 MESSAGE_SINGLE(NORMAL, logger, "Opening connection for FlowID " << flowID); 00147 assure(!listeners.knows(flowID.srcPort), "Unable to open source port " << flowID << " actively. Application is listening."); 00148 addFlowSeparatorInstance(flowID); 00149 00150 // get handshake fu from instance of flow separator according to flowID 00151 wns::ldk::ConstKeyPtr key(new FlowIDKey(flowID)); 00152 assure(flowSeparator->getInstance(key)!=NULL,"No flow created according to flowID " << flowID); 00153 HandshakeStrategyInterface* handshakeStrategy = getHandshakeStrategyFU(flowID); 00154 00155 handshakeStrategy->registerStrategyHandler(this); 00156 handshakeStrategy->activeOpen(flowID); 00157 } 00158 00159 void 00160 Service::dllFlowChanged(wns::service::tl::FlowID flowID, wns::service::dll::FlowID dllFlowID) 00161 { 00162 // delete old Flow, save new one 00163 lowerConvergence->unmapFlowID(flowID); 00164 lowerConvergence->mapFlowID(flowID, dllFlowID); 00165 } 00166 00167 void 00168 Service::passiveOpenConnection(const wns::service::tl::FlowID& _flowID) 00169 { 00170 wns::service::tl::ConnectionHandler* ch = listeners.find(_flowID.srcPort); 00171 00172 assure(!flowIDToConnectionHandler.knows(_flowID), "Connection Handler already registered for flowID " << _flowID); 00173 flowIDToConnectionHandler.insert(_flowID, ch); 00174 00175 assure(!flowIDToConnections.knows(_flowID), "Connection already created for flowID " << _flowID); 00176 Connection* connection = new Connection( 00177 _flowID, upperConvergence, this->pyco.get<wns::pyconfig::View>("connection")); 00178 00179 flowIDToConnections.insert(_flowID, connection); 00180 00181 wns::ldk::ConstKeyPtr key(new FlowIDKey(_flowID)); 00182 assure(flowSeparator->getInstance(key)!=NULL,"No flow created according to flowID " << _flowID); 00183 HandshakeStrategyInterface* handshakeStrategy = getHandshakeStrategyFU(_flowID); 00184 handshakeStrategy->registerStrategyHandler(this); 00185 handshakeStrategy->passiveOpen(_flowID); 00186 } 00187 00188 void 00189 Service::addFlowSeparatorInstance(const wns::service::tl::FlowID& _flowID) 00190 { 00191 MESSAGE_SINGLE(VERBOSE, this->logger, "Asking FlowSeparator to create instance for flowID: " << _flowID); 00192 // The instance must not be available! 00193 wns::ldk::ConstKeyPtr key(new FlowIDKey(_flowID)); 00194 assure(flowSeparator->getInstance(key) == NULL, "Instance of prototype flow separator already generated for flow id!"); 00195 flowSeparator->addInstance(key); 00196 } 00197 00198 HandshakeStrategyInterface* 00199 Service::getHandshakeStrategyFU(const wns::service::tl::FlowID& _flowID) 00200 { 00201 // get handshake fu from instance of flow separator according to flowID 00202 wns::ldk::ConstKeyPtr key(new FlowIDKey(_flowID)); 00203 assure(flowSeparator->getInstance(key)!=NULL, 00204 "No instance of flow separator created for flowID " << _flowID); 00205 HandshakeStrategyInterface* hs = dynamic_cast<HandshakeStrategyInterface*>( 00206 dynamic_cast<wns::ldk::Group*>( 00207 flowSeparator->getInstance(key))->getSubFUN()->getFunctionalUnit(pyco.get<std::string>("handshakeStrategy"))); 00208 00209 return hs; 00210 } 00211 00212 void 00213 Service::connectionEstablished(const wns::service::tl::FlowID& _flowID) 00214 { 00215 Connection* connection = flowIDToConnections.find(_flowID); 00216 00217 flowIDToConnectionHandler.find(_flowID)->onConnectionEstablished(_flowID.dstAddress, connection); 00218 MESSAGE_SINGLE(NORMAL, logger, "Connection established for flow id " << _flowID); 00219 } 00220 00221 void 00222 Service::closeConnection(wns::service::tl::Connection* _connection) 00223 { 00224 assure(_connection, "No valid Connection provided (is NULL)"); 00225 assureType(_connection, tcp::Connection*); 00226 00227 wns::service::tl::FlowID flowID = dynamic_cast<tcp::Connection*>(_connection)->getFlowID(); 00228 00229 HandshakeStrategyInterface* hs = getHandshakeStrategyFU(flowID); 00230 hs->closeConnection(flowID); 00231 } 00232 00233 void 00234 Service::setDataTransmissionService(wns::service::nl::Service* _ipService) 00235 { 00236 assure(!ipService, "ipService already set!"); 00237 assure(_ipService, "invalid ip service (NULL)"); 00238 00239 ipService = _ipService; 00240 00241 MESSAGE_SINGLE(NORMAL, logger, "IP services registered."); 00242 } 00243 00244 void 00245 Service::setTcpFlowHandlerService(tcp::FlowHandler* _flowHandler) 00246 { 00247 assure(_flowHandler, "invalid TcpFlowHandler service (NULL)!"); 00248 tcpFlowHandler = _flowHandler; 00249 MESSAGE_SINGLE(NORMAL, logger, "TcpFlowHandler service registered."); 00250 } 00251 00252 void 00253 Service::setDNSService(wns::service::nl::DNSService* _dns) 00254 { 00255 assure(!dns, "DNSService already set!"); 00256 assure(_dns, "invalid DNS service (NULL)"); 00257 00258 dns = _dns; 00259 00260 MESSAGE_SINGLE(NORMAL, logger, "DNS services registered."); 00261 } 00262 00263 bool 00264 Service::isListening(wns::service::tl::Port _port) 00265 { 00266 return listeners.knows(_port); 00267 } 00268 00269 wns::service::nl::Service* 00270 Service::getIPService() 00271 { 00272 return ipService; 00273 } 00274 00275 Connection* 00276 Service::getConnection(const wns::service::tl::FlowID& _flowID) 00277 { 00284 if(!flowIDToConnections.knows(_flowID)){ // server: first compound arrived 00289 passiveOpenConnection(_flowID); 00290 } 00291 00292 assure(flowIDToConnections.knows(_flowID), "No connection created for flowID " << _flowID); 00293 return flowIDToConnections.find(_flowID); 00294 } 00295 00296 bool 00297 Service::isValidFlow(const wns::ldk::ConstKeyPtr& _key) const 00298 { 00299 ConstFlowIDKeyPtr key = wns::dynamicCast<const FlowIDKey>(_key); 00300 wns::service::tl::FlowID flowID = key->flowID_; 00301 00302 MESSAGE_SINGLE(VERBOSE, logger, "isValidFlow(): flowID: " << flowID); 00303 00304 if(listeners.knows(flowID.srcPort)) 00305 { // server: incoming compound 00306 //const_cast<Service*>(this)->passiveOpenConnection(*flowID); 00307 return true; 00308 } 00309 else if(flowIDToConnections.knows(flowID)) 00310 { 00311 // no connection open on client side 00312 return true; 00313 } 00314 else 00315 { 00316 return false; 00317 } 00318 } 00319 00320 void 00321 Service::connectionClosed(const wns::service::tl::FlowID& _flowID) 00322 { 00323 assure(flowIDToConnections.knows(_flowID), "No connection created for flow id " << _flowID); 00324 Connection* _connection = flowIDToConnections.find(_flowID); 00325 assure(flowIDToConnectionHandler.knows(_flowID), "No connection handler registered for flow id " << _flowID); 00326 wns::service::tl::ConnectionHandler* ch = flowIDToConnectionHandler.find(_flowID); 00327 00328 if(listeners.knows(_flowID.srcPort)){ // server 00329 ch->onConnectionClosed(_connection); 00330 flowIDToConnectionHandler.erase(_flowID); 00331 flowIDToConnections.erase(_flowID); 00332 } 00333 else { // client 00334 ch->onConnectionClosed(_connection); 00335 flowIDToConnectionHandler.erase(_flowID); 00336 flowIDToConnections.erase(_flowID); 00337 portPool.unbind(_flowID.srcPort); 00338 } 00339 00340 wns::simulator::getEventScheduler()->scheduleNow(RemoveFlowSeparatorInstance(this, _flowID)); 00341 // release the flow in layer 2 00342 lowerConvergence->unmapFlowID(_flowID); 00343 00344 if(!(flowEstablishmentAndRelease == NULL)) 00345 { 00346 MESSAGE_SINGLE(NORMAL, logger, "Deleting DLLFlow for TlFlowID: " <<_flowID); 00347 flowEstablishmentAndRelease->releaseFlow(_flowID); 00348 } 00349 00350 // release flow in layer 2 only if there is a layer 2 at this peer 00351 delete _connection; 00352 } 00353 00354 void 00355 Service::passiveClosed(const wns::service::tl::FlowID& _flowID) 00356 { 00357 assure(flowIDToConnections.knows(_flowID), "No connection created for flow id " << _flowID); 00358 Connection* _connection = flowIDToConnections.find(_flowID); 00359 assure(flowIDToConnectionHandler.knows(_flowID), "No connection handler registered for flow id " << _flowID); 00360 wns::service::tl::ConnectionHandler* ch = flowIDToConnectionHandler.find(_flowID); 00361 00362 ch->onConnectionClosedByPeer(_connection); 00363 flowIDToConnectionHandler.erase(_flowID); 00364 flowIDToConnections.erase(_flowID); 00365 00366 wns::simulator::getEventScheduler()->scheduleNow(RemoveFlowSeparatorInstance(this, _flowID)); 00367 // the right place to release the flow in layer 2 00368 // release flow in layer 2 only if there is a layer 2 at this peer 00369 delete _connection; 00370 } 00371 void 00372 Service::deleteFlowSeparatorInstance(const wns::service::tl::FlowID& _flowID) 00373 { 00374 wns::ldk::ConstKeyPtr key(new FlowIDKey(_flowID)); 00375 assure(flowSeparator->getInstance(key)!=NULL, "No instance with flowID " << _flowID); 00376 flowSeparator->removeInstance(key); 00377 }
1.5.5