]> git.ipfire.org Git - thirdparty/strongswan.git/blob - src/libcharon/config/peer_cfg.c
4eebfb09d16ab0ceb9d79ee5ef42bd9514769978
[thirdparty/strongswan.git] / src / libcharon / config / peer_cfg.c
1 /*
2 * Copyright (C) 2007-2015 Tobias Brunner
3 * Copyright (C) 2005-2009 Martin Willi
4 * Copyright (C) 2005 Jan Hutter
5 * 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/mutex.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 * mutex to lock access to list of child_cfgs
75 */
76 mutex_t *mutex;
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 intervall
130 */
131 uint32_t dpd;
132
133 /**
134 * DPD timeout intervall (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 #ifdef ME
159 /**
160 * Is this a mediation connection?
161 */
162 bool mediation;
163
164 /**
165 * Name of the mediation connection to mediate through
166 */
167 peer_cfg_t *mediated_by;
168
169 /**
170 * ID of our peer at the mediation server (= leftid of the peer's conn with
171 * the mediation server)
172 */
173 identification_t *peer_id;
174 #endif /* ME */
175 };
176
177 METHOD(peer_cfg_t, get_name, char*,
178 private_peer_cfg_t *this)
179 {
180 return this->name;
181 }
182
183 METHOD(peer_cfg_t, get_ike_version, ike_version_t,
184 private_peer_cfg_t *this)
185 {
186 return this->ike_cfg->get_version(this->ike_cfg);
187 }
188
189 METHOD(peer_cfg_t, get_ike_cfg, ike_cfg_t*,
190 private_peer_cfg_t *this)
191 {
192 return this->ike_cfg;
193 }
194
195 METHOD(peer_cfg_t, add_child_cfg, void,
196 private_peer_cfg_t *this, child_cfg_t *child_cfg)
197 {
198 this->mutex->lock(this->mutex);
199 this->child_cfgs->insert_last(this->child_cfgs, child_cfg);
200 this->mutex->unlock(this->mutex);
201 }
202
203 typedef struct {
204 enumerator_t public;
205 linked_list_t *removed;
206 linked_list_t *added;
207 enumerator_t *wrapped;
208 bool add;
209 } child_cfgs_replace_enumerator_t;
210
211 METHOD(enumerator_t, child_cfgs_replace_enumerate, bool,
212 child_cfgs_replace_enumerator_t *this, child_cfg_t **chd, bool *added)
213 {
214 child_cfg_t *child_cfg;
215
216 if (!this->wrapped)
217 {
218 this->wrapped = this->removed->create_enumerator(this->removed);
219 }
220 while (TRUE)
221 {
222 if (this->wrapped->enumerate(this->wrapped, &child_cfg))
223 {
224 if (chd)
225 {
226 *chd = child_cfg;
227 }
228 if (added)
229 {
230 *added = this->add;
231 }
232 return TRUE;
233 }
234 if (this->add)
235 {
236 break;
237 }
238 this->wrapped = this->added->create_enumerator(this->added);
239 this->add = TRUE;
240 }
241 return FALSE;
242 }
243
244 METHOD(enumerator_t, child_cfgs_replace_enumerator_destroy, void,
245 child_cfgs_replace_enumerator_t *this)
246 {
247 DESTROY_IF(this->wrapped);
248 this->removed->destroy_offset(this->removed, offsetof(child_cfg_t, destroy));
249 this->added->destroy_offset(this->added, offsetof(child_cfg_t, destroy));
250 free(this);
251 }
252
253 METHOD(peer_cfg_t, replace_child_cfgs, enumerator_t*,
254 private_peer_cfg_t *this, peer_cfg_t *other_pub)
255 {
256 private_peer_cfg_t *other = (private_peer_cfg_t*)other_pub;
257 linked_list_t *removed, *added;
258 enumerator_t *mine, *others;
259 child_cfg_t *my_cfg, *other_cfg;
260 child_cfgs_replace_enumerator_t *enumerator;
261 bool found;
262
263 removed = linked_list_create();
264
265 other->mutex->lock(other->mutex);
266 added = linked_list_create_from_enumerator(
267 other->child_cfgs->create_enumerator(other->child_cfgs));
268 added->invoke_offset(added, offsetof(child_cfg_t, get_ref));
269 other->mutex->unlock(other->mutex);
270
271 this->mutex->lock(this->mutex);
272 others = added->create_enumerator(added);
273 mine = this->child_cfgs->create_enumerator(this->child_cfgs);
274 while (mine->enumerate(mine, &my_cfg))
275 {
276 found = FALSE;
277 while (others->enumerate(others, &other_cfg))
278 {
279 if (my_cfg->equals(my_cfg, other_cfg))
280 {
281 added->remove_at(added, others);
282 other_cfg->destroy(other_cfg);
283 found = TRUE;
284 break;
285 }
286 }
287 added->reset_enumerator(added, others);
288 if (!found)
289 {
290 this->child_cfgs->remove_at(this->child_cfgs, mine);
291 removed->insert_last(removed, my_cfg);
292 }
293 }
294 while (others->enumerate(others, &other_cfg))
295 {
296 this->child_cfgs->insert_last(this->child_cfgs,
297 other_cfg->get_ref(other_cfg));
298 }
299 others->destroy(others);
300 mine->destroy(mine);
301 this->mutex->unlock(this->mutex);
302
303 INIT(enumerator,
304 .public = {
305 .enumerate = (void*)_child_cfgs_replace_enumerate,
306 .destroy = (void*)_child_cfgs_replace_enumerator_destroy,
307 },
308 .removed = removed,
309 .added = added,
310 );
311 return &enumerator->public;
312 }
313
314 /**
315 * child_cfg enumerator
316 */
317 typedef struct {
318 enumerator_t public;
319 enumerator_t *wrapped;
320 mutex_t *mutex;
321 } child_cfg_enumerator_t;
322
323 METHOD(peer_cfg_t, remove_child_cfg, void,
324 private_peer_cfg_t *this, child_cfg_enumerator_t *enumerator)
325 {
326 this->child_cfgs->remove_at(this->child_cfgs, enumerator->wrapped);
327 }
328
329 METHOD(enumerator_t, child_cfg_enumerator_destroy, void,
330 child_cfg_enumerator_t *this)
331 {
332 this->mutex->unlock(this->mutex);
333 this->wrapped->destroy(this->wrapped);
334 free(this);
335 }
336
337 METHOD(enumerator_t, child_cfg_enumerate, bool,
338 child_cfg_enumerator_t *this, child_cfg_t **chd)
339 {
340 return this->wrapped->enumerate(this->wrapped, chd);
341 }
342
343 METHOD(peer_cfg_t, create_child_cfg_enumerator, enumerator_t*,
344 private_peer_cfg_t *this)
345 {
346 child_cfg_enumerator_t *enumerator;
347
348 INIT(enumerator,
349 .public = {
350 .enumerate = (void*)_child_cfg_enumerate,
351 .destroy = (void*)_child_cfg_enumerator_destroy,
352 },
353 .mutex = this->mutex,
354 .wrapped = this->child_cfgs->create_enumerator(this->child_cfgs),
355 );
356
357 this->mutex->lock(this->mutex);
358 return &enumerator->public;
359 }
360
361 /**
362 * Check how good a list of TS matches a given child config
363 */
364 static int get_ts_match(child_cfg_t *cfg, bool local,
365 linked_list_t *sup_list, linked_list_t *hosts)
366 {
367 linked_list_t *cfg_list;
368 enumerator_t *sup_enum, *cfg_enum;
369 traffic_selector_t *sup_ts, *cfg_ts, *subset;
370 int match = 0, round;
371
372 /* fetch configured TS list, narrowing dynamic TS */
373 cfg_list = cfg->get_traffic_selectors(cfg, local, NULL, hosts);
374
375 /* use a round counter to rate leading TS with higher priority */
376 round = sup_list->get_count(sup_list);
377
378 sup_enum = sup_list->create_enumerator(sup_list);
379 while (sup_enum->enumerate(sup_enum, &sup_ts))
380 {
381 cfg_enum = cfg_list->create_enumerator(cfg_list);
382 while (cfg_enum->enumerate(cfg_enum, &cfg_ts))
383 {
384 if (cfg_ts->equals(cfg_ts, sup_ts))
385 { /* equality is honored better than matches */
386 match += round * 5;
387 }
388 else
389 {
390 subset = cfg_ts->get_subset(cfg_ts, sup_ts);
391 if (subset)
392 {
393 subset->destroy(subset);
394 match += round * 1;
395 }
396 }
397 }
398 cfg_enum->destroy(cfg_enum);
399 round--;
400 }
401 sup_enum->destroy(sup_enum);
402
403 cfg_list->destroy_offset(cfg_list, offsetof(traffic_selector_t, destroy));
404
405 return match;
406 }
407
408 METHOD(peer_cfg_t, select_child_cfg, child_cfg_t*,
409 private_peer_cfg_t *this, linked_list_t *my_ts, linked_list_t *other_ts,
410 linked_list_t *my_hosts, linked_list_t *other_hosts)
411 {
412 child_cfg_t *current, *found = NULL;
413 enumerator_t *enumerator;
414 int best = 0;
415
416 DBG2(DBG_CFG, "looking for a child config for %#R === %#R", my_ts, other_ts);
417 enumerator = create_child_cfg_enumerator(this);
418 while (enumerator->enumerate(enumerator, &current))
419 {
420 int my_prio, other_prio;
421
422 my_prio = get_ts_match(current, TRUE, my_ts, my_hosts);
423 other_prio = get_ts_match(current, FALSE, other_ts, other_hosts);
424
425 if (my_prio && other_prio)
426 {
427 DBG2(DBG_CFG, " candidate \"%s\" with prio %d+%d",
428 current->get_name(current), my_prio, other_prio);
429 if (my_prio + other_prio > best)
430 {
431 best = my_prio + other_prio;
432 DESTROY_IF(found);
433 found = current->get_ref(current);
434 }
435 }
436 }
437 enumerator->destroy(enumerator);
438 if (found)
439 {
440 DBG2(DBG_CFG, "found matching child config \"%s\" with prio %d",
441 found->get_name(found), best);
442 }
443 return found;
444 }
445
446 METHOD(peer_cfg_t, get_cert_policy, cert_policy_t,
447 private_peer_cfg_t *this)
448 {
449 return this->cert_policy;
450 }
451
452 METHOD(peer_cfg_t, get_unique_policy, unique_policy_t,
453 private_peer_cfg_t *this)
454 {
455 return this->unique;
456 }
457
458 METHOD(peer_cfg_t, get_keyingtries, uint32_t,
459 private_peer_cfg_t *this)
460 {
461 return this->keyingtries;
462 }
463
464 METHOD(peer_cfg_t, get_rekey_time, uint32_t,
465 private_peer_cfg_t *this, bool jitter)
466 {
467 if (this->rekey_time == 0)
468 {
469 return 0;
470 }
471 if (this->jitter_time == 0 || !jitter)
472 {
473 return this->rekey_time;
474 }
475 return this->rekey_time - (random() % this->jitter_time);
476 }
477
478 METHOD(peer_cfg_t, get_reauth_time, uint32_t,
479 private_peer_cfg_t *this, bool jitter)
480 {
481 if (this->reauth_time == 0)
482 {
483 return 0;
484 }
485 if (this->jitter_time == 0 || !jitter)
486 {
487 return this->reauth_time;
488 }
489 return this->reauth_time - (random() % this->jitter_time);
490 }
491
492 METHOD(peer_cfg_t, get_over_time, uint32_t,
493 private_peer_cfg_t *this)
494 {
495 return this->over_time;
496 }
497
498 METHOD(peer_cfg_t, use_mobike, bool,
499 private_peer_cfg_t *this)
500 {
501 return this->use_mobike;
502 }
503
504 METHOD(peer_cfg_t, use_aggressive, bool,
505 private_peer_cfg_t *this)
506 {
507 return this->aggressive;
508 }
509
510 METHOD(peer_cfg_t, use_pull_mode, bool,
511 private_peer_cfg_t *this)
512 {
513 return this->pull_mode;
514 }
515
516 METHOD(peer_cfg_t, get_dpd, uint32_t,
517 private_peer_cfg_t *this)
518 {
519 return this->dpd;
520 }
521
522 METHOD(peer_cfg_t, get_dpd_timeout, uint32_t,
523 private_peer_cfg_t *this)
524 {
525 return this->dpd_timeout;
526 }
527
528 METHOD(peer_cfg_t, add_virtual_ip, void,
529 private_peer_cfg_t *this, host_t *vip)
530 {
531 this->vips->insert_last(this->vips, vip);
532 }
533
534 METHOD(peer_cfg_t, create_virtual_ip_enumerator, enumerator_t*,
535 private_peer_cfg_t *this)
536 {
537 return this->vips->create_enumerator(this->vips);
538 }
539
540 METHOD(peer_cfg_t, add_pool, void,
541 private_peer_cfg_t *this, char *name)
542 {
543 this->pools->insert_last(this->pools, strdup(name));
544 }
545
546 METHOD(peer_cfg_t, create_pool_enumerator, enumerator_t*,
547 private_peer_cfg_t *this)
548 {
549 return this->pools->create_enumerator(this->pools);
550 }
551
552 METHOD(peer_cfg_t, add_auth_cfg, void,
553 private_peer_cfg_t *this, auth_cfg_t *cfg, bool local)
554 {
555 if (local)
556 {
557 this->local_auth->insert_last(this->local_auth, cfg);
558 }
559 else
560 {
561 this->remote_auth->insert_last(this->remote_auth, cfg);
562 }
563 }
564
565 METHOD(peer_cfg_t, create_auth_cfg_enumerator, enumerator_t*,
566 private_peer_cfg_t *this, bool local)
567 {
568 if (local)
569 {
570 return this->local_auth->create_enumerator(this->local_auth);
571 }
572 return this->remote_auth->create_enumerator(this->remote_auth);
573 }
574
575 #ifdef ME
576 METHOD(peer_cfg_t, is_mediation, bool,
577 private_peer_cfg_t *this)
578 {
579 return this->mediation;
580 }
581
582 METHOD(peer_cfg_t, get_mediated_by, peer_cfg_t*,
583 private_peer_cfg_t *this)
584 {
585 return this->mediated_by;
586 }
587
588 METHOD(peer_cfg_t, get_peer_id, identification_t*,
589 private_peer_cfg_t *this)
590 {
591 return this->peer_id;
592 }
593 #endif /* ME */
594
595 /**
596 * check auth configs for equality
597 */
598 static bool auth_cfg_equal(private_peer_cfg_t *this, private_peer_cfg_t *other)
599 {
600 enumerator_t *e1, *e2;
601 auth_cfg_t *cfg1, *cfg2;
602 bool equal = TRUE;
603
604 if (this->local_auth->get_count(this->local_auth) !=
605 other->local_auth->get_count(other->local_auth))
606 {
607 return FALSE;
608 }
609 if (this->remote_auth->get_count(this->remote_auth) !=
610 other->remote_auth->get_count(other->remote_auth))
611 {
612 return FALSE;
613 }
614
615 e1 = this->local_auth->create_enumerator(this->local_auth);
616 e2 = other->local_auth->create_enumerator(other->local_auth);
617 while (e1->enumerate(e1, &cfg1) && e2->enumerate(e2, &cfg2))
618 {
619 if (!cfg1->equals(cfg1, cfg2))
620 {
621 equal = FALSE;
622 break;
623 }
624 }
625 e1->destroy(e1);
626 e2->destroy(e2);
627
628 if (!equal)
629 {
630 return FALSE;
631 }
632
633 e1 = this->remote_auth->create_enumerator(this->remote_auth);
634 e2 = other->remote_auth->create_enumerator(other->remote_auth);
635 while (e1->enumerate(e1, &cfg1) && e2->enumerate(e2, &cfg2))
636 {
637 if (!cfg1->equals(cfg1, cfg2))
638 {
639 equal = FALSE;
640 break;
641 }
642 }
643 e1->destroy(e1);
644 e2->destroy(e2);
645
646 return equal;
647 }
648
649 METHOD(peer_cfg_t, equals, bool,
650 private_peer_cfg_t *this, private_peer_cfg_t *other)
651 {
652 if (this == other)
653 {
654 return TRUE;
655 }
656 if (this->public.equals != other->public.equals)
657 {
658 return FALSE;
659 }
660 if (!this->vips->equals_offset(this->vips, other->vips,
661 offsetof(host_t, ip_equals)))
662 {
663 return FALSE;
664 }
665 if (!this->pools->equals_function(this->pools, other->pools, (void*)streq))
666 {
667 return FALSE;
668 }
669 return (
670 get_ike_version(this) == get_ike_version(other) &&
671 this->cert_policy == other->cert_policy &&
672 this->unique == other->unique &&
673 this->keyingtries == other->keyingtries &&
674 this->use_mobike == other->use_mobike &&
675 this->rekey_time == other->rekey_time &&
676 this->reauth_time == other->reauth_time &&
677 this->jitter_time == other->jitter_time &&
678 this->over_time == other->over_time &&
679 this->dpd == other->dpd &&
680 this->aggressive == other->aggressive &&
681 this->pull_mode == other->pull_mode &&
682 auth_cfg_equal(this, other)
683 #ifdef ME
684 && this->mediation == other->mediation &&
685 this->mediated_by == other->mediated_by &&
686 (this->peer_id == other->peer_id ||
687 (this->peer_id && other->peer_id &&
688 this->peer_id->equals(this->peer_id, other->peer_id)))
689 #endif /* ME */
690 );
691 }
692
693 METHOD(peer_cfg_t, get_ref, peer_cfg_t*,
694 private_peer_cfg_t *this)
695 {
696 ref_get(&this->refcount);
697 return &this->public;
698 }
699
700 METHOD(peer_cfg_t, destroy, void,
701 private_peer_cfg_t *this)
702 {
703 if (ref_put(&this->refcount))
704 {
705 this->ike_cfg->destroy(this->ike_cfg);
706 this->child_cfgs->destroy_offset(this->child_cfgs,
707 offsetof(child_cfg_t, destroy));
708 this->local_auth->destroy_offset(this->local_auth,
709 offsetof(auth_cfg_t, destroy));
710 this->remote_auth->destroy_offset(this->remote_auth,
711 offsetof(auth_cfg_t, destroy));
712 this->vips->destroy_offset(this->vips, offsetof(host_t, destroy));
713 this->pools->destroy_function(this->pools, free);
714 #ifdef ME
715 DESTROY_IF(this->mediated_by);
716 DESTROY_IF(this->peer_id);
717 #endif /* ME */
718 this->mutex->destroy(this->mutex);
719 free(this->name);
720 free(this);
721 }
722 }
723
724 /*
725 * Described in header-file
726 */
727 peer_cfg_t *peer_cfg_create(char *name,
728 ike_cfg_t *ike_cfg, cert_policy_t cert_policy,
729 unique_policy_t unique, uint32_t keyingtries,
730 uint32_t rekey_time, uint32_t reauth_time,
731 uint32_t jitter_time, uint32_t over_time,
732 bool mobike, bool aggressive, bool pull_mode,
733 uint32_t dpd, uint32_t dpd_timeout,
734 bool mediation, peer_cfg_t *mediated_by,
735 identification_t *peer_id)
736 {
737 private_peer_cfg_t *this;
738
739 if (rekey_time && jitter_time > rekey_time)
740 {
741 jitter_time = rekey_time;
742 }
743 if (reauth_time && jitter_time > reauth_time)
744 {
745 jitter_time = reauth_time;
746 }
747 if (dpd && dpd_timeout && dpd > dpd_timeout)
748 {
749 dpd_timeout = dpd;
750 }
751
752 INIT(this,
753 .public = {
754 .get_name = _get_name,
755 .get_ike_version = _get_ike_version,
756 .get_ike_cfg = _get_ike_cfg,
757 .add_child_cfg = _add_child_cfg,
758 .remove_child_cfg = (void*)_remove_child_cfg,
759 .replace_child_cfgs = _replace_child_cfgs,
760 .create_child_cfg_enumerator = _create_child_cfg_enumerator,
761 .select_child_cfg = _select_child_cfg,
762 .get_cert_policy = _get_cert_policy,
763 .get_unique_policy = _get_unique_policy,
764 .get_keyingtries = _get_keyingtries,
765 .get_rekey_time = _get_rekey_time,
766 .get_reauth_time = _get_reauth_time,
767 .get_over_time = _get_over_time,
768 .use_mobike = _use_mobike,
769 .use_aggressive = _use_aggressive,
770 .use_pull_mode = _use_pull_mode,
771 .get_dpd = _get_dpd,
772 .get_dpd_timeout = _get_dpd_timeout,
773 .add_virtual_ip = _add_virtual_ip,
774 .create_virtual_ip_enumerator = _create_virtual_ip_enumerator,
775 .add_pool = _add_pool,
776 .create_pool_enumerator = _create_pool_enumerator,
777 .add_auth_cfg = _add_auth_cfg,
778 .create_auth_cfg_enumerator = _create_auth_cfg_enumerator,
779 .equals = (void*)_equals,
780 .get_ref = _get_ref,
781 .destroy = _destroy,
782 #ifdef ME
783 .is_mediation = _is_mediation,
784 .get_mediated_by = _get_mediated_by,
785 .get_peer_id = _get_peer_id,
786 #endif /* ME */
787 },
788 .name = strdup(name),
789 .ike_cfg = ike_cfg,
790 .child_cfgs = linked_list_create(),
791 .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
792 .cert_policy = cert_policy,
793 .unique = unique,
794 .keyingtries = keyingtries,
795 .rekey_time = rekey_time,
796 .reauth_time = reauth_time,
797 .jitter_time = jitter_time,
798 .over_time = over_time,
799 .use_mobike = mobike,
800 .aggressive = aggressive,
801 .pull_mode = pull_mode,
802 .dpd = dpd,
803 .dpd_timeout = dpd_timeout,
804 .vips = linked_list_create(),
805 .pools = linked_list_create(),
806 .local_auth = linked_list_create(),
807 .remote_auth = linked_list_create(),
808 .refcount = 1,
809 );
810
811 #ifdef ME
812 this->mediation = mediation;
813 this->mediated_by = mediated_by;
814 this->peer_id = peer_id;
815 #else /* ME */
816 DESTROY_IF(mediated_by);
817 DESTROY_IF(peer_id);
818 #endif /* ME */
819
820 return &this->public;
821 }