2 ** Copyright 2002 Addison Wesley. All Rights Reserved.
5 #include "ace/config-all.h"
7 #if defined (ACE_WIN32) || (defined (ACE_HAS_AIO_CALLS))
9 #include "ace/OS_NS_string.h"
10 #include "ace/OS_NS_sys_socket.h"
11 #include "ace/Asynch_Acceptor.h"
12 #include "ace/Asynch_Connector.h"
13 #include "ace/Asynch_IO.h"
14 #include "ace/CDR_Stream.h"
15 #include "ace/Get_Opt.h"
16 #include "ace/INET_Addr.h"
17 #include "ace/Message_Block.h"
18 #include "ace/Null_Condition.h"
19 #include "ace/Null_Mutex.h"
20 #include "ace/Proactor.h"
21 #include "ace/SOCK_Stream.h"
22 #include "ace/Service_Object.h"
23 #include "ace/Signal.h"
24 #include "ace/Singleton.h"
26 #include "ace/Thread_Manager.h"
27 #include "ace/Unbounded_Set.h"
28 #include "ace/os_include/os_netdb.h"
29 #include "AIO_CLD_export.h"
30 #include "AIO_Client_Logging_Daemon.h"
31 #include <openssl/ssl.h>
33 class AIO_CLD_Acceptor
34 : public ACE_Asynch_Acceptor
<AIO_Input_Handler
> {
36 //FUZZ: disable check_for_lack_ACE_OS
37 // Cancel accept and close all clients.
39 //FUZZ: enable check_for_lack_ACE_OS
41 // Remove handler from client set.
42 void remove (AIO_Input_Handler
*ih
)
43 { clients_
.remove (ih
); }
46 // Service handler factory method.
47 virtual AIO_Input_Handler
*make_handler ();
49 // Set of all connected clients
50 ACE_Unbounded_Set
<AIO_Input_Handler
*> clients_
;
54 class AIO_Client_Logging_Daemon
: public ACE_Task
<ACE_NULL_SYNCH
> {
56 ACE_INET_Addr cld_addr_
;
57 ACE_INET_Addr sld_addr_
;
59 // Factory that passively connects the <AIO_Input_Handler>.
60 AIO_CLD_Acceptor acceptor_
;
63 // Service Configurator hook methods.
64 virtual int init (int argc
, ACE_TCHAR
*argv
[]);
69 /******************************************************/
71 AIO_Output_Handler::~AIO_Output_Handler () {
74 ACE_OS::closesocket (handle ());
77 int AIO_Output_Handler::put (ACE_Message_Block
*mb
,
78 ACE_Time_Value
*timeout
) {
79 if (can_write_
) { start_write (mb
); return 0; }
80 return putq (mb
, timeout
);
83 void AIO_Output_Handler::open
84 (ACE_HANDLE new_handle
, ACE_Message_Block
&) {
85 ACE_SOCK_Stream
peer (new_handle
);
86 int bufsiz
= ACE_DEFAULT_MAX_SOCKET_BUFSIZ
;
87 peer
.set_option (SOL_SOCKET
, SO_SNDBUF
,
88 &bufsiz
, sizeof bufsiz
);
90 reader_
.open (*this, new_handle
, 0, proactor ());
91 writer_
.open (*this, new_handle
, 0, proactor ());
93 ACE_Message_Block
*mb
= 0;
94 ACE_NEW (mb
, ACE_Message_Block (1));
95 reader_
.read (*mb
, 1);
96 ACE_Sig_Action
no_sigpipe ((ACE_SignalHandler
) SIG_IGN
);
97 no_sigpipe
.register_action (SIGPIPE
, 0);
102 void AIO_Output_Handler::start_write (ACE_Message_Block
*mblk
) {
104 ACE_Time_Value
nonblock (0);
105 getq (mblk
, &nonblock
);
109 if (writer_
.write (*mblk
, mblk
->length ()) == -1)
114 void AIO_Output_Handler::handle_read_stream
115 (const ACE_Asynch_Read_Stream::Result
&result
) {
116 result
.message_block ().release ();
118 ACE_OS::closesocket (result
.handle ());
119 handle (ACE_INVALID_HANDLE
);
121 CLD_CONNECTOR::instance ()->reconnect ();
124 void AIO_Output_Handler::handle_write_stream
125 (const ACE_Asynch_Write_Stream::Result
&result
) {
126 ACE_Message_Block
&mblk
= result
.message_block ();
127 if (!result
.success ()) {
128 mblk
.rd_ptr (mblk
.base ());
132 can_write_
= handle () == result
.handle ();
133 if (mblk
.length () == 0) {
135 if (can_write_
) start_write ();
137 else if (can_write_
) start_write (&mblk
);
138 else { mblk
.rd_ptr (mblk
.base ()); ungetq (&mblk
); }
142 /******************************************************/
144 AIO_Input_Handler::~AIO_Input_Handler () {
146 ACE_OS::closesocket (handle ());
147 if (mblk_
!= 0) mblk_
->release ();
149 acceptor_
->remove (this);
152 void AIO_Input_Handler::open
153 (ACE_HANDLE new_handle
, ACE_Message_Block
&) {
154 reader_
.open (*this, new_handle
, 0, proactor ());
156 (mblk_
, ACE_Message_Block (ACE_DEFAULT_CDR_BUFSIZE
));
157 // Align the Message Block for a CDR stream
158 ACE_CDR::mb_align (mblk_
);
159 reader_
.read (*mblk_
, LOG_HEADER_SIZE
);
162 void AIO_Input_Handler::handle_read_stream
163 (const ACE_Asynch_Read_Stream::Result
&result
) {
164 if (!result
.success () || result
.bytes_transferred () == 0)
166 else if (result
.bytes_transferred () < result
.bytes_to_read ())
167 reader_
.read (*mblk_
, result
.bytes_to_read () -
168 result
.bytes_transferred ());
169 else if (mblk_
->length () == LOG_HEADER_SIZE
) {
170 ACE_InputCDR
cdr (mblk_
);
172 ACE_CDR::Boolean byte_order
;
173 cdr
>> ACE_InputCDR::to_boolean (byte_order
);
174 cdr
.reset_byte_order (byte_order
);
176 ACE_CDR::ULong length
;
179 mblk_
->size (length
+ LOG_HEADER_SIZE
);
180 reader_
.read (*mblk_
, length
);
183 if (OUTPUT_HANDLER::instance ()->put (mblk_
) == -1)
187 (mblk_
, ACE_Message_Block (ACE_DEFAULT_CDR_BUFSIZE
));
188 ACE_CDR::mb_align (mblk_
);
189 reader_
.read (*mblk_
, LOG_HEADER_SIZE
);
193 /********************************************************/
195 void AIO_CLD_Acceptor::close () {
196 ACE_Unbounded_Set_Iterator
<AIO_Input_Handler
*>
197 iter (clients_
.begin ());
198 AIO_Input_Handler
**ih
;
199 for (; iter
.next (ih
); ++iter
)
203 AIO_Input_Handler
* AIO_CLD_Acceptor::make_handler () {
204 AIO_Input_Handler
*ih
;
205 ACE_NEW_RETURN (ih
, AIO_Input_Handler (this), 0);
206 if (clients_
.insert (ih
) == -1)
207 { delete ih
; return 0; }
211 /*******************************************************/
213 #if !defined (CLD_CERTIFICATE_FILENAME)
214 # define CLD_CERTIFICATE_FILENAME "cld-cert.pem"
215 #endif /* !CLD_CERTIFICATE_FILENAME */
216 #if !defined (CLD_KEY_FILENAME)
217 # define CLD_KEY_FILENAME "cld-key.pem"
218 #endif /* !CLD_KEY_FILENAME */
221 int AIO_CLD_Connector::validate_connection
222 (const ACE_Asynch_Connect::Result
& result
,
223 const ACE_INET_Addr
&remote
, const ACE_INET_Addr
&) {
224 remote_addr_
= remote
;
225 if (!result
.success ()) {
226 ACE_Time_Value
delay (retry_delay_
);
228 if (retry_delay_
> MAX_RETRY_DELAY
)
229 retry_delay_
= MAX_RETRY_DELAY
;
230 proactor ()->schedule_timer (*this, 0, delay
);
233 retry_delay_
= INITIAL_RETRY_DELAY
;
236 OpenSSL_add_ssl_algorithms ();
237 ssl_ctx_
= SSL_CTX_new (SSLv23_client_method ());
238 if (ssl_ctx_
== 0) return -1;
240 if (SSL_CTX_use_certificate_file (ssl_ctx_
,
241 CLD_CERTIFICATE_FILENAME
,
242 SSL_FILETYPE_PEM
) <= 0
243 || SSL_CTX_use_PrivateKey_file (ssl_ctx_
,
245 SSL_FILETYPE_PEM
) <= 0
246 || !SSL_CTX_check_private_key (ssl_ctx_
)) {
247 SSL_CTX_free (ssl_ctx_
);
251 ssl_
= SSL_new (ssl_ctx_
);
253 SSL_CTX_free (ssl_ctx_
); ssl_ctx_
= 0;
259 #if defined (ACE_WIN32)
260 // ACE_WIN32 is the only platform where ACE_HANDLE is not an int.
261 // See ace/config-lite.h for the typedefs.
262 SSL_set_fd (ssl_
, reinterpret_cast<int> (result
.connect_handle ()));
264 SSL_set_fd (ssl_
, result
.connect_handle ());
265 #endif /* ACE_WIN32 */
266 SSL_set_verify (ssl_
, SSL_VERIFY_PEER
, 0);
268 if (SSL_connect (ssl_
) == -1
269 || SSL_shutdown (ssl_
) == -1) return -1;
273 void AIO_CLD_Connector::handle_time_out
274 (const ACE_Time_Value
&, const void *) {
275 this->connect (remote_addr_
);
278 /******************************************************/
280 int AIO_Client_Logging_Daemon::init
281 (int argc
, ACE_TCHAR
*argv
[]) {
282 u_short cld_port
= ACE_DEFAULT_SERVICE_PORT
;
283 u_short sld_port
= ACE_DEFAULT_LOGGING_SERVER_PORT
;
284 ACE_TCHAR sld_host
[MAXHOSTNAMELEN
];
285 ACE_OS::strcpy (sld_host
, ACE_LOCALHOST
);
287 ACE_Get_Opt
get_opt (argc
, argv
, ACE_TEXT ("p:r:s:"), 0);
288 get_opt
.long_option (ACE_TEXT ("client_port"), 'p',
289 ACE_Get_Opt::ARG_REQUIRED
);
290 get_opt
.long_option (ACE_TEXT ("server_port"), 'r',
291 ACE_Get_Opt::ARG_REQUIRED
);
292 get_opt
.long_option (ACE_TEXT ("server_name"), 's',
293 ACE_Get_Opt::ARG_REQUIRED
);
295 for (int c
; (c
= get_opt ()) != -1;)
297 case 'p': // Client logging daemon acceptor port number.
298 cld_port
= static_cast<u_short
> (ACE_OS::atoi (get_opt
.opt_arg ()));
300 case 'r': // Server logging daemon acceptor port number.
301 sld_port
= static_cast<u_short
> (ACE_OS::atoi (get_opt
.opt_arg ()));
303 case 's': // Server logging daemon hostname.
305 (sld_host
, get_opt
.opt_arg (), MAXHOSTNAMELEN
);
309 if (cld_addr_
.set (cld_port
) == -1 ||
310 sld_addr_
.set (sld_port
, sld_host
) == -1)
315 int AIO_Client_Logging_Daemon::fini () {
316 ACE_Proactor::instance ()->proactor_end_event_loop ();
321 int AIO_Client_Logging_Daemon::svc () {
322 if (acceptor_
.open (cld_addr_
) == -1) return -1;
323 if (CLD_CONNECTOR::instance ()->connect (sld_addr_
) == 0)
324 ACE_Proactor::instance ()->proactor_run_event_loop ();
326 CLD_CONNECTOR::close ();
327 OUTPUT_HANDLER::close ();
331 #else /* There's no AIO support on this platform */
333 #include "ace/Task.h"
334 #include "ace/Service_Object.h"
335 #include "ace/Synch_Traits.h"
336 #include "AIO_CLD_export.h"
338 class AIO_Client_Logging_Daemon
: public ACE_Task
<ACE_NULL_SYNCH
> {
340 // Service Configurator hook methods.
341 virtual int init (int, ACE_TCHAR
*[]);
345 int AIO_Client_Logging_Daemon::init (int, ACE_TCHAR
*[]) {
347 ((LM_ERROR
, ACE_TEXT ("This service requires AIO support\n")), -1);
350 int AIO_Client_Logging_Daemon::fini () {
354 #endif /* ACE_WIN32 || ACE_HAS_AIO_CALLS */
356 ACE_FACTORY_DEFINE (AIO_CLD
, AIO_Client_Logging_Daemon
)