summaryrefslogtreecommitdiff
path: root/ACE/ace/SSL/SSL_SOCK_Stream.h
blob: fdacb49d5f4ba41975a601249e3a3144196a956e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
// -*- C++ -*-

//=============================================================================
/**
 *  @file    SSL_SOCK_Stream.h
 *
 *  @author Ossama Othman <ossama@uci.edu>
 *  @author Carlos O'Ryan <coryan@uci.edu>
 *  @author John Heitmann
 */
//=============================================================================


#ifndef ACE_SSL_SOCK_STREAM_H
#define ACE_SSL_SOCK_STREAM_H

#include /**/ "ace/pre.h"

#include "SSL_Export.h"

#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */

// This must be included before any <openssl> include on LynxOS
#include "ace/os_include/os_stdio.h"

#include <openssl/err.h>

#include "SSL_SOCK.h"
#include "SSL_Context.h"

#include "ace/SOCK_Stream.h"

ACE_BEGIN_VERSIONED_NAMESPACE_DECL

/**
 * @class ACE_SSL_SOCK_Stream
 *
 * @brief Defines methods in the ACE_SSL_SOCK_Stream abstraction.
 *
 * This class encapsulates the methods and functionality necessary to
 * send and receive data over TLS/SSL.
 * @par
 * Since SSL is record-oriented, some additional steps must be taken
 * to make the ACE_SSL_SOCK_Stream interact properly with the
 * Reactor (if one is used) when performing non-blocking IO.  In
 * particular, if ::SSL_pending (ssl), where "ssl" is a pointer to the
 * SSL data structure returned from ACE_SSL_SOCK_Stream::ssl(),
 * returns a non-zero value then the event handler that calls the IO
 * methods in this class should return a value greater than zero to
 * force the Reactor to invoke the event handler before polling for
 * additional events (e.g. blocking on select()).
 *
 * @note The user must currently ensure that only one thread services
 *       a given SSL session at any given time since underlying SSL
 *       implementations, such as OpenSSL, are not entirely
 *       thread-safe or reentrant.
 */
class ACE_SSL_Export ACE_SSL_SOCK_Stream : public ACE_SSL_SOCK
{
public:
  /// Constructor
  /**
   * @param context Pointer to @c ACE_SSL_Context instance containing
   *                the OpenSSL @c SSL data structure to be associated
   *                with this @c ACE_SSL_SOCK_Stream.  The @c SSL data
   *                structure will be copied to make it at least
   *                logically independent of the supplied @a context.
   */
  ACE_SSL_SOCK_Stream (ACE_SSL_Context *context =
                       ACE_SSL_Context::instance ());

  /// Destructor
  ~ACE_SSL_SOCK_Stream ();

  /// Send an @a n byte buffer to the ssl socket using the semantics of
  /// send(3n).
  /**
   * ACE_SSL supports no flags for sending at this time.
   */
  ssize_t send (const void *buf,
                size_t n,
                int flags) const;

  /// Recv an @a n byte buffer from the ssl socket using the semantics of
  /// recv(3n).
  /**
   * ACE_SSL supports MSG_PEEK, but no other flags at this time.
   */
  ssize_t recv (void *buf,
                size_t n,
                int flags) const;

  /// Send an @a n byte buffer to the ssl socket using the semantics of
  /// write(2).
  ssize_t send (const void *buf,
                size_t n) const;

  /// Recv an @a n byte buffer from the ssl socket using the semantics of
  /// read(2).
  ssize_t recv (void *buf,
                size_t n) const;

  /// Send an iovec of size @a n to the ssl socket.
  /**
   * Note that it is not possible to perform a "scattered" write with
   * the underlying OpenSSL implementation.  As such, the expected
   * semantics are not fully reproduced with this implementation.
   */
  ssize_t sendv (const iovec iov[],
                 size_t n,
                 const ACE_Time_Value *timeout = 0) const;

  /**
   * Allows a client to read from a socket without having to provide a
   * buffer to read.  This method determines how much data is in the
   * socket, allocates a buffer of this size, reads in the data, and
   * returns the number of bytes read.  The caller is responsible for
   * deleting the member in the iov_base field of io_vec using
   * delete [] io_vec->iov_base.
   */
  ssize_t recvv (iovec *io_vec,
                 const ACE_Time_Value *timeout = 0) const;

  /**
   * Wait to timeout amount of time to send up to n bytes into buf
   * (uses the send() call).  If send() times out -1 is returned with
   * errno == ETIME.  If it succeeds the number of bytes sent is
   * returned. No flags are supported.
   */
  ssize_t send (const void *buf,
                size_t n,
                int flags,
                const ACE_Time_Value *timeout) const;

  /**
   * Wait up to timeout amount of time to receive up to @a n bytes into
   * @a buf (uses the recv() call).  If recv() times out -1 is returned
   * with errno == ETIME.  If it succeeds the number of bytes received
   * is returned.  MSG_PEEK is the only supported flag.
   */
  ssize_t recv (void *buf,
                size_t n,
                int flags,
                const ACE_Time_Value *timeout) const;

  /**
   * Wait to to timeout amount of time to send up to @a n bytes into
   * @a buf (uses the send() call).  If send() times out
   * a -1 is returned with errno == ETIME.  If it succeeds the
   * number of bytes sent is returned.
   */
  ssize_t send (const void *buf,
                size_t n,
                const ACE_Time_Value *timeout) const;

  /**
   * Wait up to timeout amount of time to receive up to @a n bytes
   * into @a buf (uses the recv() call).  If recv() times
   * out a -1 is returned with @c errno == ETIME.  If it succeeds the
   * number of bytes received is returned.
   */
  ssize_t recv (void *buf,
                size_t n,
                const ACE_Time_Value *timeout) const;

