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