Annotation of embedaddon/strongswan/src/libcharon/plugins/load_tester/load_tester_plugin.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2008 Martin Willi
        !             3:  * HSR Hochschule fuer Technik Rapperswil
        !             4:  *
        !             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>.
        !             9:  *
        !            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
        !            13:  * for more details.
        !            14:  */
        !            15: 
        !            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_control.h"
        !            22: #include "load_tester_diffie_hellman.h"
        !            23: 
        !            24: #include <unistd.h>
        !            25: 
        !            26: #include <daemon.h>
        !            27: #include <processing/jobs/callback_job.h>
        !            28: #include <threading/condvar.h>
        !            29: #include <threading/mutex.h>
        !            30: 
        !            31: typedef struct private_load_tester_plugin_t private_load_tester_plugin_t;
        !            32: 
        !            33: /**
        !            34:  * private data of load_tester plugin
        !            35:  */
        !            36: struct private_load_tester_plugin_t {
        !            37: 
        !            38:        /**
        !            39:         * implements plugin interface
        !            40:         */
        !            41:        load_tester_plugin_t public;
        !            42: 
        !            43:        /**
        !            44:         * load_tester configuration backend
        !            45:         */
        !            46:        load_tester_config_t *config;
        !            47: 
        !            48:        /**
        !            49:         * load_tester credential set implementation
        !            50:         */
        !            51:        load_tester_creds_t *creds;
        !            52: 
        !            53:        /**
        !            54:         * Unix control socket to initiate load-tests
        !            55:         */
        !            56:        load_tester_control_t *control;
        !            57: 
        !            58:        /**
        !            59:         * event handler, listens on bus
        !            60:         */
        !            61:        load_tester_listener_t *listener;
        !            62: 
        !            63:        /**
        !            64:         * number of iterations per thread
        !            65:         */
        !            66:        int iterations;
        !            67: 
        !            68:        /**
        !            69:         * number desired initiator threads
        !            70:         */
        !            71:        int initiators;
        !            72: 
        !            73:        /**
        !            74:         * currently running initiators
        !            75:         */
        !            76:        int running;
        !            77: 
        !            78:        /**
        !            79:         * delay between initiations, in ms
        !            80:         */
        !            81:        int delay;
        !            82: 
        !            83:        /**
        !            84:         * Throttle initiation if half-open IKE_SA count reached
        !            85:         */
        !            86:        int init_limit;
        !            87: 
        !            88:        /**
        !            89:         * mutex to lock running field
        !            90:         */
        !            91:        mutex_t *mutex;
        !            92: 
        !            93:        /**
        !            94:         * condvar to wait for initiators
        !            95:         */
        !            96:        condvar_t *condvar;
        !            97: };
        !            98: 
        !            99: /**
        !           100:  * Begin the load test
        !           101:  */
        !           102: static job_requeue_t do_load_test(private_load_tester_plugin_t *this)
        !           103: {
        !           104:        int i, s = 0, ms = 0;
        !           105: 
        !           106:        this->mutex->lock(this->mutex);
        !           107:        this->running++;
        !           108:        this->mutex->unlock(this->mutex);
        !           109:        if (this->delay)
        !           110:        {
        !           111:                s = this->delay / 1000;
        !           112:                ms = this->delay % 1000;
        !           113:        }
        !           114: 
        !           115:        for (i = 0; this->iterations == 0 || i < this->iterations; i++)
        !           116:        {
        !           117:                peer_cfg_t *peer_cfg;
        !           118:                child_cfg_t *child_cfg = NULL;
        !           119:                enumerator_t *enumerator;
        !           120: 
        !           121:                if (this->init_limit)
        !           122:                {
        !           123:                        while ((charon->ike_sa_manager->get_count(charon->ike_sa_manager) -
        !           124:                                                this->listener->get_established(this->listener)) >
        !           125:                                        this->init_limit)
        !           126:                        {
        !           127:                                if (s)
        !           128:                                {
        !           129:                                        sleep(s);
        !           130:                                }
        !           131:                                if (ms)
        !           132:                                {
        !           133:                                        usleep(ms * 1000);
        !           134:                                }
        !           135:                        }
        !           136:                }
        !           137: 
        !           138:                peer_cfg = charon->backends->get_peer_cfg_by_name(charon->backends,
        !           139:                                                                                                                  "load-test");
        !           140:                if (!peer_cfg)
        !           141:                {
        !           142:                        break;
        !           143:                }
        !           144:                enumerator = peer_cfg->create_child_cfg_enumerator(peer_cfg);
        !           145:                if (!enumerator->enumerate(enumerator, &child_cfg))
        !           146:                {
        !           147:                        enumerator->destroy(enumerator);
        !           148:                        break;
        !           149:                }
        !           150:                enumerator->destroy(enumerator);
        !           151: 
        !           152:                charon->controller->initiate(charon->controller,
        !           153:                                        peer_cfg, child_cfg->get_ref(child_cfg),
        !           154:                                        NULL, NULL, 0, FALSE);
        !           155:                if (s)
        !           156:                {
        !           157:                        sleep(s);
        !           158:                }
        !           159:                if (ms)
        !           160:                {
        !           161:                        usleep(ms * 1000);
        !           162:                }
        !           163:        }
        !           164:        this->mutex->lock(this->mutex);
        !           165:        this->running--;
        !           166:        this->condvar->signal(this->condvar);
        !           167:        this->mutex->unlock(this->mutex);
        !           168:        return JOB_REQUEUE_NONE;
        !           169: }
        !           170: 
        !           171: METHOD(plugin_t, get_name, char*,
        !           172:        private_load_tester_plugin_t *this)
        !           173: {
        !           174:        return "load-tester";
        !           175: }
        !           176: 
        !           177: /**
        !           178:  * Register load_tester plugin features
        !           179:  */
        !           180: static bool register_load_tester(private_load_tester_plugin_t *this,
        !           181:                                                                 plugin_feature_t *feature, bool reg, void *data)
        !           182: {
        !           183:        if (reg)
        !           184:        {
        !           185:                u_int i, shutdown_on = 0;
        !           186: 
        !           187:                this->config = load_tester_config_create();
        !           188:                this->creds = load_tester_creds_create();
        !           189:                this->control = load_tester_control_create();
        !           190: 
        !           191:                charon->backends->add_backend(charon->backends, &this->config->backend);
        !           192:                lib->credmgr->add_set(lib->credmgr, &this->creds->credential_set);
        !           193: 
        !           194:                if (lib->settings->get_bool(lib->settings,
        !           195:                                "%s.plugins.load-tester.shutdown_when_complete", 0, lib->ns))
        !           196:                {
        !           197:                        shutdown_on = this->iterations * this->initiators;
        !           198:                }
        !           199:                this->listener = load_tester_listener_create(shutdown_on, this->config);
        !           200:                charon->bus->add_listener(charon->bus, &this->listener->listener);
        !           201: 
        !           202:                for (i = 0; i < this->initiators; i++)
        !           203:                {
        !           204:                        lib->processor->queue_job(lib->processor, (job_t*)
        !           205:                                callback_job_create_with_prio((callback_job_cb_t)do_load_test,
        !           206:                                                                                this, NULL, NULL, JOB_PRIO_CRITICAL));
        !           207:                }
        !           208:        }
        !           209:        else
        !           210:        {
        !           211:                this->iterations = -1;
        !           212:                this->mutex->lock(this->mutex);
        !           213:                while (this->running)
        !           214:                {
        !           215:                        this->condvar->wait(this->condvar, this->mutex);
        !           216:                }
        !           217:                this->mutex->unlock(this->mutex);
        !           218:                charon->backends->remove_backend(charon->backends, &this->config->backend);
        !           219:                lib->credmgr->remove_set(lib->credmgr, &this->creds->credential_set);
        !           220:                charon->bus->remove_listener(charon->bus, &this->listener->listener);
        !           221:                this->config->destroy(this->config);
        !           222:                this->creds->destroy(this->creds);
        !           223:                this->listener->destroy(this->listener);
        !           224:                this->control->destroy(this->control);
        !           225:        }
        !           226:        return TRUE;
        !           227: }
        !           228: 
        !           229: METHOD(plugin_t, get_features, int,
        !           230:        private_load_tester_plugin_t *this, plugin_feature_t *features[])
        !           231: {
        !           232:        static plugin_feature_t f[] = {
        !           233:                PLUGIN_REGISTER(DH, load_tester_diffie_hellman_create),
        !           234:                        PLUGIN_PROVIDE(DH, MODP_NULL),
        !           235:                                PLUGIN_DEPENDS(CUSTOM, "load-tester"),
        !           236:                PLUGIN_CALLBACK((plugin_feature_callback_t)register_load_tester, NULL),
        !           237:                        PLUGIN_PROVIDE(CUSTOM, "load-tester"),
        !           238:                                PLUGIN_DEPENDS(CUSTOM, "kernel-net"),
        !           239:                                PLUGIN_SDEPEND(PRIVKEY, KEY_RSA),
        !           240:                                PLUGIN_SDEPEND(CERT_DECODE, CERT_ANY),
        !           241:                                PLUGIN_SDEPEND(CERT_DECODE, CERT_X509),
        !           242:                PLUGIN_CALLBACK(kernel_ipsec_register, load_tester_ipsec_create),
        !           243:                        PLUGIN_PROVIDE(CUSTOM, "kernel-ipsec"),
        !           244:        };
        !           245:        int count = countof(f);
        !           246: 
        !           247:        *features = f;
        !           248: 
        !           249:        if (!lib->settings->get_bool(lib->settings,
        !           250:                        "%s.plugins.load-tester.fake_kernel", FALSE, lib->ns))
        !           251:        {
        !           252:                count -= 2;
        !           253:        }
        !           254:        return count;
        !           255: }
        !           256: 
        !           257: METHOD(plugin_t, destroy, void,
        !           258:        private_load_tester_plugin_t *this)
        !           259: {
        !           260:        this->mutex->destroy(this->mutex);
        !           261:        this->condvar->destroy(this->condvar);
        !           262:        free(this);
        !           263: }
        !           264: 
        !           265: /*
        !           266:  * see header file
        !           267:  */
        !           268: plugin_t *load_tester_plugin_create()
        !           269: {
        !           270:        private_load_tester_plugin_t *this;
        !           271: 
        !           272:        if (!lib->settings->get_bool(lib->settings, "%s.plugins.load-tester.enable",
        !           273:                                                                 FALSE, lib->ns))
        !           274:        {
        !           275:                DBG1(DBG_CFG, "disabling load-tester plugin, not configured");
        !           276:                return NULL;
        !           277:        }
        !           278: 
        !           279:        INIT(this,
        !           280:                .public = {
        !           281:                        .plugin = {
        !           282:                                .get_name = _get_name,
        !           283:                                .get_features = _get_features,
        !           284:                                .reload = (void*)return_false,
        !           285:                                .destroy = _destroy,
        !           286:                        },
        !           287:                },
        !           288:                .delay = lib->settings->get_int(lib->settings,
        !           289:                                                        "%s.plugins.load-tester.delay", 0, lib->ns),
        !           290:                .iterations = lib->settings->get_int(lib->settings,
        !           291:                                                        "%s.plugins.load-tester.iterations", 1, lib->ns),
        !           292:                .initiators = lib->settings->get_int(lib->settings,
        !           293:                                                        "%s.plugins.load-tester.initiators", 0, lib->ns),
        !           294:                .init_limit = lib->settings->get_int(lib->settings,
        !           295:                                                        "%s.plugins.load-tester.init_limit", 0, lib->ns),
        !           296:                .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
        !           297:                .condvar = condvar_create(CONDVAR_TYPE_DEFAULT),
        !           298:        );
        !           299:        return &this->public.plugin;
        !           300: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>