Also use Objects as part of an operation but as a result don't generate Any operation...
[ACE_TAO.git] / ACE / ace / SOCK_Acceptor.cpp
blob47057df08d3d3a94fd97cf66e0f3a345d4a06695
1 #include "ace/SOCK_Acceptor.h"
3 #include "ace/Log_Category.h"
4 #include "ace/OS_Errno.h"
5 #include "ace/OS_NS_string.h"
6 #include "ace/OS_NS_sys_socket.h"
7 #include "ace/os_include/os_fcntl.h"
8 #if defined (ACE_HAS_ALLOC_HOOKS)
9 # include "ace/Malloc_Base.h"
10 #endif /* ACE_HAS_ALLOC_HOOKS */
12 #if !defined (__ACE_INLINE__)
13 #include "ace/SOCK_Acceptor.inl"
14 #endif /* __ACE_INLINE__ */
16 #if !defined (ACE_HAS_WINCE)
17 #include "ace/OS_QoS.h"
18 #endif // ACE_HAS_WINCE
22 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
24 ACE_ALLOC_HOOK_DEFINE(ACE_SOCK_Acceptor)
26 // Do nothing routine for constructor.
28 ACE_SOCK_Acceptor::ACE_SOCK_Acceptor (void)
30 ACE_TRACE ("ACE_SOCK_Acceptor::ACE_SOCK_Acceptor");
33 // Performs the timed accept operation.
35 int
36 ACE_SOCK_Acceptor::shared_accept_start (ACE_Time_Value *timeout,
37 bool restart,
38 int &in_blocking_mode) const
40 ACE_TRACE ("ACE_SOCK_Acceptor::shared_accept_start");
42 ACE_HANDLE handle = this->get_handle ();
44 // Handle the case where we're doing a timed <accept>.
45 if (timeout != 0)
47 if (ACE::handle_timed_accept (handle,
48 timeout,
49 restart) == -1)
50 return -1;
51 else
53 in_blocking_mode = ACE_BIT_DISABLED (ACE::get_flags (handle),
54 ACE_NONBLOCK);
55 // Set the handle into non-blocking mode if it's not already
56 // in it.
57 if (in_blocking_mode
58 && ACE::set_flags (handle,
59 ACE_NONBLOCK) == -1)
60 return -1;
64 return 0;
67 int
68 ACE_SOCK_Acceptor::shared_accept_finish (ACE_SOCK_Stream new_stream,
69 int in_blocking_mode,
70 bool reset_new_handle) const
72 ACE_TRACE ("ACE_SOCK_Acceptor::shared_accept_finish ()");
74 ACE_HANDLE new_handle = new_stream.get_handle ();
76 // Check to see if we were originally in blocking mode, and if so,
77 // set the <new_stream>'s handle and <this> handle to be in blocking
78 // mode.
79 if (in_blocking_mode)
81 // Save/restore errno.
82 ACE_Errno_Guard error (errno);
84 // Only disable ACE_NONBLOCK if we weren't in non-blocking mode
85 // originally.
86 ACE::clr_flags (this->get_handle (),
87 ACE_NONBLOCK);
88 ACE::clr_flags (new_handle,
89 ACE_NONBLOCK);
92 #if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
93 if (reset_new_handle)
94 // Reset the event association inherited by the new handle.
95 ::WSAEventSelect ((SOCKET) new_handle, 0, 0);
96 #else
97 ACE_UNUSED_ARG (reset_new_handle);
98 #endif /* ACE_WIN32 */
100 return new_handle == ACE_INVALID_HANDLE ? -1 : 0;
103 // General purpose routine for accepting new connections.
106 ACE_SOCK_Acceptor::accept (ACE_SOCK_Stream &new_stream,
107 ACE_Addr *remote_addr,
108 ACE_Time_Value *timeout,
109 bool restart,
110 bool reset_new_handle) const
112 ACE_TRACE ("ACE_SOCK_Acceptor::accept");
114 int in_blocking_mode = 0;
115 if (this->shared_accept_start (timeout,
116 restart,
117 in_blocking_mode) == -1)
118 return -1;
119 else
121 // On Win32 the third parameter to <accept> must be a NULL
122 // pointer if we want to ignore the client's address.
123 int *len_ptr = 0;
124 sockaddr *addr = 0;
125 int len = 0;
127 if (remote_addr != 0)
129 len = remote_addr->get_size ();
130 len_ptr = &len;
131 addr = (sockaddr *) remote_addr->get_addr ();
135 new_stream.set_handle (ACE_OS::accept (this->get_handle (),
136 addr,
137 len_ptr));
138 while (new_stream.get_handle () == ACE_INVALID_HANDLE
139 && restart
140 && errno == EINTR
141 && timeout == 0);
143 // Reset the size of the addr, so the proper UNIX/IPv4/IPv6 family
144 // is known.
145 if (new_stream.get_handle () != ACE_INVALID_HANDLE
146 && remote_addr != 0)
148 remote_addr->set_size (len);
149 if (addr)
150 remote_addr->set_type (addr->sa_family);
154 return this->shared_accept_finish (new_stream,
155 in_blocking_mode,
156 reset_new_handle);
159 #if !defined (ACE_HAS_WINCE)
161 ACE_SOCK_Acceptor::accept (ACE_SOCK_Stream &new_stream,
162 ACE_Accept_QoS_Params qos_params,
163 ACE_Addr *remote_addr,
164 ACE_Time_Value *timeout,
165 bool restart,
166 bool reset_new_handle) const
168 ACE_TRACE ("ACE_SOCK_Acceptor::accept");
170 int in_blocking_mode = 0;
171 if (this->shared_accept_start (timeout,
172 restart,
173 in_blocking_mode) == -1)
174 return -1;
175 else
177 // On Win32 the third parameter to <accept> must be a NULL
178 // pointer if we want to ignore the client's address.
179 int *len_ptr = 0;
180 int len = 0;
181 sockaddr *addr = 0;
183 if (remote_addr != 0)
185 len = remote_addr->get_size ();
186 len_ptr = &len;
187 addr = (sockaddr *) remote_addr->get_addr ();
191 new_stream.set_handle (ACE_OS::accept (this->get_handle (),
192 addr,
193 len_ptr,
194 qos_params));
195 while (new_stream.get_handle () == ACE_INVALID_HANDLE
196 && restart
197 && errno == EINTR
198 && timeout == 0);
200 // Reset the size of the addr, which is only necessary for UNIX
201 // domain sockets.
202 if (new_stream.get_handle () != ACE_INVALID_HANDLE
203 && remote_addr != 0)
204 remote_addr->set_size (len);
207 return this->shared_accept_finish (new_stream,
208 in_blocking_mode,
209 reset_new_handle);
211 #endif // ACE_HAS_WINCE
213 void
214 ACE_SOCK_Acceptor::dump (void) const
216 #if defined (ACE_HAS_DUMP)
217 ACE_TRACE ("ACE_SOCK_Acceptor::dump");
218 #endif /* ACE_HAS_DUMP */
222 ACE_SOCK_Acceptor::shared_open (const ACE_Addr &local_sap,
223 int protocol_family,
224 int backlog,
225 int ipv6_only)
227 ACE_TRACE ("ACE_SOCK_Acceptor::shared_open");
228 int error = 0;
230 #if !defined (ACE_HAS_IPV6)
231 ACE_UNUSED_ARG (ipv6_only);
232 #else /* defined (ACE_HAS_IPV6) */
233 if (protocol_family == PF_INET6)
235 sockaddr_in6 local_inet6_addr;
236 ACE_OS::memset (reinterpret_cast<void *> (&local_inet6_addr),
238 sizeof local_inet6_addr);
240 if (local_sap == ACE_Addr::sap_any)
242 local_inet6_addr.sin6_family = AF_INET6;
243 local_inet6_addr.sin6_port = 0;
244 local_inet6_addr.sin6_addr = in6addr_any;
246 else
247 local_inet6_addr = *reinterpret_cast<sockaddr_in6 *> (local_sap.get_addr ());
250 * Handle IPv6-only requests. On Windows, v6-only is the default
251 * unless it is turned off. On Linux, v4/v6 dual is the default
252 * unless v6-only is turned on.
253 * This must be done before attempting to bind the address.
254 * On Windows older than Vista this will fail.
256 int setting = !!ipv6_only;
257 if (-1 == ACE_OS::setsockopt (this->get_handle (),
258 IPPROTO_IPV6,
259 IPV6_V6ONLY,
260 (char *)&setting,
261 sizeof (setting)))
262 error = 1;
263 else
264 // We probably don't need a bind_port written here.
265 // There are currently no supported OS's that define
266 // ACE_LACKS_WILDCARD_BIND.
267 if (ACE_OS::bind (this->get_handle (),
268 reinterpret_cast<sockaddr *> (&local_inet6_addr),
269 sizeof local_inet6_addr) == -1)
270 error = 1;
272 else
273 #endif /* ACE_HAS_IPV6 */
274 if (protocol_family == PF_INET)
276 sockaddr_in local_inet_addr;
277 ACE_OS::memset (reinterpret_cast<void *> (&local_inet_addr),
279 sizeof local_inet_addr);
281 if (local_sap == ACE_Addr::sap_any)
283 local_inet_addr.sin_port = 0;
285 else
286 local_inet_addr = *reinterpret_cast<sockaddr_in *> (local_sap.get_addr ());
287 if (local_inet_addr.sin_port == 0)
289 if (ACE::bind_port (this->get_handle (),
290 ACE_NTOHL (ACE_UINT32 (local_inet_addr.sin_addr.s_addr))) == -1)
291 error = 1;
293 else if (ACE_OS::bind (this->get_handle (),
294 reinterpret_cast<sockaddr *> (&local_inet_addr),
295 sizeof local_inet_addr) == -1)
296 error = 1;
298 else if (ACE_OS::bind (this->get_handle (),
299 (sockaddr *) local_sap.get_addr (),
300 local_sap.get_size ()) == -1)
301 error = 1;
303 if (error != 0
304 || ACE_OS::listen (this->get_handle (),
305 backlog) == -1)
307 ACE_Errno_Guard g (errno); // Preserve across close() below.
308 error = 1;
309 this->close ();
312 return error ? -1 : 0;
316 ACE_SOCK_Acceptor::open (const ACE_Addr &local_sap,
317 ACE_Protocol_Info *protocolinfo,
318 ACE_SOCK_GROUP g,
319 u_long flags,
320 int reuse_addr,
321 int protocol_family,
322 int backlog,
323 int protocol,
324 int ipv6_only)
326 ACE_TRACE ("ACE_SOCK_Acceptor::open");
328 if (protocol_family == PF_UNSPEC)
329 protocol_family = local_sap.get_type ();
331 if (ACE_SOCK::open (SOCK_STREAM,
332 protocol_family,
333 protocol,
334 protocolinfo,
336 flags,
337 reuse_addr) == -1)
338 return -1;
339 else
340 return this->shared_open (local_sap,
341 protocol_family,
342 backlog,
343 ipv6_only);
346 ACE_SOCK_Acceptor::ACE_SOCK_Acceptor (const ACE_Addr &local_sap,
347 ACE_Protocol_Info *protocolinfo,
348 ACE_SOCK_GROUP g,
349 u_long flags,
350 int reuse_addr,
351 int protocol_family,
352 int backlog,
353 int protocol,
354 int ipv6_only)
356 ACE_TRACE ("ACE_SOCK_Acceptor::ACE_SOCK_Acceptor");
357 if (this->open (local_sap,
358 protocolinfo,
360 flags,
361 reuse_addr,
362 protocol_family,
363 backlog,
364 protocol,
365 ipv6_only) == -1)
366 ACELIB_ERROR ((LM_ERROR,
367 ACE_TEXT ("%p\n"),
368 ACE_TEXT ("ACE_SOCK_Acceptor")));
371 // General purpose routine for performing server ACE_SOCK creation.
374 ACE_SOCK_Acceptor::open (const ACE_Addr &local_sap,
375 int reuse_addr,
376 int protocol_family,
377 int backlog,
378 int protocol,
379 int ipv6_only)
381 ACE_TRACE ("ACE_SOCK_Acceptor::open");
383 if (local_sap != ACE_Addr::sap_any)
384 protocol_family = local_sap.get_type ();
385 else if (protocol_family == PF_UNSPEC)
387 #if defined (ACE_HAS_IPV6)
388 protocol_family = ACE::ipv6_enabled () ? PF_INET6 : PF_INET;
389 #else
390 protocol_family = PF_INET;
391 #endif /* ACE_HAS_IPV6 */
394 if (ACE_SOCK::open (SOCK_STREAM,
395 protocol_family,
396 protocol,
397 reuse_addr) == -1)
398 return -1;
399 else
400 return this->shared_open (local_sap,
401 protocol_family,
402 backlog,
403 ipv6_only);
406 // General purpose routine for performing server ACE_SOCK creation.
408 ACE_SOCK_Acceptor::ACE_SOCK_Acceptor (const ACE_Addr &local_sap,
409 int reuse_addr,
410 int protocol_family,
411 int backlog,
412 int protocol,
413 int ipv6_only)
415 ACE_TRACE ("ACE_SOCK_Acceptor::ACE_SOCK_Acceptor");
416 if (this->open (local_sap,
417 reuse_addr,
418 protocol_family,
419 backlog,
420 protocol,
421 ipv6_only) == -1)
422 ACELIB_ERROR ((LM_ERROR,
423 ACE_TEXT ("%p\n"),
424 ACE_TEXT ("ACE_SOCK_Acceptor")));
428 ACE_SOCK_Acceptor::close (void)
430 return ACE_SOCK::close ();
433 ACE_END_VERSIONED_NAMESPACE_DECL