a32948fe9bb5e4e1346d465874ea71cccacbb1ac
[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 <utils/allocator.h>
32 #include <queues/jobs/initiate_ike_sa_job.h>
33
34
35
36
37 typedef struct private_daemon_t private_daemon_t;
38
39 /**
40 * Private additions to daemon_t, contains
41 * threads and internal functions.
42 */
43 struct private_daemon_t {
44 /**
45 * public members of daemon_t
46 */
47 daemon_t public;
48
49 /**
50 * logger_t object assigned for daemon things
51 */
52 logger_t *logger;
53
54 /**
55 * Signal set used for signal handling
56 */
57 sigset_t signal_set;
58
59 void (*run) (private_daemon_t *this);
60 void (*destroy) (private_daemon_t *this, char *reason);
61 void (*build_test_jobs) (private_daemon_t *this);
62 void (*initialize) (private_daemon_t *this);
63 void (*cleanup) (private_daemon_t *this);
64 };
65
66
67
68 /**
69 * instance of the daemon
70 */
71 daemon_t *charon;
72
73
74
75 /**
76 * Loop of the main thread, waits for signals
77 */
78 static void run(private_daemon_t *this)
79 {
80 while(TRUE)
81 {
82 int signal_number;
83 int error;
84
85 error = sigwait(&(this->signal_set), &signal_number);
86 if(error)
87 {
88 this->logger->log(this->logger, ERROR, "Error %d when waiting for signal", error);
89 return;
90 }
91 switch (signal_number)
92 {
93 case SIGHUP:
94 {
95 this->logger->log(this->logger, CONTROL, "Signal of type SIGHUP received. Do nothing");
96 break;
97 }
98 case SIGINT:
99 {
100 this->logger->log(this->logger, CONTROL, "Signal of type SIGINT received. Exit main loop.");
101 return;
102 }
103 case SIGTERM:
104 this->logger->log(this->logger, CONTROL, "Signal of type SIGTERM received. Exit main loop.");
105 return;
106 default:
107 {
108 this->logger->log(this->logger, CONTROL, "Unknown signal %d received. Do nothing", signal_number);
109 break;
110 }
111 }
112 }
113 }
114
115 /**
116 * Initialize the destruction of the daemon
117 */
118 static void destroy(private_daemon_t *this, char *reason)
119 {
120 /* we send SIGTERM, so the daemon can cleanly shut down */
121 this->logger->log(this->logger, ERROR, "Killing daemon: %s", reason);
122 this->logger->log(this->logger, CONTROL, "sending SIGTERM to ourself", reason);
123 kill(0, SIGTERM);
124 /* thread must die, since he produced a ciritcal failure and can't continue */
125 pthread_exit(NULL);
126 }
127
128 /**
129 * build some jobs to test daemon functionality
130 */
131 static void build_test_jobs(daemon_t *this)
132 {
133 int i;
134 for(i = 0; i<1; i++)
135 {
136 initiate_ike_sa_job_t *initiate_job;
137 initiate_job = initiate_ike_sa_job_create("localhost");
138 this->job_queue->add(this->job_queue, (job_t*)initiate_job);
139 }
140 }
141
142
143 /**
144 * Initialize global objects and threads
145 */
146 static void initialize(daemon_t *this)
147 {
148 this->socket = socket_create(IKEV2_UDP_PORT);
149 this->ike_sa_manager = ike_sa_manager_create();
150 this->job_queue = job_queue_create();
151 this->event_queue = event_queue_create();
152 this->send_queue = send_queue_create();
153 this->configuration_manager = configuration_manager_create();
154
155 this->sender = sender_create();
156 this->receiver = receiver_create();
157 this->scheduler = scheduler_create();
158 this->thread_pool = thread_pool_create(NUMBER_OF_WORKING_THREADS);
159 }
160
161 /**
162 * Destory all initiated objects
163 */
164 static void cleanup(daemon_t *this)
165 {
166 if (this->receiver != NULL)
167 {
168 this->receiver->destroy(this->receiver);
169 }
170 if (this->scheduler != NULL)
171 {
172 this->scheduler->destroy(this->scheduler);
173 }
174 if (this->sender != NULL)
175 {
176 this->sender->destroy(this->sender);
177 }
178 if (this->thread_pool != NULL)
179 {
180 this->thread_pool->destroy(this->thread_pool);
181 }
182 if (this->job_queue != NULL)
183 {
184 this->job_queue->destroy(this->job_queue);
185 }
186 if (this->event_queue != NULL)
187 {
188 this->event_queue->destroy(this->event_queue);
189 }
190 if (this->send_queue != NULL)
191 {
192 this->send_queue->destroy(this->send_queue);
193 }
194 if (this->socket != NULL)
195 {
196 this->socket->destroy(this->socket);
197 }
198 if (this->ike_sa_manager != NULL)
199 {
200 this->ike_sa_manager->destroy(this->ike_sa_manager);
201 }
202 if (this->configuration_manager != NULL)
203 {
204 this->configuration_manager->destroy(this->configuration_manager);
205 }
206
207 this->logger_manager->destroy(this->logger_manager);
208 allocator_free(this);
209 }
210
211
212
213 /**
214 * @brief Create the daemon.
215 *
216 * @return created daemon_t
217 */
218 private_daemon_t *daemon_create()
219 {
220 private_daemon_t *this = allocator_alloc_thing(private_daemon_t);
221
222 /* assign methods */
223 this->run = run;
224 this->public.destroy = (void (*) (daemon_t*,char*))destroy;
225 this->build_test_jobs = (void (*) (private_daemon_t*)) build_test_jobs;
226 this->initialize = (void (*) (private_daemon_t*))initialize;
227 this->cleanup = (void (*) (private_daemon_t*))cleanup;
228
229 /* first build a logger */
230 this->public.logger_manager = logger_manager_create(DEFAULT_LOGLEVEL);
231 this->logger = (this->public.logger_manager)->create_logger(this->public.logger_manager, DAEMON, NULL);
232
233 /* NULL members for clean destruction */
234 this->public.socket = NULL;
235 this->public.ike_sa_manager = NULL;
236 this->public.job_queue = NULL;
237 this->public.event_queue = NULL;
238 this->public.send_queue = NULL;
239 this->public.configuration_manager = NULL;
240 this->public.sender= NULL;
241 this->public.receiver = NULL;
242 this->public.scheduler = NULL;
243 this->public.thread_pool = NULL;
244
245 /* setup signal handling */
246 sigemptyset(&(this->signal_set));
247 sigaddset(&(this->signal_set), SIGINT);
248 sigaddset(&(this->signal_set), SIGHUP);
249 sigaddset(&(this->signal_set), SIGTERM);
250 pthread_sigmask(SIG_BLOCK, &(this->signal_set), 0);
251
252 return this;
253 }
254
255 /**
256 * Main function, manages the daemon
257 */
258 int main(int argc, char *argv[])
259 {
260 private_daemon_t *private_charon;
261
262 private_charon = daemon_create();
263 charon = (daemon_t*)private_charon;
264
265 private_charon->initialize(private_charon);
266
267 private_charon->build_test_jobs(private_charon);
268
269 private_charon->run(private_charon);
270
271 private_charon->cleanup(private_charon);
272
273 #ifdef LEAK_DETECTIVE
274 report_memory_leaks(void);
275 #endif
276
277 return 0;
278 }
279