Changes to attempt to silence bcc64x
[ACE_TAO.git] / ACE / ace / SOCK_Acceptor.cpp
blobb0c62030d7e3832c609b849e7886905090925433
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 #include "ace/OS_QoS.h"
18 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
20 ACE_ALLOC_HOOK_DEFINE(ACE_SOCK_Acceptor)
22 // Do nothing routine for constructor.
24 ACE_SOCK_Acceptor::ACE_SOCK_Acceptor ()
26 ACE_TRACE ("ACE_SOCK_Acceptor::ACE_SOCK_Acceptor");
29 // Performs the timed accept operation.
31 int
32 ACE_SOCK_Acceptor::shared_accept_start (ACE_Time_Value *timeout,
33 bool restart,
34 int &in_blocking_mode) const
36 ACE_TRACE ("ACE_SOCK_Acceptor::shared_accept_start");
38 ACE_HANDLE handle = this->get_handle ();
40 // Handle the case where we're doing a timed <accept>.
41 if (timeout != 0)
43 if (ACE::handle_timed_accept (handle,
44 timeout,
45 restart) == -1)
46 return -1;
47 else
49 in_blocking_mode = ACE_BIT_DISABLED (ACE::get_flags (handle),
50 ACE_NONBLOCK);
51 // Set the handle into non-blocking mode if it's not already
52 // in it.
53 if (in_blocking_mode
54 && ACE::set_flags (handle,
55 ACE_NONBLOCK) == -1)
56 return -1;
60 return 0;
63 int
64 ACE_SOCK_Acceptor::shared_accept_finish (ACE_SOCK_Stream new_stream,
65 int in_blocking_mode,
66 bool reset_new_handle) const
68 ACE_TRACE ("ACE_SOCK_Acceptor::shared_accept_finish ()");
70 ACE_HANDLE new_handle = new_stream.get_handle ();
72 // Check to see if we were originally in blocking mode, and if so,
73 // set the <new_stream>'s handle and <this> handle to be in blocking
74 // mode.
75 if (in_blocking_mode)
77 // Save/restore errno.
78 ACE_Errno_Guard error (errno);
80 // Only disable ACE_NONBLOCK if we weren't in non-blocking mode
81 // originally.
82 ACE::clr_flags (this->get_handle (),
83 ACE_NONBLOCK);
84 ACE::clr_flags (new_handle,
85 ACE_NONBLOCK);
88 #if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
89 if (reset_new_handle)
90 // Reset the event association inherited by the new handle.
91 ::WSAEventSelect ((SOCKET) new_handle, 0, 0);
92 #else
93 ACE_UNUSED_ARG (reset_new_handle);
94 #endif /* ACE_WIN32 */
96 return new_handle == ACE_INVALID_HANDLE ? -1 : 0;
99 // General purpose routine for accepting new connections.
102 ACE_SOCK_Acceptor::accept (ACE_SOCK_Stream &new_stream,
103 ACE_Addr *remote_addr,
104 ACE_Time_Value *timeout,
105 bool restart,
106 bool reset_new_handle) const
108 ACE_TRACE ("ACE_SOCK_Acceptor::accept");
110 int in_blocking_mode = 0;
111 if (this->shared_accept_start (timeout,
112 restart,
113 in_blocking_mode) == -1)
114 return -1;
115 else
117 // On Win32 the third parameter to <accept> must be a NULL
118 // pointer if we want to ignore the client's address.
119 int *len_ptr = 0;
120 sockaddr *addr = 0;
121 int len = 0;
123 if (remote_addr != 0)
125 len = remote_addr->get_size ();
126 len_ptr = &len;
127 addr = (sockaddr *) remote_addr->get_addr ();
131 new_stream.set_handle (ACE_OS::accept (this->get_handle (),
132 addr,
133 len_ptr));
134 while (new_stream.get_handle () == ACE_INVALID_HANDLE
135 && restart
136 && errno == EINTR
137 && timeout == 0);
139 // Reset the size of the addr, so the proper UNIX/IPv4/IPv6 family
140 // is known.
141 if (new_stream.get_handle () != ACE_INVALID_HANDLE
142 && remote_addr != 0)
144 remote_addr->set_size (len);
145 if (addr)
146 remote_addr->set_type (addr->sa_family);
150 return this->shared_accept_finish (new_stream,
151 in_blocking_mode,
152 reset_new_handle);
156 ACE_SOCK_Acceptor::accept (ACE_SOCK_Stream &new_stream,
157 ACE_Accept_QoS_Params qos_params,
158 ACE_Addr *remote_addr,
159 ACE_Time_Value *timeout,
160 bool restart,
161 bool reset_new_handle) const
163 ACE_TRACE ("ACE_SOCK_Acceptor::accept");
165 int in_blocking_mode = 0;
166 if (this->shared_accept_start (timeout,
167 restart,
168 in_blocking_mode) == -1)
169 return -1;
170 else
172 // On Win32 the third parameter to <accept> must be a NULL
173 // pointer if we want to ignore the client's address.
174 int *len_ptr = 0;
175 int len = 0;
176 sockaddr *addr = 0;
178 if (remote_addr != 0)
180 len = remote_addr->get_size ();
181 len_ptr = &len;
182 addr = (sockaddr *) remote_addr->get_addr ();
186 new_stream.set_handle (ACE_OS::accept (this->get_handle (),
187 addr,
188 len_ptr,
189 qos_params));
190 while (new_stream.get_handle () == ACE_INVALID_HANDLE
191 && restart
192 && errno == EINTR
193 && timeout == 0);
195 // Reset the size of the addr, which is only necessary for UNIX
196 // domain sockets.
197 if (new_stream.get_handle () != ACE_INVALID_HANDLE
198 && remote_addr != 0)
199 remote_addr->set_size (len);
202 return this->shared_accept_finish (new_stream,
203 in_blocking_mode,
204 reset_new_handle);
207 void
208 ACE_SOCK_Acceptor::dump () const
210 #if defined (ACE_HAS_DUMP)
211 ACE_TRACE ("ACE_SOCK_Acceptor::dump");
212 #endif /* ACE_HAS_DUMP */
216 ACE_SOCK_Acceptor::shared_open (const ACE_Addr &local_sap,
217 int protocol_family,
218 int backlog,
219 int ipv6_only)
221 ACE_TRACE ("ACE_SOCK_Acceptor::shared_open");
222 int error = 0;
224 #if !defined (ACE_HAS_IPV6)
225 ACE_UNUSED_ARG (ipv6_only);
226 #else /* defined (ACE_HAS_IPV6) */
227 if (protocol_family == PF_INET6)
229 sockaddr_in6 local_inet6_addr;
230 ACE_OS::memset (reinterpret_cast<void *> (&local_inet6_addr),
232 sizeof local_inet6_addr);
234 if (local_sap == ACE_Addr::sap_any)
236 local_inet6_addr.sin6_family = AF_INET6;
237 local_inet6_addr.sin6_port = 0;
238 local_inet6_addr.sin6_addr = in6addr_any;
240 else
241 local_inet6_addr = *reinterpret_cast<sockaddr_in6 *> (local_sap.get_addr ());
244 * Handle IPv6-only requests. On Windows, v6-only is the default
245 * unless it is turned off. On Linux, v4/v6 dual is the default
246 * unless v6-only is turned on.
247 * This must be done before attempting to bind the address.
248 * On Windows older than Vista this will fail.
250 int setting = !!ipv6_only;
251 if (-1 == ACE_OS::setsockopt (this->get_handle (),
252 IPPROTO_IPV6,
253 IPV6_V6ONLY,
254 (char *)&setting,
255 sizeof (setting)))
256 error = 1;
257 else
258 // We probably don't need a bind_port written here.
259 // There are currently no supported OS's that define
260 // ACE_LACKS_WILDCARD_BIND.
261 if (ACE_OS::bind (this->get_handle (),
262 reinterpret_cast<sockaddr *> (&local_inet6_addr),
263 sizeof local_inet6_addr) == -1)
264 error = 1;
266 else
267 #endif /* ACE_HAS_IPV6 */
268 if (protocol_family == PF_INET)
270 sockaddr_in local_inet_addr;
271 ACE_OS::memset (reinterpret_cast<void *> (&local_inet_addr),
273 sizeof local_inet_addr);
275 if (local_sap == ACE_Addr::sap_any)
277 local_inet_addr.sin_port = 0;
279 else
280 local_inet_addr = *reinterpret_cast<sockaddr_in *> (local_sap.get_addr ());
281 if (local_inet_addr.sin_port == 0)
283 if (ACE::bind_port (this->get_handle (),
284 ACE_NTOHL (ACE_UINT32 (local_inet_addr.sin_addr.s_addr))) == -1)
285 error = 1;
287 else if (ACE_OS::bind (this->get_handle (),
288 reinterpret_cast<sockaddr *> (&local_inet_addr),
289 sizeof local_inet_addr) == -1)
290 error = 1;
292 else if (ACE_OS::bind (this->get_handle (),
293 (sockaddr *) local_sap.get_addr (),
294 local_sap.get_size ()) == -1)
295 error = 1;
297 if (error != 0
298 || ACE_OS::listen (this->get_handle (),
299 backlog) == -1)
301 ACE_Errno_Guard g (errno); // Preserve across close() below.
302 error = 1;
303 this->close ();
306 return error ? -1 : 0;
310 ACE_SOCK_Acceptor::open (const ACE_Addr &local_sap,
311 ACE_Protocol_Info *protocolinfo,
312 ACE_SOCK_GROUP g,
313 u_long flags,
314 int reuse_addr,
315 int protocol_family,
316 int backlog,
317 int protocol,
318 int ipv6_only)
320 ACE_TRACE ("ACE_SOCK_Acceptor::open");
322 if (protocol_family == PF_UNSPEC)
323 protocol_family = local_sap.get_type ();
325 if (ACE_SOCK::open (SOCK_STREAM,
326 protocol_family,
327 protocol,
328 protocolinfo,
330 flags,
331 reuse_addr) == -1)
332 return -1;
333 else
334 return this->shared_open (local_sap,
335 protocol_family,
336 backlog,
337 ipv6_only);
340 ACE_SOCK_Acceptor::ACE_SOCK_Acceptor (const ACE_Addr &local_sap,
341 ACE_Protocol_Info *protocolinfo,
342 ACE_SOCK_GROUP g,
343 u_long flags,
344 int reuse_addr,
345 int protocol_family,
346 int backlog,
347 int protocol,
348 int ipv6_only)
350 ACE_TRACE ("ACE_SOCK_Acceptor::ACE_SOCK_Acceptor");
351 if (this->open (local_sap,
352 protocolinfo,
354 flags,
355 reuse_addr,
356 protocol_family,
357 backlog,
358 protocol,
359 ipv6_only) == -1)
360 ACELIB_ERROR ((LM_ERROR,
361 ACE_TEXT ("%p\n"),
362 ACE_TEXT ("ACE_SOCK_Acceptor")));
365 // General purpose routine for performing server ACE_SOCK creation.
368 ACE_SOCK_Acceptor::open (const ACE_Addr &local_sap,
369 int reuse_addr,
370 int protocol_family,
371 int backlog,
372 int protocol,
373 int ipv6_only)
375 ACE_TRACE ("ACE_SOCK_Acceptor::open");
377 if (local_sap != ACE_Addr::sap_any)
378 protocol_family = local_sap.get_type ();
379 else if (protocol_family == PF_UNSPEC)
381 #if defined (ACE_HAS_IPV6)
382 protocol_family = ACE::ipv6_enabled () ? PF_INET6 : PF_INET;
383 #else
384 protocol_family = PF_INET;
385 #endif /* ACE_HAS_IPV6 */
388 if (ACE_SOCK::open (SOCK_STREAM,
389 protocol_family,
390 protocol,
391 reuse_addr) == -1)
392 return -1;
393 else
394 return this->shared_open (local_sap,
395 protocol_family,
396 backlog,
397 ipv6_only);
400 // General purpose routine for performing server ACE_SOCK creation.
402 ACE_SOCK_Acceptor::ACE_SOCK_Acceptor (const ACE_Addr &local_sap,
403 int reuse_addr,
404 int protocol_family,
405 int backlog,
406 int protocol,
407 int ipv6_only)
409 ACE_TRACE ("ACE_SOCK_Acceptor::ACE_SOCK_Acceptor");
410 if (this->open (local_sap,
411 reuse_addr,
412 protocol_family,
413 backlog,
414 protocol,
415 ipv6_only) == -1)
416 ACELIB_ERROR ((LM_ERROR,
417 ACE_TEXT ("%p\n"),
418 ACE_TEXT ("ACE_SOCK_Acceptor")));
422 ACE_SOCK_Acceptor::close ()
424 return ACE_SOCK::close ();
427 ACE_END_VERSIONED_NAMESPACE_DECL