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