An Overlay-based
Virtual Network Substrate
SpoVNet

source: trash/old-modules/transport/protlib/tp_over_tls_tcp.h @ 5641

Last change on this file since 5641 was 5641, checked in by Christoph Mayer, 14 years ago
File size: 9.0 KB
Line 
1/// ----------------------------------------*- mode: C++; -*--
2/// @file tp_over_tls_tcp.h
3/// Transport over TLS/TCP
4/// ----------------------------------------------------------
5/// $Id: tp_over_tls_tcp.h 2872 2008-02-18 10:58:03Z bless $
6/// $HeadURL: https://svn.ipv6.tm.uka.de/nsis/protlib/trunk/include/tp_over_tls_tcp.h $
7// ===========================================================
8//                     
9// Copyright (C) 2005-2007, all rights reserved by
10// - Institute of Telematics, Universitaet Karlsruhe (TH)
11//
12// More information and contact:
13// https://projekte.tm.uka.de/trac/NSIS
14//                     
15// This program is free software; you can redistribute it and/or modify
16// it under the terms of the GNU General Public License as published by
17// the Free Software Foundation; version 2 of the License
18//
19// This program is distributed in the hope that it will be useful,
20// but WITHOUT ANY WARRANTY; without even the implied warranty of
21// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22// GNU General Public License for more details.
23//
24// You should have received a copy of the GNU General Public License along
25// with this program; if not, write to the Free Software Foundation, Inc.,
26// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27//
28// ===========================================================
29/** @ingroup transport
30 * @file tp_over_tls_tcp.h
31 * TP over TLS/TCP
32 */
33
34#ifndef TP_OVER_TLS_H
35#define TP_OVER_TLS_H
36
37#include <ext/hash_map>
38
39#include "tp.h"
40#include "threads.h"
41#include "threadsafe_db.h"
42#include "connectionmap.h"
43#include "assocdata.h"
44
45#include <openssl/ssl.h>
46#include <openssl/err.h>
47#include <openssl/evp.h>
48
49
50namespace protlib
51{
52
53/** this struct contains parameters that determine
54  * the behavior of listener and receiver threads in TPoverTLS_TCP
55  * @param port - port number for master listener thread (server port)
56  * @param sleep - time (in ms) that listener and receiver wait at a poll() call
57  * @param d - destination module, where internal message are sent
58  */
59struct TPoverTLS_TCPParam : public ThreadParam
60{
61  /// constructor
62  TPoverTLS_TCPParam(
63        const char* client_cert_filename,
64        const char* client_privkey_filename,
65        const char* root_cert_filename,
66        unsigned short common_header_length,
67        bool (*const getmsglength) (NetMsg& m, uint32& clen_bytes),
68        port_t p,
69        const char* threadname= "TPoverTLS_TCP",
70        uint32 sleep = ThreadParam::default_sleep_time,
71        bool debug_pdu = false,
72        message::qaddr_t source = message::qaddr_tp_over_tls_tcp,
73        message::qaddr_t dest = message::qaddr_signaling,
74        bool sendaborts = false,
75        uint8 tos = 0x10) :
76        ThreadParam(sleep,threadname,1,1),
77        port(p),
78        debug_pdu(debug_pdu),
79        source(source),
80        dest(dest),
81        common_header_length(common_header_length),
82        client_cert_filename(client_cert_filename),
83        client_privkey_filename(client_privkey_filename),
84        root_cert_filename(root_cert_filename),
85        getmsglength(getmsglength),
86        terminate(false),
87        ip_tos(tos)
88  {
89   
90    //set up SSL
91    ssl_ctx_client = SSL_CTX_new(TLSv1_client_method());
92    ssl_ctx_server = SSL_CTX_new(TLSv1_server_method());
93   
94  };
95
96  /// to bind master listener thread to
97  const port_t port;
98  bool debug_pdu;
99
100  /// message source
101  const message::qaddr_t source;
102  const message::qaddr_t dest;
103
104  /// what is the length of the common header
105  const unsigned short common_header_length;
106   
107  /// holds SSL context
108  SSL_CTX *ssl_ctx_client;
109  SSL_CTX *ssl_ctx_server;
110
111  const char* client_cert_filename;
112  const char* client_privkey_filename;
113  const char* root_cert_filename;
114 
115  /// function pointer to a function that figures out the msg length in number of 4 byte words
116  /// it returns false if error occured (e.g., malformed header), result is returned in variable clen_words
117  bool (*const getmsglength) (NetMsg& m, uint32& clen_words);
118 
119  /// should master thread terminate?
120  const bool terminate;
121  const uint8 ip_tos;
122}; // end TPoverTLS_TCPParam
123
124
125typedef hash_map<uint32, SSL*> sslmap_t;
126
127/// TP over TCP
128/** This class implements the TP interface using TCP. */
129class TPoverTLS_TCP : public TP, public Thread
130{
131/***** inherited from TP *****/
132public:
133  /// sends a network message, spawns receiver thread if necessary
134  virtual void send(NetMsg* msg,const address& addr, bool use_existing_connection);
135  virtual void terminate(const address& addr);
136 
137  /***** inherited from Thread *****/
138public:
139  /// main loop
140  virtual void main_loop(uint32 nr);
141 
142/***** other members *****/
143public:
144  /// constructor
145  TPoverTLS_TCP(const TPoverTLS_TCPParam& p) :
146    TP(prot_tls_tcp,"TLS",p.name,p.common_header_length,p.getmsglength),
147    Thread(p), tpparam(p), already_aborted(false), msgqueue(NULL), debug_pdu(p.debug_pdu)
148  { 
149    // perform some initializing actions
150    // currently not required (SCTP had to init its library)
151    init= true; ///< init done;
152   
153   
154    sslmap.resize(128);
155
156  }
157  /// virtual destructor
158  virtual ~TPoverTLS_TCP();
159 
160  typedef
161  struct receiver_thread_arg
162  {
163    const AssocData* peer_assoc;
164    bool sig_terminate;
165    bool terminated;
166  public:
167    receiver_thread_arg(const AssocData* peer_assoc) : 
168      peer_assoc(peer_assoc), sig_terminate(false), terminated(true) {};
169  } receiver_thread_arg_t;
170 
171  class receiver_thread_start_arg_t
172  {
173  public:
174    TPoverTLS_TCP* instance;
175    receiver_thread_arg_t* rtargp;
176   
177    receiver_thread_start_arg_t(TPoverTLS_TCP* instance, receiver_thread_arg_t* rtargp) :
178      instance(instance), rtargp(rtargp) {};
179  };
180
181  class sender_thread_start_arg_t
182  {
183  public:
184    TPoverTLS_TCP* instance;
185    FastQueue* sender_thread_queue;
186   
187    sender_thread_start_arg_t(TPoverTLS_TCP* instance, FastQueue* sq) :
188      instance(instance), sender_thread_queue(sq) {};
189  };
190 
191private:
192  /// returns already existing connection or establishes a new one
193  AssocData* get_connection_to(const appladdress& addr);
194   
195  static const char *SSLerrmessage(void);
196
197  /// receiver thread for a specific socket
198  void sender_thread(void *argp);
199   
200  /// receiver thread for a specific socket
201  void receiver_thread(void *argp);
202   
203  /// send a message to the network via TCP+TLS
204  void tcptlssend(NetMsg* msg, appladdress* addr);
205   
206  /// sender thread starter for a specific socket
207  static void* sender_thread_starter(void *argp);
208   
209  /// receiver thread starter for a specific socket
210  static void* receiver_thread_starter(void *argp);
211   
212  /// a static starter method to invoke the actual main listener
213  static void* master_listener_thread_starter(void *argp);
214   
215  /// main listener thread procedure
216  void master_listener_thread();
217   
218  // create and start new sender thread
219  void create_new_sender_thread(FastQueue* senderqueue);
220   
221  // create and start new receiver thread
222  void create_new_receiver_thread(AssocData* peer_assoc);
223   
224  /// terminates particular thread
225  void stop_receiver_thread(AssocData* peer_assoc);
226   
227  /// cleans up thread management structures
228  void cleanup_receiver_thread(AssocData* peer_assoc);
229   
230  /// terminates a sender thread
231  void terminate_sender_thread(const AssocData* assoc);
232   
233  /// terminates all active receiver or sender threads
234  void terminate_all_threads();
235   
236  /// ConnectionMap instance for keeping track of all existing connections
237  ConnectionMap connmap;
238   
239   
240  /// SSL Context
241  SSL_CTX *ssl_ctx;
242   
243  /// store per receiver thread arguments, e.g. for signaling termination
244  typedef hash_map<pthread_t, receiver_thread_arg_t*> recv_thread_argmap_t;
245  recv_thread_argmap_t  recv_thread_argmap;
246
247  /// store sender thread related information
248  typedef hash_map<appladdress, FastQueue*> sender_thread_queuemap_t;
249  sender_thread_queuemap_t  senderthread_queuemap;
250   
251  /// parameters for main TPoverTLS_TCP thread
252  const TPoverTLS_TCPParam tpparam;
253   
254  /// did we already abort at thread shutdown
255  bool already_aborted;
256  /// message queue
257  FastQueue* msgqueue;
258   
259  bool debug_pdu;
260
261  /// holds socket<->SSL pointer assignment
262  sslmap_t sslmap;
263   
264}; // end class TPoverTLS_TCP
265
266/** A simple internal message for selfmessages
267 * please note that carried items may get deleted after use of this message
268 * the message destructor does not delete any item automatically
269 */
270class TPoverTLS_TCPMsg : public message
271{
272 public:
273  // message type start/stop thread, send data
274  enum msg_t { start, 
275               stop,
276               send_data
277  };
278
279 private:
280  const AssocData* peer_assoc;
281  const TPoverTLS_TCPMsg::msg_t type;
282  NetMsg* netmsg;
283  appladdress* addr;
284
285public:
286  TPoverTLS_TCPMsg(const AssocData* peer_assoc, message::qaddr_t source= qaddr_unknown, TPoverTLS_TCPMsg::msg_t type= stop) : 
287    message(type_transport, source), peer_assoc(peer_assoc), type(type), netmsg(0), addr(0)  {}
288
289  TPoverTLS_TCPMsg(NetMsg* netmsg, appladdress* addr, message::qaddr_t source= qaddr_unknown) : 
290    message(type_transport, source), peer_assoc(0), type(send_data), netmsg(netmsg), addr(addr) {}
291
292  const AssocData* get_peer_assoc() const { return peer_assoc; }
293  TPoverTLS_TCPMsg::msg_t get_msgtype() const { return type; }
294  NetMsg* get_netmsg() const { return netmsg; }
295  appladdress* get_appladdr() const { return addr; } 
296};
297
298} // end namespace protlib
299
300#endif
Note: See TracBrowser for help on using the repository browser.