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.
36 ACE_SOCK_Acceptor::shared_accept_start (ACE_Time_Value
*timeout
,
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>.
47 if (ACE::handle_timed_accept (handle
,
53 in_blocking_mode
= ACE_BIT_DISABLED (ACE::get_flags (handle
),
55 // Set the handle into non-blocking mode if it's not already
58 && ACE::set_flags (handle
,
68 ACE_SOCK_Acceptor::shared_accept_finish (ACE_SOCK_Stream new_stream
,
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
81 // Save/restore errno.
82 ACE_Errno_Guard
error (errno
);
84 // Only disable ACE_NONBLOCK if we weren't in non-blocking mode
86 ACE::clr_flags (this->get_handle (),
88 ACE::clr_flags (new_handle
,
92 #if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
94 // Reset the event association inherited by the new handle.
95 ::WSAEventSelect ((SOCKET
) new_handle
, 0, 0);
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
,
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
,
117 in_blocking_mode
) == -1)
121 // On Win32 the third parameter to <accept> must be a NULL
122 // pointer if we want to ignore the client's address.
127 if (remote_addr
!= 0)
129 len
= remote_addr
->get_size ();
131 addr
= (sockaddr
*) remote_addr
->get_addr ();
135 new_stream
.set_handle (ACE_OS::accept (this->get_handle (),
138 while (new_stream
.get_handle () == ACE_INVALID_HANDLE
143 // Reset the size of the addr, so the proper UNIX/IPv4/IPv6 family
145 if (new_stream
.get_handle () != ACE_INVALID_HANDLE
148 remote_addr
->set_size (len
);
150 remote_addr
->set_type (addr
->sa_family
);
154 return this->shared_accept_finish (new_stream
,
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
,
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
,
173 in_blocking_mode
) == -1)
177 // On Win32 the third parameter to <accept> must be a NULL
178 // pointer if we want to ignore the client's address.
183 if (remote_addr
!= 0)
185 len
= remote_addr
->get_size ();
187 addr
= (sockaddr
*) remote_addr
->get_addr ();
191 new_stream
.set_handle (ACE_OS::accept (this->get_handle (),
195 while (new_stream
.get_handle () == ACE_INVALID_HANDLE
200 // Reset the size of the addr, which is only necessary for UNIX
202 if (new_stream
.get_handle () != ACE_INVALID_HANDLE
204 remote_addr
->set_size (len
);
207 return this->shared_accept_finish (new_stream
,
211 #endif // ACE_HAS_WINCE
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
,
227 ACE_TRACE ("ACE_SOCK_Acceptor::shared_open");
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
;
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 (),
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)
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;
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)
293 else if (ACE_OS::bind (this->get_handle (),
294 reinterpret_cast<sockaddr
*> (&local_inet_addr
),
295 sizeof local_inet_addr
) == -1)
298 else if (ACE_OS::bind (this->get_handle (),
299 (sockaddr
*) local_sap
.get_addr (),
300 local_sap
.get_size ()) == -1)
304 || ACE_OS::listen (this->get_handle (),
307 ACE_Errno_Guard
g (errno
); // Preserve across close() below.
312 return error
? -1 : 0;
316 ACE_SOCK_Acceptor::open (const ACE_Addr
&local_sap
,
317 ACE_Protocol_Info
*protocolinfo
,
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
,
340 return this->shared_open (local_sap
,
346 ACE_SOCK_Acceptor::ACE_SOCK_Acceptor (const ACE_Addr
&local_sap
,
347 ACE_Protocol_Info
*protocolinfo
,
356 ACE_TRACE ("ACE_SOCK_Acceptor::ACE_SOCK_Acceptor");
357 if (this->open (local_sap
,
366 ACELIB_ERROR ((LM_ERROR
,
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
,
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
;
390 protocol_family
= PF_INET
;
391 #endif /* ACE_HAS_IPV6 */
394 if (ACE_SOCK::open (SOCK_STREAM
,
400 return this->shared_open (local_sap
,
406 // General purpose routine for performing server ACE_SOCK creation.
408 ACE_SOCK_Acceptor::ACE_SOCK_Acceptor (const ACE_Addr
&local_sap
,
415 ACE_TRACE ("ACE_SOCK_Acceptor::ACE_SOCK_Acceptor");
416 if (this->open (local_sap
,
422 ACELIB_ERROR ((LM_ERROR
,
424 ACE_TEXT ("ACE_SOCK_Acceptor")));
428 ACE_SOCK_Acceptor::close (void)
430 return ACE_SOCK::close ();
433 ACE_END_VERSIONED_NAMESPACE_DECL