- began to clean code documentation
[strongswan.git] / Source / charon / daemon.c
1 /**
2 * @file daemon.c
3 *
4 * @brief Main of IKEv2-Daemon
5 *
6 */
7
8 /*
9 * Copyright (C) 2005 Jan Hutter, Martin Willi
10 * Hochschule fuer Technik Rapperswil
11 *
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>.
16 *
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
20 * for more details.
21 */
22
23 #include <stdio.h>
24 #include <signal.h>
25 #include <pthread.h>
26
27 #include "daemon.h"
28
29
30 #include <types.h>
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>
43
44
45 /* function declaration (defined and described after main function) */
46
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);
54
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;
61 /** Global socket */
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;
69
70 /**
71 * logger_t object assigned for daemon things
72 */
73 static logger_t *logger = NULL;
74
75 /**
76 * Sender-Thread
77 */
78 static sender_t *sender_thread = NULL;
79 /**
80 * Receiver-Thread
81 */
82 static receiver_t *receiver_thread = NULL;
83 /**
84 * Scheduler-Thread
85 */
86 static scheduler_t *scheduler_thread = NULL;
87 /**
88 * Thread pool holding the worker threads
89 */
90 static thread_pool_t *thread_pool = NULL;
91
92 /**
93 * Signal set used for signal handling
94 */
95 sigset_t signal_set;
96
97
98 int main()
99 {
100 /* set signal handler */
101 register_signals();
102
103 /* logger_manager is created first */
104 global_logger_manager = logger_manager_create(FULL);
105 if (global_logger_manager == NULL)
106 {
107 printf("could not create logger manager");
108 return -1;
109 }
110
111 /* a own logger for the daemon is created */
112 logger = global_logger_manager->create_logger(global_logger_manager,DAEMON,NULL);
113 if (logger == NULL)
114 {
115 printf("could not create logger object");
116 destroy_globals();
117 return -1;
118 }
119
120 /* initialize all global objects */
121 if (initialize_globals() != SUCCESS)
122 {
123 destroy_globals();
124 return -1;
125 }
126
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)
130 {
131 /* ugh, not good */
132 logger->log(logger,CONTROL,"Fatal error: Needed Threads could not be started");
133 destroy_and_exit(-1);
134 }
135
136 int i;
137 for(i = 0; i<1; i++)
138 {
139 initiate_ike_sa_job_t *initiate_job;
140
141 initiate_job = initiate_ike_sa_job_create("pinflb31");
142 global_event_queue->add_relative(global_event_queue, (job_t*)initiate_job, i * 1000);
143
144 }
145
146 logger->log(logger,CONTROL|MORE,"going to wait for exit signal");
147 /* go and handle signals*/
148 main_loop();
149
150 destroy_and_exit(0);
151
152 /* never reached */
153 return -1;
154 }
155
156 /**
157 * Main Loop.
158 * Waits for registered signals and acts dependently
159 */
160 static void main_loop()
161 {
162 while(1)
163 {
164 int signal_number;
165 int error;
166
167 error = sigwait(&signal_set, &signal_number);
168
169 if(error)
170 {
171 /* do error code */
172 logger->log(logger,CONTROL,"Error %d when waiting for signal",error);
173 return;
174 }
175 switch (signal_number)
176 {
177 case SIGHUP:
178 {
179 logger->log(logger,CONTROL,"Signal of type SIGHUP received. Do nothing");
180 break;
181 }
182 case SIGINT:
183 {
184 logger->log(logger,CONTROL,"Signal of type SIGINT received. Exit main loop.");
185 return;
186 }
187 case SIGTERM:
188 {
189 logger->log(logger,CONTROL,"Signal of type SIGTERM received. Exit main loop.");
190 return;
191 }
192 default:
193 {
194 logger->log(logger,CONTROL,"Unknown signal %d received. Do nothing",signal_number);
195 break;
196 }
197 }
198 }
199 }
200
201 /**
202 * Registers signals SIGINT, SIGHUP and SIGTERM.
203 * Signals are handled in main_loop()
204 */
205 static void register_signals()
206 {
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);
212
213 }
214
215 /**
216 * Initializes global objects
217 *
218 * @return
219 * - SUCCESS
220 * - FAILED
221 */
222 static status_t initialize_globals()
223 {
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();
231
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))
238 {
239 return FAILED;
240 }
241
242 return SUCCESS;
243 }
244
245 /**
246 * Destroy global objects
247 */
248 static void destroy_globals()
249 {
250 if (global_job_queue != NULL)
251 {
252 logger->log(logger,CONTROL|MOST,"destroy global_job_queue");
253 global_job_queue->destroy(global_job_queue);
254 }
255 if (global_event_queue != NULL)
256 {
257 logger->log(logger,CONTROL|MOST,"destroy global_event_queue");
258 global_event_queue->destroy(global_event_queue);
259 }
260 if (global_send_queue != NULL)
261 {
262 logger->log(logger,CONTROL|MOST,"destroy global_send_queue");
263 global_send_queue->destroy(global_send_queue);
264 }
265 if (global_socket != NULL)
266 {
267 logger->log(logger,CONTROL|MOST,"destroy global_socket");
268 global_socket->destroy(global_socket);
269 }
270 if (global_ike_sa_manager != NULL)
271 {
272 logger->log(logger,CONTROL|MOST,"destroy global_ike_sa_manager");
273 global_ike_sa_manager->destroy(global_ike_sa_manager);
274 }
275 if (global_configuration_manager != NULL)
276 {
277 logger->log(logger,CONTROL|MOST,"destroy global_configuration_manager");
278 global_configuration_manager->destroy(global_configuration_manager);
279 }
280 }
281
282 /**
283 * Creates all needed Threads
284 *
285 * @return
286 * - SUCCESS
287 * - FAILED
288 */
289 static status_t start_threads()
290 {
291 sender_thread = sender_create();
292 if (sender_thread == NULL)
293 {
294 return FAILED;
295 }
296 scheduler_thread = scheduler_create();
297 if (scheduler_thread == NULL)
298 {
299 return FAILED;
300 }
301 thread_pool = thread_pool_create(NUMBER_OF_WORKING_THREADS);
302 if (thread_pool == NULL)
303 {
304 return FAILED;
305 }
306 receiver_thread = receiver_create();
307 if (receiver_thread == NULL)
308 {
309 return FAILED;
310 }
311
312 return SUCCESS;
313 }
314
315
316 /**
317 * Ends all Threads
318 *
319 */
320 static void end_threads()
321 {
322 if (receiver_thread != NULL)
323 {
324 receiver_thread->destroy(receiver_thread);
325 }
326 if (scheduler_thread != NULL)
327 {
328 scheduler_thread->destroy(scheduler_thread);
329 }
330 if (sender_thread != NULL)
331 {
332 sender_thread->destroy(sender_thread);
333 }
334 if (thread_pool != NULL)
335 {
336 thread_pool->destroy(thread_pool);
337 }
338
339 }
340
341 /**
342 * Destroys initialized objects, kills all threads and exits
343 *
344 * @param exit_code Code to exit with
345 */
346 static void destroy_and_exit(int exit_code)
347 {
348 logger->log(logger,CONTROL,"going to exit daemon");
349
350 end_threads();
351
352 /* all globals can be destroyed now */
353 destroy_globals();
354
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);
361
362 #ifdef LEAK_DETECTIVE
363 /* Leaks are reported in log file */
364 report_memory_leaks(void);
365 #endif
366
367 exit(exit_code);
368 }