Annotation of embedaddon/strongswan/src/libcharon/config/peer_cfg.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2007-2019 Tobias Brunner
! 3: * Copyright (C) 2005-2009 Martin Willi
! 4: * Copyright (C) 2005 Jan Hutter
! 5: * HSR Hochschule fuer Technik Rapperswil
! 6: *
! 7: * This program is free software; you can redistribute it and/or modify it
! 8: * under the terms of the GNU General Public License as published by the
! 9: * Free Software Foundation; either version 2 of the License, or (at your
! 10: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
! 11: *
! 12: * This program is distributed in the hope that it will be useful, but
! 13: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! 14: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
! 15: * for more details.
! 16: */
! 17:
! 18: #include <string.h>
! 19:
! 20: #include "peer_cfg.h"
! 21:
! 22: #include <daemon.h>
! 23:
! 24: #include <threading/rwlock.h>
! 25: #include <collections/linked_list.h>
! 26: #include <utils/identification.h>
! 27:
! 28: ENUM(cert_policy_names, CERT_ALWAYS_SEND, CERT_NEVER_SEND,
! 29: "CERT_ALWAYS_SEND",
! 30: "CERT_SEND_IF_ASKED",
! 31: "CERT_NEVER_SEND",
! 32: );
! 33:
! 34: ENUM(unique_policy_names, UNIQUE_NEVER, UNIQUE_KEEP,
! 35: "UNIQUE_NEVER",
! 36: "UNIQUE_NO",
! 37: "UNIQUE_REPLACE",
! 38: "UNIQUE_KEEP",
! 39: );
! 40:
! 41: typedef struct private_peer_cfg_t private_peer_cfg_t;
! 42:
! 43: /**
! 44: * Private data of an peer_cfg_t object
! 45: */
! 46: struct private_peer_cfg_t {
! 47:
! 48: /**
! 49: * Public part
! 50: */
! 51: peer_cfg_t public;
! 52:
! 53: /**
! 54: * Number of references hold by others to this peer_cfg
! 55: */
! 56: refcount_t refcount;
! 57:
! 58: /**
! 59: * Name of the peer_cfg, used to query it
! 60: */
! 61: char *name;
! 62:
! 63: /**
! 64: * IKE config associated to this peer config
! 65: */
! 66: ike_cfg_t *ike_cfg;
! 67:
! 68: /**
! 69: * list of child configs associated to this peer config
! 70: */
! 71: linked_list_t *child_cfgs;
! 72:
! 73: /**
! 74: * lock to access list of child_cfgs
! 75: */
! 76: rwlock_t *lock;
! 77:
! 78: /**
! 79: * should we send a certificate
! 80: */
! 81: cert_policy_t cert_policy;
! 82:
! 83: /**
! 84: * uniqueness of an IKE_SA
! 85: */
! 86: unique_policy_t unique;
! 87:
! 88: /**
! 89: * number of tries after giving up if peer does not respond
! 90: */
! 91: uint32_t keyingtries;
! 92:
! 93: /**
! 94: * enable support for MOBIKE
! 95: */
! 96: bool use_mobike;
! 97:
! 98: /**
! 99: * Use aggressive mode?
! 100: */
! 101: bool aggressive;
! 102:
! 103: /**
! 104: * Use pull or push in mode config?
! 105: */
! 106: bool pull_mode;
! 107:
! 108: /**
! 109: * Time before starting rekeying
! 110: */
! 111: uint32_t rekey_time;
! 112:
! 113: /**
! 114: * Time before starting reauthentication
! 115: */
! 116: uint32_t reauth_time;
! 117:
! 118: /**
! 119: * Time, which specifies the range of a random value subtracted from above.
! 120: */
! 121: uint32_t jitter_time;
! 122:
! 123: /**
! 124: * Delay before deleting a rekeying/reauthenticating SA
! 125: */
! 126: uint32_t over_time;
! 127:
! 128: /**
! 129: * DPD check interval
! 130: */
! 131: uint32_t dpd;
! 132:
! 133: /**
! 134: * DPD timeout interval (used for IKEv1 only)
! 135: */
! 136: uint32_t dpd_timeout;
! 137:
! 138: /**
! 139: * List of virtual IPs (host_t*) to request
! 140: */
! 141: linked_list_t *vips;
! 142:
! 143: /**
! 144: * List of pool names to use for virtual IP lookup
! 145: */
! 146: linked_list_t *pools;
! 147:
! 148: /**
! 149: * local authentication configs (rulesets)
! 150: */
! 151: linked_list_t *local_auth;
! 152:
! 153: /**
! 154: * remote authentication configs (constraints)
! 155: */
! 156: linked_list_t *remote_auth;
! 157:
! 158: /**
! 159: * Optional interface ID to use for inbound CHILD_SA
! 160: */
! 161: uint32_t if_id_in;
! 162:
! 163: /**
! 164: * Optional interface ID to use for outbound CHILD_SA
! 165: */
! 166: uint32_t if_id_out;
! 167:
! 168: /**
! 169: * PPK ID
! 170: */
! 171: identification_t *ppk_id;
! 172:
! 173: /**
! 174: * Whether a PPK is required
! 175: */
! 176: bool ppk_required;
! 177:
! 178: #ifdef ME
! 179: /**
! 180: * Is this a mediation connection?
! 181: */
! 182: bool mediation;
! 183:
! 184: /**
! 185: * Name of the mediation connection to mediate through
! 186: */
! 187: char *mediated_by;
! 188:
! 189: /**
! 190: * ID of our peer at the mediation server (= leftid of the peer's conn with
! 191: * the mediation server)
! 192: */
! 193: identification_t *peer_id;
! 194: #endif /* ME */
! 195: };
! 196:
! 197: METHOD(peer_cfg_t, get_name, char*,
! 198: private_peer_cfg_t *this)
! 199: {
! 200: return this->name;
! 201: }
! 202:
! 203: METHOD(peer_cfg_t, get_ike_version, ike_version_t,
! 204: private_peer_cfg_t *this)
! 205: {
! 206: return this->ike_cfg->get_version(this->ike_cfg);
! 207: }
! 208:
! 209: METHOD(peer_cfg_t, get_ike_cfg, ike_cfg_t*,
! 210: private_peer_cfg_t *this)
! 211: {
! 212: return this->ike_cfg;
! 213: }
! 214:
! 215: METHOD(peer_cfg_t, add_child_cfg, void,
! 216: private_peer_cfg_t *this, child_cfg_t *child_cfg)
! 217: {
! 218: this->lock->write_lock(this->lock);
! 219: this->child_cfgs->insert_last(this->child_cfgs, child_cfg);
! 220: this->lock->unlock(this->lock);
! 221: }
! 222:
! 223: typedef struct {
! 224: enumerator_t public;
! 225: linked_list_t *removed;
! 226: linked_list_t *added;
! 227: enumerator_t *wrapped;
! 228: bool add;
! 229: } child_cfgs_replace_enumerator_t;
! 230:
! 231: METHOD(enumerator_t, child_cfgs_replace_enumerate, bool,
! 232: child_cfgs_replace_enumerator_t *this, va_list args)
! 233: {
! 234: child_cfg_t *child_cfg, **chd;
! 235: bool *added;
! 236:
! 237: VA_ARGS_VGET(args, chd, added);
! 238:
! 239: if (!this->wrapped)
! 240: {
! 241: this->wrapped = this->removed->create_enumerator(this->removed);
! 242: }
! 243: while (TRUE)
! 244: {
! 245: if (this->wrapped->enumerate(this->wrapped, &child_cfg))
! 246: {
! 247: if (chd)
! 248: {
! 249: *chd = child_cfg;
! 250: }
! 251: if (added)
! 252: {
! 253: *added = this->add;
! 254: }
! 255: return TRUE;
! 256: }
! 257: if (this->add)
! 258: {
! 259: break;
! 260: }
! 261: this->wrapped->destroy(this->wrapped);
! 262: this->wrapped = this->added->create_enumerator(this->added);
! 263: this->add = TRUE;
! 264: }
! 265: return FALSE;
! 266: }
! 267:
! 268: METHOD(enumerator_t, child_cfgs_replace_enumerator_destroy, void,
! 269: child_cfgs_replace_enumerator_t *this)
! 270: {
! 271: DESTROY_IF(this->wrapped);
! 272: this->removed->destroy_offset(this->removed, offsetof(child_cfg_t, destroy));
! 273: this->added->destroy_offset(this->added, offsetof(child_cfg_t, destroy));
! 274: free(this);
! 275: }
! 276:
! 277: METHOD(peer_cfg_t, replace_child_cfgs, enumerator_t*,
! 278: private_peer_cfg_t *this, peer_cfg_t *other_pub)
! 279: {
! 280: private_peer_cfg_t *other = (private_peer_cfg_t*)other_pub;
! 281: linked_list_t *new_cfgs, *removed, *added;
! 282: enumerator_t *mine, *others;
! 283: child_cfg_t *my_cfg, *other_cfg;
! 284: child_cfgs_replace_enumerator_t *enumerator;
! 285: bool found;
! 286:
! 287: added = linked_list_create();
! 288:
! 289: other->lock->read_lock(other->lock);
! 290: new_cfgs = linked_list_create_from_enumerator(
! 291: other->child_cfgs->create_enumerator(other->child_cfgs));
! 292: new_cfgs->invoke_offset(new_cfgs, offsetof(child_cfg_t, get_ref));
! 293: other->lock->unlock(other->lock);
! 294:
! 295: this->lock->write_lock(this->lock);
! 296: removed = this->child_cfgs;
! 297: this->child_cfgs = new_cfgs;
! 298: others = new_cfgs->create_enumerator(new_cfgs);
! 299: mine = removed->create_enumerator(removed);
! 300: while (others->enumerate(others, &other_cfg))
! 301: {
! 302: found = FALSE;
! 303: while (mine->enumerate(mine, &my_cfg))
! 304: {
! 305: if (my_cfg->equals(my_cfg, other_cfg))
! 306: {
! 307: removed->remove_at(removed, mine);
! 308: my_cfg->destroy(my_cfg);
! 309: found = TRUE;
! 310: break;
! 311: }
! 312: }
! 313: removed->reset_enumerator(removed, mine);
! 314: if (!found)
! 315: {
! 316: added->insert_last(added, other_cfg->get_ref(other_cfg));
! 317: }
! 318: }
! 319: others->destroy(others);
! 320: mine->destroy(mine);
! 321: this->lock->unlock(this->lock);
! 322:
! 323: INIT(enumerator,
! 324: .public = {
! 325: .enumerate = enumerator_enumerate_default,
! 326: .venumerate = _child_cfgs_replace_enumerate,
! 327: .destroy = _child_cfgs_replace_enumerator_destroy,
! 328: },
! 329: .removed = removed,
! 330: .added = added,
! 331: );
! 332: return &enumerator->public;
! 333: }
! 334:
! 335: /**
! 336: * child_cfg enumerator
! 337: */
! 338: typedef struct {
! 339: enumerator_t public;
! 340: enumerator_t *wrapped;
! 341: rwlock_t *lock;
! 342: } child_cfg_enumerator_t;
! 343:
! 344: METHOD(peer_cfg_t, remove_child_cfg, void,
! 345: private_peer_cfg_t *this, child_cfg_enumerator_t *enumerator)
! 346: {
! 347: this->child_cfgs->remove_at(this->child_cfgs, enumerator->wrapped);
! 348: }
! 349:
! 350: METHOD(enumerator_t, child_cfg_enumerator_destroy, void,
! 351: child_cfg_enumerator_t *this)
! 352: {
! 353: this->lock->unlock(this->lock);
! 354: this->wrapped->destroy(this->wrapped);
! 355: free(this);
! 356: }
! 357:
! 358: METHOD(enumerator_t, child_cfg_enumerate, bool,
! 359: child_cfg_enumerator_t *this, va_list args)
! 360: {
! 361: child_cfg_t **chd;
! 362:
! 363: VA_ARGS_VGET(args, chd);
! 364: return this->wrapped->enumerate(this->wrapped, chd);
! 365: }
! 366:
! 367: METHOD(peer_cfg_t, create_child_cfg_enumerator, enumerator_t*,
! 368: private_peer_cfg_t *this)
! 369: {
! 370: child_cfg_enumerator_t *enumerator;
! 371:
! 372: INIT(enumerator,
! 373: .public = {
! 374: .enumerate = enumerator_enumerate_default,
! 375: .venumerate = _child_cfg_enumerate,
! 376: .destroy = _child_cfg_enumerator_destroy,
! 377: },
! 378: .lock = this->lock,
! 379: .wrapped = this->child_cfgs->create_enumerator(this->child_cfgs),
! 380: );
! 381:
! 382: this->lock->read_lock(this->lock);
! 383: return &enumerator->public;
! 384: }
! 385:
! 386: /**
! 387: * Check how good a list of TS matches a given child config
! 388: */
! 389: static int get_ts_match(child_cfg_t *cfg, bool local,
! 390: linked_list_t *sup_list, linked_list_t *hosts)
! 391: {
! 392: linked_list_t *cfg_list;
! 393: enumerator_t *sup_enum, *cfg_enum;
! 394: traffic_selector_t *sup_ts, *cfg_ts, *subset;
! 395: int match = 0, round;
! 396:
! 397: /* fetch configured TS list, narrowing dynamic TS */
! 398: cfg_list = cfg->get_traffic_selectors(cfg, local, NULL, hosts, TRUE);
! 399:
! 400: /* use a round counter to rate leading TS with higher priority */
! 401: round = sup_list->get_count(sup_list);
! 402:
! 403: sup_enum = sup_list->create_enumerator(sup_list);
! 404: while (sup_enum->enumerate(sup_enum, &sup_ts))
! 405: {
! 406: cfg_enum = cfg_list->create_enumerator(cfg_list);
! 407: while (cfg_enum->enumerate(cfg_enum, &cfg_ts))
! 408: {
! 409: if (cfg_ts->equals(cfg_ts, sup_ts))
! 410: { /* equality is honored better than matches */
! 411: match += round * 5;
! 412: }
! 413: else
! 414: {
! 415: subset = cfg_ts->get_subset(cfg_ts, sup_ts);
! 416: if (subset)
! 417: {
! 418: subset->destroy(subset);
! 419: match += round * 1;
! 420: }
! 421: }
! 422: }
! 423: cfg_enum->destroy(cfg_enum);
! 424: round--;
! 425: }
! 426: sup_enum->destroy(sup_enum);
! 427:
! 428: cfg_list->destroy_offset(cfg_list, offsetof(traffic_selector_t, destroy));
! 429:
! 430: return match;
! 431: }
! 432:
! 433: METHOD(peer_cfg_t, select_child_cfg, child_cfg_t*,
! 434: private_peer_cfg_t *this, linked_list_t *my_ts, linked_list_t *other_ts,
! 435: linked_list_t *my_hosts, linked_list_t *other_hosts)
! 436: {
! 437: child_cfg_t *current, *found = NULL;
! 438: enumerator_t *enumerator;
! 439: int best = 0;
! 440:
! 441: DBG2(DBG_CFG, "looking for a child config for %#R === %#R", my_ts, other_ts);
! 442: enumerator = create_child_cfg_enumerator(this);
! 443: while (enumerator->enumerate(enumerator, ¤t))
! 444: {
! 445: int my_prio, other_prio;
! 446:
! 447: my_prio = get_ts_match(current, TRUE, my_ts, my_hosts);
! 448: other_prio = get_ts_match(current, FALSE, other_ts, other_hosts);
! 449:
! 450: if (my_prio && other_prio)
! 451: {
! 452: DBG2(DBG_CFG, " candidate \"%s\" with prio %d+%d",
! 453: current->get_name(current), my_prio, other_prio);
! 454: if (my_prio + other_prio > best)
! 455: {
! 456: best = my_prio + other_prio;
! 457: DESTROY_IF(found);
! 458: found = current->get_ref(current);
! 459: }
! 460: }
! 461: }
! 462: enumerator->destroy(enumerator);
! 463: if (found)
! 464: {
! 465: DBG2(DBG_CFG, "found matching child config \"%s\" with prio %d",
! 466: found->get_name(found), best);
! 467: }
! 468: return found;
! 469: }
! 470:
! 471: METHOD(peer_cfg_t, get_cert_policy, cert_policy_t,
! 472: private_peer_cfg_t *this)
! 473: {
! 474: return this->cert_policy;
! 475: }
! 476:
! 477: METHOD(peer_cfg_t, get_unique_policy, unique_policy_t,
! 478: private_peer_cfg_t *this)
! 479: {
! 480: return this->unique;
! 481: }
! 482:
! 483: METHOD(peer_cfg_t, get_keyingtries, uint32_t,
! 484: private_peer_cfg_t *this)
! 485: {
! 486: return this->keyingtries;
! 487: }
! 488:
! 489: METHOD(peer_cfg_t, get_rekey_time, uint32_t,
! 490: private_peer_cfg_t *this, bool jitter)
! 491: {
! 492: if (this->rekey_time == 0)
! 493: {
! 494: return 0;
! 495: }
! 496: if (this->jitter_time == 0 || !jitter)
! 497: {
! 498: return this->rekey_time;
! 499: }
! 500: return this->rekey_time - (random() % this->jitter_time);
! 501: }
! 502:
! 503: METHOD(peer_cfg_t, get_reauth_time, uint32_t,
! 504: private_peer_cfg_t *this, bool jitter)
! 505: {
! 506: if (this->reauth_time == 0)
! 507: {
! 508: return 0;
! 509: }
! 510: if (this->jitter_time == 0 || !jitter)
! 511: {
! 512: return this->reauth_time;
! 513: }
! 514: return this->reauth_time - (random() % this->jitter_time);
! 515: }
! 516:
! 517: METHOD(peer_cfg_t, get_over_time, uint32_t,
! 518: private_peer_cfg_t *this)
! 519: {
! 520: return this->over_time;
! 521: }
! 522:
! 523: METHOD(peer_cfg_t, use_mobike, bool,
! 524: private_peer_cfg_t *this)
! 525: {
! 526: return this->use_mobike;
! 527: }
! 528:
! 529: METHOD(peer_cfg_t, use_aggressive, bool,
! 530: private_peer_cfg_t *this)
! 531: {
! 532: return this->aggressive;
! 533: }
! 534:
! 535: METHOD(peer_cfg_t, use_pull_mode, bool,
! 536: private_peer_cfg_t *this)
! 537: {
! 538: return this->pull_mode;
! 539: }
! 540:
! 541: METHOD(peer_cfg_t, get_dpd, uint32_t,
! 542: private_peer_cfg_t *this)
! 543: {
! 544: return this->dpd;
! 545: }
! 546:
! 547: METHOD(peer_cfg_t, get_dpd_timeout, uint32_t,
! 548: private_peer_cfg_t *this)
! 549: {
! 550: return this->dpd_timeout;
! 551: }
! 552:
! 553: METHOD(peer_cfg_t, add_virtual_ip, void,
! 554: private_peer_cfg_t *this, host_t *vip)
! 555: {
! 556: this->vips->insert_last(this->vips, vip);
! 557: }
! 558:
! 559: METHOD(peer_cfg_t, create_virtual_ip_enumerator, enumerator_t*,
! 560: private_peer_cfg_t *this)
! 561: {
! 562: return this->vips->create_enumerator(this->vips);
! 563: }
! 564:
! 565: METHOD(peer_cfg_t, add_pool, void,
! 566: private_peer_cfg_t *this, char *name)
! 567: {
! 568: this->pools->insert_last(this->pools, strdup(name));
! 569: }
! 570:
! 571: METHOD(peer_cfg_t, create_pool_enumerator, enumerator_t*,
! 572: private_peer_cfg_t *this)
! 573: {
! 574: return this->pools->create_enumerator(this->pools);
! 575: }
! 576:
! 577: METHOD(peer_cfg_t, add_auth_cfg, void,
! 578: private_peer_cfg_t *this, auth_cfg_t *cfg, bool local)
! 579: {
! 580: if (local)
! 581: {
! 582: this->local_auth->insert_last(this->local_auth, cfg);
! 583: }
! 584: else
! 585: {
! 586: this->remote_auth->insert_last(this->remote_auth, cfg);
! 587: }
! 588: }
! 589:
! 590: METHOD(peer_cfg_t, create_auth_cfg_enumerator, enumerator_t*,
! 591: private_peer_cfg_t *this, bool local)
! 592: {
! 593: if (local)
! 594: {
! 595: return this->local_auth->create_enumerator(this->local_auth);
! 596: }
! 597: return this->remote_auth->create_enumerator(this->remote_auth);
! 598: }
! 599:
! 600: METHOD(peer_cfg_t, get_if_id, uint32_t,
! 601: private_peer_cfg_t *this, bool inbound)
! 602: {
! 603: return inbound ? this->if_id_in : this->if_id_out;
! 604: }
! 605:
! 606: METHOD(peer_cfg_t, get_ppk_id, identification_t*,
! 607: private_peer_cfg_t *this)
! 608: {
! 609: return this->ppk_id;
! 610: }
! 611:
! 612: METHOD(peer_cfg_t, ppk_required, bool,
! 613: private_peer_cfg_t *this)
! 614: {
! 615: return this->ppk_required;
! 616: }
! 617:
! 618: #ifdef ME
! 619: METHOD(peer_cfg_t, is_mediation, bool,
! 620: private_peer_cfg_t *this)
! 621: {
! 622: return this->mediation;
! 623: }
! 624:
! 625: METHOD(peer_cfg_t, get_mediated_by, char*,
! 626: private_peer_cfg_t *this)
! 627: {
! 628: return this->mediated_by;
! 629: }
! 630:
! 631: METHOD(peer_cfg_t, get_peer_id, identification_t*,
! 632: private_peer_cfg_t *this)
! 633: {
! 634: return this->peer_id;
! 635: }
! 636: #endif /* ME */
! 637:
! 638: /**
! 639: * check auth configs for equality
! 640: */
! 641: static bool auth_cfg_equal(private_peer_cfg_t *this, private_peer_cfg_t *other)
! 642: {
! 643: enumerator_t *e1, *e2;
! 644: auth_cfg_t *cfg1, *cfg2;
! 645: bool equal = TRUE;
! 646:
! 647: if (this->local_auth->get_count(this->local_auth) !=
! 648: other->local_auth->get_count(other->local_auth))
! 649: {
! 650: return FALSE;
! 651: }
! 652: if (this->remote_auth->get_count(this->remote_auth) !=
! 653: other->remote_auth->get_count(other->remote_auth))
! 654: {
! 655: return FALSE;
! 656: }
! 657:
! 658: e1 = this->local_auth->create_enumerator(this->local_auth);
! 659: e2 = other->local_auth->create_enumerator(other->local_auth);
! 660: while (e1->enumerate(e1, &cfg1) && e2->enumerate(e2, &cfg2))
! 661: {
! 662: if (!cfg1->equals(cfg1, cfg2))
! 663: {
! 664: equal = FALSE;
! 665: break;
! 666: }
! 667: }
! 668: e1->destroy(e1);
! 669: e2->destroy(e2);
! 670:
! 671: if (!equal)
! 672: {
! 673: return FALSE;
! 674: }
! 675:
! 676: e1 = this->remote_auth->create_enumerator(this->remote_auth);
! 677: e2 = other->remote_auth->create_enumerator(other->remote_auth);
! 678: while (e1->enumerate(e1, &cfg1) && e2->enumerate(e2, &cfg2))
! 679: {
! 680: if (!cfg1->equals(cfg1, cfg2))
! 681: {
! 682: equal = FALSE;
! 683: break;
! 684: }
! 685: }
! 686: e1->destroy(e1);
! 687: e2->destroy(e2);
! 688:
! 689: return equal;
! 690: }
! 691:
! 692: /**
! 693: * Check if two identities are equal, or both are not set
! 694: */
! 695: static bool id_equal(identification_t *this, identification_t *other)
! 696: {
! 697: return this == other || (this && other && this->equals(this, other));
! 698: }
! 699:
! 700: METHOD(peer_cfg_t, equals, bool,
! 701: private_peer_cfg_t *this, private_peer_cfg_t *other)
! 702: {
! 703: if (this == other)
! 704: {
! 705: return TRUE;
! 706: }
! 707: if (this->public.equals != other->public.equals)
! 708: {
! 709: return FALSE;
! 710: }
! 711: if (!this->vips->equals_offset(this->vips, other->vips,
! 712: offsetof(host_t, ip_equals)))
! 713: {
! 714: return FALSE;
! 715: }
! 716: if (!this->pools->equals_function(this->pools, other->pools, (void*)streq))
! 717: {
! 718: return FALSE;
! 719: }
! 720: return (
! 721: get_ike_version(this) == get_ike_version(other) &&
! 722: this->cert_policy == other->cert_policy &&
! 723: this->unique == other->unique &&
! 724: this->keyingtries == other->keyingtries &&
! 725: this->use_mobike == other->use_mobike &&
! 726: this->rekey_time == other->rekey_time &&
! 727: this->reauth_time == other->reauth_time &&
! 728: this->jitter_time == other->jitter_time &&
! 729: this->over_time == other->over_time &&
! 730: this->dpd == other->dpd &&
! 731: this->aggressive == other->aggressive &&
! 732: this->pull_mode == other->pull_mode &&
! 733: auth_cfg_equal(this, other) &&
! 734: this->if_id_in == other->if_id_in &&
! 735: this->if_id_out == other->if_id_out &&
! 736: this->ppk_required == other->ppk_required &&
! 737: id_equal(this->ppk_id, other->ppk_id)
! 738: #ifdef ME
! 739: && this->mediation == other->mediation &&
! 740: streq(this->mediated_by, other->mediated_by) &&
! 741: id_equal(this->peer_id, other->peer_id)
! 742: #endif /* ME */
! 743: );
! 744: }
! 745:
! 746: METHOD(peer_cfg_t, get_ref, peer_cfg_t*,
! 747: private_peer_cfg_t *this)
! 748: {
! 749: ref_get(&this->refcount);
! 750: return &this->public;
! 751: }
! 752:
! 753: METHOD(peer_cfg_t, destroy, void,
! 754: private_peer_cfg_t *this)
! 755: {
! 756: if (ref_put(&this->refcount))
! 757: {
! 758: this->ike_cfg->destroy(this->ike_cfg);
! 759: this->child_cfgs->destroy_offset(this->child_cfgs,
! 760: offsetof(child_cfg_t, destroy));
! 761: this->local_auth->destroy_offset(this->local_auth,
! 762: offsetof(auth_cfg_t, destroy));
! 763: this->remote_auth->destroy_offset(this->remote_auth,
! 764: offsetof(auth_cfg_t, destroy));
! 765: this->vips->destroy_offset(this->vips, offsetof(host_t, destroy));
! 766: this->pools->destroy_function(this->pools, free);
! 767: #ifdef ME
! 768: DESTROY_IF(this->peer_id);
! 769: free(this->mediated_by);
! 770: #endif /* ME */
! 771: DESTROY_IF(this->ppk_id);
! 772: this->lock->destroy(this->lock);
! 773: free(this->name);
! 774: free(this);
! 775: }
! 776: }
! 777:
! 778: /*
! 779: * Described in header-file
! 780: */
! 781: peer_cfg_t *peer_cfg_create(char *name, ike_cfg_t *ike_cfg,
! 782: peer_cfg_create_t *data)
! 783: {
! 784: private_peer_cfg_t *this;
! 785:
! 786: if (data->rekey_time && data->jitter_time > data->rekey_time)
! 787: {
! 788: data->jitter_time = data->rekey_time;
! 789: }
! 790: if (data->reauth_time && data->jitter_time > data->reauth_time)
! 791: {
! 792: data->jitter_time = data->reauth_time;
! 793: }
! 794: if (data->dpd && data->dpd_timeout && data->dpd > data->dpd_timeout)
! 795: {
! 796: data->dpd_timeout = data->dpd;
! 797: }
! 798:
! 799: INIT(this,
! 800: .public = {
! 801: .get_name = _get_name,
! 802: .get_ike_version = _get_ike_version,
! 803: .get_ike_cfg = _get_ike_cfg,
! 804: .add_child_cfg = _add_child_cfg,
! 805: .remove_child_cfg = (void*)_remove_child_cfg,
! 806: .replace_child_cfgs = _replace_child_cfgs,
! 807: .create_child_cfg_enumerator = _create_child_cfg_enumerator,
! 808: .select_child_cfg = _select_child_cfg,
! 809: .get_cert_policy = _get_cert_policy,
! 810: .get_unique_policy = _get_unique_policy,
! 811: .get_keyingtries = _get_keyingtries,
! 812: .get_rekey_time = _get_rekey_time,
! 813: .get_reauth_time = _get_reauth_time,
! 814: .get_over_time = _get_over_time,
! 815: .use_mobike = _use_mobike,
! 816: .use_aggressive = _use_aggressive,
! 817: .use_pull_mode = _use_pull_mode,
! 818: .get_dpd = _get_dpd,
! 819: .get_dpd_timeout = _get_dpd_timeout,
! 820: .add_virtual_ip = _add_virtual_ip,
! 821: .create_virtual_ip_enumerator = _create_virtual_ip_enumerator,
! 822: .add_pool = _add_pool,
! 823: .create_pool_enumerator = _create_pool_enumerator,
! 824: .add_auth_cfg = _add_auth_cfg,
! 825: .create_auth_cfg_enumerator = _create_auth_cfg_enumerator,
! 826: .get_if_id = _get_if_id,
! 827: .get_ppk_id = _get_ppk_id,
! 828: .ppk_required = _ppk_required,
! 829: .equals = (void*)_equals,
! 830: .get_ref = _get_ref,
! 831: .destroy = _destroy,
! 832: #ifdef ME
! 833: .is_mediation = _is_mediation,
! 834: .get_mediated_by = _get_mediated_by,
! 835: .get_peer_id = _get_peer_id,
! 836: #endif /* ME */
! 837: },
! 838: .name = strdup(name),
! 839: .ike_cfg = ike_cfg,
! 840: .child_cfgs = linked_list_create(),
! 841: .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
! 842: .cert_policy = data->cert_policy,
! 843: .unique = data->unique,
! 844: .keyingtries = data->keyingtries,
! 845: .rekey_time = data->rekey_time,
! 846: .reauth_time = data->reauth_time,
! 847: .jitter_time = data->jitter_time,
! 848: .over_time = data->over_time,
! 849: .use_mobike = !data->no_mobike,
! 850: .aggressive = data->aggressive,
! 851: .pull_mode = !data->push_mode,
! 852: .dpd = data->dpd,
! 853: .dpd_timeout = data->dpd_timeout,
! 854: .if_id_in = data->if_id_in,
! 855: .if_id_out = data->if_id_out,
! 856: .ppk_id = data->ppk_id,
! 857: .ppk_required = data->ppk_required,
! 858: .vips = linked_list_create(),
! 859: .pools = linked_list_create(),
! 860: .local_auth = linked_list_create(),
! 861: .remote_auth = linked_list_create(),
! 862: .refcount = 1,
! 863: #ifdef ME
! 864: .mediation = data->mediation,
! 865: .mediated_by = strdupnull(data->mediated_by),
! 866: .peer_id = data->peer_id,
! 867: #endif /* ME */
! 868: );
! 869:
! 870: return &this->public;
! 871: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>