certificate tasks added to passive list for responder
[strongswan.git] / src / libcharon / sa / task_manager_v1.c
1 /*
2 * Copyright (C) 2007-2011 Tobias Brunner
3 * Copyright (C) 2007-2011 Martin Willi
4 * Hochschule fuer Technik Rapperswil
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17 #include "task_manager_v1.h"
18
19 #include <math.h>
20
21 #include <daemon.h>
22 #include <sa/tasks/main_mode.h>
23 #include <sa/tasks/quick_mode.h>
24 #include <sa/tasks/xauth_request.h>
25 #include <sa/tasks/ike_natd_v1.h>
26 #include <sa/tasks/ike_vendor_v1.h>
27 #include <sa/tasks/ike_cert_pre.h>
28 #include <sa/tasks/ike_cert_post.h>
29 #include <processing/jobs/retransmit_job.h>
30 #include <processing/jobs/delete_ike_sa_job.h>
31
32 typedef struct exchange_t exchange_t;
33
34 /**
35 * An exchange in the air, used do detect and handle retransmission
36 */
37 struct exchange_t {
38
39 /**
40 * Message ID used for this transaction
41 */
42 u_int32_t mid;
43
44 /**
45 * generated packet for retransmission
46 */
47 packet_t *packet;
48 };
49
50 typedef struct private_task_manager_t private_task_manager_t;
51
52 /**
53 * private data of the task manager
54 */
55 struct private_task_manager_t {
56
57 /**
58 * public functions
59 */
60 task_manager_v1_t public;
61
62 /**
63 * associated IKE_SA we are serving
64 */
65 ike_sa_t *ike_sa;
66
67 /**
68 * RNG to create message IDs
69 */
70 rng_t *rng;
71
72 /**
73 * Exchange we are currently handling as responder
74 */
75 struct {
76 /**
77 * Message ID of the exchange
78 */
79 u_int32_t mid;
80
81 /**
82 * Hash of a previously received message
83 */
84 u_int32_t hash;
85
86 /**
87 * packet for retransmission
88 */
89 packet_t *packet;
90
91 } responding;
92
93 /**
94 * Exchange we are currently handling as initiator
95 */
96 struct {
97 /**
98 * Message ID of the exchange
99 */
100 u_int32_t mid;
101
102 /**
103 * Hash of a previously received message
104 */
105 u_int32_t hash;
106
107 /**
108 * how many times we have retransmitted so far
109 */
110 u_int retransmitted;
111
112 /**
113 * packet for retransmission
114 */
115 packet_t *packet;
116
117 /**
118 * type of the initated exchange
119 */
120 exchange_type_t type;
121
122 } initiating;
123
124 /**
125 * List of queued tasks not yet in action
126 */
127 linked_list_t *queued_tasks;
128
129 /**
130 * List of active tasks, initiated by ourselve
131 */
132 linked_list_t *active_tasks;
133
134 /**
135 * List of tasks initiated by peer
136 */
137 linked_list_t *passive_tasks;
138
139 /**
140 * Number of times we retransmit messages before giving up
141 */
142 u_int retransmit_tries;
143
144 /**
145 * Retransmission timeout
146 */
147 double retransmit_timeout;
148
149 /**
150 * Base to calculate retransmission timeout
151 */
152 double retransmit_base;
153 };
154
155 /**
156 * flush all tasks in the task manager
157 */
158 static void flush(private_task_manager_t *this)
159 {
160 this->queued_tasks->destroy_offset(this->queued_tasks,
161 offsetof(task_t, destroy));
162 this->queued_tasks = linked_list_create();
163 this->passive_tasks->destroy_offset(this->passive_tasks,
164 offsetof(task_t, destroy));
165 this->passive_tasks = linked_list_create();
166 this->active_tasks->destroy_offset(this->active_tasks,
167 offsetof(task_t, destroy));
168 this->active_tasks = linked_list_create();
169 }
170
171 /**
172 * move a task of a specific type from the queue to the active list
173 */
174 static bool activate_task(private_task_manager_t *this, task_type_t type)
175 {
176 enumerator_t *enumerator;
177 task_t *task;
178 bool found = FALSE;
179
180 enumerator = this->queued_tasks->create_enumerator(this->queued_tasks);
181 while (enumerator->enumerate(enumerator, (void**)&task))
182 {
183 if (task->get_type(task) == type)
184 {
185 DBG2(DBG_IKE, " activating %N task", task_type_names, type);
186 this->queued_tasks->remove_at(this->queued_tasks, enumerator);
187 this->active_tasks->insert_last(this->active_tasks, task);
188 found = TRUE;
189 break;
190 }
191 }
192 enumerator->destroy(enumerator);
193 return found;
194 }
195
196 METHOD(task_manager_t, retransmit, status_t,
197 private_task_manager_t *this, u_int32_t message_id)
198 {
199 if (message_id == this->initiating.mid)
200 {
201 u_int32_t timeout;
202 packet_t *packet;
203 job_t *job;
204
205 if (this->initiating.retransmitted <= this->retransmit_tries)
206 {
207 timeout = (u_int32_t)(this->retransmit_timeout * 1000.0 *
208 pow(this->retransmit_base, this->initiating.retransmitted));
209 }
210 else
211 {
212 DBG1(DBG_IKE, "giving up after %d retransmits",
213 this->initiating.retransmitted - 1);
214 if (this->ike_sa->get_state(this->ike_sa) != IKE_CONNECTING)
215 {
216 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
217 }
218 return DESTROY_ME;
219 }
220
221 if (this->initiating.retransmitted)
222 {
223 DBG1(DBG_IKE, "retransmit %d of request with message ID %d",
224 this->initiating.retransmitted, message_id);
225 }
226 packet = this->initiating.packet->clone(this->initiating.packet);
227 charon->sender->send(charon->sender, packet);
228
229 this->initiating.retransmitted++;
230 job = (job_t*)retransmit_job_create(this->initiating.mid,
231 this->ike_sa->get_id(this->ike_sa));
232 lib->scheduler->schedule_job_ms(lib->scheduler, job, timeout);
233 }
234 return SUCCESS;
235 }
236
237 METHOD(task_manager_t, initiate, status_t,
238 private_task_manager_t *this)
239 {
240 enumerator_t *enumerator;
241 task_t *task;
242 message_t *message;
243 host_t *me, *other;
244 status_t status;
245 exchange_type_t exchange = EXCHANGE_TYPE_UNDEFINED;
246 bool new_mid = FALSE;
247
248 if (!this->rng)
249 {
250 DBG1(DBG_IKE, "no RNG supported");
251 return FAILED;
252 }
253
254 if (this->initiating.type != EXCHANGE_TYPE_UNDEFINED)
255 {
256 DBG2(DBG_IKE, "delaying task initiation, %N exchange in progress",
257 exchange_type_names, this->initiating.type);
258 /* do not initiate if we already have a message in the air */
259 return SUCCESS;
260 }
261
262 if (this->active_tasks->get_count(this->active_tasks) == 0)
263 {
264 DBG2(DBG_IKE, "activating new tasks");
265 switch (this->ike_sa->get_state(this->ike_sa))
266 {
267 case IKE_CREATED:
268 activate_task(this, TASK_VENDOR_V1);
269 if (activate_task(this, TASK_MAIN_MODE))
270 {
271 exchange = ID_PROT;
272 activate_task(this, TASK_IKE_NATD_V1);
273 }
274 break;
275 case IKE_CONNECTING:
276 if (activate_task(this, TASK_XAUTH_REQUEST))
277 {
278 exchange = TRANSACTION;
279 new_mid = TRUE;
280 }
281 break;
282 case IKE_ESTABLISHED:
283 if (activate_task(this, TASK_QUICK_MODE))
284 {
285 exchange = QUICK_MODE;
286 new_mid = TRUE;
287 break;
288 }
289 break;
290 default:
291 break;
292 }
293 }
294 else
295 {
296 DBG2(DBG_IKE, "reinitiating already active tasks");
297 enumerator = this->active_tasks->create_enumerator(this->active_tasks);
298 while (enumerator->enumerate(enumerator, (void**)&task))
299 {
300 DBG2(DBG_IKE, " %N task", task_type_names, task->get_type(task));
301 switch (task->get_type(task))
302 {
303 case TASK_MAIN_MODE:
304 exchange = ID_PROT;
305 break;
306 case TASK_QUICK_MODE:
307 exchange = QUICK_MODE;
308 break;
309 case TASK_XAUTH_REQUEST:
310 exchange = TRANSACTION;
311 new_mid = TRUE;
312 break;
313 default:
314 continue;
315 }
316 break;
317 }
318 enumerator->destroy(enumerator);
319 }
320
321 if (exchange == EXCHANGE_TYPE_UNDEFINED)
322 {
323 DBG2(DBG_IKE, "nothing to initiate");
324 /* nothing to do yet... */
325 return SUCCESS;
326 }
327
328 me = this->ike_sa->get_my_host(this->ike_sa);
329 other = this->ike_sa->get_other_host(this->ike_sa);
330
331 message = message_create(IKEV1_MAJOR_VERSION, IKEV1_MINOR_VERSION);
332 if (new_mid)
333 {
334 this->rng->get_bytes(this->rng, sizeof(this->initiating.mid),
335 (void*)&this->initiating.mid);
336 }
337 message->set_message_id(message, this->initiating.mid);
338 message->set_source(message, me->clone(me));
339 message->set_destination(message, other->clone(other));
340 message->set_exchange_type(message, exchange);
341 this->initiating.type = exchange;
342 this->initiating.retransmitted = 0;
343
344 enumerator = this->active_tasks->create_enumerator(this->active_tasks);
345 while (enumerator->enumerate(enumerator, (void*)&task))
346 {
347 switch (task->build(task, message))
348 {
349 case SUCCESS:
350 /* task completed, remove it */
351 this->active_tasks->remove_at(this->active_tasks, enumerator);
352 task->destroy(task);
353 break;
354 case NEED_MORE:
355 /* processed, but task needs another exchange */
356 break;
357 case FAILED:
358 default:
359 if (this->ike_sa->get_state(this->ike_sa) != IKE_CONNECTING)
360 {
361 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
362 }
363 /* FALL */
364 case DESTROY_ME:
365 /* critical failure, destroy IKE_SA */
366 enumerator->destroy(enumerator);
367 message->destroy(message);
368 flush(this);
369 return DESTROY_ME;
370 }
371 }
372 enumerator->destroy(enumerator);
373
374 /* update exchange type if a task changed it */
375 this->initiating.type = message->get_exchange_type(message);
376
377 status = this->ike_sa->generate_message(this->ike_sa, message,
378 &this->initiating.packet);
379 if (status != SUCCESS)
380 {
381 /* message generation failed. There is nothing more to do than to
382 * close the SA */
383 message->destroy(message);
384 flush(this);
385 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
386 return DESTROY_ME;
387 }
388 message->destroy(message);
389
390 charon->sender->send(charon->sender,
391 this->initiating.packet->clone(this->initiating.packet));
392
393 return SUCCESS;
394 }
395
396 /**
397 * handle exchange collisions
398 */
399 static bool handle_collisions(private_task_manager_t *this, task_t *task)
400 {
401 return FALSE;
402 }
403
404 /**
405 * build a response depending on the "passive" task list
406 */
407 static status_t build_response(private_task_manager_t *this, message_t *request)
408 {
409 enumerator_t *enumerator;
410 task_t *task;
411 message_t *message;
412 host_t *me, *other;
413 bool delete = FALSE;
414 status_t status;
415
416 me = request->get_destination(request);
417 other = request->get_source(request);
418
419 message = message_create(IKEV1_MAJOR_VERSION, IKEV1_MINOR_VERSION);
420 message->set_exchange_type(message, request->get_exchange_type(request));
421 /* send response along the path the request came in */
422 message->set_source(message, me->clone(me));
423 message->set_destination(message, other->clone(other));
424 message->set_message_id(message, request->get_message_id(request));
425 message->set_request(message, FALSE);
426
427 enumerator = this->passive_tasks->create_enumerator(this->passive_tasks);
428 while (enumerator->enumerate(enumerator, (void*)&task))
429 {
430 switch (task->build(task, message))
431 {
432 case SUCCESS:
433 /* task completed, remove it */
434 this->passive_tasks->remove_at(this->passive_tasks, enumerator);
435 if (!handle_collisions(this, task))
436 {
437 task->destroy(task);
438 }
439 break;
440 case NEED_MORE:
441 /* processed, but task needs another exchange */
442 if (handle_collisions(this, task))
443 {
444 this->passive_tasks->remove_at(this->passive_tasks,
445 enumerator);
446 }
447 break;
448 case FAILED:
449 default:
450 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
451 /* FALL */
452 case DESTROY_ME:
453 /* destroy IKE_SA, but SEND response first */
454 delete = TRUE;
455 break;
456 }
457 if (delete)
458 {
459 break;
460 }
461 }
462 enumerator->destroy(enumerator);
463
464 /* message complete, send it */
465 DESTROY_IF(this->responding.packet);
466 this->responding.packet = NULL;
467 status = this->ike_sa->generate_message(this->ike_sa, message,
468 &this->responding.packet);
469 message->destroy(message);
470 if (status != SUCCESS)
471 {
472 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
473 return DESTROY_ME;
474 }
475
476 charon->sender->send(charon->sender,
477 this->responding.packet->clone(this->responding.packet));
478 if (delete)
479 {
480 return DESTROY_ME;
481 }
482 return SUCCESS;
483 }
484
485 /**
486 * handle an incoming request message
487 */
488 static status_t process_request(private_task_manager_t *this,
489 message_t *message)
490 {
491 enumerator_t *enumerator;
492 task_t *task = NULL;
493 bool send_response = FALSE;
494 payload_t *payload;
495 notify_payload_t *notify;
496
497 if (this->passive_tasks->get_count(this->passive_tasks) == 0)
498 { /* create tasks depending on request type, if not already some queued */
499 switch (message->get_exchange_type(message))
500 {
501 case ID_PROT:
502 task = (task_t *)ike_vendor_v1_create(this->ike_sa, FALSE);
503 this->passive_tasks->insert_last(this->passive_tasks, task);
504 task = (task_t*)ike_cert_pre_create(this->ike_sa, FALSE);
505 this->passive_tasks->insert_last(this->passive_tasks, task);
506 task = (task_t *)main_mode_create(this->ike_sa, FALSE);
507 this->passive_tasks->insert_last(this->passive_tasks, task);
508 task = (task_t *)ike_natd_v1_create(this->ike_sa, FALSE);
509 this->passive_tasks->insert_last(this->passive_tasks, task);
510 task = (task_t*)ike_cert_post_create(this->ike_sa, FALSE);
511 this->passive_tasks->insert_last(this->passive_tasks, task);
512 break;
513 case AGGRESSIVE:
514 /* TODO-IKEv1: agressive mode */
515 return FAILED;
516 case QUICK_MODE:
517 task = (task_t *)quick_mode_create(this->ike_sa, NULL,
518 NULL, NULL);
519 this->passive_tasks->insert_last(this->passive_tasks, task);
520 break;
521 case INFORMATIONAL_V1:
522 enumerator = message->create_payload_enumerator(message);
523 while (enumerator->enumerate(enumerator, &payload))
524 {
525 switch (payload->get_type(payload))
526 {
527 case NOTIFY_V1:
528 {
529 notify = (notify_payload_t*)payload;
530 switch (notify->get_notify_type(notify))
531 {
532 /* TODO-IKEv1: Add notification types here as needed */
533 case INITIAL_CONTACT_IKEV1:
534 break;
535 default:
536 if(notify->get_notify_type(notify) < 16384)
537 {
538 DBG1(DBG_IKE, "Received %N error notification.", notify_type_names, notify->get_notify_type(notify));
539 return FAILED;
540 }
541 break;
542 }
543 break;
544 }
545 case DELETE_V1:
546 {
547 /* TODO-IKEv1: Delete payload handling. */
548 break;
549 }
550 default:
551 break;
552 }
553 if (task)
554 {
555 break;
556 }
557 }
558 enumerator->destroy(enumerator);
559 break;
560 case TRANSACTION:
561 task = (task_t *)xauth_request_create(this->ike_sa, FALSE);
562 this->passive_tasks->insert_last(this->passive_tasks, task);
563 break;
564 default:
565 return FAILED;
566 }
567 }
568 /* let the tasks process the message */
569 enumerator = this->passive_tasks->create_enumerator(this->passive_tasks);
570 while (enumerator->enumerate(enumerator, (void*)&task))
571 {
572 switch (task->process(task, message))
573 {
574 case SUCCESS:
575 /* task completed, remove it */
576 this->passive_tasks->remove_at(this->passive_tasks, enumerator);
577 task->destroy(task);
578 break;
579 case NEED_MORE:
580 /* processed, but task needs at least another call to build() */
581 send_response = TRUE;
582 break;
583 case FAILED:
584 default:
585 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
586 /* FALL */
587 case DESTROY_ME:
588 /* critical failure, destroy IKE_SA */
589 this->passive_tasks->remove_at(this->passive_tasks, enumerator);
590 enumerator->destroy(enumerator);
591 task->destroy(task);
592 return DESTROY_ME;
593 }
594 }
595 enumerator->destroy(enumerator);
596
597 if (send_response)
598 {
599 return build_response(this, message);
600 }
601 return SUCCESS;
602 }
603
604 /**
605 * handle an incoming response message
606 */
607 static status_t process_response(private_task_manager_t *this,
608 message_t *message)
609 {
610 enumerator_t *enumerator;
611 task_t *task;
612
613 if (message->get_exchange_type(message) != this->initiating.type)
614 {
615 DBG1(DBG_IKE, "received %N response, but expected %N",
616 exchange_type_names, message->get_exchange_type(message),
617 exchange_type_names, this->initiating.type);
618 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
619 return DESTROY_ME;
620 }
621
622 enumerator = this->active_tasks->create_enumerator(this->active_tasks);
623 while (enumerator->enumerate(enumerator, (void*)&task))
624 {
625 switch (task->process(task, message))
626 {
627 case SUCCESS:
628 /* task completed, remove it */
629 this->active_tasks->remove_at(this->active_tasks, enumerator);
630 task->destroy(task);
631 break;
632 case NEED_MORE:
633 /* processed, but task needs another exchange */
634 break;
635 case FAILED:
636 default:
637 charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
638 /* FALL */
639 case DESTROY_ME:
640 /* critical failure, destroy IKE_SA */
641 this->active_tasks->remove_at(this->active_tasks, enumerator);
642 enumerator->destroy(enumerator);
643 task->destroy(task);
644 return DESTROY_ME;
645 }
646 }
647 enumerator->destroy(enumerator);
648
649 this->initiating.type = EXCHANGE_TYPE_UNDEFINED;
650 this->initiating.packet->destroy(this->initiating.packet);
651 this->initiating.packet = NULL;
652
653 return initiate(this);
654 }
655
656 /**
657 * Send a notify in a separate INFORMATIONAL exchange back to the sender.
658 */
659 static void send_notify_response(private_task_manager_t *this,
660 message_t *request, notify_type_t type,
661 chunk_t data)
662 {
663 message_t *response;
664 packet_t *packet;
665 host_t *me, *other;
666 u_int32_t mid;
667
668 if (request->get_exchange_type(request) == INFORMATIONAL_V1)
669 { /* don't respond to INFORMATIONAL requests to avoid a notify war */
670 DBG1(DBG_IKE, "ignore malformed INFORMATIONAL request");
671 return;
672 }
673
674 response = message_create(IKEV1_MAJOR_VERSION, IKEV1_MINOR_VERSION);
675 response->set_exchange_type(response, INFORMATIONAL_V1);
676 response->set_request(response, TRUE);
677 this->rng->get_bytes(this->rng, sizeof(mid), (void*)&mid);
678 response->set_message_id(response, mid);
679 response->add_notify(response, FALSE, type, data);
680 me = this->ike_sa->get_my_host(this->ike_sa);
681 if (me->is_anyaddr(me))
682 {
683 me = request->get_destination(request);
684 this->ike_sa->set_my_host(this->ike_sa, me->clone(me));
685 }
686 other = this->ike_sa->get_other_host(this->ike_sa);
687 if (other->is_anyaddr(other))
688 {
689 other = request->get_source(request);
690 this->ike_sa->set_other_host(this->ike_sa, other->clone(other));
691 }
692 response->set_source(response, me->clone(me));
693 response->set_destination(response, other->clone(other));
694 if (this->ike_sa->generate_message(this->ike_sa, response,
695 &packet) == SUCCESS)
696 {
697 charon->sender->send(charon->sender, packet);
698 }
699 response->destroy(response);
700 }
701
702 /**
703 * Parse the given message and verify that it is valid.
704 */
705 static status_t parse_message(private_task_manager_t *this, message_t *msg)
706 {
707 status_t status;
708
709 status = msg->parse_body(msg, this->ike_sa->get_keymat(this->ike_sa));
710
711 if (status != SUCCESS)
712 {
713 switch (status)
714 {
715 case NOT_SUPPORTED:
716 DBG1(DBG_IKE, "unsupported exchange type");
717 send_notify_response(this, msg,
718 INVALID_EXCHANGE_TYPE, chunk_empty);
719 break;
720 case PARSE_ERROR:
721 DBG1(DBG_IKE, "message parsing failed");
722 send_notify_response(this, msg,
723 PAYLOAD_MALFORMED, chunk_empty);
724 break;
725 case VERIFY_ERROR:
726 DBG1(DBG_IKE, "message verification failed");
727 send_notify_response(this, msg,
728 PAYLOAD_MALFORMED, chunk_empty);
729 break;
730 case FAILED:
731 DBG1(DBG_IKE, "integrity check failed");
732 send_notify_response(this, msg,
733 INVALID_HASH_INFORMATION, chunk_empty);
734 break;
735 case INVALID_STATE:
736 DBG1(DBG_IKE, "found encrypted message, but no keys available");
737 send_notify_response(this, msg,
738 PAYLOAD_MALFORMED, chunk_empty);
739 default:
740 break;
741 }
742 DBG1(DBG_IKE, "%N %s with message ID %d processing failed",
743 exchange_type_names, msg->get_exchange_type(msg),
744 msg->get_request(msg) ? "request" : "response",
745 msg->get_message_id(msg));
746
747 if (this->ike_sa->get_state(this->ike_sa) == IKE_CREATED)
748 { /* invalid initiation attempt, close SA */
749 return DESTROY_ME;
750 }
751 }
752 return status;
753 }
754
755 METHOD(task_manager_t, process_message, status_t,
756 private_task_manager_t *this, message_t *msg)
757 {
758 u_int32_t hash, mid;
759 host_t *me, *other;
760 status_t status;
761
762 /* TODO-IKEv1: update hosts more selectively */
763 me = msg->get_destination(msg);
764 other = msg->get_source(msg);
765 mid = msg->get_message_id(msg);
766
767 if ((mid && mid == this->initiating.mid) ||
768 (this->initiating.mid == 0 &&
769 this->active_tasks->get_count(this->active_tasks)))
770 {
771 msg->set_request(msg, FALSE);
772 status = parse_message(this, msg);
773 if (status != SUCCESS)
774 {
775 return status;
776 }
777 this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND,
778 time_monotonic(NULL));
779 this->ike_sa->update_hosts(this->ike_sa, me, other, TRUE);
780 charon->bus->message(charon->bus, msg, FALSE);
781 if (process_response(this, msg) != SUCCESS)
782 {
783 flush(this);
784 return DESTROY_ME;
785 }
786 }
787 else
788 {
789 hash = chunk_hash(msg->get_packet_data(msg));
790 if (hash == this->responding.hash)
791 {
792 DBG1(DBG_IKE, "received retransmit of request with ID %d, "
793 "retransmitting response", mid);
794 charon->sender->send(charon->sender,
795 this->responding.packet->clone(this->responding.packet));
796 return SUCCESS;
797 }
798 msg->set_request(msg, TRUE);
799 status = parse_message(this, msg);
800 if (status != SUCCESS)
801 {
802 return status;
803 }
804 /* if this IKE_SA is virgin, we check for a config */
805 if (this->ike_sa->get_ike_cfg(this->ike_sa) == NULL)
806 {
807 ike_sa_id_t *ike_sa_id;
808 ike_cfg_t *ike_cfg;
809 job_t *job;
810 ike_cfg = charon->backends->get_ike_cfg(charon->backends, me, other);
811 if (ike_cfg == NULL)
812 {
813 /* no config found for these hosts, destroy */
814 DBG1(DBG_IKE, "no IKE config found for %H...%H, sending %N",
815 me, other, notify_type_names, NO_PROPOSAL_CHOSEN);
816 send_notify_response(this, msg,
817 NO_PROPOSAL_CHOSEN, chunk_empty);
818 return DESTROY_ME;
819 }
820 this->ike_sa->set_ike_cfg(this->ike_sa, ike_cfg);
821 ike_cfg->destroy(ike_cfg);
822 /* add a timeout if peer does not establish it completely */
823 ike_sa_id = this->ike_sa->get_id(this->ike_sa);
824 job = (job_t*)delete_ike_sa_job_create(ike_sa_id, FALSE);
825 lib->scheduler->schedule_job(lib->scheduler, job,
826 lib->settings->get_int(lib->settings,
827 "charon.half_open_timeout", HALF_OPEN_IKE_SA_TIMEOUT));
828 }
829 this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND,
830 time_monotonic(NULL));
831 this->ike_sa->update_hosts(this->ike_sa, me, other, TRUE);
832 charon->bus->message(charon->bus, msg, TRUE);
833 if (process_request(this, msg) != SUCCESS)
834 {
835 flush(this);
836 return DESTROY_ME;
837 }
838
839 this->responding.mid = mid;
840 this->responding.hash = hash;
841 }
842 return SUCCESS;
843 }
844
845 METHOD(task_manager_t, queue_task, void,
846 private_task_manager_t *this, task_t *task)
847 {
848 DBG2(DBG_IKE, "queueing %N task", task_type_names, task->get_type(task));
849 this->queued_tasks->insert_last(this->queued_tasks, task);
850 }
851
852 METHOD(task_manager_t, adopt_tasks, void,
853 private_task_manager_t *this, task_manager_t *other_public)
854 {
855 private_task_manager_t *other = (private_task_manager_t*)other_public;
856 task_t *task;
857
858 /* move queued tasks from other to this */
859 while (other->queued_tasks->remove_last(other->queued_tasks,
860 (void**)&task) == SUCCESS)
861 {
862 DBG2(DBG_IKE, "migrating %N task", task_type_names, task->get_type(task));
863 task->migrate(task, this->ike_sa);
864 this->queued_tasks->insert_first(this->queued_tasks, task);
865 }
866 }
867
868 METHOD(task_manager_t, busy, bool,
869 private_task_manager_t *this)
870 {
871 return (this->active_tasks->get_count(this->active_tasks) > 0);
872 }
873
874 METHOD(task_manager_t, incr_mid, void,
875 private_task_manager_t *this, bool initiate)
876 {
877 }
878
879 METHOD(task_manager_t, reset, void,
880 private_task_manager_t *this, u_int32_t initiate, u_int32_t respond)
881 {
882 }
883
884 METHOD(task_manager_t, create_task_enumerator, enumerator_t*,
885 private_task_manager_t *this, task_queue_t queue)
886 {
887 switch (queue)
888 {
889 case TASK_QUEUE_ACTIVE:
890 return this->active_tasks->create_enumerator(this->active_tasks);
891 case TASK_QUEUE_PASSIVE:
892 return this->passive_tasks->create_enumerator(this->passive_tasks);
893 case TASK_QUEUE_QUEUED:
894 return this->queued_tasks->create_enumerator(this->queued_tasks);
895 default:
896 return enumerator_create_empty();
897 }
898 }
899
900 METHOD(task_manager_t, destroy, void,
901 private_task_manager_t *this)
902 {
903 flush(this);
904
905 this->active_tasks->destroy(this->active_tasks);
906 this->queued_tasks->destroy(this->queued_tasks);
907 this->passive_tasks->destroy(this->passive_tasks);
908
909 DESTROY_IF(this->responding.packet);
910 DESTROY_IF(this->initiating.packet);
911 DESTROY_IF(this->rng);
912 free(this);
913 }
914
915 /*
916 * see header file
917 */
918 task_manager_v1_t *task_manager_v1_create(ike_sa_t *ike_sa)
919 {
920 private_task_manager_t *this;
921
922 INIT(this,
923 .public = {
924 .task_manager = {
925 .process_message = _process_message,
926 .queue_task = _queue_task,
927 .initiate = _initiate,
928 .retransmit = _retransmit,
929 .incr_mid = _incr_mid,
930 .reset = _reset,
931 .adopt_tasks = _adopt_tasks,
932 .busy = _busy,
933 .create_task_enumerator = _create_task_enumerator,
934 .destroy = _destroy,
935 },
936 },
937 .ike_sa = ike_sa,
938 .initiating.type = EXCHANGE_TYPE_UNDEFINED,
939 .rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK),
940 .queued_tasks = linked_list_create(),
941 .active_tasks = linked_list_create(),
942 .passive_tasks = linked_list_create(),
943 .retransmit_tries = lib->settings->get_int(lib->settings,
944 "charon.retransmit_tries", RETRANSMIT_TRIES),
945 .retransmit_timeout = lib->settings->get_double(lib->settings,
946 "charon.retransmit_timeout", RETRANSMIT_TIMEOUT),
947 .retransmit_base = lib->settings->get_double(lib->settings,
948 "charon.retransmit_base", RETRANSMIT_BASE),
949 );
950
951 return &this->public;
952 }