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>