2 * Copyright (C) 2006-2012 Tobias Brunner
3 * Copyright (C) 2005-2009 Martin Willi
4 * Copyright (C) 2006 Daniel Roethlisberger
5 * Copyright (C) 2005 Jan Hutter
6 * Hochschule fuer Technik Rapperswil
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 #include <sys/types.h>
27 #include <plugins/plugin_feature.h>
28 #include <config/proposal.h>
29 #include <kernel/kernel_handler.h>
30 #include <processing/jobs/start_action_job.h>
33 #define CAP_NET_ADMIN 12
36 typedef struct private_daemon_t private_daemon_t
;
39 * Private additions to daemon_t, contains threads and internal functions.
41 struct private_daemon_t
{
43 * Public members of daemon_t.
48 * Handler for kernel events
50 kernel_handler_t
*kernel_handler
;
54 * One and only instance of the daemon.
59 * hook in library for debugging messages
61 extern void (*dbg
) (debug_t group
, level_t level
, char *fmt
, ...);
64 * we store the previous debug function so we can reset it
66 static void (*dbg_old
) (debug_t group
, level_t level
, char *fmt
, ...);
69 * Logging hook for library logs, spreads debug message over bus
71 static void dbg_bus(debug_t group
, level_t level
, char *fmt
, ...)
76 charon
->bus
->vlog(charon
->bus
, group
, level
, fmt
, args
);
81 * Clean up all daemon resources
83 static void destroy(private_daemon_t
*this)
85 /* terminate all idle threads */
86 lib
->processor
->set_threads(lib
->processor
, 0);
88 /* close all IKE_SAs */
89 if (this->public.ike_sa_manager
)
91 this->public.ike_sa_manager
->flush(this->public.ike_sa_manager
);
93 if (this->public.traps
)
95 this->public.traps
->flush(this->public.traps
);
97 if (this->public.sender
)
99 this->public.sender
->flush(this->public.sender
);
102 /* cancel all threads and wait for their termination */
103 lib
->processor
->cancel(lib
->processor
);
105 DESTROY_IF(this->public.receiver
);
107 DESTROY_IF(this->public.connect_manager
);
108 DESTROY_IF(this->public.mediation_manager
);
110 /* make sure the cache is clear before unloading plugins */
111 lib
->credmgr
->flush_cache(lib
->credmgr
, CERT_ANY
);
112 lib
->plugins
->unload(lib
->plugins
);
113 DESTROY_IF(this->kernel_handler
);
114 DESTROY_IF(this->public.traps
);
115 DESTROY_IF(this->public.shunts
);
116 DESTROY_IF(this->public.ike_sa_manager
);
117 DESTROY_IF(this->public.controller
);
118 DESTROY_IF(this->public.eap
);
119 DESTROY_IF(this->public.xauth
);
120 DESTROY_IF(this->public.backends
);
121 DESTROY_IF(this->public.sender
);
122 DESTROY_IF(this->public.socket
);
123 DESTROY_IF(this->public.caps
);
125 /* rehook library logging, shutdown logging */
127 DESTROY_IF(this->public.bus
);
128 this->public.file_loggers
->destroy_offset(this->public.file_loggers
,
129 offsetof(file_logger_t
, destroy
));
130 this->public.sys_loggers
->destroy_offset(this->public.sys_loggers
,
131 offsetof(sys_logger_t
, destroy
));
132 free((void*)this->public.name
);
136 METHOD(daemon_t
, start
, void,
137 private_daemon_t
*this)
139 /* start the engine, go multithreaded */
140 lib
->processor
->set_threads(lib
->processor
,
141 lib
->settings
->get_int(lib
->settings
, "%s.threads",
142 DEFAULT_THREADS
, charon
->name
));
145 METHOD(daemon_t
, initialize
, bool,
146 private_daemon_t
*this, char *plugins
)
148 static plugin_feature_t features
[] = {
149 PLUGIN_PROVIDE(CUSTOM
, "libcharon"),
150 PLUGIN_DEPENDS(HASHER
, HASH_SHA1
),
151 PLUGIN_DEPENDS(RNG
, RNG_STRONG
),
152 PLUGIN_DEPENDS(NONCE_GEN
),
153 PLUGIN_DEPENDS(CUSTOM
, "kernel-ipsec"),
154 PLUGIN_DEPENDS(CUSTOM
, "kernel-net"),
155 PLUGIN_DEPENDS(CUSTOM
, "socket"),
157 lib
->plugins
->add_static_features(lib
->plugins
, charon
->name
, features
,
158 countof(features
), TRUE
);
160 /* load plugins, further infrastructure may need it */
161 if (!lib
->plugins
->load(lib
->plugins
, NULL
, plugins
))
165 DBG1(DBG_DMN
, "loaded plugins: %s",
166 lib
->plugins
->loaded_plugins(lib
->plugins
));
168 this->public.ike_sa_manager
= ike_sa_manager_create();
169 if (this->public.ike_sa_manager
== NULL
)
173 this->public.sender
= sender_create();
174 this->public.receiver
= receiver_create();
175 if (this->public.receiver
== NULL
)
180 /* Queue start_action job */
181 lib
->processor
->queue_job(lib
->processor
, (job_t
*)start_action_job_create());
184 this->public.connect_manager
= connect_manager_create();
185 if (this->public.connect_manager
== NULL
)
189 this->public.mediation_manager
= mediation_manager_create();
198 private_daemon_t
*daemon_create(const char *name
)
200 private_daemon_t
*this;
204 .initialize
= _initialize
,
207 .file_loggers
= linked_list_create(),
208 .sys_loggers
= linked_list_create(),
209 .name
= strdup(name ?
: "libcharon"),
212 charon
= &this->public;
213 this->public.caps
= capabilities_create();
214 this->public.controller
= controller_create();
215 this->public.eap
= eap_manager_create();
216 this->public.xauth
= xauth_manager_create();
217 this->public.backends
= backend_manager_create();
218 this->public.socket
= socket_manager_create();
219 this->public.traps
= trap_manager_create();
220 this->public.shunts
= shunt_manager_create();
221 this->kernel_handler
= kernel_handler_create();
223 this->public.caps
->keep(this->public.caps
, CAP_NET_ADMIN
);
229 * Described in header.
231 void libcharon_deinit()
233 destroy((private_daemon_t
*)charon
);
238 * Described in header.
240 bool libcharon_init(const char *name
)
244 /* for uncritical pseudo random numbers */
245 srandom(time(NULL
) + getpid());
247 /* set up hook to log dbg message in library via charons message bus */
251 lib
->printf_hook
->add_handler(lib
->printf_hook
, 'P',
252 proposal_printf_hook
,
253 PRINTF_HOOK_ARGTYPE_POINTER
,
254 PRINTF_HOOK_ARGTYPE_END
);
256 if (lib
->integrity
&&
257 !lib
->integrity
->check(lib
->integrity
, "libcharon", libcharon_init
))
259 dbg(DBG_DMN
, 1, "integrity check of libcharon failed");