2 * Copyright (C) 2007 Tobias Brunner
3 * Copyright (C) 2007-2010 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->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();
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 enumerator_t
*enumerator
;
182 enumerator
= this->queued_tasks
->create_enumerator(this->queued_tasks
);
183 while (enumerator
->enumerate(enumerator
, (void**)&task
))
185 if (task
->get_type(task
) == type
)
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
);
194 enumerator
->destroy(enumerator
);
198 METHOD(task_manager_t
, retransmit
, status_t
,
199 private_task_manager_t
*this, u_int32_t message_id
)
201 if (message_id
== this->initiating
.mid
)
205 enumerator_t
*enumerator
;
208 ike_mobike_t
*mobike
= NULL
;
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
))
214 if (task
->get_type(task
) == IKE_MOBIKE
)
216 mobike
= (ike_mobike_t
*)task
;
217 if (!mobike
->is_probing(mobike
))
224 enumerator
->destroy(enumerator
);
228 if (this->initiating
.retransmitted
<= this->retransmit_tries
)
230 timeout
= (u_int32_t
)(this->retransmit_timeout
* 1000.0 *
231 pow(this->retransmit_base
, this->initiating
.retransmitted
));
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
)
239 charon
->bus
->ike_updown(charon
->bus
, this->ike_sa
, FALSE
);
244 if (this->initiating
.retransmitted
)
246 DBG1(DBG_IKE
, "retransmit %d of request with message ID %d",
247 this->initiating
.retransmitted
, message_id
);
249 packet
= this->initiating
.packet
->clone(this->initiating
.packet
);
250 charon
->sender
->send(charon
->sender
, packet
);
253 { /* for routeability checks, we use a more aggressive behavior */
254 if (this->initiating
.retransmitted
<= ROUTEABILITY_CHECK_TRIES
)
256 timeout
= ROUTEABILITY_CHECK_INTERVAL
;
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
);
266 if (this->initiating
.retransmitted
)
268 DBG1(DBG_IKE
, "path probing attempt %d",
269 this->initiating
.retransmitted
);
271 mobike
->transmit(mobike
, this->initiating
.packet
);
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
);
282 METHOD(task_manager_t
, initiate
, status_t
,
283 private_task_manager_t
*this)
285 enumerator_t
*enumerator
;
290 exchange_type_t exchange
= 0;
292 if (this->initiating
.type
!= EXCHANGE_TYPE_UNDEFINED
)
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 */
300 if (this->active_tasks
->get_count(this->active_tasks
) == 0)
302 DBG2(DBG_IKE
, "activating new tasks");
303 switch (this->ike_sa
->get_state(this->ike_sa
))
306 activate_task(this, IKE_VENDOR
);
307 if (activate_task(this, IKE_INIT
))
309 this->initiating
.mid
= 0;
310 exchange
= IKE_SA_INIT
;
311 activate_task(this, IKE_NATD
);
312 activate_task(this, IKE_CERT_PRE
);
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.
318 activate_task(this, IKE_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
);
328 case IKE_ESTABLISHED
:
329 if (activate_task(this, CHILD_CREATE
))
331 exchange
= CREATE_CHILD_SA
;
334 if (activate_task(this, CHILD_DELETE
))
336 exchange
= INFORMATIONAL
;
339 if (activate_task(this, CHILD_REKEY
))
341 exchange
= CREATE_CHILD_SA
;
344 if (activate_task(this, IKE_DELETE
))
346 exchange
= INFORMATIONAL
;
349 if (activate_task(this, IKE_REKEY
))
351 exchange
= CREATE_CHILD_SA
;
354 if (activate_task(this, IKE_REAUTH
))
356 exchange
= INFORMATIONAL
;
359 if (activate_task(this, IKE_MOBIKE
))
361 exchange
= INFORMATIONAL
;
364 if (activate_task(this, IKE_DPD
))
366 exchange
= INFORMATIONAL
;
370 if (activate_task(this, IKE_ME
))
372 exchange
= ME_CONNECT
;
377 if (activate_task(this, IKE_DELETE
))
379 exchange
= INFORMATIONAL
;
389 DBG2(DBG_IKE
, "reinitiating already active tasks");
390 enumerator
= this->active_tasks
->create_enumerator(this->active_tasks
);
391 while (enumerator
->enumerate(enumerator
, (void**)&task
))
393 DBG2(DBG_IKE
, " %N task", task_type_names
, task
->get_type(task
));
394 switch (task
->get_type(task
))
397 exchange
= IKE_SA_INIT
;
399 case IKE_AUTHENTICATE
:
405 exchange
= CREATE_CHILD_SA
;
408 exchange
= INFORMATIONAL
;
414 enumerator
->destroy(enumerator
);
419 DBG2(DBG_IKE
, "nothing to initiate");
420 /* nothing to do yet... */
424 me
= this->ike_sa
->get_my_host(this->ike_sa
);
425 other
= this->ike_sa
->get_other_host(this->ike_sa
);
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;
435 enumerator
= this->active_tasks
->create_enumerator(this->active_tasks
);
436 while (enumerator
->enumerate(enumerator
, (void*)&task
))
438 switch (task
->build(task
, message
))
441 /* task completed, remove it */
442 this->active_tasks
->remove_at(this->active_tasks
, enumerator
);
446 /* processed, but task needs another exchange */
450 if (this->ike_sa
->get_state(this->ike_sa
) != IKE_CONNECTING
)
452 charon
->bus
->ike_updown(charon
->bus
, this->ike_sa
, FALSE
);
456 /* critical failure, destroy IKE_SA */
457 enumerator
->destroy(enumerator
);
458 message
->destroy(message
);
463 enumerator
->destroy(enumerator
);
465 /* update exchange type if a task changed it */
466 this->initiating
.type
= message
->get_exchange_type(message
);
468 status
= this->ike_sa
->generate_message(this->ike_sa
, message
,
469 &this->initiating
.packet
);
470 if (status
!= SUCCESS
)
472 /* message generation failed. There is nothing more to do than to
474 message
->destroy(message
);
476 charon
->bus
->ike_updown(charon
->bus
, this->ike_sa
, FALSE
);
479 message
->destroy(message
);
481 return retransmit(this, this->initiating
.mid
);
485 * handle an incoming response message
487 static status_t
process_response(private_task_manager_t
*this,
490 enumerator_t
*enumerator
;
493 if (message
->get_exchange_type(message
) != this->initiating
.type
)
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
);
502 /* catch if we get resetted while processing */
504 enumerator
= this->active_tasks
->create_enumerator(this->active_tasks
);
505 while (enumerator
->enumerate(enumerator
, (void*)&task
))
507 switch (task
->process(task
, message
))
510 /* task completed, remove it */
511 this->active_tasks
->remove_at(this->active_tasks
, enumerator
);
515 /* processed, but task needs another exchange */
519 charon
->bus
->ike_updown(charon
->bus
, this->ike_sa
, FALSE
);
522 /* critical failure, destroy IKE_SA */
523 this->active_tasks
->remove_at(this->active_tasks
, enumerator
);
524 enumerator
->destroy(enumerator
);
529 { /* start all over again if we were reset */
531 enumerator
->destroy(enumerator
);
532 return initiate(this);
535 enumerator
->destroy(enumerator
);
537 this->initiating
.mid
++;
538 this->initiating
.type
= EXCHANGE_TYPE_UNDEFINED
;
539 this->initiating
.packet
->destroy(this->initiating
.packet
);
540 this->initiating
.packet
= NULL
;
542 return initiate(this);
546 * handle exchange collisions
548 static bool handle_collisions(private_task_manager_t
*this, task_t
*task
)
550 enumerator_t
*enumerator
;
554 type
= task
->get_type(task
);
556 /* do we have to check */
557 if (type
== IKE_REKEY
|| type
== CHILD_REKEY
||
558 type
== CHILD_DELETE
|| type
== IKE_DELETE
|| type
== IKE_REAUTH
)
560 /* find an exchange collision, and notify these tasks */
561 enumerator
= this->active_tasks
->create_enumerator(this->active_tasks
);
562 while (enumerator
->enumerate(enumerator
, (void**)&active
))
564 switch (active
->get_type(active
))
567 if (type
== IKE_REKEY
|| type
== IKE_DELETE
||
570 ike_rekey_t
*rekey
= (ike_rekey_t
*)active
;
571 rekey
->collide(rekey
, task
);
576 if (type
== CHILD_REKEY
|| type
== CHILD_DELETE
)
578 child_rekey_t
*rekey
= (child_rekey_t
*)active
;
579 rekey
->collide(rekey
, task
);
586 enumerator
->destroy(enumerator
);
589 enumerator
->destroy(enumerator
);
595 * build a response depending on the "passive" task list
597 static status_t
build_response(private_task_manager_t
*this, message_t
*request
)
599 enumerator_t
*enumerator
;
606 me
= request
->get_destination(request
);
607 other
= request
->get_source(request
);
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
);
617 enumerator
= this->passive_tasks
->create_enumerator(this->passive_tasks
);
618 while (enumerator
->enumerate(enumerator
, (void*)&task
))
620 switch (task
->build(task
, message
))
623 /* task completed, remove it */
624 this->passive_tasks
->remove_at(this->passive_tasks
, enumerator
);
625 if (!handle_collisions(this, task
))
631 /* processed, but task needs another exchange */
632 if (handle_collisions(this, task
))
634 this->passive_tasks
->remove_at(this->passive_tasks
,
640 charon
->bus
->ike_updown(charon
->bus
, this->ike_sa
, FALSE
);
643 /* destroy IKE_SA, but SEND response first */
652 enumerator
->destroy(enumerator
);
654 /* remove resonder SPI if IKE_SA_INIT failed */
655 if (delete && request
->get_exchange_type(request
) == IKE_SA_INIT
)
657 ike_sa_id_t
*id
= this->ike_sa
->get_id(this->ike_sa
);
658 id
->set_responder_spi(id
, 0);
661 /* message complete, send it */
662 DESTROY_IF(this->responding
.packet
);
663 this->responding
.packet
= NULL
;
664 status
= this->ike_sa
->generate_message(this->ike_sa
, message
,
665 &this->responding
.packet
);
666 message
->destroy(message
);
667 if (status
!= SUCCESS
)
669 charon
->bus
->ike_updown(charon
->bus
, this->ike_sa
, FALSE
);
673 charon
->sender
->send(charon
->sender
,
674 this->responding
.packet
->clone(this->responding
.packet
));
683 * handle an incoming request message
685 static status_t
process_request(private_task_manager_t
*this,
688 enumerator_t
*enumerator
;
691 notify_payload_t
*notify
;
692 delete_payload_t
*delete;
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
))
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
);
709 task
= (task_t
*)ike_me_create(this->ike_sa
, FALSE
);
710 this->passive_tasks
->insert_last(this->passive_tasks
, task
);
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
,
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
);
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
))
733 switch (payload
->get_type(payload
))
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
))
746 case TRAFFIC_SELECTOR_INITIATOR
:
747 case TRAFFIC_SELECTOR_RESPONDER
:
748 { /* if we don't find a TS, its IKE rekeying */
756 enumerator
->destroy(enumerator
);
762 task
= (task_t
*)child_rekey_create(this->ike_sa
,
767 task
= (task_t
*)child_create_create(this->ike_sa
, NULL
,
773 task
= (task_t
*)ike_rekey_create(this->ike_sa
, FALSE
);
775 this->passive_tasks
->insert_last(this->passive_tasks
, task
);
780 enumerator
= message
->create_payload_enumerator(message
);
781 while (enumerator
->enumerate(enumerator
, &payload
))
783 switch (payload
->get_type(payload
))
787 notify
= (notify_payload_t
*)payload
;
788 switch (notify
->get_notify_type(notify
))
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
:
798 case NAT_DETECTION_SOURCE_IP
:
799 case NAT_DETECTION_DESTINATION_IP
:
800 task
= (task_t
*)ike_mobike_create(
801 this->ike_sa
, FALSE
);
804 task
= (task_t
*)ike_auth_lifetime_create(
805 this->ike_sa
, FALSE
);
814 delete = (delete_payload_t
*)payload
;
815 if (delete->get_protocol_id(delete) == PROTO_IKE
)
817 task
= (task_t
*)ike_delete_create(this->ike_sa
,
822 task
= (task_t
*)child_delete_create(this->ike_sa
,
835 enumerator
->destroy(enumerator
);
839 task
= (task_t
*)ike_dpd_create(FALSE
);
841 this->passive_tasks
->insert_last(this->passive_tasks
, task
);
847 task
= (task_t
*)ike_me_create(this->ike_sa
, FALSE
);
848 this->passive_tasks
->insert_last(this->passive_tasks
, task
);
856 /* let the tasks process the message */
857 enumerator
= this->passive_tasks
->create_enumerator(this->passive_tasks
);
858 while (enumerator
->enumerate(enumerator
, (void*)&task
))
860 switch (task
->process(task
, message
))
863 /* task completed, remove it */
864 this->passive_tasks
->remove_at(this->passive_tasks
, enumerator
);
868 /* processed, but task needs at least another call to build() */
872 charon
->bus
->ike_updown(charon
->bus
, this->ike_sa
, FALSE
);
875 /* critical failure, destroy IKE_SA */
876 this->passive_tasks
->remove_at(this->passive_tasks
, enumerator
);
877 enumerator
->destroy(enumerator
);
882 enumerator
->destroy(enumerator
);
884 return build_response(this, message
);
887 METHOD(task_manager_t
, process_message
, status_t
,
888 private_task_manager_t
*this, message_t
*msg
)
893 mid
= msg
->get_message_id(msg
);
894 me
= msg
->get_destination(msg
);
895 other
= msg
->get_source(msg
);
897 if (msg
->get_request(msg
))
899 if (mid
== this->responding
.mid
)
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);
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 */
915 if (process_request(this, msg
) != SUCCESS
)
920 this->responding
.mid
++;
922 else if ((mid
== this->responding
.mid
- 1) && this->responding
.packet
)
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
);
938 DBG1(DBG_IKE
, "received message ID %d, expected %d. Ignored",
939 mid
, this->responding
.mid
);
944 if (mid
== this->initiating
.mid
)
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
);
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 */
960 if (process_response(this, msg
) != SUCCESS
)
968 DBG1(DBG_IKE
, "received message ID %d, expected %d. Ignored",
969 mid
, this->initiating
.mid
);
976 METHOD(task_manager_t
, queue_task
, void,
977 private_task_manager_t
*this, task_t
*task
)
979 if (task
->get_type(task
) == IKE_MOBIKE
)
980 { /* there is no need to queue more than one mobike task */
981 enumerator_t
*enumerator
;
984 enumerator
= this->queued_tasks
->create_enumerator(this->queued_tasks
);
985 while (enumerator
->enumerate(enumerator
, (void**)¤t
))
987 if (current
->get_type(current
) == IKE_MOBIKE
)
989 enumerator
->destroy(enumerator
);
994 enumerator
->destroy(enumerator
);
996 DBG2(DBG_IKE
, "queueing %N task", task_type_names
, task
->get_type(task
));
997 this->queued_tasks
->insert_last(this->queued_tasks
, task
);
1000 METHOD(task_manager_t
, adopt_tasks
, void,
1001 private_task_manager_t
*this, task_manager_t
*other_public
)
1003 private_task_manager_t
*other
= (private_task_manager_t
*)other_public
;
1006 /* move queued tasks from other to this */
1007 while (other
->queued_tasks
->remove_last(other
->queued_tasks
,
1008 (void**)&task
) == SUCCESS
)
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
);
1016 METHOD(task_manager_t
, busy
, bool,
1017 private_task_manager_t
*this)
1019 return (this->active_tasks
->get_count(this->active_tasks
) > 0);
1022 METHOD(task_manager_t
, incr_mid
, void,
1023 private_task_manager_t
*this, bool initiate
)
1027 this->initiating
.mid
++;
1031 this->responding
.mid
++;
1035 METHOD(task_manager_t
, reset
, void,
1036 private_task_manager_t
*this, u_int32_t initiate
, u_int32_t respond
)
1038 enumerator_t
*enumerator
;
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
)
1048 this->initiating
.mid
= initiate
;
1050 if (respond
!= UINT_MAX
)
1052 this->responding
.mid
= respond
;
1054 this->initiating
.type
= EXCHANGE_TYPE_UNDEFINED
;
1056 /* reset queued tasks */
1057 enumerator
= this->queued_tasks
->create_enumerator(this->queued_tasks
);
1058 while (enumerator
->enumerate(enumerator
, &task
))
1060 task
->migrate(task
, this->ike_sa
);
1062 enumerator
->destroy(enumerator
);
1064 /* reset active tasks */
1065 while (this->active_tasks
->remove_last(this->active_tasks
,
1066 (void**)&task
) == SUCCESS
)
1068 task
->migrate(task
, this->ike_sa
);
1069 this->queued_tasks
->insert_first(this->queued_tasks
, task
);
1075 METHOD(task_manager_t
, create_task_enumerator
, enumerator_t
*,
1076 private_task_manager_t
*this, task_queue_t queue
)
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
);
1087 return enumerator_create_empty();
1091 METHOD(task_manager_t
, destroy
, void,
1092 private_task_manager_t
*this)
1096 this->active_tasks
->destroy(this->active_tasks
);
1097 this->queued_tasks
->destroy(this->queued_tasks
);
1098 this->passive_tasks
->destroy(this->passive_tasks
);
1100 DESTROY_IF(this->responding
.packet
);
1101 DESTROY_IF(this->initiating
.packet
);
1108 task_manager_t
*task_manager_create(ike_sa_t
*ike_sa
)
1110 private_task_manager_t
*this;
1114 .process_message
= _process_message
,
1115 .queue_task
= _queue_task
,
1116 .initiate
= _initiate
,
1117 .retransmit
= _retransmit
,
1118 .incr_mid
= _incr_mid
,
1120 .adopt_tasks
= _adopt_tasks
,
1122 .create_task_enumerator
= _create_task_enumerator
,
1123 .destroy
= _destroy
,
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
),
1138 return &this->public;