]> git.ipfire.org Git - thirdparty/strongswan.git/blame - src/libcharon/sa/ikev1/task_manager_v1.c
Use correct enum values to detect three message tasks for retransmission
[thirdparty/strongswan.git] / src / libcharon / sa / ikev1 / task_manager_v1.c
CommitLineData
4a09d9ee 1/*
68c6863b
TB
2 * Copyright (C) 2007-2011 Tobias Brunner
3 * Copyright (C) 2007-2011 Martin Willi
4a09d9ee
MW
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_v1.h"
18
da063ec9
MW
19#include <math.h>
20
4a09d9ee 21#include <daemon.h>
15a682f4 22#include <sa/ikev1/tasks/main_mode.h>
830ab2ae 23#include <sa/ikev1/tasks/aggressive_mode.h>
15a682f4 24#include <sa/ikev1/tasks/quick_mode.h>
83c5fda0 25#include <sa/ikev1/tasks/quick_delete.h>
15a682f4
MW
26#include <sa/ikev1/tasks/xauth.h>
27#include <sa/ikev1/tasks/mode_config.h>
28#include <sa/ikev1/tasks/informational.h>
29#include <sa/ikev1/tasks/isakmp_natd.h>
30#include <sa/ikev1/tasks/isakmp_vendor.h>
31#include <sa/ikev1/tasks/isakmp_cert_pre.h>
32#include <sa/ikev1/tasks/isakmp_cert_post.h>
3ed148b3 33#include <sa/ikev1/tasks/isakmp_delete.h>
3e6b7403
CO
34#include <sa/ikev1/tasks/isakmp_dpd.h>
35
da063ec9 36#include <processing/jobs/retransmit_job.h>
68c6863b 37#include <processing/jobs/delete_ike_sa_job.h>
4a09d9ee 38
fce566a8
MW
39/**
40 * Number of old messages hashes we keep for retransmission.
41 *
42 * In Main Mode, we must ignore messages from a previous message pair if
43 * we already continued to the next. Otherwise a late retransmission
44 * could be considered as a reply to the newer request.
45 */
46#define MAX_OLD_HASHES 2
47
f5a84055
MW
48/**
49 * First sequence number of responding packets.
50 *
51 * To distinguish retransmission jobs for initiating and responding packets,
52 * we split up the sequence counter and use the upper half for responding.
53 */
54#define RESPONDING_SEQ INT_MAX
55
4a09d9ee
MW
56typedef struct exchange_t exchange_t;
57
58/**
59 * An exchange in the air, used do detect and handle retransmission
60 */
61struct exchange_t {
62
63 /**
64 * Message ID used for this transaction
65 */
66 u_int32_t mid;
67
68 /**
69 * generated packet for retransmission
70 */
71 packet_t *packet;
72};
73
74typedef struct private_task_manager_t private_task_manager_t;
75
76/**
77 * private data of the task manager
78 */
79struct private_task_manager_t {
80
81 /**
82 * public functions
83 */
84 task_manager_v1_t public;
85
86 /**
87 * associated IKE_SA we are serving
88 */
89 ike_sa_t *ike_sa;
90
73aaf76b
MW
91 /**
92 * RNG to create message IDs
93 */
94 rng_t *rng;
95
4a09d9ee
MW
96 /**
97 * Exchange we are currently handling as responder
98 */
99 struct {
f5a84055
MW
100 /**
101 * Message ID of the last response
102 */
103 u_int32_t mid;
104
9cc8bd4f
MW
105 /**
106 * Hash of a previously received message
107 */
108 u_int32_t hash;
109
4a09d9ee
MW
110 /**
111 * packet for retransmission
112 */
113 packet_t *packet;
114
f5a84055
MW
115 /**
116 * Sequence number of the last sent message
117 */
118 u_int32_t seqnr;
119
120 /**
121 * how many times we have retransmitted so far
122 */
123 u_int retransmitted;
124
4a09d9ee
MW
125 } responding;
126
127 /**
128 * Exchange we are currently handling as initiator
129 */
130 struct {
131 /**
132 * Message ID of the exchange
133 */
134 u_int32_t mid;
135
fce566a8
MW
136 /**
137 * Hashes of old responses we can ignore
138 */
139 u_int32_t old_hashes[MAX_OLD_HASHES];
140
141 /**
142 * Position in old hash array
143 */
144 int old_hash_pos;
145
9cc8bd4f 146 /**
751bd02e 147 * Sequence number of the last sent message
9cc8bd4f 148 */
751bd02e 149 u_int32_t seqnr;
9cc8bd4f 150
4a09d9ee
MW
151 /**
152 * how many times we have retransmitted so far
153 */
154 u_int retransmitted;
155
156 /**
157 * packet for retransmission
158 */
159 packet_t *packet;
160
161 /**
162 * type of the initated exchange
163 */
164 exchange_type_t type;
165
166 } initiating;
167
168 /**
169 * List of queued tasks not yet in action
170 */
171 linked_list_t *queued_tasks;
172
173 /**
174 * List of active tasks, initiated by ourselve
175 */
176 linked_list_t *active_tasks;
177
178 /**
179 * List of tasks initiated by peer
180 */
181 linked_list_t *passive_tasks;
182
f91b6ac7
MW
183 /**
184 * Queued messages not yet ready to process
185 */
186 message_t *queued;
187
4a09d9ee
MW
188 /**
189 * Number of times we retransmit messages before giving up
190 */
191 u_int retransmit_tries;
192
193 /**
194 * Retransmission timeout
195 */
196 double retransmit_timeout;
197
198 /**
199 * Base to calculate retransmission timeout
200 */
201 double retransmit_base;
3e6b7403
CO
202
203 /**
204 * Sequence number for sending DPD requests
205 */
2ddd45c9 206 u_int32_t dpd_send;
3e6b7403
CO
207
208 /**
209 * Sequence number for received DPD requests
210 */
2ddd45c9 211 u_int32_t dpd_recv;
4a09d9ee
MW
212};
213
0f61964e
MW
214/**
215 * Flush a single task queue
216 */
217static void flush_queue(private_task_manager_t *this, linked_list_t *list)
218{
219 task_t *task;
220
429d95fe
MW
221 if (this->queued)
222 {
223 this->queued->destroy(this->queued);
224 this->queued = NULL;
225 }
0f61964e
MW
226 while (list->remove_last(list, (void**)&task) == SUCCESS)
227 {
228 task->destroy(task);
229 }
230}
231
4a09d9ee
MW
232/**
233 * flush all tasks in the task manager
234 */
235static void flush(private_task_manager_t *this)
236{
0f61964e
MW
237 flush_queue(this, this->queued_tasks);
238 flush_queue(this, this->passive_tasks);
239 flush_queue(this, this->active_tasks);
4a09d9ee
MW
240}
241
26b55dc6
MW
242/**
243 * move a task of a specific type from the queue to the active list
244 */
245static bool activate_task(private_task_manager_t *this, task_type_t type)
246{
247 enumerator_t *enumerator;
248 task_t *task;
249 bool found = FALSE;
250
251 enumerator = this->queued_tasks->create_enumerator(this->queued_tasks);
252 while (enumerator->enumerate(enumerator, (void**)&task))
253 {
254 if (task->get_type(task) == type)
255 {
256 DBG2(DBG_IKE, " activating %N task", task_type_names, type);
257 this->queued_tasks->remove_at(this->queued_tasks, enumerator);
258 this->active_tasks->insert_last(this->active_tasks, task);
259 found = TRUE;
260 break;
261 }
262 }
263 enumerator->destroy(enumerator);
264 return found;
265}
266
f5a84055
MW
267/**
268 * Retransmit a packet, either as initiator or as responder
269 */
270static status_t retransmit_packet(private_task_manager_t *this, u_int32_t seqnr,
271 u_int mid, u_int retransmitted, packet_t *packet)
23f4e4b4 272{
f5a84055 273 u_int32_t t;
23f4e4b4 274
f5a84055
MW
275 if (retransmitted > this->retransmit_tries)
276 {
277 DBG1(DBG_IKE, "giving up after %u retransmits", retransmitted - 1);
278 if (this->ike_sa->get_state(this->ike_sa) != IKE_CONNECTING)
23f4e4b4 279 {
f5a84055 280 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
23f4e4b4 281 }
f5a84055
MW
282 return DESTROY_ME;
283 }
284 t = (u_int32_t)(this->retransmit_timeout * 1000.0 *
285 pow(this->retransmit_base, retransmitted));
286 if (retransmitted)
287 {
288 DBG1(DBG_IKE, "sending retransmit %u of %s message ID %u, seq %u",
289 retransmitted, seqnr < RESPONDING_SEQ ? "request" : "response",
290 mid, seqnr < RESPONDING_SEQ ? seqnr : seqnr - RESPONDING_SEQ);
291 }
292 charon->sender->send(charon->sender, packet->clone(packet));
293 lib->scheduler->schedule_job_ms(lib->scheduler, (job_t*)
294 retransmit_job_create(seqnr, this->ike_sa->get_id(this->ike_sa)), t);
295 return NEED_MORE;
296}
297
298METHOD(task_manager_t, retransmit, status_t,
299 private_task_manager_t *this, u_int32_t seqnr)
300{
301 status_t status = SUCCESS;
302
303 if (seqnr == this->initiating.seqnr && this->initiating.packet)
304 {
305 status = retransmit_packet(this, seqnr, this->initiating.mid,
306 this->initiating.retransmitted, this->initiating.packet);
307 if (status == NEED_MORE)
23f4e4b4 308 {
f5a84055
MW
309 this->initiating.retransmitted++;
310 status = SUCCESS;
23f4e4b4 311 }
f5a84055
MW
312 }
313 if (seqnr == this->responding.seqnr && this->responding.packet)
314 {
315 status = retransmit_packet(this, seqnr, this->responding.mid,
316 this->responding.retransmitted, this->responding.packet);
317 if (status == NEED_MORE)
23f4e4b4 318 {
f5a84055
MW
319 this->responding.retransmitted++;
320 status = SUCCESS;
23f4e4b4 321 }
23f4e4b4 322 }
f5a84055 323 return status;
23f4e4b4
CO
324}
325
4a09d9ee
MW
326METHOD(task_manager_t, initiate, status_t,
327 private_task_manager_t *this)
328{
26b55dc6
MW
329 enumerator_t *enumerator;
330 task_t *task;
331 message_t *message;
332 host_t *me, *other;
333 status_t status;
73aaf76b 334 exchange_type_t exchange = EXCHANGE_TYPE_UNDEFINED;
1b82eb23 335 bool new_mid = FALSE, expect_response = FALSE, flushed = FALSE, keep = FALSE;
73aaf76b 336
477559ca
MW
337 if (this->initiating.type != EXCHANGE_TYPE_UNDEFINED &&
338 this->initiating.type != INFORMATIONAL_V1)
26b55dc6
MW
339 {
340 DBG2(DBG_IKE, "delaying task initiation, %N exchange in progress",
341 exchange_type_names, this->initiating.type);
342 /* do not initiate if we already have a message in the air */
343 return SUCCESS;
344 }
345
346 if (this->active_tasks->get_count(this->active_tasks) == 0)
347 {
348 DBG2(DBG_IKE, "activating new tasks");
349 switch (this->ike_sa->get_state(this->ike_sa))
350 {
351 case IKE_CREATED:
2e3c9f87 352 activate_task(this, TASK_ISAKMP_VENDOR);
824dc0ad 353 activate_task(this, TASK_ISAKMP_CERT_PRE);
a09972df 354 if (activate_task(this, TASK_MAIN_MODE))
26b55dc6
MW
355 {
356 exchange = ID_PROT;
357 }
830ab2ae
MW
358 else if (activate_task(this, TASK_AGGRESSIVE_MODE))
359 {
360 exchange = AGGRESSIVE;
361 }
362 activate_task(this, TASK_ISAKMP_CERT_POST);
363 activate_task(this, TASK_ISAKMP_NATD);
26b55dc6 364 break;
c5dc9d33 365 case IKE_CONNECTING:
429d95fe
MW
366 if (activate_task(this, TASK_ISAKMP_DELETE))
367 {
368 exchange = INFORMATIONAL_V1;
369 new_mid = TRUE;
370 break;
371 }
69adeb5b 372 if (activate_task(this, TASK_XAUTH))
744c0801 373 {
c5dc9d33 374 exchange = TRANSACTION;
3e246c48 375 new_mid = TRUE;
429d95fe 376 break;
744c0801 377 }
accf4612
MW
378 if (activate_task(this, TASK_INFORMATIONAL))
379 {
380 exchange = INFORMATIONAL_V1;
381 new_mid = TRUE;
429d95fe 382 break;
accf4612 383 }
c5dc9d33
CO
384 break;
385 case IKE_ESTABLISHED:
156b8662
MW
386 if (activate_task(this, TASK_MODE_CONFIG))
387 {
388 exchange = TRANSACTION;
389 new_mid = TRUE;
390 break;
391 }
c5dc9d33 392 if (activate_task(this, TASK_QUICK_MODE))
23f4e4b4 393 {
c5dc9d33 394 exchange = QUICK_MODE;
3e246c48
MW
395 new_mid = TRUE;
396 break;
23f4e4b4 397 }
accf4612
MW
398 if (activate_task(this, TASK_INFORMATIONAL))
399 {
400 exchange = INFORMATIONAL_V1;
401 new_mid = TRUE;
429d95fe 402 break;
accf4612 403 }
daee47ba 404 if (activate_task(this, TASK_QUICK_DELETE))
8ef2bae4
MW
405 {
406 exchange = INFORMATIONAL_V1;
407 new_mid = TRUE;
429d95fe 408 break;
8ef2bae4 409 }
daee47ba 410 if (activate_task(this, TASK_ISAKMP_DELETE))
8ef2bae4
MW
411 {
412 exchange = INFORMATIONAL_V1;
413 new_mid = TRUE;
429d95fe 414 break;
8ef2bae4 415 }
3e6b7403
CO
416 if (activate_task(this, TASK_ISAKMP_DPD))
417 {
418 exchange = INFORMATIONAL_V1;
419 new_mid = TRUE;
420 break;
421 }
744c0801 422 break;
26b55dc6
MW
423 default:
424 break;
425 }
426 }
427 else
428 {
429 DBG2(DBG_IKE, "reinitiating already active tasks");
430 enumerator = this->active_tasks->create_enumerator(this->active_tasks);
431 while (enumerator->enumerate(enumerator, (void**)&task))
432 {
433 DBG2(DBG_IKE, " %N task", task_type_names, task->get_type(task));
434 switch (task->get_type(task))
435 {
a09972df 436 case TASK_MAIN_MODE:
26b55dc6
MW
437 exchange = ID_PROT;
438 break;
830ab2ae
MW
439 case TASK_AGGRESSIVE_MODE:
440 exchange = AGGRESSIVE;
441 break;
744c0801
MW
442 case TASK_QUICK_MODE:
443 exchange = QUICK_MODE;
444 break;
69adeb5b 445 case TASK_XAUTH:
52ac2ceb
CO
446 exchange = TRANSACTION;
447 new_mid = TRUE;
448 break;
26b55dc6
MW
449 default:
450 continue;
451 }
452 break;
453 }
454 enumerator->destroy(enumerator);
455 }
456
73aaf76b 457 if (exchange == EXCHANGE_TYPE_UNDEFINED)
26b55dc6
MW
458 {
459 DBG2(DBG_IKE, "nothing to initiate");
460 /* nothing to do yet... */
461 return SUCCESS;
462 }
463
464 me = this->ike_sa->get_my_host(this->ike_sa);
465 other = this->ike_sa->get_other_host(this->ike_sa);
466
467 message = message_create(IKEV1_MAJOR_VERSION, IKEV1_MINOR_VERSION);
3e246c48 468 if (new_mid)
26b55dc6 469 {
73aaf76b
MW
470 this->rng->get_bytes(this->rng, sizeof(this->initiating.mid),
471 (void*)&this->initiating.mid);
26b55dc6 472 }
3e246c48 473 message->set_message_id(message, this->initiating.mid);
26b55dc6
MW
474 message->set_source(message, me->clone(me));
475 message->set_destination(message, other->clone(other));
476 message->set_exchange_type(message, exchange);
477 this->initiating.type = exchange;
478 this->initiating.retransmitted = 0;
479
480 enumerator = this->active_tasks->create_enumerator(this->active_tasks);
481 while (enumerator->enumerate(enumerator, (void*)&task))
482 {
483 switch (task->build(task, message))
484 {
485 case SUCCESS:
486 /* task completed, remove it */
487 this->active_tasks->remove_at(this->active_tasks, enumerator);
182d55b2
MW
488 if (task->get_type(task) == TASK_AGGRESSIVE_MODE ||
489 task->get_type(task) == TASK_QUICK_MODE)
1b82eb23
MW
490 { /* last message of three message exchange */
491 keep = TRUE;
492 }
26b55dc6 493 task->destroy(task);
590ca1d4 494 continue;
26b55dc6 495 case NEED_MORE:
751bd02e 496 expect_response = TRUE;
26b55dc6 497 /* processed, but task needs another exchange */
590ca1d4
MW
498 continue;
499 case ALREADY_DONE:
500 flush_queue(this, this->active_tasks);
b64d6423 501 flushed = TRUE;
26b55dc6
MW
502 break;
503 case FAILED:
504 default:
505 if (this->ike_sa->get_state(this->ike_sa) != IKE_CONNECTING)
506 {
507 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
508 }
509 /* FALL */
510 case DESTROY_ME:
511 /* critical failure, destroy IKE_SA */
512 enumerator->destroy(enumerator);
513 message->destroy(message);
514 flush(this);
515 return DESTROY_ME;
516 }
590ca1d4 517 break;
26b55dc6
MW
518 }
519 enumerator->destroy(enumerator);
520
1b82eb23
MW
521 if (this->active_tasks->get_count(this->active_tasks) == 0 &&
522 (exchange == QUICK_MODE || exchange == AGGRESSIVE))
41fbde45
MW
523 { /* tasks completed, no exchange active anymore */
524 this->initiating.type = EXCHANGE_TYPE_UNDEFINED;
525 }
1b82eb23
MW
526 if (exchange == INFORMATIONAL_V1)
527 {
528 if (message->get_notify(message, DPD_R_U_THERE))
529 {
530 expect_response = TRUE;
531 }
532 if (message->get_notify(message, DPD_R_U_THERE_ACK))
533 {
534 keep = TRUE;
535 }
536 }
b64d6423
MW
537 if (flushed)
538 {
539 message->destroy(message);
540 return initiate(this);
541 }
26b55dc6 542
f5a84055 543 DESTROY_IF(this->initiating.packet);
26b55dc6
MW
544 status = this->ike_sa->generate_message(this->ike_sa, message,
545 &this->initiating.packet);
546 if (status != SUCCESS)
547 {
548 /* message generation failed. There is nothing more to do than to
549 * close the SA */
550 message->destroy(message);
551 flush(this);
552 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
553 return DESTROY_ME;
554 }
26b55dc6 555
f5a84055 556 this->initiating.seqnr++;
1b82eb23 557 if (expect_response )
751bd02e 558 {
f5a84055 559 message->destroy(message);
751bd02e
CO
560 return retransmit(this, this->initiating.seqnr);
561 }
1b82eb23
MW
562 if (keep)
563 { /* keep the packet for retransmission, the responder might request it */
f5a84055
MW
564 charon->sender->send(charon->sender,
565 this->initiating.packet->clone(this->initiating.packet));
566 }
567 else
568 {
569 charon->sender->send(charon->sender, this->initiating.packet);
570 this->initiating.packet = NULL;
571 }
572 message->destroy(message);
46505067 573
07095794 574 if (exchange == INFORMATIONAL_V1)
46505067 575 {
07095794
MW
576 switch (this->ike_sa->get_state(this->ike_sa))
577 {
578 case IKE_CONNECTING:
579 /* close after sending an INFORMATIONAL when unestablished */
580 return FAILED;
581 case IKE_DELETING:
582 /* close after sending a DELETE */
583 return DESTROY_ME;
584 default:
585 break;
586 }
46505067 587 }
daee47ba 588 return initiate(this);
4a09d9ee
MW
589}
590
4a09d9ee
MW
591/**
592 * build a response depending on the "passive" task list
593 */
594static status_t build_response(private_task_manager_t *this, message_t *request)
595{
596 enumerator_t *enumerator;
597 task_t *task;
598 message_t *message;
599 host_t *me, *other;
f5a84055 600 bool delete = FALSE, flushed = FALSE, expect_request = FALSE;
4a09d9ee
MW
601 status_t status;
602
603 me = request->get_destination(request);
604 other = request->get_source(request);
605
606 message = message_create(IKEV1_MAJOR_VERSION, IKEV1_MINOR_VERSION);
607 message->set_exchange_type(message, request->get_exchange_type(request));
608 /* send response along the path the request came in */
609 message->set_source(message, me->clone(me));
610 message->set_destination(message, other->clone(other));
1b82eb23 611 message->set_message_id(message, request->get_message_id(request));
4a09d9ee
MW
612 message->set_request(message, FALSE);
613
f5a84055
MW
614 this->responding.mid = request->get_message_id(request);
615 this->responding.retransmitted = 0;
616 this->responding.seqnr++;
617
4a09d9ee
MW
618 enumerator = this->passive_tasks->create_enumerator(this->passive_tasks);
619 while (enumerator->enumerate(enumerator, (void*)&task))
620 {
621 switch (task->build(task, message))
622 {
623 case SUCCESS:
624 /* task completed, remove it */
625 this->passive_tasks->remove_at(this->passive_tasks, enumerator);
f5a84055 626 task->destroy(task);
590ca1d4 627 continue;
4a09d9ee
MW
628 case NEED_MORE:
629 /* processed, but task needs another exchange */
346dad30
MW
630 if (task->get_type(task) == TASK_QUICK_MODE ||
631 task->get_type(task) == TASK_AGGRESSIVE_MODE)
f5a84055
MW
632 { /* we rely on initiator retransmission, except for
633 * three-message exchanges */
634 expect_request = TRUE;
4a09d9ee 635 }
590ca1d4
MW
636 continue;
637 case ALREADY_DONE:
638 flush_queue(this, this->passive_tasks);
b64d6423 639 flushed = TRUE;
4a09d9ee
MW
640 break;
641 case FAILED:
642 default:
643 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
644 /* FALL */
645 case DESTROY_ME:
646 /* destroy IKE_SA, but SEND response first */
647 delete = TRUE;
648 break;
649 }
590ca1d4 650 break;
4a09d9ee
MW
651 }
652 enumerator->destroy(enumerator);
653
4a09d9ee
MW
654 DESTROY_IF(this->responding.packet);
655 this->responding.packet = NULL;
b64d6423
MW
656 if (flushed)
657 {
658 message->destroy(message);
659 return initiate(this);
660 }
4a09d9ee
MW
661 status = this->ike_sa->generate_message(this->ike_sa, message,
662 &this->responding.packet);
663 message->destroy(message);
664 if (status != SUCCESS)
665 {
666 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
667 return DESTROY_ME;
668 }
669
f5a84055
MW
670 if (expect_request && !delete)
671 {
672 return retransmit(this, this->responding.seqnr);
673 }
4a09d9ee 674 charon->sender->send(charon->sender,
f5a84055 675 this->responding.packet->clone(this->responding.packet));
4a09d9ee
MW
676 if (delete)
677 {
678 return DESTROY_ME;
679 }
680 return SUCCESS;
681}
682
fbbd439b
CO
683/**
684 * Send a notify in a separate INFORMATIONAL exchange back to the sender.
e647c98a 685 * The notify protocol_id is set to ISAKMP
fbbd439b 686 */
b4705269
MW
687static void send_notify(private_task_manager_t *this, message_t *request,
688 notify_type_t type)
fbbd439b
CO
689{
690 message_t *response;
691 packet_t *packet;
692 host_t *me, *other;
693 u_int32_t mid;
694
695 if (request && request->get_exchange_type(request) == INFORMATIONAL_V1)
696 { /* don't respond to INFORMATIONAL requests to avoid a notify war */
697 DBG1(DBG_IKE, "ignore malformed INFORMATIONAL request");
698 return;
699 }
700
701 response = message_create(IKEV1_MAJOR_VERSION, IKEV1_MINOR_VERSION);
702 response->set_exchange_type(response, INFORMATIONAL_V1);
703 response->set_request(response, TRUE);
704 this->rng->get_bytes(this->rng, sizeof(mid), (void*)&mid);
705 response->set_message_id(response, mid);
b4705269
MW
706 response->add_payload(response, (payload_t*)
707 notify_payload_create_from_protocol_and_type(NOTIFY_V1,
708 PROTO_IKE, type));
fbbd439b
CO
709
710 me = this->ike_sa->get_my_host(this->ike_sa);
711 if (me->is_anyaddr(me))
712 {
713 me = request->get_destination(request);
714 this->ike_sa->set_my_host(this->ike_sa, me->clone(me));
715 }
716 other = this->ike_sa->get_other_host(this->ike_sa);
717 if (other->is_anyaddr(other))
718 {
719 other = request->get_source(request);
720 this->ike_sa->set_other_host(this->ike_sa, other->clone(other));
721 }
722 response->set_source(response, me->clone(me));
723 response->set_destination(response, other->clone(other));
724 if (this->ike_sa->generate_message(this->ike_sa, response,
725 &packet) == SUCCESS)
726 {
727 charon->sender->send(charon->sender, packet);
728 }
729 response->destroy(response);
730}
731
4a09d9ee
MW
732/**
733 * handle an incoming request message
734 */
735static status_t process_request(private_task_manager_t *this,
736 message_t *message)
737{
738 enumerator_t *enumerator;
739 task_t *task = NULL;
ff6b084a 740 bool send_response = FALSE, dpd = FALSE;
2ddd45c9
MW
741 notify_payload_t *notify;
742 chunk_t data;
4a09d9ee 743
9276f712
MW
744 if (message->get_exchange_type(message) == INFORMATIONAL_V1 ||
745 this->passive_tasks->get_count(this->passive_tasks) == 0)
4a09d9ee
MW
746 { /* create tasks depending on request type, if not already some queued */
747 switch (message->get_exchange_type(message))
748 {
749 case ID_PROT:
2e3c9f87 750 task = (task_t *)isakmp_vendor_create(this->ike_sa, FALSE);
01685247 751 this->passive_tasks->insert_last(this->passive_tasks, task);
824dc0ad 752 task = (task_t*)isakmp_cert_pre_create(this->ike_sa, FALSE);
8ad5cd1f 753 this->passive_tasks->insert_last(this->passive_tasks, task);
c73c832c
MW
754 task = (task_t *)main_mode_create(this->ike_sa, FALSE);
755 this->passive_tasks->insert_last(this->passive_tasks, task);
0aa2af5e 756 task = (task_t*)isakmp_cert_post_create(this->ike_sa, FALSE);
c64a4b4f 757 this->passive_tasks->insert_last(this->passive_tasks, task);
79d6fc7f 758 task = (task_t *)isakmp_natd_create(this->ike_sa, FALSE);
1cc4ec46 759 this->passive_tasks->insert_last(this->passive_tasks, task);
4a09d9ee
MW
760 break;
761 case AGGRESSIVE:
830ab2ae
MW
762 task = (task_t *)isakmp_vendor_create(this->ike_sa, FALSE);
763 this->passive_tasks->insert_last(this->passive_tasks, task);
764 task = (task_t*)isakmp_cert_pre_create(this->ike_sa, FALSE);
765 this->passive_tasks->insert_last(this->passive_tasks, task);
766 task = (task_t *)aggressive_mode_create(this->ike_sa, FALSE);
767 this->passive_tasks->insert_last(this->passive_tasks, task);
768 task = (task_t*)isakmp_cert_post_create(this->ike_sa, FALSE);
769 this->passive_tasks->insert_last(this->passive_tasks, task);
770 task = (task_t *)isakmp_natd_create(this->ike_sa, FALSE);
771 this->passive_tasks->insert_last(this->passive_tasks, task);
772 break;
4a09d9ee 773 case QUICK_MODE:
a22b9e4f
MW
774 if (this->ike_sa->get_state(this->ike_sa) != IKE_ESTABLISHED)
775 {
776 DBG1(DBG_IKE, "received quick mode request for "
777 "unestablished IKE_SA, ignored");
778 return FAILED;
779 }
744c0801
MW
780 task = (task_t *)quick_mode_create(this->ike_sa, NULL,
781 NULL, NULL);
782 this->passive_tasks->insert_last(this->passive_tasks, task);
783 break;
4a09d9ee 784 case INFORMATIONAL_V1:
2ddd45c9
MW
785 notify = message->get_notify(message, DPD_R_U_THERE);
786 if (notify)
787 {
788 data = notify->get_notification_data(notify);
789 if (this->dpd_recv == 0 && data.len == 4)
790 { /* first DPD request, initialize counter */
791 this->dpd_recv = untoh32(data.ptr);
792 }
793 task = (task_t *)isakmp_dpd_create(this->ike_sa, FALSE,
794 this->dpd_recv++);
ff6b084a 795 dpd = TRUE;
2ddd45c9
MW
796 }
797 else if (message->get_notify(message, DPD_R_U_THERE_ACK))
798 {
799 task = (task_t *)isakmp_dpd_create(this->ike_sa, TRUE,
800 this->dpd_send - 1);
ff6b084a 801 dpd = TRUE;
2ddd45c9
MW
802 }
803 else
804 {
805 task = (task_t *)informational_create(this->ike_sa, NULL);
806 }
dc8e9647 807 this->passive_tasks->insert_first(this->passive_tasks, task);
07abb470 808 break;
c5dc9d33 809 case TRANSACTION:
156b8662
MW
810 if (this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)
811 {
812 task = (task_t *)mode_config_create(this->ike_sa, FALSE);
813 }
814 else
815 {
816 task = (task_t *)xauth_create(this->ike_sa, FALSE);
817 }
c5dc9d33
CO
818 this->passive_tasks->insert_last(this->passive_tasks, task);
819 break;
4a09d9ee
MW
820 default:
821 return FAILED;
822 }
823 }
ff6b084a
MW
824 if (!dpd)
825 {
826 this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND,
827 time_monotonic(NULL));
828 }
4a09d9ee
MW
829 /* let the tasks process the message */
830 enumerator = this->passive_tasks->create_enumerator(this->passive_tasks);
831 while (enumerator->enumerate(enumerator, (void*)&task))
832 {
833 switch (task->process(task, message))
834 {
835 case SUCCESS:
836 /* task completed, remove it */
837 this->passive_tasks->remove_at(this->passive_tasks, enumerator);
838 task->destroy(task);
590ca1d4 839 continue;
4a09d9ee
MW
840 case NEED_MORE:
841 /* processed, but task needs at least another call to build() */
8cb6f4f9 842 send_response = TRUE;
590ca1d4
MW
843 continue;
844 case ALREADY_DONE:
845 send_response = FALSE;
846 flush_queue(this, this->passive_tasks);
4a09d9ee
MW
847 break;
848 case FAILED:
849 default:
850 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
851 /* FALL */
852 case DESTROY_ME:
853 /* critical failure, destroy IKE_SA */
854 this->passive_tasks->remove_at(this->passive_tasks, enumerator);
855 enumerator->destroy(enumerator);
856 task->destroy(task);
857 return DESTROY_ME;
858 }
590ca1d4 859 break;
4a09d9ee
MW
860 }
861 enumerator->destroy(enumerator);
862
1b82eb23
MW
863 if (dpd && this->initiating.type == INFORMATIONAL_V1)
864 { /* got a DPD reply, cancel any retransmission */
865 this->initiating.type = EXCHANGE_TYPE_UNDEFINED;
866 DESTROY_IF(this->initiating.packet);
867 this->initiating.packet = NULL;
868 }
8cb6f4f9
TB
869 if (send_response)
870 {
69adeb5b
MW
871 if (build_response(this, message) != SUCCESS)
872 {
873 return DESTROY_ME;
874 }
875 }
7b34de45
MW
876 else
877 { /* We don't send a response, so don't retransmit one if we get
878 * the same message again. */
879 DESTROY_IF(this->responding.packet);
880 this->responding.packet = NULL;
881 }
69adeb5b
MW
882 if (this->passive_tasks->get_count(this->passive_tasks) == 0 &&
883 this->queued_tasks->get_count(this->queued_tasks) > 0)
884 {
885 /* passive tasks completed, check if an active task has been queued,
886 * such as XAUTH or modeconfig push */
887 return initiate(this);
8cb6f4f9
TB
888 }
889 return SUCCESS;
4a09d9ee
MW
890}
891
26b55dc6
MW
892/**
893 * handle an incoming response message
894 */
895static status_t process_response(private_task_manager_t *this,
896 message_t *message)
897{
898 enumerator_t *enumerator;
f91b6ac7 899 status_t status;
26b55dc6
MW
900 task_t *task;
901
902 if (message->get_exchange_type(message) != this->initiating.type)
903 {
904 DBG1(DBG_IKE, "received %N response, but expected %N",
905 exchange_type_names, message->get_exchange_type(message),
906 exchange_type_names, this->initiating.type);
907 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
908 return DESTROY_ME;
909 }
910
911 enumerator = this->active_tasks->create_enumerator(this->active_tasks);
912 while (enumerator->enumerate(enumerator, (void*)&task))
913 {
914 switch (task->process(task, message))
915 {
916 case SUCCESS:
917 /* task completed, remove it */
918 this->active_tasks->remove_at(this->active_tasks, enumerator);
919 task->destroy(task);
590ca1d4 920 continue;
26b55dc6
MW
921 case NEED_MORE:
922 /* processed, but task needs another exchange */
590ca1d4
MW
923 continue;
924 case ALREADY_DONE:
925 flush_queue(this, this->active_tasks);
26b55dc6
MW
926 break;
927 case FAILED:
928 default:
929 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
930 /* FALL */
931 case DESTROY_ME:
932 /* critical failure, destroy IKE_SA */
933 this->active_tasks->remove_at(this->active_tasks, enumerator);
934 enumerator->destroy(enumerator);
935 task->destroy(task);
936 return DESTROY_ME;
937 }
590ca1d4 938 break;
26b55dc6
MW
939 }
940 enumerator->destroy(enumerator);
941
942 this->initiating.type = EXCHANGE_TYPE_UNDEFINED;
943 this->initiating.packet->destroy(this->initiating.packet);
944 this->initiating.packet = NULL;
945
f91b6ac7
MW
946 if (this->queued && this->active_tasks->get_count(this->active_tasks) == 0)
947 {
948 status = this->public.task_manager.process_message(
949 &this->public.task_manager, this->queued);
950 this->queued->destroy(this->queued);
951 this->queued = NULL;
952 if (status == DESTROY_ME)
953 {
954 return status;
955 }
956 }
957
26b55dc6
MW
958 return initiate(this);
959}
960
b235e69c
TB
961/**
962 * Parse the given message and verify that it is valid.
963 */
964static status_t parse_message(private_task_manager_t *this, message_t *msg)
965{
966 status_t status;
967
968 status = msg->parse_body(msg, this->ike_sa->get_keymat(this->ike_sa));
969
970 if (status != SUCCESS)
971 {
972 switch (status)
973 {
29a5e070
TB
974 case NOT_SUPPORTED:
975 DBG1(DBG_IKE, "unsupported exchange type");
b4705269 976 send_notify(this, msg, INVALID_EXCHANGE_TYPE);
29a5e070 977 break;
b235e69c
TB
978 case PARSE_ERROR:
979 DBG1(DBG_IKE, "message parsing failed");
b4705269 980 send_notify(this, msg, PAYLOAD_MALFORMED);
b235e69c
TB
981 break;
982 case VERIFY_ERROR:
983 DBG1(DBG_IKE, "message verification failed");
b4705269 984 send_notify(this, msg, PAYLOAD_MALFORMED);
b235e69c
TB
985 break;
986 case FAILED:
987 DBG1(DBG_IKE, "integrity check failed");
b4705269 988 send_notify(this, msg, INVALID_HASH_INFORMATION);
b235e69c
TB
989 break;
990 case INVALID_STATE:
991 DBG1(DBG_IKE, "found encrypted message, but no keys available");
b4705269 992 send_notify(this, msg, PAYLOAD_MALFORMED);
b235e69c
TB
993 default:
994 break;
995 }
f5ef3577 996 DBG1(DBG_IKE, "%N %s with message ID %u processing failed",
b235e69c
TB
997 exchange_type_names, msg->get_exchange_type(msg),
998 msg->get_request(msg) ? "request" : "response",
999 msg->get_message_id(msg));
1000
1001 if (this->ike_sa->get_state(this->ike_sa) == IKE_CREATED)
1002 { /* invalid initiation attempt, close SA */
1003 return DESTROY_ME;
1004 }
1005 }
1006 return status;
1007}
1008
4a09d9ee
MW
1009METHOD(task_manager_t, process_message, status_t,
1010 private_task_manager_t *this, message_t *msg)
1011{
fce566a8 1012 u_int32_t hash, mid, i;
3d59c5c3 1013 host_t *me, *other;
68c6863b 1014 status_t status;
73aaf76b 1015
1960312c 1016 /* TODO-IKEv1: update hosts more selectively */
3d59c5c3
TB
1017 me = msg->get_destination(msg);
1018 other = msg->get_source(msg);
68c6863b 1019 mid = msg->get_message_id(msg);
fce566a8
MW
1020 hash = chunk_hash(msg->get_packet_data(msg));
1021 for (i = 0; i < MAX_OLD_HASHES; i++)
1022 {
1023 if (this->initiating.old_hashes[i] == hash)
1024 {
f5a84055
MW
1025 if (this->initiating.packet &&
1026 i == (this->initiating.old_hash_pos % MAX_OLD_HASHES) &&
346dad30
MW
1027 (msg->get_exchange_type(msg) == QUICK_MODE ||
1028 msg->get_exchange_type(msg) == AGGRESSIVE))
f5a84055
MW
1029 {
1030 DBG1(DBG_IKE, "received retransmit of response with ID %u, "
1031 "resending last request", mid);
1032 charon->sender->send(charon->sender,
1033 this->initiating.packet->clone(this->initiating.packet));
1034 return SUCCESS;
1035 }
fce566a8
MW
1036 DBG1(DBG_IKE, "received retransmit of response with ID %u, "
1037 "but next request already sent", mid);
1038 return SUCCESS;
1039 }
1040 }
1960312c 1041
2ddd45c9 1042 if ((mid && mid == this->initiating.mid) ||
73aaf76b 1043 (this->initiating.mid == 0 &&
1cc3e92c 1044 msg->get_exchange_type(msg) == this->initiating.type &&
dc8e9647 1045 this->active_tasks->get_count(this->active_tasks)))
4a09d9ee 1046 {
7519106d 1047 msg->set_request(msg, FALSE);
47b8f6ef 1048 charon->bus->message(charon->bus, msg, TRUE, FALSE);
b235e69c 1049 status = parse_message(this, msg);
1960312c
TB
1050 if (status != SUCCESS)
1051 {
1052 return status;
1053 }
1054 this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND,
1055 time_monotonic(NULL));
3d59c5c3 1056 this->ike_sa->update_hosts(this->ike_sa, me, other, TRUE);
47b8f6ef 1057 charon->bus->message(charon->bus, msg, TRUE, TRUE);
73aaf76b 1058 if (process_response(this, msg) != SUCCESS)
4a09d9ee
MW
1059 {
1060 flush(this);
1061 return DESTROY_ME;
1062 }
f5a84055 1063 this->initiating.old_hashes[(++this->initiating.old_hash_pos) %
fce566a8 1064 MAX_OLD_HASHES] = hash;
4a09d9ee
MW
1065 }
1066 else
1067 {
7b34de45 1068 if (hash == this->responding.hash)
73aaf76b 1069 {
7b34de45
MW
1070 if (this->responding.packet)
1071 {
1072 DBG1(DBG_IKE, "received retransmit of request with ID %u, "
1073 "retransmitting response", mid);
1074 charon->sender->send(charon->sender,
1075 this->responding.packet->clone(this->responding.packet));
1076 }
1b82eb23
MW
1077 else if (this->initiating.packet &&
1078 this->initiating.type == INFORMATIONAL_V1)
1079 {
1080 DBG1(DBG_IKE, "received retransmit of DPD request, "
1081 "retransmitting response");
1082 charon->sender->send(charon->sender,
1083 this->initiating.packet->clone(this->initiating.packet));
1084 }
7b34de45
MW
1085 else
1086 {
1087 DBG1(DBG_IKE, "received retransmit of request with ID %u, "
1088 "but no response to retransmit", mid);
1089 }
73aaf76b
MW
1090 return SUCCESS;
1091 }
f91b6ac7 1092 if (msg->get_exchange_type(msg) == TRANSACTION &&
0b0191e1 1093 this->active_tasks->get_count(this->active_tasks))
f91b6ac7 1094 { /* main mode not yet complete, queue XAuth/Mode config tasks */
0b0191e1
MW
1095 if (this->queued)
1096 {
1097 DBG1(DBG_IKE, "ignoring additional %N request, queue full",
1098 exchange_type_names, TRANSACTION);
1099 return SUCCESS;
1100 }
f91b6ac7
MW
1101 this->queued = message_create_from_packet(msg->get_packet(msg));
1102 if (this->queued->parse_header(this->queued) != SUCCESS)
1103 {
1104 this->queued->destroy(this->queued);
1105 this->queued = NULL;
1106 return FAILED;
1107 }
1108 DBG1(DBG_IKE, "queueing %N request as tasks still active",
1109 exchange_type_names, TRANSACTION);
1110 return SUCCESS;
1111 }
1112
7519106d 1113 msg->set_request(msg, TRUE);
47b8f6ef 1114 charon->bus->message(charon->bus, msg, TRUE, FALSE);
b235e69c 1115 status = parse_message(this, msg);
1960312c
TB
1116 if (status != SUCCESS)
1117 {
1118 return status;
1119 }
1120 /* if this IKE_SA is virgin, we check for a config */
1121 if (this->ike_sa->get_ike_cfg(this->ike_sa) == NULL)
1122 {
1123 ike_sa_id_t *ike_sa_id;
1124 ike_cfg_t *ike_cfg;
1125 job_t *job;
f5a84055 1126
1960312c
TB
1127 ike_cfg = charon->backends->get_ike_cfg(charon->backends, me, other);
1128 if (ike_cfg == NULL)
1129 {
1130 /* no config found for these hosts, destroy */
4cfd0db8
TB
1131 DBG1(DBG_IKE, "no IKE config found for %H...%H, sending %N",
1132 me, other, notify_type_names, NO_PROPOSAL_CHOSEN);
b4705269 1133 send_notify(this, msg, NO_PROPOSAL_CHOSEN);
1960312c
TB
1134 return DESTROY_ME;
1135 }
1136 this->ike_sa->set_ike_cfg(this->ike_sa, ike_cfg);
1137 ike_cfg->destroy(ike_cfg);
1138 /* add a timeout if peer does not establish it completely */
1139 ike_sa_id = this->ike_sa->get_id(this->ike_sa);
1140 job = (job_t*)delete_ike_sa_job_create(ike_sa_id, FALSE);
1141 lib->scheduler->schedule_job(lib->scheduler, job,
1142 lib->settings->get_int(lib->settings,
3fca5bd1 1143 "charon.half_open_timeout", HALF_OPEN_IKE_SA_TIMEOUT));
1960312c 1144 }
3d59c5c3 1145 this->ike_sa->update_hosts(this->ike_sa, me, other, TRUE);
47b8f6ef 1146 charon->bus->message(charon->bus, msg, TRUE, TRUE);
73aaf76b 1147 if (process_request(this, msg) != SUCCESS)
26b55dc6
MW
1148 {
1149 flush(this);
1150 return DESTROY_ME;
1151 }
9cc8bd4f 1152 this->responding.hash = hash;
4a09d9ee
MW
1153 }
1154 return SUCCESS;
1155}
1156
1157METHOD(task_manager_t, queue_task, void,
1158 private_task_manager_t *this, task_t *task)
1159{
1160 DBG2(DBG_IKE, "queueing %N task", task_type_names, task->get_type(task));
1161 this->queued_tasks->insert_last(this->queued_tasks, task);
1162}
1163
8ed976c0
MW
1164/**
1165 * Check if a given task has been queued already
1166 */
1167static bool has_queued(private_task_manager_t *this, task_type_t type)
1168{
1169 enumerator_t *enumerator;
1170 bool found = FALSE;
1171 task_t *task;
1172
1173 enumerator = this->queued_tasks->create_enumerator(this->queued_tasks);
1174 while (enumerator->enumerate(enumerator, &task))
1175 {
1176 if (task->get_type(task) == type)
1177 {
1178 found = TRUE;
1179 break;
1180 }
1181 }
1182 enumerator->destroy(enumerator);
1183 return found;
1184}
1185
a60daa07
MW
1186METHOD(task_manager_t, queue_ike, void,
1187 private_task_manager_t *this)
1188{
830ab2ae
MW
1189 peer_cfg_t *peer_cfg;
1190
8ed976c0
MW
1191 if (!has_queued(this, TASK_ISAKMP_VENDOR))
1192 {
1193 queue_task(this, (task_t*)isakmp_vendor_create(this->ike_sa, TRUE));
1194 }
1195 if (!has_queued(this, TASK_ISAKMP_CERT_PRE))
1196 {
1197 queue_task(this, (task_t*)isakmp_cert_pre_create(this->ike_sa, TRUE));
1198 }
830ab2ae
MW
1199 peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
1200 if (peer_cfg->use_aggressive(peer_cfg))
8ed976c0 1201 {
830ab2ae
MW
1202 if (!has_queued(this, TASK_AGGRESSIVE_MODE))
1203 {
1204 queue_task(this, (task_t*)aggressive_mode_create(this->ike_sa, TRUE));
1205 }
1206 }
1207 else
1208 {
1209 if (!has_queued(this, TASK_MAIN_MODE))
1210 {
1211 queue_task(this, (task_t*)main_mode_create(this->ike_sa, TRUE));
1212 }
8ed976c0
MW
1213 }
1214 if (!has_queued(this, TASK_ISAKMP_CERT_POST))
1215 {
1216 queue_task(this, (task_t*)isakmp_cert_post_create(this->ike_sa, TRUE));
1217 }
1218 if (!has_queued(this, TASK_ISAKMP_NATD))
1219 {
1220 queue_task(this, (task_t*)isakmp_natd_create(this->ike_sa, TRUE));
1221 }
a60daa07
MW
1222}
1223
4f49b068 1224METHOD(task_manager_t, queue_ike_reauth, void,
dab60d64
MW
1225 private_task_manager_t *this)
1226{
4f49b068
MW
1227 enumerator_t *enumerator;
1228 child_sa_t *child_sa;
1229 ike_sa_t *new;
1230 host_t *host;
1231
1232 new = charon->ike_sa_manager->checkout_new(charon->ike_sa_manager,
1233 this->ike_sa->get_version(this->ike_sa), TRUE);
1234 if (!new)
1235 { /* shouldn't happen */
1236 return;
1237 }
1238
1239 new->set_peer_cfg(new, this->ike_sa->get_peer_cfg(this->ike_sa));
1240 host = this->ike_sa->get_other_host(this->ike_sa);
1241 new->set_other_host(new, host->clone(host));
1242 host = this->ike_sa->get_my_host(this->ike_sa);
1243 new->set_my_host(new, host->clone(host));
1244 host = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE);
1245 if (host)
1246 {
1247 new->set_virtual_ip(new, TRUE, host);
1248 }
1249
1250 enumerator = this->ike_sa->create_child_sa_enumerator(this->ike_sa);
1251 while (enumerator->enumerate(enumerator, &child_sa))
1252 {
1253 this->ike_sa->remove_child_sa(this->ike_sa, enumerator);
1254 new->add_child_sa(new, child_sa);
1255 }
1256 enumerator->destroy(enumerator);
1257
1258 if (new->initiate(new, NULL, 0, NULL, NULL) != DESTROY_ME)
1259 {
1260 charon->ike_sa_manager->checkin(charon->ike_sa_manager, new);
1b79299b 1261 this->ike_sa->set_state(this->ike_sa, IKE_REKEYING);
4f49b068
MW
1262 }
1263 else
1264 {
1265 charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, new);
1266 DBG1(DBG_IKE, "reauthenticating IKE_SA failed");
1267 }
1268 charon->bus->set_sa(charon->bus, this->ike_sa);
dab60d64
MW
1269}
1270
4f49b068 1271METHOD(task_manager_t, queue_ike_rekey, void,
cedb412e
MW
1272 private_task_manager_t *this)
1273{
4f49b068 1274 queue_ike_reauth(this);
cedb412e
MW
1275}
1276
3ed148b3
MW
1277METHOD(task_manager_t, queue_ike_delete, void,
1278 private_task_manager_t *this)
1279{
daee47ba
MW
1280 enumerator_t *enumerator;
1281 child_sa_t *child_sa;
1282
1283 enumerator = this->ike_sa->create_child_sa_enumerator(this->ike_sa);
1284 while (enumerator->enumerate(enumerator, &child_sa))
1285 {
1286 queue_task(this, (task_t*)
1287 quick_delete_create(this->ike_sa, child_sa->get_protocol(child_sa),
3a925f74 1288 child_sa->get_spi(child_sa, TRUE), FALSE, FALSE));
daee47ba
MW
1289 }
1290 enumerator->destroy(enumerator);
1291
3ed148b3
MW
1292 queue_task(this, (task_t*)isakmp_delete_create(this->ike_sa, TRUE));
1293}
1294
873df908
MW
1295METHOD(task_manager_t, queue_mobike, void,
1296 private_task_manager_t *this, bool roam, bool address)
1297{
1298 /* Not supported in IKEv1 */
1299}
1300
fe43d9a2
MW
1301METHOD(task_manager_t, queue_child, void,
1302 private_task_manager_t *this, child_cfg_t *cfg, u_int32_t reqid,
1303 traffic_selector_t *tsi, traffic_selector_t *tsr)
1304{
14dc7941
MW
1305 quick_mode_t *task;
1306
1307 task = quick_mode_create(this->ike_sa, cfg, tsi, tsr);
1308 task->use_reqid(task, reqid);
1309
1310 queue_task(this, &task->task);
fe43d9a2
MW
1311}
1312
463a73cc
MW
1313METHOD(task_manager_t, queue_child_rekey, void,
1314 private_task_manager_t *this, protocol_id_t protocol, u_int32_t spi)
1315{
23eb447c
MW
1316 child_sa_t *child_sa;
1317 child_cfg_t *cfg;
1318 quick_mode_t *task;
1319
1320 child_sa = this->ike_sa->get_child_sa(this->ike_sa, protocol, spi, TRUE);
1321 if (!child_sa)
1322 {
1323 child_sa = this->ike_sa->get_child_sa(this->ike_sa, protocol, spi, FALSE);
1324 }
1325 if (child_sa && child_sa->get_state(child_sa) == CHILD_INSTALLED)
1326 {
1327 child_sa->set_state(child_sa, CHILD_REKEYING);
1328 cfg = child_sa->get_config(child_sa);
1329 task = quick_mode_create(this->ike_sa, cfg->get_ref(cfg), NULL, NULL);
1330 task->use_reqid(task, child_sa->get_reqid(child_sa));
669d8bde 1331 task->rekey(task, child_sa->get_spi(child_sa, TRUE));
23eb447c
MW
1332
1333 queue_task(this, &task->task);
1334 }
463a73cc
MW
1335}
1336
83c5fda0 1337METHOD(task_manager_t, queue_child_delete, void,
3a925f74
MW
1338 private_task_manager_t *this, protocol_id_t protocol, u_int32_t spi,
1339 bool expired)
83c5fda0
MW
1340{
1341 queue_task(this, (task_t*)quick_delete_create(this->ike_sa, protocol,
3a925f74 1342 spi, FALSE, expired));
83c5fda0
MW
1343}
1344
244d715d
MW
1345METHOD(task_manager_t, queue_dpd, void,
1346 private_task_manager_t *this)
1347{
2ddd45c9
MW
1348 queue_task(this, (task_t*)isakmp_dpd_create(this->ike_sa, TRUE,
1349 this->dpd_send++));
244d715d
MW
1350}
1351
4a09d9ee
MW
1352METHOD(task_manager_t, adopt_tasks, void,
1353 private_task_manager_t *this, task_manager_t *other_public)
1354{
1355 private_task_manager_t *other = (private_task_manager_t*)other_public;
1356 task_t *task;
1357
1358 /* move queued tasks from other to this */
1359 while (other->queued_tasks->remove_last(other->queued_tasks,
1360 (void**)&task) == SUCCESS)
1361 {
1362 DBG2(DBG_IKE, "migrating %N task", task_type_names, task->get_type(task));
1363 task->migrate(task, this->ike_sa);
1364 this->queued_tasks->insert_first(this->queued_tasks, task);
1365 }
1366}
1367
1368METHOD(task_manager_t, busy, bool,
1369 private_task_manager_t *this)
1370{
1371 return (this->active_tasks->get_count(this->active_tasks) > 0);
1372}
1373
1374METHOD(task_manager_t, incr_mid, void,
1375 private_task_manager_t *this, bool initiate)
1376{
4a09d9ee
MW
1377}
1378
1379METHOD(task_manager_t, reset, void,
1380 private_task_manager_t *this, u_int32_t initiate, u_int32_t respond)
1381{
d9c1dae2
MW
1382 enumerator_t *enumerator;
1383 task_t *task;
1384
1385 /* reset message counters and retransmit packets */
1386 DESTROY_IF(this->responding.packet);
1387 DESTROY_IF(this->initiating.packet);
1388 this->responding.packet = NULL;
f5a84055
MW
1389 this->responding.seqnr = RESPONDING_SEQ;
1390 this->responding.retransmitted = 0;
d9c1dae2
MW
1391 this->initiating.packet = NULL;
1392 this->initiating.mid = 0;
1393 this->initiating.seqnr = 0;
1394 this->initiating.retransmitted = 0;
1395 this->initiating.type = EXCHANGE_TYPE_UNDEFINED;
fd6fbf17
MW
1396 if (initiate != UINT_MAX)
1397 {
1398 this->dpd_send = initiate;
1399 }
1400 if (respond != UINT_MAX)
1401 {
1402 this->dpd_recv = respond;
1403 }
d9c1dae2
MW
1404
1405 /* reset queued tasks */
1406 enumerator = this->queued_tasks->create_enumerator(this->queued_tasks);
1407 while (enumerator->enumerate(enumerator, &task))
1408 {
1409 task->migrate(task, this->ike_sa);
1410 }
1411 enumerator->destroy(enumerator);
1412
1413 /* reset active tasks */
1414 while (this->active_tasks->remove_last(this->active_tasks,
1415 (void**)&task) == SUCCESS)
1416 {
1417 task->migrate(task, this->ike_sa);
1418 this->queued_tasks->insert_first(this->queued_tasks, task);
1419 }
4a09d9ee
MW
1420}
1421
1422METHOD(task_manager_t, create_task_enumerator, enumerator_t*,
1423 private_task_manager_t *this, task_queue_t queue)
1424{
1425 switch (queue)
1426 {
1427 case TASK_QUEUE_ACTIVE:
1428 return this->active_tasks->create_enumerator(this->active_tasks);
1429 case TASK_QUEUE_PASSIVE:
1430 return this->passive_tasks->create_enumerator(this->passive_tasks);
1431 case TASK_QUEUE_QUEUED:
1432 return this->queued_tasks->create_enumerator(this->queued_tasks);
1433 default:
1434 return enumerator_create_empty();
1435 }
1436}
1437
1438METHOD(task_manager_t, destroy, void,
1439 private_task_manager_t *this)
1440{
1441 flush(this);
1442
1443 this->active_tasks->destroy(this->active_tasks);
1444 this->queued_tasks->destroy(this->queued_tasks);
1445 this->passive_tasks->destroy(this->passive_tasks);
1446
f91b6ac7 1447 DESTROY_IF(this->queued);
4a09d9ee
MW
1448 DESTROY_IF(this->responding.packet);
1449 DESTROY_IF(this->initiating.packet);
73aaf76b 1450 DESTROY_IF(this->rng);
4a09d9ee
MW
1451 free(this);
1452}
1453
1454/*
1455 * see header file
1456 */
1457task_manager_v1_t *task_manager_v1_create(ike_sa_t *ike_sa)
1458{
1459 private_task_manager_t *this;
1460
1461 INIT(this,
1462 .public = {
1463 .task_manager = {
1464 .process_message = _process_message,
1465 .queue_task = _queue_task,
a60daa07 1466 .queue_ike = _queue_ike,
dab60d64 1467 .queue_ike_rekey = _queue_ike_rekey,
cedb412e 1468 .queue_ike_reauth = _queue_ike_reauth,
3ed148b3 1469 .queue_ike_delete = _queue_ike_delete,
873df908 1470 .queue_mobike = _queue_mobike,
fe43d9a2 1471 .queue_child = _queue_child,
463a73cc 1472 .queue_child_rekey = _queue_child_rekey,
83c5fda0 1473 .queue_child_delete = _queue_child_delete,
244d715d 1474 .queue_dpd = _queue_dpd,
4a09d9ee
MW
1475 .initiate = _initiate,
1476 .retransmit = _retransmit,
1477 .incr_mid = _incr_mid,
1478 .reset = _reset,
1479 .adopt_tasks = _adopt_tasks,
1480 .busy = _busy,
1481 .create_task_enumerator = _create_task_enumerator,
1482 .destroy = _destroy,
1483 },
1484 },
1485 .ike_sa = ike_sa,
1486 .initiating.type = EXCHANGE_TYPE_UNDEFINED,
f5a84055 1487 .responding.seqnr = RESPONDING_SEQ,
73aaf76b 1488 .rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK),
4a09d9ee
MW
1489 .queued_tasks = linked_list_create(),
1490 .active_tasks = linked_list_create(),
1491 .passive_tasks = linked_list_create(),
1492 .retransmit_tries = lib->settings->get_int(lib->settings,
1493 "charon.retransmit_tries", RETRANSMIT_TRIES),
1494 .retransmit_timeout = lib->settings->get_double(lib->settings,
1495 "charon.retransmit_timeout", RETRANSMIT_TIMEOUT),
1496 .retransmit_base = lib->settings->get_double(lib->settings,
1497 "charon.retransmit_base", RETRANSMIT_BASE),
1498 );
1499
3fca5bd1
MW
1500 if (!this->rng)
1501 {
1502 DBG1(DBG_IKE, "no RNG found, unable to create IKE_SA");
1503 destroy(this);
1504 return NULL;
1505 }
3e6b7403 1506
2ddd45c9
MW
1507 this->rng->get_bytes(this->rng, sizeof(this->dpd_send),
1508 (void*)&this->dpd_send);
1509 this->dpd_send &= 0x7FFFFFFF;
3e6b7403 1510
4a09d9ee
MW
1511 return &this->public;
1512}
3e6b7403 1513