  /// Send @a n varargs messages to the connected ssl socket.
  ssize_t send (size_t n,
                ...) const;

  /// Recv @a n varargs messages to the connected ssl socket.
  ssize_t recv (size_t n,
                ...) const;

  /// Send @a n bytes, keep trying until n are sent.
  ssize_t send_n (const void *buf, int n) const;

  /// Recv @a n bytes, keep trying until @a n are received.
  ssize_t recv_n (void *buf, int n) const;

  /**
   * @note In the following four methods, only MSG_PEEK is supported
   * for recv_n(), and no flags are supported for send_n().
   */
  //@{
  /// Send @a n bytes, keep trying until @a n are sent.
  ssize_t send_n (const void *buf, int n, int flags) const;

  /// Recv @a n bytes, keep trying until @a n are sent.
  ssize_t recv_n (void *buf, int n, int flags) const;

  /**
   * Try to send exactly @a len bytes into @a buf (uses the send() call).
   * If send() blocks for longer than timeout the number of bytes
   * actually sent is returned with errno == ETIME.  If a timeout does
   * not occur, send_n() return len (i.e., the number of bytes
   * requested to be sent).
   */
  ssize_t send_n (const void *buf,
                  size_t len,
                  int flags,
                  const ACE_Time_Value *timeout,
                  size_t *bytes_transferred = 0) const;

  /**
   * Try to send exactly @a len bytes into @a buf (uses the send() call).
   * If send() blocks for longer than timeout the number of bytes
   * actually sent is returned with errno == ETIME.  If a timeout does
   * not occur, send_n() return len (i.e., the number of bytes
   * requested to be sent).
   */
  ssize_t send_n (const void *buf,
                  size_t len,
                  const ACE_Time_Value *timeout,
                  size_t *bytes_transferred = 0) const;

  /**
   * Try to receive exactly @a len bytes into @a buf (uses the recv() call).
   * The ACE_Time_Value indicates how long to blocking trying to
   * receive.  If timeout == 0, the caller will block until action is
   * possible, else will wait until the relative time specified in
   * timeout elapses).  If recv() blocks for longer than timeout the
   * number of bytes actually read is returned with errno == ETIME.
   * If a timeout does not occur, recv_n return len (i.e., the number
   * of bytes requested to be read).
   */
  ssize_t recv_n (void *buf,
                  size_t len,
                  int flags,
                  const ACE_Time_Value *timeout,
                  size_t *bytes_transferred = 0) const;

  /**
   * Try to receive exactly len bytes into buf (uses the recv() call).
   * The ACE_Time_Value indicates how long to blocking trying to
   * receive.  If timeout == 0, the caller will block until action is
   * possible, else will wait until the relative time specified in
   * timeout elapses).  If recv() blocks for longer than timeout the
   * number of bytes actually read is returned with errno == ETIME.
   * If a timeout does not occur, recv_n return len (i.e., the number
   * of bytes requested to be read).
   */
  ssize_t recv_n (void *buf,
                  size_t len,
                  const ACE_Time_Value *timeout,
                  size_t *bytes_transferred = 0) const;
  //@}

  /**
   * Send an iovec of size n to the connected socket.  Will block
   * until all bytes are sent or an error occurs.
   */
  ssize_t sendv_n (const iovec iov[],
                   size_t n) const;

  /// Receive an iovec of size n to the connected socket.
  ssize_t recvv_n (iovec iov[],
                   size_t n) const;

  /**
   * Selectively close endpoints.
   */
  //@{
  /// Close down the reader.
  int close_reader ();

  /// Close down the writer.
  int close_writer ();
  //@}

  ///Close down the socket.
  int close ();

  /// Meta-type info
  typedef ACE_INET_Addr PEER_ADDR;

  /// Declare the dynamic allocation hooks.
  ACE_ALLOC_HOOK_DECLARE;

  /// Overridden set_handle() method.
  /**
   * Only an ACE_SSL_SOCK_Acceptor or ACE_SSL_SOCK_Connector should
   * access this method since some state in the underlying "ssl_" data
   * structure is set during SSL connection establishment.
   */
  void set_handle (ACE_HANDLE fd);

  /// Return a pointer to the underlying SSL structure.
  SSL *ssl () const;

  /**
   * Return the address of the remotely connected peer (if there is
   * one), in the referenced ACE_Addr. Returns 0 if successful, else
   * -1.
   *
   * @note If the TCP connection has been completed but the SSL
   *       connection has not been completed yet, -1 will be
   *       returned.
   */
  int get_remote_addr (ACE_Addr &) const;

  /// Return the underlying ACE_SOCK_Stream which ACE_SSL runs atop of.
  ACE_SOCK_Stream & peer ();

protected:
  /// Underlying send() helper method common to all public send()
  /// methods.
  ssize_t send_i (const void *buf,
                  size_t n,
                  int flags) const;

  /// Underlying send() helper method common to all public send()
  /// methods.
  ssize_t recv_i (void *buf,
                  size_t n,
                  int flags,
                  const ACE_Time_Value *timeout) const;

private:
  ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_SSL_SOCK_Stream &))
  ACE_UNIMPLEMENTED_FUNC (ACE_SSL_SOCK_Stream (const ACE_SSL_SOCK_Stream &))

protected:
  /// The SSL session.
  SSL *ssl_;

  /// The stream which works under the ssl connection.
  ACE_SOCK_Stream stream_;
};

ACE_END_VERSIONED_NAMESPACE_DECL

#if defined (__ACE_INLINE__)
#include "SSL_SOCK_Stream.inl"
#endif /* __ACE_INLINE__ */

#include /**/ "ace/post.h"

#endif /* ACE_SSL_SOCK_STREAM_H */