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

1.1       misho       1: /*
1.1.1.2 ! misho       2:  * Copyright (C) 2010-2020 Tobias Brunner
1.1       misho       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:  * Apply the port of the old host, if its ip equals the new, use port otherwise.
                    274:  */
                    275: static void apply_port(host_t *host, host_t *old, uint16_t port, bool local)
                    276: {
                    277:        if (host->ip_equals(host, old))
                    278:        {
                    279:                port = old->get_port(old);
                    280:        }
                    281:        else if (local && port == charon->socket->get_port(charon->socket, FALSE))
                    282:        {
                    283:                port = charon->socket->get_port(charon->socket, TRUE);
                    284:        }
                    285:        else if (!local && port == IKEV2_UDP_PORT)
                    286:        {
                    287:                port = IKEV2_NATT_PORT;
                    288:        }
                    289:        host->set_port(host, port);
                    290: }
                    291: 
                    292: METHOD(ike_mobike_t, transmit, bool,
                    293:           private_ike_mobike_t *this, packet_t *packet)
                    294: {
                    295:        host_t *me, *other, *me_old, *other_old;
                    296:        enumerator_t *enumerator;
                    297:        ike_cfg_t *ike_cfg;
                    298:        packet_t *copy;
                    299:        int family = AF_UNSPEC;
                    300:        bool found = FALSE;
                    301: 
                    302:        me_old = this->ike_sa->get_my_host(this->ike_sa);
                    303:        other_old = this->ike_sa->get_other_host(this->ike_sa);
                    304:        ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
                    305: 
                    306:        if (!this->check)
                    307:        {
                    308:                me = charon->kernel->get_source_addr(charon->kernel, other_old, me_old);
                    309:                if (me)
                    310:                {
                    311:                        if (me->ip_equals(me, me_old))
                    312:                        {
                    313:                                copy = packet->clone(packet);
                    314:                                /* hosts might have been updated by a peer's MOBIKE exchange */
                    315:                                copy->set_source(copy, me_old->clone(me_old));
                    316:                                copy->set_destination(copy, other_old->clone(other_old));
                    317:                                charon->sender->send(charon->sender, copy);
                    318:                                me->destroy(me);
                    319:                                return TRUE;
                    320:                        }
                    321:                        me->destroy(me);
                    322:                }
                    323:                this->check = TRUE;
                    324:        }
                    325: 
                    326:        switch (charon->socket->supported_families(charon->socket))
                    327:        {
                    328:                case SOCKET_FAMILY_IPV4:
                    329:                        family = AF_INET;
                    330:                        break;
                    331:                case SOCKET_FAMILY_IPV6:
                    332:                        family = AF_INET6;
                    333:                        break;
                    334:                case SOCKET_FAMILY_BOTH:
                    335:                case SOCKET_FAMILY_NONE:
                    336:                        break;
                    337:        }
                    338: 
                    339:        enumerator = this->ike_sa->create_peer_address_enumerator(this->ike_sa);
                    340:        while (enumerator->enumerate(enumerator, (void**)&other))
                    341:        {
                    342:                if (family != AF_UNSPEC && other->get_family(other) != family)
                    343:                {
                    344:                        continue;
                    345:                }
                    346:                me = charon->kernel->get_source_addr(charon->kernel, other, NULL);
                    347:                if (me)
                    348:                {
                    349:                        /* reuse port for an active address, 4500 otherwise */
                    350:                        apply_port(me, me_old, ike_cfg->get_my_port(ike_cfg), TRUE);
                    351:                        other = other->clone(other);
                    352:                        apply_port(other, other_old, ike_cfg->get_other_port(ike_cfg), FALSE);
                    353:                        DBG1(DBG_IKE, "checking path %#H - %#H", me, other);
                    354:                        copy = packet->clone(packet);
                    355:                        copy->set_source(copy, me);
                    356:                        copy->set_destination(copy, other);
                    357:                        charon->sender->send(charon->sender, copy);
                    358:                        found = TRUE;
                    359:                }
                    360:        }
                    361:        enumerator->destroy(enumerator);
                    362:        return found;
                    363: }
                    364: 
                    365: METHOD(task_t, build_i, status_t,
                    366:           private_ike_mobike_t *this, message_t *message)
                    367: {
                    368:        if (message->get_exchange_type(message) == IKE_AUTH &&
                    369:                message->get_message_id(message) == 1)
                    370:        {       /* only in first IKE_AUTH */
                    371:                message->add_notify(message, FALSE, MOBIKE_SUPPORTED, chunk_empty);
                    372:                build_address_list(this, message);
                    373:        }
                    374:        else if (message->get_exchange_type(message) == INFORMATIONAL)
                    375:        {
                    376:                host_t *old, *new;
                    377: 
                    378:                /* we check if the existing address is still valid */
                    379:                old = message->get_source(message);
                    380:                new = charon->kernel->get_source_addr(charon->kernel,
                    381:                                                                                message->get_destination(message), old);
                    382:                if (new)
                    383:                {
                    384:                        if (!new->ip_equals(new, old))
                    385:                        {
                    386:                                new->set_port(new, old->get_port(old));
                    387:                                message->set_source(message, new);
                    388:                        }
                    389:                        else
                    390:                        {
                    391:                                new->destroy(new);
                    392:                        }
                    393:                }
                    394:                if (this->update)
                    395:                {
                    396:                        message->add_notify(message, FALSE, UPDATE_SA_ADDRESSES,
                    397:                                                                chunk_empty);
                    398:                        if (!build_cookie(this, message))
                    399:                        {
                    400:                                return FAILED;
                    401:                        }
                    402:                }
                    403:                if (this->address && !this->check)
                    404:                {
                    405:                        build_address_list(this, message);
                    406:                }
                    407:                if (this->natd)
                    408:                {
                    409:                        this->natd->task.build(&this->natd->task, message);
                    410:                }
                    411:        }
                    412:        return NEED_MORE;
                    413: }
                    414: 
                    415: METHOD(task_t, process_r, status_t,
                    416:           private_ike_mobike_t *this, message_t *message)
                    417: {
                    418:        if (message->get_exchange_type(message) == IKE_AUTH &&
                    419:                message->get_message_id(message) == 1)
                    420:        {       /* only first IKE_AUTH */
                    421:                process_payloads(this, message);
                    422:        }
                    423:        else if (message->get_exchange_type(message) == INFORMATIONAL)
                    424:        {
1.1.1.2 ! misho     425:                host_t *me_new = NULL, *other, *other_old, *other_new = NULL;
1.1       misho     426: 
1.1.1.2 ! misho     427:                process_payloads(this, message);
1.1       misho     428: 
                    429:                if (this->natd)
                    430:                {
                    431:                        this->natd->task.process(&this->natd->task, message);
                    432:                }
1.1.1.2 ! misho     433: 
        !           434:                if (this->update)
1.1       misho     435:                {
1.1.1.2 ! misho     436:                        me_new = message->get_destination(message);
        !           437:                        other_new = message->get_source(message);
        !           438:                }
        !           439:                else if (this->addresses_updated &&
        !           440:                                 this->ike_sa->has_condition(this->ike_sa, COND_ORIGINAL_INITIATOR))
        !           441:                {
        !           442:                        other = message->get_source(message);
        !           443:                        other_old = this->ike_sa->get_other_host(this->ike_sa);
1.1       misho     444:                        if (!other->equals(other, other_old))
                    445:                        {
                    446:                                DBG1(DBG_IKE, "remote address changed from %H to %H", other_old,
                    447:                                         other);
1.1.1.2 ! misho     448:                                other_new = other;
        !           449:                                /* our address might have changed too if the responder used
        !           450:                                 * a different address from our list to reach us */
        !           451:                                me_new = message->get_destination(message);
1.1       misho     452:                        }
                    453:                }
1.1.1.2 ! misho     454: 
        !           455:                if (me_new || other_new)
        !           456:                {
        !           457:                        this->ike_sa->update_hosts(this->ike_sa, me_new,
        !           458:                                                                           other_new, UPDATE_HOSTS_FORCE_ALL);
        !           459:                }
1.1       misho     460:        }
                    461:        return NEED_MORE;
                    462: }
                    463: 
                    464: METHOD(task_t, build_r, status_t,
                    465:           private_ike_mobike_t *this, message_t *message)
                    466: {
                    467:        if (message->get_exchange_type(message) == IKE_AUTH &&
                    468:                this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)
                    469:        {
                    470:                if (this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE))
                    471:                {
                    472:                        message->add_notify(message, FALSE, MOBIKE_SUPPORTED, chunk_empty);
                    473:                        build_address_list(this, message);
                    474:                }
                    475:                return SUCCESS;
                    476:        }
                    477:        else if (message->get_exchange_type(message) == INFORMATIONAL)
                    478:        {
                    479:                if (this->natd)
                    480:                {
                    481:                        this->natd->task.build(&this->natd->task, message);
                    482:                }
                    483:                if (this->cookie2.ptr)
                    484:                {
                    485:                        message->add_notify(message, FALSE, COOKIE2, this->cookie2);
                    486:                        chunk_free(&this->cookie2);
                    487:                }
                    488:                return SUCCESS;
                    489:        }
                    490:        return NEED_MORE;
                    491: }
                    492: 
                    493: METHOD(task_t, process_i, status_t,
                    494:           private_ike_mobike_t *this, message_t *message)
                    495: {
                    496:        if (message->get_exchange_type(message) == IKE_AUTH &&
                    497:                this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)
                    498:        {
                    499:                process_payloads(this, message);
                    500:                return SUCCESS;
                    501:        }
                    502:        else if (message->get_exchange_type(message) == INFORMATIONAL)
                    503:        {
                    504:                if (is_newer_update_queued(this))
                    505:                {
                    506:                        return SUCCESS;
                    507:                }
                    508:                if (this->cookie2.ptr)
                    509:                {       /* check cookie if we included one */
                    510:                        chunk_t cookie2;
                    511: 
                    512:                        cookie2 = this->cookie2;
                    513:                        this->cookie2 = chunk_empty;
                    514:                        process_payloads(this, message);
                    515:                        if (!chunk_equals_const(cookie2, this->cookie2))
                    516:                        {
                    517:                                chunk_free(&cookie2);
                    518:                                DBG1(DBG_IKE, "COOKIE2 mismatch, closing IKE_SA");
                    519:                                return FAILED;
                    520:                        }
                    521:                        chunk_free(&cookie2);
                    522:                }
                    523:                else
                    524:                {
                    525:                        process_payloads(this, message);
                    526:                }
                    527:                if (this->natd)
                    528:                {
                    529:                        this->natd->task.process(&this->natd->task, message);
1.1.1.2 ! misho     530: 
        !           531:                        if (this->update)
        !           532:                        {       /* update children again, as NAT state may have changed */
        !           533:                                this->ike_sa->update_hosts(this->ike_sa, NULL, NULL,
        !           534:                                                                                   UPDATE_HOSTS_FORCE_CHILDREN);
        !           535:                        }
        !           536:                        else if (this->natd->has_mapping_changed(this->natd))
        !           537:                        {       /* force a check/update if mappings have changed during a DPD */
        !           538:                                this->check = TRUE;
1.1       misho     539:                                DBG1(DBG_IKE, "detected changes in NAT mappings, "
                    540:                                         "initiating MOBIKE update");
                    541:                        }
                    542:                }
                    543:                if (this->check)
                    544:                {
1.1.1.2 ! misho     545:                        host_t *me, *me_new = NULL, *other, *other_new = NULL;
1.1       misho     546: 
1.1.1.2 ! misho     547:                        me = message->get_destination(message);
        !           548:                        other = message->get_source(message);
1.1       misho     549: 
1.1.1.2 ! misho     550:                        if (!me->equals(me, this->ike_sa->get_my_host(this->ike_sa)))
1.1       misho     551:                        {
1.1.1.2 ! misho     552:                                me_new = me;
1.1       misho     553:                        }
1.1.1.2 ! misho     554:                        if (!other->equals(other, this->ike_sa->get_other_host(this->ike_sa)))
1.1       misho     555:                        {
1.1.1.2 ! misho     556:                                other_new = other;
1.1       misho     557:                        }
1.1.1.2 ! misho     558:                        if (me_new || other_new)
1.1       misho     559:                        {
1.1.1.2 ! misho     560:                                this->ike_sa->update_hosts(this->ike_sa, me_new, other_new,
        !           561:                                                                                   UPDATE_HOSTS_FORCE_ALL);
1.1       misho     562:                                /* use the same task to ... */
                    563:                                if (!this->ike_sa->has_condition(this->ike_sa,
                    564:                                                                                                 COND_ORIGINAL_INITIATOR))
                    565:                                {       /*... send an updated list of addresses as responder */
1.1.1.2 ! misho     566:                                        this->address = TRUE;
1.1       misho     567:                                }
                    568:                                else
                    569:                                {       /* ... send the update as original initiator */
1.1.1.2 ! misho     570:                                        this->update = TRUE;
1.1       misho     571:                                        if (this->natd)
                    572:                                        {
                    573:                                                this->natd->task.destroy(&this->natd->task);
                    574:                                        }
                    575:                                        this->natd = ike_natd_create(this->ike_sa, this->initiator);
                    576:                                }
                    577:                                this->check = FALSE;
                    578:                                return NEED_MORE;
                    579:                        }
                    580:                }
                    581:                return SUCCESS;
                    582:        }
                    583:        return NEED_MORE;
                    584: }
                    585: 
                    586: METHOD(ike_mobike_t, addresses, void,
                    587:           private_ike_mobike_t *this)
                    588: {
                    589:        this->address = TRUE;
                    590: }
                    591: 
                    592: METHOD(ike_mobike_t, roam, void,
                    593:           private_ike_mobike_t *this, bool address)
                    594: {
                    595:        this->check = TRUE;
                    596:        this->address |= address;
                    597: }
                    598: 
                    599: METHOD(ike_mobike_t, dpd, void,
                    600:           private_ike_mobike_t *this)
                    601: {
                    602:        if (!this->natd && this->ike_sa->has_condition(this->ike_sa, COND_NAT_HERE))
                    603:        {
                    604:                this->natd = ike_natd_create(this->ike_sa, this->initiator);
                    605:        }
                    606: }
                    607: 
                    608: METHOD(ike_mobike_t, is_probing, bool,
                    609:           private_ike_mobike_t *this)
                    610: {
                    611:        return this->check;
                    612: }
                    613: 
                    614: METHOD(ike_mobike_t, enable_probing, void,
                    615:        private_ike_mobike_t *this)
                    616: {
                    617:        this->check = TRUE;
                    618: }
                    619: 
                    620: METHOD(task_t, get_type, task_type_t,
                    621:           private_ike_mobike_t *this)
                    622: {
                    623:        return TASK_IKE_MOBIKE;
                    624: }
                    625: 
                    626: METHOD(task_t, migrate, void,
                    627:           private_ike_mobike_t *this, ike_sa_t *ike_sa)
                    628: {
                    629:        chunk_free(&this->cookie2);
                    630:        this->ike_sa = ike_sa;
                    631:        if (this->natd)
                    632:        {
                    633:                this->natd->task.migrate(&this->natd->task, ike_sa);
                    634:        }
                    635: }
                    636: 
                    637: METHOD(task_t, destroy, void,
                    638:           private_ike_mobike_t *this)
                    639: {
                    640:        chunk_free(&this->cookie2);
                    641:        if (this->natd)
                    642:        {
                    643:                this->natd->task.destroy(&this->natd->task);
                    644:        }
                    645:        free(this);
                    646: }
                    647: 
                    648: /*
                    649:  * Described in header.
                    650:  */
                    651: ike_mobike_t *ike_mobike_create(ike_sa_t *ike_sa, bool initiator)
                    652: {
                    653:        private_ike_mobike_t *this;
                    654: 
                    655:        INIT(this,
                    656:                .public = {
                    657:                        .task = {
                    658:                                .get_type = _get_type,
                    659:                                .migrate = _migrate,
                    660:                                .destroy = _destroy,
                    661:                        },
                    662:                        .addresses = _addresses,
                    663:                        .roam = _roam,
                    664:                        .dpd = _dpd,
                    665:                        .transmit = _transmit,
                    666:                        .is_probing = _is_probing,
                    667:                        .enable_probing = _enable_probing,
                    668:                },
                    669:                .ike_sa = ike_sa,
                    670:                .initiator = initiator,
                    671:        );
                    672: 
                    673:        if (initiator)
                    674:        {
                    675:                this->public.task.build = _build_i;
                    676:                this->public.task.process = _process_i;
                    677:        }
                    678:        else
                    679:        {
                    680:                this->public.task.build = _build_r;
                    681:                this->public.task.process = _process_r;
                    682:        }
                    683: 
                    684:        return &this->public;
                    685: }

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