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