00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef _TCPTUNNEL_H_
00018 #define _TCPTUNNEL_H_
00019
00020 #include <map>
00021 #include <dtn_api.h>
00022
00023 #include <oasys/debug/Log.h>
00024 #include <oasys/io/TCPClient.h>
00025 #include <oasys/io/TCPServer.h>
00026 #include <oasys/thread/MsgQueue.h>
00027 #include <oasys/thread/Thread.h>
00028 #include <oasys/util/ExpandableBuffer.h>
00029
00030 #include "IPTunnel.h"
00031
00032 namespace dtntunnel {
00033
00037 class TCPTunnel : public IPTunnel {
00038 public:
00040 TCPTunnel();
00041
00044 void add_listener(in_addr_t listen_addr, u_int16_t listen_port,
00045 in_addr_t remote_addr, u_int16_t remote_port);
00046
00048 void handle_bundle(dtn::APIBundle* bundle);
00049
00050 protected:
00052 class Listener : public oasys::TCPServerThread {
00053 public:
00054 Listener(TCPTunnel* t,
00055 in_addr_t listen_addr, u_int16_t listen_port,
00056 in_addr_t remote_addr, u_int16_t remote_port);
00057
00058 void accepted(int fd, in_addr_t addr, u_int16_t port);
00059
00060 protected:
00061 TCPTunnel* tcptun_;
00062
00065 in_addr_t listen_addr_;
00066 u_int16_t listen_port_;
00067 in_addr_t remote_addr_;
00068 u_int16_t remote_port_;
00070 };
00071
00073 class Connection : public oasys::Formatter,
00074 public oasys::Thread,
00075 public oasys::Logger
00076 {
00077 public:
00080 Connection(TCPTunnel* t, dtn_endpoint_id_t* dest_eid,
00081 in_addr_t client_addr, u_int16_t client_port,
00082 in_addr_t remote_addr, u_int16_t remote_port,
00083 u_int32_t connection_id);
00084
00086 Connection(TCPTunnel* t, dtn_endpoint_id_t* dest_eid, int fd,
00087 in_addr_t client_addr, u_int16_t client_port,
00088 in_addr_t remote_addr, u_int16_t remote_port,
00089 u_int32_t connection_id);
00090
00092 ~Connection();
00093
00095 int format(char* buf, size_t sz) const;
00096
00098 void handle_bundle(dtn::APIBundle* bundle);
00099
00100 protected:
00101 friend class TCPTunnel;
00102
00104 void run();
00105
00107 TCPTunnel* tcptun_;
00108
00110 oasys::TCPClient sock_;
00111
00113 dtn::APIBundleQueue queue_;
00114
00116 typedef std::map<u_int32_t, dtn::APIBundle*> ReorderTable;
00117 ReorderTable reorder_table_;
00118
00120 u_int32_t next_seqno_;
00121
00123 dtn_endpoint_id_t dest_eid_;
00124 in_addr_t client_addr_;
00125 u_int16_t client_port_;
00126 in_addr_t remote_addr_;
00127 u_int16_t remote_port_;
00128 u_int32_t connection_id_;
00129 };
00130
00132 u_int32_t next_connection_id();
00133
00135 void new_connection(Connection* c);
00136
00138 void kill_connection(Connection* c);
00139
00141 struct ConnKey {
00142 ConnKey()
00143 : endpoint_id_(""),
00144 client_addr_(INADDR_NONE), client_port_(0),
00145 remote_addr_(INADDR_NONE), remote_port_(0),
00146 connection_id_(0) {}
00147
00148 ConnKey(const dtn_endpoint_id_t& eid,
00149 in_addr_t client_addr, u_int16_t client_port,
00150 in_addr_t remote_addr, u_int16_t remote_port,
00151 u_int32_t connection_id)
00152 : endpoint_id_(eid.uri),
00153 client_addr_(client_addr),
00154 client_port_(client_port),
00155 remote_addr_(remote_addr),
00156 remote_port_(remote_port),
00157 connection_id_(connection_id) {}
00158
00159 bool operator<(const ConnKey& other) const
00160 {
00161 #define COMPARE(_x) if (_x != other._x) return _x < other._x;
00162 COMPARE(connection_id_);
00163 COMPARE(client_addr_);
00164 COMPARE(client_port_);
00165 COMPARE(remote_addr_);
00166 COMPARE(remote_port_);
00167 #undef COMPARE
00168
00169 return endpoint_id_ < other.endpoint_id_;
00170 }
00171
00172 std::string endpoint_id_;
00173 in_addr_t client_addr_;
00174 u_int16_t client_port_;
00175 in_addr_t remote_addr_;
00176 u_int16_t remote_port_;
00177 u_int32_t connection_id_;
00178 };
00179
00181 typedef std::map<ConnKey, Connection*> ConnTable;
00182 ConnTable connections_;
00183
00186 typedef std::map<ConnKey, dtn::APIBundleVector*> NoConnBundleTable;
00187 NoConnBundleTable no_conn_bundles_;
00188
00190 oasys::SpinLock lock_;
00191
00193 u_int32_t next_connection_id_;
00194 };
00195
00196 }
00197
00198 #endif