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