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