Store the major IKE version on ike_sa_id_t.
[strongswan.git] / src / libcharon / sa / ike_sa_manager.c
1 /*
2 * Copyright (C) 2005-2011 Martin Willi
3 * Copyright (C) 2011 revosec AG
4 * Copyright (C) 2008-2012 Tobias Brunner
5 * Copyright (C) 2005 Jan Hutter
6 * Hochschule fuer Technik Rapperswil
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * for more details.
17 */
18
19 #include <string.h>
20
21 #include "ike_sa_manager.h"
22
23 #include <daemon.h>
24 #include <sa/ike_sa_id.h>
25 #include <bus/bus.h>
26 #include <threading/condvar.h>
27 #include <threading/mutex.h>
28 #include <threading/rwlock.h>
29 #include <utils/linked_list.h>
30 #include <crypto/hashers/hasher.h>
31
32 /* the default size of the hash table (MUST be a power of 2) */
33 #define DEFAULT_HASHTABLE_SIZE 1
34
35 /* the maximum size of the hash table (MUST be a power of 2) */
36 #define MAX_HASHTABLE_SIZE (1 << 30)
37
38 /* the default number of segments (MUST be a power of 2) */
39 #define DEFAULT_SEGMENT_COUNT 1
40
41 typedef struct entry_t entry_t;
42
43 /**
44 * An entry in the linked list, contains IKE_SA, locking and lookup data.
45 */
46 struct entry_t {
47
48 /**
49 * Number of threads waiting for this ike_sa_t object.
50 */
51 int waiting_threads;
52
53 /**
54 * Condvar where threads can wait until ike_sa_t object is free for use again.
55 */
56 condvar_t *condvar;
57
58 /**
59 * Is this ike_sa currently checked out?
60 */
61 bool checked_out;
62
63 /**
64 * Does this SA drives out new threads?
65 */
66 bool driveout_new_threads;
67
68 /**
69 * Does this SA drives out waiting threads?
70 */
71 bool driveout_waiting_threads;
72
73 /**
74 * Identification of an IKE_SA (SPIs).
75 */
76 ike_sa_id_t *ike_sa_id;
77
78 /**
79 * The contained ike_sa_t object.
80 */
81 ike_sa_t *ike_sa;
82
83 /**
84 * hash of the IKE_SA_INIT message, used to detect retransmissions
85 */
86 chunk_t init_hash;
87
88 /**
89 * remote host address, required for DoS detection and duplicate
90 * checking (host with same my_id and other_id is *not* considered
91 * a duplicate if the address family differs)
92 */
93 host_t *other;
94
95 /**
96 * As responder: Is this SA half-open?
97 */
98 bool half_open;
99
100 /**
101 * own identity, required for duplicate checking
102 */
103 identification_t *my_id;
104
105 /**
106 * remote identity, required for duplicate checking
107 */
108 identification_t *other_id;
109
110 /**
111 * message ID currently processing, if any
112 */
113 u_int32_t message_id;
114 };
115
116 /**
117 * Implementation of entry_t.destroy.
118 */
119 static status_t entry_destroy(entry_t *this)
120 {
121 /* also destroy IKE SA */
122 this->ike_sa->destroy(this->ike_sa);
123 this->ike_sa_id->destroy(this->ike_sa_id);
124 chunk_free(&this->init_hash);
125 DESTROY_IF(this->other);
126 DESTROY_IF(this->my_id);
127 DESTROY_IF(this->other_id);
128 this->condvar->destroy(this->condvar);
129 free(this);
130 return SUCCESS;
131 }
132
133 /**
134 * Creates a new entry for the ike_sa_t list.
135 */
136 static entry_t *entry_create()
137 {
138 entry_t *this = malloc_thing(entry_t);
139
140 this->waiting_threads = 0;
141 this->condvar = condvar_create(CONDVAR_TYPE_DEFAULT);
142
143 /* we set checkout flag when we really give it out */
144 this->checked_out = FALSE;
145 this->driveout_new_threads = FALSE;
146 this->driveout_waiting_threads = FALSE;
147 this->message_id = -1;
148 this->init_hash = chunk_empty;
149 this->other = NULL;
150 this->half_open = FALSE;
151 this->my_id = NULL;
152 this->other_id = NULL;
153 this->ike_sa_id = NULL;
154 this->ike_sa = NULL;
155
156 return this;
157 }
158
159 /**
160 * Function that matches entry_t objects by initiator SPI and the hash of the
161 * IKE_SA_INIT message.
162 */
163 static bool entry_match_by_hash(entry_t *entry, ike_sa_id_t *id, chunk_t *hash)
164 {
165 return id->get_responder_spi(id) == 0 &&
166 id->get_initiator_spi(id) == entry->ike_sa_id->get_initiator_spi(entry->ike_sa_id) &&
167 chunk_equals(*hash, entry->init_hash);
168 }
169
170 /**
171 * Function that matches entry_t objects by ike_sa_id_t.
172 */
173 static bool entry_match_by_id(entry_t *entry, ike_sa_id_t *id)
174 {
175 if (id->equals(id, entry->ike_sa_id))
176 {
177 return TRUE;
178 }
179 if ((id->get_responder_spi(id) == 0 ||
180 entry->ike_sa_id->get_responder_spi(entry->ike_sa_id) == 0) &&
181 id->get_initiator_spi(id) == entry->ike_sa_id->get_initiator_spi(entry->ike_sa_id))
182 {
183 /* this is TRUE for IKE_SAs that we initiated but have not yet received a response */
184 return TRUE;
185 }
186 return FALSE;
187 }
188
189 /**
190 * Function that matches entry_t objects by ike_sa_t pointers.
191 */
192 static bool entry_match_by_sa(entry_t *entry, ike_sa_t *ike_sa)
193 {
194 return entry->ike_sa == ike_sa;
195 }
196
197 /**
198 * Hash function for ike_sa_id_t objects.
199 */
200 static u_int ike_sa_id_hash(ike_sa_id_t *ike_sa_id)
201 {
202 /* we always use initiator spi as key */
203 return ike_sa_id->get_initiator_spi(ike_sa_id);
204 }
205
206 typedef struct half_open_t half_open_t;
207
208 /**
209 * Struct to manage half-open IKE_SAs per peer.
210 */
211 struct half_open_t {
212 /** chunk of remote host address */
213 chunk_t other;
214
215 /** the number of half-open IKE_SAs with that host */
216 u_int count;
217 };
218
219 /**
220 * Destroys a half_open_t object.
221 */
222 static void half_open_destroy(half_open_t *this)
223 {
224 chunk_free(&this->other);
225 free(this);
226 }
227
228 /**
229 * Function that matches half_open_t objects by the given IP address chunk.
230 */
231 static bool half_open_match(half_open_t *half_open, chunk_t *addr)
232 {
233 return chunk_equals(*addr, half_open->other);
234 }
235
236 typedef struct connected_peers_t connected_peers_t;
237
238 struct connected_peers_t {
239 /** own identity */
240 identification_t *my_id;
241
242 /** remote identity */
243 identification_t *other_id;
244
245 /** ip address family of peer */
246 int family;
247
248 /** list of ike_sa_id_t objects of IKE_SAs between the two identities */
249 linked_list_t *sas;
250 };
251
252 static void connected_peers_destroy(connected_peers_t *this)
253 {
254 this->my_id->destroy(this->my_id);
255 this->other_id->destroy(this->other_id);
256 this->sas->destroy(this->sas);
257 free(this);
258 }
259
260 /**
261 * Function that matches connected_peers_t objects by the given ids.
262 */
263 static bool connected_peers_match(connected_peers_t *connected_peers,
264 identification_t *my_id, identification_t *other_id,
265 uintptr_t family)
266 {
267 return my_id->equals(my_id, connected_peers->my_id) &&
268 other_id->equals(other_id, connected_peers->other_id) &&
269 (!family || family == connected_peers->family);
270 }
271
272 typedef struct segment_t segment_t;
273
274 /**
275 * Struct to manage segments of the hash table.
276 */
277 struct segment_t {
278 /** mutex to access a segment exclusively */
279 mutex_t *mutex;
280
281 /** the number of entries in this segment */
282 u_int count;
283 };
284
285 typedef struct shareable_segment_t shareable_segment_t;
286
287 /**
288 * Struct to manage segments of the "half-open" and "connected peers" hash tables.
289 */
290 struct shareable_segment_t {
291 /** rwlock to access a segment non-/exclusively */
292 rwlock_t *lock;
293
294 /** the number of entries in this segment - in case of the "half-open table"
295 * it's the sum of all half_open_t.count in a segment. */
296 u_int count;
297 };
298
299 typedef struct private_ike_sa_manager_t private_ike_sa_manager_t;
300
301 /**
302 * Additional private members of ike_sa_manager_t.
303 */
304 struct private_ike_sa_manager_t {
305 /**
306 * Public interface of ike_sa_manager_t.
307 */
308 ike_sa_manager_t public;
309
310 /**
311 * Hash table with entries for the ike_sa_t objects.
312 */
313 linked_list_t **ike_sa_table;
314
315 /**
316 * The size of the hash table.
317 */
318 u_int table_size;
319
320 /**
321 * Mask to map the hashes to table rows.
322 */
323 u_int table_mask;
324
325 /**
326 * Segments of the hash table.
327 */
328 segment_t *segments;
329
330 /**
331 * The number of segments.
332 */
333 u_int segment_count;
334
335 /**
336 * Mask to map a table row to a segment.
337 */
338 u_int segment_mask;
339
340 /**
341 * Hash table with half_open_t objects.
342 */
343 linked_list_t **half_open_table;
344
345 /**
346 * Segments of the "half-open" hash table.
347 */
348 shareable_segment_t *half_open_segments;
349
350 /**
351 * Hash table with connected_peers_t objects.
352 */
353 linked_list_t **connected_peers_table;
354
355 /**
356 * Segments of the "connected peers" hash table.
357 */
358 shareable_segment_t *connected_peers_segments;
359
360 /**
361 * RNG to get random SPIs for our side
362 */
363 rng_t *rng;
364
365 /**
366 * SHA1 hasher for IKE_SA_INIT retransmit detection
367 */
368 hasher_t *hasher;
369
370 /**
371 * reuse existing IKE_SAs in checkout_by_config
372 */
373 bool reuse_ikesa;
374 };
375
376 /**
377 * Acquire a lock to access the segment of the table row with the given index.
378 * It also works with the segment index directly.
379 */
380 static void lock_single_segment(private_ike_sa_manager_t *this, u_int index)
381 {
382 mutex_t *lock = this->segments[index & this->segment_mask].mutex;
383
384 lock->lock(lock);
385 }
386
387 /**
388 * Release the lock required to access the segment of the table row with the given index.
389 * It also works with the segment index directly.
390 */
391 static void unlock_single_segment(private_ike_sa_manager_t *this, u_int index)
392 {
393 mutex_t *lock = this->segments[index & this->segment_mask].mutex;
394
395 lock->unlock(lock);
396 }
397
398 /**
399 * Lock all segments
400 */
401 static void lock_all_segments(private_ike_sa_manager_t *this)
402 {
403 u_int i;
404
405 for (i = 0; i < this->segment_count; i++)
406 {
407 this->segments[i].mutex->lock(this->segments[i].mutex);
408 }
409 }
410
411 /**
412 * Unlock all segments
413 */
414 static void unlock_all_segments(private_ike_sa_manager_t *this)
415 {
416 u_int i;
417
418 for (i = 0; i < this->segment_count; i++)
419 {
420 this->segments[i].mutex->unlock(this->segments[i].mutex);
421 }
422 }
423
424 typedef struct private_enumerator_t private_enumerator_t;
425
426 /**
427 * hash table enumerator implementation
428 */
429 struct private_enumerator_t {
430
431 /**
432 * implements enumerator interface
433 */
434 enumerator_t enumerator;
435
436 /**
437 * associated ike_sa_manager_t
438 */
439 private_ike_sa_manager_t *manager;
440
441 /**
442 * current segment index
443 */
444 u_int segment;
445
446 /**
447 * currently enumerating entry
448 */
449 entry_t *entry;
450
451 /**
452 * current table row index
453 */
454 u_int row;
455
456 /**
457 * enumerator for the current table row
458 */
459 enumerator_t *current;
460 };
461
462 METHOD(enumerator_t, enumerate, bool,
463 private_enumerator_t *this, entry_t **entry, u_int *segment)
464 {
465 if (this->entry)
466 {
467 this->entry->condvar->signal(this->entry->condvar);
468 this->entry = NULL;
469 }
470 while (this->segment < this->manager->segment_count)
471 {
472 while (this->row < this->manager->table_size)
473 {
474 if (this->current)
475 {
476 entry_t *item;
477
478 if (this->current->enumerate(this->current, &item))
479 {
480 *entry = this->entry = item;
481 *segment = this->segment;
482 return TRUE;
483 }
484 this->current->destroy(this->current);
485 this->current = NULL;
486 unlock_single_segment(this->manager, this->segment);
487 }
488 else
489 {
490 linked_list_t *list;
491
492 lock_single_segment(this->manager, this->segment);
493 if ((list = this->manager->ike_sa_table[this->row]) != NULL &&
494 list->get_count(list))
495 {
496 this->current = list->create_enumerator(list);
497 continue;
498 }
499 unlock_single_segment(this->manager, this->segment);
500 }
501 this->row += this->manager->segment_count;
502 }
503 this->segment++;
504 this->row = this->segment;
505 }
506 return FALSE;
507 }
508
509 METHOD(enumerator_t, enumerator_destroy, void,
510 private_enumerator_t *this)
511 {
512 if (this->entry)
513 {
514 this->entry->condvar->signal(this->entry->condvar);
515 }
516 if (this->current)
517 {
518 this->current->destroy(this->current);
519 unlock_single_segment(this->manager, this->segment);
520 }
521 free(this);
522 }
523
524 /**
525 * Creates an enumerator to enumerate the entries in the hash table.
526 */
527 static enumerator_t* create_table_enumerator(private_ike_sa_manager_t *this)
528 {
529 private_enumerator_t *enumerator;
530
531 INIT(enumerator,
532 .enumerator = {
533 .enumerate = (void*)_enumerate,
534 .destroy = _enumerator_destroy,
535 },
536 .manager = this,
537 );
538 return &enumerator->enumerator;
539 }
540
541 /**
542 * Put an entry into the hash table.
543 * Note: The caller has to unlock the returned segment.
544 */
545 static u_int put_entry(private_ike_sa_manager_t *this, entry_t *entry)
546 {
547 linked_list_t *list;
548 u_int row, segment;
549
550 row = ike_sa_id_hash(entry->ike_sa_id) & this->table_mask;
551 segment = row & this->segment_mask;
552
553 lock_single_segment(this, segment);
554 list = this->ike_sa_table[row];
555 if (!list)
556 {
557 list = this->ike_sa_table[row] = linked_list_create();
558 }
559 list->insert_last(list, entry);
560 this->segments[segment].count++;
561 return segment;
562 }
563
564 /**
565 * Remove an entry from the hash table.
566 * Note: The caller MUST have a lock on the segment of this entry.
567 */
568 static void remove_entry(private_ike_sa_manager_t *this, entry_t *entry)
569 {
570 linked_list_t *list;
571 u_int row, segment;
572
573 row = ike_sa_id_hash(entry->ike_sa_id) & this->table_mask;
574 segment = row & this->segment_mask;
575 list = this->ike_sa_table[row];
576 if (list)
577 {
578 entry_t *current;
579 enumerator_t *enumerator;
580
581 enumerator = list->create_enumerator(list);
582 while (enumerator->enumerate(enumerator, &current))
583 {
584 if (current == entry)
585 {
586 list->remove_at(list, enumerator);
587 this->segments[segment].count--;
588 break;
589 }
590 }
591 enumerator->destroy(enumerator);
592 }
593 }
594
595 /**
596 * Remove the entry at the current enumerator position.
597 */
598 static void remove_entry_at(private_enumerator_t *this)
599 {
600 this->entry = NULL;
601 if (this->current)
602 {
603 linked_list_t *list = this->manager->ike_sa_table[this->row];
604 list->remove_at(list, this->current);
605 this->manager->segments[this->segment].count--;
606 }
607 }
608
609 /**
610 * Find an entry using the provided match function to compare the entries for
611 * equality.
612 */
613 static status_t get_entry_by_match_function(private_ike_sa_manager_t *this,
614 ike_sa_id_t *ike_sa_id, entry_t **entry, u_int *segment,
615 linked_list_match_t match, void *p1, void *p2)
616 {
617 entry_t *current;
618 linked_list_t *list;
619 u_int row, seg;
620
621 row = ike_sa_id_hash(ike_sa_id) & this->table_mask;
622 seg = row & this->segment_mask;
623
624 lock_single_segment(this, seg);
625 list = this->ike_sa_table[row];
626 if (list)
627 {
628 if (list->find_first(list, match, (void**)&current, p1, p2) == SUCCESS)
629 {
630 *entry = current;
631 *segment = seg;
632 /* the locked segment has to be unlocked by the caller */
633 return SUCCESS;
634 }
635 }
636 unlock_single_segment(this, seg);
637 return NOT_FOUND;
638 }
639
640 /**
641 * Find an entry by ike_sa_id_t.
642 * Note: On SUCCESS, the caller has to unlock the segment.
643 */
644 static status_t get_entry_by_id(private_ike_sa_manager_t *this,
645 ike_sa_id_t *ike_sa_id, entry_t **entry, u_int *segment)
646 {
647 return get_entry_by_match_function(this, ike_sa_id, entry, segment,
648 (linked_list_match_t)entry_match_by_id, ike_sa_id, NULL);
649 }
650
651 /**
652 * Find an entry by initiator SPI and IKE_SA_INIT hash.
653 * Note: On SUCCESS, the caller has to unlock the segment.
654 */
655 static status_t get_entry_by_hash(private_ike_sa_manager_t *this,
656 ike_sa_id_t *ike_sa_id, chunk_t hash, entry_t **entry, u_int *segment)
657 {
658 return get_entry_by_match_function(this, ike_sa_id, entry, segment,
659 (linked_list_match_t)entry_match_by_hash, ike_sa_id, &hash);
660 }
661
662 /**
663 * Find an entry by IKE_SA pointer.
664 * Note: On SUCCESS, the caller has to unlock the segment.
665 */
666 static status_t get_entry_by_sa(private_ike_sa_manager_t *this,
667 ike_sa_id_t *ike_sa_id, ike_sa_t *ike_sa, entry_t **entry, u_int *segment)
668 {
669 return get_entry_by_match_function(this, ike_sa_id, entry, segment,
670 (linked_list_match_t)entry_match_by_sa, ike_sa, NULL);
671 }
672
673 /**
674 * Wait until no other thread is using an IKE_SA, return FALSE if entry not
675 * acquirable.
676 */
677 static bool wait_for_entry(private_ike_sa_manager_t *this, entry_t *entry,
678 u_int segment)
679 {
680 if (entry->driveout_new_threads)
681 {
682 /* we are not allowed to get this */
683 return FALSE;
684 }
685 while (entry->checked_out && !entry->driveout_waiting_threads)
686 {
687 /* so wait until we can get it for us.
688 * we register us as waiting. */
689 entry->waiting_threads++;
690 entry->condvar->wait(entry->condvar, this->segments[segment].mutex);
691 entry->waiting_threads--;
692 }
693 /* hm, a deletion request forbids us to get this SA, get next one */
694 if (entry->driveout_waiting_threads)
695 {
696 /* we must signal here, others may be waiting on it, too */
697 entry->condvar->signal(entry->condvar);
698 return FALSE;
699 }
700 return TRUE;
701 }
702
703 /**
704 * Put a half-open SA into the hash table.
705 */
706 static void put_half_open(private_ike_sa_manager_t *this, entry_t *entry)
707 {
708 half_open_t *half_open = NULL;
709 linked_list_t *list;
710 chunk_t addr;
711 u_int row, segment;
712 rwlock_t *lock;
713
714 addr = entry->other->get_address(entry->other);
715 row = chunk_hash(addr) & this->table_mask;
716 segment = row & this->segment_mask;
717 lock = this->half_open_segments[segment].lock;
718 lock->write_lock(lock);
719 list = this->half_open_table[row];
720 if (list)
721 {
722 half_open_t *current;
723
724 if (list->find_first(list, (linked_list_match_t)half_open_match,
725 (void**)&current, &addr) == SUCCESS)
726 {
727 half_open = current;
728 half_open->count++;
729 this->half_open_segments[segment].count++;
730 }
731 }
732 else
733 {
734 list = this->half_open_table[row] = linked_list_create();
735 }
736
737 if (!half_open)
738 {
739 INIT(half_open,
740 .other = chunk_clone(addr),
741 .count = 1,
742 );
743 list->insert_last(list, half_open);
744 this->half_open_segments[segment].count++;
745 }
746 lock->unlock(lock);
747 }
748
749 /**
750 * Remove a half-open SA from the hash table.
751 */
752 static void remove_half_open(private_ike_sa_manager_t *this, entry_t *entry)
753 {
754 linked_list_t *list;
755 chunk_t addr;
756 u_int row, segment;
757 rwlock_t *lock;
758
759 addr = entry->other->get_address(entry->other);
760 row = chunk_hash(addr) & this->table_mask;
761 segment = row & this->segment_mask;
762 lock = this->half_open_segments[segment].lock;
763 lock->write_lock(lock);
764 list = this->half_open_table[row];
765 if (list)
766 {
767 half_open_t *current;
768 enumerator_t *enumerator;
769
770 enumerator = list->create_enumerator(list);
771 while (enumerator->enumerate(enumerator, &current))
772 {
773 if (half_open_match(current, &addr))
774 {
775 if (--current->count == 0)
776 {
777 list->remove_at(list, enumerator);
778 half_open_destroy(current);
779 }
780 this->half_open_segments[segment].count--;
781 break;
782 }
783 }
784 enumerator->destroy(enumerator);
785 }
786 lock->unlock(lock);
787 }
788
789 /**
790 * Put an SA between two peers into the hash table.
791 */
792 static void put_connected_peers(private_ike_sa_manager_t *this, entry_t *entry)
793 {
794 connected_peers_t *connected_peers = NULL;
795 chunk_t my_id, other_id;
796 linked_list_t *list;
797 u_int row, segment;
798 rwlock_t *lock;
799
800 my_id = entry->my_id->get_encoding(entry->my_id);
801 other_id = entry->other_id->get_encoding(entry->other_id);
802 row = chunk_hash_inc(other_id, chunk_hash(my_id)) & this->table_mask;
803 segment = row & this->segment_mask;
804 lock = this->connected_peers_segments[segment].lock;
805 lock->write_lock(lock);
806 list = this->connected_peers_table[row];
807 if (list)
808 {
809 connected_peers_t *current;
810
811 if (list->find_first(list, (linked_list_match_t)connected_peers_match,
812 (void**)&current, entry->my_id, entry->other_id,
813 (uintptr_t)entry->other->get_family(entry->other)) == SUCCESS)
814 {
815 connected_peers = current;
816 if (connected_peers->sas->find_first(connected_peers->sas,
817 (linked_list_match_t)entry->ike_sa_id->equals,
818 NULL, entry->ike_sa_id) == SUCCESS)
819 {
820 lock->unlock(lock);
821 return;
822 }
823 }
824 }
825 else
826 {
827 list = this->connected_peers_table[row] = linked_list_create();
828 }
829
830 if (!connected_peers)
831 {
832 INIT(connected_peers,
833 .my_id = entry->my_id->clone(entry->my_id),
834 .other_id = entry->other_id->clone(entry->other_id),
835 .family = entry->other->get_family(entry->other),
836 .sas = linked_list_create(),
837 );
838 list->insert_last(list, connected_peers);
839 }
840 connected_peers->sas->insert_last(connected_peers->sas,
841 entry->ike_sa_id->clone(entry->ike_sa_id));
842 this->connected_peers_segments[segment].count++;
843 lock->unlock(lock);
844 }
845
846 /**
847 * Remove an SA between two peers from the hash table.
848 */
849 static void remove_connected_peers(private_ike_sa_manager_t *this, entry_t *entry)
850 {
851 chunk_t my_id, other_id;
852 linked_list_t *list;
853 u_int row, segment;
854 rwlock_t *lock;
855
856 my_id = entry->my_id->get_encoding(entry->my_id);
857 other_id = entry->other_id->get_encoding(entry->other_id);
858 row = chunk_hash_inc(other_id, chunk_hash(my_id)) & this->table_mask;
859 segment = row & this->segment_mask;
860
861 lock = this->connected_peers_segments[segment].lock;
862 lock->write_lock(lock);
863 list = this->connected_peers_table[row];
864 if (list)
865 {
866 connected_peers_t *current;
867 enumerator_t *enumerator;
868
869 enumerator = list->create_enumerator(list);
870 while (enumerator->enumerate(enumerator, &current))
871 {
872 if (connected_peers_match(current, entry->my_id, entry->other_id,
873 (uintptr_t)entry->other->get_family(entry->other)))
874 {
875 ike_sa_id_t *ike_sa_id;
876 enumerator_t *inner;
877
878 inner = current->sas->create_enumerator(current->sas);
879 while (inner->enumerate(inner, &ike_sa_id))
880 {
881 if (ike_sa_id->equals(ike_sa_id, entry->ike_sa_id))
882 {
883 current->sas->remove_at(current->sas, inner);
884 ike_sa_id->destroy(ike_sa_id);
885 this->connected_peers_segments[segment].count--;
886 break;
887 }
888 }
889 inner->destroy(inner);
890 if (current->sas->get_count(current->sas) == 0)
891 {
892 list->remove_at(list, enumerator);
893 connected_peers_destroy(current);
894 }
895 break;
896 }
897 }
898 enumerator->destroy(enumerator);
899 }
900 lock->unlock(lock);
901 }
902
903 /**
904 * Get a random SPI for new IKE_SAs
905 */
906 static u_int64_t get_spi(private_ike_sa_manager_t *this)
907 {
908 u_int64_t spi = 0;
909
910 if (this->rng)
911 {
912 this->rng->get_bytes(this->rng, sizeof(spi), (u_int8_t*)&spi);
913 }
914 return spi;
915 }
916
917 METHOD(ike_sa_manager_t, checkout, ike_sa_t*,
918 private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id)
919 {
920 ike_sa_t *ike_sa = NULL;
921 entry_t *entry;
922 u_int segment;
923
924 DBG2(DBG_MGR, "checkout IKE_SA");
925
926 if (get_entry_by_id(this, ike_sa_id, &entry, &segment) == SUCCESS)
927 {
928 if (wait_for_entry(this, entry, segment))
929 {
930 entry->checked_out = TRUE;
931 ike_sa = entry->ike_sa;
932 DBG2(DBG_MGR, "IKE_SA %s[%u] successfully checked out",
933 ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa));
934 }
935 unlock_single_segment(this, segment);
936 }
937 charon->bus->set_sa(charon->bus, ike_sa);
938 return ike_sa;
939 }
940
941 METHOD(ike_sa_manager_t, checkout_new, ike_sa_t*,
942 private_ike_sa_manager_t* this, ike_version_t version, bool initiator)
943 {
944 ike_sa_id_t *ike_sa_id;
945 ike_sa_t *ike_sa;
946 u_int8_t ike_version;
947
948 ike_version = version == IKEV1 ? IKEV1_MAJOR_VERSION : IKEV2_MAJOR_VERSION;
949
950 if (initiator)
951 {
952 ike_sa_id = ike_sa_id_create(ike_version, get_spi(this), 0, TRUE);
953 }
954 else
955 {
956 ike_sa_id = ike_sa_id_create(ike_version, 0, get_spi(this), FALSE);
957 }
958 ike_sa = ike_sa_create(ike_sa_id, initiator, version);
959 ike_sa_id->destroy(ike_sa_id);
960
961 if (ike_sa)
962 {
963 DBG2(DBG_MGR, "created IKE_SA %s[%u]", ike_sa->get_name(ike_sa),
964 ike_sa->get_unique_id(ike_sa));
965 }
966 return ike_sa;
967 }
968
969 METHOD(ike_sa_manager_t, checkout_by_message, ike_sa_t*,
970 private_ike_sa_manager_t* this, message_t *message)
971 {
972 u_int segment;
973 entry_t *entry;
974 ike_sa_t *ike_sa = NULL;
975 ike_sa_id_t *id;
976 ike_version_t ike_version;
977 bool is_init = FALSE;
978
979 id = message->get_ike_sa_id(message);
980 id = id->clone(id);
981 id->switch_initiator(id);
982
983 DBG2(DBG_MGR, "checkout IKE_SA by message");
984
985 if (id->get_responder_spi(id) == 0)
986 {
987 if (message->get_major_version(message) == IKEV2_MAJOR_VERSION)
988 {
989 if (message->get_exchange_type(message) == IKE_SA_INIT &&
990 message->get_request(message))
991 {
992 ike_version = IKEV2;
993 is_init = TRUE;
994 }
995 }
996 else
997 {
998 if (message->get_exchange_type(message) == ID_PROT ||
999 message->get_exchange_type(message) == AGGRESSIVE)
1000 {
1001 ike_version = IKEV1;
1002 is_init = TRUE;
1003 if (id->is_initiator(id))
1004 { /* not set in IKEv1, switch back before applying to new SA */
1005 id->switch_initiator(id);
1006 }
1007 }
1008 }
1009 }
1010
1011 if (is_init && this->hasher)
1012 {
1013 /* First request. Check for an IKE_SA with such a message hash. */
1014 chunk_t hash;
1015
1016 this->hasher->allocate_hash(this->hasher,
1017 message->get_packet_data(message), &hash);
1018
1019 if (get_entry_by_hash(this, id, hash, &entry, &segment) == SUCCESS)
1020 {
1021 if (message->get_exchange_type(message) == IKE_SA_INIT &&
1022 entry->message_id == 0)
1023 {
1024 unlock_single_segment(this, segment);
1025 chunk_free(&hash);
1026 id->destroy(id);
1027 DBG1(DBG_MGR, "ignoring IKE_SA_INIT, already processing");
1028 return NULL;
1029 }
1030 else if (wait_for_entry(this, entry, segment))
1031 {
1032 entry->checked_out = TRUE;
1033 entry->message_id = message->get_message_id(message);
1034 ike_sa = entry->ike_sa;
1035 DBG2(DBG_MGR, "IKE_SA %s[%u] checked out by hash",
1036 ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa));
1037 chunk_free(&hash);
1038 }
1039 unlock_single_segment(this, segment);
1040 }
1041
1042 if (ike_sa == NULL)
1043 {
1044 /* no IKE_SA found, create a new one */
1045 id->set_responder_spi(id, get_spi(this));
1046 ike_sa = ike_sa_create(id, FALSE, ike_version);
1047 if (ike_sa)
1048 {
1049 entry = entry_create();
1050 /* a new SA checked out by message is a responder SA */
1051 entry->ike_sa = ike_sa;
1052 entry->ike_sa_id = id->clone(id);
1053
1054 segment = put_entry(this, entry);
1055 entry->checked_out = TRUE;
1056 unlock_single_segment(this, segment);
1057
1058 entry->message_id = message->get_message_id(message);
1059 entry->init_hash = hash;
1060
1061 DBG2(DBG_MGR, "created IKE_SA %s[%u]",
1062 ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa));
1063 }
1064 }
1065 if (ike_sa == NULL)
1066 {
1067 chunk_free(&hash);
1068 DBG1(DBG_MGR, "ignoring message, no such IKE_SA");
1069 }
1070 id->destroy(id);
1071 charon->bus->set_sa(charon->bus, ike_sa);
1072 return ike_sa;
1073 }
1074
1075 if (get_entry_by_id(this, id, &entry, &segment) == SUCCESS)
1076 {
1077 /* only check out in IKEv2 if we are not already processing it */
1078 if (message->get_request(message) &&
1079 message->get_message_id(message) == entry->message_id)
1080 {
1081 DBG1(DBG_MGR, "ignoring request with ID %u, already processing",
1082 entry->message_id);
1083 }
1084 else if (wait_for_entry(this, entry, segment))
1085 {
1086 ike_sa_id_t *ike_id;
1087
1088 ike_id = entry->ike_sa->get_id(entry->ike_sa);
1089 entry->checked_out = TRUE;
1090 entry->message_id = message->get_message_id(message);
1091 if (ike_id->get_responder_spi(ike_id) == 0)
1092 {
1093 ike_id->set_responder_spi(ike_id, id->get_responder_spi(id));
1094 }
1095 ike_sa = entry->ike_sa;
1096 DBG2(DBG_MGR, "IKE_SA %s[%u] successfully checked out",
1097 ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa));
1098 }
1099 unlock_single_segment(this, segment);
1100 }
1101 id->destroy(id);
1102 charon->bus->set_sa(charon->bus, ike_sa);
1103 return ike_sa;
1104 }
1105
1106 METHOD(ike_sa_manager_t, checkout_by_config, ike_sa_t*,
1107 private_ike_sa_manager_t *this, peer_cfg_t *peer_cfg)
1108 {
1109 enumerator_t *enumerator;
1110 entry_t *entry;
1111 ike_sa_t *ike_sa = NULL;
1112 peer_cfg_t *current_peer;
1113 ike_cfg_t *current_ike;
1114 u_int segment;
1115
1116 DBG2(DBG_MGR, "checkout IKE_SA by config");
1117
1118 if (!this->reuse_ikesa)
1119 { /* IKE_SA reuse disable by config */
1120 ike_sa = checkout_new(this, peer_cfg->get_ike_version(peer_cfg), TRUE);
1121 charon->bus->set_sa(charon->bus, ike_sa);
1122 return ike_sa;
1123 }
1124
1125 enumerator = create_table_enumerator(this);
1126 while (enumerator->enumerate(enumerator, &entry, &segment))
1127 {
1128 if (!wait_for_entry(this, entry, segment))
1129 {
1130 continue;
1131 }
1132 if (entry->ike_sa->get_state(entry->ike_sa) == IKE_DELETING)
1133 { /* skip IKE_SAs which are not usable */
1134 continue;
1135 }
1136
1137 current_peer = entry->ike_sa->get_peer_cfg(entry->ike_sa);
1138 if (current_peer && current_peer->equals(current_peer, peer_cfg))
1139 {
1140 current_ike = current_peer->get_ike_cfg(current_peer);
1141 if (current_ike->equals(current_ike, peer_cfg->get_ike_cfg(peer_cfg)))
1142 {
1143 entry->checked_out = TRUE;
1144 ike_sa = entry->ike_sa;
1145 DBG2(DBG_MGR, "found existing IKE_SA %u with a '%s' config",
1146 ike_sa->get_unique_id(ike_sa),
1147 current_peer->get_name(current_peer));
1148 break;
1149 }
1150 }
1151 }
1152 enumerator->destroy(enumerator);
1153
1154 if (!ike_sa)
1155 { /* no IKE_SA using such a config, hand out a new */
1156 ike_sa = checkout_new(this, peer_cfg->get_ike_version(peer_cfg), TRUE);
1157 }
1158 charon->bus->set_sa(charon->bus, ike_sa);
1159 return ike_sa;
1160 }
1161
1162 METHOD(ike_sa_manager_t, checkout_by_id, ike_sa_t*,
1163 private_ike_sa_manager_t *this, u_int32_t id, bool child)
1164 {
1165 enumerator_t *enumerator, *children;
1166 entry_t *entry;
1167 ike_sa_t *ike_sa = NULL;
1168 child_sa_t *child_sa;
1169 u_int segment;
1170
1171 DBG2(DBG_MGR, "checkout IKE_SA by ID");
1172
1173 enumerator = create_table_enumerator(this);
1174 while (enumerator->enumerate(enumerator, &entry, &segment))
1175 {
1176 if (wait_for_entry(this, entry, segment))
1177 {
1178 /* look for a child with such a reqid ... */
1179 if (child)
1180 {
1181 children = entry->ike_sa->create_child_sa_enumerator(entry->ike_sa);
1182 while (children->enumerate(children, (void**)&child_sa))
1183 {
1184 if (child_sa->get_reqid(child_sa) == id)
1185 {
1186 ike_sa = entry->ike_sa;
1187 break;
1188 }
1189 }
1190 children->destroy(children);
1191 }
1192 else /* ... or for a IKE_SA with such a unique id */
1193 {
1194 if (entry->ike_sa->get_unique_id(entry->ike_sa) == id)
1195 {
1196 ike_sa = entry->ike_sa;
1197 }
1198 }
1199 /* got one, return */
1200 if (ike_sa)
1201 {
1202 entry->checked_out = TRUE;
1203 DBG2(DBG_MGR, "IKE_SA %s[%u] successfully checked out",
1204 ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa));
1205 break;
1206 }
1207 }
1208 }
1209 enumerator->destroy(enumerator);
1210
1211 charon->bus->set_sa(charon->bus, ike_sa);
1212 return ike_sa;
1213 }
1214
1215 METHOD(ike_sa_manager_t, checkout_by_name, ike_sa_t*,
1216 private_ike_sa_manager_t *this, char *name, bool child)
1217 {
1218 enumerator_t *enumerator, *children;
1219 entry_t *entry;
1220 ike_sa_t *ike_sa = NULL;
1221 child_sa_t *child_sa;
1222 u_int segment;
1223
1224 enumerator = create_table_enumerator(this);
1225 while (enumerator->enumerate(enumerator, &entry, &segment))
1226 {
1227 if (wait_for_entry(this, entry, segment))
1228 {
1229 /* look for a child with such a policy name ... */
1230 if (child)
1231 {
1232 children = entry->ike_sa->create_child_sa_enumerator(entry->ike_sa);
1233 while (children->enumerate(children, (void**)&child_sa))
1234 {
1235 if (streq(child_sa->get_name(child_sa), name))
1236 {
1237 ike_sa = entry->ike_sa;
1238 break;
1239 }
1240 }
1241 children->destroy(children);
1242 }
1243 else /* ... or for a IKE_SA with such a connection name */
1244 {
1245 if (streq(entry->ike_sa->get_name(entry->ike_sa), name))
1246 {
1247 ike_sa = entry->ike_sa;
1248 }
1249 }
1250 /* got one, return */
1251 if (ike_sa)
1252 {
1253 entry->checked_out = TRUE;
1254 DBG2(DBG_MGR, "IKE_SA %s[%u] successfully checked out",
1255 ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa));
1256 break;
1257 }
1258 }
1259 }
1260 enumerator->destroy(enumerator);
1261
1262 charon->bus->set_sa(charon->bus, ike_sa);
1263 return ike_sa;
1264 }
1265
1266 /**
1267 * enumerator filter function, waiting variant
1268 */
1269 static bool enumerator_filter_wait(private_ike_sa_manager_t *this,
1270 entry_t **in, ike_sa_t **out, u_int *segment)
1271 {
1272 if (wait_for_entry(this, *in, *segment))
1273 {
1274 *out = (*in)->ike_sa;
1275 charon->bus->set_sa(charon->bus, *out);
1276 return TRUE;
1277 }
1278 return FALSE;
1279 }
1280
1281 /**
1282 * enumerator filter function, skipping variant
1283 */
1284 static bool enumerator_filter_skip(private_ike_sa_manager_t *this,
1285 entry_t **in, ike_sa_t **out, u_int *segment)
1286 {
1287 if (!(*in)->driveout_new_threads &&
1288 !(*in)->driveout_waiting_threads &&
1289 !(*in)->checked_out)
1290 {
1291 *out = (*in)->ike_sa;
1292 charon->bus->set_sa(charon->bus, *out);
1293 return TRUE;
1294 }
1295 return FALSE;
1296 }
1297
1298 /**
1299 * Reset threads SA after enumeration
1300 */
1301 static void reset_sa(void *data)
1302 {
1303 charon->bus->set_sa(charon->bus, NULL);
1304 }
1305
1306 METHOD(ike_sa_manager_t, create_enumerator, enumerator_t*,
1307 private_ike_sa_manager_t* this, bool wait)
1308 {
1309 return enumerator_create_filter(create_table_enumerator(this),
1310 wait ? (void*)enumerator_filter_wait : (void*)enumerator_filter_skip,
1311 this, reset_sa);
1312 }
1313
1314 METHOD(ike_sa_manager_t, checkin, void,
1315 private_ike_sa_manager_t *this, ike_sa_t *ike_sa)
1316 {
1317 /* to check the SA back in, we look for the pointer of the ike_sa
1318 * in all entries.
1319 * The lookup is done by initiator SPI, so even if the SPI has changed (e.g.
1320 * on reception of a IKE_SA_INIT response) the lookup will work but
1321 * updating of the SPI MAY be necessary...
1322 */
1323 entry_t *entry;
1324 ike_sa_id_t *ike_sa_id;
1325 host_t *other;
1326 identification_t *my_id, *other_id;
1327 u_int segment;
1328
1329 ike_sa_id = ike_sa->get_id(ike_sa);
1330 my_id = ike_sa->get_my_id(ike_sa);
1331 other_id = ike_sa->get_other_id(ike_sa);
1332 other = ike_sa->get_other_host(ike_sa);
1333
1334 DBG2(DBG_MGR, "checkin IKE_SA %s[%u]", ike_sa->get_name(ike_sa),
1335 ike_sa->get_unique_id(ike_sa));
1336
1337 /* look for the entry */
1338 if (get_entry_by_sa(this, ike_sa_id, ike_sa, &entry, &segment) == SUCCESS)
1339 {
1340 /* ike_sa_id must be updated */
1341 entry->ike_sa_id->replace_values(entry->ike_sa_id, ike_sa->get_id(ike_sa));
1342 /* signal waiting threads */
1343 entry->checked_out = FALSE;
1344 entry->message_id = -1;
1345 /* check if this SA is half-open */
1346 if (entry->half_open && ike_sa->get_state(ike_sa) != IKE_CONNECTING)
1347 {
1348 /* not half open anymore */
1349 entry->half_open = FALSE;
1350 remove_half_open(this, entry);
1351 }
1352 else if (entry->half_open && !other->ip_equals(other, entry->other))
1353 {
1354 /* the other host's IP has changed, we must update the hash table */
1355 remove_half_open(this, entry);
1356 DESTROY_IF(entry->other);
1357 entry->other = other->clone(other);
1358 put_half_open(this, entry);
1359 }
1360 else if (!entry->half_open &&
1361 !entry->ike_sa_id->is_initiator(entry->ike_sa_id) &&
1362 ike_sa->get_state(ike_sa) == IKE_CONNECTING)
1363 {
1364 /* this is a new half-open SA */
1365 entry->half_open = TRUE;
1366 entry->other = other->clone(other);
1367 put_half_open(this, entry);
1368 }
1369 DBG2(DBG_MGR, "check-in of IKE_SA successful.");
1370 entry->condvar->signal(entry->condvar);
1371 }
1372 else
1373 {
1374 entry = entry_create();
1375 entry->ike_sa_id = ike_sa_id->clone(ike_sa_id);
1376 entry->ike_sa = ike_sa;
1377 segment = put_entry(this, entry);
1378 }
1379
1380 /* apply identities for duplicate test */
1381 if ((ike_sa->get_state(ike_sa) == IKE_ESTABLISHED ||
1382 ike_sa->get_state(ike_sa) == IKE_PASSIVE) &&
1383 entry->my_id == NULL && entry->other_id == NULL)
1384 {
1385 if (ike_sa->get_version(ike_sa) == IKEV1)
1386 {
1387 /* If authenticated and received INITIAL_CONTACT,
1388 * delete any existing IKE_SAs with that peer. */
1389 if (ike_sa->has_condition(ike_sa, COND_INIT_CONTACT_SEEN))
1390 {
1391 this->public.check_uniqueness(&this->public, ike_sa, TRUE);
1392 ike_sa->set_condition(ike_sa, COND_INIT_CONTACT_SEEN, FALSE);
1393 }
1394 }
1395
1396 entry->my_id = my_id->clone(my_id);
1397 entry->other_id = other_id->clone(other_id);
1398 if (!entry->other)
1399 {
1400 entry->other = other->clone(other);
1401 }
1402 put_connected_peers(this, entry);
1403 }
1404
1405 unlock_single_segment(this, segment);
1406
1407 charon->bus->set_sa(charon->bus, NULL);
1408 }
1409
1410 METHOD(ike_sa_manager_t, checkin_and_destroy, void,
1411 private_ike_sa_manager_t *this, ike_sa_t *ike_sa)
1412 {
1413 /* deletion is a bit complex, we must ensure that no thread is waiting for
1414 * this SA.
1415 * We take this SA from the table, and start signaling while threads
1416 * are in the condvar.
1417 */
1418 entry_t *entry;
1419 ike_sa_id_t *ike_sa_id;
1420 u_int segment;
1421
1422 ike_sa_id = ike_sa->get_id(ike_sa);
1423
1424 DBG2(DBG_MGR, "checkin and destroy IKE_SA %s[%u]", ike_sa->get_name(ike_sa),
1425 ike_sa->get_unique_id(ike_sa));
1426
1427 if (get_entry_by_sa(this, ike_sa_id, ike_sa, &entry, &segment) == SUCCESS)
1428 {
1429 /* drive out waiting threads, as we are in hurry */
1430 entry->driveout_waiting_threads = TRUE;
1431 /* mark it, so no new threads can get this entry */
1432 entry->driveout_new_threads = TRUE;
1433 /* wait until all workers have done their work */
1434 while (entry->waiting_threads)
1435 {
1436 /* wake up all */
1437 entry->condvar->broadcast(entry->condvar);
1438 /* they will wake us again when their work is done */
1439 entry->condvar->wait(entry->condvar, this->segments[segment].mutex);
1440 }
1441 remove_entry(this, entry);
1442 unlock_single_segment(this, segment);
1443
1444 if (entry->half_open)
1445 {
1446 remove_half_open(this, entry);
1447 }
1448 if (entry->my_id && entry->other_id)
1449 {
1450 remove_connected_peers(this, entry);
1451 }
1452
1453 entry_destroy(entry);
1454
1455 DBG2(DBG_MGR, "check-in and destroy of IKE_SA successful");
1456 }
1457 else
1458 {
1459 DBG1(DBG_MGR, "tried to check-in and delete nonexisting IKE_SA");
1460 ike_sa->destroy(ike_sa);
1461 }
1462 charon->bus->set_sa(charon->bus, NULL);
1463 }
1464
1465 /**
1466 * Cleanup function for create_id_enumerator
1467 */
1468 static void id_enumerator_cleanup(linked_list_t *ids)
1469 {
1470 ids->destroy_offset(ids, offsetof(ike_sa_id_t, destroy));
1471 }
1472
1473 METHOD(ike_sa_manager_t, create_id_enumerator, enumerator_t*,
1474 private_ike_sa_manager_t *this, identification_t *me,
1475 identification_t *other, int family)
1476 {
1477 linked_list_t *list, *ids = NULL;
1478 connected_peers_t *current;
1479 u_int row, segment;
1480 rwlock_t *lock;
1481
1482 row = chunk_hash_inc(other->get_encoding(other),
1483 chunk_hash(me->get_encoding(me))) & this->table_mask;
1484 segment = row & this->segment_mask;
1485
1486 lock = this->connected_peers_segments[segment & this->segment_mask].lock;
1487 lock->read_lock(lock);
1488 list = this->connected_peers_table[row];
1489 if (list)
1490 {
1491 if (list->find_first(list, (linked_list_match_t)connected_peers_match,
1492 (void**)&current, me, other, (uintptr_t)family) == SUCCESS)
1493 {
1494 ids = current->sas->clone_offset(current->sas,
1495 offsetof(ike_sa_id_t, clone));
1496 }
1497 }
1498 lock->unlock(lock);
1499
1500 if (!ids)
1501 {
1502 return enumerator_create_empty();
1503 }
1504 return enumerator_create_cleaner(ids->create_enumerator(ids),
1505 (void*)id_enumerator_cleanup, ids);
1506 }
1507
1508 METHOD(ike_sa_manager_t, check_uniqueness, bool,
1509 private_ike_sa_manager_t *this, ike_sa_t *ike_sa, bool force_replace)
1510 {
1511 bool cancel = FALSE;
1512 peer_cfg_t *peer_cfg;
1513 unique_policy_t policy;
1514 enumerator_t *enumerator;
1515 ike_sa_id_t *id = NULL;
1516 identification_t *me, *other;
1517 host_t *other_host;
1518
1519 peer_cfg = ike_sa->get_peer_cfg(ike_sa);
1520 policy = peer_cfg->get_unique_policy(peer_cfg);
1521 if (policy == UNIQUE_NO && !force_replace)
1522 {
1523 return FALSE;
1524 }
1525 me = ike_sa->get_my_id(ike_sa);
1526 other = ike_sa->get_other_id(ike_sa);
1527 other_host = ike_sa->get_other_host(ike_sa);
1528
1529 enumerator = create_id_enumerator(this, me, other,
1530 other_host->get_family(other_host));
1531 while (enumerator->enumerate(enumerator, &id))
1532 {
1533 status_t status = SUCCESS;
1534 ike_sa_t *duplicate;
1535
1536 duplicate = checkout(this, id);
1537 if (!duplicate)
1538 {
1539 continue;
1540 }
1541 if (force_replace)
1542 {
1543 DBG1(DBG_IKE, "destroying duplicate IKE_SA for peer '%Y', "
1544 "received INITIAL_CONTACT", other);
1545 checkin_and_destroy(this, duplicate);
1546 continue;
1547 }
1548 peer_cfg = duplicate->get_peer_cfg(duplicate);
1549 if (peer_cfg && peer_cfg->equals(peer_cfg, ike_sa->get_peer_cfg(ike_sa)))
1550 {
1551 switch (duplicate->get_state(duplicate))
1552 {
1553 case IKE_ESTABLISHED:
1554 case IKE_REKEYING:
1555 switch (policy)
1556 {
1557 case UNIQUE_REPLACE:
1558 DBG1(DBG_IKE, "deleting duplicate IKE_SA for peer "
1559 "'%Y' due to uniqueness policy", other);
1560 status = duplicate->delete(duplicate);
1561 break;
1562 case UNIQUE_KEEP:
1563 cancel = TRUE;
1564 /* we keep the first IKE_SA and delete all
1565 * other duplicates that might exist */
1566 policy = UNIQUE_REPLACE;
1567 break;
1568 default:
1569 break;
1570 }
1571 break;
1572 default:
1573 break;
1574 }
1575 }
1576 if (status == DESTROY_ME)
1577 {
1578 checkin_and_destroy(this, duplicate);
1579 }
1580 else
1581 {
1582 checkin(this, duplicate);
1583 }
1584 }
1585 enumerator->destroy(enumerator);
1586 /* reset thread's current IKE_SA after checkin */
1587 charon->bus->set_sa(charon->bus, ike_sa);
1588 return cancel;
1589 }
1590
1591 METHOD(ike_sa_manager_t, has_contact, bool,
1592 private_ike_sa_manager_t *this, identification_t *me,
1593 identification_t *other, int family)
1594 {
1595 linked_list_t *list;
1596 u_int row, segment;
1597 rwlock_t *lock;
1598 bool found = FALSE;
1599
1600 row = chunk_hash_inc(other->get_encoding(other),
1601 chunk_hash(me->get_encoding(me))) & this->table_mask;
1602 segment = row & this->segment_mask;
1603 lock = this->connected_peers_segments[segment & this->segment_mask].lock;
1604 lock->read_lock(lock);
1605 list = this->connected_peers_table[row];
1606 if (list)
1607 {
1608 if (list->find_first(list, (linked_list_match_t)connected_peers_match,
1609 NULL, me, other, family) == SUCCESS)
1610 {
1611 found = TRUE;
1612 }
1613 }
1614 lock->unlock(lock);
1615
1616 return found;
1617 }
1618
1619 METHOD(ike_sa_manager_t, get_count, u_int,
1620 private_ike_sa_manager_t *this)
1621 {
1622 u_int segment, count = 0;
1623 mutex_t *mutex;
1624
1625 for (segment = 0; segment < this->segment_count; segment++)
1626 {
1627 mutex = this->segments[segment & this->segment_mask].mutex;
1628 mutex->lock(mutex);
1629 count += this->segments[segment].count;
1630 mutex->unlock(mutex);
1631 }
1632 return count;
1633 }
1634
1635 METHOD(ike_sa_manager_t, get_half_open_count, u_int,
1636 private_ike_sa_manager_t *this, host_t *ip)
1637 {
1638 linked_list_t *list;
1639 u_int segment, row;
1640 rwlock_t *lock;
1641 chunk_t addr;
1642 u_int count = 0;
1643
1644 if (ip)
1645 {
1646 addr = ip->get_address(ip);
1647 row = chunk_hash(addr) & this->table_mask;
1648 segment = row & this->segment_mask;
1649 lock = this->half_open_segments[segment & this->segment_mask].lock;
1650 lock->read_lock(lock);
1651 if ((list = this->half_open_table[row]) != NULL)
1652 {
1653 half_open_t *current;
1654
1655 if (list->find_first(list, (linked_list_match_t)half_open_match,
1656 (void**)&current, &addr) == SUCCESS)
1657 {
1658 count = current->count;
1659 }
1660 }
1661 lock->unlock(lock);
1662 }
1663 else
1664 {
1665 for (segment = 0; segment < this->segment_count; segment++)
1666 {
1667 lock = this->half_open_segments[segment & this->segment_mask].lock;
1668 lock->read_lock(lock);
1669 count += this->half_open_segments[segment].count;
1670 lock->unlock(lock);
1671 }
1672 }
1673 return count;
1674 }
1675
1676 METHOD(ike_sa_manager_t, flush, void,
1677 private_ike_sa_manager_t *this)
1678 {
1679 /* destroy all list entries */
1680 enumerator_t *enumerator;
1681 entry_t *entry;
1682 u_int segment;
1683
1684 lock_all_segments(this);
1685 DBG2(DBG_MGR, "going to destroy IKE_SA manager and all managed IKE_SA's");
1686 /* Step 1: drive out all waiting threads */
1687 DBG2(DBG_MGR, "set driveout flags for all stored IKE_SA's");
1688 enumerator = create_table_enumerator(this);
1689 while (enumerator->enumerate(enumerator, &entry, &segment))
1690 {
1691 /* do not accept new threads, drive out waiting threads */
1692 entry->driveout_new_threads = TRUE;
1693 entry->driveout_waiting_threads = TRUE;
1694 }
1695 enumerator->destroy(enumerator);
1696 DBG2(DBG_MGR, "wait for all threads to leave IKE_SA's");
1697 /* Step 2: wait until all are gone */
1698 enumerator = create_table_enumerator(this);
1699 while (enumerator->enumerate(enumerator, &entry, &segment))
1700 {
1701 while (entry->waiting_threads || entry->checked_out)
1702 {
1703 /* wake up all */
1704 entry->condvar->broadcast(entry->condvar);
1705 /* go sleeping until they are gone */
1706 entry->condvar->wait(entry->condvar, this->segments[segment].mutex);
1707 }
1708 }
1709 enumerator->destroy(enumerator);
1710 DBG2(DBG_MGR, "delete all IKE_SA's");
1711 /* Step 3: initiate deletion of all IKE_SAs */
1712 enumerator = create_table_enumerator(this);
1713 while (enumerator->enumerate(enumerator, &entry, &segment))
1714 {
1715 charon->bus->set_sa(charon->bus, entry->ike_sa);
1716 if (entry->ike_sa->get_version(entry->ike_sa) == IKEV2)
1717 { /* as the delete never gets processed, fire down events */
1718 switch (entry->ike_sa->get_state(entry->ike_sa))
1719 {
1720 case IKE_ESTABLISHED:
1721 case IKE_REKEYING:
1722 case IKE_DELETING:
1723 charon->bus->ike_updown(charon->bus, entry->ike_sa, FALSE);
1724 break;
1725 default:
1726 break;
1727 }
1728 }
1729 entry->ike_sa->delete(entry->ike_sa);
1730 }
1731 enumerator->destroy(enumerator);
1732
1733 DBG2(DBG_MGR, "destroy all entries");
1734 /* Step 4: destroy all entries */
1735 enumerator = create_table_enumerator(this);
1736 while (enumerator->enumerate(enumerator, &entry, &segment))
1737 {
1738 charon->bus->set_sa(charon->bus, entry->ike_sa);
1739 if (entry->half_open)
1740 {
1741 remove_half_open(this, entry);
1742 }
1743 if (entry->my_id && entry->other_id)
1744 {
1745 remove_connected_peers(this, entry);
1746 }
1747 remove_entry_at((private_enumerator_t*)enumerator);
1748 entry_destroy(entry);
1749 }
1750 enumerator->destroy(enumerator);
1751 charon->bus->set_sa(charon->bus, NULL);
1752 unlock_all_segments(this);
1753
1754 this->rng->destroy(this->rng);
1755 this->rng = NULL;
1756 this->hasher->destroy(this->hasher);
1757 this->hasher = NULL;
1758 }
1759
1760 METHOD(ike_sa_manager_t, destroy, void,
1761 private_ike_sa_manager_t *this)
1762 {
1763 u_int i;
1764
1765 for (i = 0; i < this->table_size; i++)
1766 {
1767 DESTROY_IF(this->ike_sa_table[i]);
1768 DESTROY_IF(this->half_open_table[i]);
1769 DESTROY_IF(this->connected_peers_table[i]);
1770 }
1771 free(this->ike_sa_table);
1772 free(this->half_open_table);
1773 free(this->connected_peers_table);
1774 for (i = 0; i < this->segment_count; i++)
1775 {
1776 this->segments[i].mutex->destroy(this->segments[i].mutex);
1777 this->half_open_segments[i].lock->destroy(this->half_open_segments[i].lock);
1778 this->connected_peers_segments[i].lock->destroy(this->connected_peers_segments[i].lock);
1779 }
1780 free(this->segments);
1781 free(this->half_open_segments);
1782 free(this->connected_peers_segments);
1783
1784 free(this);
1785 }
1786
1787 /**
1788 * This function returns the next-highest power of two for the given number.
1789 * The algorithm works by setting all bits on the right-hand side of the most
1790 * significant 1 to 1 and then increments the whole number so it rolls over
1791 * to the nearest power of two. Note: returns 0 for n == 0
1792 */
1793 static u_int get_nearest_powerof2(u_int n)
1794 {
1795 u_int i;
1796
1797 --n;
1798 for (i = 1; i < sizeof(u_int) * 8; i <<= 1)
1799 {
1800 n |= n >> i;
1801 }
1802 return ++n;
1803 }
1804
1805 /*
1806 * Described in header.
1807 */
1808 ike_sa_manager_t *ike_sa_manager_create()
1809 {
1810 private_ike_sa_manager_t *this;
1811 u_int i;
1812
1813 INIT(this,
1814 .public = {
1815 .checkout = _checkout,
1816 .checkout_new = _checkout_new,
1817 .checkout_by_message = _checkout_by_message,
1818 .checkout_by_config = _checkout_by_config,
1819 .checkout_by_id = _checkout_by_id,
1820 .checkout_by_name = _checkout_by_name,
1821 .check_uniqueness = _check_uniqueness,
1822 .has_contact = _has_contact,
1823 .create_enumerator = _create_enumerator,
1824 .create_id_enumerator = _create_id_enumerator,
1825 .checkin = _checkin,
1826 .checkin_and_destroy = _checkin_and_destroy,
1827 .get_count = _get_count,
1828 .get_half_open_count = _get_half_open_count,
1829 .flush = _flush,
1830 .destroy = _destroy,
1831 },
1832 );
1833
1834 this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_PREFERRED);
1835 if (this->hasher == NULL)
1836 {
1837 DBG1(DBG_MGR, "manager initialization failed, no hasher supported");
1838 free(this);
1839 return NULL;
1840 }
1841 this->rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
1842 if (this->rng == NULL)
1843 {
1844 DBG1(DBG_MGR, "manager initialization failed, no RNG supported");
1845 this->hasher->destroy(this->hasher);
1846 free(this);
1847 return NULL;
1848 }
1849
1850 this->table_size = get_nearest_powerof2(lib->settings->get_int(lib->settings,
1851 "charon.ikesa_table_size", DEFAULT_HASHTABLE_SIZE));
1852 this->table_size = max(1, min(this->table_size, MAX_HASHTABLE_SIZE));
1853 this->table_mask = this->table_size - 1;
1854
1855 this->segment_count = get_nearest_powerof2(lib->settings->get_int(lib->settings,
1856 "charon.ikesa_table_segments", DEFAULT_SEGMENT_COUNT));
1857 this->segment_count = max(1, min(this->segment_count, this->table_size));
1858 this->segment_mask = this->segment_count - 1;
1859 this->ike_sa_table = calloc(this->table_size, sizeof(linked_list_t*));
1860
1861 this->segments = (segment_t*)calloc(this->segment_count, sizeof(segment_t));
1862 for (i = 0; i < this->segment_count; i++)
1863 {
1864 this->segments[i].mutex = mutex_create(MUTEX_TYPE_RECURSIVE);
1865 this->segments[i].count = 0;
1866 }
1867
1868 /* we use the same table parameters for the table to track half-open SAs */
1869 this->half_open_table = calloc(this->table_size, sizeof(linked_list_t*));
1870 this->half_open_segments = calloc(this->segment_count, sizeof(shareable_segment_t));
1871 for (i = 0; i < this->segment_count; i++)
1872 {
1873 this->half_open_segments[i].lock = rwlock_create(RWLOCK_TYPE_DEFAULT);
1874 this->half_open_segments[i].count = 0;
1875 }
1876
1877 /* also for the hash table used for duplicate tests */
1878 this->connected_peers_table = calloc(this->table_size, sizeof(linked_list_t*));
1879 this->connected_peers_segments = calloc(this->segment_count, sizeof(shareable_segment_t));
1880 for (i = 0; i < this->segment_count; i++)
1881 {
1882 this->connected_peers_segments[i].lock = rwlock_create(RWLOCK_TYPE_DEFAULT);
1883 this->connected_peers_segments[i].count = 0;
1884 }
1885
1886 this->reuse_ikesa = lib->settings->get_bool(lib->settings,
1887 "charon.reuse_ikesa", TRUE);
1888 return &this->public;
1889 }