Annotation of embedaddon/strongswan/src/libcharon/sa/ikev2/task_manager_v2.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2007-2018 Tobias Brunner
                      3:  * Copyright (C) 2007-2010 Martin Willi
                      4:  * HSR Hochschule fuer Technik Rapperswil
                      5:  *
                      6:  * This program is free software; you can redistribute it and/or modify it
                      7:  * under the terms of the GNU General Public License as published by the
                      8:  * Free Software Foundation; either version 2 of the License, or (at your
                      9:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                     10:  *
                     11:  * This program is distributed in the hope that it will be useful, but
                     12:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     13:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     14:  * for more details.
                     15:  */
                     16: 
                     17: #include "task_manager_v2.h"
                     18: 
                     19: #include <math.h>
                     20: 
                     21: #include <collections/array.h>
                     22: #include <daemon.h>
                     23: #include <sa/ikev2/tasks/ike_init.h>
                     24: #include <sa/ikev2/tasks/ike_natd.h>
                     25: #include <sa/ikev2/tasks/ike_mobike.h>
                     26: #include <sa/ikev2/tasks/ike_auth.h>
                     27: #include <sa/ikev2/tasks/ike_auth_lifetime.h>
                     28: #include <sa/ikev2/tasks/ike_cert_pre.h>
                     29: #include <sa/ikev2/tasks/ike_cert_post.h>
                     30: #include <sa/ikev2/tasks/ike_rekey.h>
                     31: #include <sa/ikev2/tasks/ike_reauth.h>
                     32: #include <sa/ikev2/tasks/ike_reauth_complete.h>
                     33: #include <sa/ikev2/tasks/ike_redirect.h>
                     34: #include <sa/ikev2/tasks/ike_delete.h>
                     35: #include <sa/ikev2/tasks/ike_config.h>
                     36: #include <sa/ikev2/tasks/ike_dpd.h>
                     37: #include <sa/ikev2/tasks/ike_mid_sync.h>
                     38: #include <sa/ikev2/tasks/ike_vendor.h>
                     39: #include <sa/ikev2/tasks/ike_verify_peer_cert.h>
                     40: #include <sa/ikev2/tasks/child_create.h>
                     41: #include <sa/ikev2/tasks/child_rekey.h>
                     42: #include <sa/ikev2/tasks/child_delete.h>
                     43: #include <encoding/payloads/delete_payload.h>
                     44: #include <encoding/payloads/unknown_payload.h>
                     45: #include <processing/jobs/retransmit_job.h>
                     46: #include <processing/jobs/delete_ike_sa_job.h>
                     47: #include <processing/jobs/initiate_tasks_job.h>
                     48: 
                     49: #ifdef ME
                     50: #include <sa/ikev2/tasks/ike_me.h>
                     51: #endif
                     52: 
                     53: typedef struct private_task_manager_t private_task_manager_t;
                     54: typedef struct queued_task_t queued_task_t;
                     55: 
                     56: /**
                     57:  * private data of the task manager
                     58:  */
                     59: struct private_task_manager_t {
                     60: 
                     61:        /**
                     62:         * public functions
                     63:         */
                     64:        task_manager_v2_t public;
                     65: 
                     66:        /**
                     67:         * associated IKE_SA we are serving
                     68:         */
                     69:        ike_sa_t *ike_sa;
                     70: 
                     71:        /**
                     72:         * Exchange we are currently handling as responder
                     73:         */
                     74:        struct {
                     75:                /**
                     76:                 * Message ID of the exchange
                     77:                 */
                     78:                uint32_t mid;
                     79: 
                     80:                /**
                     81:                 * packet(s) for retransmission
                     82:                 */
                     83:                array_t *packets;
                     84: 
                     85:                /**
                     86:                 * Helper to defragment the request
                     87:                 */
                     88:                message_t *defrag;
                     89: 
                     90:        } responding;
                     91: 
                     92:        /**
                     93:         * Exchange we are currently handling as initiator
                     94:         */
                     95:        struct {
                     96:                /**
                     97:                 * Message ID of the exchange
                     98:                 */
                     99:                uint32_t mid;
                    100: 
                    101:                /**
                    102:                 * how many times we have retransmitted so far
                    103:                 */
                    104:                u_int retransmitted;
                    105: 
                    106:                /**
                    107:                 * packet(s) for retransmission
                    108:                 */
                    109:                array_t *packets;
                    110: 
                    111:                /**
                    112:                 * type of the initiated exchange
                    113:                 */
                    114:                exchange_type_t type;
                    115: 
                    116:                /**
                    117:                 * TRUE if exchange was deferred because no path was available
                    118:                 */
                    119:                bool deferred;
                    120: 
                    121:                /**
                    122:                 * Helper to defragment the response
                    123:                 */
                    124:                message_t *defrag;
                    125: 
                    126:        } initiating;
                    127: 
                    128:        /**
                    129:         * Array of queued tasks not yet in action
                    130:         */
                    131:        array_t *queued_tasks;
                    132: 
                    133:        /**
                    134:         * Array of active tasks, initiated by ourselves
                    135:         */
                    136:        array_t *active_tasks;
                    137: 
                    138:        /**
                    139:         * Array of tasks initiated by peer
                    140:         */
                    141:        array_t *passive_tasks;
                    142: 
                    143:        /**
                    144:         * the task manager has been reset
                    145:         */
                    146:        bool reset;
                    147: 
                    148:        /**
                    149:         * Number of times we retransmit messages before giving up
                    150:         */
                    151:        u_int retransmit_tries;
                    152: 
                    153:        /**
                    154:         * Retransmission timeout
                    155:         */
                    156:        double retransmit_timeout;
                    157: 
                    158:        /**
                    159:         * Base to calculate retransmission timeout
                    160:         */
                    161:        double retransmit_base;
                    162: 
                    163:        /**
                    164:         * Jitter to apply to calculated retransmit timeout (in percent)
                    165:         */
                    166:        u_int retransmit_jitter;
                    167: 
                    168:        /**
                    169:         * Limit retransmit timeout to this value
                    170:         */
                    171:        uint32_t retransmit_limit;
                    172: 
                    173:        /**
                    174:         * Use make-before-break instead of break-before-make reauth?
                    175:         */
                    176:        bool make_before_break;
                    177: };
                    178: 
                    179: /**
                    180:  * Queued tasks
                    181:  */
                    182: struct queued_task_t {
                    183: 
                    184:        /**
                    185:         * Queued task
                    186:         */
                    187:        task_t *task;
                    188: 
                    189:        /**
                    190:         * Time before which the task is not to be initiated
                    191:         */
                    192:        timeval_t time;
                    193: };
                    194: 
                    195: /**
                    196:  * Reset retransmission packet list
                    197:  */
                    198: static void clear_packets(array_t *array)
                    199: {
                    200:        packet_t *packet;
                    201: 
                    202:        while (array_remove(array, ARRAY_TAIL, &packet))
                    203:        {
                    204:                packet->destroy(packet);
                    205:        }
                    206: }
                    207: 
                    208: METHOD(task_manager_t, flush_queue, void,
                    209:        private_task_manager_t *this, task_queue_t queue)
                    210: {
                    211:        array_t *array;
                    212:        task_t *task;
                    213: 
                    214:        switch (queue)
                    215:        {
                    216:                case TASK_QUEUE_ACTIVE:
                    217:                        array = this->active_tasks;
                    218:                        break;
                    219:                case TASK_QUEUE_PASSIVE:
                    220:                        array = this->passive_tasks;
                    221:                        break;
                    222:                case TASK_QUEUE_QUEUED:
                    223:                        array = this->queued_tasks;
                    224:                        break;
                    225:                default:
                    226:                        return;
                    227:        }
                    228:        while (array_remove(array, ARRAY_TAIL, &task))
                    229:        {
                    230:                if (queue == TASK_QUEUE_QUEUED)
                    231:                {
                    232:                        queued_task_t *queued = (queued_task_t*)task;
                    233:                        task = queued->task;
                    234:                        free(queued);
                    235:                }
                    236:                task->destroy(task);
                    237:        }
                    238: }
                    239: 
                    240: METHOD(task_manager_t, flush, void,
                    241:        private_task_manager_t *this)
                    242: {
                    243:        flush_queue(this, TASK_QUEUE_QUEUED);
                    244:        flush_queue(this, TASK_QUEUE_PASSIVE);
                    245:        flush_queue(this, TASK_QUEUE_ACTIVE);
                    246: }
                    247: 
                    248: /**
                    249:  * Move a task of a specific type from the queue to the active list, if it is
                    250:  * not delayed.
                    251:  */
                    252: static bool activate_task(private_task_manager_t *this, task_type_t type)
                    253: {
                    254:        enumerator_t *enumerator;
                    255:        queued_task_t *queued;
                    256:        timeval_t now;
                    257:        bool found = FALSE;
                    258: 
                    259:        time_monotonic(&now);
                    260: 
                    261:        enumerator = array_create_enumerator(this->queued_tasks);
                    262:        while (enumerator->enumerate(enumerator, (void**)&queued))
                    263:        {
                    264:                if (queued->task->get_type(queued->task) == type &&
                    265:                        !timercmp(&now, &queued->time, <))
                    266:                {
                    267:                        DBG2(DBG_IKE, "  activating %N task", task_type_names, type);
                    268:                        array_remove_at(this->queued_tasks, enumerator);
                    269:                        array_insert(this->active_tasks, ARRAY_TAIL, queued->task);
                    270:                        free(queued);
                    271:                        found = TRUE;
                    272:                        break;
                    273:                }
                    274:        }
                    275:        enumerator->destroy(enumerator);
                    276:        return found;
                    277: }
                    278: 
                    279: /**
                    280:  * Send packets in the given array (they get cloned). Optionally, the
                    281:  * source and destination addresses are changed before sending it.
                    282:  */
                    283: static void send_packets(private_task_manager_t *this, array_t *packets,
                    284:                                                 host_t *src, host_t *dst)
                    285: {
                    286:        packet_t *packet, *clone;
                    287:        int i;
                    288: 
                    289:        for (i = 0; i < array_count(packets); i++)
                    290:        {
                    291:                array_get(packets, i, &packet);
                    292:                clone = packet->clone(packet);
                    293:                if (src)
                    294:                {
                    295:                        clone->set_source(clone, src->clone(src));
                    296:                }
                    297:                if (dst)
                    298:                {
                    299:                        clone->set_destination(clone, dst->clone(dst));
                    300:                }
                    301:                charon->sender->send(charon->sender, clone);
                    302:        }
                    303: }
                    304: 
                    305: /**
                    306:  * Generates the given message and stores packet(s) in the given array
                    307:  */
                    308: static bool generate_message(private_task_manager_t *this, message_t *message,
                    309:                                                         array_t **packets)
                    310: {
                    311:        enumerator_t *fragments;
                    312:        packet_t *fragment;
                    313: 
                    314:        if (this->ike_sa->generate_message_fragmented(this->ike_sa, message,
                    315:                                                                                                  &fragments) != SUCCESS)
                    316:        {
                    317:                return FALSE;
                    318:        }
                    319:        while (fragments->enumerate(fragments, &fragment))
                    320:        {
                    321:                array_insert_create(packets, ARRAY_TAIL, fragment);
                    322:        }
                    323:        fragments->destroy(fragments);
                    324:        array_compress(*packets);
                    325:        return TRUE;
                    326: }
                    327: 
                    328: METHOD(task_manager_t, retransmit, status_t,
                    329:        private_task_manager_t *this, uint32_t message_id)
                    330: {
                    331:        if (message_id == this->initiating.mid &&
                    332:                array_count(this->initiating.packets))
                    333:        {
                    334:                uint32_t timeout, max_jitter;
                    335:                job_t *job;
                    336:                enumerator_t *enumerator;
                    337:                packet_t *packet;
                    338:                task_t *task;
                    339:                ike_mobike_t *mobike = NULL;
                    340: 
                    341:                array_get(this->initiating.packets, 0, &packet);
                    342: 
                    343:                /* check if we are retransmitting a MOBIKE routability check */
                    344:                if (this->initiating.type == INFORMATIONAL)
                    345:                {
                    346:                        enumerator = array_create_enumerator(this->active_tasks);
                    347:                        while (enumerator->enumerate(enumerator, (void*)&task))
                    348:                        {
                    349:                                if (task->get_type(task) == TASK_IKE_MOBIKE)
                    350:                                {
                    351:                                        mobike = (ike_mobike_t*)task;
                    352:                                        break;
                    353:                                }
                    354:                        }
                    355:                        enumerator->destroy(enumerator);
                    356:                }
                    357: 
                    358:                if (!mobike || !mobike->is_probing(mobike))
                    359:                {
                    360:                        if (this->initiating.retransmitted <= this->retransmit_tries)
                    361:                        {
                    362:                                timeout = (uint32_t)(this->retransmit_timeout * 1000.0 *
                    363:                                        pow(this->retransmit_base, this->initiating.retransmitted));
                    364: 
                    365:                                if (this->retransmit_limit)
                    366:                                {
                    367:                                        timeout = min(timeout, this->retransmit_limit);
                    368:                                }
                    369:                                if (this->retransmit_jitter)
                    370:                                {
                    371:                                        max_jitter = (timeout / 100.0) * this->retransmit_jitter;
                    372:                                        timeout -= max_jitter * (random() / (RAND_MAX + 1.0));
                    373:                                }
                    374:                        }
                    375:                        else
                    376:                        {
                    377:                                DBG1(DBG_IKE, "giving up after %d retransmits",
                    378:                                         this->initiating.retransmitted - 1);
                    379:                                charon->bus->alert(charon->bus, ALERT_RETRANSMIT_SEND_TIMEOUT,
                    380:                                                                   packet);
                    381:                                return DESTROY_ME;
                    382:                        }
                    383: 
                    384:                        if (this->initiating.retransmitted)
                    385:                        {
                    386:                                DBG1(DBG_IKE, "retransmit %d of request with message ID %d",
                    387:                                         this->initiating.retransmitted, message_id);
                    388:                                charon->bus->alert(charon->bus, ALERT_RETRANSMIT_SEND, packet,
                    389:                                                                   this->initiating.retransmitted);
                    390:                        }
                    391:                        if (!mobike)
                    392:                        {
                    393:                                send_packets(this, this->initiating.packets,
                    394:                                                         this->ike_sa->get_my_host(this->ike_sa),
                    395:                                                         this->ike_sa->get_other_host(this->ike_sa));
                    396:                        }
                    397:                        else
                    398:                        {
                    399:                                if (!mobike->transmit(mobike, packet))
                    400:                                {
                    401:                                        DBG1(DBG_IKE, "no route found to reach peer, MOBIKE update "
                    402:                                                 "deferred");
                    403:                                        this->ike_sa->set_condition(this->ike_sa, COND_STALE, TRUE);
                    404:                                        this->initiating.deferred = TRUE;
                    405:                                        return SUCCESS;
                    406:                                }
                    407:                                else if (mobike->is_probing(mobike))
                    408:                                {
                    409:                                        timeout = ROUTABILITY_CHECK_INTERVAL;
                    410:                                }
                    411:                        }
                    412:                }
                    413:                else
                    414:                {       /* for routability checks, we use a more aggressive behavior */
                    415:                        if (this->initiating.retransmitted <= ROUTABILITY_CHECK_TRIES)
                    416:                        {
                    417:                                timeout = ROUTABILITY_CHECK_INTERVAL;
                    418:                        }
                    419:                        else
                    420:                        {
                    421:                                DBG1(DBG_IKE, "giving up after %d path probings",
                    422:                                         this->initiating.retransmitted - 1);
                    423:                                return DESTROY_ME;
                    424:                        }
                    425: 
                    426:                        if (this->initiating.retransmitted)
                    427:                        {
                    428:                                DBG1(DBG_IKE, "path probing attempt %d",
                    429:                                         this->initiating.retransmitted);
                    430:                        }
                    431:                        /* TODO-FRAG: presumably these small packets are not fragmented,
                    432:                         * we should maybe ensure this is the case when generating them */
                    433:                        if (!mobike->transmit(mobike, packet))
                    434:                        {
                    435:                                DBG1(DBG_IKE, "no route found to reach peer, path probing "
                    436:                                         "deferred");
                    437:                                this->ike_sa->set_condition(this->ike_sa, COND_STALE, TRUE);
                    438:                                this->initiating.deferred = TRUE;
                    439:                                return SUCCESS;
                    440:                        }
                    441:                }
                    442: 
                    443:                this->initiating.retransmitted++;
                    444:                job = (job_t*)retransmit_job_create(this->initiating.mid,
                    445:                                                                                        this->ike_sa->get_id(this->ike_sa));
                    446:                lib->scheduler->schedule_job_ms(lib->scheduler, job, timeout);
                    447:        }
                    448:        return SUCCESS;
                    449: }
                    450: 
                    451: METHOD(task_manager_t, initiate, status_t,
                    452:        private_task_manager_t *this)
                    453: {
                    454:        enumerator_t *enumerator;
                    455:        task_t *task;
                    456:        message_t *message;
                    457:        host_t *me, *other;
                    458:        exchange_type_t exchange = 0;
                    459: 
                    460:        if (this->initiating.type != EXCHANGE_TYPE_UNDEFINED)
                    461:        {
                    462:                DBG2(DBG_IKE, "delaying task initiation, %N exchange in progress",
                    463:                                exchange_type_names, this->initiating.type);
                    464:                /* do not initiate if we already have a message in the air */
                    465:                if (this->initiating.deferred)
                    466:                {       /* re-initiate deferred exchange */
                    467:                        this->initiating.deferred = FALSE;
                    468:                        this->initiating.retransmitted = 0;
                    469:                        return retransmit(this, this->initiating.mid);
                    470:                }
                    471:                return SUCCESS;
                    472:        }
                    473: 
                    474:        if (array_count(this->active_tasks) == 0)
                    475:        {
                    476:                DBG2(DBG_IKE, "activating new tasks");
                    477:                switch (this->ike_sa->get_state(this->ike_sa))
                    478:                {
                    479:                        case IKE_CREATED:
                    480:                                activate_task(this, TASK_IKE_VENDOR);
                    481:                                if (activate_task(this, TASK_IKE_INIT))
                    482:                                {
                    483:                                        this->initiating.mid = 0;
                    484:                                        exchange = IKE_SA_INIT;
                    485:                                        activate_task(this, TASK_IKE_NATD);
                    486:                                        activate_task(this, TASK_IKE_CERT_PRE);
                    487: #ifdef ME
                    488:                                        /* this task has to be activated before the TASK_IKE_AUTH
                    489:                                         * task, because that task pregenerates the packet after
                    490:                                         * which no payloads can be added to the message anymore.
                    491:                                         */
                    492:                                        activate_task(this, TASK_IKE_ME);
                    493: #endif /* ME */
                    494:                                        activate_task(this, TASK_IKE_AUTH);
                    495:                                        activate_task(this, TASK_IKE_CERT_POST);
                    496:                                        activate_task(this, TASK_IKE_CONFIG);
                    497:                                        activate_task(this, TASK_CHILD_CREATE);
                    498:                                        activate_task(this, TASK_IKE_AUTH_LIFETIME);
                    499:                                        activate_task(this, TASK_IKE_MOBIKE);
                    500:                                }
                    501:                                break;
                    502:                        case IKE_ESTABLISHED:
                    503:                                if (activate_task(this, TASK_IKE_MOBIKE))
                    504:                                {
                    505:                                        exchange = INFORMATIONAL;
                    506:                                        break;
                    507:                                }
                    508:                                if (activate_task(this, TASK_IKE_DELETE))
                    509:                                {
                    510:                                        exchange = INFORMATIONAL;
                    511:                                        break;
                    512:                                }
                    513:                                if (activate_task(this, TASK_IKE_REDIRECT))
                    514:                                {
                    515:                                        exchange = INFORMATIONAL;
                    516:                                        break;
                    517:                                }
                    518:                                if (activate_task(this, TASK_CHILD_DELETE))
                    519:                                {
                    520:                                        exchange = INFORMATIONAL;
                    521:                                        break;
                    522:                                }
                    523:                                if (activate_task(this, TASK_IKE_REAUTH))
                    524:                                {
                    525:                                        exchange = INFORMATIONAL;
                    526:                                        break;
                    527:                                }
                    528:                                if (activate_task(this, TASK_CHILD_CREATE))
                    529:                                {
                    530:                                        exchange = CREATE_CHILD_SA;
                    531:                                        break;
                    532:                                }
                    533:                                if (activate_task(this, TASK_CHILD_REKEY))
                    534:                                {
                    535:                                        exchange = CREATE_CHILD_SA;
                    536:                                        break;
                    537:                                }
                    538:                                if (activate_task(this, TASK_IKE_REKEY))
                    539:                                {
                    540:                                        exchange = CREATE_CHILD_SA;
                    541:                                        break;
                    542:                                }
                    543:                                if (activate_task(this, TASK_IKE_DPD))
                    544:                                {
                    545:                                        exchange = INFORMATIONAL;
                    546:                                        break;
                    547:                                }
                    548:                                if (activate_task(this, TASK_IKE_AUTH_LIFETIME))
                    549:                                {
                    550:                                        exchange = INFORMATIONAL;
                    551:                                        break;
                    552:                                }
                    553: #ifdef ME
                    554:                                if (activate_task(this, TASK_IKE_ME))
                    555:                                {
                    556:                                        exchange = ME_CONNECT;
                    557:                                        break;
                    558:                                }
                    559: #endif /* ME */
                    560:                                if (activate_task(this, TASK_IKE_REAUTH_COMPLETE))
                    561:                                {
                    562:                                        exchange = INFORMATIONAL;
                    563:                                        break;
                    564:                                }
                    565:                                if (activate_task(this, TASK_IKE_VERIFY_PEER_CERT))
                    566:                                {
                    567:                                        exchange = INFORMATIONAL;
                    568:                                        break;
                    569:                                }
                    570:                        case IKE_REKEYING:
                    571:                        case IKE_REKEYED:
                    572:                                if (activate_task(this, TASK_IKE_DELETE))
                    573:                                {
                    574:                                        exchange = INFORMATIONAL;
                    575:                                        break;
                    576:                                }
                    577:                        case IKE_DELETING:
                    578:                        default:
                    579:                                break;
                    580:                }
                    581:        }
                    582:        else
                    583:        {
                    584:                DBG2(DBG_IKE, "reinitiating already active tasks");
                    585:                enumerator = array_create_enumerator(this->active_tasks);
                    586:                while (enumerator->enumerate(enumerator, &task))
                    587:                {
                    588:                        DBG2(DBG_IKE, "  %N task", task_type_names, task->get_type(task));
                    589:                        switch (task->get_type(task))
                    590:                        {
                    591:                                case TASK_IKE_INIT:
                    592:                                        exchange = IKE_SA_INIT;
                    593:                                        break;
                    594:                                case TASK_IKE_AUTH:
                    595:                                        exchange = IKE_AUTH;
                    596:                                        break;
                    597:                                case TASK_CHILD_CREATE:
                    598:                                case TASK_CHILD_REKEY:
                    599:                                case TASK_IKE_REKEY:
                    600:                                        exchange = CREATE_CHILD_SA;
                    601:                                        break;
                    602:                                case TASK_IKE_MOBIKE:
                    603:                                        exchange = INFORMATIONAL;
                    604:                                        break;
                    605:                                default:
                    606:                                        continue;
                    607:                        }
                    608:                        break;
                    609:                }
                    610:                enumerator->destroy(enumerator);
                    611:        }
                    612: 
                    613:        if (exchange == 0)
                    614:        {
                    615:                DBG2(DBG_IKE, "nothing to initiate");
                    616:                /* nothing to do yet... */
                    617:                return SUCCESS;
                    618:        }
                    619: 
                    620:        me = this->ike_sa->get_my_host(this->ike_sa);
                    621:        other = this->ike_sa->get_other_host(this->ike_sa);
                    622: 
                    623:        message = message_create(IKEV2_MAJOR_VERSION, IKEV2_MINOR_VERSION);
                    624:        message->set_message_id(message, this->initiating.mid);
                    625:        message->set_source(message, me->clone(me));
                    626:        message->set_destination(message, other->clone(other));
                    627:        message->set_exchange_type(message, exchange);
                    628:        this->initiating.type = exchange;
                    629:        this->initiating.retransmitted = 0;
                    630:        this->initiating.deferred = FALSE;
                    631: 
                    632:        enumerator = array_create_enumerator(this->active_tasks);
                    633:        while (enumerator->enumerate(enumerator, &task))
                    634:        {
                    635:                switch (task->build(task, message))
                    636:                {
                    637:                        case SUCCESS:
                    638:                                /* task completed, remove it */
                    639:                                array_remove_at(this->active_tasks, enumerator);
                    640:                                task->destroy(task);
                    641:                                break;
                    642:                        case NEED_MORE:
                    643:                                /* processed, but task needs another exchange */
                    644:                                break;
                    645:                        case FAILED:
                    646:                        default:
                    647:                                this->initiating.type = EXCHANGE_TYPE_UNDEFINED;
                    648:                                if (this->ike_sa->get_state(this->ike_sa) != IKE_CONNECTING &&
                    649:                                        this->ike_sa->get_state(this->ike_sa) != IKE_REKEYED)
                    650:                                {
                    651:                                        charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
                    652:                                }
                    653:                                /* FALL */
                    654:                        case DESTROY_ME:
                    655:                                /* critical failure, destroy IKE_SA */
                    656:                                enumerator->destroy(enumerator);
                    657:                                message->destroy(message);
                    658:                                flush(this);
                    659:                                return DESTROY_ME;
                    660:                }
                    661:        }
                    662:        enumerator->destroy(enumerator);
                    663: 
                    664:        /* update exchange type if a task changed it */
                    665:        this->initiating.type = message->get_exchange_type(message);
                    666:        if (this->initiating.type == EXCHANGE_TYPE_UNDEFINED)
                    667:        {
                    668:                message->destroy(message);
                    669:                return initiate(this);
                    670:        }
                    671: 
                    672:        if (!generate_message(this, message, &this->initiating.packets))
                    673:        {
                    674:                /* message generation failed. There is nothing more to do than to
                    675:                 * close the SA */
                    676:                message->destroy(message);
                    677:                flush(this);
                    678:                charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
                    679:                return DESTROY_ME;
                    680:        }
                    681:        message->destroy(message);
                    682: 
                    683:        array_compress(this->active_tasks);
                    684:        array_compress(this->queued_tasks);
                    685: 
                    686:        return retransmit(this, this->initiating.mid);
                    687: }
                    688: 
                    689: /**
                    690:  * handle an incoming response message
                    691:  */
                    692: static status_t process_response(private_task_manager_t *this,
                    693:                                                                 message_t *message)
                    694: {
                    695:        enumerator_t *enumerator;
                    696:        task_t *task;
                    697: 
                    698:        if (message->get_exchange_type(message) != this->initiating.type)
                    699:        {
                    700:                DBG1(DBG_IKE, "received %N response, but expected %N",
                    701:                         exchange_type_names, message->get_exchange_type(message),
                    702:                         exchange_type_names, this->initiating.type);
                    703:                charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
                    704:                return DESTROY_ME;
                    705:        }
                    706: 
                    707:        /* handle fatal INVALID_SYNTAX notifies */
                    708:        switch (message->get_exchange_type(message))
                    709:        {
                    710:                case CREATE_CHILD_SA:
                    711:                case INFORMATIONAL:
                    712:                        if (message->get_notify(message, INVALID_SYNTAX))
                    713:                        {
                    714:                                DBG1(DBG_IKE, "received %N notify error, destroying IKE_SA",
                    715:                                         notify_type_names, INVALID_SYNTAX);
                    716:                                charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
                    717:                                return DESTROY_ME;
                    718:                        }
                    719:                        break;
                    720:                default:
                    721:                        break;
                    722:        }
                    723: 
                    724:        enumerator = array_create_enumerator(this->active_tasks);
                    725:        while (enumerator->enumerate(enumerator, &task))
                    726:        {
                    727:                if (!task->pre_process)
                    728:                {
                    729:                        continue;
                    730:                }
                    731:                switch (task->pre_process(task, message))
                    732:                {
                    733:                        case SUCCESS:
                    734:                                break;
                    735:                        case FAILED:
                    736:                        default:
                    737:                                /* just ignore the message */
                    738:                                DBG1(DBG_IKE, "ignore invalid %N response",
                    739:                                         exchange_type_names, message->get_exchange_type(message));
                    740:                                enumerator->destroy(enumerator);
                    741:                                return SUCCESS;
                    742:                        case DESTROY_ME:
                    743:                                /* critical failure, destroy IKE_SA */
                    744:                                enumerator->destroy(enumerator);
                    745:                                return DESTROY_ME;
                    746:                }
                    747:        }
                    748:        enumerator->destroy(enumerator);
                    749: 
                    750:        if (this->initiating.retransmitted > 1)
                    751:        {
                    752:                packet_t *packet = NULL;
                    753:                array_get(this->initiating.packets, 0, &packet);
                    754:                charon->bus->alert(charon->bus, ALERT_RETRANSMIT_SEND_CLEARED, packet);
                    755:        }
                    756: 
                    757:        /* catch if we get reset while processing */
                    758:        this->reset = FALSE;
                    759:        enumerator = array_create_enumerator(this->active_tasks);
                    760:        while (enumerator->enumerate(enumerator, &task))
                    761:        {
                    762:                switch (task->process(task, message))
                    763:                {
                    764:                        case SUCCESS:
                    765:                                /* task completed, remove it */
                    766:                                array_remove_at(this->active_tasks, enumerator);
                    767:                                task->destroy(task);
                    768:                                break;
                    769:                        case NEED_MORE:
                    770:                                /* processed, but task needs another exchange */
                    771:                                break;
                    772:                        case FAILED:
                    773:                        default:
                    774:                                charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
                    775:                                /* FALL */
                    776:                        case DESTROY_ME:
                    777:                                /* critical failure, destroy IKE_SA */
                    778:                                array_remove_at(this->active_tasks, enumerator);
                    779:                                enumerator->destroy(enumerator);
                    780:                                task->destroy(task);
                    781:                                return DESTROY_ME;
                    782:                }
                    783:                if (this->reset)
                    784:                {       /* start all over again if we were reset */
                    785:                        this->reset = FALSE;
                    786:                        enumerator->destroy(enumerator);
                    787:                        return initiate(this);
                    788:                }
                    789:        }
                    790:        enumerator->destroy(enumerator);
                    791: 
                    792:        this->initiating.mid++;
                    793:        this->initiating.type = EXCHANGE_TYPE_UNDEFINED;
                    794:        clear_packets(this->initiating.packets);
                    795: 
                    796:        array_compress(this->active_tasks);
                    797: 
                    798:        return initiate(this);
                    799: }
                    800: 
                    801: /**
                    802:  * handle exchange collisions
                    803:  */
                    804: static bool handle_collisions(private_task_manager_t *this, task_t *task)
                    805: {
                    806:        enumerator_t *enumerator;
                    807:        task_t *active;
                    808:        task_type_t type;
                    809: 
                    810:        type = task->get_type(task);
                    811: 
                    812:        /* do we have to check  */
                    813:        if (type == TASK_IKE_REKEY || type == TASK_CHILD_REKEY ||
                    814:                type == TASK_CHILD_DELETE || type == TASK_IKE_DELETE)
                    815:        {
                    816:                /* find an exchange collision, and notify these tasks */
                    817:                enumerator = array_create_enumerator(this->active_tasks);
                    818:                while (enumerator->enumerate(enumerator, &active))
                    819:                {
                    820:                        switch (active->get_type(active))
                    821:                        {
                    822:                                case TASK_IKE_REKEY:
                    823:                                        if (type == TASK_IKE_REKEY || type == TASK_IKE_DELETE)
                    824:                                        {
                    825:                                                ike_rekey_t *rekey = (ike_rekey_t*)active;
                    826:                                                rekey->collide(rekey, task);
                    827:                                                break;
                    828:                                        }
                    829:                                        continue;
                    830:                                case TASK_CHILD_REKEY:
                    831:                                        if (type == TASK_CHILD_REKEY || type == TASK_CHILD_DELETE)
                    832:                                        {
                    833:                                                child_rekey_t *rekey = (child_rekey_t*)active;
                    834:                                                rekey->collide(rekey, task);
                    835:                                                break;
                    836:                                        }
                    837:                                        continue;
                    838:                                default:
                    839:                                        continue;
                    840:                        }
                    841:                        enumerator->destroy(enumerator);
                    842:                        return TRUE;
                    843:                }
                    844:                enumerator->destroy(enumerator);
                    845:        }
                    846:        return FALSE;
                    847: }
                    848: 
                    849: /**
                    850:  * build a response depending on the "passive" task list
                    851:  */
                    852: static status_t build_response(private_task_manager_t *this, message_t *request)
                    853: {
                    854:        enumerator_t *enumerator;
                    855:        task_t *task;
                    856:        message_t *message;
                    857:        host_t *me, *other;
                    858:        bool delete = FALSE, hook = FALSE, mid_sync = FALSE;
                    859:        ike_sa_id_t *id = NULL;
                    860:        uint64_t responder_spi = 0;
                    861:        bool result;
                    862: 
                    863:        me = request->get_destination(request);
                    864:        other = request->get_source(request);
                    865: 
                    866:        message = message_create(IKEV2_MAJOR_VERSION, IKEV2_MINOR_VERSION);
                    867:        message->set_exchange_type(message, request->get_exchange_type(request));
                    868:        /* send response along the path the request came in */
                    869:        message->set_source(message, me->clone(me));
                    870:        message->set_destination(message, other->clone(other));
                    871:        message->set_message_id(message, this->responding.mid);
                    872:        message->set_request(message, FALSE);
                    873: 
                    874:        enumerator = array_create_enumerator(this->passive_tasks);
                    875:        while (enumerator->enumerate(enumerator, (void*)&task))
                    876:        {
                    877:                if (task->get_type(task) == TASK_IKE_MID_SYNC)
                    878:                {
                    879:                        mid_sync = TRUE;
                    880:                }
                    881:                switch (task->build(task, message))
                    882:                {
                    883:                        case SUCCESS:
                    884:                                /* task completed, remove it */
                    885:                                array_remove_at(this->passive_tasks, enumerator);
                    886:                                if (!handle_collisions(this, task))
                    887:                                {
                    888:                                        task->destroy(task);
                    889:                                }
                    890:                                break;
                    891:                        case NEED_MORE:
                    892:                                /* processed, but task needs another exchange */
                    893:                                if (handle_collisions(this, task))
                    894:                                {
                    895:                                        array_remove_at(this->passive_tasks, enumerator);
                    896:                                }
                    897:                                break;
                    898:                        case FAILED:
                    899:                        default:
                    900:                                hook = TRUE;
                    901:                                /* FALL */
                    902:                        case DESTROY_ME:
                    903:                                /* destroy IKE_SA, but SEND response first */
                    904:                                if (handle_collisions(this, task))
                    905:                                {
                    906:                                        array_remove_at(this->passive_tasks, enumerator);
                    907:                                }
                    908:                                delete = TRUE;
                    909:                                break;
                    910:                }
                    911:                if (delete)
                    912:                {
                    913:                        break;
                    914:                }
                    915:        }
                    916:        enumerator->destroy(enumerator);
                    917: 
                    918:        /* RFC 5996, section 2.6 mentions that in the event of a failure during
                    919:         * IKE_SA_INIT the responder's SPI will be 0 in the response, while it
                    920:         * actually explicitly allows it to be non-zero.  Since we use the responder
                    921:         * SPI to create hashes in the IKE_SA manager we can only set the SPI to
                    922:         * zero temporarily, otherwise checking the SA in would fail. */
                    923:        if (delete && request->get_exchange_type(request) == IKE_SA_INIT)
                    924:        {
                    925:                id = this->ike_sa->get_id(this->ike_sa);
                    926:                responder_spi = id->get_responder_spi(id);
                    927:                id->set_responder_spi(id, 0);
                    928:        }
                    929: 
                    930:        /* message complete, send it */
                    931:        clear_packets(this->responding.packets);
                    932:        result = generate_message(this, message, &this->responding.packets);
                    933:        message->destroy(message);
                    934:        if (id)
                    935:        {
                    936:                id->set_responder_spi(id, responder_spi);
                    937:        }
                    938:        if (!result)
                    939:        {
                    940:                charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
                    941:                return DESTROY_ME;
                    942:        }
                    943: 
                    944:        send_packets(this, this->responding.packets, NULL, NULL);
                    945:        if (delete)
                    946:        {
                    947:                if (hook)
                    948:                {
                    949:                        charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
                    950:                }
                    951:                return DESTROY_ME;
                    952:        }
                    953:        else if (mid_sync)
                    954:        {
                    955:                /* we don't want to resend messages to sync MIDs if requests with the
                    956:                 * previous MID arrive */
                    957:                clear_packets(this->responding.packets);
                    958:                /* avoid increasing the expected message ID after handling a message
                    959:                 * to sync MIDs with MID 0 */
                    960:                return NEED_MORE;
                    961:        }
                    962: 
                    963:        array_compress(this->passive_tasks);
                    964: 
                    965:        return SUCCESS;
                    966: }
                    967: 
                    968: /**
                    969:  * handle an incoming request message
                    970:  */
                    971: static status_t process_request(private_task_manager_t *this,
                    972:                                                                message_t *message)
                    973: {
                    974:        enumerator_t *enumerator;
                    975:        task_t *task = NULL;
                    976:        payload_t *payload;
                    977:        notify_payload_t *notify;
                    978:        delete_payload_t *delete;
                    979:        ike_sa_state_t state;
                    980: 
                    981:        if (array_count(this->passive_tasks) == 0)
                    982:        {       /* create tasks depending on request type, if not already some queued */
                    983:                state = this->ike_sa->get_state(this->ike_sa);
                    984:                switch (message->get_exchange_type(message))
                    985:                {
                    986:                        case IKE_SA_INIT:
                    987:                        {
                    988:                                task = (task_t*)ike_vendor_create(this->ike_sa, FALSE);
                    989:                                array_insert(this->passive_tasks, ARRAY_TAIL, task);
                    990:                                task = (task_t*)ike_init_create(this->ike_sa, FALSE, NULL);
                    991:                                array_insert(this->passive_tasks, ARRAY_TAIL, task);
                    992:                                task = (task_t*)ike_natd_create(this->ike_sa, FALSE);
                    993:                                array_insert(this->passive_tasks, ARRAY_TAIL, task);
                    994:                                task = (task_t*)ike_cert_pre_create(this->ike_sa, FALSE);
                    995:                                array_insert(this->passive_tasks, ARRAY_TAIL, task);
                    996: #ifdef ME
                    997:                                task = (task_t*)ike_me_create(this->ike_sa, FALSE);
                    998:                                array_insert(this->passive_tasks, ARRAY_TAIL, task);
                    999: #endif /* ME */
                   1000:                                task = (task_t*)ike_auth_create(this->ike_sa, FALSE);
                   1001:                                array_insert(this->passive_tasks, ARRAY_TAIL, task);
                   1002:                                task = (task_t*)ike_cert_post_create(this->ike_sa, FALSE);
                   1003:                                array_insert(this->passive_tasks, ARRAY_TAIL, task);
                   1004:                                task = (task_t*)ike_config_create(this->ike_sa, FALSE);
                   1005:                                array_insert(this->passive_tasks, ARRAY_TAIL, task);
                   1006:                                task = (task_t*)child_create_create(this->ike_sa, NULL, FALSE,
                   1007:                                                                                                        NULL, NULL);
                   1008:                                array_insert(this->passive_tasks, ARRAY_TAIL, task);
                   1009:                                task = (task_t*)ike_auth_lifetime_create(this->ike_sa, FALSE);
                   1010:                                array_insert(this->passive_tasks, ARRAY_TAIL, task);
                   1011:                                task = (task_t*)ike_mobike_create(this->ike_sa, FALSE);
                   1012:                                array_insert(this->passive_tasks, ARRAY_TAIL, task);
                   1013:                                break;
                   1014:                        }
                   1015:                        case CREATE_CHILD_SA:
                   1016:                        {       /* FIXME: we should prevent this on mediation connections */
                   1017:                                bool notify_found = FALSE, ts_found = FALSE;
                   1018: 
                   1019:                                if (state == IKE_CREATED ||
                   1020:                                        state == IKE_CONNECTING)
                   1021:                                {
                   1022:                                        DBG1(DBG_IKE, "received CREATE_CHILD_SA request for "
                   1023:                                                 "unestablished IKE_SA, rejected");
                   1024:                                        return FAILED;
                   1025:                                }
                   1026: 
                   1027:                                enumerator = message->create_payload_enumerator(message);
                   1028:                                while (enumerator->enumerate(enumerator, &payload))
                   1029:                                {
                   1030:                                        switch (payload->get_type(payload))
                   1031:                                        {
                   1032:                                                case PLV2_NOTIFY:
                   1033:                                                {       /* if we find a rekey notify, its CHILD_SA rekeying */
                   1034:                                                        notify = (notify_payload_t*)payload;
                   1035:                                                        if (notify->get_notify_type(notify) == REKEY_SA &&
                   1036:                                                                (notify->get_protocol_id(notify) == PROTO_AH ||
                   1037:                                                                 notify->get_protocol_id(notify) == PROTO_ESP))
                   1038:                                                        {
                   1039:                                                                notify_found = TRUE;
                   1040:                                                        }
                   1041:                                                        break;
                   1042:                                                }
                   1043:                                                case PLV2_TS_INITIATOR:
                   1044:                                                case PLV2_TS_RESPONDER:
                   1045:                                                {       /* if we don't find a TS, its IKE rekeying */
                   1046:                                                        ts_found = TRUE;
                   1047:                                                        break;
                   1048:                                                }
                   1049:                                                default:
                   1050:                                                        break;
                   1051:                                        }
                   1052:                                }
                   1053:                                enumerator->destroy(enumerator);
                   1054: 
                   1055:                                if (ts_found)
                   1056:                                {
                   1057:                                        if (notify_found)
                   1058:                                        {
                   1059:                                                task = (task_t*)child_rekey_create(this->ike_sa,
                   1060:                                                                                                                   PROTO_NONE, 0);
                   1061:                                        }
                   1062:                                        else
                   1063:                                        {
                   1064:                                                task = (task_t*)child_create_create(this->ike_sa, NULL,
                   1065:                                                                                                                        FALSE, NULL, NULL);
                   1066:                                        }
                   1067:                                }
                   1068:                                else
                   1069:                                {
                   1070:                                        task = (task_t*)ike_rekey_create(this->ike_sa, FALSE);
                   1071:                                }
                   1072:                                array_insert(this->passive_tasks, ARRAY_TAIL, task);
                   1073:                                break;
                   1074:                        }
                   1075:                        case INFORMATIONAL:
                   1076:                        {
                   1077:                                enumerator = message->create_payload_enumerator(message);
                   1078:                                while (enumerator->enumerate(enumerator, &payload))
                   1079:                                {
                   1080:                                        switch (payload->get_type(payload))
                   1081:                                        {
                   1082:                                                case PLV2_NOTIFY:
                   1083:                                                {
                   1084:                                                        notify = (notify_payload_t*)payload;
                   1085:                                                        if (state == IKE_REKEYED)
                   1086:                                                        {
                   1087:                                                                DBG1(DBG_IKE, "received unexpected notify %N "
                   1088:                                                                         "for rekeyed IKE_SA, ignored",
                   1089:                                                                         notify_type_names,
                   1090:                                                                         notify->get_notify_type(notify));
                   1091:                                                                break;
                   1092:                                                        }
                   1093:                                                        switch (notify->get_notify_type(notify))
                   1094:                                                        {
                   1095:                                                                case ADDITIONAL_IP4_ADDRESS:
                   1096:                                                                case ADDITIONAL_IP6_ADDRESS:
                   1097:                                                                case NO_ADDITIONAL_ADDRESSES:
                   1098:                                                                case UPDATE_SA_ADDRESSES:
                   1099:                                                                case NO_NATS_ALLOWED:
                   1100:                                                                case UNACCEPTABLE_ADDRESSES:
                   1101:                                                                case UNEXPECTED_NAT_DETECTED:
                   1102:                                                                case COOKIE2:
                   1103:                                                                case NAT_DETECTION_SOURCE_IP:
                   1104:                                                                case NAT_DETECTION_DESTINATION_IP:
                   1105:                                                                        task = (task_t*)ike_mobike_create(
                   1106:                                                                                                                        this->ike_sa, FALSE);
                   1107:                                                                        break;
                   1108:                                                                case AUTH_LIFETIME:
                   1109:                                                                        task = (task_t*)ike_auth_lifetime_create(
                   1110:                                                                                                                        this->ike_sa, FALSE);
                   1111:                                                                        break;
                   1112:                                                                case AUTHENTICATION_FAILED:
                   1113:                                                                        /* initiator failed to authenticate us.
                   1114:                                                                         * We use ike_delete to handle this, which
                   1115:                                                                         * invokes all the required hooks. */
                   1116:                                                                        task = (task_t*)ike_delete_create(
                   1117:                                                                                                                this->ike_sa, FALSE);
                   1118:                                                                        break;
                   1119:                                                                case REDIRECT:
                   1120:                                                                        task = (task_t*)ike_redirect_create(
                   1121:                                                                                                                        this->ike_sa, NULL);
                   1122:                                                                        break;
                   1123:                                                                case IKEV2_MESSAGE_ID_SYNC:
                   1124:                                                                        task = (task_t*)ike_mid_sync_create(
                   1125:                                                                                                                                 this->ike_sa);
                   1126:                                                                        break;
                   1127:                                                                default:
                   1128:                                                                        break;
                   1129:                                                        }
                   1130:                                                        break;
                   1131:                                                }
                   1132:                                                case PLV2_DELETE:
                   1133:                                                {
                   1134:                                                        delete = (delete_payload_t*)payload;
                   1135:                                                        if (delete->get_protocol_id(delete) == PROTO_IKE)
                   1136:                                                        {
                   1137:                                                                task = (task_t*)ike_delete_create(this->ike_sa,
                   1138:                                                                                                                                FALSE);
                   1139:                                                        }
                   1140:                                                        else
                   1141:                                                        {
                   1142:                                                                task = (task_t*)child_delete_create(this->ike_sa,
                   1143:                                                                                                                PROTO_NONE, 0, FALSE);
                   1144:                                                        }
                   1145:                                                        break;
                   1146:                                                }
                   1147:                                                default:
                   1148:                                                        break;
                   1149:                                        }
                   1150:                                        if (task)
                   1151:                                        {
                   1152:                                                break;
                   1153:                                        }
                   1154:                                }
                   1155:                                enumerator->destroy(enumerator);
                   1156: 
                   1157:                                if (task == NULL)
                   1158:                                {
                   1159:                                        task = (task_t*)ike_dpd_create(FALSE);
                   1160:                                }
                   1161:                                array_insert(this->passive_tasks, ARRAY_TAIL, task);
                   1162:                                break;
                   1163:                        }
                   1164: #ifdef ME
                   1165:                        case ME_CONNECT:
                   1166:                        {
                   1167:                                task = (task_t*)ike_me_create(this->ike_sa, FALSE);
                   1168:                                array_insert(this->passive_tasks, ARRAY_TAIL, task);
                   1169:                        }
                   1170: #endif /* ME */
                   1171:                        default:
                   1172:                                break;
                   1173:                }
                   1174:        }
                   1175: 
                   1176:        enumerator = array_create_enumerator(this->passive_tasks);
                   1177:        while (enumerator->enumerate(enumerator, &task))
                   1178:        {
                   1179:                if (!task->pre_process)
                   1180:                {
                   1181:                        continue;
                   1182:                }
                   1183:                switch (task->pre_process(task, message))
                   1184:                {
                   1185:                        case SUCCESS:
                   1186:                                break;
                   1187:                        case FAILED:
                   1188:                        default:
                   1189:                                /* just ignore the message */
                   1190:                                DBG1(DBG_IKE, "ignore invalid %N request",
                   1191:                                         exchange_type_names, message->get_exchange_type(message));
                   1192:                                enumerator->destroy(enumerator);
                   1193:                                switch (message->get_exchange_type(message))
                   1194:                                {
                   1195:                                        case IKE_SA_INIT:
                   1196:                                                /* no point in keeping the SA when it was created with
                   1197:                                                 * an invalid IKE_SA_INIT message */
                   1198:                                                return DESTROY_ME;
                   1199:                                        default:
                   1200:                                                /* remove tasks we queued for this request */
                   1201:                                                flush_queue(this, TASK_QUEUE_PASSIVE);
                   1202:                                                /* fall-through */
                   1203:                                        case IKE_AUTH:
                   1204:                                                return NEED_MORE;
                   1205:                                }
                   1206:                        case DESTROY_ME:
                   1207:                                /* critical failure, destroy IKE_SA */
                   1208:                                enumerator->destroy(enumerator);
                   1209:                                return DESTROY_ME;
                   1210:                }
                   1211:        }
                   1212:        enumerator->destroy(enumerator);
                   1213: 
                   1214:        /* let the tasks process the message */
                   1215:        enumerator = array_create_enumerator(this->passive_tasks);
                   1216:        while (enumerator->enumerate(enumerator, (void*)&task))
                   1217:        {
                   1218:                switch (task->process(task, message))
                   1219:                {
                   1220:                        case SUCCESS:
                   1221:                                /* task completed, remove it */
                   1222:                                array_remove_at(this->passive_tasks, enumerator);
                   1223:                                task->destroy(task);
                   1224:                                break;
                   1225:                        case NEED_MORE:
                   1226:                                /* processed, but task needs at least another call to build() */
                   1227:                                break;
                   1228:                        case FAILED:
                   1229:                        default:
                   1230:                                charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
                   1231:                                /* FALL */
                   1232:                        case DESTROY_ME:
                   1233:                                /* critical failure, destroy IKE_SA */
                   1234:                                array_remove_at(this->passive_tasks, enumerator);
                   1235:                                enumerator->destroy(enumerator);
                   1236:                                task->destroy(task);
                   1237:                                return DESTROY_ME;
                   1238:                }
                   1239:        }
                   1240:        enumerator->destroy(enumerator);
                   1241: 
                   1242:        return build_response(this, message);
                   1243: }
                   1244: 
                   1245: METHOD(task_manager_t, incr_mid, void,
                   1246:        private_task_manager_t *this, bool initiate)
                   1247: {
                   1248:        if (initiate)
                   1249:        {
                   1250:                this->initiating.mid++;
                   1251:        }
                   1252:        else
                   1253:        {
                   1254:                this->responding.mid++;
                   1255:        }
                   1256: }
                   1257: 
                   1258: METHOD(task_manager_t, get_mid, uint32_t,
                   1259:        private_task_manager_t *this, bool initiate)
                   1260: {
                   1261:        return initiate ? this->initiating.mid : this->responding.mid;
                   1262: }
                   1263: 
                   1264: /**
                   1265:  * Handle the given IKE fragment, if it is one.
                   1266:  *
                   1267:  * Returns SUCCESS if the message is not a fragment, and NEED_MORE if it was
                   1268:  * handled properly.  Error states are  returned if the fragment was invalid or
                   1269:  * the reassembled message could not have been processed properly.
                   1270:  */
                   1271: static status_t handle_fragment(private_task_manager_t *this,
                   1272:                                                                message_t **defrag, message_t *msg)
                   1273: {
                   1274:        message_t *reassembled;
                   1275:        status_t status;
                   1276: 
                   1277:        if (!msg->get_payload(msg, PLV2_FRAGMENT))
                   1278:        {
                   1279:                return SUCCESS;
                   1280:        }
                   1281:        if (!*defrag)
                   1282:        {
                   1283:                *defrag = message_create_defrag(msg);
                   1284:                if (!*defrag)
                   1285:                {
                   1286:                        return FAILED;
                   1287:                }
                   1288:        }
                   1289:        status = (*defrag)->add_fragment(*defrag, msg);
                   1290:        if (status == SUCCESS)
                   1291:        {
                   1292:                /* reinject the reassembled message */
                   1293:                reassembled = *defrag;
                   1294:                *defrag = NULL;
                   1295:                status = this->ike_sa->process_message(this->ike_sa, reassembled);
                   1296:                if (status == SUCCESS)
                   1297:                {
                   1298:                        /* avoid processing the last fragment */
                   1299:                        status = NEED_MORE;
                   1300:                }
                   1301:                reassembled->destroy(reassembled);
                   1302:        }
                   1303:        return status;
                   1304: }
                   1305: 
                   1306: /**
                   1307:  * Send a notify back to the sender
                   1308:  */
                   1309: static void send_notify_response(private_task_manager_t *this,
                   1310:                                                                 message_t *request, notify_type_t type,
                   1311:                                                                 chunk_t data)
                   1312: {
                   1313:        message_t *response;
                   1314:        packet_t *packet;
                   1315:        host_t *me, *other;
                   1316: 
                   1317:        response = message_create(IKEV2_MAJOR_VERSION, IKEV2_MINOR_VERSION);
                   1318:        response->set_exchange_type(response, request->get_exchange_type(request));
                   1319:        response->set_request(response, FALSE);
                   1320:        response->set_message_id(response, request->get_message_id(request));
                   1321:        response->add_notify(response, FALSE, type, data);
                   1322:        me = this->ike_sa->get_my_host(this->ike_sa);
                   1323:        if (me->is_anyaddr(me))
                   1324:        {
                   1325:                me = request->get_destination(request);
                   1326:                this->ike_sa->set_my_host(this->ike_sa, me->clone(me));
                   1327:        }
                   1328:        other = this->ike_sa->get_other_host(this->ike_sa);
                   1329:        if (other->is_anyaddr(other))
                   1330:        {
                   1331:                other = request->get_source(request);
                   1332:                this->ike_sa->set_other_host(this->ike_sa, other->clone(other));
                   1333:        }
                   1334:        response->set_source(response, me->clone(me));
                   1335:        response->set_destination(response, other->clone(other));
                   1336:        if (this->ike_sa->generate_message(this->ike_sa, response,
                   1337:                                                                           &packet) == SUCCESS)
                   1338:        {
                   1339:                charon->sender->send(charon->sender, packet);
                   1340:        }
                   1341:        response->destroy(response);
                   1342: }
                   1343: 
                   1344: /**
                   1345:  * Send an INVALID_SYNTAX notify and destroy the IKE_SA for authenticated
                   1346:  * messages.
                   1347:  */
                   1348: static status_t send_invalid_syntax(private_task_manager_t *this,
                   1349:                                                                        message_t *msg)
                   1350: {
                   1351:        send_notify_response(this, msg, INVALID_SYNTAX, chunk_empty);
                   1352:        incr_mid(this, FALSE);
                   1353: 
                   1354:        /* IKE_SA_INIT is currently the only type the parser accepts unprotected,
                   1355:         * don't destroy the IKE_SA if such a message is invalid */
                   1356:        if (msg->get_exchange_type(msg) == IKE_SA_INIT)
                   1357:        {
                   1358:                return FAILED;
                   1359:        }
                   1360:        return DESTROY_ME;
                   1361: }
                   1362: 
                   1363: /**
                   1364:  * Parse the given message and verify that it is valid.
                   1365:  */
                   1366: static status_t parse_message(private_task_manager_t *this, message_t *msg)
                   1367: {
                   1368:        status_t parse_status, status;
                   1369:        uint8_t type = 0;
                   1370: 
                   1371:        parse_status = msg->parse_body(msg, this->ike_sa->get_keymat(this->ike_sa));
                   1372: 
                   1373:        if (parse_status == SUCCESS)
                   1374:        {       /* check for unsupported critical payloads */
                   1375:                enumerator_t *enumerator;
                   1376:                unknown_payload_t *unknown;
                   1377:                payload_t *payload;
                   1378: 
                   1379:                enumerator = msg->create_payload_enumerator(msg);
                   1380:                while (enumerator->enumerate(enumerator, &payload))
                   1381:                {
                   1382:                        if (payload->get_type(payload) == PL_UNKNOWN)
                   1383:                        {
                   1384:                                unknown = (unknown_payload_t*)payload;
                   1385:                                if (unknown->is_critical(unknown))
                   1386:                                {
                   1387:                                        type = unknown->get_type(unknown);
                   1388:                                        DBG1(DBG_ENC, "payload type %N is not supported, "
                   1389:                                                 "but payload is critical!", payload_type_names, type);
                   1390:                                        parse_status = NOT_SUPPORTED;
                   1391:                                        break;
                   1392:                                }
                   1393:                        }
                   1394:                }
                   1395:                enumerator->destroy(enumerator);
                   1396:        }
                   1397: 
                   1398:        status = parse_status;
                   1399: 
                   1400:        if (parse_status != SUCCESS)
                   1401:        {
                   1402:                bool is_request = msg->get_request(msg);
                   1403: 
                   1404:                switch (parse_status)
                   1405:                {
                   1406:                        case NOT_SUPPORTED:
                   1407:                                DBG1(DBG_IKE, "critical unknown payloads found");
                   1408:                                if (is_request)
                   1409:                                {
                   1410:                                        send_notify_response(this, msg,
                   1411:                                                                                 UNSUPPORTED_CRITICAL_PAYLOAD,
                   1412:                                                                                 chunk_from_thing(type));
                   1413:                                        incr_mid(this, FALSE);
                   1414:                                }
                   1415:                                break;
                   1416:                        case PARSE_ERROR:
                   1417:                                DBG1(DBG_IKE, "message parsing failed");
                   1418:                                if (is_request)
                   1419:                                {
                   1420:                                        status = send_invalid_syntax(this, msg);
                   1421:                                }
                   1422:                                break;
                   1423:                        case VERIFY_ERROR:
                   1424:                                DBG1(DBG_IKE, "message verification failed");
                   1425:                                if (is_request)
                   1426:                                {
                   1427:                                        status = send_invalid_syntax(this, msg);
                   1428:                                }
                   1429:                                break;
                   1430:                        case FAILED:
                   1431:                                DBG1(DBG_IKE, "integrity check failed");
                   1432:                                /* ignored */
                   1433:                                break;
                   1434:                        case INVALID_STATE:
                   1435:                                DBG1(DBG_IKE, "found encrypted message, but no keys available");
                   1436:                        default:
                   1437:                                break;
                   1438:                }
                   1439:                DBG1(DBG_IKE, "%N %s with message ID %d processing failed",
                   1440:                         exchange_type_names, msg->get_exchange_type(msg),
                   1441:                         is_request ? "request" : "response",
                   1442:                         msg->get_message_id(msg));
                   1443: 
                   1444:                charon->bus->alert(charon->bus, ALERT_PARSE_ERROR_BODY, msg,
                   1445:                                                   parse_status);
                   1446: 
                   1447:                switch (this->ike_sa->get_state(this->ike_sa))
                   1448:                {
                   1449:                        case IKE_CREATED:
                   1450:                                /* invalid initiation attempt, close SA */
                   1451:                                status = DESTROY_ME;
                   1452:                                break;
                   1453:                        case IKE_CONNECTING:
                   1454:                        case IKE_REKEYED:
                   1455:                                /* don't trigger updown event in these states */
                   1456:                                break;
                   1457:                        default:
                   1458:                                if (status == DESTROY_ME)
                   1459:                                {
                   1460:                                        charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
                   1461:                                }
                   1462:                                break;
                   1463:                }
                   1464:        }
                   1465:        return status;
                   1466: }
                   1467: 
                   1468: /**
                   1469:  * Check if a message with message ID 0 looks like it is used to synchronize
                   1470:  * the message IDs.
                   1471:  */
                   1472: static bool looks_like_mid_sync(private_task_manager_t *this, message_t *msg,
                   1473:                                                                bool strict)
                   1474: {
                   1475:        enumerator_t *enumerator;
                   1476:        notify_payload_t *notify;
                   1477:        payload_t *payload;
                   1478:        bool found = FALSE, other = FALSE;
                   1479: 
                   1480:        if (msg->get_exchange_type(msg) == INFORMATIONAL)
                   1481:        {
                   1482:                enumerator = msg->create_payload_enumerator(msg);
                   1483:                while (enumerator->enumerate(enumerator, &payload))
                   1484:                {
                   1485:                        if (payload->get_type(payload) == PLV2_NOTIFY)
                   1486:                        {
                   1487:                                notify = (notify_payload_t*)payload;
                   1488:                                switch (notify->get_notify_type(notify))
                   1489:                                {
                   1490:                                        case IKEV2_MESSAGE_ID_SYNC:
                   1491:                                        case IPSEC_REPLAY_COUNTER_SYNC:
                   1492:                                                found = TRUE;
                   1493:                                                continue;
                   1494:                                        default:
                   1495:                                                break;
                   1496:                                }
                   1497:                        }
                   1498:                        if (strict)
                   1499:                        {
                   1500:                                other = TRUE;
                   1501:                                break;
                   1502:                        }
                   1503:                }
                   1504:                enumerator->destroy(enumerator);
                   1505:        }
                   1506:        return found && !other;
                   1507: }
                   1508: 
                   1509: /**
                   1510:  * Check whether we should reject the given request message
                   1511:  */
                   1512: static inline bool reject_request(private_task_manager_t *this,
                   1513:                                                                  message_t *msg)
                   1514: {
                   1515:        ike_sa_state_t state;
                   1516:        exchange_type_t type;
                   1517:        ike_sa_id_t *ike_sa_id;
                   1518:        bool reject = FALSE;
                   1519: 
                   1520:        state = this->ike_sa->get_state(this->ike_sa);
                   1521:        type = msg->get_exchange_type(msg);
                   1522: 
                   1523:        /* reject initial messages if not received in specific states */
                   1524:        switch (type)
                   1525:        {
                   1526:                case IKE_SA_INIT:
                   1527:                        reject = state != IKE_CREATED;
                   1528:                        break;
                   1529:                case IKE_AUTH:
                   1530:                        reject = state != IKE_CONNECTING;
                   1531:                        break;
                   1532:                default:
                   1533:                        break;
                   1534:        }
                   1535: 
                   1536:        if (!reject)
                   1537:        {
                   1538:                switch (state)
                   1539:                {
                   1540:                        /* after rekeying we only expect a DELETE in an INFORMATIONAL */
                   1541:                        case IKE_REKEYED:
                   1542:                                reject = type != INFORMATIONAL;
                   1543:                                break;
                   1544:                        /* also reject requests for half-open IKE_SAs as initiator */
                   1545:                        case IKE_CREATED:
                   1546:                        case IKE_CONNECTING:
                   1547:                                ike_sa_id = this->ike_sa->get_id(this->ike_sa);
                   1548:                                reject = ike_sa_id->is_initiator(ike_sa_id);
                   1549:                                break;
                   1550:                        default:
                   1551:                                break;
                   1552:                }
                   1553:        }
                   1554: 
                   1555:        if (reject)
                   1556:        {
                   1557:                DBG1(DBG_IKE, "ignoring %N in IKE_SA state %N", exchange_type_names,
                   1558:                         type, ike_sa_state_names, state);
                   1559:        }
                   1560:        return reject;
                   1561: }
                   1562: /**
                   1563:  * Check if a message with message ID 0 looks like it is used to synchronize
                   1564:  * the message IDs and we are prepared to process it.
                   1565:  *
                   1566:  * Note: This is not called if the responder never sent a message before (i.e.
                   1567:  * we expect MID 0).
                   1568:  */
                   1569: static bool is_mid_sync(private_task_manager_t *this, message_t *msg)
                   1570: {
                   1571:        if (this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED &&
                   1572:                this->ike_sa->supports_extension(this->ike_sa,
                   1573:                                                                                 EXT_IKE_MESSAGE_ID_SYNC))
                   1574:        {
                   1575:                return looks_like_mid_sync(this, msg, TRUE);
                   1576:        }
                   1577:        return FALSE;
                   1578: }
                   1579: 
                   1580: METHOD(task_manager_t, process_message, status_t,
                   1581:        private_task_manager_t *this, message_t *msg)
                   1582: {
                   1583:        host_t *me, *other;
                   1584:        status_t status;
                   1585:        uint32_t mid;
                   1586:        bool schedule_delete_job = FALSE;
                   1587: 
                   1588:        charon->bus->message(charon->bus, msg, TRUE, FALSE);
                   1589:        status = parse_message(this, msg);
                   1590:        if (status != SUCCESS)
                   1591:        {
                   1592:                return status;
                   1593:        }
                   1594: 
                   1595:        me = msg->get_destination(msg);
                   1596:        other = msg->get_source(msg);
                   1597: 
                   1598:        /* if this IKE_SA is virgin, we check for a config */
                   1599:        if (this->ike_sa->get_ike_cfg(this->ike_sa) == NULL)
                   1600:        {
                   1601:                ike_cfg_t *ike_cfg;
                   1602: 
                   1603:                ike_cfg = charon->backends->get_ike_cfg(charon->backends,
                   1604:                                                                                                me, other, IKEV2);
                   1605:                if (ike_cfg == NULL)
                   1606:                {
                   1607:                        /* no config found for these hosts, destroy */
                   1608:                        DBG1(DBG_IKE, "no IKE config found for %H...%H, sending %N",
                   1609:                                 me, other, notify_type_names, NO_PROPOSAL_CHOSEN);
                   1610:                        send_notify_response(this, msg,
                   1611:                                                                 NO_PROPOSAL_CHOSEN, chunk_empty);
                   1612:                        return DESTROY_ME;
                   1613:                }
                   1614:                this->ike_sa->set_ike_cfg(this->ike_sa, ike_cfg);
                   1615:                ike_cfg->destroy(ike_cfg);
                   1616:                /* add a timeout if peer does not establish it completely */
                   1617:                schedule_delete_job = TRUE;
                   1618:        }
                   1619: 
                   1620:        mid = msg->get_message_id(msg);
                   1621:        if (msg->get_request(msg))
                   1622:        {
                   1623:                if (mid == this->responding.mid || (mid == 0 && is_mid_sync(this, msg)))
                   1624:                {
                   1625:                        if (reject_request(this, msg))
                   1626:                        {
                   1627:                                return FAILED;
                   1628:                        }
                   1629:                        if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE))
                   1630:                        {       /* with MOBIKE, we do no implicit updates */
                   1631:                                this->ike_sa->update_hosts(this->ike_sa, me, other, mid == 1);
                   1632:                        }
                   1633:                        status = handle_fragment(this, &this->responding.defrag, msg);
                   1634:                        if (status != SUCCESS)
                   1635:                        {
                   1636:                                if (status == NEED_MORE)
                   1637:                                {
                   1638:                                        this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND,
                   1639:                                                                                                time_monotonic(NULL));
                   1640:                                }
                   1641:                                return status;
                   1642:                        }
                   1643:                        charon->bus->message(charon->bus, msg, TRUE, TRUE);
                   1644:                        if (msg->get_exchange_type(msg) == EXCHANGE_TYPE_UNDEFINED)
                   1645:                        {       /* ignore messages altered to EXCHANGE_TYPE_UNDEFINED */
                   1646:                                return SUCCESS;
                   1647:                        }
                   1648:                        switch (process_request(this, msg))
                   1649:                        {
                   1650:                                case SUCCESS:
                   1651:                                        this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND,
                   1652:                                                                                                time_monotonic(NULL));
                   1653:                                        this->responding.mid++;
                   1654:                                        break;
                   1655:                                case NEED_MORE:
                   1656:                                        break;
                   1657:                                default:
                   1658:                                        flush(this);
                   1659:                                        return DESTROY_ME;
                   1660:                        }
                   1661:                }
                   1662:                else if ((mid == this->responding.mid - 1) &&
                   1663:                                 array_count(this->responding.packets) &&
                   1664:                                 !(mid == 0 && looks_like_mid_sync(this, msg, FALSE)))
                   1665:                {
                   1666:                        status = handle_fragment(this, &this->responding.defrag, msg);
                   1667:                        if (status != SUCCESS)
                   1668:                        {
                   1669:                                if (status == NEED_MORE)
                   1670:                                {
                   1671:                                        this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND,
                   1672:                                                                                                time_monotonic(NULL));
                   1673:                                }
                   1674:                                return status;
                   1675:                        }
                   1676:                        DBG1(DBG_IKE, "received retransmit of request with ID %d, "
                   1677:                                 "retransmitting response", mid);
                   1678:                        this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND,
                   1679:                                                                                time_monotonic(NULL));
                   1680:                        charon->bus->alert(charon->bus, ALERT_RETRANSMIT_RECEIVE, msg);
                   1681:                        send_packets(this, this->responding.packets,
                   1682:                                                 msg->get_destination(msg), msg->get_source(msg));
                   1683:                }
                   1684:                else
                   1685:                {
                   1686:                        DBG1(DBG_IKE, "received message ID %d, expected %d, ignored",
                   1687:                                 mid, this->responding.mid);
                   1688:                }
                   1689:        }
                   1690:        else
                   1691:        {
                   1692:                if (mid == this->initiating.mid)
                   1693:                {
                   1694:                        if (this->ike_sa->get_state(this->ike_sa) == IKE_CREATED ||
                   1695:                                this->ike_sa->get_state(this->ike_sa) == IKE_CONNECTING ||
                   1696:                                msg->get_exchange_type(msg) != IKE_SA_INIT)
                   1697:                        {       /* only do updates based on verified messages (or initial ones) */
                   1698:                                if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE))
                   1699:                                {       /* with MOBIKE, we do no implicit updates.  we force an
                   1700:                                         * update of the local address on IKE_SA_INIT, but never
                   1701:                                         * for the remote address */
                   1702:                                        this->ike_sa->update_hosts(this->ike_sa, me, NULL, mid == 0);
                   1703:                                        this->ike_sa->update_hosts(this->ike_sa, NULL, other, FALSE);
                   1704:                                }
                   1705:                        }
                   1706:                        status = handle_fragment(this, &this->initiating.defrag, msg);
                   1707:                        if (status != SUCCESS)
                   1708:                        {
                   1709:                                if (status == NEED_MORE)
                   1710:                                {
                   1711:                                        this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND,
                   1712:                                                                                                time_monotonic(NULL));
                   1713:                                }
                   1714:                                return status;
                   1715:                        }
                   1716:                        charon->bus->message(charon->bus, msg, TRUE, TRUE);
                   1717:                        if (msg->get_exchange_type(msg) == EXCHANGE_TYPE_UNDEFINED)
                   1718:                        {       /* ignore messages altered to EXCHANGE_TYPE_UNDEFINED */
                   1719:                                return SUCCESS;
                   1720:                        }
                   1721:                        if (process_response(this, msg) != SUCCESS)
                   1722:                        {
                   1723:                                flush(this);
                   1724:                                return DESTROY_ME;
                   1725:                        }
                   1726:                        this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND,
                   1727:                                                                                time_monotonic(NULL));
                   1728:                }
                   1729:                else
                   1730:                {
                   1731:                        DBG1(DBG_IKE, "received message ID %d, expected %d, ignored",
                   1732:                                 mid, this->initiating.mid);
                   1733:                        return SUCCESS;
                   1734:                }
                   1735:        }
                   1736: 
                   1737:        if (schedule_delete_job)
                   1738:        {
                   1739:                ike_sa_id_t *ike_sa_id;
                   1740:                job_t *job;
                   1741: 
                   1742:                ike_sa_id = this->ike_sa->get_id(this->ike_sa);
                   1743:                job = (job_t*)delete_ike_sa_job_create(ike_sa_id, FALSE);
                   1744:                lib->scheduler->schedule_job(lib->scheduler, job,
                   1745:                                lib->settings->get_int(lib->settings,
                   1746:                                                "%s.half_open_timeout", HALF_OPEN_IKE_SA_TIMEOUT,
                   1747:                                                lib->ns));
                   1748:        }
                   1749:        return SUCCESS;
                   1750: }
                   1751: 
                   1752: METHOD(task_manager_t, queue_task_delayed, void,
                   1753:        private_task_manager_t *this, task_t *task, uint32_t delay)
                   1754: {
                   1755:        queued_task_t *queued;
                   1756:        timeval_t time;
                   1757: 
                   1758:        time_monotonic(&time);
                   1759:        if (delay)
                   1760:        {
                   1761:                job_t *job;
                   1762: 
                   1763:                DBG2(DBG_IKE, "queueing %N task (delayed by %us)", task_type_names,
                   1764:                         task->get_type(task), delay);
                   1765:                time.tv_sec += delay;
                   1766: 
                   1767:                job = (job_t*)initiate_tasks_job_create(
                   1768:                                                                                        this->ike_sa->get_id(this->ike_sa));
                   1769:                lib->scheduler->schedule_job_tv(lib->scheduler, job, time);
                   1770:        }
                   1771:        else
                   1772:        {
                   1773:                DBG2(DBG_IKE, "queueing %N task", task_type_names,
                   1774:                         task->get_type(task));
                   1775:        }
                   1776:        INIT(queued,
                   1777:                .task = task,
                   1778:                .time = time,
                   1779:        );
                   1780:        array_insert(this->queued_tasks, ARRAY_TAIL, queued);
                   1781: }
                   1782: 
                   1783: METHOD(task_manager_t, queue_task, void,
                   1784:        private_task_manager_t *this, task_t *task)
                   1785: {
                   1786:        queue_task_delayed(this, task, 0);
                   1787: }
                   1788: 
                   1789: /**
                   1790:  * Check if a given task has been queued already
                   1791:  */
                   1792: static bool has_queued(private_task_manager_t *this, task_type_t type)
                   1793: {
                   1794:        enumerator_t *enumerator;
                   1795:        bool found = FALSE;
                   1796:        queued_task_t *queued;
                   1797: 
                   1798:        enumerator = array_create_enumerator(this->queued_tasks);
                   1799:        while (enumerator->enumerate(enumerator, &queued))
                   1800:        {
                   1801:                if (queued->task->get_type(queued->task) == type)
                   1802:                {
                   1803:                        found = TRUE;
                   1804:                        break;
                   1805:                }
                   1806:        }
                   1807:        enumerator->destroy(enumerator);
                   1808:        return found;
                   1809: }
                   1810: 
                   1811: METHOD(task_manager_t, queue_ike, void,
                   1812:        private_task_manager_t *this)
                   1813: {
                   1814:        if (!has_queued(this, TASK_IKE_VENDOR))
                   1815:        {
                   1816:                queue_task(this, (task_t*)ike_vendor_create(this->ike_sa, TRUE));
                   1817:        }
                   1818:        if (!has_queued(this, TASK_IKE_INIT))
                   1819:        {
                   1820:                queue_task(this, (task_t*)ike_init_create(this->ike_sa, TRUE, NULL));
                   1821:        }
                   1822:        if (!has_queued(this, TASK_IKE_NATD))
                   1823:        {
                   1824:                queue_task(this, (task_t*)ike_natd_create(this->ike_sa, TRUE));
                   1825:        }
                   1826:        if (!has_queued(this, TASK_IKE_CERT_PRE))
                   1827:        {
                   1828:                queue_task(this, (task_t*)ike_cert_pre_create(this->ike_sa, TRUE));
                   1829:        }
                   1830:        if (!has_queued(this, TASK_IKE_AUTH))
                   1831:        {
                   1832:                queue_task(this, (task_t*)ike_auth_create(this->ike_sa, TRUE));
                   1833:        }
                   1834:        if (!has_queued(this, TASK_IKE_CERT_POST))
                   1835:        {
                   1836:                queue_task(this, (task_t*)ike_cert_post_create(this->ike_sa, TRUE));
                   1837:        }
                   1838:        if (!has_queued(this, TASK_IKE_CONFIG))
                   1839:        {
                   1840:                queue_task(this, (task_t*)ike_config_create(this->ike_sa, TRUE));
                   1841:        }
                   1842:        if (!has_queued(this, TASK_IKE_AUTH_LIFETIME))
                   1843:        {
                   1844:                queue_task(this, (task_t*)ike_auth_lifetime_create(this->ike_sa, TRUE));
                   1845:        }
                   1846:        if (!has_queued(this, TASK_IKE_MOBIKE))
                   1847:        {
                   1848:                peer_cfg_t *peer_cfg;
                   1849: 
                   1850:                peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
                   1851:                if (peer_cfg->use_mobike(peer_cfg))
                   1852:                {
                   1853:                        queue_task(this, (task_t*)ike_mobike_create(this->ike_sa, TRUE));
                   1854:                }
                   1855:        }
                   1856: #ifdef ME
                   1857:        if (!has_queued(this, TASK_IKE_ME))
                   1858:        {
                   1859:                queue_task(this, (task_t*)ike_me_create(this->ike_sa, TRUE));
                   1860:        }
                   1861: #endif /* ME */
                   1862: }
                   1863: 
                   1864: METHOD(task_manager_t, queue_ike_rekey, void,
                   1865:        private_task_manager_t *this)
                   1866: {
                   1867:        queue_task(this, (task_t*)ike_rekey_create(this->ike_sa, TRUE));
                   1868: }
                   1869: 
                   1870: /**
                   1871:  * Start reauthentication using make-before-break
                   1872:  */
                   1873: static void trigger_mbb_reauth(private_task_manager_t *this)
                   1874: {
                   1875:        enumerator_t *enumerator;
                   1876:        child_sa_t *child_sa;
                   1877:        child_cfg_t *cfg;
                   1878:        peer_cfg_t *peer;
                   1879:        ike_sa_t *new;
                   1880:        host_t *host;
                   1881:        queued_task_t *queued;
                   1882:        bool children = FALSE;
                   1883: 
                   1884:        new = charon->ike_sa_manager->checkout_new(charon->ike_sa_manager,
                   1885:                                                                this->ike_sa->get_version(this->ike_sa), TRUE);
                   1886:        if (!new)
                   1887:        {       /* shouldn't happen */
                   1888:                return;
                   1889:        }
                   1890: 
                   1891:        peer = this->ike_sa->get_peer_cfg(this->ike_sa);
                   1892:        new->set_peer_cfg(new, peer);
                   1893:        host = this->ike_sa->get_other_host(this->ike_sa);
                   1894:        new->set_other_host(new, host->clone(host));
                   1895:        host = this->ike_sa->get_my_host(this->ike_sa);
                   1896:        new->set_my_host(new, host->clone(host));
                   1897:        enumerator = this->ike_sa->create_virtual_ip_enumerator(this->ike_sa, TRUE);
                   1898:        while (enumerator->enumerate(enumerator, &host))
                   1899:        {
                   1900:                new->add_virtual_ip(new, TRUE, host);
                   1901:        }
                   1902:        enumerator->destroy(enumerator);
                   1903: 
                   1904:        enumerator = this->ike_sa->create_child_sa_enumerator(this->ike_sa);
                   1905:        while (enumerator->enumerate(enumerator, &child_sa))
                   1906:        {
                   1907:                child_create_t *child_create;
                   1908: 
                   1909:                switch (child_sa->get_state(child_sa))
                   1910:                {
                   1911:                        case CHILD_REKEYED:
                   1912:                        case CHILD_DELETED:
                   1913:                                /* ignore CHILD_SAs in these states */
                   1914:                                continue;
                   1915:                        default:
                   1916:                                break;
                   1917:                }
                   1918:                cfg = child_sa->get_config(child_sa);
                   1919:                child_create = child_create_create(new, cfg->get_ref(cfg),
                   1920:                                                                                   FALSE, NULL, NULL);
                   1921:                child_create->use_reqid(child_create, child_sa->get_reqid(child_sa));
                   1922:                child_create->use_marks(child_create,
                   1923:                                                                child_sa->get_mark(child_sa, TRUE).value,
                   1924:                                                                child_sa->get_mark(child_sa, FALSE).value);
                   1925:                /* interface IDs are not migrated as the new CHILD_SAs on old and new
                   1926:                 * IKE_SA go though regular updown events */
                   1927:                new->queue_task(new, &child_create->task);
                   1928:                children = TRUE;
                   1929:        }
                   1930:        enumerator->destroy(enumerator);
                   1931: 
                   1932:        enumerator = array_create_enumerator(this->queued_tasks);
                   1933:        while (enumerator->enumerate(enumerator, &queued))
                   1934:        {
                   1935:                if (queued->task->get_type(queued->task) == TASK_CHILD_CREATE)
                   1936:                {
                   1937:                        queued->task->migrate(queued->task, new);
                   1938:                        new->queue_task(new, queued->task);
                   1939:                        array_remove_at(this->queued_tasks, enumerator);
                   1940:                        free(queued);
                   1941:                        children = TRUE;
                   1942:                }
                   1943:        }
                   1944:        enumerator->destroy(enumerator);
                   1945: 
                   1946:        if (!children
                   1947: #ifdef ME
                   1948:                /* allow reauth of mediation connections without CHILD_SAs */
                   1949:                && !peer->is_mediation(peer)
                   1950: #endif /* ME */
                   1951:                )
                   1952:        {
                   1953:                charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, new);
                   1954:                DBG1(DBG_IKE, "unable to reauthenticate IKE_SA, no CHILD_SA "
                   1955:                         "to recreate");
                   1956:                return;
                   1957:        }
                   1958: 
                   1959:        /* suspend online revocation checking until the SA is established */
                   1960:        new->set_condition(new, COND_ONLINE_VALIDATION_SUSPENDED, TRUE);
                   1961: 
                   1962:        if (new->initiate(new, NULL, 0, NULL, NULL) != DESTROY_ME)
                   1963:        {
                   1964:                new->queue_task(new, (task_t*)ike_verify_peer_cert_create(new));
                   1965:                new->queue_task(new, (task_t*)ike_reauth_complete_create(new,
                   1966:                                                                                this->ike_sa->get_id(this->ike_sa)));
                   1967:                charon->ike_sa_manager->checkin(charon->ike_sa_manager, new);
                   1968:        }
                   1969:        else
                   1970:        {
                   1971:                charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, new);
                   1972:                DBG1(DBG_IKE, "reauthenticating IKE_SA failed");
                   1973:        }
                   1974:        charon->bus->set_sa(charon->bus, this->ike_sa);
                   1975: }
                   1976: 
                   1977: METHOD(task_manager_t, queue_ike_reauth, void,
                   1978:        private_task_manager_t *this)
                   1979: {
                   1980:        if (this->make_before_break)
                   1981:        {
                   1982:                return trigger_mbb_reauth(this);
                   1983:        }
                   1984:        queue_task(this, (task_t*)ike_reauth_create(this->ike_sa));
                   1985: }
                   1986: 
                   1987: METHOD(task_manager_t, queue_ike_delete, void,
                   1988:        private_task_manager_t *this)
                   1989: {
                   1990:        queue_task(this, (task_t*)ike_delete_create(this->ike_sa, TRUE));
                   1991: }
                   1992: 
                   1993: /**
                   1994:  * There is no need to queue more than one mobike task, so this either returns
                   1995:  * an already queued task or queues one if there is none yet.
                   1996:  */
                   1997: static ike_mobike_t *queue_mobike_task(private_task_manager_t *this)
                   1998: {
                   1999:        enumerator_t *enumerator;
                   2000:        queued_task_t *queued;
                   2001:        ike_mobike_t *mobike = NULL;
                   2002: 
                   2003:        enumerator = array_create_enumerator(this->queued_tasks);
                   2004:        while (enumerator->enumerate(enumerator, &queued))
                   2005:        {
                   2006:                if (queued->task->get_type(queued->task) == TASK_IKE_MOBIKE)
                   2007:                {
                   2008:                        mobike = (ike_mobike_t*)queued->task;
                   2009:                        break;
                   2010:                }
                   2011:        }
                   2012:        enumerator->destroy(enumerator);
                   2013: 
                   2014:        if (!mobike)
                   2015:        {
                   2016:                mobike = ike_mobike_create(this->ike_sa, TRUE);
                   2017:                queue_task(this, &mobike->task);
                   2018:        }
                   2019:        return mobike;
                   2020: }
                   2021: 
                   2022: METHOD(task_manager_t, queue_mobike, void,
                   2023:        private_task_manager_t *this, bool roam, bool address)
                   2024: {
                   2025:        ike_mobike_t *mobike;
                   2026: 
                   2027:        mobike = queue_mobike_task(this);
                   2028:        if (roam)
                   2029:        {
                   2030:                enumerator_t *enumerator;
                   2031:                task_t *current;
                   2032: 
                   2033:                mobike->roam(mobike, address);
                   2034: 
                   2035:                /* enable path probing for a currently active MOBIKE task.  This might
                   2036:                 * not be the case if an address appeared on a new interface while the
                   2037:                 * current address is not working but has not yet disappeared. */
                   2038:                enumerator = array_create_enumerator(this->active_tasks);
                   2039:                while (enumerator->enumerate(enumerator, &current))
                   2040:                {
                   2041:                        if (current->get_type(current) == TASK_IKE_MOBIKE)
                   2042:                        {
                   2043:                                ike_mobike_t *active = (ike_mobike_t*)current;
                   2044:                                active->enable_probing(active);
                   2045:                                break;
                   2046:                        }
                   2047:                }
                   2048:                enumerator->destroy(enumerator);
                   2049:        }
                   2050:        else
                   2051:        {
                   2052:                mobike->addresses(mobike);
                   2053:        }
                   2054: }
                   2055: 
                   2056: METHOD(task_manager_t, queue_dpd, void,
                   2057:        private_task_manager_t *this)
                   2058: {
                   2059:        ike_mobike_t *mobike;
                   2060: 
                   2061:        if (this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE))
                   2062:        {
                   2063: #ifdef ME
                   2064:                peer_cfg_t *cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
                   2065:                if (cfg->get_peer_id(cfg) ||
                   2066:                        this->ike_sa->has_condition(this->ike_sa, COND_ORIGINAL_INITIATOR))
                   2067: #else
                   2068:                if (this->ike_sa->has_condition(this->ike_sa, COND_ORIGINAL_INITIATOR))
                   2069: #endif
                   2070:                {
                   2071:                        /* use mobike enabled DPD to detect NAT mapping changes */
                   2072:                        mobike = queue_mobike_task(this);
                   2073:                        mobike->dpd(mobike);
                   2074:                        return;
                   2075:                }
                   2076:        }
                   2077:        queue_task(this, (task_t*)ike_dpd_create(TRUE));
                   2078: }
                   2079: 
                   2080: METHOD(task_manager_t, queue_child, void,
                   2081:        private_task_manager_t *this, child_cfg_t *cfg, uint32_t reqid,
                   2082:        traffic_selector_t *tsi, traffic_selector_t *tsr)
                   2083: {
                   2084:        child_create_t *task;
                   2085: 
                   2086:        task = child_create_create(this->ike_sa, cfg, FALSE, tsi, tsr);
                   2087:        if (reqid)
                   2088:        {
                   2089:                task->use_reqid(task, reqid);
                   2090:        }
                   2091:        queue_task(this, &task->task);
                   2092: }
                   2093: 
                   2094: METHOD(task_manager_t, queue_child_rekey, void,
                   2095:        private_task_manager_t *this, protocol_id_t protocol, uint32_t spi)
                   2096: {
                   2097:        queue_task(this, (task_t*)child_rekey_create(this->ike_sa, protocol, spi));
                   2098: }
                   2099: 
                   2100: METHOD(task_manager_t, queue_child_delete, void,
                   2101:        private_task_manager_t *this, protocol_id_t protocol, uint32_t spi,
                   2102:        bool expired)
                   2103: {
                   2104:        queue_task(this, (task_t*)child_delete_create(this->ike_sa,
                   2105:                                                                                                  protocol, spi, expired));
                   2106: }
                   2107: 
                   2108: METHOD(task_manager_t, adopt_tasks, void,
                   2109:        private_task_manager_t *this, task_manager_t *other_public)
                   2110: {
                   2111:        private_task_manager_t *other = (private_task_manager_t*)other_public;
                   2112:        queued_task_t *queued;
                   2113:        timeval_t now;
                   2114: 
                   2115:        time_monotonic(&now);
                   2116: 
                   2117:        /* move queued tasks from other to this */
                   2118:        while (array_remove(other->queued_tasks, ARRAY_TAIL, &queued))
                   2119:        {
                   2120:                DBG2(DBG_IKE, "migrating %N task", task_type_names,
                   2121:                         queued->task->get_type(queued->task));
                   2122:                queued->task->migrate(queued->task, this->ike_sa);
                   2123:                /* don't delay tasks on the new IKE_SA */
                   2124:                queued->time = now;
                   2125:                array_insert(this->queued_tasks, ARRAY_HEAD, queued);
                   2126:        }
                   2127: }
                   2128: 
                   2129: METHOD(task_manager_t, busy, bool,
                   2130:        private_task_manager_t *this)
                   2131: {
                   2132:        return array_count(this->active_tasks) > 0;
                   2133: }
                   2134: 
                   2135: METHOD(task_manager_t, reset, void,
                   2136:        private_task_manager_t *this, uint32_t initiate, uint32_t respond)
                   2137: {
                   2138:        enumerator_t *enumerator;
                   2139:        queued_task_t *queued;
                   2140:        task_t *task;
                   2141:        timeval_t now;
                   2142: 
                   2143:        /* reset message counters and retransmit packets */
                   2144:        clear_packets(this->responding.packets);
                   2145:        clear_packets(this->initiating.packets);
                   2146:        DESTROY_IF(this->responding.defrag);
                   2147:        DESTROY_IF(this->initiating.defrag);
                   2148:        this->responding.defrag = NULL;
                   2149:        this->initiating.defrag = NULL;
                   2150:        if (initiate != UINT_MAX)
                   2151:        {
                   2152:                this->initiating.mid = initiate;
                   2153:        }
                   2154:        if (respond != UINT_MAX)
                   2155:        {
                   2156:                this->responding.mid = respond;
                   2157:        }
                   2158:        this->initiating.type = EXCHANGE_TYPE_UNDEFINED;
                   2159: 
                   2160:        time_monotonic(&now);
                   2161:        /* reset queued tasks */
                   2162:        enumerator = array_create_enumerator(this->queued_tasks);
                   2163:        while (enumerator->enumerate(enumerator, &queued))
                   2164:        {
                   2165:                queued->time = now;
                   2166:                queued->task->migrate(queued->task, this->ike_sa);
                   2167:        }
                   2168:        enumerator->destroy(enumerator);
                   2169: 
                   2170:        /* reset active tasks */
                   2171:        while (array_remove(this->active_tasks, ARRAY_TAIL, &task))
                   2172:        {
                   2173:                task->migrate(task, this->ike_sa);
                   2174:                INIT(queued,
                   2175:                        .task = task,
                   2176:                        .time = now,
                   2177:                );
                   2178:                array_insert(this->queued_tasks, ARRAY_HEAD, queued);
                   2179:        }
                   2180: 
                   2181:        this->reset = TRUE;
                   2182: }
                   2183: 
                   2184: /**
                   2185:  * Data for a task queue enumerator
                   2186:  */
                   2187: typedef struct {
                   2188:        enumerator_t public;
                   2189:        task_queue_t queue;
                   2190:        enumerator_t *inner;
                   2191:        queued_task_t *queued;
                   2192: } task_enumerator_t;
                   2193: 
                   2194: METHOD(enumerator_t, task_enumerator_destroy, void,
                   2195:        task_enumerator_t *this)
                   2196: {
                   2197:        this->inner->destroy(this->inner);
                   2198:        free(this);
                   2199: }
                   2200: 
                   2201: METHOD(enumerator_t, task_enumerator_enumerate, bool,
                   2202:        task_enumerator_t *this, va_list args)
                   2203: {
                   2204:        task_t **task;
                   2205: 
                   2206:        VA_ARGS_VGET(args, task);
                   2207:        if (this->queue == TASK_QUEUE_QUEUED)
                   2208:        {
                   2209:                if (this->inner->enumerate(this->inner, &this->queued))
                   2210:                {
                   2211:                        *task = this->queued->task;
                   2212:                        return TRUE;
                   2213:                }
                   2214:        }
                   2215:        else if (this->inner->enumerate(this->inner, task))
                   2216:        {
                   2217:                return TRUE;
                   2218:        }
                   2219:        return FALSE;
                   2220: }
                   2221: 
                   2222: METHOD(task_manager_t, create_task_enumerator, enumerator_t*,
                   2223:        private_task_manager_t *this, task_queue_t queue)
                   2224: {
                   2225:        task_enumerator_t *enumerator;
                   2226: 
                   2227:        INIT(enumerator,
                   2228:                .public = {
                   2229:                        .enumerate = enumerator_enumerate_default,
                   2230:                        .venumerate = _task_enumerator_enumerate,
                   2231:                        .destroy = _task_enumerator_destroy,
                   2232:                },
                   2233:                .queue = queue,
                   2234:        );
                   2235:        switch (queue)
                   2236:        {
                   2237:                case TASK_QUEUE_ACTIVE:
                   2238:                        enumerator->inner = array_create_enumerator(this->active_tasks);
                   2239:                        break;
                   2240:                case TASK_QUEUE_PASSIVE:
                   2241:                        enumerator->inner = array_create_enumerator(this->passive_tasks);
                   2242:                        break;
                   2243:                case TASK_QUEUE_QUEUED:
                   2244:                        enumerator->inner = array_create_enumerator(this->queued_tasks);
                   2245:                        break;
                   2246:                default:
                   2247:                        enumerator->inner = enumerator_create_empty();
                   2248:                        break;
                   2249:        }
                   2250:        return &enumerator->public;
                   2251: }
                   2252: 
                   2253: METHOD(task_manager_t, remove_task, void,
                   2254:        private_task_manager_t *this, enumerator_t *enumerator_public)
                   2255: {
                   2256:        task_enumerator_t *enumerator = (task_enumerator_t*)enumerator_public;
                   2257: 
                   2258:        switch (enumerator->queue)
                   2259:        {
                   2260:                case TASK_QUEUE_ACTIVE:
                   2261:                        array_remove_at(this->active_tasks, enumerator->inner);
                   2262:                        break;
                   2263:                case TASK_QUEUE_PASSIVE:
                   2264:                        array_remove_at(this->passive_tasks, enumerator->inner);
                   2265:                        break;
                   2266:                case TASK_QUEUE_QUEUED:
                   2267:                        array_remove_at(this->queued_tasks, enumerator->inner);
                   2268:                        free(enumerator->queued);
                   2269:                        enumerator->queued = NULL;
                   2270:                        break;
                   2271:                default:
                   2272:                        break;
                   2273:        }
                   2274: }
                   2275: 
                   2276: METHOD(task_manager_t, destroy, void,
                   2277:        private_task_manager_t *this)
                   2278: {
                   2279:        flush(this);
                   2280: 
                   2281:        array_destroy(this->active_tasks);
                   2282:        array_destroy(this->queued_tasks);
                   2283:        array_destroy(this->passive_tasks);
                   2284: 
                   2285:        clear_packets(this->responding.packets);
                   2286:        array_destroy(this->responding.packets);
                   2287:        clear_packets(this->initiating.packets);
                   2288:        array_destroy(this->initiating.packets);
                   2289:        DESTROY_IF(this->responding.defrag);
                   2290:        DESTROY_IF(this->initiating.defrag);
                   2291:        free(this);
                   2292: }
                   2293: 
                   2294: /*
                   2295:  * see header file
                   2296:  */
                   2297: task_manager_v2_t *task_manager_v2_create(ike_sa_t *ike_sa)
                   2298: {
                   2299:        private_task_manager_t *this;
                   2300: 
                   2301:        INIT(this,
                   2302:                .public = {
                   2303:                        .task_manager = {
                   2304:                                .process_message = _process_message,
                   2305:                                .queue_task = _queue_task,
                   2306:                                .queue_task_delayed = _queue_task_delayed,
                   2307:                                .queue_ike = _queue_ike,
                   2308:                                .queue_ike_rekey = _queue_ike_rekey,
                   2309:                                .queue_ike_reauth = _queue_ike_reauth,
                   2310:                                .queue_ike_delete = _queue_ike_delete,
                   2311:                                .queue_mobike = _queue_mobike,
                   2312:                                .queue_child = _queue_child,
                   2313:                                .queue_child_rekey = _queue_child_rekey,
                   2314:                                .queue_child_delete = _queue_child_delete,
                   2315:                                .queue_dpd = _queue_dpd,
                   2316:                                .initiate = _initiate,
                   2317:                                .retransmit = _retransmit,
                   2318:                                .incr_mid = _incr_mid,
                   2319:                                .get_mid = _get_mid,
                   2320:                                .reset = _reset,
                   2321:                                .adopt_tasks = _adopt_tasks,
                   2322:                                .busy = _busy,
                   2323:                                .create_task_enumerator = _create_task_enumerator,
                   2324:                                .remove_task = _remove_task,
                   2325:                                .flush = _flush,
                   2326:                                .flush_queue = _flush_queue,
                   2327:                                .destroy = _destroy,
                   2328:                        },
                   2329:                },
                   2330:                .ike_sa = ike_sa,
                   2331:                .initiating.type = EXCHANGE_TYPE_UNDEFINED,
                   2332:                .queued_tasks = array_create(0, 0),
                   2333:                .active_tasks = array_create(0, 0),
                   2334:                .passive_tasks = array_create(0, 0),
                   2335:                .retransmit_tries = lib->settings->get_int(lib->settings,
                   2336:                                        "%s.retransmit_tries", RETRANSMIT_TRIES, lib->ns),
                   2337:                .retransmit_timeout = lib->settings->get_double(lib->settings,
                   2338:                                        "%s.retransmit_timeout", RETRANSMIT_TIMEOUT, lib->ns),
                   2339:                .retransmit_base = lib->settings->get_double(lib->settings,
                   2340:                                        "%s.retransmit_base", RETRANSMIT_BASE, lib->ns),
                   2341:                .retransmit_jitter = min(lib->settings->get_int(lib->settings,
                   2342:                                        "%s.retransmit_jitter", 0, lib->ns), RETRANSMIT_JITTER_MAX),
                   2343:                .retransmit_limit = lib->settings->get_int(lib->settings,
                   2344:                                        "%s.retransmit_limit", 0, lib->ns) * 1000,
                   2345:                .make_before_break = lib->settings->get_bool(lib->settings,
                   2346:                                        "%s.make_before_break", FALSE, lib->ns),
                   2347:        );
                   2348: 
                   2349:        return &this->public;
                   2350: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>