Annotation of embedaddon/strongswan/src/libcharon/sa/ikev2/task_manager_v2.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2007-2018 Tobias Brunner
3: * Copyright (C) 2007-2010 Martin Willi
4: * HSR 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_v2.h"
18:
19: #include <math.h>
20:
21: #include <collections/array.h>
22: #include <daemon.h>
23: #include <sa/ikev2/tasks/ike_init.h>
24: #include <sa/ikev2/tasks/ike_natd.h>
25: #include <sa/ikev2/tasks/ike_mobike.h>
26: #include <sa/ikev2/tasks/ike_auth.h>
27: #include <sa/ikev2/tasks/ike_auth_lifetime.h>
28: #include <sa/ikev2/tasks/ike_cert_pre.h>
29: #include <sa/ikev2/tasks/ike_cert_post.h>
30: #include <sa/ikev2/tasks/ike_rekey.h>
31: #include <sa/ikev2/tasks/ike_reauth.h>
32: #include <sa/ikev2/tasks/ike_reauth_complete.h>
33: #include <sa/ikev2/tasks/ike_redirect.h>
34: #include <sa/ikev2/tasks/ike_delete.h>
35: #include <sa/ikev2/tasks/ike_config.h>
36: #include <sa/ikev2/tasks/ike_dpd.h>
37: #include <sa/ikev2/tasks/ike_mid_sync.h>
38: #include <sa/ikev2/tasks/ike_vendor.h>
39: #include <sa/ikev2/tasks/ike_verify_peer_cert.h>
40: #include <sa/ikev2/tasks/child_create.h>
41: #include <sa/ikev2/tasks/child_rekey.h>
42: #include <sa/ikev2/tasks/child_delete.h>
43: #include <encoding/payloads/delete_payload.h>
44: #include <encoding/payloads/unknown_payload.h>
45: #include <processing/jobs/retransmit_job.h>
46: #include <processing/jobs/delete_ike_sa_job.h>
47: #include <processing/jobs/initiate_tasks_job.h>
48:
49: #ifdef ME
50: #include <sa/ikev2/tasks/ike_me.h>
51: #endif
52:
53: typedef struct private_task_manager_t private_task_manager_t;
54: typedef struct queued_task_t queued_task_t;
55:
56: /**
57: * private data of the task manager
58: */
59: struct private_task_manager_t {
60:
61: /**
62: * public functions
63: */
64: task_manager_v2_t public;
65:
66: /**
67: * associated IKE_SA we are serving
68: */
69: ike_sa_t *ike_sa;
70:
71: /**
72: * Exchange we are currently handling as responder
73: */
74: struct {
75: /**
76: * Message ID of the exchange
77: */
78: uint32_t mid;
79:
80: /**
81: * packet(s) for retransmission
82: */
83: array_t *packets;
84:
85: /**
86: * Helper to defragment the request
87: */
88: message_t *defrag;
89:
90: } responding;
91:
92: /**
93: * Exchange we are currently handling as initiator
94: */
95: struct {
96: /**
97: * Message ID of the exchange
98: */
99: uint32_t mid;
100:
101: /**
102: * how many times we have retransmitted so far
103: */
104: u_int retransmitted;
105:
106: /**
107: * packet(s) for retransmission
108: */
109: array_t *packets;
110:
111: /**
112: * type of the initiated exchange
113: */
114: exchange_type_t type;
115:
116: /**
117: * TRUE if exchange was deferred because no path was available
118: */
119: bool deferred;
120:
121: /**
122: * Helper to defragment the response
123: */
124: message_t *defrag;
125:
126: } initiating;
127:
128: /**
129: * Array of queued tasks not yet in action
130: */
131: array_t *queued_tasks;
132:
133: /**
134: * Array of active tasks, initiated by ourselves
135: */
136: array_t *active_tasks;
137:
138: /**
139: * Array of tasks initiated by peer
140: */
141: array_t *passive_tasks;
142:
143: /**
144: * the task manager has been reset
145: */
146: bool reset;
147:
148: /**
149: * Number of times we retransmit messages before giving up
150: */
151: u_int retransmit_tries;
152:
153: /**
154: * Retransmission timeout
155: */
156: double retransmit_timeout;
157:
158: /**
159: * Base to calculate retransmission timeout
160: */
161: double retransmit_base;
162:
163: /**
164: * Jitter to apply to calculated retransmit timeout (in percent)
165: */
166: u_int retransmit_jitter;
167:
168: /**
169: * Limit retransmit timeout to this value
170: */
171: uint32_t retransmit_limit;
172:
173: /**
174: * Use make-before-break instead of break-before-make reauth?
175: */
176: bool make_before_break;
177: };
178:
179: /**
180: * Queued tasks
181: */
182: struct queued_task_t {
183:
184: /**
185: * Queued task
186: */
187: task_t *task;
188:
189: /**
190: * Time before which the task is not to be initiated
191: */
192: timeval_t time;
193: };
194:
195: /**
196: * Reset retransmission packet list
197: */
198: static void clear_packets(array_t *array)
199: {
200: packet_t *packet;
201:
202: while (array_remove(array, ARRAY_TAIL, &packet))
203: {
204: packet->destroy(packet);
205: }
206: }
207:
208: METHOD(task_manager_t, flush_queue, void,
209: private_task_manager_t *this, task_queue_t queue)
210: {
211: array_t *array;
212: task_t *task;
213:
214: switch (queue)
215: {
216: case TASK_QUEUE_ACTIVE:
217: array = this->active_tasks;
218: break;
219: case TASK_QUEUE_PASSIVE:
220: array = this->passive_tasks;
221: break;
222: case TASK_QUEUE_QUEUED:
223: array = this->queued_tasks;
224: break;
225: default:
226: return;
227: }
228: while (array_remove(array, ARRAY_TAIL, &task))
229: {
230: if (queue == TASK_QUEUE_QUEUED)
231: {
232: queued_task_t *queued = (queued_task_t*)task;
233: task = queued->task;
234: free(queued);
235: }
236: task->destroy(task);
237: }
238: }
239:
240: METHOD(task_manager_t, flush, void,
241: private_task_manager_t *this)
242: {
243: flush_queue(this, TASK_QUEUE_QUEUED);
244: flush_queue(this, TASK_QUEUE_PASSIVE);
245: flush_queue(this, TASK_QUEUE_ACTIVE);
246: }
247:
248: /**
249: * Move a task of a specific type from the queue to the active list, if it is
250: * not delayed.
251: */
252: static bool activate_task(private_task_manager_t *this, task_type_t type)
253: {
254: enumerator_t *enumerator;
255: queued_task_t *queued;
256: timeval_t now;
257: bool found = FALSE;
258:
259: time_monotonic(&now);
260:
261: enumerator = array_create_enumerator(this->queued_tasks);
262: while (enumerator->enumerate(enumerator, (void**)&queued))
263: {
264: if (queued->task->get_type(queued->task) == type &&
265: !timercmp(&now, &queued->time, <))
266: {
267: DBG2(DBG_IKE, " activating %N task", task_type_names, type);
268: array_remove_at(this->queued_tasks, enumerator);
269: array_insert(this->active_tasks, ARRAY_TAIL, queued->task);
270: free(queued);
271: found = TRUE;
272: break;
273: }
274: }
275: enumerator->destroy(enumerator);
276: return found;
277: }
278:
279: /**
280: * Send packets in the given array (they get cloned). Optionally, the
281: * source and destination addresses are changed before sending it.
282: */
283: static void send_packets(private_task_manager_t *this, array_t *packets,
284: host_t *src, host_t *dst)
285: {
286: packet_t *packet, *clone;
287: int i;
288:
289: for (i = 0; i < array_count(packets); i++)
290: {
291: array_get(packets, i, &packet);
292: clone = packet->clone(packet);
293: if (src)
294: {
295: clone->set_source(clone, src->clone(src));
296: }
297: if (dst)
298: {
299: clone->set_destination(clone, dst->clone(dst));
300: }
301: charon->sender->send(charon->sender, clone);
302: }
303: }
304:
305: /**
306: * Generates the given message and stores packet(s) in the given array
307: */
308: static bool generate_message(private_task_manager_t *this, message_t *message,
309: array_t **packets)
310: {
311: enumerator_t *fragments;
312: packet_t *fragment;
313:
314: if (this->ike_sa->generate_message_fragmented(this->ike_sa, message,
315: &fragments) != SUCCESS)
316: {
317: return FALSE;
318: }
319: while (fragments->enumerate(fragments, &fragment))
320: {
321: array_insert_create(packets, ARRAY_TAIL, fragment);
322: }
323: fragments->destroy(fragments);
324: array_compress(*packets);
325: return TRUE;
326: }
327:
328: METHOD(task_manager_t, retransmit, status_t,
329: private_task_manager_t *this, uint32_t message_id)
330: {
331: if (message_id == this->initiating.mid &&
332: array_count(this->initiating.packets))
333: {
334: uint32_t timeout, max_jitter;
335: job_t *job;
336: enumerator_t *enumerator;
337: packet_t *packet;
338: task_t *task;
339: ike_mobike_t *mobike = NULL;
340:
341: array_get(this->initiating.packets, 0, &packet);
342:
343: /* check if we are retransmitting a MOBIKE routability check */
344: if (this->initiating.type == INFORMATIONAL)
345: {
346: enumerator = array_create_enumerator(this->active_tasks);
347: while (enumerator->enumerate(enumerator, (void*)&task))
348: {
349: if (task->get_type(task) == TASK_IKE_MOBIKE)
350: {
351: mobike = (ike_mobike_t*)task;
352: break;
353: }
354: }
355: enumerator->destroy(enumerator);
356: }
357:
358: if (!mobike || !mobike->is_probing(mobike))
359: {
360: if (this->initiating.retransmitted <= this->retransmit_tries)
361: {
362: timeout = (uint32_t)(this->retransmit_timeout * 1000.0 *
363: pow(this->retransmit_base, this->initiating.retransmitted));
364:
365: if (this->retransmit_limit)
366: {
367: timeout = min(timeout, this->retransmit_limit);
368: }
369: if (this->retransmit_jitter)
370: {
371: max_jitter = (timeout / 100.0) * this->retransmit_jitter;
372: timeout -= max_jitter * (random() / (RAND_MAX + 1.0));
373: }
374: }
375: else
376: {
377: DBG1(DBG_IKE, "giving up after %d retransmits",
378: this->initiating.retransmitted - 1);
379: charon->bus->alert(charon->bus, ALERT_RETRANSMIT_SEND_TIMEOUT,
380: packet);
381: return DESTROY_ME;
382: }
383:
384: if (this->initiating.retransmitted)
385: {
386: DBG1(DBG_IKE, "retransmit %d of request with message ID %d",
387: this->initiating.retransmitted, message_id);
388: charon->bus->alert(charon->bus, ALERT_RETRANSMIT_SEND, packet,
389: this->initiating.retransmitted);
390: }
391: if (!mobike)
392: {
393: send_packets(this, this->initiating.packets,
394: this->ike_sa->get_my_host(this->ike_sa),
395: this->ike_sa->get_other_host(this->ike_sa));
396: }
397: else
398: {
399: if (!mobike->transmit(mobike, packet))
400: {
401: DBG1(DBG_IKE, "no route found to reach peer, MOBIKE update "
402: "deferred");
403: this->ike_sa->set_condition(this->ike_sa, COND_STALE, TRUE);
404: this->initiating.deferred = TRUE;
405: return SUCCESS;
406: }
407: else if (mobike->is_probing(mobike))
408: {
409: timeout = ROUTABILITY_CHECK_INTERVAL;
410: }
411: }
412: }
413: else
414: { /* for routability checks, we use a more aggressive behavior */
415: if (this->initiating.retransmitted <= ROUTABILITY_CHECK_TRIES)
416: {
417: timeout = ROUTABILITY_CHECK_INTERVAL;
418: }
419: else
420: {
421: DBG1(DBG_IKE, "giving up after %d path probings",
422: this->initiating.retransmitted - 1);
423: return DESTROY_ME;
424: }
425:
426: if (this->initiating.retransmitted)
427: {
428: DBG1(DBG_IKE, "path probing attempt %d",
429: this->initiating.retransmitted);
430: }
431: /* TODO-FRAG: presumably these small packets are not fragmented,
432: * we should maybe ensure this is the case when generating them */
433: if (!mobike->transmit(mobike, packet))
434: {
435: DBG1(DBG_IKE, "no route found to reach peer, path probing "
436: "deferred");
437: this->ike_sa->set_condition(this->ike_sa, COND_STALE, TRUE);
438: this->initiating.deferred = TRUE;
439: return SUCCESS;
440: }
441: }
442:
443: this->initiating.retransmitted++;
444: job = (job_t*)retransmit_job_create(this->initiating.mid,
445: this->ike_sa->get_id(this->ike_sa));
446: lib->scheduler->schedule_job_ms(lib->scheduler, job, timeout);
447: }
448: return SUCCESS;
449: }
450:
451: METHOD(task_manager_t, initiate, status_t,
452: private_task_manager_t *this)
453: {
454: enumerator_t *enumerator;
455: task_t *task;
456: message_t *message;
457: host_t *me, *other;
458: exchange_type_t exchange = 0;
459:
460: if (this->initiating.type != EXCHANGE_TYPE_UNDEFINED)
461: {
462: DBG2(DBG_IKE, "delaying task initiation, %N exchange in progress",
463: exchange_type_names, this->initiating.type);
464: /* do not initiate if we already have a message in the air */
465: if (this->initiating.deferred)
466: { /* re-initiate deferred exchange */
467: this->initiating.deferred = FALSE;
468: this->initiating.retransmitted = 0;
469: return retransmit(this, this->initiating.mid);
470: }
471: return SUCCESS;
472: }
473:
474: if (array_count(this->active_tasks) == 0)
475: {
476: DBG2(DBG_IKE, "activating new tasks");
477: switch (this->ike_sa->get_state(this->ike_sa))
478: {
479: case IKE_CREATED:
480: activate_task(this, TASK_IKE_VENDOR);
481: if (activate_task(this, TASK_IKE_INIT))
482: {
483: this->initiating.mid = 0;
484: exchange = IKE_SA_INIT;
485: activate_task(this, TASK_IKE_NATD);
486: activate_task(this, TASK_IKE_CERT_PRE);
487: #ifdef ME
488: /* this task has to be activated before the TASK_IKE_AUTH
489: * task, because that task pregenerates the packet after
490: * which no payloads can be added to the message anymore.
491: */
492: activate_task(this, TASK_IKE_ME);
493: #endif /* ME */
494: activate_task(this, TASK_IKE_AUTH);
495: activate_task(this, TASK_IKE_CERT_POST);
496: activate_task(this, TASK_IKE_CONFIG);
497: activate_task(this, TASK_CHILD_CREATE);
498: activate_task(this, TASK_IKE_AUTH_LIFETIME);
499: activate_task(this, TASK_IKE_MOBIKE);
500: }
501: break;
502: case IKE_ESTABLISHED:
503: if (activate_task(this, TASK_IKE_MOBIKE))
504: {
505: exchange = INFORMATIONAL;
506: break;
507: }
508: if (activate_task(this, TASK_IKE_DELETE))
509: {
510: exchange = INFORMATIONAL;
511: break;
512: }
513: if (activate_task(this, TASK_IKE_REDIRECT))
514: {
515: exchange = INFORMATIONAL;
516: break;
517: }
518: if (activate_task(this, TASK_CHILD_DELETE))
519: {
520: exchange = INFORMATIONAL;
521: break;
522: }
523: if (activate_task(this, TASK_IKE_REAUTH))
524: {
525: exchange = INFORMATIONAL;
526: break;
527: }
528: if (activate_task(this, TASK_CHILD_CREATE))
529: {
530: exchange = CREATE_CHILD_SA;
531: break;
532: }
533: if (activate_task(this, TASK_CHILD_REKEY))
534: {
535: exchange = CREATE_CHILD_SA;
536: break;
537: }
538: if (activate_task(this, TASK_IKE_REKEY))
539: {
540: exchange = CREATE_CHILD_SA;
541: break;
542: }
543: if (activate_task(this, TASK_IKE_DPD))
544: {
545: exchange = INFORMATIONAL;
546: break;
547: }
548: if (activate_task(this, TASK_IKE_AUTH_LIFETIME))
549: {
550: exchange = INFORMATIONAL;
551: break;
552: }
553: #ifdef ME
554: if (activate_task(this, TASK_IKE_ME))
555: {
556: exchange = ME_CONNECT;
557: break;
558: }
559: #endif /* ME */
560: if (activate_task(this, TASK_IKE_REAUTH_COMPLETE))
561: {
562: exchange = INFORMATIONAL;
563: break;
564: }
565: if (activate_task(this, TASK_IKE_VERIFY_PEER_CERT))
566: {
567: exchange = INFORMATIONAL;
568: break;
569: }
570: case IKE_REKEYING:
571: case IKE_REKEYED:
572: if (activate_task(this, TASK_IKE_DELETE))
573: {
574: exchange = INFORMATIONAL;
575: break;
576: }
577: case IKE_DELETING:
578: default:
579: break;
580: }
581: }
582: else
583: {
584: DBG2(DBG_IKE, "reinitiating already active tasks");
585: enumerator = array_create_enumerator(this->active_tasks);
586: while (enumerator->enumerate(enumerator, &task))
587: {
588: DBG2(DBG_IKE, " %N task", task_type_names, task->get_type(task));
589: switch (task->get_type(task))
590: {
591: case TASK_IKE_INIT:
592: exchange = IKE_SA_INIT;
593: break;
594: case TASK_IKE_AUTH:
595: exchange = IKE_AUTH;
596: break;
597: case TASK_CHILD_CREATE:
598: case TASK_CHILD_REKEY:
599: case TASK_IKE_REKEY:
600: exchange = CREATE_CHILD_SA;
601: break;
602: case TASK_IKE_MOBIKE:
603: exchange = INFORMATIONAL;
604: break;
605: default:
606: continue;
607: }
608: break;
609: }
610: enumerator->destroy(enumerator);
611: }
612:
613: if (exchange == 0)
614: {
615: DBG2(DBG_IKE, "nothing to initiate");
616: /* nothing to do yet... */
617: return SUCCESS;
618: }
619:
620: me = this->ike_sa->get_my_host(this->ike_sa);
621: other = this->ike_sa->get_other_host(this->ike_sa);
622:
623: message = message_create(IKEV2_MAJOR_VERSION, IKEV2_MINOR_VERSION);
624: message->set_message_id(message, this->initiating.mid);
625: message->set_source(message, me->clone(me));
626: message->set_destination(message, other->clone(other));
627: message->set_exchange_type(message, exchange);
628: this->initiating.type = exchange;
629: this->initiating.retransmitted = 0;
630: this->initiating.deferred = FALSE;
631:
632: enumerator = array_create_enumerator(this->active_tasks);
633: while (enumerator->enumerate(enumerator, &task))
634: {
635: switch (task->build(task, message))
636: {
637: case SUCCESS:
638: /* task completed, remove it */
639: array_remove_at(this->active_tasks, enumerator);
640: task->destroy(task);
641: break;
642: case NEED_MORE:
643: /* processed, but task needs another exchange */
644: break;
645: case FAILED:
646: default:
647: this->initiating.type = EXCHANGE_TYPE_UNDEFINED;
648: if (this->ike_sa->get_state(this->ike_sa) != IKE_CONNECTING &&
649: this->ike_sa->get_state(this->ike_sa) != IKE_REKEYED)
650: {
651: charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
652: }
653: /* FALL */
654: case DESTROY_ME:
655: /* critical failure, destroy IKE_SA */
656: enumerator->destroy(enumerator);
657: message->destroy(message);
658: flush(this);
659: return DESTROY_ME;
660: }
661: }
662: enumerator->destroy(enumerator);
663:
664: /* update exchange type if a task changed it */
665: this->initiating.type = message->get_exchange_type(message);
666: if (this->initiating.type == EXCHANGE_TYPE_UNDEFINED)
667: {
668: message->destroy(message);
669: return initiate(this);
670: }
671:
672: if (!generate_message(this, message, &this->initiating.packets))
673: {
674: /* message generation failed. There is nothing more to do than to
675: * close the SA */
676: message->destroy(message);
677: flush(this);
678: charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
679: return DESTROY_ME;
680: }
681: message->destroy(message);
682:
683: array_compress(this->active_tasks);
684: array_compress(this->queued_tasks);
685:
686: return retransmit(this, this->initiating.mid);
687: }
688:
689: /**
690: * handle an incoming response message
691: */
692: static status_t process_response(private_task_manager_t *this,
693: message_t *message)
694: {
695: enumerator_t *enumerator;
696: task_t *task;
697:
698: if (message->get_exchange_type(message) != this->initiating.type)
699: {
700: DBG1(DBG_IKE, "received %N response, but expected %N",
701: exchange_type_names, message->get_exchange_type(message),
702: exchange_type_names, this->initiating.type);
703: charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
704: return DESTROY_ME;
705: }
706:
707: /* handle fatal INVALID_SYNTAX notifies */
708: switch (message->get_exchange_type(message))
709: {
710: case CREATE_CHILD_SA:
711: case INFORMATIONAL:
712: if (message->get_notify(message, INVALID_SYNTAX))
713: {
714: DBG1(DBG_IKE, "received %N notify error, destroying IKE_SA",
715: notify_type_names, INVALID_SYNTAX);
716: charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
717: return DESTROY_ME;
718: }
719: break;
720: default:
721: break;
722: }
723:
724: enumerator = array_create_enumerator(this->active_tasks);
725: while (enumerator->enumerate(enumerator, &task))
726: {
727: if (!task->pre_process)
728: {
729: continue;
730: }
731: switch (task->pre_process(task, message))
732: {
733: case SUCCESS:
734: break;
735: case FAILED:
736: default:
737: /* just ignore the message */
738: DBG1(DBG_IKE, "ignore invalid %N response",
739: exchange_type_names, message->get_exchange_type(message));
740: enumerator->destroy(enumerator);
741: return SUCCESS;
742: case DESTROY_ME:
743: /* critical failure, destroy IKE_SA */
744: enumerator->destroy(enumerator);
745: return DESTROY_ME;
746: }
747: }
748: enumerator->destroy(enumerator);
749:
750: if (this->initiating.retransmitted > 1)
751: {
752: packet_t *packet = NULL;
753: array_get(this->initiating.packets, 0, &packet);
754: charon->bus->alert(charon->bus, ALERT_RETRANSMIT_SEND_CLEARED, packet);
755: }
756:
757: /* catch if we get reset while processing */
758: this->reset = FALSE;
759: enumerator = array_create_enumerator(this->active_tasks);
760: while (enumerator->enumerate(enumerator, &task))
761: {
762: switch (task->process(task, message))
763: {
764: case SUCCESS:
765: /* task completed, remove it */
766: array_remove_at(this->active_tasks, enumerator);
767: task->destroy(task);
768: break;
769: case NEED_MORE:
770: /* processed, but task needs another exchange */
771: break;
772: case FAILED:
773: default:
774: charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
775: /* FALL */
776: case DESTROY_ME:
777: /* critical failure, destroy IKE_SA */
778: array_remove_at(this->active_tasks, enumerator);
779: enumerator->destroy(enumerator);
780: task->destroy(task);
781: return DESTROY_ME;
782: }
783: if (this->reset)
784: { /* start all over again if we were reset */
785: this->reset = FALSE;
786: enumerator->destroy(enumerator);
787: return initiate(this);
788: }
789: }
790: enumerator->destroy(enumerator);
791:
792: this->initiating.mid++;
793: this->initiating.type = EXCHANGE_TYPE_UNDEFINED;
794: clear_packets(this->initiating.packets);
795:
796: array_compress(this->active_tasks);
797:
798: return initiate(this);
799: }
800:
801: /**
802: * handle exchange collisions
803: */
804: static bool handle_collisions(private_task_manager_t *this, task_t *task)
805: {
806: enumerator_t *enumerator;
807: task_t *active;
808: task_type_t type;
809:
810: type = task->get_type(task);
811:
812: /* do we have to check */
813: if (type == TASK_IKE_REKEY || type == TASK_CHILD_REKEY ||
814: type == TASK_CHILD_DELETE || type == TASK_IKE_DELETE)
815: {
816: /* find an exchange collision, and notify these tasks */
817: enumerator = array_create_enumerator(this->active_tasks);
818: while (enumerator->enumerate(enumerator, &active))
819: {
820: switch (active->get_type(active))
821: {
822: case TASK_IKE_REKEY:
823: if (type == TASK_IKE_REKEY || type == TASK_IKE_DELETE)
824: {
825: ike_rekey_t *rekey = (ike_rekey_t*)active;
826: rekey->collide(rekey, task);
827: break;
828: }
829: continue;
830: case TASK_CHILD_REKEY:
831: if (type == TASK_CHILD_REKEY || type == TASK_CHILD_DELETE)
832: {
833: child_rekey_t *rekey = (child_rekey_t*)active;
834: rekey->collide(rekey, task);
835: break;
836: }
837: continue;
838: default:
839: continue;
840: }
841: enumerator->destroy(enumerator);
842: return TRUE;
843: }
844: enumerator->destroy(enumerator);
845: }
846: return FALSE;
847: }
848:
849: /**
850: * build a response depending on the "passive" task list
851: */
852: static status_t build_response(private_task_manager_t *this, message_t *request)
853: {
854: enumerator_t *enumerator;
855: task_t *task;
856: message_t *message;
857: host_t *me, *other;
858: bool delete = FALSE, hook = FALSE, mid_sync = FALSE;
859: ike_sa_id_t *id = NULL;
860: uint64_t responder_spi = 0;
861: bool result;
862:
863: me = request->get_destination(request);
864: other = request->get_source(request);
865:
866: message = message_create(IKEV2_MAJOR_VERSION, IKEV2_MINOR_VERSION);
867: message->set_exchange_type(message, request->get_exchange_type(request));
868: /* send response along the path the request came in */
869: message->set_source(message, me->clone(me));
870: message->set_destination(message, other->clone(other));
871: message->set_message_id(message, this->responding.mid);
872: message->set_request(message, FALSE);
873:
874: enumerator = array_create_enumerator(this->passive_tasks);
875: while (enumerator->enumerate(enumerator, (void*)&task))
876: {
877: if (task->get_type(task) == TASK_IKE_MID_SYNC)
878: {
879: mid_sync = TRUE;
880: }
881: switch (task->build(task, message))
882: {
883: case SUCCESS:
884: /* task completed, remove it */
885: array_remove_at(this->passive_tasks, enumerator);
886: if (!handle_collisions(this, task))
887: {
888: task->destroy(task);
889: }
890: break;
891: case NEED_MORE:
892: /* processed, but task needs another exchange */
893: if (handle_collisions(this, task))
894: {
895: array_remove_at(this->passive_tasks, enumerator);
896: }
897: break;
898: case FAILED:
899: default:
900: hook = TRUE;
901: /* FALL */
902: case DESTROY_ME:
903: /* destroy IKE_SA, but SEND response first */
904: if (handle_collisions(this, task))
905: {
906: array_remove_at(this->passive_tasks, enumerator);
907: }
908: delete = TRUE;
909: break;
910: }
911: if (delete)
912: {
913: break;
914: }
915: }
916: enumerator->destroy(enumerator);
917:
918: /* RFC 5996, section 2.6 mentions that in the event of a failure during
919: * IKE_SA_INIT the responder's SPI will be 0 in the response, while it
920: * actually explicitly allows it to be non-zero. Since we use the responder
921: * SPI to create hashes in the IKE_SA manager we can only set the SPI to
922: * zero temporarily, otherwise checking the SA in would fail. */
923: if (delete && request->get_exchange_type(request) == IKE_SA_INIT)
924: {
925: id = this->ike_sa->get_id(this->ike_sa);
926: responder_spi = id->get_responder_spi(id);
927: id->set_responder_spi(id, 0);
928: }
929:
930: /* message complete, send it */
931: clear_packets(this->responding.packets);
932: result = generate_message(this, message, &this->responding.packets);
933: message->destroy(message);
934: if (id)
935: {
936: id->set_responder_spi(id, responder_spi);
937: }
938: if (!result)
939: {
940: charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
941: return DESTROY_ME;
942: }
943:
944: send_packets(this, this->responding.packets, NULL, NULL);
945: if (delete)
946: {
947: if (hook)
948: {
949: charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
950: }
951: return DESTROY_ME;
952: }
953: else if (mid_sync)
954: {
955: /* we don't want to resend messages to sync MIDs if requests with the
956: * previous MID arrive */
957: clear_packets(this->responding.packets);
958: /* avoid increasing the expected message ID after handling a message
959: * to sync MIDs with MID 0 */
960: return NEED_MORE;
961: }
962:
963: array_compress(this->passive_tasks);
964:
965: return SUCCESS;
966: }
967:
968: /**
969: * handle an incoming request message
970: */
971: static status_t process_request(private_task_manager_t *this,
972: message_t *message)
973: {
974: enumerator_t *enumerator;
975: task_t *task = NULL;
976: payload_t *payload;
977: notify_payload_t *notify;
978: delete_payload_t *delete;
979: ike_sa_state_t state;
980:
981: if (array_count(this->passive_tasks) == 0)
982: { /* create tasks depending on request type, if not already some queued */
983: state = this->ike_sa->get_state(this->ike_sa);
984: switch (message->get_exchange_type(message))
985: {
986: case IKE_SA_INIT:
987: {
988: task = (task_t*)ike_vendor_create(this->ike_sa, FALSE);
989: array_insert(this->passive_tasks, ARRAY_TAIL, task);
990: task = (task_t*)ike_init_create(this->ike_sa, FALSE, NULL);
991: array_insert(this->passive_tasks, ARRAY_TAIL, task);
992: task = (task_t*)ike_natd_create(this->ike_sa, FALSE);
993: array_insert(this->passive_tasks, ARRAY_TAIL, task);
994: task = (task_t*)ike_cert_pre_create(this->ike_sa, FALSE);
995: array_insert(this->passive_tasks, ARRAY_TAIL, task);
996: #ifdef ME
997: task = (task_t*)ike_me_create(this->ike_sa, FALSE);
998: array_insert(this->passive_tasks, ARRAY_TAIL, task);
999: #endif /* ME */
1000: task = (task_t*)ike_auth_create(this->ike_sa, FALSE);
1001: array_insert(this->passive_tasks, ARRAY_TAIL, task);
1002: task = (task_t*)ike_cert_post_create(this->ike_sa, FALSE);
1003: array_insert(this->passive_tasks, ARRAY_TAIL, task);
1004: task = (task_t*)ike_config_create(this->ike_sa, FALSE);
1005: array_insert(this->passive_tasks, ARRAY_TAIL, task);
1006: task = (task_t*)child_create_create(this->ike_sa, NULL, FALSE,
1007: NULL, NULL);
1008: array_insert(this->passive_tasks, ARRAY_TAIL, task);
1009: task = (task_t*)ike_auth_lifetime_create(this->ike_sa, FALSE);
1010: array_insert(this->passive_tasks, ARRAY_TAIL, task);
1011: task = (task_t*)ike_mobike_create(this->ike_sa, FALSE);
1012: array_insert(this->passive_tasks, ARRAY_TAIL, task);
1013: break;
1014: }
1015: case CREATE_CHILD_SA:
1016: { /* FIXME: we should prevent this on mediation connections */
1017: bool notify_found = FALSE, ts_found = FALSE;
1018:
1019: if (state == IKE_CREATED ||
1020: state == IKE_CONNECTING)
1021: {
1022: DBG1(DBG_IKE, "received CREATE_CHILD_SA request for "
1023: "unestablished IKE_SA, rejected");
1024: return FAILED;
1025: }
1026:
1027: enumerator = message->create_payload_enumerator(message);
1028: while (enumerator->enumerate(enumerator, &payload))
1029: {
1030: switch (payload->get_type(payload))
1031: {
1032: case PLV2_NOTIFY:
1033: { /* if we find a rekey notify, its CHILD_SA rekeying */
1034: notify = (notify_payload_t*)payload;
1035: if (notify->get_notify_type(notify) == REKEY_SA &&
1036: (notify->get_protocol_id(notify) == PROTO_AH ||
1037: notify->get_protocol_id(notify) == PROTO_ESP))
1038: {
1039: notify_found = TRUE;
1040: }
1041: break;
1042: }
1043: case PLV2_TS_INITIATOR:
1044: case PLV2_TS_RESPONDER:
1045: { /* if we don't find a TS, its IKE rekeying */
1046: ts_found = TRUE;
1047: break;
1048: }
1049: default:
1050: break;
1051: }
1052: }
1053: enumerator->destroy(enumerator);
1054:
1055: if (ts_found)
1056: {
1057: if (notify_found)
1058: {
1059: task = (task_t*)child_rekey_create(this->ike_sa,
1060: PROTO_NONE, 0);
1061: }
1062: else
1063: {
1064: task = (task_t*)child_create_create(this->ike_sa, NULL,
1065: FALSE, NULL, NULL);
1066: }
1067: }
1068: else
1069: {
1070: task = (task_t*)ike_rekey_create(this->ike_sa, FALSE);
1071: }
1072: array_insert(this->passive_tasks, ARRAY_TAIL, task);
1073: break;
1074: }
1075: case INFORMATIONAL:
1076: {
1077: enumerator = message->create_payload_enumerator(message);
1078: while (enumerator->enumerate(enumerator, &payload))
1079: {
1080: switch (payload->get_type(payload))
1081: {
1082: case PLV2_NOTIFY:
1083: {
1084: notify = (notify_payload_t*)payload;
1085: if (state == IKE_REKEYED)
1086: {
1087: DBG1(DBG_IKE, "received unexpected notify %N "
1088: "for rekeyed IKE_SA, ignored",
1089: notify_type_names,
1090: notify->get_notify_type(notify));
1091: break;
1092: }
1093: switch (notify->get_notify_type(notify))
1094: {
1095: case ADDITIONAL_IP4_ADDRESS:
1096: case ADDITIONAL_IP6_ADDRESS:
1097: case NO_ADDITIONAL_ADDRESSES:
1098: case UPDATE_SA_ADDRESSES:
1099: case NO_NATS_ALLOWED:
1100: case UNACCEPTABLE_ADDRESSES:
1101: case UNEXPECTED_NAT_DETECTED:
1102: case COOKIE2:
1103: case NAT_DETECTION_SOURCE_IP:
1104: case NAT_DETECTION_DESTINATION_IP:
1105: task = (task_t*)ike_mobike_create(
1106: this->ike_sa, FALSE);
1107: break;
1108: case AUTH_LIFETIME:
1109: task = (task_t*)ike_auth_lifetime_create(
1110: this->ike_sa, FALSE);
1111: break;
1112: case AUTHENTICATION_FAILED:
1113: /* initiator failed to authenticate us.
1114: * We use ike_delete to handle this, which
1115: * invokes all the required hooks. */
1116: task = (task_t*)ike_delete_create(
1117: this->ike_sa, FALSE);
1118: break;
1119: case REDIRECT:
1120: task = (task_t*)ike_redirect_create(
1121: this->ike_sa, NULL);
1122: break;
1123: case IKEV2_MESSAGE_ID_SYNC:
1124: task = (task_t*)ike_mid_sync_create(
1125: this->ike_sa);
1126: break;
1127: default:
1128: break;
1129: }
1130: break;
1131: }
1132: case PLV2_DELETE:
1133: {
1134: delete = (delete_payload_t*)payload;
1135: if (delete->get_protocol_id(delete) == PROTO_IKE)
1136: {
1137: task = (task_t*)ike_delete_create(this->ike_sa,
1138: FALSE);
1139: }
1140: else
1141: {
1142: task = (task_t*)child_delete_create(this->ike_sa,
1143: PROTO_NONE, 0, FALSE);
1144: }
1145: break;
1146: }
1147: default:
1148: break;
1149: }
1150: if (task)
1151: {
1152: break;
1153: }
1154: }
1155: enumerator->destroy(enumerator);
1156:
1157: if (task == NULL)
1158: {
1159: task = (task_t*)ike_dpd_create(FALSE);
1160: }
1161: array_insert(this->passive_tasks, ARRAY_TAIL, task);
1162: break;
1163: }
1164: #ifdef ME
1165: case ME_CONNECT:
1166: {
1167: task = (task_t*)ike_me_create(this->ike_sa, FALSE);
1168: array_insert(this->passive_tasks, ARRAY_TAIL, task);
1169: }
1170: #endif /* ME */
1171: default:
1172: break;
1173: }
1174: }
1175:
1176: enumerator = array_create_enumerator(this->passive_tasks);
1177: while (enumerator->enumerate(enumerator, &task))
1178: {
1179: if (!task->pre_process)
1180: {
1181: continue;
1182: }
1183: switch (task->pre_process(task, message))
1184: {
1185: case SUCCESS:
1186: break;
1187: case FAILED:
1188: default:
1189: /* just ignore the message */
1190: DBG1(DBG_IKE, "ignore invalid %N request",
1191: exchange_type_names, message->get_exchange_type(message));
1192: enumerator->destroy(enumerator);
1193: switch (message->get_exchange_type(message))
1194: {
1195: case IKE_SA_INIT:
1196: /* no point in keeping the SA when it was created with
1197: * an invalid IKE_SA_INIT message */
1198: return DESTROY_ME;
1199: default:
1200: /* remove tasks we queued for this request */
1201: flush_queue(this, TASK_QUEUE_PASSIVE);
1202: /* fall-through */
1203: case IKE_AUTH:
1204: return NEED_MORE;
1205: }
1206: case DESTROY_ME:
1207: /* critical failure, destroy IKE_SA */
1208: enumerator->destroy(enumerator);
1209: return DESTROY_ME;
1210: }
1211: }
1212: enumerator->destroy(enumerator);
1213:
1214: /* let the tasks process the message */
1215: enumerator = array_create_enumerator(this->passive_tasks);
1216: while (enumerator->enumerate(enumerator, (void*)&task))
1217: {
1218: switch (task->process(task, message))
1219: {
1220: case SUCCESS:
1221: /* task completed, remove it */
1222: array_remove_at(this->passive_tasks, enumerator);
1223: task->destroy(task);
1224: break;
1225: case NEED_MORE:
1226: /* processed, but task needs at least another call to build() */
1227: break;
1228: case FAILED:
1229: default:
1230: charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
1231: /* FALL */
1232: case DESTROY_ME:
1233: /* critical failure, destroy IKE_SA */
1234: array_remove_at(this->passive_tasks, enumerator);
1235: enumerator->destroy(enumerator);
1236: task->destroy(task);
1237: return DESTROY_ME;
1238: }
1239: }
1240: enumerator->destroy(enumerator);
1241:
1242: return build_response(this, message);
1243: }
1244:
1245: METHOD(task_manager_t, incr_mid, void,
1246: private_task_manager_t *this, bool initiate)
1247: {
1248: if (initiate)
1249: {
1250: this->initiating.mid++;
1251: }
1252: else
1253: {
1254: this->responding.mid++;
1255: }
1256: }
1257:
1258: METHOD(task_manager_t, get_mid, uint32_t,
1259: private_task_manager_t *this, bool initiate)
1260: {
1261: return initiate ? this->initiating.mid : this->responding.mid;
1262: }
1263:
1264: /**
1265: * Handle the given IKE fragment, if it is one.
1266: *
1267: * Returns SUCCESS if the message is not a fragment, and NEED_MORE if it was
1268: * handled properly. Error states are returned if the fragment was invalid or
1269: * the reassembled message could not have been processed properly.
1270: */
1271: static status_t handle_fragment(private_task_manager_t *this,
1272: message_t **defrag, message_t *msg)
1273: {
1274: message_t *reassembled;
1275: status_t status;
1276:
1277: if (!msg->get_payload(msg, PLV2_FRAGMENT))
1278: {
1279: return SUCCESS;
1280: }
1281: if (!*defrag)
1282: {
1283: *defrag = message_create_defrag(msg);
1284: if (!*defrag)
1285: {
1286: return FAILED;
1287: }
1288: }
1289: status = (*defrag)->add_fragment(*defrag, msg);
1290: if (status == SUCCESS)
1291: {
1292: /* reinject the reassembled message */
1293: reassembled = *defrag;
1294: *defrag = NULL;
1295: status = this->ike_sa->process_message(this->ike_sa, reassembled);
1296: if (status == SUCCESS)
1297: {
1298: /* avoid processing the last fragment */
1299: status = NEED_MORE;
1300: }
1301: reassembled->destroy(reassembled);
1302: }
1303: return status;
1304: }
1305:
1306: /**
1307: * Send a notify back to the sender
1308: */
1309: static void send_notify_response(private_task_manager_t *this,
1310: message_t *request, notify_type_t type,
1311: chunk_t data)
1312: {
1313: message_t *response;
1314: packet_t *packet;
1315: host_t *me, *other;
1316:
1317: response = message_create(IKEV2_MAJOR_VERSION, IKEV2_MINOR_VERSION);
1318: response->set_exchange_type(response, request->get_exchange_type(request));
1319: response->set_request(response, FALSE);
1320: response->set_message_id(response, request->get_message_id(request));
1321: response->add_notify(response, FALSE, type, data);
1322: me = this->ike_sa->get_my_host(this->ike_sa);
1323: if (me->is_anyaddr(me))
1324: {
1325: me = request->get_destination(request);
1326: this->ike_sa->set_my_host(this->ike_sa, me->clone(me));
1327: }
1328: other = this->ike_sa->get_other_host(this->ike_sa);
1329: if (other->is_anyaddr(other))
1330: {
1331: other = request->get_source(request);
1332: this->ike_sa->set_other_host(this->ike_sa, other->clone(other));
1333: }
1334: response->set_source(response, me->clone(me));
1335: response->set_destination(response, other->clone(other));
1336: if (this->ike_sa->generate_message(this->ike_sa, response,
1337: &packet) == SUCCESS)
1338: {
1339: charon->sender->send(charon->sender, packet);
1340: }
1341: response->destroy(response);
1342: }
1343:
1344: /**
1345: * Send an INVALID_SYNTAX notify and destroy the IKE_SA for authenticated
1346: * messages.
1347: */
1348: static status_t send_invalid_syntax(private_task_manager_t *this,
1349: message_t *msg)
1350: {
1351: send_notify_response(this, msg, INVALID_SYNTAX, chunk_empty);
1352: incr_mid(this, FALSE);
1353:
1354: /* IKE_SA_INIT is currently the only type the parser accepts unprotected,
1355: * don't destroy the IKE_SA if such a message is invalid */
1356: if (msg->get_exchange_type(msg) == IKE_SA_INIT)
1357: {
1358: return FAILED;
1359: }
1360: return DESTROY_ME;
1361: }
1362:
1363: /**
1364: * Parse the given message and verify that it is valid.
1365: */
1366: static status_t parse_message(private_task_manager_t *this, message_t *msg)
1367: {
1368: status_t parse_status, status;
1369: uint8_t type = 0;
1370:
1371: parse_status = msg->parse_body(msg, this->ike_sa->get_keymat(this->ike_sa));
1372:
1373: if (parse_status == SUCCESS)
1374: { /* check for unsupported critical payloads */
1375: enumerator_t *enumerator;
1376: unknown_payload_t *unknown;
1377: payload_t *payload;
1378:
1379: enumerator = msg->create_payload_enumerator(msg);
1380: while (enumerator->enumerate(enumerator, &payload))
1381: {
1382: if (payload->get_type(payload) == PL_UNKNOWN)
1383: {
1384: unknown = (unknown_payload_t*)payload;
1385: if (unknown->is_critical(unknown))
1386: {
1387: type = unknown->get_type(unknown);
1388: DBG1(DBG_ENC, "payload type %N is not supported, "
1389: "but payload is critical!", payload_type_names, type);
1390: parse_status = NOT_SUPPORTED;
1391: break;
1392: }
1393: }
1394: }
1395: enumerator->destroy(enumerator);
1396: }
1397:
1398: status = parse_status;
1399:
1400: if (parse_status != SUCCESS)
1401: {
1402: bool is_request = msg->get_request(msg);
1403:
1404: switch (parse_status)
1405: {
1406: case NOT_SUPPORTED:
1407: DBG1(DBG_IKE, "critical unknown payloads found");
1408: if (is_request)
1409: {
1410: send_notify_response(this, msg,
1411: UNSUPPORTED_CRITICAL_PAYLOAD,
1412: chunk_from_thing(type));
1413: incr_mid(this, FALSE);
1414: }
1415: break;
1416: case PARSE_ERROR:
1417: DBG1(DBG_IKE, "message parsing failed");
1418: if (is_request)
1419: {
1420: status = send_invalid_syntax(this, msg);
1421: }
1422: break;
1423: case VERIFY_ERROR:
1424: DBG1(DBG_IKE, "message verification failed");
1425: if (is_request)
1426: {
1427: status = send_invalid_syntax(this, msg);
1428: }
1429: break;
1430: case FAILED:
1431: DBG1(DBG_IKE, "integrity check failed");
1432: /* ignored */
1433: break;
1434: case INVALID_STATE:
1435: DBG1(DBG_IKE, "found encrypted message, but no keys available");
1436: default:
1437: break;
1438: }
1439: DBG1(DBG_IKE, "%N %s with message ID %d processing failed",
1440: exchange_type_names, msg->get_exchange_type(msg),
1441: is_request ? "request" : "response",
1442: msg->get_message_id(msg));
1443:
1444: charon->bus->alert(charon->bus, ALERT_PARSE_ERROR_BODY, msg,
1445: parse_status);
1446:
1447: switch (this->ike_sa->get_state(this->ike_sa))
1448: {
1449: case IKE_CREATED:
1450: /* invalid initiation attempt, close SA */
1451: status = DESTROY_ME;
1452: break;
1453: case IKE_CONNECTING:
1454: case IKE_REKEYED:
1455: /* don't trigger updown event in these states */
1456: break;
1457: default:
1458: if (status == DESTROY_ME)
1459: {
1460: charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
1461: }
1462: break;
1463: }
1464: }
1465: return status;
1466: }
1467:
1468: /**
1469: * Check if a message with message ID 0 looks like it is used to synchronize
1470: * the message IDs.
1471: */
1472: static bool looks_like_mid_sync(private_task_manager_t *this, message_t *msg,
1473: bool strict)
1474: {
1475: enumerator_t *enumerator;
1476: notify_payload_t *notify;
1477: payload_t *payload;
1478: bool found = FALSE, other = FALSE;
1479:
1480: if (msg->get_exchange_type(msg) == INFORMATIONAL)
1481: {
1482: enumerator = msg->create_payload_enumerator(msg);
1483: while (enumerator->enumerate(enumerator, &payload))
1484: {
1485: if (payload->get_type(payload) == PLV2_NOTIFY)
1486: {
1487: notify = (notify_payload_t*)payload;
1488: switch (notify->get_notify_type(notify))
1489: {
1490: case IKEV2_MESSAGE_ID_SYNC:
1491: case IPSEC_REPLAY_COUNTER_SYNC:
1492: found = TRUE;
1493: continue;
1494: default:
1495: break;
1496: }
1497: }
1498: if (strict)
1499: {
1500: other = TRUE;
1501: break;
1502: }
1503: }
1504: enumerator->destroy(enumerator);
1505: }
1506: return found && !other;
1507: }
1508:
1509: /**
1510: * Check whether we should reject the given request message
1511: */
1512: static inline bool reject_request(private_task_manager_t *this,
1513: message_t *msg)
1514: {
1515: ike_sa_state_t state;
1516: exchange_type_t type;
1517: ike_sa_id_t *ike_sa_id;
1518: bool reject = FALSE;
1519:
1520: state = this->ike_sa->get_state(this->ike_sa);
1521: type = msg->get_exchange_type(msg);
1522:
1523: /* reject initial messages if not received in specific states */
1524: switch (type)
1525: {
1526: case IKE_SA_INIT:
1527: reject = state != IKE_CREATED;
1528: break;
1529: case IKE_AUTH:
1530: reject = state != IKE_CONNECTING;
1531: break;
1532: default:
1533: break;
1534: }
1535:
1536: if (!reject)
1537: {
1538: switch (state)
1539: {
1540: /* after rekeying we only expect a DELETE in an INFORMATIONAL */
1541: case IKE_REKEYED:
1542: reject = type != INFORMATIONAL;
1543: break;
1544: /* also reject requests for half-open IKE_SAs as initiator */
1545: case IKE_CREATED:
1546: case IKE_CONNECTING:
1547: ike_sa_id = this->ike_sa->get_id(this->ike_sa);
1548: reject = ike_sa_id->is_initiator(ike_sa_id);
1549: break;
1550: default:
1551: break;
1552: }
1553: }
1554:
1555: if (reject)
1556: {
1557: DBG1(DBG_IKE, "ignoring %N in IKE_SA state %N", exchange_type_names,
1558: type, ike_sa_state_names, state);
1559: }
1560: return reject;
1561: }
1562: /**
1563: * Check if a message with message ID 0 looks like it is used to synchronize
1564: * the message IDs and we are prepared to process it.
1565: *
1566: * Note: This is not called if the responder never sent a message before (i.e.
1567: * we expect MID 0).
1568: */
1569: static bool is_mid_sync(private_task_manager_t *this, message_t *msg)
1570: {
1571: if (this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED &&
1572: this->ike_sa->supports_extension(this->ike_sa,
1573: EXT_IKE_MESSAGE_ID_SYNC))
1574: {
1575: return looks_like_mid_sync(this, msg, TRUE);
1576: }
1577: return FALSE;
1578: }
1579:
1580: METHOD(task_manager_t, process_message, status_t,
1581: private_task_manager_t *this, message_t *msg)
1582: {
1583: host_t *me, *other;
1584: status_t status;
1585: uint32_t mid;
1586: bool schedule_delete_job = FALSE;
1587:
1588: charon->bus->message(charon->bus, msg, TRUE, FALSE);
1589: status = parse_message(this, msg);
1590: if (status != SUCCESS)
1591: {
1592: return status;
1593: }
1594:
1595: me = msg->get_destination(msg);
1596: other = msg->get_source(msg);
1597:
1598: /* if this IKE_SA is virgin, we check for a config */
1599: if (this->ike_sa->get_ike_cfg(this->ike_sa) == NULL)
1600: {
1601: ike_cfg_t *ike_cfg;
1602:
1603: ike_cfg = charon->backends->get_ike_cfg(charon->backends,
1604: me, other, IKEV2);
1605: if (ike_cfg == NULL)
1606: {
1607: /* no config found for these hosts, destroy */
1608: DBG1(DBG_IKE, "no IKE config found for %H...%H, sending %N",
1609: me, other, notify_type_names, NO_PROPOSAL_CHOSEN);
1610: send_notify_response(this, msg,
1611: NO_PROPOSAL_CHOSEN, chunk_empty);
1612: return DESTROY_ME;
1613: }
1614: this->ike_sa->set_ike_cfg(this->ike_sa, ike_cfg);
1615: ike_cfg->destroy(ike_cfg);
1616: /* add a timeout if peer does not establish it completely */
1617: schedule_delete_job = TRUE;
1618: }
1619:
1620: mid = msg->get_message_id(msg);
1621: if (msg->get_request(msg))
1622: {
1623: if (mid == this->responding.mid || (mid == 0 && is_mid_sync(this, msg)))
1624: {
1625: if (reject_request(this, msg))
1626: {
1627: return FAILED;
1628: }
1629: if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE))
1630: { /* with MOBIKE, we do no implicit updates */
1631: this->ike_sa->update_hosts(this->ike_sa, me, other, mid == 1);
1632: }
1633: status = handle_fragment(this, &this->responding.defrag, msg);
1634: if (status != SUCCESS)
1635: {
1636: if (status == NEED_MORE)
1637: {
1638: this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND,
1639: time_monotonic(NULL));
1640: }
1641: return status;
1642: }
1643: charon->bus->message(charon->bus, msg, TRUE, TRUE);
1644: if (msg->get_exchange_type(msg) == EXCHANGE_TYPE_UNDEFINED)
1645: { /* ignore messages altered to EXCHANGE_TYPE_UNDEFINED */
1646: return SUCCESS;
1647: }
1648: switch (process_request(this, msg))
1649: {
1650: case SUCCESS:
1651: this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND,
1652: time_monotonic(NULL));
1653: this->responding.mid++;
1654: break;
1655: case NEED_MORE:
1656: break;
1657: default:
1658: flush(this);
1659: return DESTROY_ME;
1660: }
1661: }
1662: else if ((mid == this->responding.mid - 1) &&
1663: array_count(this->responding.packets) &&
1664: !(mid == 0 && looks_like_mid_sync(this, msg, FALSE)))
1665: {
1666: status = handle_fragment(this, &this->responding.defrag, msg);
1667: if (status != SUCCESS)
1668: {
1669: if (status == NEED_MORE)
1670: {
1671: this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND,
1672: time_monotonic(NULL));
1673: }
1674: return status;
1675: }
1676: DBG1(DBG_IKE, "received retransmit of request with ID %d, "
1677: "retransmitting response", mid);
1678: this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND,
1679: time_monotonic(NULL));
1680: charon->bus->alert(charon->bus, ALERT_RETRANSMIT_RECEIVE, msg);
1681: send_packets(this, this->responding.packets,
1682: msg->get_destination(msg), msg->get_source(msg));
1683: }
1684: else
1685: {
1686: DBG1(DBG_IKE, "received message ID %d, expected %d, ignored",
1687: mid, this->responding.mid);
1688: }
1689: }
1690: else
1691: {
1692: if (mid == this->initiating.mid)
1693: {
1694: if (this->ike_sa->get_state(this->ike_sa) == IKE_CREATED ||
1695: this->ike_sa->get_state(this->ike_sa) == IKE_CONNECTING ||
1696: msg->get_exchange_type(msg) != IKE_SA_INIT)
1697: { /* only do updates based on verified messages (or initial ones) */
1698: if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE))
1699: { /* with MOBIKE, we do no implicit updates. we force an
1700: * update of the local address on IKE_SA_INIT, but never
1701: * for the remote address */
1702: this->ike_sa->update_hosts(this->ike_sa, me, NULL, mid == 0);
1703: this->ike_sa->update_hosts(this->ike_sa, NULL, other, FALSE);
1704: }
1705: }
1706: status = handle_fragment(this, &this->initiating.defrag, msg);
1707: if (status != SUCCESS)
1708: {
1709: if (status == NEED_MORE)
1710: {
1711: this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND,
1712: time_monotonic(NULL));
1713: }
1714: return status;
1715: }
1716: charon->bus->message(charon->bus, msg, TRUE, TRUE);
1717: if (msg->get_exchange_type(msg) == EXCHANGE_TYPE_UNDEFINED)
1718: { /* ignore messages altered to EXCHANGE_TYPE_UNDEFINED */
1719: return SUCCESS;
1720: }
1721: if (process_response(this, msg) != SUCCESS)
1722: {
1723: flush(this);
1724: return DESTROY_ME;
1725: }
1726: this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND,
1727: time_monotonic(NULL));
1728: }
1729: else
1730: {
1731: DBG1(DBG_IKE, "received message ID %d, expected %d, ignored",
1732: mid, this->initiating.mid);
1733: return SUCCESS;
1734: }
1735: }
1736:
1737: if (schedule_delete_job)
1738: {
1739: ike_sa_id_t *ike_sa_id;
1740: job_t *job;
1741:
1742: ike_sa_id = this->ike_sa->get_id(this->ike_sa);
1743: job = (job_t*)delete_ike_sa_job_create(ike_sa_id, FALSE);
1744: lib->scheduler->schedule_job(lib->scheduler, job,
1745: lib->settings->get_int(lib->settings,
1746: "%s.half_open_timeout", HALF_OPEN_IKE_SA_TIMEOUT,
1747: lib->ns));
1748: }
1749: return SUCCESS;
1750: }
1751:
1752: METHOD(task_manager_t, queue_task_delayed, void,
1753: private_task_manager_t *this, task_t *task, uint32_t delay)
1754: {
1755: queued_task_t *queued;
1756: timeval_t time;
1757:
1758: time_monotonic(&time);
1759: if (delay)
1760: {
1761: job_t *job;
1762:
1763: DBG2(DBG_IKE, "queueing %N task (delayed by %us)", task_type_names,
1764: task->get_type(task), delay);
1765: time.tv_sec += delay;
1766:
1767: job = (job_t*)initiate_tasks_job_create(
1768: this->ike_sa->get_id(this->ike_sa));
1769: lib->scheduler->schedule_job_tv(lib->scheduler, job, time);
1770: }
1771: else
1772: {
1773: DBG2(DBG_IKE, "queueing %N task", task_type_names,
1774: task->get_type(task));
1775: }
1776: INIT(queued,
1777: .task = task,
1778: .time = time,
1779: );
1780: array_insert(this->queued_tasks, ARRAY_TAIL, queued);
1781: }
1782:
1783: METHOD(task_manager_t, queue_task, void,
1784: private_task_manager_t *this, task_t *task)
1785: {
1786: queue_task_delayed(this, task, 0);
1787: }
1788:
1789: /**
1790: * Check if a given task has been queued already
1791: */
1792: static bool has_queued(private_task_manager_t *this, task_type_t type)
1793: {
1794: enumerator_t *enumerator;
1795: bool found = FALSE;
1796: queued_task_t *queued;
1797:
1798: enumerator = array_create_enumerator(this->queued_tasks);
1799: while (enumerator->enumerate(enumerator, &queued))
1800: {
1801: if (queued->task->get_type(queued->task) == type)
1802: {
1803: found = TRUE;
1804: break;
1805: }
1806: }
1807: enumerator->destroy(enumerator);
1808: return found;
1809: }
1810:
1811: METHOD(task_manager_t, queue_ike, void,
1812: private_task_manager_t *this)
1813: {
1814: if (!has_queued(this, TASK_IKE_VENDOR))
1815: {
1816: queue_task(this, (task_t*)ike_vendor_create(this->ike_sa, TRUE));
1817: }
1818: if (!has_queued(this, TASK_IKE_INIT))
1819: {
1820: queue_task(this, (task_t*)ike_init_create(this->ike_sa, TRUE, NULL));
1821: }
1822: if (!has_queued(this, TASK_IKE_NATD))
1823: {
1824: queue_task(this, (task_t*)ike_natd_create(this->ike_sa, TRUE));
1825: }
1826: if (!has_queued(this, TASK_IKE_CERT_PRE))
1827: {
1828: queue_task(this, (task_t*)ike_cert_pre_create(this->ike_sa, TRUE));
1829: }
1830: if (!has_queued(this, TASK_IKE_AUTH))
1831: {
1832: queue_task(this, (task_t*)ike_auth_create(this->ike_sa, TRUE));
1833: }
1834: if (!has_queued(this, TASK_IKE_CERT_POST))
1835: {
1836: queue_task(this, (task_t*)ike_cert_post_create(this->ike_sa, TRUE));
1837: }
1838: if (!has_queued(this, TASK_IKE_CONFIG))
1839: {
1840: queue_task(this, (task_t*)ike_config_create(this->ike_sa, TRUE));
1841: }
1842: if (!has_queued(this, TASK_IKE_AUTH_LIFETIME))
1843: {
1844: queue_task(this, (task_t*)ike_auth_lifetime_create(this->ike_sa, TRUE));
1845: }
1846: if (!has_queued(this, TASK_IKE_MOBIKE))
1847: {
1848: peer_cfg_t *peer_cfg;
1849:
1850: peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
1851: if (peer_cfg->use_mobike(peer_cfg))
1852: {
1853: queue_task(this, (task_t*)ike_mobike_create(this->ike_sa, TRUE));
1854: }
1855: }
1856: #ifdef ME
1857: if (!has_queued(this, TASK_IKE_ME))
1858: {
1859: queue_task(this, (task_t*)ike_me_create(this->ike_sa, TRUE));
1860: }
1861: #endif /* ME */
1862: }
1863:
1864: METHOD(task_manager_t, queue_ike_rekey, void,
1865: private_task_manager_t *this)
1866: {
1867: queue_task(this, (task_t*)ike_rekey_create(this->ike_sa, TRUE));
1868: }
1869:
1870: /**
1871: * Start reauthentication using make-before-break
1872: */
1873: static void trigger_mbb_reauth(private_task_manager_t *this)
1874: {
1875: enumerator_t *enumerator;
1876: child_sa_t *child_sa;
1877: child_cfg_t *cfg;
1878: peer_cfg_t *peer;
1879: ike_sa_t *new;
1880: host_t *host;
1881: queued_task_t *queued;
1882: bool children = FALSE;
1883:
1884: new = charon->ike_sa_manager->checkout_new(charon->ike_sa_manager,
1885: this->ike_sa->get_version(this->ike_sa), TRUE);
1886: if (!new)
1887: { /* shouldn't happen */
1888: return;
1889: }
1890:
1891: peer = this->ike_sa->get_peer_cfg(this->ike_sa);
1892: new->set_peer_cfg(new, peer);
1893: host = this->ike_sa->get_other_host(this->ike_sa);
1894: new->set_other_host(new, host->clone(host));
1895: host = this->ike_sa->get_my_host(this->ike_sa);
1896: new->set_my_host(new, host->clone(host));
1897: enumerator = this->ike_sa->create_virtual_ip_enumerator(this->ike_sa, TRUE);
1898: while (enumerator->enumerate(enumerator, &host))
1899: {
1900: new->add_virtual_ip(new, TRUE, host);
1901: }
1902: enumerator->destroy(enumerator);
1903:
1904: enumerator = this->ike_sa->create_child_sa_enumerator(this->ike_sa);
1905: while (enumerator->enumerate(enumerator, &child_sa))
1906: {
1907: child_create_t *child_create;
1908:
1909: switch (child_sa->get_state(child_sa))
1910: {
1911: case CHILD_REKEYED:
1912: case CHILD_DELETED:
1913: /* ignore CHILD_SAs in these states */
1914: continue;
1915: default:
1916: break;
1917: }
1918: cfg = child_sa->get_config(child_sa);
1919: child_create = child_create_create(new, cfg->get_ref(cfg),
1920: FALSE, NULL, NULL);
1921: child_create->use_reqid(child_create, child_sa->get_reqid(child_sa));
1922: child_create->use_marks(child_create,
1923: child_sa->get_mark(child_sa, TRUE).value,
1924: child_sa->get_mark(child_sa, FALSE).value);
1925: /* interface IDs are not migrated as the new CHILD_SAs on old and new
1926: * IKE_SA go though regular updown events */
1927: new->queue_task(new, &child_create->task);
1928: children = TRUE;
1929: }
1930: enumerator->destroy(enumerator);
1931:
1932: enumerator = array_create_enumerator(this->queued_tasks);
1933: while (enumerator->enumerate(enumerator, &queued))
1934: {
1935: if (queued->task->get_type(queued->task) == TASK_CHILD_CREATE)
1936: {
1937: queued->task->migrate(queued->task, new);
1938: new->queue_task(new, queued->task);
1939: array_remove_at(this->queued_tasks, enumerator);
1940: free(queued);
1941: children = TRUE;
1942: }
1943: }
1944: enumerator->destroy(enumerator);
1945:
1946: if (!children
1947: #ifdef ME
1948: /* allow reauth of mediation connections without CHILD_SAs */
1949: && !peer->is_mediation(peer)
1950: #endif /* ME */
1951: )
1952: {
1953: charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, new);
1954: DBG1(DBG_IKE, "unable to reauthenticate IKE_SA, no CHILD_SA "
1955: "to recreate");
1956: return;
1957: }
1958:
1959: /* suspend online revocation checking until the SA is established */
1960: new->set_condition(new, COND_ONLINE_VALIDATION_SUSPENDED, TRUE);
1961:
1962: if (new->initiate(new, NULL, 0, NULL, NULL) != DESTROY_ME)
1963: {
1964: new->queue_task(new, (task_t*)ike_verify_peer_cert_create(new));
1965: new->queue_task(new, (task_t*)ike_reauth_complete_create(new,
1966: this->ike_sa->get_id(this->ike_sa)));
1967: charon->ike_sa_manager->checkin(charon->ike_sa_manager, new);
1968: }
1969: else
1970: {
1971: charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, new);
1972: DBG1(DBG_IKE, "reauthenticating IKE_SA failed");
1973: }
1974: charon->bus->set_sa(charon->bus, this->ike_sa);
1975: }
1976:
1977: METHOD(task_manager_t, queue_ike_reauth, void,
1978: private_task_manager_t *this)
1979: {
1980: if (this->make_before_break)
1981: {
1982: return trigger_mbb_reauth(this);
1983: }
1984: queue_task(this, (task_t*)ike_reauth_create(this->ike_sa));
1985: }
1986:
1987: METHOD(task_manager_t, queue_ike_delete, void,
1988: private_task_manager_t *this)
1989: {
1990: queue_task(this, (task_t*)ike_delete_create(this->ike_sa, TRUE));
1991: }
1992:
1993: /**
1994: * There is no need to queue more than one mobike task, so this either returns
1995: * an already queued task or queues one if there is none yet.
1996: */
1997: static ike_mobike_t *queue_mobike_task(private_task_manager_t *this)
1998: {
1999: enumerator_t *enumerator;
2000: queued_task_t *queued;
2001: ike_mobike_t *mobike = NULL;
2002:
2003: enumerator = array_create_enumerator(this->queued_tasks);
2004: while (enumerator->enumerate(enumerator, &queued))
2005: {
2006: if (queued->task->get_type(queued->task) == TASK_IKE_MOBIKE)
2007: {
2008: mobike = (ike_mobike_t*)queued->task;
2009: break;
2010: }
2011: }
2012: enumerator->destroy(enumerator);
2013:
2014: if (!mobike)
2015: {
2016: mobike = ike_mobike_create(this->ike_sa, TRUE);
2017: queue_task(this, &mobike->task);
2018: }
2019: return mobike;
2020: }
2021:
2022: METHOD(task_manager_t, queue_mobike, void,
2023: private_task_manager_t *this, bool roam, bool address)
2024: {
2025: ike_mobike_t *mobike;
2026:
2027: mobike = queue_mobike_task(this);
2028: if (roam)
2029: {
2030: enumerator_t *enumerator;
2031: task_t *current;
2032:
2033: mobike->roam(mobike, address);
2034:
2035: /* enable path probing for a currently active MOBIKE task. This might
2036: * not be the case if an address appeared on a new interface while the
2037: * current address is not working but has not yet disappeared. */
2038: enumerator = array_create_enumerator(this->active_tasks);
2039: while (enumerator->enumerate(enumerator, ¤t))
2040: {
2041: if (current->get_type(current) == TASK_IKE_MOBIKE)
2042: {
2043: ike_mobike_t *active = (ike_mobike_t*)current;
2044: active->enable_probing(active);
2045: break;
2046: }
2047: }
2048: enumerator->destroy(enumerator);
2049: }
2050: else
2051: {
2052: mobike->addresses(mobike);
2053: }
2054: }
2055:
2056: METHOD(task_manager_t, queue_dpd, void,
2057: private_task_manager_t *this)
2058: {
2059: ike_mobike_t *mobike;
2060:
2061: if (this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE))
2062: {
2063: #ifdef ME
2064: peer_cfg_t *cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
2065: if (cfg->get_peer_id(cfg) ||
2066: this->ike_sa->has_condition(this->ike_sa, COND_ORIGINAL_INITIATOR))
2067: #else
2068: if (this->ike_sa->has_condition(this->ike_sa, COND_ORIGINAL_INITIATOR))
2069: #endif
2070: {
2071: /* use mobike enabled DPD to detect NAT mapping changes */
2072: mobike = queue_mobike_task(this);
2073: mobike->dpd(mobike);
2074: return;
2075: }
2076: }
2077: queue_task(this, (task_t*)ike_dpd_create(TRUE));
2078: }
2079:
2080: METHOD(task_manager_t, queue_child, void,
2081: private_task_manager_t *this, child_cfg_t *cfg, uint32_t reqid,
2082: traffic_selector_t *tsi, traffic_selector_t *tsr)
2083: {
2084: child_create_t *task;
2085:
2086: task = child_create_create(this->ike_sa, cfg, FALSE, tsi, tsr);
2087: if (reqid)
2088: {
2089: task->use_reqid(task, reqid);
2090: }
2091: queue_task(this, &task->task);
2092: }
2093:
2094: METHOD(task_manager_t, queue_child_rekey, void,
2095: private_task_manager_t *this, protocol_id_t protocol, uint32_t spi)
2096: {
2097: queue_task(this, (task_t*)child_rekey_create(this->ike_sa, protocol, spi));
2098: }
2099:
2100: METHOD(task_manager_t, queue_child_delete, void,
2101: private_task_manager_t *this, protocol_id_t protocol, uint32_t spi,
2102: bool expired)
2103: {
2104: queue_task(this, (task_t*)child_delete_create(this->ike_sa,
2105: protocol, spi, expired));
2106: }
2107:
2108: METHOD(task_manager_t, adopt_tasks, void,
2109: private_task_manager_t *this, task_manager_t *other_public)
2110: {
2111: private_task_manager_t *other = (private_task_manager_t*)other_public;
2112: queued_task_t *queued;
2113: timeval_t now;
2114:
2115: time_monotonic(&now);
2116:
2117: /* move queued tasks from other to this */
2118: while (array_remove(other->queued_tasks, ARRAY_TAIL, &queued))
2119: {
2120: DBG2(DBG_IKE, "migrating %N task", task_type_names,
2121: queued->task->get_type(queued->task));
2122: queued->task->migrate(queued->task, this->ike_sa);
2123: /* don't delay tasks on the new IKE_SA */
2124: queued->time = now;
2125: array_insert(this->queued_tasks, ARRAY_HEAD, queued);
2126: }
2127: }
2128:
2129: METHOD(task_manager_t, busy, bool,
2130: private_task_manager_t *this)
2131: {
2132: return array_count(this->active_tasks) > 0;
2133: }
2134:
2135: METHOD(task_manager_t, reset, void,
2136: private_task_manager_t *this, uint32_t initiate, uint32_t respond)
2137: {
2138: enumerator_t *enumerator;
2139: queued_task_t *queued;
2140: task_t *task;
2141: timeval_t now;
2142:
2143: /* reset message counters and retransmit packets */
2144: clear_packets(this->responding.packets);
2145: clear_packets(this->initiating.packets);
2146: DESTROY_IF(this->responding.defrag);
2147: DESTROY_IF(this->initiating.defrag);
2148: this->responding.defrag = NULL;
2149: this->initiating.defrag = NULL;
2150: if (initiate != UINT_MAX)
2151: {
2152: this->initiating.mid = initiate;
2153: }
2154: if (respond != UINT_MAX)
2155: {
2156: this->responding.mid = respond;
2157: }
2158: this->initiating.type = EXCHANGE_TYPE_UNDEFINED;
2159:
2160: time_monotonic(&now);
2161: /* reset queued tasks */
2162: enumerator = array_create_enumerator(this->queued_tasks);
2163: while (enumerator->enumerate(enumerator, &queued))
2164: {
2165: queued->time = now;
2166: queued->task->migrate(queued->task, this->ike_sa);
2167: }
2168: enumerator->destroy(enumerator);
2169:
2170: /* reset active tasks */
2171: while (array_remove(this->active_tasks, ARRAY_TAIL, &task))
2172: {
2173: task->migrate(task, this->ike_sa);
2174: INIT(queued,
2175: .task = task,
2176: .time = now,
2177: );
2178: array_insert(this->queued_tasks, ARRAY_HEAD, queued);
2179: }
2180:
2181: this->reset = TRUE;
2182: }
2183:
2184: /**
2185: * Data for a task queue enumerator
2186: */
2187: typedef struct {
2188: enumerator_t public;
2189: task_queue_t queue;
2190: enumerator_t *inner;
2191: queued_task_t *queued;
2192: } task_enumerator_t;
2193:
2194: METHOD(enumerator_t, task_enumerator_destroy, void,
2195: task_enumerator_t *this)
2196: {
2197: this->inner->destroy(this->inner);
2198: free(this);
2199: }
2200:
2201: METHOD(enumerator_t, task_enumerator_enumerate, bool,
2202: task_enumerator_t *this, va_list args)
2203: {
2204: task_t **task;
2205:
2206: VA_ARGS_VGET(args, task);
2207: if (this->queue == TASK_QUEUE_QUEUED)
2208: {
2209: if (this->inner->enumerate(this->inner, &this->queued))
2210: {
2211: *task = this->queued->task;
2212: return TRUE;
2213: }
2214: }
2215: else if (this->inner->enumerate(this->inner, task))
2216: {
2217: return TRUE;
2218: }
2219: return FALSE;
2220: }
2221:
2222: METHOD(task_manager_t, create_task_enumerator, enumerator_t*,
2223: private_task_manager_t *this, task_queue_t queue)
2224: {
2225: task_enumerator_t *enumerator;
2226:
2227: INIT(enumerator,
2228: .public = {
2229: .enumerate = enumerator_enumerate_default,
2230: .venumerate = _task_enumerator_enumerate,
2231: .destroy = _task_enumerator_destroy,
2232: },
2233: .queue = queue,
2234: );
2235: switch (queue)
2236: {
2237: case TASK_QUEUE_ACTIVE:
2238: enumerator->inner = array_create_enumerator(this->active_tasks);
2239: break;
2240: case TASK_QUEUE_PASSIVE:
2241: enumerator->inner = array_create_enumerator(this->passive_tasks);
2242: break;
2243: case TASK_QUEUE_QUEUED:
2244: enumerator->inner = array_create_enumerator(this->queued_tasks);
2245: break;
2246: default:
2247: enumerator->inner = enumerator_create_empty();
2248: break;
2249: }
2250: return &enumerator->public;
2251: }
2252:
2253: METHOD(task_manager_t, remove_task, void,
2254: private_task_manager_t *this, enumerator_t *enumerator_public)
2255: {
2256: task_enumerator_t *enumerator = (task_enumerator_t*)enumerator_public;
2257:
2258: switch (enumerator->queue)
2259: {
2260: case TASK_QUEUE_ACTIVE:
2261: array_remove_at(this->active_tasks, enumerator->inner);
2262: break;
2263: case TASK_QUEUE_PASSIVE:
2264: array_remove_at(this->passive_tasks, enumerator->inner);
2265: break;
2266: case TASK_QUEUE_QUEUED:
2267: array_remove_at(this->queued_tasks, enumerator->inner);
2268: free(enumerator->queued);
2269: enumerator->queued = NULL;
2270: break;
2271: default:
2272: break;
2273: }
2274: }
2275:
2276: METHOD(task_manager_t, destroy, void,
2277: private_task_manager_t *this)
2278: {
2279: flush(this);
2280:
2281: array_destroy(this->active_tasks);
2282: array_destroy(this->queued_tasks);
2283: array_destroy(this->passive_tasks);
2284:
2285: clear_packets(this->responding.packets);
2286: array_destroy(this->responding.packets);
2287: clear_packets(this->initiating.packets);
2288: array_destroy(this->initiating.packets);
2289: DESTROY_IF(this->responding.defrag);
2290: DESTROY_IF(this->initiating.defrag);
2291: free(this);
2292: }
2293:
2294: /*
2295: * see header file
2296: */
2297: task_manager_v2_t *task_manager_v2_create(ike_sa_t *ike_sa)
2298: {
2299: private_task_manager_t *this;
2300:
2301: INIT(this,
2302: .public = {
2303: .task_manager = {
2304: .process_message = _process_message,
2305: .queue_task = _queue_task,
2306: .queue_task_delayed = _queue_task_delayed,
2307: .queue_ike = _queue_ike,
2308: .queue_ike_rekey = _queue_ike_rekey,
2309: .queue_ike_reauth = _queue_ike_reauth,
2310: .queue_ike_delete = _queue_ike_delete,
2311: .queue_mobike = _queue_mobike,
2312: .queue_child = _queue_child,
2313: .queue_child_rekey = _queue_child_rekey,
2314: .queue_child_delete = _queue_child_delete,
2315: .queue_dpd = _queue_dpd,
2316: .initiate = _initiate,
2317: .retransmit = _retransmit,
2318: .incr_mid = _incr_mid,
2319: .get_mid = _get_mid,
2320: .reset = _reset,
2321: .adopt_tasks = _adopt_tasks,
2322: .busy = _busy,
2323: .create_task_enumerator = _create_task_enumerator,
2324: .remove_task = _remove_task,
2325: .flush = _flush,
2326: .flush_queue = _flush_queue,
2327: .destroy = _destroy,
2328: },
2329: },
2330: .ike_sa = ike_sa,
2331: .initiating.type = EXCHANGE_TYPE_UNDEFINED,
2332: .queued_tasks = array_create(0, 0),
2333: .active_tasks = array_create(0, 0),
2334: .passive_tasks = array_create(0, 0),
2335: .retransmit_tries = lib->settings->get_int(lib->settings,
2336: "%s.retransmit_tries", RETRANSMIT_TRIES, lib->ns),
2337: .retransmit_timeout = lib->settings->get_double(lib->settings,
2338: "%s.retransmit_timeout", RETRANSMIT_TIMEOUT, lib->ns),
2339: .retransmit_base = lib->settings->get_double(lib->settings,
2340: "%s.retransmit_base", RETRANSMIT_BASE, lib->ns),
2341: .retransmit_jitter = min(lib->settings->get_int(lib->settings,
2342: "%s.retransmit_jitter", 0, lib->ns), RETRANSMIT_JITTER_MAX),
2343: .retransmit_limit = lib->settings->get_int(lib->settings,
2344: "%s.retransmit_limit", 0, lib->ns) * 1000,
2345: .make_before_break = lib->settings->get_bool(lib->settings,
2346: "%s.make_before_break", FALSE, lib->ns),
2347: );
2348:
2349: return &this->public;
2350: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>