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