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