Annotation of embedaddon/strongswan/src/libcharon/sa/ike_sa_manager.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2005-2011 Martin Willi
3: * Copyright (C) 2011 revosec AG
4: *
5: * Copyright (C) 2008-2018 Tobias Brunner
6: * Copyright (C) 2005 Jan Hutter
7: * HSR Hochschule fuer Technik Rapperswil
8: *
9: * This program is free software; you can redistribute it and/or modify it
10: * under the terms of the GNU General Public License as published by the
11: * Free Software Foundation; either version 2 of the License, or (at your
12: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
13: *
14: * This program is distributed in the hope that it will be useful, but
15: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17: * for more details.
18: */
19:
20: #include <string.h>
21: #include <inttypes.h>
22:
23: #include "ike_sa_manager.h"
24:
25: #include <daemon.h>
26: #include <sa/ike_sa_id.h>
27: #include <bus/bus.h>
28: #include <threading/thread.h>
29: #include <threading/condvar.h>
30: #include <threading/mutex.h>
31: #include <threading/rwlock.h>
32: #include <collections/linked_list.h>
33: #include <crypto/hashers/hasher.h>
34: #include <processing/jobs/delete_ike_sa_job.h>
35:
36: /* the default size of the hash table (MUST be a power of 2) */
37: #define DEFAULT_HASHTABLE_SIZE 1
38:
39: /* the maximum size of the hash table (MUST be a power of 2) */
40: #define MAX_HASHTABLE_SIZE (1 << 30)
41:
42: /* the default number of segments (MUST be a power of 2) */
43: #define DEFAULT_SEGMENT_COUNT 1
44:
45: typedef struct entry_t entry_t;
46:
47: /**
48: * An entry in the linked list, contains IKE_SA, locking and lookup data.
49: */
50: struct entry_t {
51:
52: /**
53: * Number of threads waiting for this ike_sa_t object.
54: */
55: int waiting_threads;
56:
57: /**
58: * Condvar where threads can wait until ike_sa_t object is free for use again.
59: */
60: condvar_t *condvar;
61:
62: /**
63: * Thread by which this IKE_SA is currently checked out, if any
64: */
65: thread_t *checked_out;
66:
67: /**
68: * Does this SA drives out new threads?
69: */
70: bool driveout_new_threads;
71:
72: /**
73: * Does this SA drives out waiting threads?
74: */
75: bool driveout_waiting_threads;
76:
77: /**
78: * Identification of an IKE_SA (SPIs).
79: */
80: ike_sa_id_t *ike_sa_id;
81:
82: /**
83: * The contained ike_sa_t object.
84: */
85: ike_sa_t *ike_sa;
86:
87: /**
88: * hash of the IKE_SA_INIT message, used to detect retransmissions
89: */
90: chunk_t init_hash;
91:
92: /**
93: * remote host address, required for DoS detection and duplicate
94: * checking (host with same my_id and other_id is *not* considered
95: * a duplicate if the address family differs)
96: */
97: host_t *other;
98:
99: /**
100: * As responder: Is this SA half-open?
101: */
102: bool half_open;
103:
104: /**
105: * own identity, required for duplicate checking
106: */
107: identification_t *my_id;
108:
109: /**
110: * remote identity, required for duplicate checking
111: */
112: identification_t *other_id;
113:
114: /**
115: * message ID or hash of currently processing message, -1 if none
116: */
117: uint32_t processing;
118: };
119:
120: /**
121: * Implementation of entry_t.destroy.
122: */
123: static status_t entry_destroy(entry_t *this)
124: {
125: /* also destroy IKE SA */
126: this->ike_sa->destroy(this->ike_sa);
127: this->ike_sa_id->destroy(this->ike_sa_id);
128: chunk_free(&this->init_hash);
129: DESTROY_IF(this->other);
130: DESTROY_IF(this->my_id);
131: DESTROY_IF(this->other_id);
132: this->condvar->destroy(this->condvar);
133: free(this);
134: return SUCCESS;
135: }
136:
137: /**
138: * Creates a new entry for the ike_sa_t list.
139: */
140: static entry_t *entry_create()
141: {
142: entry_t *this;
143:
144: INIT(this,
145: .condvar = condvar_create(CONDVAR_TYPE_DEFAULT),
146: .processing = -1,
147: );
148:
149: return this;
150: }
151:
152: /**
153: * Function that matches entry_t objects by ike_sa_id_t.
154: */
155: static bool entry_match_by_id(entry_t *entry, void *arg)
156: {
157: ike_sa_id_t *id = arg;
158:
159: if (id->equals(id, entry->ike_sa_id))
160: {
161: return TRUE;
162: }
163: if ((id->get_responder_spi(id) == 0 ||
164: entry->ike_sa_id->get_responder_spi(entry->ike_sa_id) == 0) &&
165: (id->get_ike_version(id) == IKEV1_MAJOR_VERSION ||
166: id->is_initiator(id) == entry->ike_sa_id->is_initiator(entry->ike_sa_id)) &&
167: id->get_initiator_spi(id) == entry->ike_sa_id->get_initiator_spi(entry->ike_sa_id))
168: {
169: /* this is TRUE for IKE_SAs that we initiated but have not yet received a response */
170: return TRUE;
171: }
172: return FALSE;
173: }
174:
175: /**
176: * Function that matches entry_t objects by ike_sa_t pointers.
177: */
178: static bool entry_match_by_sa(entry_t *entry, void *ike_sa)
179: {
180: return entry->ike_sa == ike_sa;
181: }
182:
183: /**
184: * Hash function for ike_sa_id_t objects.
185: */
186: static u_int ike_sa_id_hash(ike_sa_id_t *ike_sa_id)
187: {
188: /* IKEv2 does not mandate random SPIs (RFC 5996, 2.6), they just have to be
189: * locally unique, so we use our randomly allocated SPI whether we are
190: * initiator or responder to ensure a good distribution. The latter is not
191: * possible for IKEv1 as we don't know whether we are original initiator or
192: * not (based on the IKE header). But as RFC 2408, section 2.5.3 proposes
193: * SPIs (Cookies) to be allocated near random (we allocate them randomly
194: * anyway) it seems safe to always use the initiator SPI. */
195: if (ike_sa_id->get_ike_version(ike_sa_id) == IKEV1_MAJOR_VERSION ||
196: ike_sa_id->is_initiator(ike_sa_id))
197: {
198: return ike_sa_id->get_initiator_spi(ike_sa_id);
199: }
200: return ike_sa_id->get_responder_spi(ike_sa_id);
201: }
202:
203: typedef struct half_open_t half_open_t;
204:
205: /**
206: * Struct to manage half-open IKE_SAs per peer.
207: */
208: struct half_open_t {
209: /** chunk of remote host address */
210: chunk_t other;
211:
212: /** the number of half-open IKE_SAs with that host */
213: u_int count;
214:
215: /** the number of half-open IKE_SAs we responded to with that host */
216: u_int count_responder;
217: };
218:
219: /**
220: * Destroys a half_open_t object.
221: */
222: static void half_open_destroy(half_open_t *this)
223: {
224: chunk_free(&this->other);
225: free(this);
226: }
227:
228: typedef struct connected_peers_t connected_peers_t;
229:
230: struct connected_peers_t {
231: /** own identity */
232: identification_t *my_id;
233:
234: /** remote identity */
235: identification_t *other_id;
236:
237: /** ip address family of peer */
238: int family;
239:
240: /** list of ike_sa_id_t objects of IKE_SAs between the two identities */
241: linked_list_t *sas;
242: };
243:
244: static void connected_peers_destroy(connected_peers_t *this)
245: {
246: this->my_id->destroy(this->my_id);
247: this->other_id->destroy(this->other_id);
248: this->sas->destroy(this->sas);
249: free(this);
250: }
251:
252: /**
253: * Function that matches connected_peers_t objects by the given ids.
254: */
255: static inline bool connected_peers_match(connected_peers_t *connected_peers,
256: identification_t *my_id, identification_t *other_id,
257: int family)
258: {
259: return my_id->equals(my_id, connected_peers->my_id) &&
260: other_id->equals(other_id, connected_peers->other_id) &&
261: (!family || family == connected_peers->family);
262: }
263:
264: typedef struct init_hash_t init_hash_t;
265:
266: struct init_hash_t {
267: /** hash of IKE_SA_INIT or initial phase1 message (data is not cloned) */
268: chunk_t hash;
269:
270: /** our SPI allocated for the IKE_SA based on this message */
271: uint64_t our_spi;
272: };
273:
274: typedef struct segment_t segment_t;
275:
276: /**
277: * Struct to manage segments of the hash table.
278: */
279: struct segment_t {
280: /** mutex to access a segment exclusively */
281: mutex_t *mutex;
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 table_item_t table_item_t;
299:
300: /**
301: * Instead of using linked_list_t for each bucket we store the data in our own
302: * list to save memory.
303: */
304: struct table_item_t {
305: /** data of this item */
306: void *value;
307:
308: /** next item in the overflow list */
309: table_item_t *next;
310: };
311:
312: typedef struct private_ike_sa_manager_t private_ike_sa_manager_t;
313:
314: /**
315: * Additional private members of ike_sa_manager_t.
316: */
317: struct private_ike_sa_manager_t {
318: /**
319: * Public interface of ike_sa_manager_t.
320: */
321: ike_sa_manager_t public;
322:
323: /**
324: * Hash table with entries for the ike_sa_t objects.
325: */
326: table_item_t **ike_sa_table;
327:
328: /**
329: * The size of the hash table.
330: */
331: u_int table_size;
332:
333: /**
334: * Mask to map the hashes to table rows.
335: */
336: u_int table_mask;
337:
338: /**
339: * Segments of the hash table.
340: */
341: segment_t *segments;
342:
343: /**
344: * The number of segments.
345: */
346: u_int segment_count;
347:
348: /**
349: * Mask to map a table row to a segment.
350: */
351: u_int segment_mask;
352:
353: /**
354: * Hash table with half_open_t objects.
355: */
356: table_item_t **half_open_table;
357:
358: /**
359: * Segments of the "half-open" hash table.
360: */
361: shareable_segment_t *half_open_segments;
362:
363: /**
364: * Total number of half-open IKE_SAs.
365: */
366: refcount_t half_open_count;
367:
368: /**
369: * Total number of half-open IKE_SAs as responder.
370: */
371: refcount_t half_open_count_responder;
372:
373: /**
374: * Total number of IKE_SAs registered with IKE_SA manager.
375: */
376: refcount_t total_sa_count;
377:
378: /**
379: * Hash table with connected_peers_t objects.
380: */
381: table_item_t **connected_peers_table;
382:
383: /**
384: * Segments of the "connected peers" hash table.
385: */
386: shareable_segment_t *connected_peers_segments;
387:
388: /**
389: * Hash table with init_hash_t objects.
390: */
391: table_item_t **init_hashes_table;
392:
393: /**
394: * Segments of the "hashes" hash table.
395: */
396: segment_t *init_hashes_segments;
397:
398: /**
399: * RNG to get random SPIs for our side
400: */
401: rng_t *rng;
402:
403: /**
404: * Registered callback for IKE SPIs
405: */
406: struct {
407: spi_cb_t cb;
408: void *data;
409: } spi_cb;
410:
411: /**
412: * Lock to access the RNG instance and the callback
413: */
414: rwlock_t *spi_lock;
415:
416: /**
417: * Mask applied to local SPIs before mixing in the label
418: */
419: uint64_t spi_mask;
420:
421: /**
422: * Label applied to local SPIs
423: */
424: uint64_t spi_label;
425:
426: /**
427: * reuse existing IKE_SAs in checkout_by_config
428: */
429: bool reuse_ikesa;
430:
431: /**
432: * Configured IKE_SA limit, if any
433: */
434: u_int ikesa_limit;
435: };
436:
437: /**
438: * Acquire a lock to access the segment of the table row with the given index.
439: * It also works with the segment index directly.
440: */
441: static inline void lock_single_segment(private_ike_sa_manager_t *this,
442: u_int index)
443: {
444: mutex_t *lock = this->segments[index & this->segment_mask].mutex;
445: lock->lock(lock);
446: }
447:
448: /**
449: * Release the lock required to access the segment of the table row with the given index.
450: * It also works with the segment index directly.
451: */
452: static inline void unlock_single_segment(private_ike_sa_manager_t *this,
453: u_int index)
454: {
455: mutex_t *lock = this->segments[index & this->segment_mask].mutex;
456: lock->unlock(lock);
457: }
458:
459: /**
460: * Lock all segments
461: */
462: static void lock_all_segments(private_ike_sa_manager_t *this)
463: {
464: u_int i;
465:
466: for (i = 0; i < this->segment_count; i++)
467: {
468: this->segments[i].mutex->lock(this->segments[i].mutex);
469: }
470: }
471:
472: /**
473: * Unlock all segments
474: */
475: static void unlock_all_segments(private_ike_sa_manager_t *this)
476: {
477: u_int i;
478:
479: for (i = 0; i < this->segment_count; i++)
480: {
481: this->segments[i].mutex->unlock(this->segments[i].mutex);
482: }
483: }
484:
485: typedef struct private_enumerator_t private_enumerator_t;
486:
487: /**
488: * hash table enumerator implementation
489: */
490: struct private_enumerator_t {
491:
492: /**
493: * implements enumerator interface
494: */
495: enumerator_t enumerator;
496:
497: /**
498: * associated ike_sa_manager_t
499: */
500: private_ike_sa_manager_t *manager;
501:
502: /**
503: * current segment index
504: */
505: u_int segment;
506:
507: /**
508: * currently enumerating entry
509: */
510: entry_t *entry;
511:
512: /**
513: * current table row index
514: */
515: u_int row;
516:
517: /**
518: * current table item
519: */
520: table_item_t *current;
521:
522: /**
523: * previous table item
524: */
525: table_item_t *prev;
526: };
527:
528: METHOD(enumerator_t, enumerate, bool,
529: private_enumerator_t *this, va_list args)
530: {
531: entry_t **entry;
532: u_int *segment;
533:
534: VA_ARGS_VGET(args, entry, segment);
535:
536: if (this->entry)
537: {
538: this->entry->condvar->signal(this->entry->condvar);
539: this->entry = NULL;
540: }
541: while (this->segment < this->manager->segment_count)
542: {
543: while (this->row < this->manager->table_size)
544: {
545: this->prev = this->current;
546: if (this->current)
547: {
548: this->current = this->current->next;
549: }
550: else
551: {
552: lock_single_segment(this->manager, this->segment);
553: this->current = this->manager->ike_sa_table[this->row];
554: }
555: if (this->current)
556: {
557: *entry = this->entry = this->current->value;
558: *segment = this->segment;
559: return TRUE;
560: }
561: unlock_single_segment(this->manager, this->segment);
562: this->row += this->manager->segment_count;
563: }
564: this->segment++;
565: this->row = this->segment;
566: }
567: return FALSE;
568: }
569:
570: METHOD(enumerator_t, enumerator_destroy, void,
571: private_enumerator_t *this)
572: {
573: if (this->entry)
574: {
575: this->entry->condvar->signal(this->entry->condvar);
576: }
577: if (this->current)
578: {
579: unlock_single_segment(this->manager, this->segment);
580: }
581: free(this);
582: }
583:
584: /**
585: * Creates an enumerator to enumerate the entries in the hash table.
586: */
587: static enumerator_t* create_table_enumerator(private_ike_sa_manager_t *this)
588: {
589: private_enumerator_t *enumerator;
590:
591: INIT(enumerator,
592: .enumerator = {
593: .enumerate = enumerator_enumerate_default,
594: .venumerate = _enumerate,
595: .destroy = _enumerator_destroy,
596: },
597: .manager = this,
598: );
599: return &enumerator->enumerator;
600: }
601:
602: /**
603: * Put an entry into the hash table.
604: * Note: The caller has to unlock the returned segment.
605: */
606: static u_int put_entry(private_ike_sa_manager_t *this, entry_t *entry)
607: {
608: table_item_t *current, *item;
609: u_int row, segment;
610:
611: INIT(item,
612: .value = entry,
613: );
614:
615: row = ike_sa_id_hash(entry->ike_sa_id) & this->table_mask;
616: segment = row & this->segment_mask;
617:
618: lock_single_segment(this, segment);
619: current = this->ike_sa_table[row];
620: if (current)
621: { /* insert at the front of current bucket */
622: item->next = current;
623: }
624: this->ike_sa_table[row] = item;
625: ref_get(&this->total_sa_count);
626: return segment;
627: }
628:
629: /**
630: * Remove an entry from the hash table.
631: * Note: The caller MUST have a lock on the segment of this entry.
632: */
633: static void remove_entry(private_ike_sa_manager_t *this, entry_t *entry)
634: {
635: table_item_t *item, *prev = NULL;
636: u_int row;
637:
638: row = ike_sa_id_hash(entry->ike_sa_id) & this->table_mask;
639: item = this->ike_sa_table[row];
640: while (item)
641: {
642: if (item->value == entry)
643: {
644: if (prev)
645: {
646: prev->next = item->next;
647: }
648: else
649: {
650: this->ike_sa_table[row] = item->next;
651: }
652: ignore_result(ref_put(&this->total_sa_count));
653: free(item);
654: break;
655: }
656: prev = item;
657: item = item->next;
658: }
659: }
660:
661: /**
662: * Remove the entry at the current enumerator position.
663: */
664: static void remove_entry_at(private_enumerator_t *this)
665: {
666: this->entry = NULL;
667: if (this->current)
668: {
669: table_item_t *current = this->current;
670:
671: ignore_result(ref_put(&this->manager->total_sa_count));
672: this->current = this->prev;
673:
674: if (this->prev)
675: {
676: this->prev->next = current->next;
677: }
678: else
679: {
680: this->manager->ike_sa_table[this->row] = current->next;
681: unlock_single_segment(this->manager, this->segment);
682: }
683: free(current);
684: }
685: }
686:
687: /**
688: * Find an entry using the provided match function to compare the entries for
689: * equality.
690: */
691: static status_t get_entry_by_match_function(private_ike_sa_manager_t *this,
692: ike_sa_id_t *ike_sa_id, entry_t **entry, u_int *segment,
693: bool (*match)(entry_t*,void*), void *param)
694: {
695: table_item_t *item;
696: u_int row, seg;
697:
698: row = ike_sa_id_hash(ike_sa_id) & this->table_mask;
699: seg = row & this->segment_mask;
700:
701: lock_single_segment(this, seg);
702: item = this->ike_sa_table[row];
703: while (item)
704: {
705: if (match(item->value, param))
706: {
707: *entry = item->value;
708: *segment = seg;
709: /* the locked segment has to be unlocked by the caller */
710: return SUCCESS;
711: }
712: item = item->next;
713: }
714: unlock_single_segment(this, seg);
715: return NOT_FOUND;
716: }
717:
718: /**
719: * Find an entry by ike_sa_id_t.
720: * Note: On SUCCESS, the caller has to unlock the segment.
721: */
722: static status_t get_entry_by_id(private_ike_sa_manager_t *this,
723: ike_sa_id_t *ike_sa_id, entry_t **entry, u_int *segment)
724: {
725: return get_entry_by_match_function(this, ike_sa_id, entry, segment,
726: entry_match_by_id, ike_sa_id);
727: }
728:
729: /**
730: * Find an entry by IKE_SA pointer.
731: * Note: On SUCCESS, the caller has to unlock the segment.
732: */
733: static status_t get_entry_by_sa(private_ike_sa_manager_t *this,
734: ike_sa_id_t *ike_sa_id, ike_sa_t *ike_sa, entry_t **entry, u_int *segment)
735: {
736: return get_entry_by_match_function(this, ike_sa_id, entry, segment,
737: entry_match_by_sa, ike_sa);
738: }
739:
740: /**
741: * Wait until no other thread is using an IKE_SA, return FALSE if entry not
742: * acquirable.
743: */
744: static bool wait_for_entry(private_ike_sa_manager_t *this, entry_t *entry,
745: u_int segment)
746: {
747: if (entry->driveout_new_threads)
748: {
749: /* we are not allowed to get this */
750: return FALSE;
751: }
752: while (entry->checked_out && !entry->driveout_waiting_threads)
753: {
754: /* so wait until we can get it for us.
755: * we register us as waiting. */
756: entry->waiting_threads++;
757: entry->condvar->wait(entry->condvar, this->segments[segment].mutex);
758: entry->waiting_threads--;
759: }
760: /* hm, a deletion request forbids us to get this SA, get next one */
761: if (entry->driveout_waiting_threads)
762: {
763: /* we must signal here, others may be waiting on it, too */
764: entry->condvar->signal(entry->condvar);
765: return FALSE;
766: }
767: return TRUE;
768: }
769:
770: /**
771: * Put a half-open SA into the hash table.
772: */
773: static void put_half_open(private_ike_sa_manager_t *this, entry_t *entry)
774: {
775: table_item_t *item;
776: u_int row, segment;
777: rwlock_t *lock;
778: ike_sa_id_t *ike_id;
779: half_open_t *half_open;
780: chunk_t addr;
781:
782: ike_id = entry->ike_sa_id;
783: addr = entry->other->get_address(entry->other);
784: row = chunk_hash(addr) & this->table_mask;
785: segment = row & this->segment_mask;
786: lock = this->half_open_segments[segment].lock;
787: lock->write_lock(lock);
788: item = this->half_open_table[row];
789: while (item)
790: {
791: half_open = item->value;
792:
793: if (chunk_equals(addr, half_open->other))
794: {
795: break;
796: }
797: item = item->next;
798: }
799:
800: if (!item)
801: {
802: INIT(half_open,
803: .other = chunk_clone(addr),
804: );
805: INIT(item,
806: .value = half_open,
807: .next = this->half_open_table[row],
808: );
809: this->half_open_table[row] = item;
810: }
811: half_open->count++;
812: ref_get(&this->half_open_count);
813: if (!ike_id->is_initiator(ike_id))
814: {
815: half_open->count_responder++;
816: ref_get(&this->half_open_count_responder);
817: }
818: this->half_open_segments[segment].count++;
819: lock->unlock(lock);
820: }
821:
822: /**
823: * Remove a half-open SA from the hash table.
824: */
825: static void remove_half_open(private_ike_sa_manager_t *this, entry_t *entry)
826: {
827: table_item_t *item, *prev = NULL;
828: u_int row, segment;
829: rwlock_t *lock;
830: ike_sa_id_t *ike_id;
831: chunk_t addr;
832:
833: ike_id = entry->ike_sa_id;
834: addr = entry->other->get_address(entry->other);
835: row = chunk_hash(addr) & this->table_mask;
836: segment = row & this->segment_mask;
837: lock = this->half_open_segments[segment].lock;
838: lock->write_lock(lock);
839: item = this->half_open_table[row];
840: while (item)
841: {
842: half_open_t *half_open = item->value;
843:
844: if (chunk_equals(addr, half_open->other))
845: {
846: if (!ike_id->is_initiator(ike_id))
847: {
848: half_open->count_responder--;
849: ignore_result(ref_put(&this->half_open_count_responder));
850: }
851: ignore_result(ref_put(&this->half_open_count));
852: if (--half_open->count == 0)
853: {
854: if (prev)
855: {
856: prev->next = item->next;
857: }
858: else
859: {
860: this->half_open_table[row] = item->next;
861: }
862: half_open_destroy(half_open);
863: free(item);
864: }
865: this->half_open_segments[segment].count--;
866: break;
867: }
868: prev = item;
869: item = item->next;
870: }
871: lock->unlock(lock);
872: }
873:
874: CALLBACK(id_matches, bool,
875: ike_sa_id_t *a, va_list args)
876: {
877: ike_sa_id_t *b;
878:
879: VA_ARGS_VGET(args, b);
880: return a->equals(a, b);
881: }
882:
883: /**
884: * Put an SA between two peers into the hash table.
885: */
886: static void put_connected_peers(private_ike_sa_manager_t *this, entry_t *entry)
887: {
888: table_item_t *item;
889: u_int row, segment;
890: rwlock_t *lock;
891: connected_peers_t *connected_peers;
892: chunk_t my_id, other_id;
893: int family;
894:
895: my_id = entry->my_id->get_encoding(entry->my_id);
896: other_id = entry->other_id->get_encoding(entry->other_id);
897: family = entry->other->get_family(entry->other);
898: row = chunk_hash_inc(other_id, chunk_hash(my_id)) & this->table_mask;
899: segment = row & this->segment_mask;
900: lock = this->connected_peers_segments[segment].lock;
901: lock->write_lock(lock);
902: item = this->connected_peers_table[row];
903: while (item)
904: {
905: connected_peers = item->value;
906:
907: if (connected_peers_match(connected_peers, entry->my_id,
908: entry->other_id, family))
909: {
910: if (connected_peers->sas->find_first(connected_peers->sas,
911: id_matches, NULL, entry->ike_sa_id))
912: {
913: lock->unlock(lock);
914: return;
915: }
916: break;
917: }
918: item = item->next;
919: }
920:
921: if (!item)
922: {
923: INIT(connected_peers,
924: .my_id = entry->my_id->clone(entry->my_id),
925: .other_id = entry->other_id->clone(entry->other_id),
926: .family = family,
927: .sas = linked_list_create(),
928: );
929: INIT(item,
930: .value = connected_peers,
931: .next = this->connected_peers_table[row],
932: );
933: this->connected_peers_table[row] = item;
934: }
935: connected_peers->sas->insert_last(connected_peers->sas,
936: entry->ike_sa_id->clone(entry->ike_sa_id));
937: this->connected_peers_segments[segment].count++;
938: lock->unlock(lock);
939: }
940:
941: /**
942: * Remove an SA between two peers from the hash table.
943: */
944: static void remove_connected_peers(private_ike_sa_manager_t *this, entry_t *entry)
945: {
946: table_item_t *item, *prev = NULL;
947: u_int row, segment;
948: rwlock_t *lock;
949: chunk_t my_id, other_id;
950: int family;
951:
952: my_id = entry->my_id->get_encoding(entry->my_id);
953: other_id = entry->other_id->get_encoding(entry->other_id);
954: family = entry->other->get_family(entry->other);
955:
956: row = chunk_hash_inc(other_id, chunk_hash(my_id)) & this->table_mask;
957: segment = row & this->segment_mask;
958:
959: lock = this->connected_peers_segments[segment].lock;
960: lock->write_lock(lock);
961: item = this->connected_peers_table[row];
962: while (item)
963: {
964: connected_peers_t *current = item->value;
965:
966: if (connected_peers_match(current, entry->my_id, entry->other_id,
967: family))
968: {
969: enumerator_t *enumerator;
970: ike_sa_id_t *ike_sa_id;
971:
972: enumerator = current->sas->create_enumerator(current->sas);
973: while (enumerator->enumerate(enumerator, &ike_sa_id))
974: {
975: if (ike_sa_id->equals(ike_sa_id, entry->ike_sa_id))
976: {
977: current->sas->remove_at(current->sas, enumerator);
978: ike_sa_id->destroy(ike_sa_id);
979: this->connected_peers_segments[segment].count--;
980: break;
981: }
982: }
983: enumerator->destroy(enumerator);
984: if (current->sas->get_count(current->sas) == 0)
985: {
986: if (prev)
987: {
988: prev->next = item->next;
989: }
990: else
991: {
992: this->connected_peers_table[row] = item->next;
993: }
994: connected_peers_destroy(current);
995: free(item);
996: }
997: break;
998: }
999: prev = item;
1000: item = item->next;
1001: }
1002: lock->unlock(lock);
1003: }
1004:
1005: /**
1006: * Get a random SPI for new IKE_SAs
1007: */
1008: static uint64_t get_spi(private_ike_sa_manager_t *this)
1009: {
1010: uint64_t spi;
1011:
1012: this->spi_lock->read_lock(this->spi_lock);
1013: if (this->spi_cb.cb)
1014: {
1015: spi = this->spi_cb.cb(this->spi_cb.data);
1016: }
1017: else if (!this->rng ||
1018: !this->rng->get_bytes(this->rng, sizeof(spi), (uint8_t*)&spi))
1019: {
1020: spi = 0;
1021: }
1022: this->spi_lock->unlock(this->spi_lock);
1023:
1024: if (spi)
1025: {
1026: spi = (spi & ~this->spi_mask) | this->spi_label;
1027: }
1028: return spi;
1029: }
1030:
1031: /**
1032: * Calculate the hash of the initial IKE message. Memory for the hash is
1033: * allocated on success.
1034: *
1035: * @returns TRUE on success
1036: */
1037: static bool get_init_hash(hasher_t *hasher, message_t *message, chunk_t *hash)
1038: {
1039: host_t *src;
1040:
1041: if (message->get_first_payload_type(message) == PLV1_FRAGMENT)
1042: { /* only hash the source IP, port and SPI for fragmented init messages */
1043: uint16_t port;
1044: uint64_t spi;
1045:
1046: src = message->get_source(message);
1047: if (!hasher->allocate_hash(hasher, src->get_address(src), NULL))
1048: {
1049: return FALSE;
1050: }
1051: port = src->get_port(src);
1052: if (!hasher->allocate_hash(hasher, chunk_from_thing(port), NULL))
1053: {
1054: return FALSE;
1055: }
1056: spi = message->get_initiator_spi(message);
1057: return hasher->allocate_hash(hasher, chunk_from_thing(spi), hash);
1058: }
1059: if (message->get_exchange_type(message) == ID_PROT)
1060: { /* include the source for Main Mode as the hash will be the same if
1061: * SPIs are reused by two initiators that use the same proposal */
1062: src = message->get_source(message);
1063:
1064: if (!hasher->allocate_hash(hasher, src->get_address(src), NULL))
1065: {
1066: return FALSE;
1067: }
1068: }
1069: return hasher->allocate_hash(hasher, message->get_packet_data(message), hash);
1070: }
1071:
1072: /**
1073: * Check if we already have created an IKE_SA based on the initial IKE message
1074: * with the given hash.
1075: * If not the hash is stored, the hash data is not(!) cloned.
1076: *
1077: * Also, the local SPI is returned. In case of a retransmit this is already
1078: * stored together with the hash, otherwise it is newly allocated and should
1079: * be used to create the IKE_SA.
1080: *
1081: * @returns ALREADY_DONE if the message with the given hash has been seen before
1082: * NOT_FOUND if the message hash was not found
1083: * FAILED if the SPI allocation failed
1084: */
1085: static status_t check_and_put_init_hash(private_ike_sa_manager_t *this,
1086: chunk_t init_hash, uint64_t *our_spi)
1087: {
1088: table_item_t *item;
1089: u_int row, segment;
1090: mutex_t *mutex;
1091: init_hash_t *init;
1092: uint64_t spi;
1093:
1094: row = chunk_hash(init_hash) & this->table_mask;
1095: segment = row & this->segment_mask;
1096: mutex = this->init_hashes_segments[segment].mutex;
1097: mutex->lock(mutex);
1098: item = this->init_hashes_table[row];
1099: while (item)
1100: {
1101: init_hash_t *current = item->value;
1102:
1103: if (chunk_equals(init_hash, current->hash))
1104: {
1105: *our_spi = current->our_spi;
1106: mutex->unlock(mutex);
1107: return ALREADY_DONE;
1108: }
1109: item = item->next;
1110: }
1111:
1112: spi = get_spi(this);
1113: if (!spi)
1114: {
1115: return FAILED;
1116: }
1117:
1118: INIT(init,
1119: .hash = {
1120: .len = init_hash.len,
1121: .ptr = init_hash.ptr,
1122: },
1123: .our_spi = spi,
1124: );
1125: INIT(item,
1126: .value = init,
1127: .next = this->init_hashes_table[row],
1128: );
1129: this->init_hashes_table[row] = item;
1130: *our_spi = init->our_spi;
1131: mutex->unlock(mutex);
1132: return NOT_FOUND;
1133: }
1134:
1135: /**
1136: * Remove the hash of an initial IKE message from the cache.
1137: */
1138: static void remove_init_hash(private_ike_sa_manager_t *this, chunk_t init_hash)
1139: {
1140: table_item_t *item, *prev = NULL;
1141: u_int row, segment;
1142: mutex_t *mutex;
1143:
1144: row = chunk_hash(init_hash) & this->table_mask;
1145: segment = row & this->segment_mask;
1146: mutex = this->init_hashes_segments[segment].mutex;
1147: mutex->lock(mutex);
1148: item = this->init_hashes_table[row];
1149: while (item)
1150: {
1151: init_hash_t *current = item->value;
1152:
1153: if (chunk_equals(init_hash, current->hash))
1154: {
1155: if (prev)
1156: {
1157: prev->next = item->next;
1158: }
1159: else
1160: {
1161: this->init_hashes_table[row] = item->next;
1162: }
1163: free(current);
1164: free(item);
1165: break;
1166: }
1167: prev = item;
1168: item = item->next;
1169: }
1170: mutex->unlock(mutex);
1171: }
1172:
1173: METHOD(ike_sa_manager_t, checkout, ike_sa_t*,
1174: private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id)
1175: {
1176: ike_sa_t *ike_sa = NULL;
1177: entry_t *entry;
1178: u_int segment;
1179:
1180: DBG2(DBG_MGR, "checkout %N SA with SPIs %.16"PRIx64"_i %.16"PRIx64"_r",
1181: ike_version_names, ike_sa_id->get_ike_version(ike_sa_id),
1182: be64toh(ike_sa_id->get_initiator_spi(ike_sa_id)),
1183: be64toh(ike_sa_id->get_responder_spi(ike_sa_id)));
1184:
1185: if (get_entry_by_id(this, ike_sa_id, &entry, &segment) == SUCCESS)
1186: {
1187: if (wait_for_entry(this, entry, segment))
1188: {
1189: entry->checked_out = thread_current();
1190: ike_sa = entry->ike_sa;
1191: DBG2(DBG_MGR, "IKE_SA %s[%u] successfully checked out",
1192: ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa));
1193: }
1194: unlock_single_segment(this, segment);
1195: }
1196: charon->bus->set_sa(charon->bus, ike_sa);
1197:
1198: if (!ike_sa)
1199: {
1200: DBG2(DBG_MGR, "IKE_SA checkout not successful");
1201: }
1202: return ike_sa;
1203: }
1204:
1205: METHOD(ike_sa_manager_t, checkout_new, ike_sa_t*,
1206: private_ike_sa_manager_t* this, ike_version_t version, bool initiator)
1207: {
1208: ike_sa_id_t *ike_sa_id;
1209: ike_sa_t *ike_sa;
1210: uint8_t ike_version;
1211: uint64_t spi;
1212:
1213: ike_version = version == IKEV1 ? IKEV1_MAJOR_VERSION : IKEV2_MAJOR_VERSION;
1214:
1215: spi = get_spi(this);
1216: if (!spi)
1217: {
1218: DBG1(DBG_MGR, "failed to allocate SPI for new IKE_SA");
1219: return NULL;
1220: }
1221:
1222: if (initiator)
1223: {
1224: ike_sa_id = ike_sa_id_create(ike_version, spi, 0, TRUE);
1225: }
1226: else
1227: {
1228: ike_sa_id = ike_sa_id_create(ike_version, 0, spi, FALSE);
1229: }
1230: ike_sa = ike_sa_create(ike_sa_id, initiator, version);
1231: ike_sa_id->destroy(ike_sa_id);
1232:
1233: if (ike_sa)
1234: {
1235: DBG2(DBG_MGR, "created IKE_SA %s[%u]", ike_sa->get_name(ike_sa),
1236: ike_sa->get_unique_id(ike_sa));
1237: }
1238: return ike_sa;
1239: }
1240:
1241: /**
1242: * Get the message ID or message hash to detect early retransmissions
1243: */
1244: static uint32_t get_message_id_or_hash(message_t *message)
1245: {
1246: if (message->get_major_version(message) == IKEV1_MAJOR_VERSION)
1247: {
1248: /* Use a hash for IKEv1 Phase 1, where we don't have a MID, and Quick
1249: * Mode, where all three messages use the same message ID */
1250: if (message->get_message_id(message) == 0 ||
1251: message->get_exchange_type(message) == QUICK_MODE)
1252: {
1253: return chunk_hash(message->get_packet_data(message));
1254: }
1255: }
1256: return message->get_message_id(message);
1257: }
1258:
1259: METHOD(ike_sa_manager_t, checkout_by_message, ike_sa_t*,
1260: private_ike_sa_manager_t* this, message_t *message)
1261: {
1262: u_int segment;
1263: entry_t *entry;
1264: ike_sa_t *ike_sa = NULL;
1265: ike_sa_id_t *id;
1266: ike_version_t ike_version;
1267: bool is_init = FALSE;
1268:
1269: id = message->get_ike_sa_id(message);
1270: /* clone the IKE_SA ID so we can modify the initiator flag */
1271: id = id->clone(id);
1272: id->switch_initiator(id);
1273:
1274: DBG2(DBG_MGR, "checkout %N SA by message with SPIs %.16"PRIx64"_i "
1275: "%.16"PRIx64"_r", ike_version_names, id->get_ike_version(id),
1276: be64toh(id->get_initiator_spi(id)),
1277: be64toh(id->get_responder_spi(id)));
1278:
1279: if (id->get_responder_spi(id) == 0 &&
1280: message->get_message_id(message) == 0)
1281: {
1282: if (message->get_major_version(message) == IKEV2_MAJOR_VERSION)
1283: {
1284: if (message->get_exchange_type(message) == IKE_SA_INIT &&
1285: message->get_request(message))
1286: {
1287: ike_version = IKEV2;
1288: is_init = TRUE;
1289: }
1290: }
1291: else
1292: {
1293: if (message->get_exchange_type(message) == ID_PROT ||
1294: message->get_exchange_type(message) == AGGRESSIVE)
1295: {
1296: ike_version = IKEV1;
1297: is_init = TRUE;
1298: if (id->is_initiator(id))
1299: { /* not set in IKEv1, switch back before applying to new SA */
1300: id->switch_initiator(id);
1301: }
1302: }
1303: }
1304: }
1305:
1306: if (is_init)
1307: {
1308: hasher_t *hasher;
1309: uint64_t our_spi;
1310: chunk_t hash;
1311:
1312: hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
1313: if (!hasher || !get_init_hash(hasher, message, &hash))
1314: {
1315: DBG1(DBG_MGR, "ignoring message, failed to hash message");
1316: DESTROY_IF(hasher);
1317: id->destroy(id);
1318: goto out;
1319: }
1320: hasher->destroy(hasher);
1321:
1322: /* ensure this is not a retransmit of an already handled init message */
1323: switch (check_and_put_init_hash(this, hash, &our_spi))
1324: {
1325: case NOT_FOUND:
1326: { /* we've not seen this packet yet, create a new IKE_SA */
1327: if (!this->ikesa_limit ||
1328: this->public.get_count(&this->public) < this->ikesa_limit)
1329: {
1330: id->set_responder_spi(id, our_spi);
1331: ike_sa = ike_sa_create(id, FALSE, ike_version);
1332: if (ike_sa)
1333: {
1334: entry = entry_create();
1335: entry->ike_sa = ike_sa;
1336: entry->ike_sa_id = id;
1337: entry->processing = get_message_id_or_hash(message);
1338: entry->init_hash = hash;
1339:
1340: segment = put_entry(this, entry);
1341: entry->checked_out = thread_current();
1342: unlock_single_segment(this, segment);
1343:
1344: DBG2(DBG_MGR, "created IKE_SA %s[%u]",
1345: ike_sa->get_name(ike_sa),
1346: ike_sa->get_unique_id(ike_sa));
1347: goto out;
1348: }
1349: else
1350: {
1351: DBG1(DBG_MGR, "creating IKE_SA failed, ignoring message");
1352: }
1353: }
1354: else
1355: {
1356: DBG1(DBG_MGR, "ignoring %N, hitting IKE_SA limit (%u)",
1357: exchange_type_names, message->get_exchange_type(message),
1358: this->ikesa_limit);
1359: }
1360: remove_init_hash(this, hash);
1361: chunk_free(&hash);
1362: id->destroy(id);
1363: goto out;
1364: }
1365: case FAILED:
1366: { /* we failed to allocate an SPI */
1367: chunk_free(&hash);
1368: id->destroy(id);
1369: DBG1(DBG_MGR, "ignoring message, failed to allocate SPI");
1370: goto out;
1371: }
1372: case ALREADY_DONE:
1373: default:
1374: break;
1375: }
1376: /* it looks like we already handled this init message to some degree */
1377: id->set_responder_spi(id, our_spi);
1378: chunk_free(&hash);
1379: }
1380:
1381: if (get_entry_by_id(this, id, &entry, &segment) == SUCCESS)
1382: {
1383: /* only check out if we are not already processing it. */
1384: if (entry->processing == get_message_id_or_hash(message))
1385: {
1386: DBG1(DBG_MGR, "ignoring request with ID %u, already processing",
1387: entry->processing);
1388: }
1389: else if (wait_for_entry(this, entry, segment))
1390: {
1391: ike_sa_id_t *ike_id;
1392:
1393: ike_id = entry->ike_sa->get_id(entry->ike_sa);
1394: entry->checked_out = thread_current();
1395: if (message->get_first_payload_type(message) != PLV1_FRAGMENT &&
1396: message->get_first_payload_type(message) != PLV2_FRAGMENT)
1397: { /* TODO-FRAG: this fails if there are unencrypted payloads */
1398: entry->processing = get_message_id_or_hash(message);
1399: }
1400: if (ike_id->get_responder_spi(ike_id) == 0)
1401: {
1402: ike_id->set_responder_spi(ike_id, id->get_responder_spi(id));
1403: }
1404: ike_sa = entry->ike_sa;
1405: DBG2(DBG_MGR, "IKE_SA %s[%u] successfully checked out",
1406: ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa));
1407: }
1408: unlock_single_segment(this, segment);
1409: }
1410: else
1411: {
1412: charon->bus->alert(charon->bus, ALERT_INVALID_IKE_SPI, message);
1413: }
1414: id->destroy(id);
1415:
1416: out:
1417: charon->bus->set_sa(charon->bus, ike_sa);
1418: if (!ike_sa)
1419: {
1420: DBG2(DBG_MGR, "IKE_SA checkout not successful");
1421: }
1422: return ike_sa;
1423: }
1424:
1425: METHOD(ike_sa_manager_t, checkout_by_config, ike_sa_t*,
1426: private_ike_sa_manager_t *this, peer_cfg_t *peer_cfg)
1427: {
1428: enumerator_t *enumerator;
1429: entry_t *entry;
1430: ike_sa_t *ike_sa = NULL;
1431: peer_cfg_t *current_peer;
1432: ike_cfg_t *current_ike;
1433: u_int segment;
1434:
1435: DBG2(DBG_MGR, "checkout IKE_SA by config");
1436:
1437: if (!this->reuse_ikesa && peer_cfg->get_ike_version(peer_cfg) != IKEV1)
1438: { /* IKE_SA reuse disabled by config (not possible for IKEv1) */
1439: ike_sa = checkout_new(this, peer_cfg->get_ike_version(peer_cfg), TRUE);
1440: charon->bus->set_sa(charon->bus, ike_sa);
1441: goto out;
1442: }
1443:
1444: enumerator = create_table_enumerator(this);
1445: while (enumerator->enumerate(enumerator, &entry, &segment))
1446: {
1447: if (!wait_for_entry(this, entry, segment))
1448: {
1449: continue;
1450: }
1451: if (entry->ike_sa->get_state(entry->ike_sa) == IKE_DELETING ||
1452: entry->ike_sa->get_state(entry->ike_sa) == IKE_REKEYED)
1453: { /* skip IKE_SAs which are not usable, wake other waiting threads */
1454: entry->condvar->signal(entry->condvar);
1455: continue;
1456: }
1457:
1458: current_peer = entry->ike_sa->get_peer_cfg(entry->ike_sa);
1459: if (current_peer && current_peer->equals(current_peer, peer_cfg))
1460: {
1461: current_ike = current_peer->get_ike_cfg(current_peer);
1462: if (current_ike->equals(current_ike, peer_cfg->get_ike_cfg(peer_cfg)))
1463: {
1464: entry->checked_out = thread_current();
1465: ike_sa = entry->ike_sa;
1466: DBG2(DBG_MGR, "found existing IKE_SA %u with a '%s' config",
1467: ike_sa->get_unique_id(ike_sa),
1468: current_peer->get_name(current_peer));
1469: break;
1470: }
1471: }
1472: /* other threads might be waiting for this entry */
1473: entry->condvar->signal(entry->condvar);
1474: }
1475: enumerator->destroy(enumerator);
1476:
1477: if (!ike_sa)
1478: { /* no IKE_SA using such a config, hand out a new */
1479: ike_sa = checkout_new(this, peer_cfg->get_ike_version(peer_cfg), TRUE);
1480: }
1481: charon->bus->set_sa(charon->bus, ike_sa);
1482:
1483: out:
1484: if (!ike_sa)
1485: {
1486: DBG2(DBG_MGR, "IKE_SA checkout not successful");
1487: }
1488: return ike_sa;
1489: }
1490:
1491: METHOD(ike_sa_manager_t, checkout_by_id, ike_sa_t*,
1492: private_ike_sa_manager_t *this, uint32_t id)
1493: {
1494: enumerator_t *enumerator;
1495: entry_t *entry;
1496: ike_sa_t *ike_sa = NULL;
1497: u_int segment;
1498:
1499: DBG2(DBG_MGR, "checkout IKE_SA by unique ID %u", id);
1500:
1501: enumerator = create_table_enumerator(this);
1502: while (enumerator->enumerate(enumerator, &entry, &segment))
1503: {
1504: if (wait_for_entry(this, entry, segment))
1505: {
1506: if (entry->ike_sa->get_unique_id(entry->ike_sa) == id)
1507: {
1508: ike_sa = entry->ike_sa;
1509: entry->checked_out = thread_current();
1510: break;
1511: }
1512: /* other threads might be waiting for this entry */
1513: entry->condvar->signal(entry->condvar);
1514: }
1515: }
1516: enumerator->destroy(enumerator);
1517:
1518: if (ike_sa)
1519: {
1520: DBG2(DBG_MGR, "IKE_SA %s[%u] successfully checked out",
1521: ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa));
1522: }
1523: else
1524: {
1525: DBG2(DBG_MGR, "IKE_SA checkout not successful");
1526: }
1527: charon->bus->set_sa(charon->bus, ike_sa);
1528: return ike_sa;
1529: }
1530:
1531: METHOD(ike_sa_manager_t, checkout_by_name, ike_sa_t*,
1532: private_ike_sa_manager_t *this, char *name, bool child)
1533: {
1534: enumerator_t *enumerator, *children;
1535: entry_t *entry;
1536: ike_sa_t *ike_sa = NULL;
1537: child_sa_t *child_sa;
1538: u_int segment;
1539:
1540: DBG2(DBG_MGR, "checkout IKE_SA by%s name '%s'", child ? " child" : "", name);
1541:
1542: enumerator = create_table_enumerator(this);
1543: while (enumerator->enumerate(enumerator, &entry, &segment))
1544: {
1545: if (wait_for_entry(this, entry, segment))
1546: {
1547: /* look for a child with such a policy name ... */
1548: if (child)
1549: {
1550: children = entry->ike_sa->create_child_sa_enumerator(entry->ike_sa);
1551: while (children->enumerate(children, (void**)&child_sa))
1552: {
1553: if (streq(child_sa->get_name(child_sa), name))
1554: {
1555: ike_sa = entry->ike_sa;
1556: break;
1557: }
1558: }
1559: children->destroy(children);
1560: }
1561: else /* ... or for a IKE_SA with such a connection name */
1562: {
1563: if (streq(entry->ike_sa->get_name(entry->ike_sa), name))
1564: {
1565: ike_sa = entry->ike_sa;
1566: }
1567: }
1568: /* got one, return */
1569: if (ike_sa)
1570: {
1571: entry->checked_out = thread_current();
1572: DBG2(DBG_MGR, "IKE_SA %s[%u] successfully checked out",
1573: ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa));
1574: break;
1575: }
1576: /* other threads might be waiting for this entry */
1577: entry->condvar->signal(entry->condvar);
1578: }
1579: }
1580: enumerator->destroy(enumerator);
1581:
1582: charon->bus->set_sa(charon->bus, ike_sa);
1583:
1584: if (!ike_sa)
1585: {
1586: DBG2(DBG_MGR, "IKE_SA checkout not successful");
1587: }
1588: return ike_sa;
1589: }
1590:
1591: METHOD(ike_sa_manager_t, new_initiator_spi, bool,
1592: private_ike_sa_manager_t *this, ike_sa_t *ike_sa)
1593: {
1594: ike_sa_state_t state;
1595: ike_sa_id_t *ike_sa_id;
1596: entry_t *entry;
1597: u_int segment;
1598: uint64_t new_spi, spi;
1599:
1600: state = ike_sa->get_state(ike_sa);
1601: if (state != IKE_CONNECTING)
1602: {
1603: DBG1(DBG_MGR, "unable to change initiator SPI for IKE_SA in state "
1604: "%N", ike_sa_state_names, state);
1605: return FALSE;
1606: }
1607:
1608: ike_sa_id = ike_sa->get_id(ike_sa);
1609: if (!ike_sa_id->is_initiator(ike_sa_id))
1610: {
1611: DBG1(DBG_MGR, "unable to change initiator SPI of IKE_SA as responder");
1612: return FALSE;
1613: }
1614:
1615: if (ike_sa != charon->bus->get_sa(charon->bus))
1616: {
1617: DBG1(DBG_MGR, "unable to change initiator SPI of IKE_SA not checked "
1618: "out by current thread");
1619: return FALSE;
1620: }
1621:
1622: new_spi = get_spi(this);
1623: if (!new_spi)
1624: {
1625: DBG1(DBG_MGR, "unable to allocate new initiator SPI for IKE_SA");
1626: return FALSE;
1627: }
1628:
1629: if (get_entry_by_sa(this, ike_sa_id, ike_sa, &entry, &segment) == SUCCESS)
1630: {
1631: if (entry->driveout_waiting_threads && entry->driveout_new_threads)
1632: { /* it looks like flush() has been called and the SA is being deleted
1633: * anyway, no need for a new SPI */
1634: DBG2(DBG_MGR, "ignored change of initiator SPI during shutdown");
1635: unlock_single_segment(this, segment);
1636: return FALSE;
1637: }
1638: }
1639: else
1640: {
1641: DBG1(DBG_MGR, "unable to change initiator SPI of IKE_SA, not found");
1642: return FALSE;
1643: }
1644:
1645: /* the hashtable row and segment are determined by the local SPI as
1646: * initiator, so if we change it the row and segment derived from it might
1647: * change as well. This could be a problem for threads waiting for the
1648: * entry (in particular those enumerating entries to check them out by
1649: * unique ID or name). In order to avoid having to drive them out and thus
1650: * preventing them from checking out the entry (even though the ID or name
1651: * will not change and enumerating it is also fine), we mask the new SPI and
1652: * merge it with the old SPI so the entry ends up in the same row/segment.
1653: * Since SPIs are 64-bit and the number of rows/segments is usually
1654: * relatively low this should not be a problem. */
1655: spi = ike_sa_id->get_initiator_spi(ike_sa_id);
1656: new_spi = (spi & (uint64_t)this->table_mask) |
1657: (new_spi & ~(uint64_t)this->table_mask);
1658:
1659: DBG2(DBG_MGR, "change initiator SPI of IKE_SA %s[%u] from %.16"PRIx64" to "
1660: "%.16"PRIx64, ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa),
1661: be64toh(spi), be64toh(new_spi));
1662:
1663: ike_sa_id->set_initiator_spi(ike_sa_id, new_spi);
1664: entry->ike_sa_id->replace_values(entry->ike_sa_id, ike_sa_id);
1665:
1666: entry->condvar->signal(entry->condvar);
1667: unlock_single_segment(this, segment);
1668: return TRUE;
1669: }
1670:
1671: CALLBACK(enumerator_filter_wait, bool,
1672: private_ike_sa_manager_t *this, enumerator_t *orig, va_list args)
1673: {
1674: entry_t *entry;
1675: u_int segment;
1676: ike_sa_t **out;
1677:
1678: VA_ARGS_VGET(args, out);
1679:
1680: while (orig->enumerate(orig, &entry, &segment))
1681: {
1682: if (wait_for_entry(this, entry, segment))
1683: {
1684: *out = entry->ike_sa;
1685: charon->bus->set_sa(charon->bus, *out);
1686: return TRUE;
1687: }
1688: }
1689: return FALSE;
1690: }
1691:
1692: CALLBACK(enumerator_filter_skip, bool,
1693: private_ike_sa_manager_t *this, enumerator_t *orig, va_list args)
1694: {
1695: entry_t *entry;
1696: u_int segment;
1697: ike_sa_t **out;
1698:
1699: VA_ARGS_VGET(args, out);
1700:
1701: while (orig->enumerate(orig, &entry, &segment))
1702: {
1703: if (!entry->driveout_new_threads &&
1704: !entry->driveout_waiting_threads &&
1705: !entry->checked_out)
1706: {
1707: *out = entry->ike_sa;
1708: charon->bus->set_sa(charon->bus, *out);
1709: return TRUE;
1710: }
1711: }
1712: return FALSE;
1713: }
1714:
1715: CALLBACK(reset_sa, void,
1716: void *data)
1717: {
1718: charon->bus->set_sa(charon->bus, NULL);
1719: }
1720:
1721: METHOD(ike_sa_manager_t, create_enumerator, enumerator_t*,
1722: private_ike_sa_manager_t* this, bool wait)
1723: {
1724: return enumerator_create_filter(create_table_enumerator(this),
1725: wait ? (void*)enumerator_filter_wait : (void*)enumerator_filter_skip,
1726: this, reset_sa);
1727: }
1728:
1729: METHOD(ike_sa_manager_t, checkin, void,
1730: private_ike_sa_manager_t *this, ike_sa_t *ike_sa)
1731: {
1732: /* to check the SA back in, we look for the pointer of the ike_sa
1733: * in all entries.
1734: * The lookup is done by initiator SPI, so even if the SPI has changed (e.g.
1735: * on reception of a IKE_SA_INIT response) the lookup will work but
1736: * updating of the SPI MAY be necessary...
1737: */
1738: entry_t *entry;
1739: ike_sa_id_t *ike_sa_id;
1740: host_t *other;
1741: identification_t *my_id, *other_id;
1742: u_int segment;
1743:
1744: ike_sa_id = ike_sa->get_id(ike_sa);
1745: my_id = ike_sa->get_my_id(ike_sa);
1746: other_id = ike_sa->get_other_eap_id(ike_sa);
1747: other = ike_sa->get_other_host(ike_sa);
1748:
1749: DBG2(DBG_MGR, "checkin IKE_SA %s[%u]", ike_sa->get_name(ike_sa),
1750: ike_sa->get_unique_id(ike_sa));
1751:
1752: /* look for the entry */
1753: if (get_entry_by_sa(this, ike_sa_id, ike_sa, &entry, &segment) == SUCCESS)
1754: {
1755: /* ike_sa_id must be updated */
1756: entry->ike_sa_id->replace_values(entry->ike_sa_id, ike_sa->get_id(ike_sa));
1757: /* signal waiting threads */
1758: entry->checked_out = NULL;
1759: entry->processing = -1;
1760: /* check if this SA is half-open */
1761: if (entry->half_open && ike_sa->get_state(ike_sa) != IKE_CONNECTING)
1762: {
1763: /* not half open anymore */
1764: entry->half_open = FALSE;
1765: remove_half_open(this, entry);
1766: }
1767: else if (entry->half_open && !other->ip_equals(other, entry->other))
1768: {
1769: /* the other host's IP has changed, we must update the hash table */
1770: remove_half_open(this, entry);
1771: DESTROY_IF(entry->other);
1772: entry->other = other->clone(other);
1773: put_half_open(this, entry);
1774: }
1775: else if (!entry->half_open &&
1776: ike_sa->get_state(ike_sa) == IKE_CONNECTING)
1777: {
1778: /* this is a new half-open SA */
1779: entry->half_open = TRUE;
1780: entry->other = other->clone(other);
1781: put_half_open(this, entry);
1782: }
1783: entry->condvar->signal(entry->condvar);
1784: }
1785: else
1786: {
1787: entry = entry_create();
1788: entry->ike_sa_id = ike_sa_id->clone(ike_sa_id);
1789: entry->ike_sa = ike_sa;
1790: if (ike_sa->get_state(ike_sa) == IKE_CONNECTING)
1791: {
1792: entry->half_open = TRUE;
1793: entry->other = other->clone(other);
1794: put_half_open(this, entry);
1795: }
1796: segment = put_entry(this, entry);
1797: }
1798: DBG2(DBG_MGR, "checkin of IKE_SA successful");
1799:
1800: /* apply identities for duplicate test */
1801: if ((ike_sa->get_state(ike_sa) == IKE_ESTABLISHED ||
1802: ike_sa->get_state(ike_sa) == IKE_PASSIVE) &&
1803: entry->my_id == NULL && entry->other_id == NULL)
1804: {
1805: if (ike_sa->get_version(ike_sa) == IKEV1)
1806: {
1807: /* If authenticated and received INITIAL_CONTACT,
1808: * delete any existing IKE_SAs with that peer. */
1809: if (ike_sa->has_condition(ike_sa, COND_INIT_CONTACT_SEEN))
1810: {
1811: /* We can't hold the segment locked while checking the
1812: * uniqueness as this could lead to deadlocks. We mark the
1813: * entry as checked out while we release the lock so no other
1814: * thread can acquire it. Since it is not yet in the list of
1815: * connected peers that will not cause a deadlock as no other
1816: * caller of check_uniqueness() will try to check out this SA */
1817: entry->checked_out = thread_current();
1818: unlock_single_segment(this, segment);
1819:
1820: this->public.check_uniqueness(&this->public, ike_sa, TRUE);
1821: ike_sa->set_condition(ike_sa, COND_INIT_CONTACT_SEEN, FALSE);
1822:
1823: /* The entry could have been modified in the mean time, e.g.
1824: * because another SA was added/removed next to it or another
1825: * thread is waiting, but it should still exist, so there is no
1826: * need for a lookup via get_entry_by... */
1827: lock_single_segment(this, segment);
1828: entry->checked_out = NULL;
1829: /* We already signaled waiting threads above, we have to do that
1830: * again after checking the SA out and back in again. */
1831: entry->condvar->signal(entry->condvar);
1832: }
1833: }
1834:
1835: entry->my_id = my_id->clone(my_id);
1836: entry->other_id = other_id->clone(other_id);
1837: if (!entry->other)
1838: {
1839: entry->other = other->clone(other);
1840: }
1841: put_connected_peers(this, entry);
1842: }
1843:
1844: unlock_single_segment(this, segment);
1845:
1846: charon->bus->set_sa(charon->bus, NULL);
1847: }
1848:
1849: METHOD(ike_sa_manager_t, checkin_and_destroy, void,
1850: private_ike_sa_manager_t *this, ike_sa_t *ike_sa)
1851: {
1852: /* deletion is a bit complex, we must ensure that no thread is waiting for
1853: * this SA.
1854: * We take this SA from the table, and start signaling while threads
1855: * are in the condvar.
1856: */
1857: entry_t *entry;
1858: ike_sa_id_t *ike_sa_id;
1859: u_int segment;
1860:
1861: ike_sa_id = ike_sa->get_id(ike_sa);
1862:
1863: DBG2(DBG_MGR, "checkin and destroy IKE_SA %s[%u]", ike_sa->get_name(ike_sa),
1864: ike_sa->get_unique_id(ike_sa));
1865:
1866: if (get_entry_by_sa(this, ike_sa_id, ike_sa, &entry, &segment) == SUCCESS)
1867: {
1868: if (entry->driveout_waiting_threads && entry->driveout_new_threads)
1869: { /* it looks like flush() has been called and the SA is being deleted
1870: * anyway, just check it in */
1871: DBG2(DBG_MGR, "ignored checkin and destroy of IKE_SA during shutdown");
1872: entry->checked_out = NULL;
1873: entry->condvar->broadcast(entry->condvar);
1874: unlock_single_segment(this, segment);
1875: return;
1876: }
1877:
1878: /* drive out waiting threads, as we are in hurry */
1879: entry->driveout_waiting_threads = TRUE;
1880: /* mark it, so no new threads can get this entry */
1881: entry->driveout_new_threads = TRUE;
1882: /* wait until all workers have done their work */
1883: while (entry->waiting_threads)
1884: {
1885: /* wake up all */
1886: entry->condvar->broadcast(entry->condvar);
1887: /* they will wake us again when their work is done */
1888: entry->condvar->wait(entry->condvar, this->segments[segment].mutex);
1889: }
1890: remove_entry(this, entry);
1891: unlock_single_segment(this, segment);
1892:
1893: if (entry->half_open)
1894: {
1895: remove_half_open(this, entry);
1896: }
1897: if (entry->my_id && entry->other_id)
1898: {
1899: remove_connected_peers(this, entry);
1900: }
1901: if (entry->init_hash.ptr)
1902: {
1903: remove_init_hash(this, entry->init_hash);
1904: }
1905:
1906: entry_destroy(entry);
1907:
1908: DBG2(DBG_MGR, "checkin and destroy of IKE_SA successful");
1909: }
1910: else
1911: {
1912: DBG1(DBG_MGR, "tried to checkin and delete nonexistent IKE_SA");
1913: ike_sa->destroy(ike_sa);
1914: }
1915: charon->bus->set_sa(charon->bus, NULL);
1916: }
1917:
1918: /**
1919: * Cleanup function for create_id_enumerator
1920: */
1921: static void id_enumerator_cleanup(linked_list_t *ids)
1922: {
1923: ids->destroy_offset(ids, offsetof(ike_sa_id_t, destroy));
1924: }
1925:
1926: METHOD(ike_sa_manager_t, create_id_enumerator, enumerator_t*,
1927: private_ike_sa_manager_t *this, identification_t *me,
1928: identification_t *other, int family)
1929: {
1930: table_item_t *item;
1931: u_int row, segment;
1932: rwlock_t *lock;
1933: linked_list_t *ids = NULL;
1934:
1935: row = chunk_hash_inc(other->get_encoding(other),
1936: chunk_hash(me->get_encoding(me))) & this->table_mask;
1937: segment = row & this->segment_mask;
1938:
1939: lock = this->connected_peers_segments[segment].lock;
1940: lock->read_lock(lock);
1941: item = this->connected_peers_table[row];
1942: while (item)
1943: {
1944: connected_peers_t *current = item->value;
1945:
1946: if (connected_peers_match(current, me, other, family))
1947: {
1948: ids = current->sas->clone_offset(current->sas,
1949: offsetof(ike_sa_id_t, clone));
1950: break;
1951: }
1952: item = item->next;
1953: }
1954: lock->unlock(lock);
1955:
1956: if (!ids)
1957: {
1958: return enumerator_create_empty();
1959: }
1960: return enumerator_create_cleaner(ids->create_enumerator(ids),
1961: (void*)id_enumerator_cleanup, ids);
1962: }
1963:
1964: /**
1965: * Move all CHILD_SAs and virtual IPs from old to new
1966: */
1967: static void adopt_children_and_vips(ike_sa_t *old, ike_sa_t *new)
1968: {
1969: enumerator_t *enumerator;
1970: child_sa_t *child_sa;
1971: host_t *vip;
1972: int chcount = 0, vipcount = 0;
1973:
1974: charon->bus->children_migrate(charon->bus, new->get_id(new),
1975: new->get_unique_id(new));
1976: enumerator = old->create_child_sa_enumerator(old);
1977: while (enumerator->enumerate(enumerator, &child_sa))
1978: {
1979: old->remove_child_sa(old, enumerator);
1980: new->add_child_sa(new, child_sa);
1981: chcount++;
1982: }
1983: enumerator->destroy(enumerator);
1984:
1985: new->adopt_child_tasks(new, old);
1986:
1987: enumerator = old->create_virtual_ip_enumerator(old, FALSE);
1988: while (enumerator->enumerate(enumerator, &vip))
1989: {
1990: new->add_virtual_ip(new, FALSE, vip);
1991: vipcount++;
1992: }
1993: enumerator->destroy(enumerator);
1994: /* this does not release the addresses, which is good, but it does trigger
1995: * an assign_vips(FALSE) event... */
1996: old->clear_virtual_ips(old, FALSE);
1997: /* ...trigger the analogous event on the new SA */
1998: charon->bus->set_sa(charon->bus, new);
1999: charon->bus->assign_vips(charon->bus, new, TRUE);
2000: charon->bus->children_migrate(charon->bus, NULL, 0);
2001: charon->bus->set_sa(charon->bus, old);
2002:
2003: if (chcount || vipcount)
2004: {
2005: DBG1(DBG_IKE, "detected reauth of existing IKE_SA, adopting %d "
2006: "children and %d virtual IPs", chcount, vipcount);
2007: }
2008: }
2009:
2010: /**
2011: * Delete an existing IKE_SA due to a unique replace policy
2012: */
2013: static status_t enforce_replace(private_ike_sa_manager_t *this,
2014: ike_sa_t *duplicate, ike_sa_t *new,
2015: identification_t *other, host_t *host)
2016: {
2017: charon->bus->alert(charon->bus, ALERT_UNIQUE_REPLACE);
2018:
2019: if (host->equals(host, duplicate->get_other_host(duplicate)))
2020: {
2021: /* looks like a reauthentication attempt */
2022: if (!new->has_condition(new, COND_INIT_CONTACT_SEEN) &&
2023: new->get_version(new) == IKEV1)
2024: {
2025: /* IKEv1 implicitly takes over children, IKEv2 recreates them
2026: * explicitly. */
2027: adopt_children_and_vips(duplicate, new);
2028: }
2029: /* For IKEv1 we have to delay the delete for the old IKE_SA. Some
2030: * peers need to complete the new SA first, otherwise the quick modes
2031: * might get lost. For IKEv2 we do the same, as we want overlapping
2032: * CHILD_SAs to keep connectivity up. */
2033: lib->scheduler->schedule_job(lib->scheduler, (job_t*)
2034: delete_ike_sa_job_create(duplicate->get_id(duplicate), TRUE), 10);
2035: DBG1(DBG_IKE, "schedule delete of duplicate IKE_SA for peer '%Y' due "
2036: "to uniqueness policy and suspected reauthentication", other);
2037: return SUCCESS;
2038: }
2039: DBG1(DBG_IKE, "deleting duplicate IKE_SA for peer '%Y' due to "
2040: "uniqueness policy", other);
2041: return duplicate->delete(duplicate, FALSE);
2042: }
2043:
2044: METHOD(ike_sa_manager_t, check_uniqueness, bool,
2045: private_ike_sa_manager_t *this, ike_sa_t *ike_sa, bool force_replace)
2046: {
2047: bool cancel = FALSE;
2048: peer_cfg_t *peer_cfg;
2049: unique_policy_t policy;
2050: enumerator_t *enumerator;
2051: ike_sa_id_t *id = NULL;
2052: identification_t *me, *other;
2053: host_t *other_host;
2054:
2055: peer_cfg = ike_sa->get_peer_cfg(ike_sa);
2056: policy = peer_cfg->get_unique_policy(peer_cfg);
2057: if (policy == UNIQUE_NEVER || (policy == UNIQUE_NO && !force_replace))
2058: {
2059: return FALSE;
2060: }
2061: me = ike_sa->get_my_id(ike_sa);
2062: other = ike_sa->get_other_eap_id(ike_sa);
2063: other_host = ike_sa->get_other_host(ike_sa);
2064:
2065: enumerator = create_id_enumerator(this, me, other,
2066: other_host->get_family(other_host));
2067: while (enumerator->enumerate(enumerator, &id))
2068: {
2069: status_t status = SUCCESS;
2070: ike_sa_t *duplicate;
2071:
2072: duplicate = checkout(this, id);
2073: if (!duplicate)
2074: {
2075: continue;
2076: }
2077: if (force_replace)
2078: {
2079: DBG1(DBG_IKE, "destroying duplicate IKE_SA for peer '%Y', "
2080: "received INITIAL_CONTACT", other);
2081: charon->bus->ike_updown(charon->bus, duplicate, FALSE);
2082: checkin_and_destroy(this, duplicate);
2083: continue;
2084: }
2085: peer_cfg = duplicate->get_peer_cfg(duplicate);
2086: if (peer_cfg && peer_cfg->equals(peer_cfg, ike_sa->get_peer_cfg(ike_sa)))
2087: {
2088: switch (duplicate->get_state(duplicate))
2089: {
2090: case IKE_ESTABLISHED:
2091: case IKE_REKEYING:
2092: switch (policy)
2093: {
2094: case UNIQUE_REPLACE:
2095: status = enforce_replace(this, duplicate, ike_sa,
2096: other, other_host);
2097: break;
2098: case UNIQUE_KEEP:
2099: /* potential reauthentication? */
2100: if (!other_host->equals(other_host,
2101: duplicate->get_other_host(duplicate)))
2102: {
2103: cancel = TRUE;
2104: /* we keep the first IKE_SA and delete all
2105: * other duplicates that might exist */
2106: policy = UNIQUE_REPLACE;
2107: }
2108: break;
2109: default:
2110: break;
2111: }
2112: break;
2113: default:
2114: break;
2115: }
2116: }
2117: if (status == DESTROY_ME)
2118: {
2119: checkin_and_destroy(this, duplicate);
2120: }
2121: else
2122: {
2123: checkin(this, duplicate);
2124: }
2125: }
2126: enumerator->destroy(enumerator);
2127: /* reset thread's current IKE_SA after checkin */
2128: charon->bus->set_sa(charon->bus, ike_sa);
2129: return cancel;
2130: }
2131:
2132: METHOD(ike_sa_manager_t, has_contact, bool,
2133: private_ike_sa_manager_t *this, identification_t *me,
2134: identification_t *other, int family)
2135: {
2136: table_item_t *item;
2137: u_int row, segment;
2138: rwlock_t *lock;
2139: bool found = FALSE;
2140:
2141: row = chunk_hash_inc(other->get_encoding(other),
2142: chunk_hash(me->get_encoding(me))) & this->table_mask;
2143: segment = row & this->segment_mask;
2144: lock = this->connected_peers_segments[segment].lock;
2145: lock->read_lock(lock);
2146: item = this->connected_peers_table[row];
2147: while (item)
2148: {
2149: if (connected_peers_match(item->value, me, other, family))
2150: {
2151: found = TRUE;
2152: break;
2153: }
2154: item = item->next;
2155: }
2156: lock->unlock(lock);
2157:
2158: return found;
2159: }
2160:
2161: METHOD(ike_sa_manager_t, get_count, u_int,
2162: private_ike_sa_manager_t *this)
2163: {
2164: return (u_int)ref_cur(&this->total_sa_count);
2165: }
2166:
2167: METHOD(ike_sa_manager_t, get_half_open_count, u_int,
2168: private_ike_sa_manager_t *this, host_t *ip, bool responder_only)
2169: {
2170: table_item_t *item;
2171: u_int row, segment;
2172: rwlock_t *lock;
2173: chunk_t addr;
2174: u_int count = 0;
2175:
2176: if (ip)
2177: {
2178: addr = ip->get_address(ip);
2179: row = chunk_hash(addr) & this->table_mask;
2180: segment = row & this->segment_mask;
2181: lock = this->half_open_segments[segment].lock;
2182: lock->read_lock(lock);
2183: item = this->half_open_table[row];
2184: while (item)
2185: {
2186: half_open_t *half_open = item->value;
2187:
2188: if (chunk_equals(addr, half_open->other))
2189: {
2190: count = responder_only ? half_open->count_responder
2191: : half_open->count;
2192: break;
2193: }
2194: item = item->next;
2195: }
2196: lock->unlock(lock);
2197: }
2198: else
2199: {
2200: count = responder_only ? (u_int)ref_cur(&this->half_open_count_responder)
2201: : (u_int)ref_cur(&this->half_open_count);
2202: }
2203: return count;
2204: }
2205:
2206: METHOD(ike_sa_manager_t, set_spi_cb, void,
2207: private_ike_sa_manager_t *this, spi_cb_t callback, void *data)
2208: {
2209: this->spi_lock->write_lock(this->spi_lock);
2210: this->spi_cb.cb = callback;
2211: this->spi_cb.data = data;
2212: this->spi_lock->unlock(this->spi_lock);
2213: }
2214:
2215: /**
2216: * Destroy all entries
2217: */
2218: static void destroy_all_entries(private_ike_sa_manager_t *this)
2219: {
2220: enumerator_t *enumerator;
2221: entry_t *entry;
2222: u_int segment;
2223:
2224: enumerator = create_table_enumerator(this);
2225: while (enumerator->enumerate(enumerator, &entry, &segment))
2226: {
2227: charon->bus->set_sa(charon->bus, entry->ike_sa);
2228: if (entry->half_open)
2229: {
2230: remove_half_open(this, entry);
2231: }
2232: if (entry->my_id && entry->other_id)
2233: {
2234: remove_connected_peers(this, entry);
2235: }
2236: if (entry->init_hash.ptr)
2237: {
2238: remove_init_hash(this, entry->init_hash);
2239: }
2240: remove_entry_at((private_enumerator_t*)enumerator);
2241: entry_destroy(entry);
2242: }
2243: enumerator->destroy(enumerator);
2244: charon->bus->set_sa(charon->bus, NULL);
2245: }
2246:
2247: METHOD(ike_sa_manager_t, flush, void,
2248: private_ike_sa_manager_t *this)
2249: {
2250: enumerator_t *enumerator;
2251: entry_t *entry;
2252: u_int segment;
2253:
2254: lock_all_segments(this);
2255: DBG2(DBG_MGR, "going to destroy IKE_SA manager and all managed IKE_SA's");
2256: /* Step 1: drive out all waiting threads */
2257: DBG2(DBG_MGR, "set driveout flags for all stored IKE_SA's");
2258: enumerator = create_table_enumerator(this);
2259: while (enumerator->enumerate(enumerator, &entry, &segment))
2260: {
2261: /* do not accept new threads, drive out waiting threads */
2262: entry->driveout_new_threads = TRUE;
2263: entry->driveout_waiting_threads = TRUE;
2264: }
2265: enumerator->destroy(enumerator);
2266: DBG2(DBG_MGR, "wait for all threads to leave IKE_SA's");
2267: /* Step 2: wait until all are gone */
2268: enumerator = create_table_enumerator(this);
2269: while (enumerator->enumerate(enumerator, &entry, &segment))
2270: {
2271: while (entry->waiting_threads || entry->checked_out)
2272: {
2273: /* wake up all */
2274: entry->condvar->broadcast(entry->condvar);
2275: /* go sleeping until they are gone */
2276: entry->condvar->wait(entry->condvar, this->segments[segment].mutex);
2277: }
2278: }
2279: enumerator->destroy(enumerator);
2280: DBG2(DBG_MGR, "delete all IKE_SA's");
2281: /* Step 3: initiate deletion of all IKE_SAs */
2282: enumerator = create_table_enumerator(this);
2283: while (enumerator->enumerate(enumerator, &entry, &segment))
2284: {
2285: charon->bus->set_sa(charon->bus, entry->ike_sa);
2286: entry->ike_sa->delete(entry->ike_sa, TRUE);
2287: }
2288: enumerator->destroy(enumerator);
2289:
2290: DBG2(DBG_MGR, "destroy all entries");
2291: /* Step 4: destroy all entries */
2292: destroy_all_entries(this);
2293: unlock_all_segments(this);
2294:
2295: this->spi_lock->write_lock(this->spi_lock);
2296: DESTROY_IF(this->rng);
2297: this->rng = NULL;
2298: this->spi_cb.cb = NULL;
2299: this->spi_cb.data = NULL;
2300: this->spi_lock->unlock(this->spi_lock);
2301: }
2302:
2303: METHOD(ike_sa_manager_t, destroy, void,
2304: private_ike_sa_manager_t *this)
2305: {
2306: u_int i;
2307:
2308: /* in case new SAs were checked in after flush() was called */
2309: lock_all_segments(this);
2310: destroy_all_entries(this);
2311: unlock_all_segments(this);
2312:
2313: free(this->ike_sa_table);
2314: free(this->half_open_table);
2315: free(this->connected_peers_table);
2316: free(this->init_hashes_table);
2317: for (i = 0; i < this->segment_count; i++)
2318: {
2319: this->segments[i].mutex->destroy(this->segments[i].mutex);
2320: this->half_open_segments[i].lock->destroy(this->half_open_segments[i].lock);
2321: this->connected_peers_segments[i].lock->destroy(this->connected_peers_segments[i].lock);
2322: this->init_hashes_segments[i].mutex->destroy(this->init_hashes_segments[i].mutex);
2323: }
2324: free(this->segments);
2325: free(this->half_open_segments);
2326: free(this->connected_peers_segments);
2327: free(this->init_hashes_segments);
2328:
2329: this->spi_lock->destroy(this->spi_lock);
2330: free(this);
2331: }
2332:
2333: /**
2334: * This function returns the next-highest power of two for the given number.
2335: * The algorithm works by setting all bits on the right-hand side of the most
2336: * significant 1 to 1 and then increments the whole number so it rolls over
2337: * to the nearest power of two. Note: returns 0 for n == 0
2338: */
2339: static u_int get_nearest_powerof2(u_int n)
2340: {
2341: u_int i;
2342:
2343: --n;
2344: for (i = 1; i < sizeof(u_int) * 8; i <<= 1)
2345: {
2346: n |= n >> i;
2347: }
2348: return ++n;
2349: }
2350:
2351: /*
2352: * Described in header.
2353: */
2354: ike_sa_manager_t *ike_sa_manager_create()
2355: {
2356: private_ike_sa_manager_t *this;
2357: char *spi_val;
2358: u_int i;
2359:
2360: INIT(this,
2361: .public = {
2362: .checkout = _checkout,
2363: .checkout_new = _checkout_new,
2364: .checkout_by_message = _checkout_by_message,
2365: .checkout_by_config = _checkout_by_config,
2366: .checkout_by_id = _checkout_by_id,
2367: .checkout_by_name = _checkout_by_name,
2368: .new_initiator_spi = _new_initiator_spi,
2369: .check_uniqueness = _check_uniqueness,
2370: .has_contact = _has_contact,
2371: .create_enumerator = _create_enumerator,
2372: .create_id_enumerator = _create_id_enumerator,
2373: .checkin = _checkin,
2374: .checkin_and_destroy = _checkin_and_destroy,
2375: .get_count = _get_count,
2376: .get_half_open_count = _get_half_open_count,
2377: .flush = _flush,
2378: .set_spi_cb = _set_spi_cb,
2379: .destroy = _destroy,
2380: },
2381: );
2382:
2383: this->rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
2384: if (this->rng == NULL)
2385: {
2386: DBG1(DBG_MGR, "manager initialization failed, no RNG supported");
2387: free(this);
2388: return NULL;
2389: }
2390: this->spi_lock = rwlock_create(RWLOCK_TYPE_DEFAULT);
2391: spi_val = lib->settings->get_str(lib->settings, "%s.spi_mask", NULL,
2392: lib->ns);
2393: this->spi_mask = settings_value_as_uint64(spi_val, 0);
2394: spi_val = lib->settings->get_str(lib->settings, "%s.spi_label", NULL,
2395: lib->ns);
2396: this->spi_label = settings_value_as_uint64(spi_val, 0);
2397: if (this->spi_mask || this->spi_label)
2398: {
2399: DBG1(DBG_IKE, "using SPI label 0x%.16"PRIx64" and mask 0x%.16"PRIx64,
2400: this->spi_label, this->spi_mask);
2401: /* the allocated SPI is assumed to be in network order */
2402: this->spi_mask = htobe64(this->spi_mask);
2403: this->spi_label = htobe64(this->spi_label);
2404: }
2405:
2406: this->ikesa_limit = lib->settings->get_int(lib->settings,
2407: "%s.ikesa_limit", 0, lib->ns);
2408:
2409: this->table_size = get_nearest_powerof2(lib->settings->get_int(
2410: lib->settings, "%s.ikesa_table_size",
2411: DEFAULT_HASHTABLE_SIZE, lib->ns));
2412: this->table_size = max(1, min(this->table_size, MAX_HASHTABLE_SIZE));
2413: this->table_mask = this->table_size - 1;
2414:
2415: this->segment_count = get_nearest_powerof2(lib->settings->get_int(
2416: lib->settings, "%s.ikesa_table_segments",
2417: DEFAULT_SEGMENT_COUNT, lib->ns));
2418: this->segment_count = max(1, min(this->segment_count, this->table_size));
2419: this->segment_mask = this->segment_count - 1;
2420:
2421: this->ike_sa_table = calloc(this->table_size, sizeof(table_item_t*));
2422: this->segments = (segment_t*)calloc(this->segment_count, sizeof(segment_t));
2423: for (i = 0; i < this->segment_count; i++)
2424: {
2425: this->segments[i].mutex = mutex_create(MUTEX_TYPE_RECURSIVE);
2426: }
2427:
2428: /* we use the same table parameters for the table to track half-open SAs */
2429: this->half_open_table = calloc(this->table_size, sizeof(table_item_t*));
2430: this->half_open_segments = calloc(this->segment_count, sizeof(shareable_segment_t));
2431: for (i = 0; i < this->segment_count; i++)
2432: {
2433: this->half_open_segments[i].lock = rwlock_create(RWLOCK_TYPE_DEFAULT);
2434: }
2435:
2436: /* also for the hash table used for duplicate tests */
2437: this->connected_peers_table = calloc(this->table_size, sizeof(table_item_t*));
2438: this->connected_peers_segments = calloc(this->segment_count, sizeof(shareable_segment_t));
2439: for (i = 0; i < this->segment_count; i++)
2440: {
2441: this->connected_peers_segments[i].lock = rwlock_create(RWLOCK_TYPE_DEFAULT);
2442: }
2443:
2444: /* and again for the table of hashes of seen initial IKE messages */
2445: this->init_hashes_table = calloc(this->table_size, sizeof(table_item_t*));
2446: this->init_hashes_segments = calloc(this->segment_count, sizeof(segment_t));
2447: for (i = 0; i < this->segment_count; i++)
2448: {
2449: this->init_hashes_segments[i].mutex = mutex_create(MUTEX_TYPE_RECURSIVE);
2450: }
2451:
2452: this->reuse_ikesa = lib->settings->get_bool(lib->settings,
2453: "%s.reuse_ikesa", TRUE, lib->ns);
2454: return &this->public;
2455: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>