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.
32 ACE_SOCK_Acceptor::shared_accept_start (ACE_Time_Value
*timeout
,
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>.
43 if (ACE::handle_timed_accept (handle
,
49 in_blocking_mode
= ACE_BIT_DISABLED (ACE::get_flags (handle
),
51 // Set the handle into non-blocking mode if it's not already
54 && ACE::set_flags (handle
,
64 ACE_SOCK_Acceptor::shared_accept_finish (ACE_SOCK_Stream new_stream
,
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
77 // Save/restore errno.
78 ACE_Errno_Guard
error (errno
);
80 // Only disable ACE_NONBLOCK if we weren't in non-blocking mode
82 ACE::clr_flags (this->get_handle (),
84 ACE::clr_flags (new_handle
,
88 #if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
90 // Reset the event association inherited by the new handle.
91 ::WSAEventSelect ((SOCKET
) new_handle
, 0, 0);
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
,
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
,
113 in_blocking_mode
) == -1)
117 // On Win32 the third parameter to <accept> must be a NULL
118 // pointer if we want to ignore the client's address.
123 if (remote_addr
!= 0)
125 len
= remote_addr
->get_size ();
127 addr
= (sockaddr
*) remote_addr
->get_addr ();
131 new_stream
.set_handle (ACE_OS::accept (this->get_handle (),
134 while (new_stream
.get_handle () == ACE_INVALID_HANDLE
139 // Reset the size of the addr, so the proper UNIX/IPv4/IPv6 family
141 if (new_stream
.get_handle () != ACE_INVALID_HANDLE
144 remote_addr
->set_size (len
);
146 remote_addr
->set_type (addr
->sa_family
);
150 return this->shared_accept_finish (new_stream
,
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
,
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
,
168 in_blocking_mode
) == -1)
172 // On Win32 the third parameter to <accept> must be a NULL
173 // pointer if we want to ignore the client's address.
178 if (remote_addr
!= 0)
180 len
= remote_addr
->get_size ();
182 addr
= (sockaddr
*) remote_addr
->get_addr ();
186 new_stream
.set_handle (ACE_OS::accept (this->get_handle (),
190 while (new_stream
.get_handle () == ACE_INVALID_HANDLE
195 // Reset the size of the addr, which is only necessary for UNIX
197 if (new_stream
.get_handle () != ACE_INVALID_HANDLE
199 remote_addr
->set_size (len
);
202 return this->shared_accept_finish (new_stream
,
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
,
221 ACE_TRACE ("ACE_SOCK_Acceptor::shared_open");
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
;
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 (),
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)
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;
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)
287 else if (ACE_OS::bind (this->get_handle (),
288 reinterpret_cast<sockaddr
*> (&local_inet_addr
),
289 sizeof local_inet_addr
) == -1)
292 else if (ACE_OS::bind (this->get_handle (),
293 (sockaddr
*) local_sap
.get_addr (),
294 local_sap
.get_size ()) == -1)
298 || ACE_OS::listen (this->get_handle (),
301 ACE_Errno_Guard
g (errno
); // Preserve across close() below.
306 return error
? -1 : 0;
310 ACE_SOCK_Acceptor::open (const ACE_Addr
&local_sap
,
311 ACE_Protocol_Info
*protocolinfo
,
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
,
334 return this->shared_open (local_sap
,
340 ACE_SOCK_Acceptor::ACE_SOCK_Acceptor (const ACE_Addr
&local_sap
,
341 ACE_Protocol_Info
*protocolinfo
,
350 ACE_TRACE ("ACE_SOCK_Acceptor::ACE_SOCK_Acceptor");
351 if (this->open (local_sap
,
360 ACELIB_ERROR ((LM_ERROR
,
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
,
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
;
384 protocol_family
= PF_INET
;
385 #endif /* ACE_HAS_IPV6 */
388 if (ACE_SOCK::open (SOCK_STREAM
,
394 return this->shared_open (local_sap
,
400 // General purpose routine for performing server ACE_SOCK creation.
402 ACE_SOCK_Acceptor::ACE_SOCK_Acceptor (const ACE_Addr
&local_sap
,
409 ACE_TRACE ("ACE_SOCK_Acceptor::ACE_SOCK_Acceptor");
410 if (this->open (local_sap
,
416 ACELIB_ERROR ((LM_ERROR
,
418 ACE_TEXT ("ACE_SOCK_Acceptor")));
422 ACE_SOCK_Acceptor::close ()
424 return ACE_SOCK::close ();
427 ACE_END_VERSIONED_NAMESPACE_DECL