Annotation of embedaddon/strongswan/src/charon-cmd/cmd/cmd_connection.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2013 Tobias Brunner
        !             3:  * HSR Hochschule fuer Technik Rapperswil
        !             4:  *
        !             5:  * Copyright (C) 2013 Martin Willi
        !             6:  * Copyright (C) 2013 revosec AG
        !             7:  *
        !             8:  * This program is free software; you can redistribute it and/or modify it
        !             9:  * under the terms of the GNU General Public License as published by the
        !            10:  * Free Software Foundation; either version 2 of the License, or (at your
        !            11:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
        !            12:  *
        !            13:  * This program is distributed in the hope that it will be useful, but
        !            14:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
        !            15:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
        !            16:  * for more details.
        !            17:  */
        !            18: 
        !            19: #include "cmd_connection.h"
        !            20: 
        !            21: #include <signal.h>
        !            22: #include <unistd.h>
        !            23: 
        !            24: #include <utils/debug.h>
        !            25: #include <processing/jobs/callback_job.h>
        !            26: #include <threading/thread.h>
        !            27: #include <daemon.h>
        !            28: 
        !            29: typedef enum profile_t profile_t;
        !            30: typedef struct private_cmd_connection_t private_cmd_connection_t;
        !            31: 
        !            32: /**
        !            33:  * Connection profiles we support
        !            34:  */
        !            35: enum profile_t {
        !            36:        PROF_UNDEF,
        !            37:        PROF_V2_PUB,
        !            38:        PROF_V2_EAP,
        !            39:        PROF_V2_PUB_EAP,
        !            40:        PROF_V1_PUB,
        !            41:        PROF_V1_PUB_AM,
        !            42:        PROF_V1_XAUTH,
        !            43:        PROF_V1_XAUTH_AM,
        !            44:        PROF_V1_XAUTH_PSK,
        !            45:        PROF_V1_XAUTH_PSK_AM,
        !            46:        PROF_V1_HYBRID,
        !            47:        PROF_V1_HYBRID_AM,
        !            48: };
        !            49: 
        !            50: ENUM(profile_names, PROF_V2_PUB, PROF_V1_HYBRID_AM,
        !            51:        "ikev2-pub",
        !            52:        "ikev2-eap",
        !            53:        "ikev2-pub-eap",
        !            54:        "ikev1-pub",
        !            55:        "ikev1-pub-am",
        !            56:        "ikev1-xauth",
        !            57:        "ikev1-xauth-am",
        !            58:        "ikev1-xauth-psk",
        !            59:        "ikev1-xauth-psk-am",
        !            60:        "ikev1-hybrid",
        !            61:        "ikev1-hybrid-am",
        !            62: );
        !            63: 
        !            64: /**
        !            65:  * Private data of an cmd_connection_t object.
        !            66:  */
        !            67: struct private_cmd_connection_t {
        !            68: 
        !            69:        /**
        !            70:         * Public cmd_connection_t interface.
        !            71:         */
        !            72:        cmd_connection_t public;
        !            73: 
        !            74:        /**
        !            75:         * Process ID to terminate on failure
        !            76:         */
        !            77:        pid_t pid;
        !            78: 
        !            79:        /**
        !            80:         * List of local traffic selectors
        !            81:         */
        !            82:        linked_list_t *local_ts;
        !            83: 
        !            84:        /**
        !            85:         * List of remote traffic selectors
        !            86:         */
        !            87:        linked_list_t *remote_ts;
        !            88: 
        !            89:        /**
        !            90:         * List of IKE proposals
        !            91:         */
        !            92:        linked_list_t *ike_proposals;
        !            93: 
        !            94:        /**
        !            95:         * List of CHILD proposals
        !            96:         */
        !            97:        linked_list_t *child_proposals;
        !            98: 
        !            99:        /**
        !           100:         * Hostname to connect to
        !           101:         */
        !           102:        char *host;
        !           103: 
        !           104:        /**
        !           105:         * Server identity, or NULL to use host
        !           106:         */
        !           107:        char *server;
        !           108: 
        !           109:        /**
        !           110:         * Local identity
        !           111:         */
        !           112:        char *identity;
        !           113: 
        !           114:        /**
        !           115:         * XAuth/EAP identity
        !           116:         */
        !           117:        char *xautheap;
        !           118: 
        !           119:        /**
        !           120:         * Is a private key configured
        !           121:         */
        !           122:        bool key_seen;
        !           123: 
        !           124:        /**
        !           125:         * Selected connection profile
        !           126:         */
        !           127:        profile_t profile;
        !           128: };
        !           129: 
        !           130: /**
        !           131:  * Shut down application
        !           132:  */
        !           133: static void terminate(pid_t pid)
        !           134: {
        !           135:        kill(pid, SIGUSR1);
        !           136: }
        !           137: 
        !           138: /**
        !           139:  * Create peer config with associated ike config
        !           140:  */
        !           141: static peer_cfg_t* create_peer_cfg(private_cmd_connection_t *this)
        !           142: {
        !           143:        ike_cfg_t *ike_cfg;
        !           144:        peer_cfg_t *peer_cfg;
        !           145:        proposal_t *proposal;
        !           146:        ike_cfg_create_t ike = {
        !           147:                .local = "0.0.0.0",
        !           148:                .remote = this->host,
        !           149:                .remote_port = IKEV2_UDP_PORT,
        !           150:                .fragmentation = FRAGMENTATION_YES,
        !           151:        };
        !           152:        peer_cfg_create_t peer = {
        !           153:                .cert_policy = CERT_SEND_IF_ASKED,
        !           154:                .unique = UNIQUE_REPLACE,
        !           155:                .keyingtries = 1,
        !           156:                .rekey_time = 36000, /* 10h */
        !           157:                .jitter_time = 600, /* 10min */
        !           158:                .over_time = 600, /* 10min */
        !           159:                .dpd = 30,
        !           160:        };
        !           161: 
        !           162:        switch (this->profile)
        !           163:        {
        !           164:                case PROF_UNDEF:
        !           165:                case PROF_V2_PUB:
        !           166:                case PROF_V2_EAP:
        !           167:                case PROF_V2_PUB_EAP:
        !           168:                        ike.version = IKEV2;
        !           169:                        break;
        !           170:                case PROF_V1_PUB_AM:
        !           171:                case PROF_V1_XAUTH_AM:
        !           172:                case PROF_V1_XAUTH_PSK_AM:
        !           173:                case PROF_V1_HYBRID_AM:
        !           174:                        peer.aggressive = TRUE;
        !           175:                        /* FALL */
        !           176:                case PROF_V1_PUB:
        !           177:                case PROF_V1_XAUTH:
        !           178:                case PROF_V1_XAUTH_PSK:
        !           179:                case PROF_V1_HYBRID:
        !           180:                        ike.version = IKEV1;
        !           181:                        break;
        !           182:        }
        !           183: 
        !           184:        ike.local_port = charon->socket->get_port(charon->socket, FALSE);
        !           185:        if (ike.local_port != IKEV2_UDP_PORT)
        !           186:        {
        !           187:                ike.remote_port = IKEV2_NATT_PORT;
        !           188:        }
        !           189:        ike_cfg = ike_cfg_create(&ike);
        !           190:        if (this->ike_proposals->get_count(this->ike_proposals))
        !           191:        {
        !           192:                while (this->ike_proposals->remove_first(this->ike_proposals,
        !           193:                                                                                                 (void**)&proposal) == SUCCESS)
        !           194:                {
        !           195:                        ike_cfg->add_proposal(ike_cfg, proposal);
        !           196:                }
        !           197:        }
        !           198:        else
        !           199:        {
        !           200:                ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
        !           201:                ike_cfg->add_proposal(ike_cfg, proposal_create_default_aead(PROTO_IKE));
        !           202:        }
        !           203:        peer_cfg = peer_cfg_create("cmd", ike_cfg, &peer);
        !           204: 
        !           205:        return peer_cfg;
        !           206: }
        !           207: 
        !           208: /**
        !           209:  * Add a single auth cfg of given class to peer cfg
        !           210:  */
        !           211: static void add_auth_cfg(private_cmd_connection_t *this, peer_cfg_t *peer_cfg,
        !           212:                                                 bool local, auth_class_t class)
        !           213: {
        !           214:        identification_t *id;
        !           215:        auth_cfg_t *auth;
        !           216: 
        !           217:        auth = auth_cfg_create();
        !           218:        auth->add(auth, AUTH_RULE_AUTH_CLASS, class);
        !           219:        if (local)
        !           220:        {
        !           221:                id = identification_create_from_string(this->identity);
        !           222:                if (this->xautheap)
        !           223:                {
        !           224:                        switch (class)
        !           225:                        {
        !           226:                                case AUTH_CLASS_EAP:
        !           227:                                        auth->add(auth, AUTH_RULE_EAP_IDENTITY,
        !           228:                                                        identification_create_from_string(this->xautheap));
        !           229:                                        break;
        !           230:                                case AUTH_CLASS_XAUTH:
        !           231:                                        auth->add(auth, AUTH_RULE_XAUTH_IDENTITY,
        !           232:                                                        identification_create_from_string(this->xautheap));
        !           233:                                        break;
        !           234:                                default:
        !           235:                                        break;
        !           236:                        }
        !           237:                }
        !           238:        }
        !           239:        else
        !           240:        {
        !           241:                if (this->server)
        !           242:                {
        !           243:                        id = identification_create_from_string(this->server);
        !           244:                }
        !           245:                else
        !           246:                {
        !           247:                        id = identification_create_from_string(this->host);
        !           248:                }
        !           249:                auth->add(auth, AUTH_RULE_IDENTITY_LOOSE, TRUE);
        !           250:        }
        !           251:        auth->add(auth, AUTH_RULE_IDENTITY, id);
        !           252:        peer_cfg->add_auth_cfg(peer_cfg, auth, local);
        !           253: }
        !           254: 
        !           255: /**
        !           256:  * Attach authentication configs to peer config
        !           257:  */
        !           258: static bool add_auth_cfgs(private_cmd_connection_t *this, peer_cfg_t *peer_cfg)
        !           259: {
        !           260:        if (this->profile == PROF_UNDEF)
        !           261:        {
        !           262:                if (this->key_seen)
        !           263:                {
        !           264:                        this->profile = PROF_V2_PUB;
        !           265:                }
        !           266:                else
        !           267:                {
        !           268:                        this->profile = PROF_V2_EAP;
        !           269:                }
        !           270:        }
        !           271:        switch (this->profile)
        !           272:        {
        !           273:                case PROF_V2_PUB:
        !           274:                case PROF_V2_PUB_EAP:
        !           275:                case PROF_V1_PUB:
        !           276:                case PROF_V1_XAUTH:
        !           277:                case PROF_V1_PUB_AM:
        !           278:                case PROF_V1_XAUTH_AM:
        !           279:                        if (!this->key_seen)
        !           280:                        {
        !           281:                                DBG1(DBG_CFG, "missing private key for profile %N",
        !           282:                                         profile_names, this->profile);
        !           283:                                return FALSE;
        !           284:                        }
        !           285:                        break;
        !           286:                default:
        !           287:                        break;
        !           288:        }
        !           289: 
        !           290:        switch (this->profile)
        !           291:        {
        !           292:                case PROF_V2_PUB:
        !           293:                        add_auth_cfg(this, peer_cfg, TRUE, AUTH_CLASS_PUBKEY);
        !           294:                        add_auth_cfg(this, peer_cfg, FALSE, AUTH_CLASS_ANY);
        !           295:                        break;
        !           296:                case PROF_V2_EAP:
        !           297:                        add_auth_cfg(this, peer_cfg, TRUE, AUTH_CLASS_EAP);
        !           298:                        add_auth_cfg(this, peer_cfg, FALSE, AUTH_CLASS_ANY);
        !           299:                        break;
        !           300:                case PROF_V2_PUB_EAP:
        !           301:                        add_auth_cfg(this, peer_cfg, TRUE, AUTH_CLASS_PUBKEY);
        !           302:                        add_auth_cfg(this, peer_cfg, TRUE, AUTH_CLASS_EAP);
        !           303:                        add_auth_cfg(this, peer_cfg, FALSE, AUTH_CLASS_ANY);
        !           304:                        break;
        !           305:                case PROF_V1_PUB:
        !           306:                case PROF_V1_PUB_AM:
        !           307:                        add_auth_cfg(this, peer_cfg, TRUE, AUTH_CLASS_PUBKEY);
        !           308:                        add_auth_cfg(this, peer_cfg, FALSE, AUTH_CLASS_PUBKEY);
        !           309:                        break;
        !           310:                case PROF_V1_XAUTH:
        !           311:                case PROF_V1_XAUTH_AM:
        !           312:                        add_auth_cfg(this, peer_cfg, TRUE, AUTH_CLASS_PUBKEY);
        !           313:                        add_auth_cfg(this, peer_cfg, TRUE, AUTH_CLASS_XAUTH);
        !           314:                        add_auth_cfg(this, peer_cfg, FALSE, AUTH_CLASS_PUBKEY);
        !           315:                        break;
        !           316:                case PROF_V1_XAUTH_PSK:
        !           317:                case PROF_V1_XAUTH_PSK_AM:
        !           318:                        add_auth_cfg(this, peer_cfg, TRUE, AUTH_CLASS_PSK);
        !           319:                        add_auth_cfg(this, peer_cfg, TRUE, AUTH_CLASS_XAUTH);
        !           320:                        add_auth_cfg(this, peer_cfg, FALSE, AUTH_CLASS_PSK);
        !           321:                        break;
        !           322:                case PROF_V1_HYBRID:
        !           323:                case PROF_V1_HYBRID_AM:
        !           324:                        add_auth_cfg(this, peer_cfg, TRUE, AUTH_CLASS_XAUTH);
        !           325:                        add_auth_cfg(this, peer_cfg, FALSE, AUTH_CLASS_PUBKEY);
        !           326:                        break;
        !           327:                default:
        !           328:                        return FALSE;
        !           329:        }
        !           330:        return TRUE;
        !           331: }
        !           332: 
        !           333: /**
        !           334:  * Attach child config to peer config
        !           335:  */
        !           336: static child_cfg_t* create_child_cfg(private_cmd_connection_t *this,
        !           337:                                                                         peer_cfg_t *peer_cfg)
        !           338: {
        !           339:        child_cfg_t *child_cfg;
        !           340:        traffic_selector_t *ts;
        !           341:        proposal_t *proposal;
        !           342:        bool has_v4 = FALSE, has_v6 = FALSE;
        !           343:        child_cfg_create_t child = {
        !           344:                .lifetime = {
        !           345:                        .time = {
        !           346:                                .life = 10800 /* 3h */,
        !           347:                                .rekey = 10200 /* 2h50min */,
        !           348:                                .jitter = 300 /* 5min */
        !           349:                        }
        !           350:                },
        !           351:                .mode = MODE_TUNNEL,
        !           352:        };
        !           353: 
        !           354:        child_cfg = child_cfg_create("cmd", &child);
        !           355:        if (this->child_proposals->get_count(this->child_proposals))
        !           356:        {
        !           357:                while (this->child_proposals->remove_first(this->child_proposals,
        !           358:                                                                                                (void**)&proposal) == SUCCESS)
        !           359:                {
        !           360:                        child_cfg->add_proposal(child_cfg, proposal);
        !           361:                }
        !           362:        }
        !           363:        else
        !           364:        {
        !           365:                child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
        !           366:                child_cfg->add_proposal(child_cfg,
        !           367:                                                                proposal_create_default_aead(PROTO_ESP));
        !           368:        }
        !           369:        while (this->local_ts->remove_first(this->local_ts, (void**)&ts) == SUCCESS)
        !           370:        {
        !           371:                child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
        !           372:        }
        !           373:        if (this->remote_ts->get_count(this->remote_ts) == 0)
        !           374:        {
        !           375:                /* add a 0.0.0.0/0 TS for remote side if none given */
        !           376:                ts = traffic_selector_create_from_string(0, TS_IPV4_ADDR_RANGE,
        !           377:                                                                        "0.0.0.0", 0, "255.255.255.255", 65535);
        !           378:                this->remote_ts->insert_last(this->remote_ts, ts);
        !           379:                has_v4 = TRUE;
        !           380:        }
        !           381:        while (this->remote_ts->remove_first(this->remote_ts,
        !           382:                                                                                 (void**)&ts) == SUCCESS)
        !           383:        {
        !           384:                switch (ts->get_type(ts))
        !           385:                {
        !           386:                        case TS_IPV4_ADDR_RANGE:
        !           387:                                has_v4 = TRUE;
        !           388:                                break;
        !           389:                        case TS_IPV6_ADDR_RANGE:
        !           390:                                has_v6 = TRUE;
        !           391:                                break;
        !           392:                }
        !           393:                child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
        !           394:        }
        !           395:        if (has_v4)
        !           396:        {
        !           397:                peer_cfg->add_virtual_ip(peer_cfg, host_create_from_string("0.0.0.0", 0));
        !           398:        }
        !           399:        if (has_v6)
        !           400:        {
        !           401:                peer_cfg->add_virtual_ip(peer_cfg, host_create_from_string("::", 0));
        !           402:        }
        !           403:        peer_cfg->add_child_cfg(peer_cfg, child_cfg->get_ref(child_cfg));
        !           404: 
        !           405:        return child_cfg;
        !           406: }
        !           407: 
        !           408: /**
        !           409:  * Initiate the configured connection
        !           410:  */
        !           411: static job_requeue_t initiate(private_cmd_connection_t *this)
        !           412: {
        !           413:        peer_cfg_t *peer_cfg;
        !           414:        child_cfg_t *child_cfg;
        !           415:        pid_t pid = this->pid;
        !           416: 
        !           417:        if (!this->host)
        !           418:        {
        !           419:                DBG1(DBG_CFG, "unable to initiate, missing --host option");
        !           420:                terminate(pid);
        !           421:                return JOB_REQUEUE_NONE;
        !           422:        }
        !           423:        if (!this->identity)
        !           424:        {
        !           425:                DBG1(DBG_CFG, "unable to initiate, missing --identity option");
        !           426:                terminate(pid);
        !           427:                return JOB_REQUEUE_NONE;
        !           428:        }
        !           429: 
        !           430:        peer_cfg = create_peer_cfg(this);
        !           431: 
        !           432:        if (!add_auth_cfgs(this, peer_cfg))
        !           433:        {
        !           434:                peer_cfg->destroy(peer_cfg);
        !           435:                terminate(pid);
        !           436:                return JOB_REQUEUE_NONE;
        !           437:        }
        !           438: 
        !           439:        child_cfg = create_child_cfg(this, peer_cfg);
        !           440: 
        !           441:        if (charon->controller->initiate(charon->controller, peer_cfg, child_cfg,
        !           442:                                                                controller_cb_empty, NULL, 0, FALSE) != SUCCESS)
        !           443:        {
        !           444:                terminate(pid);
        !           445:        }
        !           446:        return JOB_REQUEUE_NONE;
        !           447: }
        !           448: 
        !           449: /**
        !           450:  * Create a traffic selector from string, add to list
        !           451:  */
        !           452: static void add_ts(private_cmd_connection_t *this,
        !           453:                                   linked_list_t *list, char *string)
        !           454: {
        !           455:        traffic_selector_t *ts;
        !           456: 
        !           457:        ts = traffic_selector_create_from_cidr(string, 0, 0, 65535);
        !           458:        if (!ts)
        !           459:        {
        !           460:                DBG1(DBG_CFG, "invalid traffic selector: %s", string);
        !           461:                exit(1);
        !           462:        }
        !           463:        list->insert_last(list, ts);
        !           464: }
        !           465: 
        !           466: /**
        !           467:  * Parse profile name identifier
        !           468:  */
        !           469: static void set_profile(private_cmd_connection_t *this, char *name)
        !           470: {
        !           471:        profile_t profile;
        !           472: 
        !           473:        if (!enum_from_name(profile_names, name, &profile))
        !           474:        {
        !           475:                DBG1(DBG_CFG, "unknown connection profile: %s", name);
        !           476:                exit(1);
        !           477:        }
        !           478:        this->profile = profile;
        !           479: }
        !           480: 
        !           481: METHOD(cmd_connection_t, handle, bool,
        !           482:        private_cmd_connection_t *this, cmd_option_type_t opt, char *arg)
        !           483: {
        !           484:        proposal_t *proposal;
        !           485: 
        !           486:        switch (opt)
        !           487:        {
        !           488:                case CMD_OPT_HOST:
        !           489:                        this->host = arg;
        !           490:                        break;
        !           491:                case CMD_OPT_REMOTE_IDENTITY:
        !           492:                        this->server = arg;
        !           493:                        break;
        !           494:                case CMD_OPT_IDENTITY:
        !           495:                        this->identity = arg;
        !           496:                        break;
        !           497:                case CMD_OPT_EAP_IDENTITY:
        !           498:                case CMD_OPT_XAUTH_USER:
        !           499:                        this->xautheap = arg;
        !           500:                        break;
        !           501:                case CMD_OPT_RSA:
        !           502:                case CMD_OPT_AGENT:
        !           503:                case CMD_OPT_PKCS12:
        !           504:                        this->key_seen = TRUE;
        !           505:                        break;
        !           506:                case CMD_OPT_LOCAL_TS:
        !           507:                        add_ts(this, this->local_ts, arg);
        !           508:                        break;
        !           509:                case CMD_OPT_REMOTE_TS:
        !           510:                        add_ts(this, this->remote_ts, arg);
        !           511:                        break;
        !           512:                case CMD_OPT_IKE_PROPOSAL:
        !           513:                        proposal = proposal_create_from_string(PROTO_IKE, arg);
        !           514:                        if (!proposal)
        !           515:                        {
        !           516:                                exit(1);
        !           517:                        }
        !           518:                        this->ike_proposals->insert_last(this->ike_proposals, proposal);
        !           519:                        break;
        !           520:                case CMD_OPT_ESP_PROPOSAL:
        !           521:                        proposal = proposal_create_from_string(PROTO_ESP, arg);
        !           522:                        if (!proposal)
        !           523:                        {
        !           524:                                exit(1);
        !           525:                        }
        !           526:                        this->child_proposals->insert_last(this->child_proposals, proposal);
        !           527:                        break;
        !           528:                case CMD_OPT_AH_PROPOSAL:
        !           529:                        proposal = proposal_create_from_string(PROTO_AH, arg);
        !           530:                        if (!proposal)
        !           531:                        {
        !           532:                                exit(1);
        !           533:                        }
        !           534:                        this->child_proposals->insert_last(this->child_proposals, proposal);
        !           535:                        break;
        !           536:                case CMD_OPT_PROFILE:
        !           537:                        set_profile(this, arg);
        !           538:                        break;
        !           539:                default:
        !           540:                        return FALSE;
        !           541:        }
        !           542:        return TRUE;
        !           543: }
        !           544: 
        !           545: METHOD(cmd_connection_t, destroy, void,
        !           546:        private_cmd_connection_t *this)
        !           547: {
        !           548:        this->ike_proposals->destroy_offset(this->ike_proposals,
        !           549:                                                                offsetof(proposal_t, destroy));
        !           550:        this->child_proposals->destroy_offset(this->child_proposals,
        !           551:                                                                offsetof(proposal_t, destroy));
        !           552:        this->local_ts->destroy_offset(this->local_ts,
        !           553:                                                                offsetof(traffic_selector_t, destroy));
        !           554:        this->remote_ts->destroy_offset(this->remote_ts,
        !           555:                                                                offsetof(traffic_selector_t, destroy));
        !           556:        free(this);
        !           557: }
        !           558: 
        !           559: /**
        !           560:  * See header
        !           561:  */
        !           562: cmd_connection_t *cmd_connection_create()
        !           563: {
        !           564:        private_cmd_connection_t *this;
        !           565: 
        !           566:        INIT(this,
        !           567:                .public = {
        !           568:                        .handle = _handle,
        !           569:                        .destroy = _destroy,
        !           570:                },
        !           571:                .pid = getpid(),
        !           572:                .local_ts = linked_list_create(),
        !           573:                .remote_ts = linked_list_create(),
        !           574:                .ike_proposals = linked_list_create(),
        !           575:                .child_proposals = linked_list_create(),
        !           576:                .profile = PROF_UNDEF,
        !           577:        );
        !           578: 
        !           579:        /* always include the virtual IP in traffic selector list */
        !           580:        this->local_ts->insert_last(this->local_ts,
        !           581:                                                                traffic_selector_create_dynamic(0, 0, 65535));
        !           582: 
        !           583:        /* queue job, gets initiated as soon as we are up and running */
        !           584:        lib->processor->queue_job(lib->processor,
        !           585:                (job_t*)callback_job_create_with_prio(
        !           586:                        (callback_job_cb_t)initiate, this, NULL,
        !           587:                        (callback_job_cancel_t)return_false, JOB_PRIO_CRITICAL));
        !           588: 
        !           589:        return &this->public;
        !           590: }

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