- fixed socket code, so we know on which address we receive traffic
[strongswan.git] / Source / charon / utils / logger_manager.c
1 /**
2 * @file logger_manager.c
3 *
4 * @brief Implementation of logger_manager_t.
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
24 #include "logger_manager.h"
25
26 #include <definitions.h>
27 #include <utils/allocator.h>
28 #include <utils/linked_list.h>
29
30 /**
31 * String mappings for logger_context_t
32 */
33 mapping_t logger_context_t_mappings[] = {
34 {PARSER, "PARSER"},
35 {GENERATOR, "GENRAT"},
36 {IKE_SA, "IKE_SA"},
37 {IKE_SA_MANAGER, "ISAMGR"},
38 {CHILD_SA, "CHLDSA"},
39 {MESSAGE, "MESSAG"},
40 {THREAD_POOL, "THPOOL"},
41 {WORKER, "WORKER"},
42 {SCHEDULER, "SCHEDU"},
43 {SENDER, "SENDER"},
44 {RECEIVER, "RECEVR"},
45 {SOCKET, "SOCKET"},
46 {TESTER, "TESTER"},
47 {DAEMON, "DAEMON"},
48 {CONFIGURATION_MANAGER, "CONFIG"},
49 {ENCRYPTION_PAYLOAD, "ENCPLD"},
50 {MAPPING_END, NULL},
51 };
52
53 /**
54 * Maximum length of a logger name in bytes.
55 */
56 #define MAX_LOGGER_NAME 45
57
58
59 typedef struct private_logger_manager_t private_logger_manager_t;
60
61 /**
62 * Private data of logger_manager_t object.
63 */
64 struct private_logger_manager_t {
65 /**
66 * Public data.
67 */
68 logger_manager_t public;
69
70 /**
71 * List of managed loggers.
72 */
73 linked_list_t *loggers;
74
75 /**
76 * Log Levels.
77 */
78 linked_list_t *logger_levels;
79
80 /**
81 * Used to manage logger list.
82 */
83 pthread_mutex_t mutex;
84
85 /**
86 * Default logger level for a created logger used
87 * if no specific logger_level is set.
88 */
89 logger_level_t default_log_level;
90
91 /**
92 * Sets set logger_level of a specific context.
93 *
94 * @param this calling object
95 * @param context context to set level
96 * @param logger_level logger_level to set
97 * @param enable enable specific level or disable it
98 */
99 void (*set_logger_level) (private_logger_manager_t *this,
100 logger_context_t context,
101 logger_level_t logger_level,
102 bool enable);
103
104 };
105
106
107 typedef struct logger_levels_entry_t logger_levels_entry_t;
108
109 /**
110 * Entry in the logger_levels linked list.
111 *
112 * This entry specifies the current log level for
113 * logger_t objects in specific context.
114 */
115 struct logger_levels_entry_t {
116 /**
117 * Logger context.
118 */
119 logger_context_t context;
120
121 /**
122 * Logger level of logger context.
123 */
124 logger_level_t level;
125 };
126
127
128 typedef struct loggers_entry_t loggers_entry_t;
129
130 /**
131 * Entry in the loggers linked list.
132 *
133 * @todo Replace loggers_entry_t with logger_t and add get_context() function to logger_t class.
134 */
135 struct loggers_entry_t {
136 /**
137 * Logger context.
138 */
139 logger_context_t context;
140 /**
141 * Assigned logger
142 */
143 logger_t *logger;
144 };
145
146 /**
147 * Implementation of logger_manager_t.create_logger.
148 */
149 static logger_t *create_logger(private_logger_manager_t *this, logger_context_t context, char * name)
150 {
151
152 char * context_name;
153 bool log_thread_ids = TRUE;
154 FILE * output = NULL;
155 char buffer[MAX_LOGGER_NAME];
156 loggers_entry_t *entry;
157 logger_t *logger;
158 logger_level_t logger_level = 0;
159
160 context_name = mapping_find(logger_context_t_mappings,context);
161
162 /* output to stdout, since we are debugging all days */
163 output = stdout;
164
165 /* defaults */
166 log_thread_ids = FALSE;
167 logger_level = this->public.get_logger_level(&(this->public),context);;
168
169 switch(context)
170 {
171 case TESTER:
172 output = stdout;
173 break;
174 case IKE_SA_MANAGER:
175 log_thread_ids = TRUE;
176 break;
177 case IKE_SA:
178 log_thread_ids = TRUE;
179 break;
180 case CHILD_SA:
181 logger_level |= LEVEL1;
182 log_thread_ids = TRUE;
183 break;
184 case CONFIGURATION_MANAGER:
185 log_thread_ids = TRUE;
186 break;
187 case MESSAGE:
188 log_thread_ids = TRUE;
189 break;
190 case ENCRYPTION_PAYLOAD:
191 log_thread_ids = TRUE;
192 break;
193 case GENERATOR:
194 log_thread_ids = TRUE;
195 break;
196 case PARSER:
197 log_thread_ids = TRUE;
198 break;
199 case WORKER:
200 log_thread_ids = TRUE;
201 break;
202 case THREAD_POOL:
203 break;
204 case SCHEDULER:
205 logger_level = 0;
206 break;
207 case SENDER:
208 break;
209 case RECEIVER:
210 break;
211 case SOCKET:
212 logger_level |= FULL;
213 break;
214 case DAEMON:
215 break;
216 }
217
218 /* logger manager is thread save */
219 pthread_mutex_lock(&(this->mutex));
220 if (name != NULL)
221 {
222 snprintf(buffer, MAX_LOGGER_NAME, "%s - %s",context_name,name);
223 /* create logger with default log_level */
224 logger = logger_create(buffer,logger_level,log_thread_ids,output);
225 }
226 else
227 {
228 logger = logger_create(context_name,logger_level,log_thread_ids,output);
229 }
230
231
232 entry = allocator_alloc_thing(loggers_entry_t);
233
234 entry->context = context;
235 entry->logger = logger;
236
237 this->loggers->insert_last(this->loggers,entry);
238
239 pthread_mutex_unlock(&(this->mutex));
240 return logger;
241
242 }
243
244 /**
245 * Implementation of logger_manager_t.get_logger_level.
246 */
247 static logger_level_t get_logger_level (private_logger_manager_t *this, logger_context_t context)
248 {
249 iterator_t *iterator;
250 /* set logger_level to default logger_level */
251 logger_level_t logger_level = this->default_log_level;
252
253 pthread_mutex_lock(&(this->mutex));
254
255 iterator = this->logger_levels->create_iterator(this->logger_levels,TRUE);
256 /* check for existing logger_level entry */
257 while (iterator->has_next(iterator))
258 {
259 logger_levels_entry_t * entry;
260 iterator->current(iterator,(void **)&entry);
261 if (entry->context == context)
262 {
263 logger_level = entry->level;
264 break;
265 }
266 }
267 iterator->destroy(iterator);
268
269 pthread_mutex_unlock(&(this->mutex));
270 return logger_level;
271 }
272
273 /**
274 * Implementation of logger_manager_t.destroy_logger.
275 */
276 static void destroy_logger(private_logger_manager_t *this,logger_t *logger)
277 {
278 iterator_t *iterator;
279
280 pthread_mutex_lock(&(this->mutex));
281
282 iterator = this->loggers->create_iterator(this->loggers,TRUE);
283 while (iterator->has_next(iterator))
284 {
285 loggers_entry_t * entry;
286 iterator->current(iterator,(void **)&entry);
287 if (entry->logger == logger)
288 {
289 iterator->remove(iterator);
290 allocator_free(entry);
291 logger->destroy(logger);
292 break;
293 }
294 }
295 iterator->destroy(iterator);
296 pthread_mutex_unlock(&(this->mutex));
297 }
298
299 /**
300 * Implementation of private_logger_manager_t.set_logger_level.
301 */
302 static void set_logger_level(private_logger_manager_t *this, logger_context_t context,logger_level_t logger_level,bool enable)
303 {
304 iterator_t *iterator;
305 bool found = FALSE;
306
307 pthread_mutex_lock(&(this->mutex));
308 iterator = this->logger_levels->create_iterator(this->logger_levels,TRUE);
309
310 /* find existing logger_level entry */
311 while (iterator->has_next(iterator))
312 {
313 logger_levels_entry_t * entry;
314 iterator->current(iterator,(void **)&entry);
315 if (entry->context == context)
316 {
317 if (enable)
318 {
319 entry->level |= logger_level;
320 }
321 else
322 {
323 entry->level &= ~logger_level;
324 }
325 found = TRUE;
326 break;
327 }
328 }
329 iterator->destroy(iterator);
330
331 if (!found)
332 {
333 /* logger_levels entry not existing for current context */
334 logger_levels_entry_t *entry = allocator_alloc_thing(logger_levels_entry_t);
335
336 entry->context = context;
337 entry->level = (enable) ? logger_level : (this->default_log_level & (~logger_level));
338
339 this->logger_levels->insert_last(this->logger_levels,entry);
340 }
341
342 iterator = this->loggers->create_iterator(this->loggers,TRUE);
343 while (iterator->has_next(iterator))
344 {
345 loggers_entry_t * entry;
346 iterator->current(iterator,(void **)&entry);
347
348 if (entry->context == context)
349 {
350 if (enable)
351 {
352 entry->logger->enable_level(entry->logger,logger_level);
353 }
354 else
355 {
356 entry->logger->disable_level(entry->logger,logger_level);
357 }
358
359 }
360 }
361 iterator->destroy(iterator);
362
363 pthread_mutex_unlock(&(this->mutex));
364 }
365
366 /**
367 * Implementation of logger_manager_t.enable_logger_level.
368 */
369 static void enable_logger_level(private_logger_manager_t *this, logger_context_t context,logger_level_t logger_level)
370 {
371 return set_logger_level(this,context,logger_level,TRUE);
372 }
373
374 /**
375 * Implementation of logger_manager_t.disable_logger_level.
376 */
377 static void disable_logger_level(private_logger_manager_t *this, logger_context_t context,logger_level_t logger_level)
378 {
379 return set_logger_level(this,context,logger_level,FALSE);
380 }
381
382 /**
383 * Implementation of logger_manager_t.destroy.
384 */
385 static void destroy(private_logger_manager_t *this)
386 {
387
388 while (this->loggers->get_count(this->loggers) > 0)
389 {
390 loggers_entry_t *current_entry;
391
392 this->loggers->remove_first(this->loggers,(void **)&current_entry);
393
394 /* destroy logger object */
395 current_entry->logger->destroy(current_entry->logger);
396
397 /* entry can be destroyed */
398 allocator_free(current_entry);
399 }
400
401 while (this->logger_levels->get_count(this->logger_levels) > 0)
402 {
403 logger_levels_entry_t *current_entry;
404
405 this->logger_levels->remove_first(this->logger_levels,(void **)&current_entry);
406
407 /* entry can be destroyed */
408 allocator_free(current_entry);
409 }
410
411 this->loggers->destroy(this->loggers);
412 this->logger_levels->destroy(this->logger_levels);
413 pthread_mutex_destroy(&(this->mutex));
414
415 allocator_free(this);
416 }
417
418 /*
419 * Described in header.
420 */
421 logger_manager_t *logger_manager_create(logger_level_t default_log_level)
422 {
423 private_logger_manager_t *this = allocator_alloc_thing(private_logger_manager_t);
424
425 this->public.create_logger = (logger_t *(*)(logger_manager_t*,logger_context_t context, char *))create_logger;
426 this->public.destroy_logger = (void(*)(logger_manager_t*,logger_t *logger))destroy_logger;
427 this->public.destroy = (void(*)(logger_manager_t*))destroy;
428 this->public.get_logger_level = (logger_level_t (*)(logger_manager_t *, logger_context_t)) get_logger_level;
429 this->public.enable_logger_level = (void (*)(logger_manager_t *, logger_context_t,logger_level_t)) enable_logger_level;
430 this->public.disable_logger_level = (void (*)(logger_manager_t *, logger_context_t,logger_level_t)) disable_logger_level;
431 this->set_logger_level = (void (*)(private_logger_manager_t *, logger_context_t,logger_level_t,bool)) set_logger_level;
432
433 /* private variables */
434 this->loggers = linked_list_create();
435 this->logger_levels = linked_list_create();
436 this->default_log_level = default_log_level;
437
438 pthread_mutex_init(&(this->mutex), NULL);
439
440 return (logger_manager_t*)this;
441 }
442