1 // $Id: Asynch_Connector.cpp 80826 2008-03-04 14:51:23Z wotte $
3 #ifndef ACE_ASYNCH_CONNECTOR_CPP
4 #define ACE_ASYNCH_CONNECTOR_CPP
6 #include "ace/Asynch_Connector.h"
8 #if !defined (ACE_LACKS_PRAGMA_ONCE)
10 #endif /* ACE_LACKS_PRAGMA_ONCE */
12 #if (defined (ACE_WIN32) || defined (ACE_HAS_AIO_CALLS)) && !defined(ACE_HAS_WINCE)
13 // This only works on platforms that support async I/O.
15 #include "ace/OS_NS_sys_socket.h"
16 #include "ace/OS_Memory.h"
17 #include "ace/Flag_Manip.h"
18 #include "ace/Log_Msg.h"
19 #include "ace/Message_Block.h"
20 #include "ace/INET_Addr.h"
22 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
24 template <class HANDLER
>
25 ACE_Asynch_Connector
<HANDLER
>::ACE_Asynch_Connector (void)
26 : pass_addresses_ (false),
27 validate_new_connection_ (false)
31 template <class HANDLER
>
32 ACE_Asynch_Connector
<HANDLER
>::~ACE_Asynch_Connector (void)
34 //this->asynch_connect_.close ();
37 template <class HANDLER
> int
38 ACE_Asynch_Connector
<HANDLER
>::open (bool pass_addresses
,
39 ACE_Proactor
*proactor
,
40 bool validate_new_connection
)
42 this->proactor (proactor
);
43 this->pass_addresses_
= pass_addresses
;
44 this->validate_new_connection_
= validate_new_connection
;
46 // Initialize the ACE_Asynch_Connect
47 if (this->asynch_connect_
.open (*this,
50 this->proactor ()) == -1)
51 ACE_ERROR_RETURN ((LM_ERROR
,
53 ACE_TEXT ("ACE_Asynch_Connect::open")),
58 template <class HANDLER
> int
59 ACE_Asynch_Connector
<HANDLER
>::connect (const ACE_INET_Addr
& remote_sap
,
60 const ACE_INET_Addr
& local_sap
,
64 // Initiate asynchronous connect
65 if (this->asynch_connect_
.connect (ACE_INVALID_HANDLE
,
70 ACE_ERROR_RETURN ((LM_ERROR
,
72 ACE_TEXT ("ACE_Asynch_Connect::connect")),
77 template <class HANDLER
> void
78 ACE_Asynch_Connector
<HANDLER
>::handle_connect (const ACE_Asynch_Connect::Result
&result
)
80 // Variable for error tracking
83 // If the asynchronous connect fails.
84 if (!result
.success () ||
85 result
.connect_handle () == ACE_INVALID_HANDLE
)
90 if (result
.error () != 0)
98 (result
.connect_handle (), ACE_NONBLOCK
) != 0)
101 ACE_ERROR ((LM_ERROR
,
103 ACE_TEXT ("ACE_Asynch_Connector::handle_connect : Set blocking mode")));
106 // Parse the addresses.
107 ACE_INET_Addr local_address
;
108 ACE_INET_Addr remote_address
;
110 (this->validate_new_connection_
|| this->pass_addresses_
))
111 this->parse_address (result
,
115 // Call validate_connection even if there was an error - it's the only
116 // way the application can learn the connect disposition.
117 if (this->validate_new_connection_
&&
118 this->validate_connection (result
, remote_address
, local_address
) == -1)
123 HANDLER
*new_handler
= 0;
126 // The Template method
127 new_handler
= this->make_handler ();
128 if (new_handler
== 0)
131 ACE_ERROR ((LM_ERROR
,
133 ACE_TEXT ("ACE_Asynch_Connector::handle_connect : Making of new handler failed")));
140 // Update the Proactor.
141 new_handler
->proactor (this->proactor ());
143 // Pass the addresses
144 if (this->pass_addresses_
)
145 new_handler
->addresses (remote_address
,
149 if (result
.act () != 0)
150 new_handler
->act (result
.act ());
152 // Set up the handler's new handle value
153 new_handler
->handle (result
.connect_handle ());
155 ACE_Message_Block mb
;
157 // Initiate the handler with empty message block;
158 new_handler
->open (result
.connect_handle (), mb
);
161 // On failure, no choice but to close the socket
163 result
.connect_handle() != ACE_INVALID_HANDLE
)
164 ACE_OS::closesocket (result
.connect_handle ());
167 template <class HANDLER
> int
168 ACE_Asynch_Connector
<HANDLER
>::validate_connection
169 (const ACE_Asynch_Connect::Result
&,
170 const ACE_INET_Addr
& /* remote_address */,
171 const ACE_INET_Addr
& /* local_address */)
173 // Default implementation always validates the remote address.
177 template <class HANDLER
> int
178 ACE_Asynch_Connector
<HANDLER
>::cancel (void)
180 return this->asynch_connect_
.cancel ();
183 template <class HANDLER
> void
184 ACE_Asynch_Connector
<HANDLER
>::parse_address (const ACE_Asynch_Connect::Result
&result
,
185 ACE_INET_Addr
&remote_address
,
186 ACE_INET_Addr
&local_address
)
188 #if defined (ACE_HAS_IPV6)
189 // Getting the addresses.
190 sockaddr_in6 local_addr
;
191 sockaddr_in6 remote_addr
;
193 // Getting the addresses.
194 sockaddr_in local_addr
;
195 sockaddr_in remote_addr
;
196 #endif /* ACE_HAS_IPV6 */
199 int local_size
= sizeof (local_addr
);
200 int remote_size
= sizeof (remote_addr
);
202 // Get the local address.
203 if (ACE_OS::getsockname (result
.connect_handle (),
204 reinterpret_cast<sockaddr
*> (&local_addr
),
206 ACE_ERROR ((LM_ERROR
,
208 ACE_TEXT("ACE_Asynch_Connector::<getsockname> failed")));
210 // Get the remote address.
211 if (ACE_OS::getpeername (result
.connect_handle (),
212 reinterpret_cast<sockaddr
*> (&remote_addr
),
214 ACE_ERROR ((LM_ERROR
,
216 ACE_TEXT("ACE_Asynch_Connector::<getpeername> failed")));
218 // Set the addresses.
219 local_address
.set (reinterpret_cast<sockaddr_in
*> (&local_addr
),
221 remote_address
.set (reinterpret_cast<sockaddr_in
*> (&remote_addr
),
225 // @@ Just debugging.
226 char local_address_buf
[BUFSIZ
];
227 char remote_address_buf
[BUFSIZ
];
229 if (local_address
.addr_to_string (local_address_buf
,
230 sizeof local_address_buf
) == -1)
231 ACE_ERROR ((LM_ERROR
,
232 "Error:%m:can't obtain local_address's address string"));
234 ACE_DEBUG ((LM_DEBUG
,
235 "ACE_Asynch_Connector<HANDLER>::parse_address : "
236 "Local address %s\n",
239 if (remote_address
.addr_to_string (remote_address_buf
,
240 sizeof remote_address_buf
) == -1)
241 ACE_ERROR ((LM_ERROR
,
242 "Error:%m:can't obtain remote_address's address string"));
244 ACE_DEBUG ((LM_DEBUG
,
245 "ACE_Asynch_Connector<HANDLER>::parse_address : "
246 "Remote address %s\n",
247 remote_address_buf
));
254 template <class HANDLER
> ACE_Asynch_Connect
&
255 ACE_Asynch_Connector
<HANDLER
>::asynch_connect (void)
257 return this->asynch_connect_
;
260 template <class HANDLER
> HANDLER
*
261 ACE_Asynch_Connector
<HANDLER
>::make_handler (void)
264 HANDLER
*handler
= 0;
265 ACE_NEW_RETURN (handler
, HANDLER
, 0);
269 template <class HANDLER
> bool
270 ACE_Asynch_Connector
<HANDLER
>::pass_addresses (void) const
272 return this->pass_addresses_
;
275 template <class HANDLER
> void
276 ACE_Asynch_Connector
<HANDLER
>::pass_addresses (bool new_value
)
278 this->pass_addresses_
= new_value
;
281 template <class HANDLER
> bool
282 ACE_Asynch_Connector
<HANDLER
>::validate_new_connection (void) const
284 return this->validate_new_connection_
;
287 template <class HANDLER
> void
288 ACE_Asynch_Connector
<HANDLER
>::validate_new_connection (bool new_value
)
290 this->validate_new_connection_
= new_value
;
293 ACE_END_VERSIONED_NAMESPACE_DECL
295 #endif /* ACE_WIN32 || ACE_HAS_AIO_CALLS */
296 #endif /* ACE_ASYNCH_CONNECTOR_CPP */