79a9aa5a0155ac7bf0e6906ac31f9efc71081504
[strongswan.git] / src / libcharon / sa / ikev2 / task_manager_v2.c
1 /*
2 * Copyright (C) 2007-2011 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_v2.h"
18
19 #include <math.h>
20
21 #include <collections/array.h>
22 #include <daemon.h>
23 #include <sa/ikev2/tasks/ike_init.h>
24 #include <sa/ikev2/tasks/ike_natd.h>
25 #include <sa/ikev2/tasks/ike_mobike.h>
26 #include <sa/ikev2/tasks/ike_auth.h>
27 #include <sa/ikev2/tasks/ike_auth_lifetime.h>
28 #include <sa/ikev2/tasks/ike_cert_pre.h>
29 #include <sa/ikev2/tasks/ike_cert_post.h>
30 #include <sa/ikev2/tasks/ike_rekey.h>
31 #include <sa/ikev2/tasks/ike_reauth.h>
32 #include <sa/ikev2/tasks/ike_delete.h>
33 #include <sa/ikev2/tasks/ike_config.h>
34 #include <sa/ikev2/tasks/ike_dpd.h>
35 #include <sa/ikev2/tasks/ike_vendor.h>
36 #include <sa/ikev2/tasks/child_create.h>
37 #include <sa/ikev2/tasks/child_rekey.h>
38 #include <sa/ikev2/tasks/child_delete.h>
39 #include <encoding/payloads/delete_payload.h>
40 #include <encoding/payloads/unknown_payload.h>
41 #include <processing/jobs/retransmit_job.h>
42 #include <processing/jobs/delete_ike_sa_job.h>
43
44 #ifdef ME
45 #include <sa/ikev2/tasks/ike_me.h>
46 #endif
47
48 typedef struct exchange_t exchange_t;
49
50 /**
51 * An exchange in the air, used do detect and handle retransmission
52 */
53 struct exchange_t {
54
55 /**
56 * Message ID used for this transaction
57 */
58 u_int32_t mid;
59
60 /**
61 * generated packet for retransmission
62 */
63 packet_t *packet;
64 };
65
66 typedef struct private_task_manager_t private_task_manager_t;
67
68 /**
69 * private data of the task manager
70 */
71 struct private_task_manager_t {
72
73 /**
74 * public functions
75 */
76 task_manager_v2_t public;
77
78 /**
79 * associated IKE_SA we are serving
80 */
81 ike_sa_t *ike_sa;
82
83 /**
84 * Exchange we are currently handling as responder
85 */
86 struct {
87 /**
88 * Message ID of the exchange
89 */
90 u_int32_t mid;
91
92 /**
93 * packet for retransmission
94 */
95 packet_t *packet;
96
97 } responding;
98
99 /**
100 * Exchange we are currently handling as initiator
101 */
102 struct {
103 /**
104 * Message ID of the exchange
105 */
106 u_int32_t mid;
107
108 /**
109 * how many times we have retransmitted so far
110 */
111 u_int retransmitted;
112
113 /**
114 * packet for retransmission
115 */
116 packet_t *packet;
117
118 /**
119 * type of the initated exchange
120 */
121 exchange_type_t type;
122
123 } initiating;
124
125 /**
126 * Array of queued tasks not yet in action
127 */
128 array_t *queued_tasks;
129
130 /**
131 * Array of active tasks, initiated by ourselve
132 */
133 array_t *active_tasks;
134
135 /**
136 * Array of tasks initiated by peer
137 */
138 array_t *passive_tasks;
139
140 /**
141 * the task manager has been reset
142 */
143 bool reset;
144
145 /**
146 * Number of times we retransmit messages before giving up
147 */
148 u_int retransmit_tries;
149
150 /**
151 * Retransmission timeout
152 */
153 double retransmit_timeout;
154
155 /**
156 * Base to calculate retransmission timeout
157 */
158 double retransmit_base;
159 };
160
161 METHOD(task_manager_t, flush_queue, void,
162 private_task_manager_t *this, task_queue_t queue)
163 {
164 array_t *array;
165 task_t *task;
166
167 switch (queue)
168 {
169 case TASK_QUEUE_ACTIVE:
170 array = this->active_tasks;
171 break;
172 case TASK_QUEUE_PASSIVE:
173 array = this->passive_tasks;
174 break;
175 case TASK_QUEUE_QUEUED:
176 array = this->queued_tasks;
177 break;
178 default:
179 return;
180 }
181 while (array_remove(array, ARRAY_TAIL, &task))
182 {
183 task->destroy(task);
184 }
185 }
186
187 /**
188 * flush all tasks in the task manager
189 */
190 static void flush(private_task_manager_t *this)
191 {
192 flush_queue(this, TASK_QUEUE_QUEUED);
193 flush_queue(this, TASK_QUEUE_PASSIVE);
194 flush_queue(this, TASK_QUEUE_ACTIVE);
195 }
196
197 /**
198 * move a task of a specific type from the queue to the active list
199 */
200 static bool activate_task(private_task_manager_t *this, task_type_t type)
201 {
202 enumerator_t *enumerator;
203 task_t *task;
204 bool found = FALSE;
205
206 enumerator = array_create_enumerator(this->queued_tasks);
207 while (enumerator->enumerate(enumerator, (void**)&task))
208 {
209 if (task->get_type(task) == type)
210 {
211 DBG2(DBG_IKE, " activating %N task", task_type_names, type);
212 array_remove_at(this->queued_tasks, enumerator);
213 array_insert(this->active_tasks, ARRAY_TAIL, task);
214 found = TRUE;
215 break;
216 }
217 }
218 enumerator->destroy(enumerator);
219 return found;
220 }
221
222 METHOD(task_manager_t, retransmit, status_t,
223 private_task_manager_t *this, u_int32_t message_id)
224 {
225 if (this->initiating.packet && message_id == this->initiating.mid)
226 {
227 u_int32_t timeout;
228 job_t *job;
229 enumerator_t *enumerator;
230 packet_t *packet;
231 task_t *task;
232 ike_mobike_t *mobike = NULL;
233
234 /* check if we are retransmitting a MOBIKE routability check */
235 enumerator = array_create_enumerator(this->active_tasks);
236 while (enumerator->enumerate(enumerator, (void*)&task))
237 {
238 if (task->get_type(task) == TASK_IKE_MOBIKE)
239 {
240 mobike = (ike_mobike_t*)task;
241 if (!mobike->is_probing(mobike))
242 {
243 mobike = NULL;
244 }
245 break;
246 }
247 }
248 enumerator->destroy(enumerator);
249
250 if (mobike == NULL)
251 {
252 if (this->initiating.retransmitted <= this->retransmit_tries)
253 {
254 timeout = (u_int32_t)(this->retransmit_timeout * 1000.0 *
255 pow(this->retransmit_base, this->initiating.retransmitted));
256 }
257 else
258 {
259 DBG1(DBG_IKE, "giving up after %d retransmits",
260 this->initiating.retransmitted - 1);
261 charon->bus->alert(charon->bus, ALERT_RETRANSMIT_SEND_TIMEOUT,
262 this->initiating.packet);
263 return DESTROY_ME;
264 }
265
266 if (this->initiating.retransmitted)
267 {
268 DBG1(DBG_IKE, "retransmit %d of request with message ID %d",
269 this->initiating.retransmitted, message_id);
270 charon->bus->alert(charon->bus, ALERT_RETRANSMIT_SEND,
271 this->initiating.packet);
272 }
273 packet = this->initiating.packet->clone(this->initiating.packet);
274 charon->sender->send(charon->sender, packet);
275 }
276 else
277 { /* for routeability checks, we use a more aggressive behavior */
278 if (this->initiating.retransmitted <= ROUTEABILITY_CHECK_TRIES)
279 {
280 timeout = ROUTEABILITY_CHECK_INTERVAL;
281 }
282 else
283 {
284 DBG1(DBG_IKE, "giving up after %d path probings",
285 this->initiating.retransmitted - 1);
286 return DESTROY_ME;
287 }
288
289 if (this->initiating.retransmitted)
290 {
291 DBG1(DBG_IKE, "path probing attempt %d",
292 this->initiating.retransmitted);
293 }
294 mobike->transmit(mobike, this->initiating.packet);
295 }
296
297 this->initiating.retransmitted++;
298 job = (job_t*)retransmit_job_create(this->initiating.mid,
299 this->ike_sa->get_id(this->ike_sa));
300 lib->scheduler->schedule_job_ms(lib->scheduler, job, timeout);
301 }
302 return SUCCESS;
303 }
304
305 METHOD(task_manager_t, initiate, status_t,
306 private_task_manager_t *this)
307 {
308 enumerator_t *enumerator;
309 task_t *task;
310 message_t *message;
311 host_t *me, *other;
312 status_t status;
313 exchange_type_t exchange = 0;
314
315 if (this->initiating.type != EXCHANGE_TYPE_UNDEFINED)
316 {
317 DBG2(DBG_IKE, "delaying task initiation, %N exchange in progress",
318 exchange_type_names, this->initiating.type);
319 /* do not initiate if we already have a message in the air */
320 return SUCCESS;
321 }
322
323 if (array_count(this->active_tasks) == 0)
324 {
325 DBG2(DBG_IKE, "activating new tasks");
326 switch (this->ike_sa->get_state(this->ike_sa))
327 {
328 case IKE_CREATED:
329 activate_task(this, TASK_IKE_VENDOR);
330 if (activate_task(this, TASK_IKE_INIT))
331 {
332 this->initiating.mid = 0;
333 exchange = IKE_SA_INIT;
334 activate_task(this, TASK_IKE_NATD);
335 activate_task(this, TASK_IKE_CERT_PRE);
336 #ifdef ME
337 /* this task has to be activated before the TASK_IKE_AUTH
338 * task, because that task pregenerates the packet after
339 * which no payloads can be added to the message anymore.
340 */
341 activate_task(this, TASK_IKE_ME);
342 #endif /* ME */
343 activate_task(this, TASK_IKE_AUTH);
344 activate_task(this, TASK_IKE_CERT_POST);
345 activate_task(this, TASK_IKE_CONFIG);
346 activate_task(this, TASK_CHILD_CREATE);
347 activate_task(this, TASK_IKE_AUTH_LIFETIME);
348 activate_task(this, TASK_IKE_MOBIKE);
349 }
350 break;
351 case IKE_ESTABLISHED:
352 if (activate_task(this, TASK_CHILD_CREATE))
353 {
354 exchange = CREATE_CHILD_SA;
355 break;
356 }
357 if (activate_task(this, TASK_CHILD_DELETE))
358 {
359 exchange = INFORMATIONAL;
360 break;
361 }
362 if (activate_task(this, TASK_CHILD_REKEY))
363 {
364 exchange = CREATE_CHILD_SA;
365 break;
366 }
367 if (activate_task(this, TASK_IKE_DELETE))
368 {
369 exchange = INFORMATIONAL;
370 break;
371 }
372 if (activate_task(this, TASK_IKE_REKEY))
373 {
374 exchange = CREATE_CHILD_SA;
375 break;
376 }
377 if (activate_task(this, TASK_IKE_REAUTH))
378 {
379 exchange = INFORMATIONAL;
380 break;
381 }
382 if (activate_task(this, TASK_IKE_MOBIKE))
383 {
384 exchange = INFORMATIONAL;
385 break;
386 }
387 if (activate_task(this, TASK_IKE_DPD))
388 {
389 exchange = INFORMATIONAL;
390 break;
391 }
392 if (activate_task(this, TASK_IKE_AUTH_LIFETIME))
393 {
394 exchange = INFORMATIONAL;
395 break;
396 }
397 #ifdef ME
398 if (activate_task(this, TASK_IKE_ME))
399 {
400 exchange = ME_CONNECT;
401 break;
402 }
403 #endif /* ME */
404 case IKE_REKEYING:
405 if (activate_task(this, TASK_IKE_DELETE))
406 {
407 exchange = INFORMATIONAL;
408 break;
409 }
410 case IKE_DELETING:
411 default:
412 break;
413 }
414 }
415 else
416 {
417 DBG2(DBG_IKE, "reinitiating already active tasks");
418 enumerator = array_create_enumerator(this->active_tasks);
419 while (enumerator->enumerate(enumerator, &task))
420 {
421 DBG2(DBG_IKE, " %N task", task_type_names, task->get_type(task));
422 switch (task->get_type(task))
423 {
424 case TASK_IKE_INIT:
425 exchange = IKE_SA_INIT;
426 break;
427 case TASK_IKE_AUTH:
428 exchange = IKE_AUTH;
429 break;
430 case TASK_CHILD_CREATE:
431 case TASK_CHILD_REKEY:
432 case TASK_IKE_REKEY:
433 exchange = CREATE_CHILD_SA;
434 break;
435 case TASK_IKE_MOBIKE:
436 exchange = INFORMATIONAL;
437 break;
438 default:
439 continue;
440 }
441 break;
442 }
443 enumerator->destroy(enumerator);
444 }
445
446 if (exchange == 0)
447 {
448 DBG2(DBG_IKE, "nothing to initiate");
449 /* nothing to do yet... */
450 return SUCCESS;
451 }
452
453 me = this->ike_sa->get_my_host(this->ike_sa);
454 other = this->ike_sa->get_other_host(this->ike_sa);
455
456 message = message_create(IKEV2_MAJOR_VERSION, IKEV2_MINOR_VERSION);
457 message->set_message_id(message, this->initiating.mid);
458 message->set_source(message, me->clone(me));
459 message->set_destination(message, other->clone(other));
460 message->set_exchange_type(message, exchange);
461 this->initiating.type = exchange;
462 this->initiating.retransmitted = 0;
463
464 enumerator = array_create_enumerator(this->active_tasks);
465 while (enumerator->enumerate(enumerator, &task))
466 {
467 switch (task->build(task, message))
468 {
469 case SUCCESS:
470 /* task completed, remove it */
471 array_remove_at(this->active_tasks, enumerator);
472 task->destroy(task);
473 break;
474 case NEED_MORE:
475 /* processed, but task needs another exchange */
476 break;
477 case FAILED:
478 default:
479 this->initiating.type = EXCHANGE_TYPE_UNDEFINED;
480 if (this->ike_sa->get_state(this->ike_sa) != IKE_CONNECTING)
481 {
482 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
483 }
484 /* FALL */
485 case DESTROY_ME:
486 /* critical failure, destroy IKE_SA */
487 enumerator->destroy(enumerator);
488 message->destroy(message);
489 flush(this);
490 return DESTROY_ME;
491 }
492 }
493 enumerator->destroy(enumerator);
494
495 /* update exchange type if a task changed it */
496 this->initiating.type = message->get_exchange_type(message);
497
498 status = this->ike_sa->generate_message(this->ike_sa, message,
499 &this->initiating.packet);
500 if (status != SUCCESS)
501 {
502 /* message generation failed. There is nothing more to do than to
503 * close the SA */
504 message->destroy(message);
505 flush(this);
506 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
507 return DESTROY_ME;
508 }
509 message->destroy(message);
510
511 array_compress(this->active_tasks);
512 array_compress(this->queued_tasks);
513
514 return retransmit(this, this->initiating.mid);
515 }
516
517 /**
518 * handle an incoming response message
519 */
520 static status_t process_response(private_task_manager_t *this,
521 message_t *message)
522 {
523 enumerator_t *enumerator;
524 task_t *task;
525
526 if (message->get_exchange_type(message) != this->initiating.type)
527 {
528 DBG1(DBG_IKE, "received %N response, but expected %N",
529 exchange_type_names, message->get_exchange_type(message),
530 exchange_type_names, this->initiating.type);
531 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
532 return DESTROY_ME;
533 }
534
535 /* catch if we get resetted while processing */
536 this->reset = FALSE;
537 enumerator = array_create_enumerator(this->active_tasks);
538 while (enumerator->enumerate(enumerator, &task))
539 {
540 switch (task->process(task, message))
541 {
542 case SUCCESS:
543 /* task completed, remove it */
544 array_remove_at(this->active_tasks, enumerator);
545 task->destroy(task);
546 break;
547 case NEED_MORE:
548 /* processed, but task needs another exchange */
549 break;
550 case FAILED:
551 default:
552 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
553 /* FALL */
554 case DESTROY_ME:
555 /* critical failure, destroy IKE_SA */
556 array_remove_at(this->active_tasks, enumerator);
557 enumerator->destroy(enumerator);
558 task->destroy(task);
559 return DESTROY_ME;
560 }
561 if (this->reset)
562 { /* start all over again if we were reset */
563 this->reset = FALSE;
564 enumerator->destroy(enumerator);
565 return initiate(this);
566 }
567 }
568 enumerator->destroy(enumerator);
569
570 this->initiating.mid++;
571 this->initiating.type = EXCHANGE_TYPE_UNDEFINED;
572 this->initiating.packet->destroy(this->initiating.packet);
573 this->initiating.packet = NULL;
574
575 array_compress(this->active_tasks);
576
577 return initiate(this);
578 }
579
580 /**
581 * handle exchange collisions
582 */
583 static bool handle_collisions(private_task_manager_t *this, task_t *task)
584 {
585 enumerator_t *enumerator;
586 task_t *active;
587 task_type_t type;
588
589 type = task->get_type(task);
590
591 /* do we have to check */
592 if (type == TASK_IKE_REKEY || type == TASK_CHILD_REKEY ||
593 type == TASK_CHILD_DELETE || type == TASK_IKE_DELETE ||
594 type == TASK_IKE_REAUTH)
595 {
596 /* find an exchange collision, and notify these tasks */
597 enumerator = array_create_enumerator(this->active_tasks);
598 while (enumerator->enumerate(enumerator, &active))
599 {
600 switch (active->get_type(active))
601 {
602 case TASK_IKE_REKEY:
603 if (type == TASK_IKE_REKEY || type == TASK_IKE_DELETE ||
604 type == TASK_IKE_REAUTH)
605 {
606 ike_rekey_t *rekey = (ike_rekey_t*)active;
607 rekey->collide(rekey, task);
608 break;
609 }
610 continue;
611 case TASK_CHILD_REKEY:
612 if (type == TASK_CHILD_REKEY || type == TASK_CHILD_DELETE)
613 {
614 child_rekey_t *rekey = (child_rekey_t*)active;
615 rekey->collide(rekey, task);
616 break;
617 }
618 continue;
619 default:
620 continue;
621 }
622 enumerator->destroy(enumerator);
623 return TRUE;
624 }
625 enumerator->destroy(enumerator);
626 }
627 return FALSE;
628 }
629
630 /**
631 * build a response depending on the "passive" task list
632 */
633 static status_t build_response(private_task_manager_t *this, message_t *request)
634 {
635 enumerator_t *enumerator;
636 task_t *task;
637 message_t *message;
638 host_t *me, *other;
639 bool delete = FALSE, hook = FALSE;
640 ike_sa_id_t *id = NULL;
641 u_int64_t responder_spi;
642 status_t status;
643
644 me = request->get_destination(request);
645 other = request->get_source(request);
646
647 message = message_create(IKEV2_MAJOR_VERSION, IKEV2_MINOR_VERSION);
648 message->set_exchange_type(message, request->get_exchange_type(request));
649 /* send response along the path the request came in */
650 message->set_source(message, me->clone(me));
651 message->set_destination(message, other->clone(other));
652 message->set_message_id(message, this->responding.mid);
653 message->set_request(message, FALSE);
654
655 enumerator = array_create_enumerator(this->passive_tasks);
656 while (enumerator->enumerate(enumerator, (void*)&task))
657 {
658 switch (task->build(task, message))
659 {
660 case SUCCESS:
661 /* task completed, remove it */
662 array_remove_at(this->passive_tasks, enumerator);
663 if (!handle_collisions(this, task))
664 {
665 task->destroy(task);
666 }
667 break;
668 case NEED_MORE:
669 /* processed, but task needs another exchange */
670 if (handle_collisions(this, task))
671 {
672 array_remove_at(this->passive_tasks, enumerator);
673 }
674 break;
675 case FAILED:
676 default:
677 hook = TRUE;
678 /* FALL */
679 case DESTROY_ME:
680 /* destroy IKE_SA, but SEND response first */
681 delete = TRUE;
682 break;
683 }
684 if (delete)
685 {
686 break;
687 }
688 }
689 enumerator->destroy(enumerator);
690
691 /* RFC 5996, section 2.6 mentions that in the event of a failure during
692 * IKE_SA_INIT the responder's SPI will be 0 in the response, while it
693 * actually explicitly allows it to be non-zero. Since we use the responder
694 * SPI to create hashes in the IKE_SA manager we can only set the SPI to
695 * zero temporarily, otherwise checking the SA in would fail. */
696 if (delete && request->get_exchange_type(request) == IKE_SA_INIT)
697 {
698 id = this->ike_sa->get_id(this->ike_sa);
699 responder_spi = id->get_responder_spi(id);
700 id->set_responder_spi(id, 0);
701 }
702
703 /* message complete, send it */
704 DESTROY_IF(this->responding.packet);
705 this->responding.packet = NULL;
706 status = this->ike_sa->generate_message(this->ike_sa, message,
707 &this->responding.packet);
708 message->destroy(message);
709 if (id)
710 {
711 id->set_responder_spi(id, responder_spi);
712 }
713 if (status != SUCCESS)
714 {
715 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
716 return DESTROY_ME;
717 }
718
719 charon->sender->send(charon->sender,
720 this->responding.packet->clone(this->responding.packet));
721 if (delete)
722 {
723 if (hook)
724 {
725 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
726 }
727 return DESTROY_ME;
728 }
729
730 array_compress(this->passive_tasks);
731
732 return SUCCESS;
733 }
734
735 /**
736 * handle an incoming request message
737 */
738 static status_t process_request(private_task_manager_t *this,
739 message_t *message)
740 {
741 enumerator_t *enumerator;
742 task_t *task = NULL;
743 payload_t *payload;
744 notify_payload_t *notify;
745 delete_payload_t *delete;
746
747 if (array_count(this->passive_tasks) == 0)
748 { /* create tasks depending on request type, if not already some queued */
749 switch (message->get_exchange_type(message))
750 {
751 case IKE_SA_INIT:
752 {
753 task = (task_t*)ike_vendor_create(this->ike_sa, FALSE);
754 array_insert(this->passive_tasks, ARRAY_TAIL, task);
755 task = (task_t*)ike_init_create(this->ike_sa, FALSE, NULL);
756 array_insert(this->passive_tasks, ARRAY_TAIL, task);
757 task = (task_t*)ike_natd_create(this->ike_sa, FALSE);
758 array_insert(this->passive_tasks, ARRAY_TAIL, task);
759 task = (task_t*)ike_cert_pre_create(this->ike_sa, FALSE);
760 array_insert(this->passive_tasks, ARRAY_TAIL, task);
761 #ifdef ME
762 task = (task_t*)ike_me_create(this->ike_sa, FALSE);
763 array_insert(this->passive_tasks, ARRAY_TAIL, task);
764 #endif /* ME */
765 task = (task_t*)ike_auth_create(this->ike_sa, FALSE);
766 array_insert(this->passive_tasks, ARRAY_TAIL, task);
767 task = (task_t*)ike_cert_post_create(this->ike_sa, FALSE);
768 array_insert(this->passive_tasks, ARRAY_TAIL, task);
769 task = (task_t*)ike_config_create(this->ike_sa, FALSE);
770 array_insert(this->passive_tasks, ARRAY_TAIL, task);
771 task = (task_t*)child_create_create(this->ike_sa, NULL, FALSE,
772 NULL, NULL);
773 array_insert(this->passive_tasks, ARRAY_TAIL, task);
774 task = (task_t*)ike_auth_lifetime_create(this->ike_sa, FALSE);
775 array_insert(this->passive_tasks, ARRAY_TAIL, task);
776 task = (task_t*)ike_mobike_create(this->ike_sa, FALSE);
777 array_insert(this->passive_tasks, ARRAY_TAIL, task);
778 break;
779 }
780 case CREATE_CHILD_SA:
781 { /* FIXME: we should prevent this on mediation connections */
782 bool notify_found = FALSE, ts_found = FALSE;
783 enumerator = message->create_payload_enumerator(message);
784 while (enumerator->enumerate(enumerator, &payload))
785 {
786 switch (payload->get_type(payload))
787 {
788 case NOTIFY:
789 { /* if we find a rekey notify, its CHILD_SA rekeying */
790 notify = (notify_payload_t*)payload;
791 if (notify->get_notify_type(notify) == REKEY_SA &&
792 (notify->get_protocol_id(notify) == PROTO_AH ||
793 notify->get_protocol_id(notify) == PROTO_ESP))
794 {
795 notify_found = TRUE;
796 }
797 break;
798 }
799 case TRAFFIC_SELECTOR_INITIATOR:
800 case TRAFFIC_SELECTOR_RESPONDER:
801 { /* if we don't find a TS, its IKE rekeying */
802 ts_found = TRUE;
803 break;
804 }
805 default:
806 break;
807 }
808 }
809 enumerator->destroy(enumerator);
810
811 if (ts_found)
812 {
813 if (notify_found)
814 {
815 task = (task_t*)child_rekey_create(this->ike_sa,
816 PROTO_NONE, 0);
817 }
818 else
819 {
820 task = (task_t*)child_create_create(this->ike_sa, NULL,
821 FALSE, NULL, NULL);
822 }
823 }
824 else
825 {
826 task = (task_t*)ike_rekey_create(this->ike_sa, FALSE);
827 }
828 array_insert(this->passive_tasks, ARRAY_TAIL, task);
829 break;
830 }
831 case INFORMATIONAL:
832 {
833 enumerator = message->create_payload_enumerator(message);
834 while (enumerator->enumerate(enumerator, &payload))
835 {
836 switch (payload->get_type(payload))
837 {
838 case NOTIFY:
839 {
840 notify = (notify_payload_t*)payload;
841 switch (notify->get_notify_type(notify))
842 {
843 case ADDITIONAL_IP4_ADDRESS:
844 case ADDITIONAL_IP6_ADDRESS:
845 case NO_ADDITIONAL_ADDRESSES:
846 case UPDATE_SA_ADDRESSES:
847 case NO_NATS_ALLOWED:
848 case UNACCEPTABLE_ADDRESSES:
849 case UNEXPECTED_NAT_DETECTED:
850 case COOKIE2:
851 case NAT_DETECTION_SOURCE_IP:
852 case NAT_DETECTION_DESTINATION_IP:
853 task = (task_t*)ike_mobike_create(
854 this->ike_sa, FALSE);
855 break;
856 case AUTH_LIFETIME:
857 task = (task_t*)ike_auth_lifetime_create(
858 this->ike_sa, FALSE);
859 break;
860 case AUTHENTICATION_FAILED:
861 /* initiator failed to authenticate us.
862 * We use ike_delete to handle this, which
863 * invokes all the required hooks. */
864 task = (task_t*)ike_delete_create(
865 this->ike_sa, FALSE);
866 default:
867 break;
868 }
869 break;
870 }
871 case DELETE:
872 {
873 delete = (delete_payload_t*)payload;
874 if (delete->get_protocol_id(delete) == PROTO_IKE)
875 {
876 task = (task_t*)ike_delete_create(this->ike_sa,
877 FALSE);
878 }
879 else
880 {
881 task = (task_t*)child_delete_create(this->ike_sa,
882 PROTO_NONE, 0, FALSE);
883 }
884 break;
885 }
886 default:
887 break;
888 }
889 if (task)
890 {
891 break;
892 }
893 }
894 enumerator->destroy(enumerator);
895
896 if (task == NULL)
897 {
898 task = (task_t*)ike_dpd_create(FALSE);
899 }
900 array_insert(this->passive_tasks, ARRAY_TAIL, task);
901 break;
902 }
903 #ifdef ME
904 case ME_CONNECT:
905 {
906 task = (task_t*)ike_me_create(this->ike_sa, FALSE);
907 array_insert(this->passive_tasks, ARRAY_TAIL, task);
908 }
909 #endif /* ME */
910 default:
911 break;
912 }
913 }
914
915 /* let the tasks process the message */
916 enumerator = array_create_enumerator(this->passive_tasks);
917 while (enumerator->enumerate(enumerator, (void*)&task))
918 {
919 switch (task->process(task, message))
920 {
921 case SUCCESS:
922 /* task completed, remove it */
923 array_remove_at(this->passive_tasks, enumerator);
924 task->destroy(task);
925 break;
926 case NEED_MORE:
927 /* processed, but task needs at least another call to build() */
928 break;
929 case FAILED:
930 default:
931 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
932 /* FALL */
933 case DESTROY_ME:
934 /* critical failure, destroy IKE_SA */
935 array_remove_at(this->passive_tasks, enumerator);
936 enumerator->destroy(enumerator);
937 task->destroy(task);
938 return DESTROY_ME;
939 }
940 }
941 enumerator->destroy(enumerator);
942
943 return build_response(this, message);
944 }
945
946 METHOD(task_manager_t, incr_mid, void,
947 private_task_manager_t *this, bool initiate)
948 {
949 if (initiate)
950 {
951 this->initiating.mid++;
952 }
953 else
954 {
955 this->responding.mid++;
956 }
957 }
958
959 /**
960 * Send a notify back to the sender
961 */
962 static void send_notify_response(private_task_manager_t *this,
963 message_t *request, notify_type_t type,
964 chunk_t data)
965 {
966 message_t *response;
967 packet_t *packet;
968 host_t *me, *other;
969
970 response = message_create(IKEV2_MAJOR_VERSION, IKEV2_MINOR_VERSION);
971 response->set_exchange_type(response, request->get_exchange_type(request));
972 response->set_request(response, FALSE);
973 response->set_message_id(response, request->get_message_id(request));
974 response->add_notify(response, FALSE, type, data);
975 me = this->ike_sa->get_my_host(this->ike_sa);
976 if (me->is_anyaddr(me))
977 {
978 me = request->get_destination(request);
979 this->ike_sa->set_my_host(this->ike_sa, me->clone(me));
980 }
981 other = this->ike_sa->get_other_host(this->ike_sa);
982 if (other->is_anyaddr(other))
983 {
984 other = request->get_source(request);
985 this->ike_sa->set_other_host(this->ike_sa, other->clone(other));
986 }
987 response->set_source(response, me->clone(me));
988 response->set_destination(response, other->clone(other));
989 if (this->ike_sa->generate_message(this->ike_sa, response,
990 &packet) == SUCCESS)
991 {
992 charon->sender->send(charon->sender, packet);
993 }
994 response->destroy(response);
995 }
996
997 /**
998 * Parse the given message and verify that it is valid.
999 */
1000 static status_t parse_message(private_task_manager_t *this, message_t *msg)
1001 {
1002 status_t status;
1003 u_int8_t type = 0;
1004
1005 status = msg->parse_body(msg, this->ike_sa->get_keymat(this->ike_sa));
1006
1007 if (status == SUCCESS)
1008 { /* check for unsupported critical payloads */
1009 enumerator_t *enumerator;
1010 unknown_payload_t *unknown;
1011 payload_t *payload;
1012
1013 enumerator = msg->create_payload_enumerator(msg);
1014 while (enumerator->enumerate(enumerator, &payload))
1015 {
1016 unknown = (unknown_payload_t*)payload;
1017 type = payload->get_type(payload);
1018 if (!payload_is_known(type) &&
1019 unknown->is_critical(unknown))
1020 {
1021 DBG1(DBG_ENC, "payload type %N is not supported, "
1022 "but its critical!", payload_type_names, type);
1023 status = NOT_SUPPORTED;
1024 break;
1025 }
1026 }
1027 enumerator->destroy(enumerator);
1028 }
1029
1030 if (status != SUCCESS)
1031 {
1032 bool is_request = msg->get_request(msg);
1033
1034 switch (status)
1035 {
1036 case NOT_SUPPORTED:
1037 DBG1(DBG_IKE, "critical unknown payloads found");
1038 if (is_request)
1039 {
1040 send_notify_response(this, msg,
1041 UNSUPPORTED_CRITICAL_PAYLOAD,
1042 chunk_from_thing(type));
1043 incr_mid(this, FALSE);
1044 }
1045 break;
1046 case PARSE_ERROR:
1047 DBG1(DBG_IKE, "message parsing failed");
1048 if (is_request)
1049 {
1050 send_notify_response(this, msg,
1051 INVALID_SYNTAX, chunk_empty);
1052 incr_mid(this, FALSE);
1053 }
1054 break;
1055 case VERIFY_ERROR:
1056 DBG1(DBG_IKE, "message verification failed");
1057 if (is_request)
1058 {
1059 send_notify_response(this, msg,
1060 INVALID_SYNTAX, chunk_empty);
1061 incr_mid(this, FALSE);
1062 }
1063 break;
1064 case FAILED:
1065 DBG1(DBG_IKE, "integrity check failed");
1066 /* ignored */
1067 break;
1068 case INVALID_STATE:
1069 DBG1(DBG_IKE, "found encrypted message, but no keys available");
1070 default:
1071 break;
1072 }
1073 DBG1(DBG_IKE, "%N %s with message ID %d processing failed",
1074 exchange_type_names, msg->get_exchange_type(msg),
1075 is_request ? "request" : "response",
1076 msg->get_message_id(msg));
1077
1078 charon->bus->alert(charon->bus, ALERT_PARSE_ERROR_BODY, msg, status);
1079
1080 if (this->ike_sa->get_state(this->ike_sa) == IKE_CREATED)
1081 { /* invalid initiation attempt, close SA */
1082 return DESTROY_ME;
1083 }
1084 }
1085 return status;
1086 }
1087
1088
1089 METHOD(task_manager_t, process_message, status_t,
1090 private_task_manager_t *this, message_t *msg)
1091 {
1092 host_t *me, *other;
1093 status_t status;
1094 u_int32_t mid;
1095
1096 charon->bus->message(charon->bus, msg, TRUE, FALSE);
1097 status = parse_message(this, msg);
1098 if (status != SUCCESS)
1099 {
1100 return status;
1101 }
1102
1103 me = msg->get_destination(msg);
1104 other = msg->get_source(msg);
1105
1106 /* if this IKE_SA is virgin, we check for a config */
1107 if (this->ike_sa->get_ike_cfg(this->ike_sa) == NULL)
1108 {
1109 ike_sa_id_t *ike_sa_id;
1110 ike_cfg_t *ike_cfg;
1111 job_t *job;
1112 ike_cfg = charon->backends->get_ike_cfg(charon->backends,
1113 me, other, IKEV2);
1114 if (ike_cfg == NULL)
1115 {
1116 /* no config found for these hosts, destroy */
1117 DBG1(DBG_IKE, "no IKE config found for %H...%H, sending %N",
1118 me, other, notify_type_names, NO_PROPOSAL_CHOSEN);
1119 send_notify_response(this, msg,
1120 NO_PROPOSAL_CHOSEN, chunk_empty);
1121 return DESTROY_ME;
1122 }
1123 this->ike_sa->set_ike_cfg(this->ike_sa, ike_cfg);
1124 ike_cfg->destroy(ike_cfg);
1125 /* add a timeout if peer does not establish it completely */
1126 ike_sa_id = this->ike_sa->get_id(this->ike_sa);
1127 job = (job_t*)delete_ike_sa_job_create(ike_sa_id, FALSE);
1128 lib->scheduler->schedule_job(lib->scheduler, job,
1129 lib->settings->get_int(lib->settings,
1130 "%s.half_open_timeout", HALF_OPEN_IKE_SA_TIMEOUT,
1131 charon->name));
1132 }
1133 this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND,
1134 time_monotonic(NULL));
1135
1136 mid = msg->get_message_id(msg);
1137 if (msg->get_request(msg))
1138 {
1139 if (mid == this->responding.mid)
1140 {
1141 /* reject initial messages once established */
1142 if (msg->get_exchange_type(msg) == IKE_SA_INIT ||
1143 msg->get_exchange_type(msg) == IKE_AUTH)
1144 {
1145 if (this->ike_sa->get_state(this->ike_sa) != IKE_CREATED &&
1146 this->ike_sa->get_state(this->ike_sa) != IKE_CONNECTING)
1147 {
1148 DBG1(DBG_IKE, "ignoring %N in established IKE_SA state",
1149 exchange_type_names, msg->get_exchange_type(msg));
1150 return FAILED;
1151 }
1152 }
1153 if (this->ike_sa->get_state(this->ike_sa) == IKE_CREATED ||
1154 this->ike_sa->get_state(this->ike_sa) == IKE_CONNECTING ||
1155 msg->get_exchange_type(msg) != IKE_SA_INIT)
1156 { /* only do host updates based on verified messages */
1157 if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE))
1158 { /* with MOBIKE, we do no implicit updates */
1159 this->ike_sa->update_hosts(this->ike_sa, me, other, mid == 1);
1160 }
1161 }
1162 charon->bus->message(charon->bus, msg, TRUE, TRUE);
1163 if (msg->get_exchange_type(msg) == EXCHANGE_TYPE_UNDEFINED)
1164 { /* ignore messages altered to EXCHANGE_TYPE_UNDEFINED */
1165 return SUCCESS;
1166 }
1167 if (process_request(this, msg) != SUCCESS)
1168 {
1169 flush(this);
1170 return DESTROY_ME;
1171 }
1172 this->responding.mid++;
1173 }
1174 else if ((mid == this->responding.mid - 1) && this->responding.packet)
1175 {
1176 packet_t *clone;
1177 host_t *host;
1178
1179 DBG1(DBG_IKE, "received retransmit of request with ID %d, "
1180 "retransmitting response", mid);
1181 charon->bus->alert(charon->bus, ALERT_RETRANSMIT_RECEIVE, msg);
1182 clone = this->responding.packet->clone(this->responding.packet);
1183 host = msg->get_destination(msg);
1184 clone->set_source(clone, host->clone(host));
1185 host = msg->get_source(msg);
1186 clone->set_destination(clone, host->clone(host));
1187 charon->sender->send(charon->sender, clone);
1188 }
1189 else
1190 {
1191 DBG1(DBG_IKE, "received message ID %d, expected %d. Ignored",
1192 mid, this->responding.mid);
1193 if (msg->get_exchange_type(msg) == IKE_SA_INIT)
1194 { /* clean up IKE_SA state if IKE_SA_INIT has invalid msg ID */
1195 return DESTROY_ME;
1196 }
1197 }
1198 }
1199 else
1200 {
1201 if (mid == this->initiating.mid)
1202 {
1203 if (this->ike_sa->get_state(this->ike_sa) == IKE_CREATED ||
1204 this->ike_sa->get_state(this->ike_sa) == IKE_CONNECTING ||
1205 msg->get_exchange_type(msg) != IKE_SA_INIT)
1206 { /* only do host updates based on verified messages */
1207 if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE))
1208 { /* with MOBIKE, we do no implicit updates */
1209 this->ike_sa->update_hosts(this->ike_sa, me, other, FALSE);
1210 }
1211 }
1212 charon->bus->message(charon->bus, msg, TRUE, TRUE);
1213 if (msg->get_exchange_type(msg) == EXCHANGE_TYPE_UNDEFINED)
1214 { /* ignore messages altered to EXCHANGE_TYPE_UNDEFINED */
1215 return SUCCESS;
1216 }
1217 if (process_response(this, msg) != SUCCESS)
1218 {
1219 flush(this);
1220 return DESTROY_ME;
1221 }
1222 }
1223 else
1224 {
1225 DBG1(DBG_IKE, "received message ID %d, expected %d. Ignored",
1226 mid, this->initiating.mid);
1227 return SUCCESS;
1228 }
1229 }
1230 return SUCCESS;
1231 }
1232
1233 METHOD(task_manager_t, queue_task, void,
1234 private_task_manager_t *this, task_t *task)
1235 {
1236 if (task->get_type(task) == TASK_IKE_MOBIKE)
1237 { /* there is no need to queue more than one mobike task */
1238 enumerator_t *enumerator;
1239 task_t *current;
1240
1241 enumerator = array_create_enumerator(this->queued_tasks);
1242 while (enumerator->enumerate(enumerator, &current))
1243 {
1244 if (current->get_type(current) == TASK_IKE_MOBIKE)
1245 {
1246 enumerator->destroy(enumerator);
1247 task->destroy(task);
1248 return;
1249 }
1250 }
1251 enumerator->destroy(enumerator);
1252 }
1253 DBG2(DBG_IKE, "queueing %N task", task_type_names, task->get_type(task));
1254 array_insert(this->queued_tasks, ARRAY_TAIL, task);
1255 }
1256
1257 /**
1258 * Check if a given task has been queued already
1259 */
1260 static bool has_queued(private_task_manager_t *this, task_type_t type)
1261 {
1262 enumerator_t *enumerator;
1263 bool found = FALSE;
1264 task_t *task;
1265
1266 enumerator = array_create_enumerator(this->queued_tasks);
1267 while (enumerator->enumerate(enumerator, &task))
1268 {
1269 if (task->get_type(task) == type)
1270 {
1271 found = TRUE;
1272 break;
1273 }
1274 }
1275 enumerator->destroy(enumerator);
1276 return found;
1277 }
1278
1279 METHOD(task_manager_t, queue_ike, void,
1280 private_task_manager_t *this)
1281 {
1282 if (!has_queued(this, TASK_IKE_VENDOR))
1283 {
1284 queue_task(this, (task_t*)ike_vendor_create(this->ike_sa, TRUE));
1285 }
1286 if (!has_queued(this, TASK_IKE_INIT))
1287 {
1288 queue_task(this, (task_t*)ike_init_create(this->ike_sa, TRUE, NULL));
1289 }
1290 if (!has_queued(this, TASK_IKE_NATD))
1291 {
1292 queue_task(this, (task_t*)ike_natd_create(this->ike_sa, TRUE));
1293 }
1294 if (!has_queued(this, TASK_IKE_CERT_PRE))
1295 {
1296 queue_task(this, (task_t*)ike_cert_pre_create(this->ike_sa, TRUE));
1297 }
1298 if (!has_queued(this, TASK_IKE_AUTH))
1299 {
1300 queue_task(this, (task_t*)ike_auth_create(this->ike_sa, TRUE));
1301 }
1302 if (!has_queued(this, TASK_IKE_CERT_POST))
1303 {
1304 queue_task(this, (task_t*)ike_cert_post_create(this->ike_sa, TRUE));
1305 }
1306 if (!has_queued(this, TASK_IKE_CONFIG))
1307 {
1308 queue_task(this, (task_t*)ike_config_create(this->ike_sa, TRUE));
1309 }
1310 if (!has_queued(this, TASK_IKE_AUTH_LIFETIME))
1311 {
1312 queue_task(this, (task_t*)ike_auth_lifetime_create(this->ike_sa, TRUE));
1313 }
1314 if (!has_queued(this, TASK_IKE_MOBIKE))
1315 {
1316 peer_cfg_t *peer_cfg;
1317
1318 peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
1319 if (peer_cfg->use_mobike(peer_cfg))
1320 {
1321 queue_task(this, (task_t*)ike_mobike_create(this->ike_sa, TRUE));
1322 }
1323 }
1324 #ifdef ME
1325 if (!has_queued(this, TASK_IKE_ME))
1326 {
1327 queue_task(this, (task_t*)ike_me_create(this->ike_sa, TRUE));
1328 }
1329 #endif /* ME */
1330 }
1331
1332 METHOD(task_manager_t, queue_ike_rekey, void,
1333 private_task_manager_t *this)
1334 {
1335 queue_task(this, (task_t*)ike_rekey_create(this->ike_sa, TRUE));
1336 }
1337
1338 METHOD(task_manager_t, queue_ike_reauth, void,
1339 private_task_manager_t *this)
1340 {
1341 queue_task(this, (task_t*)ike_reauth_create(this->ike_sa));
1342 }
1343
1344 METHOD(task_manager_t, queue_ike_delete, void,
1345 private_task_manager_t *this)
1346 {
1347 queue_task(this, (task_t*)ike_delete_create(this->ike_sa, TRUE));
1348 }
1349
1350 METHOD(task_manager_t, queue_mobike, void,
1351 private_task_manager_t *this, bool roam, bool address)
1352 {
1353 ike_mobike_t *mobike;
1354
1355 mobike = ike_mobike_create(this->ike_sa, TRUE);
1356 if (roam)
1357 {
1358 mobike->roam(mobike, address);
1359 }
1360 else
1361 {
1362 mobike->addresses(mobike);
1363 }
1364 queue_task(this, &mobike->task);
1365 }
1366
1367 METHOD(task_manager_t, queue_child, void,
1368 private_task_manager_t *this, child_cfg_t *cfg, u_int32_t reqid,
1369 traffic_selector_t *tsi, traffic_selector_t *tsr)
1370 {
1371 child_create_t *task;
1372
1373 task = child_create_create(this->ike_sa, cfg, FALSE, tsi, tsr);
1374 if (reqid)
1375 {
1376 task->use_reqid(task, reqid);
1377 }
1378 queue_task(this, &task->task);
1379 }
1380
1381 METHOD(task_manager_t, queue_child_rekey, void,
1382 private_task_manager_t *this, protocol_id_t protocol, u_int32_t spi)
1383 {
1384 queue_task(this, (task_t*)child_rekey_create(this->ike_sa, protocol, spi));
1385 }
1386
1387 METHOD(task_manager_t, queue_child_delete, void,
1388 private_task_manager_t *this, protocol_id_t protocol, u_int32_t spi,
1389 bool expired)
1390 {
1391 queue_task(this, (task_t*)child_delete_create(this->ike_sa,
1392 protocol, spi, expired));
1393 }
1394
1395 METHOD(task_manager_t, queue_dpd, void,
1396 private_task_manager_t *this)
1397 {
1398 ike_mobike_t *mobike;
1399
1400 if (this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE) &&
1401 this->ike_sa->has_condition(this->ike_sa, COND_NAT_HERE))
1402 {
1403 /* use mobike enabled DPD to detect NAT mapping changes */
1404 mobike = ike_mobike_create(this->ike_sa, TRUE);
1405 mobike->dpd(mobike);
1406 queue_task(this, &mobike->task);
1407 }
1408 else
1409 {
1410 queue_task(this, (task_t*)ike_dpd_create(TRUE));
1411 }
1412 }
1413
1414 METHOD(task_manager_t, adopt_tasks, void,
1415 private_task_manager_t *this, task_manager_t *other_public)
1416 {
1417 private_task_manager_t *other = (private_task_manager_t*)other_public;
1418 task_t *task;
1419
1420 /* move queued tasks from other to this */
1421 while (array_remove(other->queued_tasks, ARRAY_TAIL, &task))
1422 {
1423 DBG2(DBG_IKE, "migrating %N task", task_type_names, task->get_type(task));
1424 task->migrate(task, this->ike_sa);
1425 array_insert(this->queued_tasks, ARRAY_HEAD, task);
1426 }
1427 }
1428
1429 METHOD(task_manager_t, busy, bool,
1430 private_task_manager_t *this)
1431 {
1432 return array_count(this->active_tasks) > 0;
1433 }
1434
1435 METHOD(task_manager_t, reset, void,
1436 private_task_manager_t *this, u_int32_t initiate, u_int32_t respond)
1437 {
1438 enumerator_t *enumerator;
1439 task_t *task;
1440
1441 /* reset message counters and retransmit packets */
1442 DESTROY_IF(this->responding.packet);
1443 DESTROY_IF(this->initiating.packet);
1444 this->responding.packet = NULL;
1445 this->initiating.packet = NULL;
1446 if (initiate != UINT_MAX)
1447 {
1448 this->initiating.mid = initiate;
1449 }
1450 if (respond != UINT_MAX)
1451 {
1452 this->responding.mid = respond;
1453 }
1454 this->initiating.type = EXCHANGE_TYPE_UNDEFINED;
1455
1456 /* reset queued tasks */
1457 enumerator = array_create_enumerator(this->queued_tasks);
1458 while (enumerator->enumerate(enumerator, &task))
1459 {
1460 task->migrate(task, this->ike_sa);
1461 }
1462 enumerator->destroy(enumerator);
1463
1464 /* reset active tasks */
1465 while (array_remove(this->active_tasks, ARRAY_TAIL, &task))
1466 {
1467 task->migrate(task, this->ike_sa);
1468 array_insert(this->queued_tasks, ARRAY_HEAD, task);
1469 }
1470
1471 this->reset = TRUE;
1472 }
1473
1474 METHOD(task_manager_t, create_task_enumerator, enumerator_t*,
1475 private_task_manager_t *this, task_queue_t queue)
1476 {
1477 switch (queue)
1478 {
1479 case TASK_QUEUE_ACTIVE:
1480 return array_create_enumerator(this->active_tasks);
1481 case TASK_QUEUE_PASSIVE:
1482 return array_create_enumerator(this->passive_tasks);
1483 case TASK_QUEUE_QUEUED:
1484 return array_create_enumerator(this->queued_tasks);
1485 default:
1486 return enumerator_create_empty();
1487 }
1488 }
1489
1490 METHOD(task_manager_t, destroy, void,
1491 private_task_manager_t *this)
1492 {
1493 flush(this);
1494
1495 array_destroy(this->active_tasks);
1496 array_destroy(this->queued_tasks);
1497 array_destroy(this->passive_tasks);
1498
1499 DESTROY_IF(this->responding.packet);
1500 DESTROY_IF(this->initiating.packet);
1501 free(this);
1502 }
1503
1504 /*
1505 * see header file
1506 */
1507 task_manager_v2_t *task_manager_v2_create(ike_sa_t *ike_sa)
1508 {
1509 private_task_manager_t *this;
1510
1511 INIT(this,
1512 .public = {
1513 .task_manager = {
1514 .process_message = _process_message,
1515 .queue_task = _queue_task,
1516 .queue_ike = _queue_ike,
1517 .queue_ike_rekey = _queue_ike_rekey,
1518 .queue_ike_reauth = _queue_ike_reauth,
1519 .queue_ike_delete = _queue_ike_delete,
1520 .queue_mobike = _queue_mobike,
1521 .queue_child = _queue_child,
1522 .queue_child_rekey = _queue_child_rekey,
1523 .queue_child_delete = _queue_child_delete,
1524 .queue_dpd = _queue_dpd,
1525 .initiate = _initiate,
1526 .retransmit = _retransmit,
1527 .incr_mid = _incr_mid,
1528 .reset = _reset,
1529 .adopt_tasks = _adopt_tasks,
1530 .busy = _busy,
1531 .create_task_enumerator = _create_task_enumerator,
1532 .flush_queue = _flush_queue,
1533 .destroy = _destroy,
1534 },
1535 },
1536 .ike_sa = ike_sa,
1537 .initiating.type = EXCHANGE_TYPE_UNDEFINED,
1538 .queued_tasks = array_create(0, 0),
1539 .active_tasks = array_create(0, 0),
1540 .passive_tasks = array_create(0, 0),
1541 .retransmit_tries = lib->settings->get_int(lib->settings,
1542 "%s.retransmit_tries", RETRANSMIT_TRIES, charon->name),
1543 .retransmit_timeout = lib->settings->get_double(lib->settings,
1544 "%s.retransmit_timeout", RETRANSMIT_TIMEOUT, charon->name),
1545 .retransmit_base = lib->settings->get_double(lib->settings,
1546 "%s.retransmit_base", RETRANSMIT_BASE, charon->name),
1547 );
1548
1549 return &this->public;
1550 }