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