IBR-DTNSuite 0.6

daemon/src/net/TCPConvergenceLayer.h

Go to the documentation of this file.
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_ */