Use a dedicated IKEv1 vendor ID task to fix using IKEv2 payloads in IKEv1
[strongswan.git] / src / libcharon / sa / task_manager_v1.c
1 /*
2 * Copyright (C) 2007 Tobias Brunner
3 * Copyright (C) 2007-2010 Martin Willi
4 * Hochschule fuer Technik Rapperswil
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17 #include "task_manager_v1.h"
18
19 #include <math.h>
20
21 #include <daemon.h>
22 #include <sa/tasks/ike_vendor.h>
23 #include <sa/tasks/main_mode.h>
24 #include <sa/tasks/quick_mode.h>
25 #include <sa/tasks/xauth_request.h>
26 #include <sa/tasks/ike_vendor_v1.h>
27 #include <processing/jobs/retransmit_job.h>
28
29 typedef struct exchange_t exchange_t;
30
31 /**
32 * An exchange in the air, used do detect and handle retransmission
33 */
34 struct exchange_t {
35
36 /**
37 * Message ID used for this transaction
38 */
39 u_int32_t mid;
40
41 /**
42 * generated packet for retransmission
43 */
44 packet_t *packet;
45 };
46
47 typedef struct private_task_manager_t private_task_manager_t;
48
49 /**
50 * private data of the task manager
51 */
52 struct private_task_manager_t {
53
54 /**
55 * public functions
56 */
57 task_manager_v1_t public;
58
59 /**
60 * associated IKE_SA we are serving
61 */
62 ike_sa_t *ike_sa;
63
64 /**
65 * RNG to create message IDs
66 */
67 rng_t *rng;
68
69 /**
70 * Exchange we are currently handling as responder
71 */
72 struct {
73 /**
74 * Message ID of the exchange
75 */
76 u_int32_t mid;
77
78 /**
79 * Hash of a previously received message
80 */
81 u_int32_t hash;
82
83 /**
84 * packet for retransmission
85 */
86 packet_t *packet;
87
88 } responding;
89
90 /**
91 * Exchange we are currently handling as initiator
92 */
93 struct {
94 /**
95 * Message ID of the exchange
96 */
97 u_int32_t mid;
98
99 /**
100 * Hash of a previously received message
101 */
102 u_int32_t hash;
103
104 /**
105 * how many times we have retransmitted so far
106 */
107 u_int retransmitted;
108
109 /**
110 * packet for retransmission
111 */
112 packet_t *packet;
113
114 /**
115 * type of the initated exchange
116 */
117 exchange_type_t type;
118
119 } initiating;
120
121 /**
122 * List of queued tasks not yet in action
123 */
124 linked_list_t *queued_tasks;
125
126 /**
127 * List of active tasks, initiated by ourselve
128 */
129 linked_list_t *active_tasks;
130
131 /**
132 * List of tasks initiated by peer
133 */
134 linked_list_t *passive_tasks;
135
136 /**
137 * Number of times we retransmit messages before giving up
138 */
139 u_int retransmit_tries;
140
141 /**
142 * Retransmission timeout
143 */
144 double retransmit_timeout;
145
146 /**
147 * Base to calculate retransmission timeout
148 */
149 double retransmit_base;
150
151 /**
152 * Signal to the task manager that we need to initiate a transaction after the response is sent.
153 */
154 bool initiate_later_flag;
155 };
156
157 /**
158 * flush all tasks in the task manager
159 */
160 static void flush(private_task_manager_t *this)
161 {
162 this->queued_tasks->destroy_offset(this->queued_tasks,
163 offsetof(task_t, destroy));
164 this->queued_tasks = linked_list_create();
165 this->passive_tasks->destroy_offset(this->passive_tasks,
166 offsetof(task_t, destroy));
167 this->passive_tasks = linked_list_create();
168 this->active_tasks->destroy_offset(this->active_tasks,
169 offsetof(task_t, destroy));
170 this->active_tasks = linked_list_create();
171 }
172
173 /**
174 * move a task of a specific type from the queue to the active list
175 */
176 static bool activate_task(private_task_manager_t *this, task_type_t type)
177 {
178 enumerator_t *enumerator;
179 task_t *task;
180 bool found = FALSE;
181
182 enumerator = this->queued_tasks->create_enumerator(this->queued_tasks);
183 while (enumerator->enumerate(enumerator, (void**)&task))
184 {
185 if (task->get_type(task) == type)
186 {
187 DBG2(DBG_IKE, " activating %N task", task_type_names, type);
188 this->queued_tasks->remove_at(this->queued_tasks, enumerator);
189 this->active_tasks->insert_last(this->active_tasks, task);
190 found = TRUE;
191 break;
192 }
193 }
194 enumerator->destroy(enumerator);
195 return found;
196 }
197
198 METHOD(task_manager_t, retransmit, status_t,
199 private_task_manager_t *this, u_int32_t message_id)
200 {
201 if (message_id == this->initiating.mid)
202 {
203 u_int32_t timeout;
204 packet_t *packet;
205 job_t *job;
206
207 if (this->initiating.retransmitted <= this->retransmit_tries)
208 {
209 timeout = (u_int32_t)(this->retransmit_timeout * 1000.0 *
210 pow(this->retransmit_base, this->initiating.retransmitted));
211 }
212 else
213 {
214 DBG1(DBG_IKE, "giving up after %d retransmits",
215 this->initiating.retransmitted - 1);
216 if (this->ike_sa->get_state(this->ike_sa) != IKE_CONNECTING)
217 {
218 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
219 }
220 return DESTROY_ME;
221 }
222
223 if (this->initiating.retransmitted)
224 {
225 DBG1(DBG_IKE, "retransmit %d of request with message ID %d",
226 this->initiating.retransmitted, message_id);
227 }
228 packet = this->initiating.packet->clone(this->initiating.packet);
229 charon->sender->send(charon->sender, packet);
230
231 this->initiating.retransmitted++;
232 job = (job_t*)retransmit_job_create(this->initiating.mid,
233 this->ike_sa->get_id(this->ike_sa));
234 lib->scheduler->schedule_job_ms(lib->scheduler, job, timeout);
235 }
236 return SUCCESS;
237 }
238
239 void migrate_tasks(linked_list_t *from, linked_list_t *to)
240 {
241 enumerator_t *enumerator;
242 task_t *task;
243
244 enumerator = from->create_enumerator(from);
245 while(enumerator->enumerate(enumerator, (void**)&task))
246 {
247 DBG4(DBG_IKE, " Migrating %N task to new queue", task_type_names, task->get_type(task));
248 if(task->swap_initiator)
249 {
250 task->swap_initiator(task);
251 }
252 to->insert_last(to, task);
253 from->remove_at(from, enumerator);
254 }
255 enumerator->destroy(enumerator);
256 }
257
258 METHOD(task_manager_t, initiate, status_t,
259 private_task_manager_t *this)
260 {
261 enumerator_t *enumerator;
262 task_t *task;
263 message_t *message;
264 host_t *me, *other;
265 status_t status;
266 exchange_type_t exchange = EXCHANGE_TYPE_UNDEFINED;
267 bool new_mid = FALSE;
268
269 if (!this->rng)
270 {
271 DBG1(DBG_IKE, "no RNG supported");
272 return FAILED;
273 }
274
275 if (this->initiating.type != EXCHANGE_TYPE_UNDEFINED)
276 {
277 DBG2(DBG_IKE, "delaying task initiation, %N exchange in progress",
278 exchange_type_names, this->initiating.type);
279 /* do not initiate if we already have a message in the air */
280 return SUCCESS;
281 }
282
283 if (this->active_tasks->get_count(this->active_tasks) == 0)
284 {
285 DBG2(DBG_IKE, "activating new tasks");
286 switch (this->ike_sa->get_state(this->ike_sa))
287 {
288 case IKE_CREATED:
289 activate_task(this, TASK_VENDOR_V1);
290 if (activate_task(this, TASK_MAIN_MODE))
291 {
292 exchange = ID_PROT;
293 }
294 break;
295 case IKE_ESTABLISHED:
296 if (activate_task(this, TASK_QUICK_MODE))
297 {
298 exchange = QUICK_MODE;
299 new_mid = TRUE;
300 break;
301 }
302 if (activate_task(this, TASK_XAUTH_REQUEST))
303 {
304 exchange = TRANSACTION;
305 new_mid = TRUE;
306 break;
307 }
308 break;
309 default:
310 break;
311 }
312 }
313 else
314 {
315 DBG2(DBG_IKE, "reinitiating already active tasks");
316 enumerator = this->active_tasks->create_enumerator(this->active_tasks);
317 while (enumerator->enumerate(enumerator, (void**)&task))
318 {
319 DBG2(DBG_IKE, " %N task", task_type_names, task->get_type(task));
320 switch (task->get_type(task))
321 {
322 case TASK_MAIN_MODE:
323 exchange = ID_PROT;
324 break;
325 case TASK_QUICK_MODE:
326 exchange = QUICK_MODE;
327 break;
328 case TASK_XAUTH_REQUEST:
329 exchange = TRANSACTION;
330 new_mid = TRUE;
331 break;
332 default:
333 continue;
334 }
335 break;
336 }
337 enumerator->destroy(enumerator);
338 }
339
340 if (exchange == EXCHANGE_TYPE_UNDEFINED)
341 {
342 DBG2(DBG_IKE, "nothing to initiate");
343 /* nothing to do yet... */
344 return SUCCESS;
345 }
346
347 me = this->ike_sa->get_my_host(this->ike_sa);
348 other = this->ike_sa->get_other_host(this->ike_sa);
349
350 message = message_create(IKEV1_MAJOR_VERSION, IKEV1_MINOR_VERSION);
351 if (new_mid)
352 {
353 this->rng->get_bytes(this->rng, sizeof(this->initiating.mid),
354 (void*)&this->initiating.mid);
355 }
356 message->set_message_id(message, this->initiating.mid);
357 message->set_source(message, me->clone(me));
358 message->set_destination(message, other->clone(other));
359 message->set_exchange_type(message, exchange);
360 this->initiating.type = exchange;
361 this->initiating.retransmitted = 0;
362
363 enumerator = this->active_tasks->create_enumerator(this->active_tasks);
364 while (enumerator->enumerate(enumerator, (void*)&task))
365 {
366 switch (task->build(task, message))
367 {
368 case SUCCESS:
369 /* task completed, remove it */
370 this->active_tasks->remove_at(this->active_tasks, enumerator);
371 task->destroy(task);
372 break;
373 case MIGRATE:
374 /* task completed, remove it */
375 this->active_tasks->remove_at(this->active_tasks, enumerator);
376 task->destroy(task);
377 /* migrate the remaining active tasks to the passive queue */
378 migrate_tasks(this->active_tasks, this->passive_tasks);
379 break;
380 case NEED_MORE:
381 /* processed, but task needs another exchange */
382 break;
383 case FAILED:
384 default:
385 if (this->ike_sa->get_state(this->ike_sa) != IKE_CONNECTING)
386 {
387 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
388 }
389 /* FALL */
390 case DESTROY_ME:
391 /* critical failure, destroy IKE_SA */
392 enumerator->destroy(enumerator);
393 message->destroy(message);
394 flush(this);
395 return DESTROY_ME;
396 }
397 }
398 enumerator->destroy(enumerator);
399
400 /* update exchange type if a task changed it */
401 this->initiating.type = message->get_exchange_type(message);
402
403 status = this->ike_sa->generate_message(this->ike_sa, message,
404 &this->initiating.packet);
405 if (status != SUCCESS)
406 {
407 /* message generation failed. There is nothing more to do than to
408 * close the SA */
409 message->destroy(message);
410 flush(this);
411 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
412 return DESTROY_ME;
413 }
414 message->destroy(message);
415
416 charon->sender->send(charon->sender,
417 this->initiating.packet->clone(this->initiating.packet));
418
419 return SUCCESS;
420 }
421
422 /**
423 * handle exchange collisions
424 */
425 static bool handle_collisions(private_task_manager_t *this, task_t *task)
426 {
427 return FALSE;
428 }
429
430 /**
431 * build a response depending on the "passive" task list
432 */
433 static status_t build_response(private_task_manager_t *this, message_t *request)
434 {
435 enumerator_t *enumerator;
436 task_t *task;
437 message_t *message;
438 host_t *me, *other;
439 bool delete = FALSE;
440 status_t status;
441 bool migrate = FALSE;
442
443 me = request->get_destination(request);
444 other = request->get_source(request);
445
446 message = message_create(IKEV1_MAJOR_VERSION, IKEV1_MINOR_VERSION);
447 message->set_exchange_type(message, request->get_exchange_type(request));
448 /* send response along the path the request came in */
449 message->set_source(message, me->clone(me));
450 message->set_destination(message, other->clone(other));
451 message->set_message_id(message, request->get_message_id(request));
452 message->set_request(message, FALSE);
453
454 enumerator = this->passive_tasks->create_enumerator(this->passive_tasks);
455 while (enumerator->enumerate(enumerator, (void*)&task))
456 {
457 switch (task->build(task, message))
458 {
459 case MIGRATE:
460 migrate = TRUE;
461 /* FALL */
462 case SUCCESS:
463 /* task completed, remove it */
464 this->passive_tasks->remove_at(this->passive_tasks, enumerator);
465 if (!handle_collisions(this, task))
466 {
467 task->destroy(task);
468 }
469 break;
470 case NEED_MORE:
471 /* processed, but task needs another exchange */
472 if (handle_collisions(this, task))
473 {
474 this->passive_tasks->remove_at(this->passive_tasks,
475 enumerator);
476 }
477 break;
478 case FAILED:
479 default:
480 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
481 /* FALL */
482 case DESTROY_ME:
483 /* destroy IKE_SA, but SEND response first */
484 delete = TRUE;
485 break;
486 }
487 if (delete)
488 {
489 break;
490 }
491 }
492 enumerator->destroy(enumerator);
493
494 /* message complete, send it */
495 DESTROY_IF(this->responding.packet);
496 this->responding.packet = NULL;
497 status = this->ike_sa->generate_message(this->ike_sa, message,
498 &this->responding.packet);
499 message->destroy(message);
500 if (status != SUCCESS)
501 {
502 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
503 return DESTROY_ME;
504 }
505
506 charon->sender->send(charon->sender,
507 this->responding.packet->clone(this->responding.packet));
508
509 if (migrate)
510 {
511 migrate_tasks(this->passive_tasks, this->queued_tasks);
512 /* Kick off the newly installed tasks */
513 initiate(this);
514 }
515
516 if (delete)
517 {
518 return DESTROY_ME;
519 }
520 return SUCCESS;
521 }
522
523 /**
524 * handle an incoming request message
525 */
526 static status_t process_request(private_task_manager_t *this,
527 message_t *message)
528 {
529 enumerator_t *enumerator;
530 task_t *task = NULL;
531 status_t process_status;
532
533 if (this->passive_tasks->get_count(this->passive_tasks) == 0)
534 { /* create tasks depending on request type, if not already some queued */
535 switch (message->get_exchange_type(message))
536 {
537 case ID_PROT:
538 task = (task_t *)ike_vendor_v1_create(this->ike_sa, FALSE);
539 this->passive_tasks->insert_last(this->passive_tasks, task);
540 task = (task_t *)main_mode_create(this->ike_sa, FALSE);
541 this->passive_tasks->insert_last(this->passive_tasks, task);
542 task = (task_t *)xauth_request_create(this->ike_sa, FALSE);
543 this->passive_tasks->insert_last(this->passive_tasks, task);
544 break;
545 case AGGRESSIVE:
546 /* TODO-IKEv1: agressive mode */
547 return FAILED;
548 case QUICK_MODE:
549 task = (task_t *)quick_mode_create(this->ike_sa, NULL,
550 NULL, NULL);
551 this->passive_tasks->insert_last(this->passive_tasks, task);
552 break;
553 case INFORMATIONAL_V1:
554 /* TODO-IKEv1: informational */
555 return FAILED;
556 default:
557 return FAILED;
558 }
559 }
560 /* let the tasks process the message */
561 enumerator = this->passive_tasks->create_enumerator(this->passive_tasks);
562 while (enumerator->enumerate(enumerator, (void*)&task))
563 {
564 switch (task->process(task, message))
565 {
566 case SUCCESS:
567 /* task completed, remove it */
568 this->passive_tasks->remove_at(this->passive_tasks, enumerator);
569 task->destroy(task);
570 enumerator->destroy(enumerator);
571 return SUCCESS;
572 case MIGRATE:
573 /* task completed, remove it */
574 this->passive_tasks->remove_at(this->passive_tasks, enumerator);
575 task->destroy(task);
576 enumerator->destroy(enumerator);
577 /* migrate the remaining tasks */
578 migrate_tasks(this->passive_tasks, this->queued_tasks);
579 /* Kick off the newly installed tasks */
580 initiate(this);
581 return SUCCESS;
582 case NEED_MORE:
583 /* processed, but task needs at least another call to build() */
584 break;
585 case FAILED:
586 default:
587 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
588 /* FALL */
589 case DESTROY_ME:
590 /* critical failure, destroy IKE_SA */
591 this->passive_tasks->remove_at(this->passive_tasks, enumerator);
592 enumerator->destroy(enumerator);
593 task->destroy(task);
594 return DESTROY_ME;
595 }
596 }
597 enumerator->destroy(enumerator);
598
599 process_status = build_response(this, message);
600
601 if(((process_status == SUCCESS) || (process_status == NEED_MORE)) && (this->initiate_later_flag == TRUE))
602 {
603 this->initiate_later_flag = FALSE;
604 return initiate(this);
605 }
606 return process_status;
607 }
608
609 /**
610 * handle an incoming response message
611 */
612 static status_t process_response(private_task_manager_t *this,
613 message_t *message)
614 {
615 enumerator_t *enumerator;
616 task_t *task;
617
618 if (message->get_exchange_type(message) != this->initiating.type)
619 {
620 DBG1(DBG_IKE, "received %N response, but expected %N",
621 exchange_type_names, message->get_exchange_type(message),
622 exchange_type_names, this->initiating.type);
623 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
624 return DESTROY_ME;
625 }
626
627 enumerator = this->active_tasks->create_enumerator(this->active_tasks);
628 while (enumerator->enumerate(enumerator, (void*)&task))
629 {
630 switch (task->process(task, message))
631 {
632 case SUCCESS:
633 /* task completed, remove it */
634 this->active_tasks->remove_at(this->active_tasks, enumerator);
635 task->destroy(task);
636 break;
637 case NEED_MORE:
638 /* processed, but task needs another exchange */
639 break;
640 case FAILED:
641 default:
642 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
643 /* FALL */
644 case DESTROY_ME:
645 /* critical failure, destroy IKE_SA */
646 this->active_tasks->remove_at(this->active_tasks, enumerator);
647 enumerator->destroy(enumerator);
648 task->destroy(task);
649 return DESTROY_ME;
650 }
651 }
652 enumerator->destroy(enumerator);
653
654 this->initiating.type = EXCHANGE_TYPE_UNDEFINED;
655 this->initiating.packet->destroy(this->initiating.packet);
656 this->initiating.packet = NULL;
657
658 return initiate(this);
659 }
660
661 METHOD(task_manager_t, process_message, status_t,
662 private_task_manager_t *this, message_t *msg)
663 {
664 u_int32_t hash, mid;
665 host_t *me, *other;
666
667 mid = msg->get_message_id(msg);
668
669 /* TODO-IKEv1: update hosts more selectively */
670 me = msg->get_destination(msg);
671 other = msg->get_source(msg);
672
673 if ((mid && mid == this->initiating.mid) ||
674 (this->initiating.mid == 0 &&
675 this->active_tasks->get_count(this->active_tasks)))
676 {
677 this->ike_sa->update_hosts(this->ike_sa, me, other, TRUE);
678 charon->bus->message(charon->bus, msg, FALSE);
679 if (process_response(this, msg) != SUCCESS)
680 {
681 flush(this);
682 return DESTROY_ME;
683 }
684 }
685 else
686 {
687 hash = chunk_hash(msg->get_packet_data(msg));
688 if (hash == this->responding.hash)
689 {
690 DBG1(DBG_IKE, "received retransmit of request with ID %d, "
691 "retransmitting response", mid);
692 charon->sender->send(charon->sender,
693 this->responding.packet->clone(this->responding.packet));
694 return SUCCESS;
695 }
696 this->ike_sa->update_hosts(this->ike_sa, me, other, TRUE);
697 charon->bus->message(charon->bus, msg, TRUE);
698 if (process_request(this, msg) != SUCCESS)
699 {
700 flush(this);
701 return DESTROY_ME;
702 }
703
704 this->responding.mid = mid;
705 this->responding.hash = hash;
706 }
707 return SUCCESS;
708 }
709
710 METHOD(task_manager_t, queue_task, void,
711 private_task_manager_t *this, task_t *task)
712 {
713 DBG2(DBG_IKE, "queueing %N task", task_type_names, task->get_type(task));
714 this->queued_tasks->insert_last(this->queued_tasks, task);
715 }
716
717 METHOD(task_manager_t, adopt_tasks, void,
718 private_task_manager_t *this, task_manager_t *other_public)
719 {
720 private_task_manager_t *other = (private_task_manager_t*)other_public;
721 task_t *task;
722
723 /* move queued tasks from other to this */
724 while (other->queued_tasks->remove_last(other->queued_tasks,
725 (void**)&task) == SUCCESS)
726 {
727 DBG2(DBG_IKE, "migrating %N task", task_type_names, task->get_type(task));
728 task->migrate(task, this->ike_sa);
729 this->queued_tasks->insert_first(this->queued_tasks, task);
730 }
731 }
732
733 METHOD(task_manager_t, busy, bool,
734 private_task_manager_t *this)
735 {
736 return (this->active_tasks->get_count(this->active_tasks) > 0);
737 }
738
739 METHOD(task_manager_t, incr_mid, void,
740 private_task_manager_t *this, bool initiate)
741 {
742 }
743
744 METHOD(task_manager_t, reset, void,
745 private_task_manager_t *this, u_int32_t initiate, u_int32_t respond)
746 {
747 }
748
749 METHOD(task_manager_t, create_task_enumerator, enumerator_t*,
750 private_task_manager_t *this, task_queue_t queue)
751 {
752 switch (queue)
753 {
754 case TASK_QUEUE_ACTIVE:
755 return this->active_tasks->create_enumerator(this->active_tasks);
756 case TASK_QUEUE_PASSIVE:
757 return this->passive_tasks->create_enumerator(this->passive_tasks);
758 case TASK_QUEUE_QUEUED:
759 return this->queued_tasks->create_enumerator(this->queued_tasks);
760 default:
761 return enumerator_create_empty();
762 }
763 }
764
765 METHOD(task_manager_t, destroy, void,
766 private_task_manager_t *this)
767 {
768 flush(this);
769
770 this->active_tasks->destroy(this->active_tasks);
771 this->queued_tasks->destroy(this->queued_tasks);
772 this->passive_tasks->destroy(this->passive_tasks);
773
774 DESTROY_IF(this->responding.packet);
775 DESTROY_IF(this->initiating.packet);
776 DESTROY_IF(this->rng);
777 free(this);
778 }
779
780 METHOD(task_manager_t, initiate_later, void,
781 private_task_manager_t *this)
782 {
783 this->initiate_later_flag = TRUE;
784 }
785
786 /*
787 * see header file
788 */
789 task_manager_v1_t *task_manager_v1_create(ike_sa_t *ike_sa)
790 {
791 private_task_manager_t *this;
792
793 INIT(this,
794 .public = {
795 .task_manager = {
796 .process_message = _process_message,
797 .queue_task = _queue_task,
798 .initiate = _initiate,
799 .retransmit = _retransmit,
800 .incr_mid = _incr_mid,
801 .reset = _reset,
802 .adopt_tasks = _adopt_tasks,
803 .busy = _busy,
804 .create_task_enumerator = _create_task_enumerator,
805 .destroy = _destroy,
806 .initiate_later = _initiate_later,
807 },
808 },
809 .ike_sa = ike_sa,
810 .initiating.type = EXCHANGE_TYPE_UNDEFINED,
811 .rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK),
812 .queued_tasks = linked_list_create(),
813 .active_tasks = linked_list_create(),
814 .passive_tasks = linked_list_create(),
815 .retransmit_tries = lib->settings->get_int(lib->settings,
816 "charon.retransmit_tries", RETRANSMIT_TRIES),
817 .retransmit_timeout = lib->settings->get_double(lib->settings,
818 "charon.retransmit_timeout", RETRANSMIT_TIMEOUT),
819 .retransmit_base = lib->settings->get_double(lib->settings,
820 "charon.retransmit_base", RETRANSMIT_BASE),
821 .initiate_later_flag = FALSE,
822 );
823
824 return &this->public;
825 }