|
IBR-DTNSuite 0.6
|
00001 /* 00002 * TCPConvergenceLayer.h 00003 * 00004 * Created on: 05.08.2009 00005 * Author: morgenro 00006 */ 00007 00008 #ifndef TCPCONVERGENCELAYER_H_ 00009 #define TCPCONVERGENCELAYER_H_ 00010 00011 #include "config.h" 00012 #include "Component.h" 00013 00014 #include "core/NodeEvent.h" 00015 #include "core/Node.h" 00016 #include "net/ConvergenceLayer.h" 00017 #include "net/DiscoveryService.h" 00018 #include "net/DiscoveryServiceProvider.h" 00019 00020 #include <ibrdtn/data/Bundle.h> 00021 #include <ibrdtn/data/EID.h> 00022 #include <ibrdtn/data/MetaBundle.h> 00023 #include <ibrdtn/data/Serializer.h> 00024 #include <ibrdtn/streams/StreamConnection.h> 00025 #include <ibrdtn/streams/StreamContactHeader.h> 00026 00027 #include <ibrcommon/net/tcpserver.h> 00028 #include <ibrcommon/net/tcpstream.h> 00029 #include <ibrcommon/net/vinterface.h> 00030 #include <ibrcommon/thread/Queue.h> 00031 #include <memory> 00032 00033 #ifdef WITH_TLS 00034 #include <ibrcommon/net/TLSStream.h> 00035 #endif 00036 00037 using namespace dtn::streams; 00038 00039 namespace dtn 00040 { 00041 namespace net 00042 { 00043 class TCPConvergenceLayer; 00044 00045 class TCPConnection : public StreamConnection::Callback, public ibrcommon::DetachedThread 00046 { 00047 public: 00056 TCPConnection(TCPConvergenceLayer &tcpsrv, ibrcommon::tcpstream *stream, const dtn::data::EID &name, const size_t timeout = 10); 00057 00066 TCPConnection(TCPConvergenceLayer &tcpsrv, const dtn::core::Node &node, const dtn::data::EID &name, const size_t timeout = 10); 00067 00072 virtual ~TCPConnection(); 00073 00077 virtual void initialize(); 00078 00082 void shutdown(); 00083 00088 const StreamContactHeader& getHeader() const; 00089 00094 const dtn::core::Node& getNode() const; 00095 00099 virtual void eventShutdown(StreamConnection::ConnectionShutdownCases csc); 00100 virtual void eventTimeout(); 00101 virtual void eventError(); 00102 virtual void eventConnectionUp(const StreamContactHeader &header); 00103 virtual void eventConnectionDown(); 00104 00105 virtual void eventBundleRefused(); 00106 virtual void eventBundleForwarded(); 00107 virtual void eventBundleAck(size_t ack); 00108 00109 dtn::core::Node::Protocol getDiscoveryProtocol() const; 00110 00115 void queue(const dtn::data::BundleID &bundle); 00116 00117 bool match(const dtn::core::Node &n) const; 00118 bool match(const dtn::data::EID &destination) const; 00119 bool match(const dtn::core::NodeEvent &evt) const; 00120 00121 friend TCPConnection& operator>>(TCPConnection &conn, dtn::data::Bundle &bundle); 00122 friend TCPConnection& operator<<(TCPConnection &conn, const dtn::data::Bundle &bundle); 00123 00124 #ifdef WITH_TLS 00125 00128 void enableTLS(); 00129 #endif 00130 00131 protected: 00132 void rejectTransmission(); 00133 00134 void setup(); 00135 void run(); 00136 void finally(); 00137 bool __cancellation(); 00138 00139 void clearQueue(); 00140 00141 void keepalive(); 00142 bool good() const; 00143 00144 private: 00145 class Sender : public ibrcommon::JoinableThread, public ibrcommon::Queue<dtn::data::BundleID> 00146 { 00147 public: 00148 Sender(TCPConnection &connection, size_t &keepalive_timeout); 00149 virtual ~Sender(); 00150 00151 protected: 00152 void run(); 00153 void finally(); 00154 bool __cancellation(); 00155 00156 private: 00157 TCPConnection &_connection; 00158 size_t &_keepalive_timeout; 00159 dtn::data::BundleID _current_transfer; 00160 }; 00161 00162 StreamContactHeader _peer; 00163 dtn::core::Node _node; 00164 00165 std::auto_ptr<ibrcommon::tcpstream> _tcpstream; 00166 StreamConnection _stream; 00167 00168 #ifdef WITH_TLS 00169 ibrcommon::TLSStream _tlsstream; 00170 #endif 00171 00172 // This thread gets awaiting bundles of the queue 00173 // and transmit them to the peer. 00174 Sender _sender; 00175 00176 // handshake variables 00177 dtn::data::EID _name; 00178 size_t _timeout; 00179 00180 ibrcommon::Queue<dtn::data::MetaBundle> _sentqueue; 00181 size_t _lastack; 00182 size_t _keepalive_timeout; 00183 00184 TCPConvergenceLayer &_callback; 00185 00186 /* flags to be used in this nodes StreamContactHeader */ 00187 char _flags; 00188 }; 00189 00194 class TCPConvergenceLayer : public dtn::daemon::IndependentComponent, public ConvergenceLayer, public DiscoveryServiceProvider 00195 { 00196 friend class TCPConnection; 00197 public: 00203 TCPConvergenceLayer(); 00204 00208 virtual ~TCPConvergenceLayer(); 00209 00215 void bind(const ibrcommon::vinterface &net, int port); 00216 00221 void queue(const dtn::core::Node &n, const ConvergenceLayer::Job &job); 00222 00228 void open(const dtn::core::Node &n); 00229 00233 virtual const std::string getName() const; 00234 00239 dtn::core::Node::Protocol getDiscoveryProtocol() const; 00240 00244 void update(const ibrcommon::vinterface &iface, std::string &name, std::string &data) throw(dtn::net::DiscoveryServiceProvider::NoServiceHereException); 00245 00246 protected: 00247 bool __cancellation(); 00248 00249 void componentUp(); 00250 void componentRun(); 00251 void componentDown(); 00252 00253 private: 00257 void closeAll(); 00258 00263 void connectionUp(TCPConnection *conn); 00264 00270 void connectionDown(TCPConnection *conn); 00271 00272 static const int DEFAULT_PORT; 00273 bool _running; 00274 00275 ibrcommon::tcpserver _tcpsrv; 00276 00277 ibrcommon::Conditional _connections_cond; 00278 std::list<TCPConnection*> _connections; 00279 std::list<ibrcommon::vinterface> _interfaces; 00280 std::map<ibrcommon::vinterface, unsigned int> _portmap; 00281 }; 00282 } 00283 } 00284 00285 #endif /* TCPCONVERGENCELAYER_H_ */