4 * @brief Implementation of task_manager_t.
9 * Copyright (C) 2007 Martin Willi
10 * Hochschule fuer Technik Rapperswil
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 #include "task_manager.h"
26 #include <sa/tasks/ike_init.h>
27 #include <sa/tasks/ike_natd.h>
28 #include <sa/tasks/ike_auth.h>
29 #include <sa/tasks/ike_cert.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/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 <queues/jobs/retransmit_job.h>
40 typedef struct exchange_t exchange_t
;
43 * An exchange in the air, used do detect and handle retransmission
48 * Message ID used for this transaction
53 * generated packet for retransmission
58 typedef struct private_task_manager_t private_task_manager_t
;
61 * private data of the task manager
63 struct private_task_manager_t
{
68 task_manager_t
public;
71 * associated IKE_SA we are serving
76 * Exchange we are currently handling as responder
80 * Message ID of the exchange
85 * packet for retransmission
92 * Exchange we are currently handling as initiator
96 * Message ID of the exchange
101 * how many times we have retransmitted so far
106 * packet for retransmission
111 * type of the initated exchange
113 exchange_type_t type
;
118 * List of queued tasks not yet in action
120 linked_list_t
*queued_tasks
;
123 * List of active tasks, initiated by ourselve
125 linked_list_t
*active_tasks
;
128 * List of tasks initiated by peer
130 linked_list_t
*passive_tasks
;
133 * ike_sa_init message we sent, stored here for later authentication
135 packet_t
*ike_sa_init
;
139 * move a task of a specific type from the queue to the active list
141 static bool activate_task(private_task_manager_t
*this, task_type_t type
)
143 iterator_t
*iterator
;
147 iterator
= this->queued_tasks
->create_iterator(this->queued_tasks
, TRUE
);
148 while (iterator
->iterate(iterator
, (void**)&task
))
150 if (task
->get_type(task
) == type
)
152 DBG2(DBG_IKE
, " activating %N task", task_type_names
, type
);
153 iterator
->remove(iterator
);
154 this->active_tasks
->insert_last(this->active_tasks
, task
);
159 iterator
->destroy(iterator
);
164 * Implementation of task_manager_t.retransmit
166 static status_t
retransmit(private_task_manager_t
*this, u_int32_t message_id
)
168 if (message_id
== this->initiating
.mid
)
173 timeout
= charon
->configuration
->get_retransmit_timeout(
174 charon
->configuration
, this->initiating
.retransmitted
);
177 DBG1(DBG_IKE
, "giving up after %d retransmits",
178 this->initiating
.retransmitted
- 1);
182 if (this->initiating
.retransmitted
)
184 DBG1(DBG_IKE
, "retransmit %d of request with message ID %d",
185 this->initiating
.retransmitted
, message_id
);
187 this->initiating
.retransmitted
++;
189 charon
->send_queue
->add(charon
->send_queue
,
190 this->initiating
.packet
->clone(this->initiating
.packet
));
191 job
= (job_t
*)retransmit_job_create(this->initiating
.mid
,
192 this->ike_sa
->get_id(this->ike_sa
));
193 charon
->event_queue
->add_relative(charon
->event_queue
, job
, timeout
);
199 * build a request using the active task list
200 * Implementation of task_manager_t.initiate
202 static status_t
build_request(private_task_manager_t
*this)
204 iterator_t
*iterator
;
208 exchange_type_t exchange
= 0;
210 if (this->active_tasks
->get_count(this->active_tasks
) == 0)
212 DBG2(DBG_IKE
, "activating new tasks");
213 switch (this->ike_sa
->get_state(this->ike_sa
))
216 if (activate_task(this, IKE_INIT
))
218 exchange
= IKE_SA_INIT
;
219 activate_task(this, IKE_NATD
);
220 activate_task(this, IKE_CERT
);
221 activate_task(this, IKE_AUTHENTICATE
);
222 activate_task(this, IKE_CONFIG
);
223 activate_task(this, CHILD_CREATE
);
226 case IKE_ESTABLISHED
:
227 if (activate_task(this, CHILD_CREATE
))
229 exchange
= CREATE_CHILD_SA
;
230 activate_task(this, IKE_CONFIG
);
233 if (activate_task(this, CHILD_DELETE
))
235 exchange
= INFORMATIONAL
;
238 if (activate_task(this, CHILD_REKEY
))
240 exchange
= CREATE_CHILD_SA
;
243 if (activate_task(this, IKE_DELETE
))
245 exchange
= INFORMATIONAL
;
248 if (activate_task(this, IKE_REKEY
))
250 exchange
= CREATE_CHILD_SA
;
253 if (activate_task(this, IKE_DEADPEER
))
255 exchange
= INFORMATIONAL
;
259 if (activate_task(this, IKE_DELETE
))
261 exchange
= INFORMATIONAL
;
271 DBG2(DBG_IKE
, "reinitiating already active tasks");
272 iterator
= this->active_tasks
->create_iterator(this->active_tasks
, TRUE
);
273 while (iterator
->iterate(iterator
, (void**)&task
))
275 DBG2(DBG_IKE
, " %N task", task_type_names
, task
->get_type(task
));
276 switch (task
->get_type(task
))
279 exchange
= IKE_SA_INIT
;
281 case IKE_AUTHENTICATE
:
289 iterator
->destroy(iterator
);
294 DBG2(DBG_IKE
, "nothing to initiate");
295 /* nothing to do yet... */
299 message
= message_create();
300 message
->set_message_id(message
, this->initiating
.mid
);
301 message
->set_exchange_type(message
, exchange
);
302 this->initiating
.type
= exchange
;
303 this->initiating
.retransmitted
= 0;
305 iterator
= this->active_tasks
->create_iterator(this->active_tasks
, TRUE
);
306 while (iterator
->iterate(iterator
, (void*)&task
))
308 switch (task
->build(task
, message
))
311 /* task completed, remove it */
312 iterator
->remove(iterator
);
316 /* processed, but task needs another exchange */
320 /* critical failure, destroy IKE_SA */
321 iterator
->destroy(iterator
);
322 message
->destroy(message
);
326 iterator
->destroy(iterator
);
328 DESTROY_IF(this->initiating
.packet
);
329 status
= this->ike_sa
->generate_message(this->ike_sa
, message
,
330 &this->initiating
.packet
);
331 message
->destroy(message
);
332 if (status
!= SUCCESS
)
334 /* message generation failed. There is nothing more to do than to
339 return retransmit(this, this->initiating
.mid
);
343 * handle an incoming response message
345 static status_t
process_response(private_task_manager_t
*this,
348 iterator_t
*iterator
;
351 if (message
->get_exchange_type(message
) != this->initiating
.type
)
353 DBG1(DBG_IKE
, "received %N response, but expected %N",
354 exchange_type_names
, message
->get_exchange_type(message
),
355 exchange_type_names
, this->initiating
.type
);
359 iterator
= this->active_tasks
->create_iterator(this->active_tasks
, TRUE
);
360 while (iterator
->iterate(iterator
, (void*)&task
))
362 switch (task
->process(task
, message
))
365 /* task completed, remove it */
366 iterator
->remove(iterator
);
370 /* processed, but task needs another exchange */
374 /* critical failure, destroy IKE_SA */
375 iterator
->destroy(iterator
);
379 iterator
->destroy(iterator
);
381 this->initiating
.mid
++;
383 return build_request(this);
387 * build a response depending on the "passive" task list
389 static status_t
build_response(private_task_manager_t
*this,
390 exchange_type_t exchange
)
392 iterator_t
*iterator
;
398 message
= message_create();
399 message
->set_exchange_type(message
, exchange
);
400 message
->set_message_id(message
, this->responding
.mid
);
401 message
->set_request(message
, FALSE
);
403 iterator
= this->passive_tasks
->create_iterator(this->passive_tasks
, TRUE
);
404 while (iterator
->iterate(iterator
, (void*)&task
))
406 switch (task
->build(task
, message
))
409 /* task completed, remove it */
410 iterator
->remove(iterator
);
414 /* processed, but task needs another exchange */
418 /* destroy IKE_SA, but SEND response first */
427 iterator
->destroy(iterator
);
429 /* message complete, send it */
430 DESTROY_IF(this->responding
.packet
);
431 status
= this->ike_sa
->generate_message(this->ike_sa
, message
,
432 &this->responding
.packet
);
433 message
->destroy(message
);
434 if (status
!= SUCCESS
)
439 charon
->send_queue
->add(charon
->send_queue
,
440 this->responding
.packet
->clone(this->responding
.packet
));
449 * handle an incoming request message
451 static status_t
process_request(private_task_manager_t
*this,
454 iterator_t
*iterator
;
456 exchange_type_t exchange
;
458 notify_payload_t
*notify
;
460 exchange
= message
->get_exchange_type(message
);
462 /* create tasks depending on request type */
467 task
= (task_t
*)ike_init_create(this->ike_sa
, FALSE
, NULL
);
468 this->passive_tasks
->insert_last(this->passive_tasks
, task
);
469 task
= (task_t
*)ike_natd_create(this->ike_sa
, FALSE
);
470 this->passive_tasks
->insert_last(this->passive_tasks
, task
);
471 task
= (task_t
*)ike_cert_create(this->ike_sa
, FALSE
);
472 this->passive_tasks
->insert_last(this->passive_tasks
, task
);
473 task
= (task_t
*)ike_config_create(this->ike_sa
, NULL
);
474 this->passive_tasks
->insert_last(this->passive_tasks
, task
);
475 task
= (task_t
*)ike_auth_create(this->ike_sa
, FALSE
);
476 this->passive_tasks
->insert_last(this->passive_tasks
, task
);
477 task
= (task_t
*)child_create_create(this->ike_sa
, NULL
);
478 this->passive_tasks
->insert_last(this->passive_tasks
, task
);
481 case CREATE_CHILD_SA
:
483 bool notify_found
= FALSE
, ts_found
= FALSE
;
484 iterator
= message
->get_payload_iterator(message
);
485 while (iterator
->iterate(iterator
, (void**)&payload
))
487 switch (payload
->get_type(payload
))
491 /* if we find a rekey notify, its CHILD_SA rekeying */
492 notify
= (notify_payload_t
*)payload
;
493 if (notify
->get_notify_type(notify
) == REKEY_SA
&&
494 (notify
->get_protocol_id(notify
) == PROTO_AH
||
495 notify
->get_protocol_id(notify
) == PROTO_ESP
))
501 case TRAFFIC_SELECTOR_INITIATOR
:
502 case TRAFFIC_SELECTOR_RESPONDER
:
504 /* if we don't find a TS, its IKE rekeying */
512 iterator
->destroy(iterator
);
518 task
= (task_t
*)child_rekey_create(this->ike_sa
, NULL
);
522 task
= (task_t
*)child_create_create(this->ike_sa
, NULL
);
527 task
= (task_t
*)ike_rekey_create(this->ike_sa
, FALSE
);
529 this->passive_tasks
->insert_last(this->passive_tasks
, task
);
535 delete_payload_t
*delete;
537 delete = (delete_payload_t
*)message
->get_payload(message
, DELETE
);
540 if (delete->get_protocol_id(delete) == PROTO_IKE
)
542 task
= (task_t
*)ike_delete_create(this->ike_sa
, FALSE
);
543 this->passive_tasks
->insert_last(this->passive_tasks
, task
);
547 task
= (task_t
*)child_delete_create(this->ike_sa
, NULL
);
548 this->passive_tasks
->insert_last(this->passive_tasks
, task
);
553 task
= (task_t
*)ike_dpd_create(FALSE
);
554 this->passive_tasks
->insert_last(this->passive_tasks
, task
);
562 /* let the tasks process the message */
563 iterator
= this->passive_tasks
->create_iterator(this->passive_tasks
, TRUE
);
564 while (iterator
->iterate(iterator
, (void*)&task
))
566 switch (task
->process(task
, message
))
569 /* task completed, remove it */
570 iterator
->remove(iterator
);
574 /* processed, but task needs at least another call to build() */
578 /* critical failure, destroy IKE_SA */
579 iterator
->destroy(iterator
);
583 iterator
->destroy(iterator
);
585 return build_response(this, exchange
);
589 * Implementation of task_manager_t.process_message
591 static status_t
process_message(private_task_manager_t
*this, message_t
*msg
)
593 u_int32_t mid
= msg
->get_message_id(msg
);
595 if (msg
->get_request(msg
))
597 if (mid
== this->responding
.mid
)
599 if (process_request(this, msg
) != SUCCESS
)
603 this->responding
.mid
++;
605 else if ((mid
== this->responding
.mid
- 1) && this->responding
.packet
)
607 DBG1(DBG_IKE
, "received retransmit of request with ID %d, "
608 "retransmitting response", mid
);
609 charon
->send_queue
->add(charon
->send_queue
,
610 this->responding
.packet
->clone(
611 this->responding
.packet
));
615 DBG1(DBG_IKE
, "received message ID %d, excepted %d. Ignored",
616 mid
, this->responding
.mid
);
621 if (mid
== this->initiating
.mid
)
623 if (process_response(this, msg
) != SUCCESS
)
630 DBG1(DBG_IKE
, "received message ID %d, excepted %d. Ignored",
631 mid
, this->initiating
.mid
);
639 * Implementation of task_manager_t.queue_task
641 static void queue_task(private_task_manager_t
*this, task_t
*task
)
643 DBG2(DBG_IKE
, "queueing %N task", task_type_names
, task
->get_type(task
));
644 this->queued_tasks
->insert_last(this->queued_tasks
, task
);
648 * Implementation of task_manager_t.adopt_tasks
650 static void adopt_tasks(private_task_manager_t
*this, private_task_manager_t
*other
)
654 /* move queued tasks from other to this */
655 while (other
->queued_tasks
->remove_last(other
->queued_tasks
,
656 (void**)&task
) == SUCCESS
)
658 task
->migrate(task
, this->ike_sa
);
659 this->queued_tasks
->insert_first(this->queued_tasks
, task
);
662 /* reset active tasks and move them to others queued tasks */
663 while (other
->active_tasks
->remove_last(other
->active_tasks
,
664 (void**)&task
) == SUCCESS
)
666 task
->migrate(task
, this->ike_sa
);
667 this->queued_tasks
->insert_first(this->queued_tasks
, task
);
672 * Implementation of task_manager_t.busy
674 static bool busy(private_task_manager_t
*this)
676 return (this->active_tasks
->get_count(this->active_tasks
) > 0);
680 * Implementation of task_manager_t.reset
682 static void reset(private_task_manager_t
*this)
686 /* reset message counters and retransmit packets */
687 DESTROY_IF(this->responding
.packet
);
688 DESTROY_IF(this->initiating
.packet
);
689 DESTROY_IF(this->ike_sa_init
);
690 this->responding
.packet
= NULL
;
691 this->initiating
.packet
= NULL
;
692 this->ike_sa_init
= NULL
;
693 this->responding
.mid
= 0;
694 this->initiating
.mid
= -1;
696 /* reset active tasks */
697 while (this->active_tasks
->remove_last(this->active_tasks
,
698 (void**)&task
) == SUCCESS
)
700 task
->migrate(task
, this->ike_sa
);
701 this->queued_tasks
->insert_first(this->queued_tasks
, task
);
706 * Implementation of task_manager_t.destroy
708 static void destroy(private_task_manager_t
*this)
712 this->queued_tasks
->destroy_offset(this->queued_tasks
,
713 offsetof(task_t
, destroy
));
714 this->passive_tasks
->destroy_offset(this->passive_tasks
,
715 offsetof(task_t
, destroy
));
717 /* emmit outstanding signals for tasks */
718 while (this->active_tasks
->remove_last(this->active_tasks
,
719 (void**)&task
) == SUCCESS
)
721 switch (task
->get_type(task
))
724 SIG(IKE_UP_FAILED
, "establishing IKE_SA failed");
727 SIG(IKE_DOWN_FAILED
, "deleteing IKE_SA properly failed");
730 SIG(IKE_REKEY_FAILED
, "rekeying IKE_SA failed");
733 SIG(CHILD_UP_FAILED
, "establishing CHILD_SA failed");
736 SIG(CHILD_DOWN_FAILED
, "deleting CHILD_SA failed");
739 SIG(IKE_REKEY_FAILED
, "rekeying CHILD_SA failed");
746 this->active_tasks
->destroy(this->active_tasks
);
747 DESTROY_IF(this->responding
.packet
);
748 DESTROY_IF(this->initiating
.packet
);
749 DESTROY_IF(this->ike_sa_init
);
756 task_manager_t
*task_manager_create(ike_sa_t
*ike_sa
)
758 private_task_manager_t
*this = malloc_thing(private_task_manager_t
);
760 this->public.process_message
= (status_t(*)(task_manager_t
*,message_t
*))process_message
;
761 this->public.queue_task
= (void(*)(task_manager_t
*,task_t
*))queue_task
;
762 this->public.initiate
= (status_t(*)(task_manager_t
*))build_request
;
763 this->public.retransmit
= (status_t(*)(task_manager_t
*,u_int32_t
))retransmit
;
764 this->public.reset
= (void(*)(task_manager_t
*))reset
;
765 this->public.adopt_tasks
= (void(*)(task_manager_t
*,task_manager_t
*))adopt_tasks
;
766 this->public.busy
= (bool(*)(task_manager_t
*))busy
;
767 this->public.destroy
= (void(*)(task_manager_t
*))destroy
;
769 this->ike_sa
= ike_sa
;
770 this->responding
.packet
= NULL
;
771 this->initiating
.packet
= NULL
;
772 this->responding
.mid
= 0;
773 this->initiating
.mid
= 0;
774 this->queued_tasks
= linked_list_create();
775 this->active_tasks
= linked_list_create();
776 this->passive_tasks
= linked_list_create();
777 this->ike_sa_init
= NULL
;
779 return &this->public;