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