Merge branch 'make-before-break'
[strongswan.git] / src / libcharon / plugins / load_tester / load_tester_config.c
1 /*
2 * Copyright (C) 2008 Martin Willi
3 * 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_config.h"
17
18 #include <netdb.h>
19
20 #include <daemon.h>
21 #include <hydra.h>
22 #include <attributes/mem_pool.h>
23 #include <collections/hashtable.h>
24 #include <threading/mutex.h>
25
26 #define UNIQUE_PORT_START 1025
27
28 typedef struct private_load_tester_config_t private_load_tester_config_t;
29
30 /**
31 * Private data of an load_tester_config_t object
32 */
33 struct private_load_tester_config_t {
34
35 /**
36 * Public part
37 */
38 load_tester_config_t public;
39
40 /**
41 * peer config
42 */
43 peer_cfg_t *peer_cfg;
44
45 /**
46 * virtual IP, if any
47 */
48 host_t *vip;
49
50 /**
51 * Initiator address
52 */
53 char *initiator;
54
55 /**
56 * Responder address
57 */
58 char *responder;
59
60 /**
61 * IP address pool
62 */
63 char *pool;
64
65 /**
66 * IKE proposal
67 */
68 proposal_t *proposal;
69
70 /**
71 * ESP proposal
72 */
73 proposal_t *esp;
74
75 /**
76 * Authentication method(s) to use/expect from initiator
77 */
78 char *initiator_auth;
79
80 /**
81 * Authentication method(s) use/expected from responder
82 */
83 char *responder_auth;
84
85 /**
86 * Initiator ID to enforce
87 */
88 char *initiator_id;
89
90 /**
91 * Initiator ID to to match against as responder
92 */
93 char *initiator_match;
94
95 /**
96 * Responder ID to enforce
97 */
98 char *responder_id;
99
100 /**
101 * IPsec mode, tunnel|transport|beet
102 */
103 char *mode;
104
105 /**
106 * Traffic Selector on initiator side, as proposed from initiator
107 */
108 char *initiator_tsi;
109
110 /**
111 * Traffic Selector on responder side, as proposed from initiator
112 */
113 char *initiator_tsr;
114
115 /**
116 * Traffic Selector on initiator side, as narrowed by responder
117 */
118 char *responder_tsi;
119
120 /**
121 * Traffic Selector on responder side, as narrowed by responder
122 */
123 char *responder_tsr;
124
125 /**
126 * Current port for unique initiator ports
127 */
128 u_int16_t unique_port;
129
130 /**
131 * IKE_SA rekeying delay
132 */
133 u_int ike_rekey;
134
135 /**
136 * CHILD_SA rekeying delay
137 */
138 u_int child_rekey;
139
140 /**
141 * DPD check delay
142 */
143 u_int dpd_delay;
144
145 /**
146 * DPD timeout (IKEv1 only)
147 */
148 u_int dpd_timeout;
149
150 /**
151 * incremental numbering of generated configs
152 */
153 refcount_t num;
154
155 /**
156 * Dynamic source port, if used
157 */
158 u_int16_t port;
159
160 /**
161 * IKE version to use for load testing
162 */
163 ike_version_t version;
164
165 /**
166 * List of pools to allocate external addresses dynamically, as mem_pool_t
167 */
168 linked_list_t *pools;
169
170 /**
171 * Address prefix to use when installing dynamic addresses
172 */
173 int prefix;
174
175 /**
176 * Keep addresses until shutdown?
177 */
178 bool keep;
179
180 /**
181 * Hashtable with leases in "pools", host_t => entry_t
182 */
183 hashtable_t *leases;
184
185 /**
186 * Mutex for leases hashtable
187 */
188 mutex_t *mutex;
189 };
190
191 /**
192 * Lease entry
193 */
194 typedef struct {
195 /** host reference, equal to key */
196 host_t *host;
197 /** associated identity */
198 identification_t *id;
199 } entry_t;
200
201 /**
202 * Destroy an entry_t
203 */
204 static void entry_destroy(entry_t *this)
205 {
206 this->host->destroy(this->host);
207 this->id->destroy(this->id);
208 free(this);
209 }
210
211 /**
212 * Hashtable hash function
213 */
214 static u_int hash(host_t *key)
215 {
216 return chunk_hash(key->get_address(key));
217 }
218
219 /**
220 * Hashtable equals function
221 */
222 static bool equals(host_t *a, host_t *b)
223 {
224 return a->ip_equals(a, b);
225 }
226
227 /**
228 * Load external addresses to use, if any
229 */
230 static void load_addrs(private_load_tester_config_t *this)
231 {
232 enumerator_t *enumerator, *tokens;
233 host_t *from, *to;
234 int bits;
235 char *iface, *token, *pos;
236 mem_pool_t *pool;
237
238 this->keep = lib->settings->get_bool(lib->settings,
239 "%s.plugins.load-tester.addrs_keep", FALSE, lib->ns);
240 this->prefix = lib->settings->get_int(lib->settings,
241 "%s.plugins.load-tester.addrs_prefix", 16, lib->ns);
242 enumerator = lib->settings->create_key_value_enumerator(lib->settings,
243 "%s.plugins.load-tester.addrs", lib->ns);
244 while (enumerator->enumerate(enumerator, &iface, &token))
245 {
246 tokens = enumerator_create_token(token, ",", " ");
247 while (tokens->enumerate(tokens, &token))
248 {
249 pos = strchr(token, '-');
250 if (pos)
251 { /* range */
252 *(pos++) = '\0';
253 /* trim whitespace */
254 while (*pos == ' ')
255 {
256 pos++;
257 }
258 while (token[strlen(token) - 1] == ' ')
259 {
260 token[strlen(token) - 1] = '\0';
261 }
262 from = host_create_from_string(token, 0);
263 to = host_create_from_string(pos, 0);
264 if (from && to)
265 {
266 pool = mem_pool_create_range(iface, from, to);
267 if (pool)
268 {
269 DBG1(DBG_CFG, "loaded load-tester address range "
270 "%H-%H on %s", from, to, iface);
271 this->pools->insert_last(this->pools, pool);
272 }
273 from->destroy(from);
274 to->destroy(to);
275 }
276 else
277 {
278 DBG1(DBG_CFG, "parsing load-tester address range %s-%s "
279 "failed, skipped", token, pos);
280 DESTROY_IF(from);
281 DESTROY_IF(to);
282 }
283 }
284 else
285 { /* subnet */
286 from = host_create_from_subnet(token, &bits);
287 if (from)
288 {
289 DBG1(DBG_CFG, "loaded load-tester address pool %H/%d on %s",
290 from, bits, iface);
291 pool = mem_pool_create(iface, from, bits);
292 from->destroy(from);
293 this->pools->insert_last(this->pools, pool);
294 }
295 else
296 {
297 DBG1(DBG_CFG, "parsing load-tester address %s failed, "
298 "skipped", token);
299 }
300 }
301 }
302 tokens->destroy(tokens);
303 }
304 enumerator->destroy(enumerator);
305 }
306
307 /**
308 * Generate auth config from string
309 */
310 static void generate_auth_cfg(private_load_tester_config_t *this, char *str,
311 peer_cfg_t *peer_cfg, bool local, int num)
312 {
313 enumerator_t *enumerator;
314 auth_cfg_t *auth;
315 identification_t *id;
316 auth_class_t class;
317 eap_type_t type;
318 char buf[128];
319 int rnd = 0;
320
321 enumerator = enumerator_create_token(str, "|", " ");
322 while (enumerator->enumerate(enumerator, &str))
323 {
324 id = NULL;
325 auth = auth_cfg_create();
326 rnd++;
327
328 if (this->initiator_id)
329 {
330 if (this->initiator_match && (!local && !num))
331 { /* as responder, use the secified identity that matches
332 * all used initiator identities, if given. */
333 snprintf(buf, sizeof(buf), this->initiator_match, rnd);
334 id = identification_create_from_string(buf);
335 }
336 else if ((local && num) || (!local && !num))
337 { /* as initiator, create peer specific identities */
338 snprintf(buf, sizeof(buf), this->initiator_id, num, rnd);
339 id = identification_create_from_string(buf);
340 }
341 }
342 if (this->responder_id)
343 {
344 if ((local && !num) || (!local && num))
345 {
346 snprintf(buf, sizeof(buf), this->responder_id, num, rnd);
347 id = identification_create_from_string(buf);
348 }
349 }
350
351 if (streq(str, "psk"))
352 { /* PSK authentication, use FQDNs */
353 class = AUTH_CLASS_PSK;
354 if (!id)
355 {
356 if ((local && !num) || (!local && num))
357 {
358 id = identification_create_from_string("srv.strongswan.org");
359 }
360 else if (local)
361 {
362 snprintf(buf, sizeof(buf), "c%d-r%d.strongswan.org",
363 num, rnd);
364 id = identification_create_from_string(buf);
365 }
366 else
367 {
368 id = identification_create_from_string("*.strongswan.org");
369 }
370 }
371 }
372 else if (strpfx(str, "eap"))
373 { /* EAP authentication, use a NAI */
374 class = AUTH_CLASS_EAP;
375 if (*(str + strlen("eap")) == '-')
376 {
377 type = eap_type_from_string(str + strlen("eap-"));
378 if (type)
379 {
380 auth->add(auth, AUTH_RULE_EAP_TYPE, type);
381 }
382 }
383 if (!id)
384 {
385 if (local && num)
386 {
387 snprintf(buf, sizeof(buf), "1%.10d%.4d@strongswan.org",
388 num, rnd);
389 id = identification_create_from_string(buf);
390 }
391 else
392 {
393 id = identification_create_from_encoding(ID_ANY, chunk_empty);
394 }
395 }
396 }
397 else
398 {
399 if (!streq(str, "pubkey"))
400 {
401 DBG1(DBG_CFG, "invalid authentication: '%s', fallback to pubkey",
402 str);
403 }
404 /* certificate authentication, use distinguished names */
405 class = AUTH_CLASS_PUBKEY;
406 if (!id)
407 {
408 if ((local && !num) || (!local && num))
409 {
410 id = identification_create_from_string(
411 "CN=srv, OU=load-test, O=strongSwan");
412 }
413 else if (local)
414 {
415 snprintf(buf, sizeof(buf),
416 "CN=c%d-r%d, OU=load-test, O=strongSwan", num, rnd);
417 id = identification_create_from_string(buf);
418 }
419 else
420 {
421 id = identification_create_from_string(
422 "CN=*, OU=load-test, O=strongSwan");
423 }
424 }
425 }
426 auth->add(auth, AUTH_RULE_AUTH_CLASS, class);
427 auth->add(auth, AUTH_RULE_IDENTITY, id);
428 peer_cfg->add_auth_cfg(peer_cfg, auth, local);
429 }
430 enumerator->destroy(enumerator);
431 }
432
433 /**
434 * Parse a protoport specifier
435 */
436 static bool parse_protoport(char *token, u_int16_t *from_port,
437 u_int16_t *to_port, u_int8_t *protocol)
438 {
439 char *sep, *port = "", *endptr;
440 struct protoent *proto;
441 struct servent *svc;
442 long int p;
443
444 sep = strrchr(token, ']');
445 if (!sep)
446 {
447 return FALSE;
448 }
449 *sep = '\0';
450
451 sep = strchr(token, '/');
452 if (sep)
453 { /* protocol/port */
454 *sep = '\0';
455 port = sep + 1;
456 }
457
458 if (streq(token, "%any"))
459 {
460 *protocol = 0;
461 }
462 else
463 {
464 proto = getprotobyname(token);
465 if (proto)
466 {
467 *protocol = proto->p_proto;
468 }
469 else
470 {
471 p = strtol(token, &endptr, 0);
472 if ((*token && *endptr) || p < 0 || p > 0xff)
473 {
474 return FALSE;
475 }
476 *protocol = (u_int8_t)p;
477 }
478 }
479 if (streq(port, "%any"))
480 {
481 *from_port = 0;
482 *to_port = 0xffff;
483 }
484 else if (streq(port, "%opaque"))
485 {
486 *from_port = 0xffff;
487 *to_port = 0;
488 }
489 else if (streq(port, "%unique"))
490 {
491 *from_port = *to_port = 0;
492 }
493 else if (*port)
494 {
495 svc = getservbyname(port, NULL);
496 if (svc)
497 {
498 *from_port = *to_port = ntohs(svc->s_port);
499 }
500 else
501 {
502 p = strtol(port, &endptr, 0);
503 if (p < 0 || p > 0xffff)
504 {
505 return FALSE;
506 }
507 *from_port = p;
508 if (*endptr == '-')
509 {
510 port = endptr + 1;
511 p = strtol(port, &endptr, 0);
512 if (p < 0 || p > 0xffff)
513 {
514 return FALSE;
515 }
516 }
517 *to_port = p;
518 if (*endptr)
519 {
520 return FALSE;
521 }
522 }
523 }
524 return TRUE;
525 }
526
527 /**
528 * Add a TS from a string to a child_cfg
529 */
530 static void add_ts(private_load_tester_config_t *this,
531 char *string, child_cfg_t *cfg, bool local, bool initiator)
532 {
533 traffic_selector_t *ts;
534
535 if (string)
536 {
537 enumerator_t *enumerator;
538 char *subnet, *pos;
539 u_int16_t from_port, to_port;
540 u_int8_t proto;
541
542 enumerator = enumerator_create_token(string, ",", " ");
543 while (enumerator->enumerate(enumerator, &subnet))
544 {
545 proto = 0;
546 from_port = 0;
547 to_port = 65535;
548
549 pos = strchr(subnet, '[');
550 if (pos)
551 {
552 *(pos++) = '\0';
553 if (!parse_protoport(pos, &from_port, &to_port, &proto))
554 {
555 DBG1(DBG_CFG, "invalid proto/port: %s, skipped subnet",
556 pos);
557 continue;
558 }
559 }
560 if (from_port == 0 && to_port == 0)
561 { /* %unique */
562 if (initiator)
563 {
564 from_port = this->unique_port++;
565 from_port = to_port = max(from_port, UNIQUE_PORT_START);
566 }
567 else
568 { /* not supported as responder, use %any */
569 to_port = 65535;
570 }
571 }
572 if (streq(subnet, "%dynamic"))
573 {
574 ts = traffic_selector_create_dynamic(proto,
575 from_port, to_port);
576 }
577 else
578 {
579 ts = traffic_selector_create_from_cidr(subnet, proto,
580 from_port, to_port);
581 }
582 if (ts)
583 {
584 cfg->add_traffic_selector(cfg, local, ts);
585 }
586 else
587 {
588 DBG1(DBG_CFG, "invalid subnet: %s, skipped", subnet);
589 }
590 }
591 enumerator->destroy(enumerator);
592 }
593 else
594 {
595 ts = traffic_selector_create_dynamic(0, 0, 65535);
596 if (ts)
597 {
598 cfg->add_traffic_selector(cfg, local, ts);
599 }
600 }
601 }
602
603 /**
604 * Allocate and install a dynamic external address to use
605 */
606 static host_t *allocate_addr(private_load_tester_config_t *this, uint num)
607 {
608 enumerator_t *enumerator;
609 mem_pool_t *pool;
610 host_t *found = NULL, *requested;
611 identification_t *id;
612 char *iface = NULL, buf[32];
613 entry_t *entry;
614
615 requested = host_create_any(AF_INET);
616 snprintf(buf, sizeof(buf), "ext-%d", num);
617 id = identification_create_from_string(buf);
618 enumerator = this->pools->create_enumerator(this->pools);
619 while (enumerator->enumerate(enumerator, &pool))
620 {
621 found = pool->acquire_address(pool, id, requested, MEM_POOL_NEW, NULL);
622 if (found)
623 {
624 iface = (char*)pool->get_name(pool);
625 break;
626 }
627 }
628 enumerator->destroy(enumerator);
629 requested->destroy(requested);
630
631 if (!found)
632 {
633 DBG1(DBG_CFG, "no address found to install as load-tester external IP");
634 id->destroy(id);
635 return NULL;
636 }
637 if (hydra->kernel_interface->add_ip(hydra->kernel_interface,
638 found, this->prefix, iface) != SUCCESS)
639 {
640 DBG1(DBG_CFG, "installing load-tester IP %H on %s failed", found, iface);
641 found->destroy(found);
642 id->destroy(id);
643 return NULL;
644 }
645 DBG1(DBG_CFG, "installed load-tester IP %H on %s", found, iface);
646 INIT(entry,
647 .host = found->clone(found),
648 .id = id,
649 );
650 this->mutex->lock(this->mutex);
651 entry = this->leases->put(this->leases, entry->host, entry);
652 this->mutex->unlock(this->mutex);
653 if (entry)
654 { /* shouldn't actually happen */
655 entry_destroy(entry);
656 }
657 return found;
658 }
659
660 /**
661 * Generate a new initiator config, num = 0 for responder config
662 */
663 static peer_cfg_t* generate_config(private_load_tester_config_t *this, uint num)
664 {
665 ike_cfg_t *ike_cfg;
666 child_cfg_t *child_cfg;
667 peer_cfg_t *peer_cfg;
668 char local[32], *remote;
669 host_t *addr;
670 ipsec_mode_t mode = MODE_TUNNEL;
671 lifetime_cfg_t lifetime = {
672 .time = {
673 .life = this->child_rekey * 2,
674 .rekey = this->child_rekey,
675 .jitter = 0
676 }
677 };
678
679 if (num)
680 { /* initiator */
681 if (this->pools->get_count(this->pools))
682 { /* using dynamically installed external addresses */
683 addr = allocate_addr(this, num);
684 if (!addr)
685 {
686 DBG1(DBG_CFG, "allocating external address failed");
687 return NULL;
688 }
689 snprintf(local, sizeof(local), "%H", addr);
690 addr->destroy(addr);
691 }
692 else
693 {
694 snprintf(local, sizeof(local), "%s", this->initiator);
695 }
696 remote = this->responder;
697 }
698 else
699 {
700 snprintf(local, sizeof(local), "%s", this->responder);
701 remote = this->initiator;
702 }
703
704 if (this->port && num)
705 {
706 ike_cfg = ike_cfg_create(this->version, TRUE, FALSE,
707 local, this->port + num - 1,
708 remote, IKEV2_NATT_PORT,
709 FRAGMENTATION_NO, 0);
710 }
711 else
712 {
713 ike_cfg = ike_cfg_create(this->version, TRUE, FALSE, local,
714 charon->socket->get_port(charon->socket, FALSE),
715 remote, IKEV2_UDP_PORT,
716 FRAGMENTATION_NO, 0);
717 }
718 ike_cfg->add_proposal(ike_cfg, this->proposal->clone(this->proposal));
719 peer_cfg = peer_cfg_create("load-test", ike_cfg,
720 CERT_SEND_IF_ASKED, UNIQUE_NO, 1, /* keytries */
721 this->ike_rekey, 0, /* rekey, reauth */
722 0, this->ike_rekey, /* jitter, overtime */
723 FALSE, FALSE, TRUE, /* mobike, aggressive, pull */
724 this->dpd_delay, /* dpd_delay */
725 this->dpd_timeout, /* dpd_timeout */
726 FALSE, NULL, NULL);
727 if (this->vip)
728 {
729 peer_cfg->add_virtual_ip(peer_cfg, this->vip->clone(this->vip));
730 }
731 if (this->pool)
732 {
733 peer_cfg->add_pool(peer_cfg, this->pool);
734 }
735 if (num)
736 { /* initiator */
737 generate_auth_cfg(this, this->initiator_auth, peer_cfg, TRUE, num);
738 generate_auth_cfg(this, this->responder_auth, peer_cfg, FALSE, num);
739 }
740 else
741 { /* responder */
742 generate_auth_cfg(this, this->responder_auth, peer_cfg, TRUE, num);
743 generate_auth_cfg(this, this->initiator_auth, peer_cfg, FALSE, num);
744 }
745
746 if (this->mode)
747 {
748 if (streq(this->mode, "transport"))
749 {
750 mode = MODE_TRANSPORT;
751 }
752 else if (streq(this->mode, "beet"))
753 {
754 mode = MODE_BEET;
755 }
756 }
757
758 child_cfg = child_cfg_create("load-test", &lifetime, NULL, TRUE, mode,
759 ACTION_NONE, ACTION_NONE, ACTION_NONE, FALSE,
760 0, 0, NULL, NULL, 0);
761 child_cfg->add_proposal(child_cfg, this->esp->clone(this->esp));
762
763 if (num)
764 { /* initiator */
765 if (this->vip)
766 {
767 add_ts(this, NULL, child_cfg, TRUE, TRUE);
768 }
769 else
770 {
771 add_ts(this, this->initiator_tsi, child_cfg, TRUE, TRUE);
772 }
773 add_ts(this, this->initiator_tsr, child_cfg, FALSE, TRUE);
774 }
775 else
776 { /* responder */
777 add_ts(this, this->responder_tsr, child_cfg, TRUE, FALSE);
778 add_ts(this, this->responder_tsi, child_cfg, FALSE, FALSE);
779 }
780 peer_cfg->add_child_cfg(peer_cfg, child_cfg);
781 return peer_cfg;
782 }
783
784 METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*,
785 private_load_tester_config_t *this,
786 identification_t *me, identification_t *other)
787 {
788 return enumerator_create_single(this->peer_cfg, NULL);
789 }
790
791 METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*,
792 private_load_tester_config_t *this, host_t *me, host_t *other)
793 {
794 ike_cfg_t *ike_cfg;
795
796 ike_cfg = this->peer_cfg->get_ike_cfg(this->peer_cfg);
797 return enumerator_create_single(ike_cfg, NULL);
798 }
799
800 METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*,
801 private_load_tester_config_t *this, char *name)
802 {
803 if (streq(name, "load-test"))
804 {
805 return generate_config(this, (u_int)ref_get(&this->num));
806 }
807 return NULL;
808 }
809
810 METHOD(load_tester_config_t, delete_ip, void,
811 private_load_tester_config_t *this, host_t *ip)
812 {
813 enumerator_t *enumerator;
814 mem_pool_t *pool;
815 entry_t *entry;
816
817 if (this->keep)
818 {
819 return;
820 }
821
822 this->mutex->lock(this->mutex);
823 entry = this->leases->remove(this->leases, ip);
824 this->mutex->unlock(this->mutex);
825
826 if (entry)
827 {
828 enumerator = this->pools->create_enumerator(this->pools);
829 while (enumerator->enumerate(enumerator, &pool))
830 {
831 if (pool->release_address(pool, entry->host, entry->id))
832 {
833 hydra->kernel_interface->del_ip(hydra->kernel_interface,
834 entry->host, this->prefix, FALSE);
835 break;
836 }
837 }
838 enumerator->destroy(enumerator);
839 entry_destroy(entry);
840 }
841 }
842
843 /**
844 * Clean up leases for allocated external addresses, if have been kept
845 */
846 static void cleanup_leases(private_load_tester_config_t *this)
847 {
848 enumerator_t *pools, *leases;
849 mem_pool_t *pool;
850 identification_t *id;
851 host_t *addr;
852 entry_t *entry;
853 bool online;
854
855 pools = this->pools->create_enumerator(this->pools);
856 while (pools->enumerate(pools, &pool))
857 {
858 leases = pool->create_lease_enumerator(pool);
859 while (leases->enumerate(leases, &id, &addr, &online))
860 {
861 if (online)
862 {
863 hydra->kernel_interface->del_ip(hydra->kernel_interface,
864 addr, this->prefix, FALSE);
865 entry = this->leases->remove(this->leases, addr);
866 if (entry)
867 {
868 entry_destroy(entry);
869 }
870 }
871 }
872 leases->destroy(leases);
873 }
874 pools->destroy(pools);
875 }
876
877 METHOD(load_tester_config_t, destroy, void,
878 private_load_tester_config_t *this)
879 {
880 if (this->keep)
881 {
882 cleanup_leases(this);
883 }
884 this->mutex->destroy(this->mutex);
885 this->leases->destroy(this->leases);
886 this->pools->destroy_offset(this->pools, offsetof(mem_pool_t, destroy));
887 this->peer_cfg->destroy(this->peer_cfg);
888 DESTROY_IF(this->proposal);
889 DESTROY_IF(this->esp);
890 DESTROY_IF(this->vip);
891 free(this);
892 }
893
894 /**
895 * Described in header.
896 */
897 load_tester_config_t *load_tester_config_create()
898 {
899 private_load_tester_config_t *this;
900
901 INIT(this,
902 .public = {
903 .backend = {
904 .create_peer_cfg_enumerator = _create_peer_cfg_enumerator,
905 .create_ike_cfg_enumerator = _create_ike_cfg_enumerator,
906 .get_peer_cfg_by_name = _get_peer_cfg_by_name,
907 },
908 .delete_ip = _delete_ip,
909 .destroy = _destroy,
910 },
911 .pools = linked_list_create(),
912 .leases = hashtable_create((hashtable_hash_t)hash,
913 (hashtable_equals_t)equals, 256),
914 .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
915 .num = 1,
916 .unique_port = UNIQUE_PORT_START,
917 );
918
919 if (lib->settings->get_bool(lib->settings,
920 "%s.plugins.load-tester.request_virtual_ip", FALSE, lib->ns))
921 {
922 this->vip = host_create_from_string("0.0.0.0", 0);
923 }
924 this->pool = lib->settings->get_str(lib->settings,
925 "%s.plugins.load-tester.pool", NULL, lib->ns);
926 this->initiator = lib->settings->get_str(lib->settings,
927 "%s.plugins.load-tester.initiator", "0.0.0.0", lib->ns);
928 this->responder = lib->settings->get_str(lib->settings,
929 "%s.plugins.load-tester.responder", "127.0.0.1", lib->ns);
930
931 this->proposal = proposal_create_from_string(PROTO_IKE,
932 lib->settings->get_str(lib->settings,
933 "%s.plugins.load-tester.proposal", "aes128-sha1-modp768",
934 lib->ns));
935 if (!this->proposal)
936 { /* fallback */
937 this->proposal = proposal_create_from_string(PROTO_IKE,
938 "aes128-sha1-modp768");
939 }
940 this->esp = proposal_create_from_string(PROTO_ESP,
941 lib->settings->get_str(lib->settings,
942 "%s.plugins.load-tester.esp", "aes128-sha1", lib->ns));
943 if (!this->esp)
944 { /* fallback */
945 this->esp = proposal_create_from_string(PROTO_ESP, "aes128-sha1");
946 }
947
948 this->ike_rekey = lib->settings->get_int(lib->settings,
949 "%s.plugins.load-tester.ike_rekey", 0, lib->ns);
950 this->child_rekey = lib->settings->get_int(lib->settings,
951 "%s.plugins.load-tester.child_rekey", 600, lib->ns);
952 this->dpd_delay = lib->settings->get_int(lib->settings,
953 "%s.plugins.load-tester.dpd_delay", 0, lib->ns);
954 this->dpd_timeout = lib->settings->get_int(lib->settings,
955 "%s.plugins.load-tester.dpd_timeout", 0, lib->ns);
956
957 this->initiator_auth = lib->settings->get_str(lib->settings,
958 "%s.plugins.load-tester.initiator_auth", "pubkey", lib->ns);
959 this->responder_auth = lib->settings->get_str(lib->settings,
960 "%s.plugins.load-tester.responder_auth", "pubkey", lib->ns);
961 this->initiator_id = lib->settings->get_str(lib->settings,
962 "%s.plugins.load-tester.initiator_id", NULL, lib->ns);
963 this->initiator_match = lib->settings->get_str(lib->settings,
964 "%s.plugins.load-tester.initiator_match", NULL, lib->ns);
965 this->responder_id = lib->settings->get_str(lib->settings,
966 "%s.plugins.load-tester.responder_id", NULL, lib->ns);
967
968 this->mode = lib->settings->get_str(lib->settings,
969 "%s.plugins.load-tester.mode", NULL, lib->ns);
970 this->initiator_tsi = lib->settings->get_str(lib->settings,
971 "%s.plugins.load-tester.initiator_tsi", NULL, lib->ns);
972 this->responder_tsi =lib->settings->get_str(lib->settings,
973 "%s.plugins.load-tester.responder_tsi",
974 this->initiator_tsi, lib->ns);
975 this->initiator_tsr = lib->settings->get_str(lib->settings,
976 "%s.plugins.load-tester.initiator_tsr", NULL, lib->ns);
977 this->responder_tsr =lib->settings->get_str(lib->settings,
978 "%s.plugins.load-tester.responder_tsr",
979 this->initiator_tsr, lib->ns);
980
981 this->port = lib->settings->get_int(lib->settings,
982 "%s.plugins.load-tester.dynamic_port", 0, lib->ns);
983 this->version = lib->settings->get_int(lib->settings,
984 "%s.plugins.load-tester.version", IKE_ANY, lib->ns);
985
986 load_addrs(this);
987
988 this->peer_cfg = generate_config(this, 0);
989
990 return &this->public;
991 }