2 * Copyright (C) 2008 Martin Willi
3 * Hochschule fuer Technik Rapperswil
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 #include "load_tester_plugin.h"
17 #include "load_tester_config.h"
18 #include "load_tester_creds.h"
19 #include "load_tester_ipsec.h"
20 #include "load_tester_listener.h"
21 #include "load_tester_diffie_hellman.h"
27 #include <processing/jobs/callback_job.h>
28 #include <threading/condvar.h>
29 #include <threading/mutex.h>
31 typedef struct private_load_tester_plugin_t private_load_tester_plugin_t
;
34 * private data of load_tester plugin
36 struct private_load_tester_plugin_t
{
39 * implements plugin interface
41 load_tester_plugin_t
public;
44 * load_tester configuration backend
46 load_tester_config_t
*config
;
49 * load_tester credential set implementation
51 load_tester_creds_t
*creds
;
54 * event handler, listens on bus
56 load_tester_listener_t
*listener
;
59 * number of iterations per thread
64 * number desired initiator threads
69 * currently running initiators
74 * delay between initiations, in ms
79 * Throttle initiation if half-open IKE_SA count reached
84 * mutex to lock running field
89 * condvar to wait for initiators
97 static job_requeue_t
do_load_test(private_load_tester_plugin_t
*this)
101 this->mutex
->lock(this->mutex
);
103 this->mutex
->unlock(this->mutex
);
106 s
= this->delay
/ 1000;
107 ms
= this->delay
% 1000;
110 for (i
= 0; this->iterations
== 0 || i
< this->iterations
; i
++)
112 peer_cfg_t
*peer_cfg
;
113 child_cfg_t
*child_cfg
= NULL
;
114 enumerator_t
*enumerator
;
116 if (this->init_limit
)
118 while ((charon
->ike_sa_manager
->get_count(charon
->ike_sa_manager
) -
119 this->listener
->get_established(this->listener
)) >
133 peer_cfg
= charon
->backends
->get_peer_cfg_by_name(charon
->backends
,
139 enumerator
= peer_cfg
->create_child_cfg_enumerator(peer_cfg
);
140 if (!enumerator
->enumerate(enumerator
, &child_cfg
))
142 enumerator
->destroy(enumerator
);
145 enumerator
->destroy(enumerator
);
147 charon
->controller
->initiate(charon
->controller
,
148 peer_cfg
, child_cfg
->get_ref(child_cfg
),
159 this->mutex
->lock(this->mutex
);
161 this->condvar
->signal(this->condvar
);
162 this->mutex
->unlock(this->mutex
);
163 return JOB_REQUEUE_NONE
;
166 METHOD(plugin_t
, get_name
, char*,
167 private_load_tester_plugin_t
*this)
169 return "load-tester";
173 * Register load_tester plugin features
175 static bool register_load_tester(private_load_tester_plugin_t
*this,
176 plugin_feature_t
*feature
, bool reg
, void *data
)
180 u_int i
, shutdown_on
= 0;
182 this->config
= load_tester_config_create();
183 this->creds
= load_tester_creds_create();
185 charon
->backends
->add_backend(charon
->backends
, &this->config
->backend
);
186 lib
->credmgr
->add_set(lib
->credmgr
, &this->creds
->credential_set
);
188 if (lib
->settings
->get_bool(lib
->settings
,
189 "%s.plugins.load-tester.shutdown_when_complete", 0, charon
->name
))
191 shutdown_on
= this->iterations
* this->initiators
;
193 this->listener
= load_tester_listener_create(shutdown_on
);
194 charon
->bus
->add_listener(charon
->bus
, &this->listener
->listener
);
196 for (i
= 0; i
< this->initiators
; i
++)
198 lib
->processor
->queue_job(lib
->processor
, (job_t
*)
199 callback_job_create_with_prio((callback_job_cb_t
)do_load_test
,
200 this, NULL
, NULL
, JOB_PRIO_CRITICAL
));
205 this->iterations
= -1;
206 this->mutex
->lock(this->mutex
);
207 while (this->running
)
209 this->condvar
->wait(this->condvar
, this->mutex
);
211 this->mutex
->unlock(this->mutex
);
212 charon
->backends
->remove_backend(charon
->backends
, &this->config
->backend
);
213 lib
->credmgr
->remove_set(lib
->credmgr
, &this->creds
->credential_set
);
214 charon
->bus
->remove_listener(charon
->bus
, &this->listener
->listener
);
215 this->config
->destroy(this->config
);
216 this->creds
->destroy(this->creds
);
217 this->listener
->destroy(this->listener
);
222 METHOD(plugin_t
, get_features
, int,
223 private_load_tester_plugin_t
*this, plugin_feature_t
*features
[])
225 static plugin_feature_t f
[] = {
226 PLUGIN_REGISTER(DH
, load_tester_diffie_hellman_create
),
227 PLUGIN_PROVIDE(DH
, MODP_NULL
),
228 PLUGIN_DEPENDS(CUSTOM
, "load-tester"),
229 PLUGIN_CALLBACK((plugin_feature_callback_t
)register_load_tester
, NULL
),
230 PLUGIN_PROVIDE(CUSTOM
, "load-tester"),
231 PLUGIN_SDEPEND(PRIVKEY
, KEY_RSA
),
232 PLUGIN_SDEPEND(CERT_DECODE
, CERT_ANY
),
233 PLUGIN_SDEPEND(CERT_DECODE
, CERT_X509
),
239 METHOD(plugin_t
, destroy
, void,
240 private_load_tester_plugin_t
*this)
242 hydra
->kernel_interface
->remove_ipsec_interface(hydra
->kernel_interface
,
243 (kernel_ipsec_constructor_t
)load_tester_ipsec_create
);
244 this->mutex
->destroy(this->mutex
);
245 this->condvar
->destroy(this->condvar
);
252 plugin_t
*load_tester_plugin_create()
254 private_load_tester_plugin_t
*this;
256 if (!lib
->settings
->get_bool(lib
->settings
,
257 "%s.plugins.load-tester.enable", FALSE
, charon
->name
))
259 DBG1(DBG_CFG
, "disabling load-tester plugin, not configured");
266 .get_name
= _get_name
,
267 .get_features
= _get_features
,
268 .reload
= (void*)return_false
,
272 .delay
= lib
->settings
->get_int(lib
->settings
,
273 "%s.plugins.load-tester.delay", 0, charon
->name
),
274 .iterations
= lib
->settings
->get_int(lib
->settings
,
275 "%s.plugins.load-tester.iterations", 1, charon
->name
),
276 .initiators
= lib
->settings
->get_int(lib
->settings
,
277 "%s.plugins.load-tester.initiators", 0, charon
->name
),
278 .init_limit
= lib
->settings
->get_int(lib
->settings
,
279 "%s.plugins.load-tester.init_limit", 0, charon
->name
),
280 .mutex
= mutex_create(MUTEX_TYPE_DEFAULT
),
281 .condvar
= condvar_create(CONDVAR_TYPE_DEFAULT
),
284 if (lib
->settings
->get_bool(lib
->settings
,
285 "%s.plugins.load-tester.fake_kernel", FALSE
, charon
->name
))
287 hydra
->kernel_interface
->add_ipsec_interface(hydra
->kernel_interface
,
288 (kernel_ipsec_constructor_t
)load_tester_ipsec_create
);
290 return &this->public.plugin
;