4 * @brief Main of IKEv2-Daemon
9 * Copyright (C) 2005 Jan Hutter, Martin Willi
10 * Hochschule fuer Technik Rapperswil
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
31 #include <sa/ike_sa_manager.h>
32 #include <threads/sender.h>
33 #include <threads/receiver.h>
34 #include <threads/scheduler.h>
35 #include <threads/thread_pool.h>
36 #include <network/socket.h>
37 #include <utils/allocator.h>
38 #include <utils/logger_manager.h>
39 #include <queues/event_queue.h>
40 #include <queues/job_queue.h>
41 #include <queues/send_queue.h>
42 #include <queues/jobs/initiate_ike_sa_job.h>
45 /* function declaration (defined and described after main function) */
47 static status_t
initialize_globals();
48 static void destroy_globals();
49 static status_t
start_threads();
50 static void end_threads();
51 static void main_loop();
52 static void register_signals();
53 static void destroy_and_exit(int);
55 /** Global job-queue */
56 job_queue_t
*global_job_queue
= NULL
;
57 /** Global event-queue */
58 event_queue_t
*global_event_queue
= NULL
;
59 /** Global send-queue */
60 send_queue_t
*global_send_queue
= NULL
;
62 socket_t
*global_socket
= NULL
;
63 /** Global logger manager */
64 logger_manager_t
*global_logger_manager
= NULL
;
65 /** Global ike_sa-manager */
66 ike_sa_manager_t
*global_ike_sa_manager
= NULL
;
67 /** Global configuration-manager */
68 configuration_manager_t
*global_configuration_manager
= NULL
;
71 * logger_t object assigned for daemon things
73 static logger_t
*logger
= NULL
;
78 static sender_t
*sender_thread
= NULL
;
82 static receiver_t
*receiver_thread
= NULL
;
86 static scheduler_t
*scheduler_thread
= NULL
;
88 * Thread pool holding the worker threads
90 static thread_pool_t
*thread_pool
= NULL
;
93 * Signal set used for signal handling
100 /* set signal handler */
103 /* logger_manager is created first */
104 global_logger_manager
= logger_manager_create(FULL
);
105 if (global_logger_manager
== NULL
)
107 printf("could not create logger manager");
111 /* a own logger for the daemon is created */
112 logger
= global_logger_manager
->create_logger(global_logger_manager
,DAEMON
,NULL
);
115 printf("could not create logger object");
120 /* initialize all global objects */
121 if (initialize_globals() != SUCCESS
)
127 logger
->log(logger
,CONTROL
,"start daemon %s", DAEMON_NAME
);
128 /* now its time to create all the different threads :-) */
129 if (start_threads() != SUCCESS
)
132 logger
->log(logger
,CONTROL
,"Fatal error: Needed Threads could not be started");
133 destroy_and_exit(-1);
139 initiate_ike_sa_job_t
*initiate_job
;
141 initiate_job
= initiate_ike_sa_job_create("pinflb31");
142 global_event_queue
->add_relative(global_event_queue
, (job_t
*)initiate_job
, i
* 1000);
146 logger
->log(logger
,CONTROL
|MORE
,"going to wait for exit signal");
147 /* go and handle signals*/
158 * Waits for registered signals and acts dependently
160 static void main_loop()
167 error
= sigwait(&signal_set
, &signal_number
);
172 logger
->log(logger
,CONTROL
,"Error %d when waiting for signal",error
);
175 switch (signal_number
)
179 logger
->log(logger
,CONTROL
,"Signal of type SIGHUP received. Do nothing");
184 logger
->log(logger
,CONTROL
,"Signal of type SIGINT received. Exit main loop.");
189 logger
->log(logger
,CONTROL
,"Signal of type SIGTERM received. Exit main loop.");
194 logger
->log(logger
,CONTROL
,"Unknown signal %d received. Do nothing",signal_number
);
202 * Registers signals SIGINT, SIGHUP and SIGTERM.
203 * Signals are handled in main_loop()
205 static void register_signals()
207 sigemptyset(&signal_set
);
208 sigaddset(&signal_set
, SIGINT
);
209 sigaddset(&signal_set
, SIGHUP
);
210 sigaddset(&signal_set
, SIGTERM
);
211 pthread_sigmask(SIG_BLOCK
, &signal_set
, 0);
216 * Initializes global objects
222 static status_t
initialize_globals()
224 /* initialize global object */
225 global_socket
= socket_create(IKEV2_UDP_PORT
);
226 global_ike_sa_manager
= ike_sa_manager_create();
227 global_job_queue
= job_queue_create();
228 global_event_queue
= event_queue_create();
229 global_send_queue
= send_queue_create();
230 global_configuration_manager
= configuration_manager_create();
232 if ( (global_socket
== NULL
) ||
233 (global_job_queue
== NULL
) ||
234 (global_event_queue
== NULL
) ||
235 (global_send_queue
== NULL
) ||
236 (global_configuration_manager
== NULL
) ||
237 (global_ike_sa_manager
== NULL
))
246 * Destroy global objects
248 static void destroy_globals()
250 if (global_job_queue
!= NULL
)
252 logger
->log(logger
,CONTROL
|MOST
,"destroy global_job_queue");
253 global_job_queue
->destroy(global_job_queue
);
255 if (global_event_queue
!= NULL
)
257 logger
->log(logger
,CONTROL
|MOST
,"destroy global_event_queue");
258 global_event_queue
->destroy(global_event_queue
);
260 if (global_send_queue
!= NULL
)
262 logger
->log(logger
,CONTROL
|MOST
,"destroy global_send_queue");
263 global_send_queue
->destroy(global_send_queue
);
265 if (global_socket
!= NULL
)
267 logger
->log(logger
,CONTROL
|MOST
,"destroy global_socket");
268 global_socket
->destroy(global_socket
);
270 if (global_ike_sa_manager
!= NULL
)
272 logger
->log(logger
,CONTROL
|MOST
,"destroy global_ike_sa_manager");
273 global_ike_sa_manager
->destroy(global_ike_sa_manager
);
275 if (global_configuration_manager
!= NULL
)
277 logger
->log(logger
,CONTROL
|MOST
,"destroy global_configuration_manager");
278 global_configuration_manager
->destroy(global_configuration_manager
);
283 * Creates all needed Threads
289 static status_t
start_threads()
291 sender_thread
= sender_create();
292 if (sender_thread
== NULL
)
296 scheduler_thread
= scheduler_create();
297 if (scheduler_thread
== NULL
)
301 thread_pool
= thread_pool_create(NUMBER_OF_WORKING_THREADS
);
302 if (thread_pool
== NULL
)
306 receiver_thread
= receiver_create();
307 if (receiver_thread
== NULL
)
320 static void end_threads()
322 if (receiver_thread
!= NULL
)
324 receiver_thread
->destroy(receiver_thread
);
326 if (scheduler_thread
!= NULL
)
328 scheduler_thread
->destroy(scheduler_thread
);
330 if (sender_thread
!= NULL
)
332 sender_thread
->destroy(sender_thread
);
334 if (thread_pool
!= NULL
)
336 thread_pool
->destroy(thread_pool
);
342 * Destroys initialized objects, kills all threads and exits
344 * @param exit_code Code to exit with
346 static void destroy_and_exit(int exit_code
)
348 logger
->log(logger
,CONTROL
,"going to exit daemon");
352 /* all globals can be destroyed now */
355 /* logger is destroyed */
356 logger
->log(logger
,CONTROL
|MORE
,"destroy logger");
357 logger
->log(logger
,CONTROL
|MORE
,"destroy logger_manager");
358 logger
->log(logger
,CONTROL
|MORE
,"------------------------------------");
359 global_logger_manager
->destroy_logger(global_logger_manager
,logger
);
360 global_logger_manager
->destroy(global_logger_manager
);
362 #ifdef LEAK_DETECTIVE
363 /* Leaks are reported in log file */
364 report_memory_leaks(void);