summaryrefslogtreecommitdiff
path: root/ACE/ace/Asynch_Acceptor.h
blob: 36b3aa1ca76644d9d49d20ceca4b5faf23686cb7 (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
/* -*- C++ -*- */

//=============================================================================
/**
 *  @file    Asynch_Acceptor.h
 *
 *  @author Irfan Pyarali (irfan@cs.wustl.edu)
 */
//=============================================================================

#ifndef ACE_ASYNCH_ACCEPTOR_H
#define ACE_ASYNCH_ACCEPTOR_H
#include /**/ "ace/pre.h"

#include /**/ "ace/config-all.h"

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

#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) || defined (ACE_HAS_AIO_CALLS)
// This only works on platforms that support async i/o.

#include "ace/Default_Constants.h"
#include "ace/Asynch_IO.h"

ACE_BEGIN_VERSIONED_NAMESPACE_DECL

// Forward declarations
class ACE_Message_Block;
class ACE_INET_Addr;

/**
 * @class ACE_Asynch_Acceptor
 *
 * @brief This class is an example of the Acceptor Pattern.  This class
 * will accept new connections and create new HANDLER to handle
 * the new connections.
 *
 * Unlike the ACE_Acceptor, however, this class is designed to
 * be used asynchronously.
 */
template <class HANDLER>
class ACE_Asynch_Acceptor : public ACE_Handler
{
public:
  /// A do nothing constructor.
  ACE_Asynch_Acceptor (void);

  /// Virtual destruction
  virtual ~ACE_Asynch_Acceptor (void);

  /**
   * @c open starts one or more asynchronous accept requests on a
   * @a address. Each accept operation may optionally read an
   * initial buffer from the new connection when accepted.
   *
   * @param address The address to listen/accept connections on.
   *                If the address does not specify a port, a random
   *                port is selected and bound.
   * @param bytes_to_read Optional, specifies the maximum number of bytes
   *                to read with the accept. The buffer for the initial
   *                data is allocated internally and passed to the
   *                @c ACE_Service_Handler::open() hook method. It is
   *                legitimate only during the @c open() method and must
   *                be copied if required after @c open() returns.
   *                This pre-read function works only on Windows.
   * @param pass_addresses Optional, a non-zero value indicates that
   *                the local and peer addresses should be passed to the
   *                associated @c ACE_Service_Handler::addresses() method
   *                after any call to @c validate_new_connection() and prior
   *                to the @c open() hook method call.
   * @param backlog Optional, defaulting to @c ACE_DEFAULT_ASYNCH_BACKLOG (which
   *                can be adjusted in your platform's @c config.h file).
   *                Specifies the listening backlog for the listening socket.
   * @param reuse_addr Optional, indicates whether the @c SO_REUSEADDR
   *                option is set on the listening socket or not.
   * @param proactor Optional, pointer to the @c ACE_Proactor to use for
   *                demultiplexing asynchronous accepts. If 0, the
   *                process's singleton @c ACE_Proactor is used.
   * @param validate_new_connection Optional, if true, this object's
   *                @c validate_connection() method is called after
   *                the accept completes, but before the service handler's
   *                @c open() hook method is called. If @c
   *                validate_connection() returns -1, the newly-accepted
   *                socket is immediately closed, and the @c addresses()
   *                method is not called.
   * @param reissue_accept Optional, if non-zero (the default), a new
   *                asynchronous accept operation is started after each
   *                completion, whether the completion is for success or
   *                failure, and whether or not a successfully-accepted
   *                connection is subsequently refused.
   * @param number_of_initial_accepts Optional, the number of asynchronous
   *                accepts that are started immediately. If -1 (the
   *                default), the value of @a backlog is used.
   *
   * @note On Windows, the peer address is only available at the time
   *       the connection is accepted.  Therefore, if you require the peer
   *       address on Windows, do not rely on the
   *       @c ACE_SOCK::get_remote_addr() method - it won't work. You must
   *       supply a non-zero value for @a pass_addresses and obtain the
   *       peer address in the @c ACE_Service_Handler::addresses() method.
   *
   * @see ACE_INET_Addr
   * @see ACE_Service_Handler
   */
  virtual int open (const ACE_INET_Addr &address,
                    size_t bytes_to_read = 0,
                    bool pass_addresses = false,
                    int backlog = ACE_DEFAULT_ASYNCH_BACKLOG,
                    int reuse_addr = 1,
                    ACE_Proactor *proactor = 0,
                    bool validate_new_connection = false,
                    int reissue_accept = 1,
                    int number_of_initial_accepts = -1);

  /// Get the underlying handle.
  virtual ACE_HANDLE get_handle () const;

  /**
   * Set the underlying listen handle. It is the user's responsibility
   * to make sure that the old listen handle has been appropriately
   * closed and the all outstanding asynchronous operations have
   * either completed or have been canceled on the old listen handle.
   */
  virtual int set_handle (ACE_HANDLE handle);

  /// This initiates a new asynchronous accept operation.
  /**
   * You need only call this method if the @a reissue_accept argument
   * passed to @c open() was 0.
   */
  virtual int accept (size_t bytes_to_read = 0, const void *act = 0);

  /**
   * Cancels all pending accepts operations issued by this object.
   *
   * @note On Windows, only accept operations initiated by the calling thread
   *       are canceled.
   */
  virtual int cancel (void);

  /**
   * Template method to validate peer before service is opened.
   * This method is called after a new connection is accepted if the
   * @a validate_connection argument to @c open() was non-zero or
   * the @c validate_new_connection() method is called to turn this
   * feature on.  The default implementation returns 0.  Users can
   * reimplement this method to perform validation of the peer
   * using it's address, running an authentication procedure (such as
   * SSL) or anything else necessary or desireable. The return value
   * from this method determines whether or not ACE will continue
   * opening the service or abort the connection.
   *
   * @param result    Result of the connection acceptance.
   * @param remote    Peer's address.
   * @param local     Local address connection was accepted at.
   *
   * @retval  -1  ACE_Asynch_Acceptor will close the connection, and
   *              the service will not be opened.
   * @retval  0   Service opening will proceeed.
   */
  virtual int validate_connection (const ACE_Asynch_Accept::Result& result,
                                   const ACE_INET_Addr &remote,
                                   const ACE_INET_Addr& local);

  /**
   * Template method for deciding whether to reissue accept.
   *
   * This hook method is called after each accept completes to decide if
   * another accept should be initiated. If the method returns a non-zero
   * value, another accept is initiated.
   *
   * The default implementation always returns the value passed as the
   * @c open() method's @a reissue_accept argument. That value can also
   * be changed using the @c reissue_accept() method.
   */
  virtual int should_reissue_accept (void);

  //
  // These are low level tweaking methods
  //

  /// Get flag that indicates if parsing and passing of addresses to
  /// the service_handler is necessary.
  virtual bool pass_addresses () const;

  /// Set flag that indicates if parsing and passing of addresses to
  /// the service_handler is necessary.
  virtual void pass_addresses (bool new_value);

  /// Get flag that indicates if address validation is required.
  virtual bool validate_new_connection () const;

  /// Set flag that indicates if address validation is required.
  virtual void validate_new_connection (bool new_value);

  /// Get flag that indicates if a new accept should be reissued when a accept
  /// completes.
  virtual int reissue_accept () const;

  /// Set flag that indicates if a new accept should be reissued when a accept
  /// completes.
  virtual void reissue_accept (int new_value);

  /// Get bytes to be read with the <accept> call.
  virtual size_t bytes_to_read () const;

  /// Set bytes to be read with the <accept> call.
  virtual void bytes_to_read (size_t new_value);

protected:

  /// This is called when an outstanding accept completes.
  virtual void handle_accept (const ACE_Asynch_Accept::Result &result);

  /// Return the listen handle.
  ACE_HANDLE handle () const;
  /// Set the listen handle.
  void handle (ACE_HANDLE h);

  /// This parses the address from read buffer.
  void parse_address (const ACE_Asynch_Accept::Result &result,
                      ACE_INET_Addr &remote_address,
                      ACE_INET_Addr &local_address);

  /// Return the asynch accept object.
  ACE_Asynch_Accept &asynch_accept (void);

  /**
   * This is the template method used to create new handler.
   * Subclasses must overwrite this method if a new handler creation
   * strategy is required.
   */
  virtual HANDLER *make_handler (void);

private:
  /// Handle used to listen for new connections.
  ACE_HANDLE listen_handle_;

  /// Asynch_Accept used to make life easier :-)
  ACE_Asynch_Accept asynch_accept_;

  /// Flag that indicates if parsing of addresses is necessary.
  bool pass_addresses_;

  /// Flag that indicates if address validation is required.
  bool validate_new_connection_;

  /// Flag that indicates if a new accept should be reissued when a
  /// accept completes.
  int reissue_accept_;

  /// Bytes to be read with the <accept> call.
  size_t bytes_to_read_;

  /// Address family used to open this object. Obtained from @a address passed
  /// to @c open().
  int addr_family_;
};

ACE_END_VERSIONED_NAMESPACE_DECL

#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
#include "ace/Asynch_Acceptor.cpp"
#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */

#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
#pragma implementation ("Asynch_Acceptor.cpp")
#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */

#endif /* ACE_HAS_WIN32_OVERLAPPED_IO || ACE_HAS_AIO_CALLS */
#include /**/ "ace/post.h"
#endif /* ACE_ASYNCH_ACCEPTOR_H */