- moved algorithm definitions from payloads to corresponding transforms
[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
43
44 /* function declaration (defined and described after main function) */
45
46 static status_t initialize_globals();
47 static void destroy_globals();
48 static status_t start_threads();
49 static void end_threads();
50 static void main_loop();
51 static void register_signals();
52 static void destroy_and_exit(int);
53
54 /** Global job-queue */
55 job_queue_t *global_job_queue = NULL;
56 /** Global event-queue */
57 event_queue_t *global_event_queue = NULL;
58 /** Global send-queue */
59 send_queue_t *global_send_queue = NULL;
60 /** Global socket */
61 socket_t *global_socket = NULL;
62 /** Global logger manager */
63 logger_manager_t *global_logger_manager = NULL;
64 /** Global ike_sa-manager */
65 ike_sa_manager_t *global_ike_sa_manager = NULL;
66 /** Global configuration-manager */
67 configuration_manager_t *global_configuration_manager = NULL;
68
69 /**
70 * logger_t object assigned for daemon things
71 */
72 static logger_t *logger = NULL;
73
74 /**
75 * Sender-Thread
76 */
77 static sender_t *sender_thread = NULL;
78 /**
79 * Receiver-Thread
80 */
81 static receiver_t *receiver_thread = NULL;
82 /**
83 * Scheduler-Thread
84 */
85 static scheduler_t *scheduler_thread = NULL;
86 /**
87 * Thread pool holding the worker threads
88 */
89 static thread_pool_t *thread_pool = NULL;
90
91 /**
92 * Signal set used for signal handling
93 */
94 sigset_t signal_set;
95
96
97 int main()
98 {
99 /* set signal handler */
100 register_signals();
101
102 /* logger_manager is created first */
103 global_logger_manager = logger_manager_create(FULL);
104 if (global_logger_manager == NULL)
105 {
106 printf("could not create logger manager");
107 return -1;
108 }
109
110 /* a own logger for the daemon is created */
111 logger = global_logger_manager->create_logger(global_logger_manager,DAEMON,NULL);
112 if (logger == NULL)
113 {
114 printf("could not create logger object");
115 destroy_globals();
116 return -1;
117 }
118
119 /* initialize all global objects */
120 if (initialize_globals() != SUCCESS)
121 {
122 destroy_globals();
123 return -1;
124 }
125
126 logger->log(logger,CONTROL,"start daemon %s", DAEMON_NAME);
127 /* now its time to create all the different threads :-) */
128 if (start_threads() != SUCCESS)
129 {
130 /* ugh, not good */
131 logger->log(logger,CONTROL,"Fatal error: Needed Threads could not be started");
132 destroy_and_exit(-1);
133 }
134
135 // int i;
136 // for(i = 0; i<1; i++)
137 // {
138 // initiate_ike_sa_job_t *initiate_job;
139 //
140 // initiate_job = initiate_ike_sa_job_create("pinflb30");
141 // global_event_queue->add_relative(global_event_queue, (job_t*)initiate_job, i * 1000);
142 //
143 // }
144
145 logger->log(logger,CONTROL|MORE,"going to wait for exit signal");
146 /* go and handle signals*/
147 main_loop();
148
149 destroy_and_exit(0);
150
151 /* never reached */
152 return -1;
153 }
154
155 /**
156 * Main Loop.
157 * Waits for registered signals and acts dependently
158 */
159 static void main_loop()
160 {
161 while(1)
162 {
163 int signal_number;
164 int error;
165
166 error = sigwait(&signal_set, &signal_number);
167
168 if(error)
169 {
170 /* do error code */
171 logger->log(logger,CONTROL,"Error %d when waiting for signal",error);
172 return;
173 }
174 switch (signal_number)
175 {
176 case SIGHUP:
177 {
178 logger->log(logger,CONTROL,"Signal of type SIGHUP received. Do nothing");
179 break;
180 }
181 case SIGINT:
182 {
183 logger->log(logger,CONTROL,"Signal of type SIGINT received. Exit main loop.");
184 return;
185 }
186 case SIGTERM:
187 {
188 logger->log(logger,CONTROL,"Signal of type SIGTERM received. Exit main loop.");
189 return;
190 }
191 default:
192 {
193 logger->log(logger,CONTROL,"Unknown signal %d received. Do nothing",signal_number);
194 break;
195 }
196 }
197 }
198 }
199
200 /**
201 * Registers signals SIGINT, SIGHUP and SIGTERM.
202 * Signals are handled in main_loop()
203 */
204 static void register_signals()
205 {
206 sigemptyset(&signal_set);
207 sigaddset(&signal_set, SIGINT);
208 sigaddset(&signal_set, SIGHUP);
209 sigaddset(&signal_set, SIGTERM);
210 pthread_sigmask(SIG_BLOCK, &signal_set, 0);
211
212 }
213
214 /**
215 * Initializes global objects
216 *
217 * @return
218 * - SUCCESS
219 * - FAILED
220 */
221 static status_t initialize_globals()
222 {
223 /* initialize global object */
224 global_socket = socket_create(IKEV2_UDP_PORT);
225 global_ike_sa_manager = ike_sa_manager_create();
226 global_job_queue = job_queue_create();
227 global_event_queue = event_queue_create();
228 global_send_queue = send_queue_create();
229 global_configuration_manager = configuration_manager_create();
230
231 if ( (global_socket == NULL) ||
232 (global_job_queue == NULL) ||
233 (global_event_queue == NULL) ||
234 (global_send_queue == NULL) ||
235 (global_configuration_manager == NULL) ||
236 (global_ike_sa_manager == NULL))
237 {
238 return FAILED;
239 }
240
241 return SUCCESS;
242 }
243
244 /**
245 * Destroy global objects
246 */
247 static void destroy_globals()
248 {
249 if (global_ike_sa_manager != NULL)
250 {
251 global_job_queue->destroy(global_job_queue);
252 }
253 if (global_event_queue != NULL)
254 {
255 global_event_queue->destroy(global_event_queue);
256 }
257 if (global_send_queue != NULL)
258 {
259 global_send_queue->destroy(global_send_queue);
260 }
261 if (global_socket != NULL)
262 {
263 global_socket->destroy(global_socket);
264 }
265 if (global_ike_sa_manager != NULL)
266 {
267 global_ike_sa_manager->destroy(global_ike_sa_manager);
268 }
269 if (global_configuration_manager != NULL)
270 {
271 global_configuration_manager->destroy(global_configuration_manager);
272 }
273 }
274
275 /**
276 * Creates all needed Threads
277 *
278 * @return
279 * - SUCCESS
280 * - FAILED
281 */
282 static status_t start_threads()
283 {
284 sender_thread = sender_create();
285 if (sender_thread == NULL)
286 {
287 return FAILED;
288 }
289 scheduler_thread = scheduler_create();
290 if (scheduler_thread == NULL)
291 {
292 return FAILED;
293 }
294 thread_pool = thread_pool_create(NUMBER_OF_WORKING_THREADS);
295 if (thread_pool == NULL)
296 {
297 return FAILED;
298 }
299 receiver_thread = receiver_create();
300 if (receiver_thread == NULL)
301 {
302 return FAILED;
303 }
304
305 return SUCCESS;
306 }
307
308
309 /**
310 * Ends all Threads
311 *
312 */
313 static void end_threads()
314 {
315 if (receiver_thread != NULL)
316 {
317 receiver_thread->destroy(receiver_thread);
318 }
319 if (scheduler_thread != NULL)
320 {
321 scheduler_thread->destroy(scheduler_thread);
322 }
323 if (sender_thread != NULL)
324 {
325 sender_thread->destroy(sender_thread);
326 }
327 if (thread_pool != NULL)
328 {
329 thread_pool->destroy(thread_pool);
330 }
331
332 }
333
334 /**
335 * Destroys initialized objects, kills all threads and exits
336 *
337 * @param exit_code Code to exit with
338 */
339 static void destroy_and_exit(int exit_code)
340 {
341 logger->log(logger,CONTROL,"going to exit daemon");
342
343 end_threads();
344
345 /* all globals can be destroyed now */
346 destroy_globals();
347
348 /* logger is destroyed */
349 logger->log(logger,CONTROL|MORE,"destroy logger");
350 logger->log(logger,CONTROL|MORE,"destroy logger_manager");
351 logger->log(logger,CONTROL|MORE,"------------------------------------");
352 global_logger_manager->destroy_logger(global_logger_manager,logger);
353 global_logger_manager->destroy(global_logger_manager);
354
355 #ifdef LEAK_DETECTIVE
356 /* Leaks are reported in log file */
357 report_memory_leaks(void);
358 #endif
359
360 exit(exit_code);
361 }