MFEM  v3.4
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 // Use X.509 certificates: (comment out to use OpenPGP keys)
25 #define MFEM_USE_GNUTLS_X509
26 #endif
27 
28 namespace mfem
29 {
30 
31 class socketbuf : public std::streambuf
32 {
33 protected:
35  static const int buflen = 1024;
37 
38 public:
40  {
41  socket_descriptor = -1;
42  }
43 
44  explicit socketbuf(int sd)
45  {
46  socket_descriptor = sd;
47  setp(obuf, obuf + buflen);
48  }
49 
50  socketbuf(const char hostname[], int port)
51  {
52  socket_descriptor = -1;
53  open(hostname, port);
54  }
55 
56  /** Attach a new socket descriptor to the socketbuf.
57  Returns the old socket descriptor which is NOT closed. */
58  virtual int attach(int sd);
59 
60  int detach() { return attach(-1); }
61 
62  virtual int open(const char hostname[], int port);
63 
64  virtual int close();
65 
67 
68  bool is_open() { return (socket_descriptor >= 0); }
69 
70  virtual ~socketbuf() { close(); }
71 
72 protected:
73  virtual int sync();
74 
75  virtual int_type underflow();
76 
77  virtual int_type overflow(int_type c = traits_type::eof());
78 
79  virtual std::streamsize xsgetn(char_type *__s, std::streamsize __n);
80 
81  virtual std::streamsize xsputn(const char_type *__s, std::streamsize __n);
82 };
83 
84 
85 #ifdef MFEM_USE_GNUTLS
86 
88 {
89 protected:
90  int res;
91 
92 public:
93  GnuTLS_status() : res(GNUTLS_E_SUCCESS) { }
94 
95  bool good() const { return (res == GNUTLS_E_SUCCESS); }
96 
97  void set_result(int result) { res = result; }
98 
99  int get_result() const { return res; }
100 
101  void print_on_error(const char *msg) const
102  {
103  if (good()) { return; }
104  mfem::out << "Error in " << msg << ": " << gnutls_strerror(res)
105  << std::endl;
106  }
107 };
108 
110 {
111 protected:
112  gnutls_dh_params_t dh_params;
114 
115  void generate_dh_params();
116 
117 public:
120 
122 
123  void set_log_level(int level)
124  { if (status.good()) { gnutls_global_set_log_level(level); } }
125 
126  gnutls_dh_params_t get_dh_params()
127  {
128  if (!dh_params) { generate_dh_params(); }
129  return dh_params;
130  }
131 };
132 
134 {
135 protected:
136  gnutls_certificate_credentials_t my_cred;
137  unsigned int my_flags;
138 
139 public:
142 
144  const char *pubkey_file,
145  const char *privkey_file,
146  const char *trustedkeys_file,
147  unsigned int flags);
149  {
150  if (my_cred) { gnutls_certificate_free_credentials(my_cred); }
151  }
152 
153  gnutls_certificate_credentials_t get_cred() const { return my_cred; }
154  unsigned int get_flags() const { return my_flags; }
155 };
156 
158 {
159 protected:
161  gnutls_session_t session;
163 
165  gnutls_certificate_credentials_t my_cred; // same as params.my_cred
166 
167  void handshake();
168  void start_session();
169  void end_session();
170 
171 public:
173  : session_started(false), params(p), my_cred(params.get_cred())
175 
176  virtual ~GnuTLS_socketbuf() { close(); }
177 
178  bool gnutls_good() const { return status.good(); }
179 
180  /** Attach a new socket descriptor to the socketbuf.
181  Returns the old socket descriptor which is NOT closed. */
182  virtual int attach(int sd);
183 
184  virtual int open(const char hostname[], int port);
185 
186  virtual int close();
187 
188 protected:
189  virtual int sync();
190 
191  virtual int_type underflow();
192 
193  // Same as in the base class:
194  // virtual int_type overflow(int_type c = traits_type::eof());
195 
196  virtual std::streamsize xsgetn(char_type *__s, std::streamsize __n);
197 
198  virtual std::streamsize xsputn(const char_type *__s, std::streamsize __n);
199 };
200 
201 #endif // MFEM_USE_GNUTLS
202 
203 class socketstream : public std::iostream
204 {
205 protected:
208 
209  void set_socket(bool secure);
210  inline void check_secure_socket();
211 #ifdef MFEM_USE_GNUTLS
212  static int num_glvis_sockets;
216  static void remove_socket();
217  inline void set_secure_socket(const GnuTLS_session_params &p);
218 #endif
219 
220 public:
221 #ifdef MFEM_USE_GNUTLS
222  static const bool secure_default = true;
223 #else
224  static const bool secure_default = false;
225 #endif
226 
227  /** @brief Create a socket stream without connecting to a host.
228 
229  If 'secure' is true, (GnuTLS support must be enabled) then the connection
230  will use GLVis client session keys from ~/.config/glvis/client for GnuTLS
231  identification. If you want to use other GnuTLS session keys or
232  parameters, use the constructor from GnuTLS_session_params. */
233  socketstream(bool secure = secure_default);
234 
235  /** @brief Create a socket stream associated with the given socket buffer.
236  The new object takes ownership of 'buf'. */
237  explicit socketstream(socketbuf *buf)
238  : std::iostream(buf), buf__(buf), glvis_client(false) { }
239 
240  /** @brief Create a socket stream and associate it with the given socket
241  descriptor 's'. The treatment of the 'secure' flag is similar to that in
242  the default constructor. */
243  explicit socketstream(int s, bool secure = secure_default);
244 
245  /** @brief Create a socket stream and connect to the given host and port.
246  The treatment of the 'secure' flag is similar to that in the default
247  constructor. */
248  socketstream(const char hostname[], int port, bool secure = secure_default)
249  : std::iostream(0) { set_socket(secure); open(hostname, port); }
250 
251 #ifdef MFEM_USE_GNUTLS
252  /// Create a secure socket stream using the given GnuTLS_session_params.
253  explicit socketstream(const GnuTLS_session_params &p);
254 #endif
255 
256  socketbuf *rdbuf() { return buf__; }
257 
258  int open(const char hostname[], int port);
259 
260  int close() { return buf__->close(); }
261 
262  bool is_open() { return buf__->is_open(); }
263 
264  virtual ~socketstream();
265 };
266 
267 
269 {
270 private:
271  int listen_socket;
272 
273 public:
274  explicit socketserver(int port, int backlog=4);
275 
276  bool good() { return (listen_socket >= 0); }
277 
278  int close();
279 
280  int accept();
281 
282  int accept(socketstream &sockstr);
283 
285 };
286 
287 } // namespace mfem
288 
289 #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 &#39;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)
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 &#39;secure&#39; flag is ...
gnutls_dh_params_t dh_params
unsigned int get_flags() 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]
int get_result() const
virtual int_type underflow()
void print_on_error(const char *msg) 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)
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)
gnutls_certificate_credentials_t get_cred() const
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
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)