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