2 * Copyright (C) 2007 Tobias Brunner
3 * Copyright (C) 2007 Martin Willi
4 * Hochschule fuer Technik Rapperswil
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>.
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
17 #include "task_manager.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>
41 #include <sa/tasks/ike_me.h>
44 typedef struct exchange_t exchange_t
;
47 * An exchange in the air, used do detect and handle retransmission
52 * Message ID used for this transaction
57 * generated packet for retransmission
62 typedef struct private_task_manager_t private_task_manager_t
;
65 * private data of the task manager
67 struct private_task_manager_t
{
72 task_manager_t
public;
75 * associated IKE_SA we are serving
80 * Exchange we are currently handling as responder
84 * Message ID of the exchange
89 * packet for retransmission
96 * Exchange we are currently handling as initiator
100 * Message ID of the exchange
105 * how many times we have retransmitted so far
110 * packet for retransmission
115 * type of the initated exchange
117 exchange_type_t type
;
122 * List of queued tasks not yet in action
124 linked_list_t
*queued_tasks
;
127 * List of active tasks, initiated by ourselve
129 linked_list_t
*active_tasks
;
132 * List of tasks initiated by peer
134 linked_list_t
*passive_tasks
;
137 * the task manager has been reset
142 * Number of times we retransmit messages before giving up
144 u_int retransmit_tries
;
147 * Retransmission timeout
149 double retransmit_timeout
;
152 * Base to calculate retransmission timeout
154 double retransmit_base
;
158 * flush all tasks in the task manager
160 static void flush(private_task_manager_t
*this)
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();
174 * move a task of a specific type from the queue to the active list
176 static bool activate_task(private_task_manager_t
*this, task_type_t type
)
178 iterator_t
*iterator
;
182 iterator
= this->queued_tasks
->create_iterator(this->queued_tasks
, TRUE
);
183 while (iterator
->iterate(iterator
, (void**)&task
))
185 if (task
->get_type(task
) == type
)
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
);
194 iterator
->destroy(iterator
);
199 * Implementation of task_manager_t.retransmit
201 static status_t
retransmit(private_task_manager_t
*this, u_int32_t message_id
)
203 if (message_id
== this->initiating
.mid
)
207 iterator_t
*iterator
;
210 ike_mobike_t
*mobike
= NULL
;
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
))
216 if (task
->get_type(task
) == IKE_MOBIKE
)
218 mobike
= (ike_mobike_t
*)task
;
219 if (!mobike
->is_probing(mobike
))
226 iterator
->destroy(iterator
);
230 if (this->initiating
.retransmitted
<= this->retransmit_tries
)
232 timeout
= (u_int32_t
)(this->retransmit_timeout
* 1000.0 *
233 pow(this->retransmit_base
, this->initiating
.retransmitted
));
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
)
241 charon
->bus
->ike_updown(charon
->bus
, this->ike_sa
, FALSE
);
246 if (this->initiating
.retransmitted
)
248 DBG1(DBG_IKE
, "retransmit %d of request with message ID %d",
249 this->initiating
.retransmitted
, message_id
);
251 packet
= this->initiating
.packet
->clone(this->initiating
.packet
);
252 charon
->sender
->send(charon
->sender
, packet
);
255 { /* for routeability checks, we use a more aggressive behavior */
256 if (this->initiating
.retransmitted
<= ROUTEABILITY_CHECK_TRIES
)
258 timeout
= ROUTEABILITY_CHECK_INTERVAL
;
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
);
268 if (this->initiating
.retransmitted
)
270 DBG1(DBG_IKE
, "path probing attempt %d",
271 this->initiating
.retransmitted
);
273 mobike
->transmit(mobike
, this->initiating
.packet
);
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
);
285 * build a request using the active task list
286 * Implementation of task_manager_t.initiate
288 static status_t
build_request(private_task_manager_t
*this)
290 iterator_t
*iterator
;
295 exchange_type_t exchange
= 0;
297 if (this->initiating
.type
!= EXCHANGE_TYPE_UNDEFINED
)
299 DBG2(DBG_IKE
, "delaying task initiation, exchange in progress");
300 /* do not initiate if we already have a message in the air */
304 if (this->active_tasks
->get_count(this->active_tasks
) == 0)
306 DBG2(DBG_IKE
, "activating new tasks");
307 switch (this->ike_sa
->get_state(this->ike_sa
))
310 activate_task(this, IKE_VENDOR
);
311 if (activate_task(this, IKE_INIT
))
313 this->initiating
.mid
= 0;
314 exchange
= IKE_SA_INIT
;
315 activate_task(this, IKE_NATD
);
316 activate_task(this, IKE_CERT_PRE
);
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.
322 activate_task(this, IKE_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
);
332 case IKE_ESTABLISHED
:
333 if (activate_task(this, CHILD_CREATE
))
335 exchange
= CREATE_CHILD_SA
;
338 if (activate_task(this, CHILD_DELETE
))
340 exchange
= INFORMATIONAL
;
343 if (activate_task(this, CHILD_REKEY
))
345 exchange
= CREATE_CHILD_SA
;
348 if (activate_task(this, IKE_DELETE
))
350 exchange
= INFORMATIONAL
;
353 if (activate_task(this, IKE_REKEY
))
355 exchange
= CREATE_CHILD_SA
;
358 if (activate_task(this, IKE_REAUTH
))
360 exchange
= INFORMATIONAL
;
363 if (activate_task(this, IKE_MOBIKE
))
365 exchange
= INFORMATIONAL
;
368 if (activate_task(this, IKE_DPD
))
370 exchange
= INFORMATIONAL
;
374 if (activate_task(this, IKE_ME
))
376 exchange
= ME_CONNECT
;
381 if (activate_task(this, IKE_DELETE
))
383 exchange
= INFORMATIONAL
;
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
))
397 DBG2(DBG_IKE
, " %N task", task_type_names
, task
->get_type(task
));
398 switch (task
->get_type(task
))
401 exchange
= IKE_SA_INIT
;
403 case IKE_AUTHENTICATE
:
409 exchange
= CREATE_CHILD_SA
;
412 exchange
= INFORMATIONAL
;
418 iterator
->destroy(iterator
);
423 DBG2(DBG_IKE
, "nothing to initiate");
424 /* nothing to do yet... */
428 me
= this->ike_sa
->get_my_host(this->ike_sa
);
429 other
= this->ike_sa
->get_other_host(this->ike_sa
);
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;
439 iterator
= this->active_tasks
->create_iterator(this->active_tasks
, TRUE
);
440 while (iterator
->iterate(iterator
, (void*)&task
))
442 switch (task
->build(task
, message
))
445 /* task completed, remove it */
446 iterator
->remove(iterator
);
450 /* processed, but task needs another exchange */
454 if (this->ike_sa
->get_state(this->ike_sa
) != IKE_CONNECTING
)
456 charon
->bus
->ike_updown(charon
->bus
, this->ike_sa
, FALSE
);
460 /* critical failure, destroy IKE_SA */
461 iterator
->destroy(iterator
);
462 message
->destroy(message
);
467 iterator
->destroy(iterator
);
469 /* update exchange type if a task changed it */
470 this->initiating
.type
= message
->get_exchange_type(message
);
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
)
477 /* message generation failed. There is nothing more to do than to
479 message
->destroy(message
);
481 charon
->bus
->ike_updown(charon
->bus
, this->ike_sa
, FALSE
);
484 message
->destroy(message
);
486 return retransmit(this, this->initiating
.mid
);
490 * handle an incoming response message
492 static status_t
process_response(private_task_manager_t
*this,
495 iterator_t
*iterator
;
498 if (message
->get_exchange_type(message
) != this->initiating
.type
)
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
);
507 /* catch if we get resetted while processing */
509 iterator
= this->active_tasks
->create_iterator(this->active_tasks
, TRUE
);
510 while (iterator
->iterate(iterator
, (void*)&task
))
512 switch (task
->process(task
, message
))
515 /* task completed, remove it */
516 iterator
->remove(iterator
);
520 /* processed, but task needs another exchange */
524 charon
->bus
->ike_updown(charon
->bus
, this->ike_sa
, FALSE
);
527 /* critical failure, destroy IKE_SA */
528 iterator
->remove(iterator
);
529 iterator
->destroy(iterator
);
534 { /* start all over again if we were reset */
536 iterator
->destroy(iterator
);
537 return build_request(this);
540 iterator
->destroy(iterator
);
542 this->initiating
.mid
++;
543 this->initiating
.type
= EXCHANGE_TYPE_UNDEFINED
;
544 this->initiating
.packet
->destroy(this->initiating
.packet
);
545 this->initiating
.packet
= NULL
;
547 return build_request(this);
551 * handle exchange collisions
553 static void handle_collisions(private_task_manager_t
*this, task_t
*task
)
555 iterator_t
*iterator
;
559 type
= task
->get_type(task
);
561 /* do we have to check */
562 if (type
== IKE_REKEY
|| type
== CHILD_REKEY
||
563 type
== CHILD_DELETE
|| type
== IKE_DELETE
|| type
== IKE_REAUTH
)
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
))
569 switch (active
->get_type(active
))
572 if (type
== IKE_REKEY
|| type
== IKE_DELETE
||
575 ike_rekey_t
*rekey
= (ike_rekey_t
*)active
;
576 rekey
->collide(rekey
, task
);
581 if (type
== CHILD_REKEY
|| type
== CHILD_DELETE
)
583 child_rekey_t
*rekey
= (child_rekey_t
*)active
;
584 rekey
->collide(rekey
, task
);
591 iterator
->destroy(iterator
);
594 iterator
->destroy(iterator
);
596 /* destroy task if not registered in any active task */
601 * build a response depending on the "passive" task list
603 static status_t
build_response(private_task_manager_t
*this, message_t
*request
)
605 iterator_t
*iterator
;
612 me
= request
->get_destination(request
);
613 other
= request
->get_source(request
);
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
);
623 iterator
= this->passive_tasks
->create_iterator(this->passive_tasks
, TRUE
);
624 while (iterator
->iterate(iterator
, (void*)&task
))
626 switch (task
->build(task
, message
))
629 /* task completed, remove it */
630 iterator
->remove(iterator
);
631 handle_collisions(this, task
);
633 /* processed, but task needs another exchange */
637 charon
->bus
->ike_updown(charon
->bus
, this->ike_sa
, FALSE
);
640 /* destroy IKE_SA, but SEND response first */
649 iterator
->destroy(iterator
);
651 /* remove resonder SPI if IKE_SA_INIT failed */
652 if (delete && request
->get_exchange_type(request
) == IKE_SA_INIT
)
654 ike_sa_id_t
*id
= this->ike_sa
->get_id(this->ike_sa
);
655 id
->set_responder_spi(id
, 0);
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
)
667 charon
->bus
->ike_updown(charon
->bus
, this->ike_sa
, FALSE
);
671 charon
->sender
->send(charon
->sender
,
672 this->responding
.packet
->clone(this->responding
.packet
));
681 * handle an incoming request message
683 static status_t
process_request(private_task_manager_t
*this,
686 enumerator_t
*enumerator
;
687 iterator_t
*iterator
;
690 notify_payload_t
*notify
;
691 delete_payload_t
*delete;
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
))
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
);
708 task
= (task_t
*)ike_me_create(this->ike_sa
, FALSE
);
709 this->passive_tasks
->insert_last(this->passive_tasks
, task
);
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
,
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
);
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
))
732 switch (payload
->get_type(payload
))
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
))
745 case TRAFFIC_SELECTOR_INITIATOR
:
746 case TRAFFIC_SELECTOR_RESPONDER
:
747 { /* if we don't find a TS, its IKE rekeying */
755 enumerator
->destroy(enumerator
);
761 task
= (task_t
*)child_rekey_create(this->ike_sa
,
766 task
= (task_t
*)child_create_create(this->ike_sa
, NULL
,
772 task
= (task_t
*)ike_rekey_create(this->ike_sa
, FALSE
);
774 this->passive_tasks
->insert_last(this->passive_tasks
, task
);
779 enumerator
= message
->create_payload_enumerator(message
);
780 while (enumerator
->enumerate(enumerator
, &payload
))
782 switch (payload
->get_type(payload
))
786 notify
= (notify_payload_t
*)payload
;
787 switch (notify
->get_notify_type(notify
))
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
:
797 case NAT_DETECTION_SOURCE_IP
:
798 case NAT_DETECTION_DESTINATION_IP
:
799 task
= (task_t
*)ike_mobike_create(
800 this->ike_sa
, FALSE
);
803 task
= (task_t
*)ike_auth_lifetime_create(
804 this->ike_sa
, FALSE
);
813 delete = (delete_payload_t
*)payload
;
814 if (delete->get_protocol_id(delete) == PROTO_IKE
)
816 task
= (task_t
*)ike_delete_create(this->ike_sa
,
821 task
= (task_t
*)child_delete_create(this->ike_sa
,
834 enumerator
->destroy(enumerator
);
838 task
= (task_t
*)ike_dpd_create(FALSE
);
840 this->passive_tasks
->insert_last(this->passive_tasks
, task
);
846 task
= (task_t
*)ike_me_create(this->ike_sa
, FALSE
);
847 this->passive_tasks
->insert_last(this->passive_tasks
, task
);
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
))
859 switch (task
->process(task
, message
))
862 /* task completed, remove it */
863 iterator
->remove(iterator
);
867 /* processed, but task needs at least another call to build() */
871 charon
->bus
->ike_updown(charon
->bus
, this->ike_sa
, FALSE
);
874 /* critical failure, destroy IKE_SA */
875 iterator
->remove(iterator
);
876 iterator
->destroy(iterator
);
881 iterator
->destroy(iterator
);
883 return build_response(this, message
);
887 * Implementation of task_manager_t.process_message
889 static status_t
process_message(private_task_manager_t
*this, message_t
*msg
)
891 u_int32_t mid
= msg
->get_message_id(msg
);
893 if (msg
->get_request(msg
))
895 if (mid
== this->responding
.mid
)
897 charon
->bus
->message(charon
->bus
, msg
, TRUE
);
898 if (process_request(this, msg
) != SUCCESS
)
903 this->responding
.mid
++;
905 else if ((mid
== this->responding
.mid
- 1) && this->responding
.packet
)
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
);
921 DBG1(DBG_IKE
, "received message ID %d, expected %d. Ignored",
922 mid
, this->responding
.mid
);
927 if (mid
== this->initiating
.mid
)
929 charon
->bus
->message(charon
->bus
, msg
, TRUE
);
930 if (process_response(this, msg
) != SUCCESS
)
938 DBG1(DBG_IKE
, "received message ID %d, expected %d. Ignored",
939 mid
, this->initiating
.mid
);
947 * Implementation of task_manager_t.queue_task
949 static void queue_task(private_task_manager_t
*this, task_t
*task
)
951 if (task
->get_type(task
) == IKE_MOBIKE
)
952 { /* there is no need to queue more than one mobike task */
953 iterator_t
*iterator
;
956 iterator
= this->queued_tasks
->create_iterator(this->queued_tasks
, TRUE
);
957 while (iterator
->iterate(iterator
, (void**)¤t
))
959 if (current
->get_type(current
) == IKE_MOBIKE
)
961 iterator
->destroy(iterator
);
966 iterator
->destroy(iterator
);
968 DBG2(DBG_IKE
, "queueing %N task", task_type_names
, task
->get_type(task
));
969 this->queued_tasks
->insert_last(this->queued_tasks
, task
);
973 * Implementation of task_manager_t.adopt_tasks
975 static void adopt_tasks(private_task_manager_t
*this, private_task_manager_t
*other
)
979 /* move queued tasks from other to this */
980 while (other
->queued_tasks
->remove_last(other
->queued_tasks
,
981 (void**)&task
) == SUCCESS
)
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
);
990 * Implementation of task_manager_t.busy
992 static bool busy(private_task_manager_t
*this)
994 return (this->active_tasks
->get_count(this->active_tasks
) > 0);
998 * Implementation of task_manager_t.reset
1000 static void reset(private_task_manager_t
*this,
1001 u_int32_t initiate
, u_int32_t respond
)
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
)
1012 this->initiating
.mid
= initiate
;
1014 if (respond
!= UINT_MAX
)
1016 this->responding
.mid
= respond
;
1018 this->initiating
.type
= EXCHANGE_TYPE_UNDEFINED
;
1020 /* reset active tasks */
1021 while (this->active_tasks
->remove_last(this->active_tasks
,
1022 (void**)&task
) == SUCCESS
)
1024 task
->migrate(task
, this->ike_sa
);
1025 this->queued_tasks
->insert_first(this->queued_tasks
, task
);
1032 * Implementation of task_manager_t.destroy
1034 static void destroy(private_task_manager_t
*this)
1038 this->active_tasks
->destroy(this->active_tasks
);
1039 this->queued_tasks
->destroy(this->queued_tasks
);
1040 this->passive_tasks
->destroy(this->passive_tasks
);
1042 DESTROY_IF(this->responding
.packet
);
1043 DESTROY_IF(this->initiating
.packet
);
1050 task_manager_t
*task_manager_create(ike_sa_t
*ike_sa
)
1052 private_task_manager_t
*this = malloc_thing(private_task_manager_t
);
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
;
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
;
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
);
1081 return &this->public;