MFEM  v3.3.2
Finite element discretization library
socketstream.hpp
Go to the documentation of this file.
1 // Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at
2 // the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
3 // reserved. See file COPYRIGHT for details.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability see http://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the GNU Lesser General Public License (as published by the Free
10 // Software Foundation) version 2.1 dated February 1999.
11 
12 #ifndef MFEM_SOCKETSTREAM
13 #define MFEM_SOCKETSTREAM
14 
15 #include "../config/config.hpp"
16 #include "error.hpp"
17 #include "globals.hpp"
18 
19 #ifdef MFEM_USE_GNUTLS
20 #include <gnutls/gnutls.h>
21 #if GNUTLS_VERSION_NUMBER < 0x020800
22 #error "MFEM requires GnuTLS version >= 2.8.0"
23 #endif
24 #endif
25 
26 namespace mfem
27 {
28 
29 class socketbuf : public std::streambuf
30 {
31 protected:
33  static const int buflen = 1024;
35 
36 public:
38  {
39  socket_descriptor = -1;
40  }
41 
42  explicit socketbuf(int sd)
43  {
44  socket_descriptor = sd;
45  setp(obuf, obuf + buflen);
46  }
47 
48  socketbuf(const char hostname[], int port)
49  {
50  socket_descriptor = -1;
51  open(hostname, port);
52  }
53 
54  /** Attach a new socket descriptor to the socketbuf.
55  Returns the old socket descriptor which is NOT closed. */
56  virtual int attach(int sd);
57 
58  int detach() { return attach(-1); }
59 
60  virtual int open(const char hostname[], int port);
61 
62  virtual int close();
63 
65 
66  bool is_open() { return (socket_descriptor >= 0); }
67 
68  virtual ~socketbuf() { close(); }
69 
70 protected:
71  virtual int sync();
72 
73  virtual int_type underflow();
74 
75  virtual int_type overflow(int_type c = traits_type::eof());
76 
77  virtual std::streamsize xsgetn(char_type *__s, std::streamsize __n);
78 
79  virtual std::streamsize xsputn(const char_type *__s, std::streamsize __n);
80 };
81 
82 
83 #ifdef MFEM_USE_GNUTLS
84 
86 {
87 protected:
88  int res;
89 
90 public:
91  GnuTLS_status() : res(GNUTLS_E_SUCCESS) { }
92 
93  bool good() const { return (res == GNUTLS_E_SUCCESS); }
94 
95  void set_result(int result) { res = result; }
96 
97  int get_result() const { return res; }
98 
99  void print_on_error(const char *msg) const
100  {
101  if (good()) { return; }
102  mfem::out << "Error in " << msg << ": " << gnutls_strerror(res)
103  << std::endl;
104  }
105 };
106 
108 {
109 protected:
110  gnutls_dh_params_t dh_params;
112 
113  void generate_dh_params();
114 
115 public:
118 
120 
121  void set_log_level(int level)
122  { if (status.good()) { gnutls_global_set_log_level(level); } }
123 
124  gnutls_dh_params_t get_dh_params()
125  {
126  if (!dh_params) { generate_dh_params(); }
127  return dh_params;
128  }
129 };
130 
132 {
133 protected:
134  gnutls_certificate_credentials_t my_cred;
135  unsigned int my_flags;
136 
137 public:
140 
142  const char *pubkey_file,
143  const char *privkey_file,
144  const char *trustedkeys_file,
145  unsigned int flags);
147  {
148  if (my_cred) { gnutls_certificate_free_credentials(my_cred); }
149  }
150 
151  gnutls_certificate_credentials_t get_cred() const { return my_cred; }
152  unsigned int get_flags() const { return my_flags; }
153 };
154 
156 {
157 protected:
159  gnutls_session_t session;
161 
163  gnutls_certificate_credentials_t my_cred; // same as params.my_cred
164 
165  void handshake();
166  void start_session();
167  void end_session();
168 
169 public:
171  : session_started(false), params(p), my_cred(params.get_cred())
172  { status.set_result(params.status.get_result()); }
173 
174  virtual ~GnuTLS_socketbuf() { close(); }
175 
176  bool gnutls_good() const { return status.good(); }
177 
178  /** Attach a new socket descriptor to the socketbuf.
179  Returns the old socket descriptor which is NOT closed. */
180  virtual int attach(int sd);
181 
182  virtual int open(const char hostname[], int port);
183 
184  virtual int close();
185 
186 protected:
187  virtual int sync();
188 
189  virtual int_type underflow();
190 
191  // Same as in the base class:
192  // virtual int_type overflow(int_type c = traits_type::eof());
193 
194  virtual std::streamsize xsgetn(char_type *__s, std::streamsize __n);
195 
196  virtual std::streamsize xsputn(const char_type *__s, std::streamsize __n);
197 };
198 
199 #endif // MFEM_USE_GNUTLS
200 
201 class socketstream : public std::iostream
202 {
203 protected:
206 
207  void set_socket(bool secure);
208  inline void check_secure_socket();
209 #ifdef MFEM_USE_GNUTLS
210  static int num_glvis_sockets;
214  static void remove_socket();
215  inline void set_secure_socket(const GnuTLS_session_params &p);
216 #endif
217 
218 public:
219 #ifdef MFEM_USE_GNUTLS
220  static const bool secure_default = true;
221 #else
222  static const bool secure_default = false;
223 #endif
224 
225  /** @brief Create a socket stream without connecting to a host.
226 
227  If 'secure' is true, (GnuTLS support must be enabled) then the connection
228  will use GLVis client session keys from ~/.config/glvis/client for GnuTLS
229  identification. If you want to use other GnuTLS session keys or
230  parameters, use the constructor from GnuTLS_session_params. */
231  socketstream(bool secure = secure_default);
232 
233  /** @brief Create a socket stream associated with the given socket buffer.
234  The new object takes ownership of 'buf'. */
235  explicit socketstream(socketbuf *buf)
236  : std::iostream(buf), buf__(buf), glvis_client(false) { }
237 
238  /** @brief Create a socket stream and associate it with the given socket
239  descriptor 's'. The treatment of the 'secure' flag is similar to that in
240  the default constructor. */
241  explicit socketstream(int s, bool secure = secure_default);
242 
243  /** @brief Create a socket stream and connect to the given host and port.
244  The treatment of the 'secure' flag is similar to that in the default
245  constructor. */
246  socketstream(const char hostname[], int port, bool secure = secure_default)
247  : std::iostream(0) { set_socket(secure); open(hostname, port); }
248 
249 #ifdef MFEM_USE_GNUTLS
250  /// Create a secure socket stream using the given GnuTLS_session_params.
251  explicit socketstream(const GnuTLS_session_params &p);
252 #endif
253 
254  socketbuf *rdbuf() { return buf__; }
255 
256  int open(const char hostname[], int port);
257 
258  int close() { return buf__->close(); }
259 
260  bool is_open() { return buf__->is_open(); }
261 
262  virtual ~socketstream();
263 };
264 
265 
267 {
268 private:
269  int listen_socket;
270 
271 public:
272  explicit socketserver(int port, int backlog=4);
273 
274  bool good() { return (listen_socket >= 0); }
275 
276  int close();
277 
278  int accept();
279 
280  int accept(socketstream &sockstr);
281 
283 };
284 
285 } // namespace mfem
286 
287 #endif
void set_result(int result)
static GnuTLS_session_params * params
virtual int attach(int sd)
socketstream(socketbuf *buf)
Create a socket stream associated with the given socket buffer. The new object takes ownership of 'bu...
virtual int_type underflow()
static int num_glvis_sockets
gnutls_certificate_credentials_t my_cred
virtual std::streamsize xsgetn(char_type *__s, std::streamsize __n)
bool gnutls_good() const
char ibuf[buflen]
virtual ~socketbuf()
GnuTLS_session_params(GnuTLS_global_state &state, const char *pubkey_file, const char *privkey_file, const char *trustedkeys_file, unsigned int flags)
socketbuf * rdbuf()
int getsocketdescriptor()
gnutls_session_t session
gnutls_certificate_credentials_t my_cred
void set_socket(bool secure)
gnutls_dh_params_t get_dh_params()
STL namespace.
socketstream(const char hostname[], int port, bool secure=secure_default)
Create a socket stream and connect to the given host and port. The treatment of the 'secure' flag is ...
int get_result() const
gnutls_dh_params_t dh_params
bool good() const
virtual int close()
virtual int open(const char hostname[], int port)
socketstream(bool secure=secure_default)
Create a socket stream without connecting to a host.
char obuf[buflen]
virtual int_type underflow()
gnutls_certificate_credentials_t get_cred() const
void set_secure_socket(const GnuTLS_session_params &p)
static GnuTLS_session_params & add_socket()
virtual int_type overflow(int_type c=traits_type::eof())
virtual int attach(int sd)
GnuTLS_socketbuf(const GnuTLS_session_params &p)
void print_on_error(const char *msg) const
virtual std::streamsize xsgetn(char_type *__s, std::streamsize __n)
GnuTLS_global_state & state
virtual int sync()
virtual std::streamsize xsputn(const char_type *__s, std::streamsize __n)
virtual std::streamsize xsputn(const char_type *__s, std::streamsize __n)
virtual int open(const char hostname[], int port)
static const int buflen
socketserver(int port, int backlog=4)
socketbuf(const char hostname[], int port)
int open(const char hostname[], int port)
static void remove_socket()
const GnuTLS_session_params & params
unsigned int get_flags() const
static const bool secure_default
static GnuTLS_global_state * state
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
Definition: globals.hpp:64
void set_log_level(int level)