7cdcf7052dac7ff06020593507471388dbb792df
[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->passive_tasks->destroy_offset(this->passive_tasks,
163 offsetof(task_t, destroy));
164 this->passive_tasks = linked_list_create();
165 this->active_tasks->destroy_offset(this->active_tasks,
166 offsetof(task_t, destroy));
167 this->active_tasks = linked_list_create();
168 this->queued_tasks->destroy_offset(this->queued_tasks,
169 offsetof(task_t, destroy));
170 this->queued_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 enumerator_t *enumerator;
179 task_t *task;
180 bool found = FALSE;
181
182 enumerator = this->queued_tasks->create_enumerator(this->queued_tasks);
183 while (enumerator->enumerate(enumerator, (void**)&task))
184 {
185 if (task->get_type(task) == type)
186 {
187 DBG2(DBG_IKE, " activating %N task", task_type_names, type);
188 this->queued_tasks->remove_at(this->queued_tasks, enumerator);
189 this->active_tasks->insert_last(this->active_tasks, task);
190 found = TRUE;
191 break;
192 }
193 }
194 enumerator->destroy(enumerator);
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 enumerator_t *enumerator;
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 enumerator = this->active_tasks->create_enumerator(this->active_tasks);
212 while (enumerator->enumerate(enumerator, (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 enumerator->destroy(enumerator);
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 enumerator_t *enumerator;
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 if (activate_task(this, IKE_AUTH_LIFETIME))
370 {
371 exchange = INFORMATIONAL;
372 break;
373 }
374 #ifdef ME
375 if (activate_task(this, IKE_ME))
376 {
377 exchange = ME_CONNECT;
378 break;
379 }
380 #endif /* ME */
381 case IKE_REKEYING:
382 if (activate_task(this, IKE_DELETE))
383 {
384 exchange = INFORMATIONAL;
385 break;
386 }
387 case IKE_DELETING:
388 default:
389 break;
390 }
391 }
392 else
393 {
394 DBG2(DBG_IKE, "reinitiating already active tasks");
395 enumerator = this->active_tasks->create_enumerator(this->active_tasks);
396 while (enumerator->enumerate(enumerator, (void**)&task))
397 {
398 DBG2(DBG_IKE, " %N task", task_type_names, task->get_type(task));
399 switch (task->get_type(task))
400 {
401 case IKE_INIT:
402 exchange = IKE_SA_INIT;
403 break;
404 case IKE_AUTHENTICATE:
405 exchange = IKE_AUTH;
406 break;
407 case CHILD_CREATE:
408 case CHILD_REKEY:
409 case IKE_REKEY:
410 exchange = CREATE_CHILD_SA;
411 break;
412 case IKE_MOBIKE:
413 exchange = INFORMATIONAL;
414 break;
415 default:
416 continue;
417 }
418 break;
419 }
420 enumerator->destroy(enumerator);
421 }
422
423 if (exchange == 0)
424 {
425 DBG2(DBG_IKE, "nothing to initiate");
426 /* nothing to do yet... */
427 return SUCCESS;
428 }
429
430 me = this->ike_sa->get_my_host(this->ike_sa);
431 other = this->ike_sa->get_other_host(this->ike_sa);
432
433 message = message_create();
434 message->set_message_id(message, this->initiating.mid);
435 message->set_source(message, me->clone(me));
436 message->set_destination(message, other->clone(other));
437 message->set_exchange_type(message, exchange);
438 this->initiating.type = exchange;
439 this->initiating.retransmitted = 0;
440
441 enumerator = this->active_tasks->create_enumerator(this->active_tasks);
442 while (enumerator->enumerate(enumerator, (void*)&task))
443 {
444 switch (task->build(task, message))
445 {
446 case SUCCESS:
447 /* task completed, remove it */
448 this->active_tasks->remove_at(this->active_tasks, enumerator);
449 task->destroy(task);
450 break;
451 case NEED_MORE:
452 /* processed, but task needs another exchange */
453 break;
454 case FAILED:
455 default:
456 if (this->ike_sa->get_state(this->ike_sa) != IKE_CONNECTING)
457 {
458 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
459 }
460 /* FALL */
461 case DESTROY_ME:
462 /* critical failure, destroy IKE_SA */
463 enumerator->destroy(enumerator);
464 message->destroy(message);
465 flush(this);
466 return DESTROY_ME;
467 }
468 }
469 enumerator->destroy(enumerator);
470
471 /* update exchange type if a task changed it */
472 this->initiating.type = message->get_exchange_type(message);
473
474 status = this->ike_sa->generate_message(this->ike_sa, message,
475 &this->initiating.packet);
476 if (status != SUCCESS)
477 {
478 /* message generation failed. There is nothing more to do than to
479 * close the SA */
480 message->destroy(message);
481 flush(this);
482 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
483 return DESTROY_ME;
484 }
485 message->destroy(message);
486
487 return retransmit(this, this->initiating.mid);
488 }
489
490 /**
491 * handle an incoming response message
492 */
493 static status_t process_response(private_task_manager_t *this,
494 message_t *message)
495 {
496 enumerator_t *enumerator;
497 task_t *task;
498
499 if (message->get_exchange_type(message) != this->initiating.type)
500 {
501 DBG1(DBG_IKE, "received %N response, but expected %N",
502 exchange_type_names, message->get_exchange_type(message),
503 exchange_type_names, this->initiating.type);
504 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
505 return DESTROY_ME;
506 }
507
508 /* catch if we get resetted while processing */
509 this->reset = FALSE;
510 enumerator = this->active_tasks->create_enumerator(this->active_tasks);
511 while (enumerator->enumerate(enumerator, (void*)&task))
512 {
513 switch (task->process(task, message))
514 {
515 case SUCCESS:
516 /* task completed, remove it */
517 this->active_tasks->remove_at(this->active_tasks, enumerator);
518 task->destroy(task);
519 break;
520 case NEED_MORE:
521 /* processed, but task needs another exchange */
522 break;
523 case FAILED:
524 default:
525 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
526 /* FALL */
527 case DESTROY_ME:
528 /* critical failure, destroy IKE_SA */
529 this->active_tasks->remove_at(this->active_tasks, enumerator);
530 enumerator->destroy(enumerator);
531 task->destroy(task);
532 return DESTROY_ME;
533 }
534 if (this->reset)
535 { /* start all over again if we were reset */
536 this->reset = FALSE;
537 enumerator->destroy(enumerator);
538 return initiate(this);
539 }
540 }
541 enumerator->destroy(enumerator);
542
543 this->initiating.mid++;
544 this->initiating.type = EXCHANGE_TYPE_UNDEFINED;
545 this->initiating.packet->destroy(this->initiating.packet);
546 this->initiating.packet = NULL;
547
548 return initiate(this);
549 }
550
551 /**
552 * handle exchange collisions
553 */
554 static bool handle_collisions(private_task_manager_t *this, task_t *task)
555 {
556 enumerator_t *enumerator;
557 task_t *active;
558 task_type_t type;
559
560 type = task->get_type(task);
561
562 /* do we have to check */
563 if (type == IKE_REKEY || type == CHILD_REKEY ||
564 type == CHILD_DELETE || type == IKE_DELETE || type == IKE_REAUTH)
565 {
566 /* find an exchange collision, and notify these tasks */
567 enumerator = this->active_tasks->create_enumerator(this->active_tasks);
568 while (enumerator->enumerate(enumerator, (void**)&active))
569 {
570 switch (active->get_type(active))
571 {
572 case IKE_REKEY:
573 if (type == IKE_REKEY || type == IKE_DELETE ||
574 type == IKE_REAUTH)
575 {
576 ike_rekey_t *rekey = (ike_rekey_t*)active;
577 rekey->collide(rekey, task);
578 break;
579 }
580 continue;
581 case CHILD_REKEY:
582 if (type == CHILD_REKEY || type == CHILD_DELETE)
583 {
584 child_rekey_t *rekey = (child_rekey_t*)active;
585 rekey->collide(rekey, task);
586 break;
587 }
588 continue;
589 default:
590 continue;
591 }
592 enumerator->destroy(enumerator);
593 return TRUE;
594 }
595 enumerator->destroy(enumerator);
596 }
597 return FALSE;
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 enumerator_t *enumerator;
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 enumerator = this->passive_tasks->create_enumerator(this->passive_tasks);
624 while (enumerator->enumerate(enumerator, (void*)&task))
625 {
626 switch (task->build(task, message))
627 {
628 case SUCCESS:
629 /* task completed, remove it */
630 this->passive_tasks->remove_at(this->passive_tasks, enumerator);
631 if (!handle_collisions(this, task))
632 {
633 task->destroy(task);
634 }
635 break;
636 case NEED_MORE:
637 /* processed, but task needs another exchange */
638 if (handle_collisions(this, task))
639 {
640 this->passive_tasks->remove_at(this->passive_tasks,
641 enumerator);
642 }
643 break;
644 case FAILED:
645 default:
646 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
647 /* FALL */
648 case DESTROY_ME:
649 /* destroy IKE_SA, but SEND response first */
650 delete = TRUE;
651 break;
652 }
653 if (delete)
654 {
655 break;
656 }
657 }
658 enumerator->destroy(enumerator);
659
660 /* remove resonder SPI if IKE_SA_INIT failed */
661 if (delete && request->get_exchange_type(request) == IKE_SA_INIT)
662 {
663 ike_sa_id_t *id = this->ike_sa->get_id(this->ike_sa);
664 id->set_responder_spi(id, 0);
665 }
666
667 /* message complete, send it */
668 DESTROY_IF(this->responding.packet);
669 this->responding.packet = NULL;
670 status = this->ike_sa->generate_message(this->ike_sa, message,
671 &this->responding.packet);
672 message->destroy(message);
673 if (status != SUCCESS)
674 {
675 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
676 return DESTROY_ME;
677 }
678
679 charon->sender->send(charon->sender,
680 this->responding.packet->clone(this->responding.packet));
681 if (delete)
682 {
683 return DESTROY_ME;
684 }
685 return SUCCESS;
686 }
687
688 /**
689 * handle an incoming request message
690 */
691 static status_t process_request(private_task_manager_t *this,
692 message_t *message)
693 {
694 enumerator_t *enumerator;
695 task_t *task = NULL;
696 payload_t *payload;
697 notify_payload_t *notify;
698 delete_payload_t *delete;
699
700 if (this->passive_tasks->get_count(this->passive_tasks) == 0)
701 { /* create tasks depending on request type, if not already some queued */
702 switch (message->get_exchange_type(message))
703 {
704 case IKE_SA_INIT:
705 {
706 task = (task_t*)ike_vendor_create(this->ike_sa, FALSE);
707 this->passive_tasks->insert_last(this->passive_tasks, task);
708 task = (task_t*)ike_init_create(this->ike_sa, FALSE, NULL);
709 this->passive_tasks->insert_last(this->passive_tasks, task);
710 task = (task_t*)ike_natd_create(this->ike_sa, FALSE);
711 this->passive_tasks->insert_last(this->passive_tasks, task);
712 task = (task_t*)ike_cert_pre_create(this->ike_sa, FALSE);
713 this->passive_tasks->insert_last(this->passive_tasks, task);
714 #ifdef ME
715 task = (task_t*)ike_me_create(this->ike_sa, FALSE);
716 this->passive_tasks->insert_last(this->passive_tasks, task);
717 #endif /* ME */
718 task = (task_t*)ike_auth_create(this->ike_sa, FALSE);
719 this->passive_tasks->insert_last(this->passive_tasks, task);
720 task = (task_t*)ike_cert_post_create(this->ike_sa, FALSE);
721 this->passive_tasks->insert_last(this->passive_tasks, task);
722 task = (task_t*)ike_config_create(this->ike_sa, FALSE);
723 this->passive_tasks->insert_last(this->passive_tasks, task);
724 task = (task_t*)child_create_create(this->ike_sa, NULL, FALSE,
725 NULL, NULL);
726 this->passive_tasks->insert_last(this->passive_tasks, task);
727 task = (task_t*)ike_auth_lifetime_create(this->ike_sa, FALSE);
728 this->passive_tasks->insert_last(this->passive_tasks, task);
729 task = (task_t*)ike_mobike_create(this->ike_sa, FALSE);
730 this->passive_tasks->insert_last(this->passive_tasks, task);
731 break;
732 }
733 case CREATE_CHILD_SA:
734 { /* FIXME: we should prevent this on mediation connections */
735 bool notify_found = FALSE, ts_found = FALSE;
736 enumerator = message->create_payload_enumerator(message);
737 while (enumerator->enumerate(enumerator, &payload))
738 {
739 switch (payload->get_type(payload))
740 {
741 case NOTIFY:
742 { /* if we find a rekey notify, its CHILD_SA rekeying */
743 notify = (notify_payload_t*)payload;
744 if (notify->get_notify_type(notify) == REKEY_SA &&
745 (notify->get_protocol_id(notify) == PROTO_AH ||
746 notify->get_protocol_id(notify) == PROTO_ESP))
747 {
748 notify_found = TRUE;
749 }
750 break;
751 }
752 case TRAFFIC_SELECTOR_INITIATOR:
753 case TRAFFIC_SELECTOR_RESPONDER:
754 { /* if we don't find a TS, its IKE rekeying */
755 ts_found = TRUE;
756 break;
757 }
758 default:
759 break;
760 }
761 }
762 enumerator->destroy(enumerator);
763
764 if (ts_found)
765 {
766 if (notify_found)
767 {
768 task = (task_t*)child_rekey_create(this->ike_sa,
769 PROTO_NONE, 0);
770 }
771 else
772 {
773 task = (task_t*)child_create_create(this->ike_sa, NULL,
774 FALSE, NULL, NULL);
775 }
776 }
777 else
778 {
779 task = (task_t*)ike_rekey_create(this->ike_sa, FALSE);
780 }
781 this->passive_tasks->insert_last(this->passive_tasks, task);
782 break;
783 }
784 case INFORMATIONAL:
785 {
786 enumerator = message->create_payload_enumerator(message);
787 while (enumerator->enumerate(enumerator, &payload))
788 {
789 switch (payload->get_type(payload))
790 {
791 case NOTIFY:
792 {
793 notify = (notify_payload_t*)payload;
794 switch (notify->get_notify_type(notify))
795 {
796 case ADDITIONAL_IP4_ADDRESS:
797 case ADDITIONAL_IP6_ADDRESS:
798 case NO_ADDITIONAL_ADDRESSES:
799 case UPDATE_SA_ADDRESSES:
800 case NO_NATS_ALLOWED:
801 case UNACCEPTABLE_ADDRESSES:
802 case UNEXPECTED_NAT_DETECTED:
803 case COOKIE2:
804 case NAT_DETECTION_SOURCE_IP:
805 case NAT_DETECTION_DESTINATION_IP:
806 task = (task_t*)ike_mobike_create(
807 this->ike_sa, FALSE);
808 break;
809 case AUTH_LIFETIME:
810 task = (task_t*)ike_auth_lifetime_create(
811 this->ike_sa, FALSE);
812 break;
813 default:
814 break;
815 }
816 break;
817 }
818 case DELETE:
819 {
820 delete = (delete_payload_t*)payload;
821 if (delete->get_protocol_id(delete) == PROTO_IKE)
822 {
823 task = (task_t*)ike_delete_create(this->ike_sa,
824 FALSE);
825 }
826 else
827 {
828 task = (task_t*)child_delete_create(this->ike_sa,
829 PROTO_NONE, 0);
830 }
831 break;
832 }
833 default:
834 break;
835 }
836 if (task)
837 {
838 break;
839 }
840 }
841 enumerator->destroy(enumerator);
842
843 if (task == NULL)
844 {
845 task = (task_t*)ike_dpd_create(FALSE);
846 }
847 this->passive_tasks->insert_last(this->passive_tasks, task);
848 break;
849 }
850 #ifdef ME
851 case ME_CONNECT:
852 {
853 task = (task_t*)ike_me_create(this->ike_sa, FALSE);
854 this->passive_tasks->insert_last(this->passive_tasks, task);
855 }
856 #endif /* ME */
857 default:
858 break;
859 }
860 }
861
862 /* let the tasks process the message */
863 enumerator = this->passive_tasks->create_enumerator(this->passive_tasks);
864 while (enumerator->enumerate(enumerator, (void*)&task))
865 {
866 switch (task->process(task, message))
867 {
868 case SUCCESS:
869 /* task completed, remove it */
870 this->passive_tasks->remove_at(this->passive_tasks, enumerator);
871 task->destroy(task);
872 break;
873 case NEED_MORE:
874 /* processed, but task needs at least another call to build() */
875 break;
876 case FAILED:
877 default:
878 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
879 /* FALL */
880 case DESTROY_ME:
881 /* critical failure, destroy IKE_SA */
882 this->passive_tasks->remove_at(this->passive_tasks, enumerator);
883 enumerator->destroy(enumerator);
884 task->destroy(task);
885 return DESTROY_ME;
886 }
887 }
888 enumerator->destroy(enumerator);
889
890 return build_response(this, message);
891 }
892
893 METHOD(task_manager_t, process_message, status_t,
894 private_task_manager_t *this, message_t *msg)
895 {
896 host_t *me, *other;
897 u_int32_t mid;
898
899 mid = msg->get_message_id(msg);
900 me = msg->get_destination(msg);
901 other = msg->get_source(msg);
902
903 if (msg->get_request(msg))
904 {
905 if (mid == this->responding.mid)
906 {
907 if (this->ike_sa->get_state(this->ike_sa) == IKE_CREATED ||
908 this->ike_sa->get_state(this->ike_sa) == IKE_CONNECTING ||
909 msg->get_exchange_type(msg) != IKE_SA_INIT)
910 { /* only do host updates based on verified messages */
911 if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE))
912 { /* with MOBIKE, we do no implicit updates */
913 this->ike_sa->update_hosts(this->ike_sa, me, other, mid == 1);
914 }
915 }
916 charon->bus->message(charon->bus, msg, TRUE);
917 if (msg->get_exchange_type(msg) == EXCHANGE_TYPE_UNDEFINED)
918 { /* ignore messages altered to EXCHANGE_TYPE_UNDEFINED */
919 return SUCCESS;
920 }
921 if (process_request(this, msg) != SUCCESS)
922 {
923 flush(this);
924 return DESTROY_ME;
925 }
926 this->responding.mid++;
927 }
928 else if ((mid == this->responding.mid - 1) && this->responding.packet)
929 {
930 packet_t *clone;
931 host_t *host;
932
933 DBG1(DBG_IKE, "received retransmit of request with ID %d, "
934 "retransmitting response", mid);
935 clone = this->responding.packet->clone(this->responding.packet);
936 host = msg->get_destination(msg);
937 clone->set_source(clone, host->clone(host));
938 host = msg->get_source(msg);
939 clone->set_destination(clone, host->clone(host));
940 charon->sender->send(charon->sender, clone);
941 }
942 else
943 {
944 DBG1(DBG_IKE, "received message ID %d, expected %d. Ignored",
945 mid, this->responding.mid);
946 }
947 }
948 else
949 {
950 if (mid == this->initiating.mid)
951 {
952 if (this->ike_sa->get_state(this->ike_sa) == IKE_CREATED ||
953 this->ike_sa->get_state(this->ike_sa) == IKE_CONNECTING ||
954 msg->get_exchange_type(msg) != IKE_SA_INIT)
955 { /* only do host updates based on verified messages */
956 if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE))
957 { /* with MOBIKE, we do no implicit updates */
958 this->ike_sa->update_hosts(this->ike_sa, me, other, FALSE);
959 }
960 }
961 charon->bus->message(charon->bus, msg, TRUE);
962 if (msg->get_exchange_type(msg) == EXCHANGE_TYPE_UNDEFINED)
963 { /* ignore messages altered to EXCHANGE_TYPE_UNDEFINED */
964 return SUCCESS;
965 }
966 if (process_response(this, msg) != SUCCESS)
967 {
968 flush(this);
969 return DESTROY_ME;
970 }
971 }
972 else
973 {
974 DBG1(DBG_IKE, "received message ID %d, expected %d. Ignored",
975 mid, this->initiating.mid);
976 return SUCCESS;
977 }
978 }
979 return SUCCESS;
980 }
981
982 METHOD(task_manager_t, queue_task, void,
983 private_task_manager_t *this, task_t *task)
984 {
985 if (task->get_type(task) == IKE_MOBIKE)
986 { /* there is no need to queue more than one mobike task */
987 enumerator_t *enumerator;
988 task_t *current;
989
990 enumerator = this->queued_tasks->create_enumerator(this->queued_tasks);
991 while (enumerator->enumerate(enumerator, (void**)&current))
992 {
993 if (current->get_type(current) == IKE_MOBIKE)
994 {
995 enumerator->destroy(enumerator);
996 task->destroy(task);
997 return;
998 }
999 }
1000 enumerator->destroy(enumerator);
1001 }
1002 DBG2(DBG_IKE, "queueing %N task", task_type_names, task->get_type(task));
1003 this->queued_tasks->insert_last(this->queued_tasks, task);
1004 }
1005
1006 METHOD(task_manager_t, adopt_tasks, void,
1007 private_task_manager_t *this, task_manager_t *other_public)
1008 {
1009 private_task_manager_t *other = (private_task_manager_t*)other_public;
1010 task_t *task;
1011
1012 /* move queued tasks from other to this */
1013 while (other->queued_tasks->remove_last(other->queued_tasks,
1014 (void**)&task) == SUCCESS)
1015 {
1016 DBG2(DBG_IKE, "migrating %N task", task_type_names, task->get_type(task));
1017 task->migrate(task, this->ike_sa);
1018 this->queued_tasks->insert_first(this->queued_tasks, task);
1019 }
1020 }
1021
1022 METHOD(task_manager_t, busy, bool,
1023 private_task_manager_t *this)
1024 {
1025 return (this->active_tasks->get_count(this->active_tasks) > 0);
1026 }
1027
1028 METHOD(task_manager_t, incr_mid, void,
1029 private_task_manager_t *this, bool initiate)
1030 {
1031 if (initiate)
1032 {
1033 this->initiating.mid++;
1034 }
1035 else
1036 {
1037 this->responding.mid++;
1038 }
1039 }
1040
1041 METHOD(task_manager_t, reset, void,
1042 private_task_manager_t *this, u_int32_t initiate, u_int32_t respond)
1043 {
1044 enumerator_t *enumerator;
1045 task_t *task;
1046
1047 /* reset message counters and retransmit packets */
1048 DESTROY_IF(this->responding.packet);
1049 DESTROY_IF(this->initiating.packet);
1050 this->responding.packet = NULL;
1051 this->initiating.packet = NULL;
1052 if (initiate != UINT_MAX)
1053 {
1054 this->initiating.mid = initiate;
1055 }
1056 if (respond != UINT_MAX)
1057 {
1058 this->responding.mid = respond;
1059 }
1060 this->initiating.type = EXCHANGE_TYPE_UNDEFINED;
1061
1062 /* reset queued tasks */
1063 enumerator = this->queued_tasks->create_enumerator(this->queued_tasks);
1064 while (enumerator->enumerate(enumerator, &task))
1065 {
1066 task->migrate(task, this->ike_sa);
1067 }
1068 enumerator->destroy(enumerator);
1069
1070 /* reset active tasks */
1071 while (this->active_tasks->remove_last(this->active_tasks,
1072 (void**)&task) == SUCCESS)
1073 {
1074 task->migrate(task, this->ike_sa);
1075 this->queued_tasks->insert_first(this->queued_tasks, task);
1076 }
1077
1078 this->reset = TRUE;
1079 }
1080
1081 METHOD(task_manager_t, create_task_enumerator, enumerator_t*,
1082 private_task_manager_t *this, task_queue_t queue)
1083 {
1084 switch (queue)
1085 {
1086 case TASK_QUEUE_ACTIVE:
1087 return this->active_tasks->create_enumerator(this->active_tasks);
1088 case TASK_QUEUE_PASSIVE:
1089 return this->passive_tasks->create_enumerator(this->passive_tasks);
1090 case TASK_QUEUE_QUEUED:
1091 return this->queued_tasks->create_enumerator(this->queued_tasks);
1092 default:
1093 return enumerator_create_empty();
1094 }
1095 }
1096
1097 METHOD(task_manager_t, destroy, void,
1098 private_task_manager_t *this)
1099 {
1100 flush(this);
1101
1102 this->active_tasks->destroy(this->active_tasks);
1103 this->queued_tasks->destroy(this->queued_tasks);
1104 this->passive_tasks->destroy(this->passive_tasks);
1105
1106 DESTROY_IF(this->responding.packet);
1107 DESTROY_IF(this->initiating.packet);
1108 free(this);
1109 }
1110
1111 /*
1112 * see header file
1113 */
1114 task_manager_t *task_manager_create(ike_sa_t *ike_sa)
1115 {
1116 private_task_manager_t *this;
1117
1118 INIT(this,
1119 .public = {
1120 .process_message = _process_message,
1121 .queue_task = _queue_task,
1122 .initiate = _initiate,
1123 .retransmit = _retransmit,
1124 .incr_mid = _incr_mid,
1125 .reset = _reset,
1126 .adopt_tasks = _adopt_tasks,
1127 .busy = _busy,
1128 .create_task_enumerator = _create_task_enumerator,
1129 .destroy = _destroy,
1130 },
1131 .ike_sa = ike_sa,
1132 .initiating.type = EXCHANGE_TYPE_UNDEFINED,
1133 .queued_tasks = linked_list_create(),
1134 .active_tasks = linked_list_create(),
1135 .passive_tasks = linked_list_create(),
1136 .retransmit_tries = lib->settings->get_int(lib->settings,
1137 "charon.retransmit_tries", RETRANSMIT_TRIES),
1138 .retransmit_timeout = lib->settings->get_double(lib->settings,
1139 "charon.retransmit_timeout", RETRANSMIT_TIMEOUT),
1140 .retransmit_base = lib->settings->get_double(lib->settings,
1141 "charon.retransmit_base", RETRANSMIT_BASE),
1142 );
1143
1144 return &this->public;
1145 }
1146