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