moved AUTH_LIFETIME handling in its own task (cleaner separation, proper payload...
[strongswan.git] / src / charon / sa / task_manager.c
1 /**
2 * @file task_manager.c
3 *
4 * @brief Implementation of task_manager_t.
5 *
6 */
7
8 /*
9 * Copyright (C) 2007 Tobias Brunner
10 * Copyright (C) 2007 Martin Willi
11 * Hochschule fuer Technik Rapperswil
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 * for more details.
22 */
23
24 #include "task_manager.h"
25
26 #include <math.h>
27
28 #include <daemon.h>
29 #include <sa/tasks/ike_init.h>
30 #include <sa/tasks/ike_natd.h>
31 #include <sa/tasks/ike_mobike.h>
32 #include <sa/tasks/ike_auth.h>
33 #include <sa/tasks/ike_auth_lifetime.h>
34 #include <sa/tasks/ike_cert.h>
35 #include <sa/tasks/ike_rekey.h>
36 #include <sa/tasks/ike_delete.h>
37 #include <sa/tasks/ike_config.h>
38 #include <sa/tasks/ike_dpd.h>
39 #include <sa/tasks/child_create.h>
40 #include <sa/tasks/child_rekey.h>
41 #include <sa/tasks/child_delete.h>
42 #include <encoding/payloads/delete_payload.h>
43 #include <processing/jobs/retransmit_job.h>
44
45 #ifdef P2P
46 #include <sa/tasks/ike_p2p.h>
47 #endif
48
49 typedef struct exchange_t exchange_t;
50
51 /**
52 * An exchange in the air, used do detect and handle retransmission
53 */
54 struct exchange_t {
55
56 /**
57 * Message ID used for this transaction
58 */
59 u_int32_t mid;
60
61 /**
62 * generated packet for retransmission
63 */
64 packet_t *packet;
65 };
66
67 typedef struct private_task_manager_t private_task_manager_t;
68
69 /**
70 * private data of the task manager
71 */
72 struct private_task_manager_t {
73
74 /**
75 * public functions
76 */
77 task_manager_t public;
78
79 /**
80 * associated IKE_SA we are serving
81 */
82 ike_sa_t *ike_sa;
83
84 /**
85 * Exchange we are currently handling as responder
86 */
87 struct {
88 /**
89 * Message ID of the exchange
90 */
91 u_int32_t mid;
92
93 /**
94 * packet for retransmission
95 */
96 packet_t *packet;
97
98 } responding;
99
100 /**
101 * Exchange we are currently handling as initiator
102 */
103 struct {
104 /**
105 * Message ID of the exchange
106 */
107 u_int32_t mid;
108
109 /**
110 * how many times we have retransmitted so far
111 */
112 u_int retransmitted;
113
114 /**
115 * packet for retransmission
116 */
117 packet_t *packet;
118
119 /**
120 * type of the initated exchange
121 */
122 exchange_type_t type;
123
124 } initiating;
125
126 /**
127 * List of queued tasks not yet in action
128 */
129 linked_list_t *queued_tasks;
130
131 /**
132 * List of active tasks, initiated by ourselve
133 */
134 linked_list_t *active_tasks;
135
136 /**
137 * List of tasks initiated by peer
138 */
139 linked_list_t *passive_tasks;
140
141 /**
142 * the task manager has been reset
143 */
144 bool reset;
145 };
146
147 /**
148 * flush all tasks in the task manager
149 */
150 static void flush(private_task_manager_t *this)
151 {
152 task_t *task;
153
154 this->queued_tasks->destroy_offset(this->queued_tasks,
155 offsetof(task_t, destroy));
156 this->passive_tasks->destroy_offset(this->passive_tasks,
157 offsetof(task_t, destroy));
158
159 /* emmit outstanding signals for tasks */
160 while (this->active_tasks->remove_last(this->active_tasks,
161 (void**)&task) == SUCCESS)
162 {
163 switch (task->get_type(task))
164 {
165 case IKE_AUTH:
166 SIG(IKE_UP_FAILED, "establishing IKE_SA failed");
167 break;
168 case IKE_DELETE:
169 SIG(IKE_DOWN_FAILED, "IKE_SA deleted");
170 break;
171 case IKE_REKEY:
172 SIG(IKE_REKEY_FAILED, "rekeying IKE_SA failed");
173 break;
174 case CHILD_CREATE:
175 SIG(CHILD_UP_FAILED, "establishing CHILD_SA failed");
176 break;
177 case CHILD_DELETE:
178 SIG(CHILD_DOWN_FAILED, "deleting CHILD_SA failed");
179 break;
180 case CHILD_REKEY:
181 SIG(IKE_REKEY_FAILED, "rekeying CHILD_SA failed");
182 break;
183 default:
184 break;
185 }
186 task->destroy(task);
187 }
188 this->queued_tasks = linked_list_create();
189 this->passive_tasks = linked_list_create();
190 }
191
192 /**
193 * move a task of a specific type from the queue to the active list
194 */
195 static bool activate_task(private_task_manager_t *this, task_type_t type)
196 {
197 iterator_t *iterator;
198 task_t *task;
199 bool found = FALSE;
200
201 iterator = this->queued_tasks->create_iterator(this->queued_tasks, TRUE);
202 while (iterator->iterate(iterator, (void**)&task))
203 {
204 if (task->get_type(task) == type)
205 {
206 DBG2(DBG_IKE, " activating %N task", task_type_names, type);
207 iterator->remove(iterator);
208 this->active_tasks->insert_last(this->active_tasks, task);
209 found = TRUE;
210 break;
211 }
212 }
213 iterator->destroy(iterator);
214 return found;
215 }
216
217 /**
218 * Implementation of task_manager_t.retransmit
219 */
220 static status_t retransmit(private_task_manager_t *this, u_int32_t message_id)
221 {
222 if (message_id == this->initiating.mid)
223 {
224 u_int32_t timeout;
225 job_t *job;
226 iterator_t *iterator;
227 packet_t *packet;
228 task_t *task;
229 ike_mobike_t *mobike = NULL;
230
231 /* check if we are retransmitting a MOBIKE routability check */
232 iterator = this->active_tasks->create_iterator(this->active_tasks, TRUE);
233 while (iterator->iterate(iterator, (void*)&task))
234 {
235 if (task->get_type(task) == IKE_MOBIKE)
236 {
237 mobike = (ike_mobike_t*)task;
238 if (!mobike->is_probing(mobike))
239 {
240 mobike = NULL;
241 }
242 break;
243 }
244 }
245 iterator->destroy(iterator);
246
247 if (mobike == NULL)
248 {
249 if (this->initiating.retransmitted <= RETRANSMIT_TRIES)
250 {
251 timeout = (u_int32_t)(RETRANSMIT_TIMEOUT *
252 pow(RETRANSMIT_BASE, this->initiating.retransmitted));
253 }
254 else
255 {
256 DBG1(DBG_IKE, "giving up after %d retransmits",
257 this->initiating.retransmitted - 1);
258 return DESTROY_ME;
259 }
260
261 if (this->initiating.retransmitted)
262 {
263 DBG1(DBG_IKE, "retransmit %d of request with message ID %d",
264 this->initiating.retransmitted, message_id);
265 }
266 packet = this->initiating.packet->clone(this->initiating.packet);
267 }
268 else
269 { /* for routeability checks, we use a more aggressive behavior */
270 if (this->initiating.retransmitted <= ROUTEABILITY_CHECK_TRIES)
271 {
272 timeout = ROUTEABILITY_CHECK_INTERVAL;
273 }
274 else
275 {
276 DBG1(DBG_IKE, "giving up after %d path probings",
277 this->initiating.retransmitted - 1);
278 return DESTROY_ME;
279 }
280
281 if (this->initiating.retransmitted)
282 {
283 DBG1(DBG_IKE, "path probing attempt %d",
284 this->initiating.retransmitted);
285 }
286 packet = this->initiating.packet->clone(this->initiating.packet);
287 mobike->transmit(mobike, packet);
288 }
289
290 charon->sender->send(charon->sender, packet);
291
292 this->initiating.retransmitted++;
293 job = (job_t*)retransmit_job_create(this->initiating.mid,
294 this->ike_sa->get_id(this->ike_sa));
295 charon->scheduler->schedule_job(charon->scheduler, job, timeout);
296 }
297 return SUCCESS;
298 }
299
300 /**
301 * build a request using the active task list
302 * Implementation of task_manager_t.initiate
303 */
304 static status_t build_request(private_task_manager_t *this)
305 {
306 iterator_t *iterator;
307 task_t *task;
308 message_t *message;
309 host_t *me, *other;
310 status_t status;
311 exchange_type_t exchange = 0;
312
313 if (this->initiating.type != EXCHANGE_TYPE_UNDEFINED)
314 {
315 DBG2(DBG_IKE, "delaying task initiation, exchange in progress");
316 /* do not initiate if we already have a message in the air */
317 return SUCCESS;
318 }
319
320 if (this->active_tasks->get_count(this->active_tasks) == 0)
321 {
322 DBG2(DBG_IKE, "activating new tasks");
323 switch (this->ike_sa->get_state(this->ike_sa))
324 {
325 case IKE_CREATED:
326 if (activate_task(this, IKE_INIT))
327 {
328 this->initiating.mid = 0;
329 exchange = IKE_SA_INIT;
330 activate_task(this, IKE_NATD);
331 activate_task(this, IKE_CERT);
332 #ifdef P2P
333 /* this task has to be activated before the IKE_AUTHENTICATE
334 * task, because that task pregenerates the packet after
335 * which no payloads can be added to the message anymore.
336 */
337 activate_task(this, IKE_P2P);
338 #endif /* P2P */
339 activate_task(this, IKE_AUTHENTICATE);
340 activate_task(this, IKE_CONFIG);
341 activate_task(this, CHILD_CREATE);
342 activate_task(this, IKE_AUTH_LIFETIME);
343 activate_task(this, IKE_MOBIKE);
344 }
345 break;
346 case IKE_ESTABLISHED:
347 if (activate_task(this, CHILD_CREATE))
348 {
349 exchange = CREATE_CHILD_SA;
350 break;
351 }
352 if (activate_task(this, CHILD_DELETE))
353 {
354 exchange = INFORMATIONAL;
355 break;
356 }
357 if (activate_task(this, CHILD_REKEY))
358 {
359 exchange = CREATE_CHILD_SA;
360 break;
361 }
362 if (activate_task(this, IKE_DELETE))
363 {
364 exchange = INFORMATIONAL;
365 break;
366 }
367 if (activate_task(this, IKE_REKEY))
368 {
369 exchange = CREATE_CHILD_SA;
370 break;
371 }
372 if (activate_task(this, IKE_REAUTH))
373 {
374 exchange = INFORMATIONAL;
375 break;
376 }
377 if (activate_task(this, IKE_MOBIKE))
378 {
379 exchange = INFORMATIONAL;
380 break;
381 }
382 if (activate_task(this, IKE_DPD))
383 {
384 exchange = INFORMATIONAL;
385 break;
386 }
387 #ifdef P2P
388 if (activate_task(this, IKE_P2P))
389 {
390 exchange = P2P_CONNECT;
391 break;
392 }
393 #endif /* P2P */
394 case IKE_REKEYING:
395 if (activate_task(this, IKE_DELETE))
396 {
397 exchange = INFORMATIONAL;
398 break;
399 }
400 case IKE_DELETING:
401 default:
402 break;
403 }
404 }
405 else
406 {
407 DBG2(DBG_IKE, "reinitiating already active tasks");
408 iterator = this->active_tasks->create_iterator(this->active_tasks, TRUE);
409 while (iterator->iterate(iterator, (void**)&task))
410 {
411 DBG2(DBG_IKE, " %N task", task_type_names, task->get_type(task));
412 switch (task->get_type(task))
413 {
414 case IKE_INIT:
415 exchange = IKE_SA_INIT;
416 break;
417 case IKE_AUTHENTICATE:
418 exchange = IKE_AUTH;
419 break;
420 case CHILD_CREATE:
421 case CHILD_REKEY:
422 case IKE_REKEY:
423 exchange = CREATE_CHILD_SA;
424 break;
425 case IKE_MOBIKE:
426 exchange = INFORMATIONAL;
427 default:
428 continue;
429 }
430 break;
431 }
432 iterator->destroy(iterator);
433 }
434
435 if (exchange == 0)
436 {
437 DBG2(DBG_IKE, "nothing to initiate");
438 /* nothing to do yet... */
439 return SUCCESS;
440 }
441
442 me = this->ike_sa->get_my_host(this->ike_sa);
443 other = this->ike_sa->get_other_host(this->ike_sa);
444
445 message = message_create();
446 message->set_message_id(message, this->initiating.mid);
447 message->set_source(message, me->clone(me));
448 message->set_destination(message, other->clone(other));
449 message->set_exchange_type(message, exchange);
450 this->initiating.type = exchange;
451 this->initiating.retransmitted = 0;
452
453 iterator = this->active_tasks->create_iterator(this->active_tasks, TRUE);
454 while (iterator->iterate(iterator, (void*)&task))
455 {
456 switch (task->build(task, message))
457 {
458 case SUCCESS:
459 /* task completed, remove it */
460 iterator->remove(iterator);
461 task->destroy(task);
462 break;
463 case NEED_MORE:
464 /* processed, but task needs another exchange */
465 break;
466 case FAILED:
467 default:
468 /* critical failure, destroy IKE_SA */
469 iterator->destroy(iterator);
470 message->destroy(message);
471 flush(this);
472 return DESTROY_ME;
473 }
474 }
475 iterator->destroy(iterator);
476
477 DESTROY_IF(this->initiating.packet);
478 status = this->ike_sa->generate_message(this->ike_sa, message,
479 &this->initiating.packet);
480 message->destroy(message);
481 if (status != SUCCESS)
482 {
483 /* message generation failed. There is nothing more to do than to
484 * close the SA */
485 flush(this);
486 return DESTROY_ME;
487 }
488
489 return retransmit(this, this->initiating.mid);
490 }
491
492 /**
493 * handle an incoming response message
494 */
495 static status_t process_response(private_task_manager_t *this,
496 message_t *message)
497 {
498 iterator_t *iterator;
499 task_t *task;
500
501 if (message->get_exchange_type(message) != this->initiating.type)
502 {
503 DBG1(DBG_IKE, "received %N response, but expected %N",
504 exchange_type_names, message->get_exchange_type(message),
505 exchange_type_names, this->initiating.type);
506 return DESTROY_ME;
507 }
508
509 /* catch if we get resetted while processing */
510 this->reset = FALSE;
511 iterator = this->active_tasks->create_iterator(this->active_tasks, TRUE);
512 while (iterator->iterate(iterator, (void*)&task))
513 {
514 switch (task->process(task, message))
515 {
516 case SUCCESS:
517 /* task completed, remove it */
518 iterator->remove(iterator);
519 task->destroy(task);
520 break;
521 case NEED_MORE:
522 /* processed, but task needs another exchange */
523 break;
524 case FAILED:
525 default:
526 /* critical failure, destroy IKE_SA */
527 iterator->destroy(iterator);
528 return DESTROY_ME;
529 }
530 if (this->reset)
531 { /* start all over again if we were reset */
532 this->reset = FALSE;
533 iterator->destroy(iterator);
534 return build_request(this);
535 }
536 }
537 iterator->destroy(iterator);
538
539 this->initiating.mid++;
540 this->initiating.type = EXCHANGE_TYPE_UNDEFINED;
541
542 return build_request(this);
543 }
544
545 /**
546 * handle exchange collisions
547 */
548 static void handle_collisions(private_task_manager_t *this, task_t *task)
549 {
550 iterator_t *iterator;
551 task_t *active;
552 task_type_t type;
553
554 type = task->get_type(task);
555
556 /* do we have to check */
557 if (type == IKE_REKEY || type == CHILD_REKEY ||
558 type == CHILD_DELETE || type == IKE_DELETE || type == IKE_REAUTH)
559 {
560 /* find an exchange collision, and notify these tasks */
561 iterator = this->active_tasks->create_iterator(this->active_tasks, TRUE);
562 while (iterator->iterate(iterator, (void**)&active))
563 {
564 switch (active->get_type(active))
565 {
566 case IKE_REKEY:
567 if (type == IKE_REKEY || type == IKE_DELETE ||
568 type == IKE_REAUTH)
569 {
570 ike_rekey_t *rekey = (ike_rekey_t*)active;
571 rekey->collide(rekey, task);
572 break;
573 }
574 continue;
575 case CHILD_REKEY:
576 if (type == CHILD_REKEY || type == CHILD_DELETE)
577 {
578 child_rekey_t *rekey = (child_rekey_t*)active;
579 rekey->collide(rekey, task);
580 break;
581 }
582 continue;
583 default:
584 continue;
585 }
586 iterator->destroy(iterator);
587 return;
588 }
589 iterator->destroy(iterator);
590 }
591 /* destroy task if not registered in any active task */
592 task->destroy(task);
593 }
594
595 /**
596 * build a response depending on the "passive" task list
597 */
598 static status_t build_response(private_task_manager_t *this, message_t *request)
599 {
600 iterator_t *iterator;
601 task_t *task;
602 message_t *message;
603 host_t *me, *other;
604 bool delete = FALSE;
605 status_t status;
606
607 me = request->get_destination(request);
608 other = request->get_source(request);
609
610 message = message_create();
611 message->set_exchange_type(message, request->get_exchange_type(request));
612 /* send response along the path the request came in */
613 message->set_source(message, me->clone(me));
614 message->set_destination(message, other->clone(other));
615 message->set_message_id(message, this->responding.mid);
616 message->set_request(message, FALSE);
617
618 iterator = this->passive_tasks->create_iterator(this->passive_tasks, TRUE);
619 while (iterator->iterate(iterator, (void*)&task))
620 {
621 switch (task->build(task, message))
622 {
623 case SUCCESS:
624 /* task completed, remove it */
625 iterator->remove(iterator);
626 handle_collisions(this, task);
627 case NEED_MORE:
628 /* processed, but task needs another exchange */
629 break;
630 case FAILED:
631 default:
632 /* destroy IKE_SA, but SEND response first */
633 delete = TRUE;
634 break;
635 }
636 if (delete)
637 {
638 break;
639 }
640 }
641 iterator->destroy(iterator);
642
643 /* remove resonder SPI if IKE_SA_INIT failed */
644 if (delete && request->get_exchange_type(request) == IKE_SA_INIT)
645 {
646 ike_sa_id_t *id = this->ike_sa->get_id(this->ike_sa);
647 id->set_responder_spi(id, 0);
648 }
649
650 /* message complete, send it */
651 DESTROY_IF(this->responding.packet);
652 status = this->ike_sa->generate_message(this->ike_sa, message,
653 &this->responding.packet);
654 message->destroy(message);
655 if (status != SUCCESS)
656 {
657 return DESTROY_ME;
658 }
659
660 charon->sender->send(charon->sender,
661 this->responding.packet->clone(this->responding.packet));
662 if (delete)
663 {
664 return DESTROY_ME;
665 }
666 return SUCCESS;
667 }
668
669 /**
670 * handle an incoming request message
671 */
672 static status_t process_request(private_task_manager_t *this,
673 message_t *message)
674 {
675 iterator_t *iterator;
676 task_t *task = NULL;
677 payload_t *payload;
678 notify_payload_t *notify;
679 delete_payload_t *delete;
680
681 /* create tasks depending on request type */
682 switch (message->get_exchange_type(message))
683 {
684 case IKE_SA_INIT:
685 {
686 task = (task_t*)ike_init_create(this->ike_sa, FALSE, NULL);
687 this->passive_tasks->insert_last(this->passive_tasks, task);
688 task = (task_t*)ike_natd_create(this->ike_sa, FALSE);
689 this->passive_tasks->insert_last(this->passive_tasks, task);
690 task = (task_t*)ike_cert_create(this->ike_sa, FALSE);
691 this->passive_tasks->insert_last(this->passive_tasks, task);
692 #ifdef P2P
693 task = (task_t*)ike_p2p_create(this->ike_sa, FALSE);
694 this->passive_tasks->insert_last(this->passive_tasks, task);
695 #endif /* P2P */
696 task = (task_t*)ike_auth_create(this->ike_sa, FALSE);
697 this->passive_tasks->insert_last(this->passive_tasks, task);
698 task = (task_t*)ike_config_create(this->ike_sa, FALSE);
699 this->passive_tasks->insert_last(this->passive_tasks, task);
700 task = (task_t*)child_create_create(this->ike_sa, NULL);
701 this->passive_tasks->insert_last(this->passive_tasks, task);
702 task = (task_t*)ike_auth_lifetime_create(this->ike_sa, FALSE);
703 this->passive_tasks->insert_last(this->passive_tasks, task);
704 task = (task_t*)ike_mobike_create(this->ike_sa, FALSE);
705 this->passive_tasks->insert_last(this->passive_tasks, task);
706 break;
707 }
708 case CREATE_CHILD_SA:
709 {//FIXME: we should prevent this on mediation connections
710 bool notify_found = FALSE, ts_found = FALSE;
711 iterator = message->get_payload_iterator(message);
712 while (iterator->iterate(iterator, (void**)&payload))
713 {
714 switch (payload->get_type(payload))
715 {
716 case NOTIFY:
717 {
718 /* if we find a rekey notify, its CHILD_SA rekeying */
719 notify = (notify_payload_t*)payload;
720 if (notify->get_notify_type(notify) == REKEY_SA &&
721 (notify->get_protocol_id(notify) == PROTO_AH ||
722 notify->get_protocol_id(notify) == PROTO_ESP))
723 {
724 notify_found = TRUE;
725 }
726 break;
727 }
728 case TRAFFIC_SELECTOR_INITIATOR:
729 case TRAFFIC_SELECTOR_RESPONDER:
730 {
731 /* if we don't find a TS, its IKE rekeying */
732 ts_found = TRUE;
733 break;
734 }
735 default:
736 break;
737 }
738 }
739 iterator->destroy(iterator);
740
741 if (ts_found)
742 {
743 if (notify_found)
744 {
745 task = (task_t*)child_rekey_create(this->ike_sa, NULL);
746 }
747 else
748 {
749 task = (task_t*)child_create_create(this->ike_sa, NULL);
750 }
751 }
752 else
753 {
754 task = (task_t*)ike_rekey_create(this->ike_sa, FALSE);
755 }
756 this->passive_tasks->insert_last(this->passive_tasks, task);
757 break;
758 }
759 case INFORMATIONAL:
760 {
761 iterator = message->get_payload_iterator(message);
762 while (iterator->iterate(iterator, (void**)&payload))
763 {
764 switch (payload->get_type(payload))
765 {
766 case NOTIFY:
767 {
768 notify = (notify_payload_t*)payload;
769 switch (notify->get_notify_type(notify))
770 {
771 case ADDITIONAL_IP4_ADDRESS:
772 case ADDITIONAL_IP6_ADDRESS:
773 case NO_ADDITIONAL_ADDRESSES:
774 case UPDATE_SA_ADDRESSES:
775 case NO_NATS_ALLOWED:
776 case UNACCEPTABLE_ADDRESSES:
777 case UNEXPECTED_NAT_DETECTED:
778 case COOKIE2:
779 task = (task_t*)ike_mobike_create(
780 this->ike_sa, FALSE);
781 break;
782 case AUTH_LIFETIME:
783 task = (task_t*)ike_auth_lifetime_create(
784 this->ike_sa, FALSE);
785 break;
786 default:
787 break;
788 }
789 break;
790 }
791 case DELETE:
792 {
793 delete = (delete_payload_t*)payload;
794 if (delete->get_protocol_id(delete) == PROTO_IKE)
795 {
796 task = (task_t*)ike_delete_create(this->ike_sa, FALSE);
797 }
798 else
799 {
800 task = (task_t*)child_delete_create(this->ike_sa, NULL);
801 }
802 break;
803 }
804 default:
805 break;
806 }
807 if (task)
808 {
809 break;
810 }
811 }
812 iterator->destroy(iterator);
813
814 if (task == NULL)
815 {
816 task = (task_t*)ike_dpd_create(FALSE);
817 }
818 this->passive_tasks->insert_last(this->passive_tasks, task);
819 break;
820 }
821 #ifdef P2P
822 case P2P_CONNECT:
823 {
824 task = (task_t*)ike_p2p_create(this->ike_sa, FALSE);
825 this->passive_tasks->insert_last(this->passive_tasks, task);
826 }
827 #endif /* P2P */
828 default:
829 break;
830 }
831
832 /* let the tasks process the message */
833 iterator = this->passive_tasks->create_iterator(this->passive_tasks, TRUE);
834 while (iterator->iterate(iterator, (void*)&task))
835 {
836 switch (task->process(task, message))
837 {
838 case SUCCESS:
839 /* task completed, remove it */
840 iterator->remove(iterator);
841 task->destroy(task);
842 break;
843 case NEED_MORE:
844 /* processed, but task needs at least another call to build() */
845 break;
846 case FAILED:
847 default:
848 /* critical failure, destroy IKE_SA */
849 iterator->destroy(iterator);
850 return DESTROY_ME;
851 }
852 }
853 iterator->destroy(iterator);
854
855 return build_response(this, message);
856 }
857
858 /**
859 * Implementation of task_manager_t.process_message
860 */
861 static status_t process_message(private_task_manager_t *this, message_t *msg)
862 {
863 u_int32_t mid = msg->get_message_id(msg);
864
865 if (msg->get_request(msg))
866 {
867 if (mid == this->responding.mid)
868 {
869 if (process_request(this, msg) != SUCCESS)
870 {
871 flush(this);
872 return DESTROY_ME;
873 }
874 this->responding.mid++;
875 }
876 else if ((mid == this->responding.mid - 1) && this->responding.packet)
877 {
878 packet_t *clone;
879 host_t *me, *other;
880
881 DBG1(DBG_IKE, "received retransmit of request with ID %d, "
882 "retransmitting response", mid);
883 clone = this->responding.packet->clone(this->responding.packet);
884 me = msg->get_destination(msg);
885 other = msg->get_source(msg);
886 clone->set_source(clone, me->clone(me));
887 clone->set_destination(clone, other->clone(other));
888 charon->sender->send(charon->sender, clone);
889 }
890 else
891 {
892 DBG1(DBG_IKE, "received message ID %d, expected %d. Ignored",
893 mid, this->responding.mid);
894 }
895 }
896 else
897 {
898 if (mid == this->initiating.mid)
899 {
900 if (process_response(this, msg) != SUCCESS)
901 {
902 flush(this);
903 return DESTROY_ME;
904 }
905 }
906 else
907 {
908 DBG1(DBG_IKE, "received message ID %d, expected %d. Ignored",
909 mid, this->initiating.mid);
910 return SUCCESS;
911 }
912 }
913 return SUCCESS;
914 }
915
916 /**
917 * Implementation of task_manager_t.queue_task
918 */
919 static void queue_task(private_task_manager_t *this, task_t *task)
920 {
921 if (task->get_type(task) == IKE_MOBIKE)
922 { /* there is no need to queue more than one mobike task */
923 iterator_t *iterator;
924 task_t *current;
925
926 iterator = this->queued_tasks->create_iterator(this->queued_tasks, TRUE);
927 while (iterator->iterate(iterator, (void**)&current))
928 {
929 if (current->get_type(current) == IKE_MOBIKE)
930 {
931 iterator->destroy(iterator);
932 task->destroy(task);
933 return;
934 }
935 }
936 iterator->destroy(iterator);
937 }
938 DBG2(DBG_IKE, "queueing %N task", task_type_names, task->get_type(task));
939 this->queued_tasks->insert_last(this->queued_tasks, task);
940 }
941
942 /**
943 * Implementation of task_manager_t.adopt_tasks
944 */
945 static void adopt_tasks(private_task_manager_t *this, private_task_manager_t *other)
946 {
947 task_t *task;
948
949 /* move queued tasks from other to this */
950 while (other->queued_tasks->remove_last(other->queued_tasks,
951 (void**)&task) == SUCCESS)
952 {
953 DBG2(DBG_IKE, "migrating %N task", task_type_names, task->get_type(task));
954 task->migrate(task, this->ike_sa);
955 this->queued_tasks->insert_first(this->queued_tasks, task);
956 }
957
958 /* reset active tasks and move them to others queued tasks */
959 while (other->active_tasks->remove_last(other->active_tasks,
960 (void**)&task) == SUCCESS)
961 {
962 DBG2(DBG_IKE, "migrating %N task", task_type_names, task->get_type(task));
963 task->migrate(task, this->ike_sa);
964 this->queued_tasks->insert_first(this->queued_tasks, task);
965 }
966 }
967
968 /**
969 * Implementation of task_manager_t.busy
970 */
971 static bool busy(private_task_manager_t *this)
972 {
973 return (this->active_tasks->get_count(this->active_tasks) > 0);
974 }
975
976 /**
977 * Implementation of task_manager_t.reset
978 */
979 static void reset(private_task_manager_t *this)
980 {
981 task_t *task;
982
983 /* reset message counters and retransmit packets */
984 DESTROY_IF(this->responding.packet);
985 DESTROY_IF(this->initiating.packet);
986 this->responding.packet = NULL;
987 this->initiating.packet = NULL;
988 this->responding.mid = 0;
989 this->initiating.mid = 0;
990 this->initiating.type = EXCHANGE_TYPE_UNDEFINED;
991
992 /* reset active tasks */
993 while (this->active_tasks->remove_last(this->active_tasks,
994 (void**)&task) == SUCCESS)
995 {
996 task->migrate(task, this->ike_sa);
997 this->queued_tasks->insert_first(this->queued_tasks, task);
998 }
999
1000 this->reset = TRUE;
1001 }
1002
1003 /**
1004 * Implementation of task_manager_t.destroy
1005 */
1006 static void destroy(private_task_manager_t *this)
1007 {
1008 flush(this);
1009
1010 this->active_tasks->destroy(this->active_tasks);
1011 this->queued_tasks->destroy(this->queued_tasks);
1012 this->passive_tasks->destroy(this->passive_tasks);
1013
1014 DESTROY_IF(this->responding.packet);
1015 DESTROY_IF(this->initiating.packet);
1016 free(this);
1017 }
1018
1019 /*
1020 * see header file
1021 */
1022 task_manager_t *task_manager_create(ike_sa_t *ike_sa)
1023 {
1024 private_task_manager_t *this = malloc_thing(private_task_manager_t);
1025
1026 this->public.process_message = (status_t(*)(task_manager_t*,message_t*))process_message;
1027 this->public.queue_task = (void(*)(task_manager_t*,task_t*))queue_task;
1028 this->public.initiate = (status_t(*)(task_manager_t*))build_request;
1029 this->public.retransmit = (status_t(*)(task_manager_t*,u_int32_t))retransmit;
1030 this->public.reset = (void(*)(task_manager_t*))reset;
1031 this->public.adopt_tasks = (void(*)(task_manager_t*,task_manager_t*))adopt_tasks;
1032 this->public.busy = (bool(*)(task_manager_t*))busy;
1033 this->public.destroy = (void(*)(task_manager_t*))destroy;
1034
1035 this->ike_sa = ike_sa;
1036 this->responding.packet = NULL;
1037 this->initiating.packet = NULL;
1038 this->responding.mid = 0;
1039 this->initiating.mid = 0;
1040 this->initiating.type = EXCHANGE_TYPE_UNDEFINED;
1041 this->queued_tasks = linked_list_create();
1042 this->active_tasks = linked_list_create();
1043 this->passive_tasks = linked_list_create();
1044 this->reset = FALSE;
1045
1046 return &this->public;
1047 }