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

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

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