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

1.1       misho       1: /*
                      2:  * Copyright (C) 2010-2018 Tobias Brunner
                      3:  * Copyright (C) 2007 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 "ike_mobike.h"
                     18: 
                     19: #include <string.h>
                     20: 
                     21: #include <daemon.h>
                     22: #include <sa/ikev2/tasks/ike_natd.h>
                     23: #include <encoding/payloads/notify_payload.h>
                     24: 
                     25: #define COOKIE2_SIZE 16
                     26: #define MAX_ADDITIONAL_ADDRS 8
                     27: 
                     28: typedef struct private_ike_mobike_t private_ike_mobike_t;
                     29: 
                     30: /**
                     31:  * Private members of a ike_mobike_t task.
                     32:  */
                     33: struct private_ike_mobike_t {
                     34: 
                     35:        /**
                     36:         * Public methods and task_t interface.
                     37:         */
                     38:        ike_mobike_t public;
                     39: 
                     40:        /**
                     41:         * Assigned IKE_SA.
                     42:         */
                     43:        ike_sa_t *ike_sa;
                     44: 
                     45:        /**
                     46:         * Are we the initiator?
                     47:         */
                     48:        bool initiator;
                     49: 
                     50:        /**
                     51:         * cookie2 value to verify new addresses
                     52:         */
                     53:        chunk_t cookie2;
                     54: 
                     55:        /**
                     56:         * NAT discovery reusing the TASK_IKE_NATD task
                     57:         */
                     58:        ike_natd_t *natd;
                     59: 
                     60:        /**
                     61:         * use task to update addresses
                     62:         */
                     63:        bool update;
                     64: 
                     65:        /**
                     66:         * do routability check
                     67:         */
                     68:        bool check;
                     69: 
                     70:        /**
                     71:         * include address list update
                     72:         */
                     73:        bool address;
                     74: 
                     75:        /**
                     76:         * additional addresses got updated
                     77:         */
                     78:        bool addresses_updated;
                     79: };
                     80: 
                     81: /**
                     82:  * Check if a newer MOBIKE update task is queued
                     83:  */
                     84: static bool is_newer_update_queued(private_ike_mobike_t *this)
                     85: {
                     86:        enumerator_t *enumerator;
                     87:        private_ike_mobike_t *mobike;
                     88:        task_t *task;
                     89:        bool found = FALSE;
                     90: 
                     91:        enumerator = this->ike_sa->create_task_enumerator(this->ike_sa,
                     92:                                                                                                          TASK_QUEUE_QUEUED);
                     93:        while (enumerator->enumerate(enumerator, &task))
                     94:        {
                     95:                if (task->get_type(task) == TASK_IKE_MOBIKE)
                     96:                {
                     97:                        mobike = (private_ike_mobike_t*)task;
                     98:                        /* a queued check or update might invalidate the results of the
                     99:                         * current task */
                    100:                        found = mobike->check || mobike->update;
                    101:                        break;
                    102:                }
                    103:        }
                    104:        enumerator->destroy(enumerator);
                    105:        return found;
                    106: }
                    107: 
                    108: /**
                    109:  * read notifys from message and evaluate them
                    110:  */
                    111: static void process_payloads(private_ike_mobike_t *this, message_t *message)
                    112: {
                    113:        enumerator_t *enumerator;
                    114:        payload_t *payload;
                    115:        bool first = TRUE;
                    116: 
                    117:        enumerator = message->create_payload_enumerator(message);
                    118:        while (enumerator->enumerate(enumerator, &payload))
                    119:        {
                    120:                int family = AF_INET;
                    121:                notify_payload_t *notify;
                    122:                chunk_t data;
                    123:                host_t *host;
                    124: 
                    125:                if (payload->get_type(payload) != PLV2_NOTIFY)
                    126:                {
                    127:                        continue;
                    128:                }
                    129:                notify = (notify_payload_t*)payload;
                    130:                switch (notify->get_notify_type(notify))
                    131:                {
                    132:                        case MOBIKE_SUPPORTED:
                    133:                        {
                    134:                                peer_cfg_t *peer_cfg;
                    135: 
                    136:                                peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
                    137:                                if (!this->initiator &&
                    138:                                        peer_cfg && !peer_cfg->use_mobike(peer_cfg))
                    139:                                {
                    140:                                        DBG1(DBG_IKE, "peer supports MOBIKE, but disabled in config");
                    141:                                }
                    142:                                else
                    143:                                {
                    144:                                        DBG1(DBG_IKE, "peer supports MOBIKE");
                    145:                                        this->ike_sa->enable_extension(this->ike_sa, EXT_MOBIKE);
                    146:                                }
                    147:                                break;
                    148:                        }
                    149:                        case COOKIE2:
                    150:                        {
                    151:                                chunk_free(&this->cookie2);
                    152:                                this->cookie2 = chunk_clone(notify->get_notification_data(notify));
                    153:                                break;
                    154:                        }
                    155:                        case ADDITIONAL_IP6_ADDRESS:
                    156:                        {
                    157:                                family = AF_INET6;
                    158:                                /* fall through */
                    159:                        }
                    160:                        case ADDITIONAL_IP4_ADDRESS:
                    161:                        {
                    162:                                if (first)
                    163:                                {       /* an ADDITIONAL_*_ADDRESS means replace, so flush once */
                    164:                                        this->ike_sa->clear_peer_addresses(this->ike_sa);
                    165:                                        first = FALSE;
                    166:                                        /* add the peer's current address to the list */
                    167:                                        host = message->get_source(message);
                    168:                                        this->ike_sa->add_peer_address(this->ike_sa,
                    169:                                                                                                   host->clone(host));
                    170:                                }
                    171:                                data = notify->get_notification_data(notify);
                    172:                                host = host_create_from_chunk(family, data, 0);
                    173:                                DBG2(DBG_IKE, "got additional MOBIKE peer address: %H", host);
                    174:                                this->ike_sa->add_peer_address(this->ike_sa, host);
                    175:                                this->addresses_updated = TRUE;
                    176:                                break;
                    177:                        }
                    178:                        case UPDATE_SA_ADDRESSES:
                    179:                        {
                    180:                                this->update = TRUE;
                    181:                                break;
                    182:                        }
                    183:                        case NO_ADDITIONAL_ADDRESSES:
                    184:                        {
                    185:                                this->ike_sa->clear_peer_addresses(this->ike_sa);
                    186:                                /* add the peer's current address to the list */
                    187:                                host = message->get_source(message);
                    188:                                this->ike_sa->add_peer_address(this->ike_sa, host->clone(host));
                    189:                                this->addresses_updated = TRUE;
                    190:                                break;
                    191:                        }
                    192:                        case NAT_DETECTION_SOURCE_IP:
                    193:                        case NAT_DETECTION_DESTINATION_IP:
                    194:                        {
                    195:                                /* NAT check in this MOBIKE exchange, create subtask for it */
                    196:                                if (!this->natd)
                    197:                                {
                    198:                                        this->natd = ike_natd_create(this->ike_sa, this->initiator);
                    199:                                }
                    200:                                break;
                    201:                        }
                    202:                        default:
                    203:                                break;
                    204:                }
                    205:        }
                    206:        enumerator->destroy(enumerator);
                    207: }
                    208: 
                    209: /**
                    210:  * Add ADDITIONAL_*_ADDRESS notifys depending on our address list
                    211:  */
                    212: static void build_address_list(private_ike_mobike_t *this, message_t *message)
                    213: {
                    214:        enumerator_t *enumerator;
                    215:        host_t *host, *me;
                    216:        notify_type_t type;
                    217:        int added = 0;
                    218: 
                    219:        me = this->ike_sa->get_my_host(this->ike_sa);
                    220:        enumerator = charon->kernel->create_address_enumerator(charon->kernel,
                    221:                                                                                                                   ADDR_TYPE_REGULAR);
                    222:        while (enumerator->enumerate(enumerator, (void**)&host))
                    223:        {
                    224:                if (me->ip_equals(me, host))
                    225:                {       /* "ADDITIONAL" means do not include IKE_SAs host */
                    226:                        continue;
                    227:                }
                    228:                switch (host->get_family(host))
                    229:                {
                    230:                        case AF_INET:
                    231:                                type = ADDITIONAL_IP4_ADDRESS;
                    232:                                break;
                    233:                        case AF_INET6:
                    234:                                type = ADDITIONAL_IP6_ADDRESS;
                    235:                                break;
                    236:                        default:
                    237:                                continue;
                    238:                }
                    239:                message->add_notify(message, FALSE, type, host->get_address(host));
                    240:                if (++added >= MAX_ADDITIONAL_ADDRS)
                    241:                {       /* limit number of notifys, some implementations do not like too
                    242:                         * many of them (f.e. strongSwan ;-) */
                    243:                        break;
                    244:                }
                    245:        }
                    246:        if (!added)
                    247:        {
                    248:                message->add_notify(message, FALSE, NO_ADDITIONAL_ADDRESSES, chunk_empty);
                    249:        }
                    250:        enumerator->destroy(enumerator);
                    251: }
                    252: 
                    253: /**
                    254:  * build a cookie and add it to the message
                    255:  */
                    256: static bool build_cookie(private_ike_mobike_t *this, message_t *message)
                    257: {
                    258:        rng_t *rng;
                    259: 
                    260:        chunk_free(&this->cookie2);
                    261:        rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
                    262:        if (!rng || !rng->allocate_bytes(rng, COOKIE2_SIZE, &this->cookie2))
                    263:        {
                    264:                DESTROY_IF(rng);
                    265:                return FALSE;
                    266:        }
                    267:        message->add_notify(message, FALSE, COOKIE2, this->cookie2);
                    268:        rng->destroy(rng);
                    269:        return TRUE;
                    270: }
                    271: 
                    272: /**
                    273:  * update addresses of associated CHILD_SAs
                    274:  */
                    275: static void update_children(private_ike_mobike_t *this)
                    276: {
                    277:        enumerator_t *enumerator;
                    278:        child_sa_t *child_sa;
                    279:        linked_list_t *vips;
                    280:        status_t status;
                    281:        host_t *host;
                    282: 
                    283:        vips = linked_list_create();
                    284: 
                    285:        enumerator = this->ike_sa->create_virtual_ip_enumerator(this->ike_sa, TRUE);
                    286:        while (enumerator->enumerate(enumerator, &host))
                    287:        {
                    288:                vips->insert_last(vips, host);
                    289:        }
                    290:        enumerator->destroy(enumerator);
                    291: 
                    292:        enumerator = this->ike_sa->create_child_sa_enumerator(this->ike_sa);
                    293:        while (enumerator->enumerate(enumerator, (void**)&child_sa))
                    294:        {
                    295:                status = child_sa->update(child_sa,
                    296:                                        this->ike_sa->get_my_host(this->ike_sa),
                    297:                                        this->ike_sa->get_other_host(this->ike_sa), vips,
                    298:                                        this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY));
                    299:                switch (status)
                    300:                {
                    301:                        case NOT_SUPPORTED:
                    302:                                this->ike_sa->rekey_child_sa(this->ike_sa,
                    303:                                                                                         child_sa->get_protocol(child_sa),
                    304:                                                                                         child_sa->get_spi(child_sa, TRUE));
                    305:                                break;
                    306:                        case SUCCESS:
                    307:                                charon->child_sa_manager->remove(charon->child_sa_manager,
                    308:                                                                                                 child_sa);
                    309:                                charon->child_sa_manager->add(charon->child_sa_manager,
                    310:                                                                                          child_sa, this->ike_sa);
                    311:                                break;
                    312:                        default:
                    313:                                break;
                    314:                }
                    315:        }
                    316:        enumerator->destroy(enumerator);
                    317: 
                    318:        vips->destroy(vips);
                    319: }
                    320: 
                    321: /**
                    322:  * Apply the port of the old host, if its ip equals the new, use port otherwise.
                    323:  */
                    324: static void apply_port(host_t *host, host_t *old, uint16_t port, bool local)
                    325: {
                    326:        if (host->ip_equals(host, old))
                    327:        {
                    328:                port = old->get_port(old);
                    329:        }
                    330:        else if (local && port == charon->socket->get_port(charon->socket, FALSE))
                    331:        {
                    332:                port = charon->socket->get_port(charon->socket, TRUE);
                    333:        }
                    334:        else if (!local && port == IKEV2_UDP_PORT)
                    335:        {
                    336:                port = IKEV2_NATT_PORT;
                    337:        }
                    338:        host->set_port(host, port);
                    339: }
                    340: 
                    341: METHOD(ike_mobike_t, transmit, bool,
                    342:           private_ike_mobike_t *this, packet_t *packet)
                    343: {
                    344:        host_t *me, *other, *me_old, *other_old;
                    345:        enumerator_t *enumerator;
                    346:        ike_cfg_t *ike_cfg;
                    347:        packet_t *copy;
                    348:        int family = AF_UNSPEC;
                    349:        bool found = FALSE;
                    350: 
                    351:        me_old = this->ike_sa->get_my_host(this->ike_sa);
                    352:        other_old = this->ike_sa->get_other_host(this->ike_sa);
                    353:        ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
                    354: 
                    355:        if (!this->check)
                    356:        {
                    357:                me = charon->kernel->get_source_addr(charon->kernel, other_old, me_old);
                    358:                if (me)
                    359:                {
                    360:                        if (me->ip_equals(me, me_old))
                    361:                        {
                    362:                                copy = packet->clone(packet);
                    363:                                /* hosts might have been updated by a peer's MOBIKE exchange */
                    364:                                copy->set_source(copy, me_old->clone(me_old));
                    365:                                copy->set_destination(copy, other_old->clone(other_old));
                    366:                                charon->sender->send(charon->sender, copy);
                    367:                                me->destroy(me);
                    368:                                return TRUE;
                    369:                        }
                    370:                        me->destroy(me);
                    371:                }
                    372:                this->check = TRUE;
                    373:        }
                    374: 
                    375:        switch (charon->socket->supported_families(charon->socket))
                    376:        {
                    377:                case SOCKET_FAMILY_IPV4:
                    378:                        family = AF_INET;
                    379:                        break;
                    380:                case SOCKET_FAMILY_IPV6:
                    381:                        family = AF_INET6;
                    382:                        break;
                    383:                case SOCKET_FAMILY_BOTH:
                    384:                case SOCKET_FAMILY_NONE:
                    385:                        break;
                    386:        }
                    387: 
                    388:        enumerator = this->ike_sa->create_peer_address_enumerator(this->ike_sa);
                    389:        while (enumerator->enumerate(enumerator, (void**)&other))
                    390:        {
                    391:                if (family != AF_UNSPEC && other->get_family(other) != family)
                    392:                {
                    393:                        continue;
                    394:                }
                    395:                me = charon->kernel->get_source_addr(charon->kernel, other, NULL);
                    396:                if (me)
                    397:                {
                    398:                        /* reuse port for an active address, 4500 otherwise */
                    399:                        apply_port(me, me_old, ike_cfg->get_my_port(ike_cfg), TRUE);
                    400:                        other = other->clone(other);
                    401:                        apply_port(other, other_old, ike_cfg->get_other_port(ike_cfg), FALSE);
                    402:                        DBG1(DBG_IKE, "checking path %#H - %#H", me, other);
                    403:                        copy = packet->clone(packet);
                    404:                        copy->set_source(copy, me);
                    405:                        copy->set_destination(copy, other);
                    406:                        charon->sender->send(charon->sender, copy);
                    407:                        found = TRUE;
                    408:                }
                    409:        }
                    410:        enumerator->destroy(enumerator);
                    411:        return found;
                    412: }
                    413: 
                    414: METHOD(task_t, build_i, status_t,
                    415:           private_ike_mobike_t *this, message_t *message)
                    416: {
                    417:        if (message->get_exchange_type(message) == IKE_AUTH &&
                    418:                message->get_message_id(message) == 1)
                    419:        {       /* only in first IKE_AUTH */
                    420:                message->add_notify(message, FALSE, MOBIKE_SUPPORTED, chunk_empty);
                    421:                build_address_list(this, message);
                    422:        }
                    423:        else if (message->get_exchange_type(message) == INFORMATIONAL)
                    424:        {
                    425:                host_t *old, *new;
                    426: 
                    427:                /* we check if the existing address is still valid */
                    428:                old = message->get_source(message);
                    429:                new = charon->kernel->get_source_addr(charon->kernel,
                    430:                                                                                message->get_destination(message), old);
                    431:                if (new)
                    432:                {
                    433:                        if (!new->ip_equals(new, old))
                    434:                        {
                    435:                                new->set_port(new, old->get_port(old));
                    436:                                message->set_source(message, new);
                    437:                        }
                    438:                        else
                    439:                        {
                    440:                                new->destroy(new);
                    441:                        }
                    442:                }
                    443:                if (this->update)
                    444:                {
                    445:                        message->add_notify(message, FALSE, UPDATE_SA_ADDRESSES,
                    446:                                                                chunk_empty);
                    447:                        if (!build_cookie(this, message))
                    448:                        {
                    449:                                return FAILED;
                    450:                        }
                    451:                        update_children(this);
                    452:                }
                    453:                if (this->address && !this->check)
                    454:                {
                    455:                        build_address_list(this, message);
                    456:                }
                    457:                if (this->natd)
                    458:                {
                    459:                        this->natd->task.build(&this->natd->task, message);
                    460:                }
                    461:        }
                    462:        return NEED_MORE;
                    463: }
                    464: 
                    465: METHOD(task_t, process_r, status_t,
                    466:           private_ike_mobike_t *this, message_t *message)
                    467: {
                    468:        if (message->get_exchange_type(message) == IKE_AUTH &&
                    469:                message->get_message_id(message) == 1)
                    470:        {       /* only first IKE_AUTH */
                    471:                process_payloads(this, message);
                    472:        }
                    473:        else if (message->get_exchange_type(message) == INFORMATIONAL)
                    474:        {
                    475:                process_payloads(this, message);
                    476:                if (this->update)
                    477:                {
                    478:                        host_t *me, *other;
                    479: 
                    480:                        me = message->get_destination(message);
                    481:                        other = message->get_source(message);
                    482:                        this->ike_sa->set_my_host(this->ike_sa, me->clone(me));
                    483:                        this->ike_sa->set_other_host(this->ike_sa, other->clone(other));
                    484:                }
                    485: 
                    486:                if (this->natd)
                    487:                {
                    488:                        this->natd->task.process(&this->natd->task, message);
                    489:                }
                    490:                if (this->addresses_updated && this->ike_sa->has_condition(this->ike_sa,
                    491:                                                                                                COND_ORIGINAL_INITIATOR))
                    492:                {
                    493:                        host_t *other = message->get_source(message);
                    494:                        host_t *other_old = this->ike_sa->get_other_host(this->ike_sa);
                    495:                        if (!other->equals(other, other_old))
                    496:                        {
                    497:                                DBG1(DBG_IKE, "remote address changed from %H to %H", other_old,
                    498:                                         other);
                    499:                                this->ike_sa->set_other_host(this->ike_sa, other->clone(other));
                    500:                                this->update = TRUE;
                    501:                        }
                    502:                }
                    503:        }
                    504:        return NEED_MORE;
                    505: }
                    506: 
                    507: METHOD(task_t, build_r, status_t,
                    508:           private_ike_mobike_t *this, message_t *message)
                    509: {
                    510:        if (message->get_exchange_type(message) == IKE_AUTH &&
                    511:                this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)
                    512:        {
                    513:                if (this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE))
                    514:                {
                    515:                        message->add_notify(message, FALSE, MOBIKE_SUPPORTED, chunk_empty);
                    516:                        build_address_list(this, message);
                    517:                }
                    518:                return SUCCESS;
                    519:        }
                    520:        else if (message->get_exchange_type(message) == INFORMATIONAL)
                    521:        {
                    522:                if (this->natd)
                    523:                {
                    524:                        this->natd->task.build(&this->natd->task, message);
                    525:                }
                    526:                if (this->cookie2.ptr)
                    527:                {
                    528:                        message->add_notify(message, FALSE, COOKIE2, this->cookie2);
                    529:                        chunk_free(&this->cookie2);
                    530:                }
                    531:                if (this->update)
                    532:                {
                    533:                        update_children(this);
                    534:                }
                    535:                return SUCCESS;
                    536:        }
                    537:        return NEED_MORE;
                    538: }
                    539: 
                    540: METHOD(task_t, process_i, status_t,
                    541:           private_ike_mobike_t *this, message_t *message)
                    542: {
                    543:        if (message->get_exchange_type(message) == IKE_AUTH &&
                    544:                this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)
                    545:        {
                    546:                process_payloads(this, message);
                    547:                return SUCCESS;
                    548:        }
                    549:        else if (message->get_exchange_type(message) == INFORMATIONAL)
                    550:        {
                    551:                if (is_newer_update_queued(this))
                    552:                {
                    553:                        return SUCCESS;
                    554:                }
                    555:                if (this->cookie2.ptr)
                    556:                {       /* check cookie if we included one */
                    557:                        chunk_t cookie2;
                    558: 
                    559:                        cookie2 = this->cookie2;
                    560:                        this->cookie2 = chunk_empty;
                    561:                        process_payloads(this, message);
                    562:                        if (!chunk_equals_const(cookie2, this->cookie2))
                    563:                        {
                    564:                                chunk_free(&cookie2);
                    565:                                DBG1(DBG_IKE, "COOKIE2 mismatch, closing IKE_SA");
                    566:                                return FAILED;
                    567:                        }
                    568:                        chunk_free(&cookie2);
                    569:                }
                    570:                else
                    571:                {
                    572:                        process_payloads(this, message);
                    573:                }
                    574:                if (this->natd)
                    575:                {
                    576:                        this->natd->task.process(&this->natd->task, message);
                    577:                        if (!this->update && this->natd->has_mapping_changed(this->natd))
                    578:                        {
                    579:                                /* force an update if mappings have changed */
                    580:                                this->update = this->check = TRUE;
                    581:                                DBG1(DBG_IKE, "detected changes in NAT mappings, "
                    582:                                         "initiating MOBIKE update");
                    583:                        }
                    584:                }
                    585:                if (this->update)
                    586:                {
                    587:                        /* update again, as NAT state may have changed */
                    588:                        update_children(this);
                    589:                }
                    590:                if (this->check)
                    591:                {
                    592:                        host_t *me_new, *me_old, *other_new, *other_old;
                    593: 
                    594:                        me_new = message->get_destination(message);
                    595:                        other_new = message->get_source(message);
                    596:                        me_old = this->ike_sa->get_my_host(this->ike_sa);
                    597:                        other_old = this->ike_sa->get_other_host(this->ike_sa);
                    598: 
                    599:                        if (!me_new->equals(me_new, me_old))
                    600:                        {
                    601:                                this->update = TRUE;
                    602:                                this->ike_sa->set_my_host(this->ike_sa, me_new->clone(me_new));
                    603:                        }
                    604:                        if (!other_new->equals(other_new, other_old))
                    605:                        {
                    606:                                this->update = TRUE;
                    607:                                this->ike_sa->set_other_host(this->ike_sa, other_new->clone(other_new));
                    608:                        }
                    609:                        if (this->update)
                    610:                        {
                    611:                                /* use the same task to ... */
                    612:                                if (!this->ike_sa->has_condition(this->ike_sa,
                    613:                                                                                                 COND_ORIGINAL_INITIATOR))
                    614:                                {       /*... send an updated list of addresses as responder */
                    615:                                        update_children(this);
                    616:                                        this->update = FALSE;
                    617:                                }
                    618:                                else
                    619:                                {       /* ... send the update as original initiator */
                    620:                                        if (this->natd)
                    621:                                        {
                    622:                                                this->natd->task.destroy(&this->natd->task);
                    623:                                        }
                    624:                                        this->natd = ike_natd_create(this->ike_sa, this->initiator);
                    625:                                }
                    626:                                this->check = FALSE;
                    627:                                return NEED_MORE;
                    628:                        }
                    629:                }
                    630:                return SUCCESS;
                    631:        }
                    632:        return NEED_MORE;
                    633: }
                    634: 
                    635: METHOD(ike_mobike_t, addresses, void,
                    636:           private_ike_mobike_t *this)
                    637: {
                    638:        this->address = TRUE;
                    639: }
                    640: 
                    641: METHOD(ike_mobike_t, roam, void,
                    642:           private_ike_mobike_t *this, bool address)
                    643: {
                    644:        this->check = TRUE;
                    645:        this->address |= address;
                    646: }
                    647: 
                    648: METHOD(ike_mobike_t, dpd, void,
                    649:           private_ike_mobike_t *this)
                    650: {
                    651:        if (!this->natd && this->ike_sa->has_condition(this->ike_sa, COND_NAT_HERE))
                    652:        {
                    653:                this->natd = ike_natd_create(this->ike_sa, this->initiator);
                    654:        }
                    655: }
                    656: 
                    657: METHOD(ike_mobike_t, is_probing, bool,
                    658:           private_ike_mobike_t *this)
                    659: {
                    660:        return this->check;
                    661: }
                    662: 
                    663: METHOD(ike_mobike_t, enable_probing, void,
                    664:        private_ike_mobike_t *this)
                    665: {
                    666:        this->check = TRUE;
                    667: }
                    668: 
                    669: METHOD(task_t, get_type, task_type_t,
                    670:           private_ike_mobike_t *this)
                    671: {
                    672:        return TASK_IKE_MOBIKE;
                    673: }
                    674: 
                    675: METHOD(task_t, migrate, void,
                    676:           private_ike_mobike_t *this, ike_sa_t *ike_sa)
                    677: {
                    678:        chunk_free(&this->cookie2);
                    679:        this->ike_sa = ike_sa;
                    680:        if (this->natd)
                    681:        {
                    682:                this->natd->task.migrate(&this->natd->task, ike_sa);
                    683:        }
                    684: }
                    685: 
                    686: METHOD(task_t, destroy, void,
                    687:           private_ike_mobike_t *this)
                    688: {
                    689:        chunk_free(&this->cookie2);
                    690:        if (this->natd)
                    691:        {
                    692:                this->natd->task.destroy(&this->natd->task);
                    693:        }
                    694:        free(this);
                    695: }
                    696: 
                    697: /*
                    698:  * Described in header.
                    699:  */
                    700: ike_mobike_t *ike_mobike_create(ike_sa_t *ike_sa, bool initiator)
                    701: {
                    702:        private_ike_mobike_t *this;
                    703: 
                    704:        INIT(this,
                    705:                .public = {
                    706:                        .task = {
                    707:                                .get_type = _get_type,
                    708:                                .migrate = _migrate,
                    709:                                .destroy = _destroy,
                    710:                        },
                    711:                        .addresses = _addresses,
                    712:                        .roam = _roam,
                    713:                        .dpd = _dpd,
                    714:                        .transmit = _transmit,
                    715:                        .is_probing = _is_probing,
                    716:                        .enable_probing = _enable_probing,
                    717:                },
                    718:                .ike_sa = ike_sa,
                    719:                .initiator = initiator,
                    720:        );
                    721: 
                    722:        if (initiator)
                    723:        {
                    724:                this->public.task.build = _build_i;
                    725:                this->public.task.process = _process_i;
                    726:        }
                    727:        else
                    728:        {
                    729:                this->public.task.build = _build_r;
                    730:                this->public.task.process = _process_r;
                    731:        }
                    732: 
                    733:        return &this->public;
                    734: }

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