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