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