2 * @file backend_manager.c
4 * @brief Implementation of backend_manager_t.
9 * Copyright (C) 2007 Martin Willi
10 * Hochschule fuer Technik Rapperswil
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>.
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
23 #include "backend_manager.h"
25 #include <sys/types.h>
31 #include <utils/linked_list.h>
32 #include <config/backends/writeable_backend.h>
35 typedef struct private_backend_manager_t private_backend_manager_t
;
38 * Private data of an backend_manager_t object.
40 struct private_backend_manager_t
{
43 * Public part of backend_manager_t object.
45 backend_manager_t
public;
48 * list of registered backends
50 linked_list_t
*backends
;
53 * Additional list of writable backends.
55 linked_list_t
*writeable
;
58 * List of dlopen() handles we used to open backends
60 linked_list_t
*handles
;
64 * implements backend_manager_t.get_ike_cfg.
66 static ike_cfg_t
*get_ike_cfg(private_backend_manager_t
*this,
67 host_t
*my_host
, host_t
*other_host
)
70 ike_cfg_t
*config
= NULL
;
71 iterator_t
*iterator
= this->backends
->create_iterator(this->backends
, TRUE
);
72 while (config
== NULL
&& iterator
->iterate(iterator
, (void**)&backend
))
74 config
= backend
->get_ike_cfg(backend
, my_host
, other_host
);
76 iterator
->destroy(iterator
);
81 * implements backend_manager_t.get_peer_cfg.
83 static peer_cfg_t
*get_peer_cfg(private_backend_manager_t
*this,
84 identification_t
*my_id
, identification_t
*other_id
,
85 ca_info_t
*other_ca_info
)
88 peer_cfg_t
*config
= NULL
;
89 iterator_t
*iterator
= this->backends
->create_iterator(this->backends
, TRUE
);
90 while (config
== NULL
&& iterator
->iterate(iterator
, (void**)&backend
))
92 config
= backend
->get_peer_cfg(backend
, my_id
, other_id
, other_ca_info
);
94 iterator
->destroy(iterator
);
99 * implements backend_manager_t.add_peer_cfg.
101 static void add_peer_cfg(private_backend_manager_t
*this, peer_cfg_t
*config
)
103 writeable_backend_t
*backend
;
105 if (this->writeable
->get_first(this->writeable
, (void**)&backend
) == SUCCESS
)
107 backend
->add_cfg(backend
, config
);
112 * implements backend_manager_t.create_iterator.
114 static iterator_t
* create_iterator(private_backend_manager_t
*this)
116 writeable_backend_t
*backend
;
118 if (this->writeable
->get_first(this->writeable
, (void**)&backend
) == SUCCESS
)
120 return backend
->create_iterator(backend
);
122 /* give out an empty iterator if we have no writable backend*/
123 return this->writeable
->create_iterator(this->writeable
, TRUE
);
127 * load the configuration backend modules
129 static void load_backends(private_backend_manager_t
*this)
131 struct dirent
* entry
;
134 dir
= opendir(IPSEC_BACKENDDIR
);
137 DBG1(DBG_CFG
, "error opening backend modules directory "IPSEC_BACKENDDIR
);
141 DBG1(DBG_CFG
, "loading backend modules from '"IPSEC_BACKENDDIR
"'");
143 while ((entry
= readdir(dir
)) != NULL
)
147 backend_constructor_t constructor
;
151 snprintf(file
, sizeof(file
), IPSEC_BACKENDDIR
"/%s", entry
->d_name
);
153 ending
= entry
->d_name
+ strlen(entry
->d_name
) - 3;
154 if (ending
<= entry
->d_name
|| !streq(ending
, ".so"))
156 /* skip anything which does not look like a library */
157 DBG2(DBG_CFG
, " skipping %s, doesn't look like a library",
161 /* try to load the library */
162 handle
= dlopen(file
, RTLD_LAZY
);
165 DBG1(DBG_CFG
, " opening backend module %s failed: %s",
166 entry
->d_name
, dlerror());
169 constructor
= dlsym(handle
, "backend_create");
170 if (constructor
== NULL
)
172 DBG1(DBG_CFG
, " backend module %s has no backend_create() "
173 "function, skipped", entry
->d_name
);
178 backend
= constructor();
181 DBG1(DBG_CFG
, " unable to create instance of backend "
182 "module %s, skipped", entry
->d_name
);
186 DBG1(DBG_CFG
, " loaded backend module successfully from %s", entry
->d_name
);
187 this->backends
->insert_last(this->backends
, backend
);
188 if (backend
->is_writeable(backend
))
190 this->writeable
->insert_last(this->writeable
, backend
);
192 this->handles
->insert_last(this->handles
, handle
);
198 * Implementation of backend_manager_t.destroy.
200 static void destroy(private_backend_manager_t
*this)
202 this->backends
->destroy_offset(this->backends
, offsetof(backend_t
, destroy
));
203 this->writeable
->destroy(this->writeable
);
204 this->handles
->destroy_function(this->handles
, (void*)dlclose
);
209 * Described in header-file
211 backend_manager_t
*backend_manager_create()
213 private_backend_manager_t
*this = malloc_thing(private_backend_manager_t
);
215 this->public.get_ike_cfg
= (ike_cfg_t
* (*)(backend_manager_t
*, host_t
*, host_t
*))get_ike_cfg
;
216 this->public.get_peer_cfg
= (peer_cfg_t
* (*)(backend_manager_t
*,identification_t
*,identification_t
*,ca_info_t
*))get_peer_cfg
;
217 this->public.add_peer_cfg
= (void (*)(backend_manager_t
*,peer_cfg_t
*))add_peer_cfg
;
218 this->public.create_iterator
= (iterator_t
* (*)(backend_manager_t
*))create_iterator
;
219 this->public.destroy
= (void (*)(backend_manager_t
*))destroy
;
221 this->backends
= linked_list_create();
222 this->writeable
= linked_list_create();
223 this->handles
= linked_list_create();
227 return &this->public;