Annotation of embedaddon/strongswan/src/libcharon/network/receiver.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2008-2012 Tobias Brunner
                      3:  * Copyright (C) 2005-2006 Martin Willi
                      4:  * Copyright (C) 2005 Jan Hutter
                      5:  * HSR Hochschule fuer Technik Rapperswil
                      6:  *
                      7:  * This program is free software; you can redistribute it and/or modify it
                      8:  * under the terms of the GNU General Public License as published by the
                      9:  * Free Software Foundation; either version 2 of the License, or (at your
                     10:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                     11:  *
                     12:  * This program is distributed in the hope that it will be useful, but
                     13:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     14:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     15:  * for more details.
                     16:  */
                     17: 
                     18: #include <stdlib.h>
                     19: #include <unistd.h>
                     20: 
                     21: #include "receiver.h"
                     22: 
                     23: #include <daemon.h>
                     24: #include <network/socket.h>
                     25: #include <processing/jobs/job.h>
                     26: #include <processing/jobs/process_message_job.h>
                     27: #include <processing/jobs/callback_job.h>
                     28: #include <crypto/hashers/hasher.h>
                     29: #include <threading/mutex.h>
                     30: #include <networking/packet.h>
                     31: 
                     32: /** lifetime of a cookie, in seconds */
                     33: #define COOKIE_LIFETIME 10
                     34: /** time we wait before disabling cookies */
                     35: #define COOKIE_CALMDOWN_DELAY 10
                     36: /** how many times to reuse the secret */
                     37: #define COOKIE_REUSE 10000
                     38: /** default value for private_receiver_t.cookie_threshold */
                     39: #define COOKIE_THRESHOLD_DEFAULT 10
                     40: /** default value for private_receiver_t.block_threshold */
                     41: #define BLOCK_THRESHOLD_DEFAULT 5
                     42: /** length of the secret to use for cookie calculation */
                     43: #define SECRET_LENGTH 16
                     44: /** Length of a notify payload header */
                     45: #define NOTIFY_PAYLOAD_HEADER_LENGTH 8
                     46: 
                     47: typedef struct private_receiver_t private_receiver_t;
                     48: 
                     49: /**
                     50:  * Private data of a receiver_t object.
                     51:  */
                     52: struct private_receiver_t {
                     53:        /**
                     54:         * Public part of a receiver_t object.
                     55:         */
                     56:        receiver_t public;
                     57: 
                     58:        /**
                     59:         * Registered callback for ESP packets
                     60:         */
                     61:        struct {
                     62:                receiver_esp_cb_t cb;
                     63:                void *data;
                     64:        } esp_cb;
                     65: 
                     66:        /**
                     67:         * Mutex for ESP callback
                     68:         */
                     69:        mutex_t *esp_cb_mutex;
                     70: 
                     71:        /**
                     72:         * current secret to use for cookie calculation
                     73:         */
                     74:        char secret[SECRET_LENGTH];
                     75: 
                     76:        /**
                     77:         * previous secret used to verify older cookies
                     78:         */
                     79:        char secret_old[SECRET_LENGTH];
                     80: 
                     81:        /**
                     82:         * how many times we have used "secret" so far
                     83:         */
                     84:        uint32_t secret_used;
                     85: 
                     86:        /**
                     87:         * time we did the cookie switch
                     88:         */
                     89:        uint32_t secret_switch;
                     90: 
                     91:        /**
                     92:         * time offset to use, hides our system time
                     93:         */
                     94:        uint32_t secret_offset;
                     95: 
                     96:        /**
                     97:         * the RNG to use for secret generation
                     98:         */
                     99:        rng_t *rng;
                    100: 
                    101:        /**
                    102:         * hasher to use for cookie calculation
                    103:         */
                    104:        hasher_t *hasher;
                    105: 
                    106:        /**
                    107:         * require cookies after this many half open IKE_SAs
                    108:         */
                    109:        uint32_t cookie_threshold;
                    110: 
                    111:        /**
                    112:         * timestamp of last cookie requested
                    113:         */
                    114:        time_t last_cookie;
                    115: 
                    116:        /**
                    117:         * how many half open IKE_SAs per peer before blocking
                    118:         */
                    119:        uint32_t block_threshold;
                    120: 
                    121:        /**
                    122:         * Drop IKE_SA_INIT requests if processor job load exceeds this limit
                    123:         */
                    124:        u_int init_limit_job_load;
                    125: 
                    126:        /**
                    127:         * Drop IKE_SA_INIT requests if half open IKE_SA count exceeds this limit
                    128:         */
                    129:        u_int init_limit_half_open;
                    130: 
                    131:        /**
                    132:         * Delay for receiving incoming packets, to simulate larger RTT
                    133:         */
                    134:        int receive_delay;
                    135: 
                    136:        /**
                    137:         * Specific message type to delay, 0 for any
                    138:         */
                    139:        int receive_delay_type;
                    140: 
                    141:        /**
                    142:         * Delay request messages?
                    143:         */
                    144:        bool receive_delay_request;
                    145: 
                    146:        /**
                    147:         * Delay response messages?
                    148:         */
                    149:        bool receive_delay_response;
                    150: 
                    151:        /**
                    152:         * Endpoint is allowed to act as an initiator only
                    153:         */
                    154:        bool initiator_only;
                    155: 
                    156: };
                    157: 
                    158: /**
                    159:  * send a notify back to the sender
                    160:  */
                    161: static void send_notify(message_t *request, int major, exchange_type_t exchange,
                    162:                                                notify_type_t type, chunk_t data)
                    163: {
                    164:        ike_sa_id_t *ike_sa_id;
                    165:        message_t *response;
                    166:        host_t *src, *dst;
                    167:        packet_t *packet;
                    168: 
                    169:        response = message_create(major, 0);
                    170:        response->set_exchange_type(response, exchange);
                    171:        response->add_notify(response, FALSE, type, data);
                    172:        dst = request->get_source(request);
                    173:        src = request->get_destination(request);
                    174:        response->set_source(response, src->clone(src));
                    175:        response->set_destination(response, dst->clone(dst));
                    176:        if (major == IKEV2_MAJOR_VERSION)
                    177:        {
                    178:                response->set_request(response, FALSE);
                    179:                response->set_message_id(response, request->get_message_id(request));
                    180:        }
                    181:        ike_sa_id = request->get_ike_sa_id(request);
                    182:        ike_sa_id->switch_initiator(ike_sa_id);
                    183:        response->set_ike_sa_id(response, ike_sa_id);
                    184:        if (response->generate(response, NULL, &packet) == SUCCESS)
                    185:        {
                    186:                charon->sender->send(charon->sender, packet);
                    187:        }
                    188:        response->destroy(response);
                    189: }
                    190: 
                    191: /**
                    192:  * build a cookie
                    193:  */
                    194: static bool cookie_build(private_receiver_t *this, message_t *message,
                    195:                                                 uint32_t t, chunk_t secret, chunk_t *cookie)
                    196: {
                    197:        uint64_t spi = message->get_initiator_spi(message);
                    198:        host_t *ip = message->get_source(message);
                    199:        chunk_t input, hash;
                    200: 
                    201:        /* COOKIE = t | sha1( IPi | SPIi | t | secret ) */
                    202:        input = chunk_cata("cccc", ip->get_address(ip), chunk_from_thing(spi),
                    203:                                          chunk_from_thing(t), secret);
                    204:        hash = chunk_alloca(this->hasher->get_hash_size(this->hasher));
                    205:        if (!this->hasher->get_hash(this->hasher, input, hash.ptr))
                    206:        {
                    207:                return FALSE;
                    208:        }
                    209:        *cookie = chunk_cat("cc", chunk_from_thing(t), hash);
                    210:        return TRUE;
                    211: }
                    212: 
                    213: /**
                    214:  * verify a received cookie
                    215:  */
                    216: static bool cookie_verify(private_receiver_t *this, message_t *message,
                    217:                                                  chunk_t cookie)
                    218: {
                    219:        uint32_t t, now;
                    220:        chunk_t reference;
                    221:        chunk_t secret;
                    222: 
                    223:        now = time_monotonic(NULL);
                    224:        t = *(uint32_t*)cookie.ptr;
                    225: 
                    226:        if (cookie.len != sizeof(uint32_t) +
                    227:                        this->hasher->get_hash_size(this->hasher) ||
                    228:                t < now - this->secret_offset - COOKIE_LIFETIME)
                    229:        {
                    230:                DBG2(DBG_NET, "received cookie lifetime expired, rejecting");
                    231:                return FALSE;
                    232:        }
                    233: 
                    234:        /* check if cookie is derived from old_secret */
                    235:        if (t + this->secret_offset > this->secret_switch)
                    236:        {
                    237:                secret = chunk_from_thing(this->secret);
                    238:        }
                    239:        else
                    240:        {
                    241:                secret = chunk_from_thing(this->secret_old);
                    242:        }
                    243: 
                    244:        /* compare own calculation against received */
                    245:        if (!cookie_build(this, message, t, secret, &reference))
                    246:        {
                    247:                return FALSE;
                    248:        }
                    249:        if (chunk_equals_const(reference, cookie))
                    250:        {
                    251:                chunk_free(&reference);
                    252:                return TRUE;
                    253:        }
                    254:        chunk_free(&reference);
                    255:        return FALSE;
                    256: }
                    257: 
                    258: /**
                    259:  * Check if a valid cookie found
                    260:  */
                    261: static bool check_cookie(private_receiver_t *this, message_t *message)
                    262: {
                    263:        chunk_t data;
                    264: 
                    265:        /* check for a cookie. We don't use our parser here and do it
                    266:         * quick and dirty for performance reasons.
                    267:         * we assume the cookie is the first payload (which is a MUST), and
                    268:         * the cookie's SPI length is zero. */
                    269:        data = message->get_packet_data(message);
                    270:        if (data.len <
                    271:                 IKE_HEADER_LENGTH + NOTIFY_PAYLOAD_HEADER_LENGTH +
                    272:                 sizeof(uint32_t) + this->hasher->get_hash_size(this->hasher) ||
                    273:                *(data.ptr + 16) != PLV2_NOTIFY ||
                    274:                *(uint16_t*)(data.ptr + IKE_HEADER_LENGTH + 6) != htons(COOKIE))
                    275:        {
                    276:                /* no cookie found */
                    277:                return FALSE;
                    278:        }
                    279:        data.ptr += IKE_HEADER_LENGTH + NOTIFY_PAYLOAD_HEADER_LENGTH;
                    280:        data.len = sizeof(uint32_t) + this->hasher->get_hash_size(this->hasher);
                    281:        if (!cookie_verify(this, message, data))
                    282:        {
                    283:                DBG2(DBG_NET, "found cookie, but content invalid");
                    284:                return FALSE;
                    285:        }
                    286:        return TRUE;
                    287: }
                    288: 
                    289: /**
                    290:  * Check if we currently require cookies
                    291:  */
                    292: static bool cookie_required(private_receiver_t *this,
                    293:                                                        u_int half_open, uint32_t now)
                    294: {
                    295:        if (this->cookie_threshold && half_open >= this->cookie_threshold)
                    296:        {
                    297:                this->last_cookie = now;
                    298:                return TRUE;
                    299:        }
                    300:        if (this->last_cookie && now < this->last_cookie + COOKIE_CALMDOWN_DELAY)
                    301:        {
                    302:                /* We don't disable cookies unless we haven't seen IKE_SA_INITs
                    303:                 * for COOKIE_CALMDOWN_DELAY seconds. This avoids jittering between
                    304:                 * cookie on / cookie off states, which is problematic. Consider the
                    305:                 * following: A legitimate initiator sends a IKE_SA_INIT while we
                    306:                 * are under a DoS attack. If we toggle our cookie behavior,
                    307:                 * multiple retransmits of this IKE_SA_INIT might get answered with
                    308:                 * and without cookies. The initiator goes on and retries with
                    309:                 * a cookie, but it can't know if the completing IKE_SA_INIT response
                    310:                 * is to its IKE_SA_INIT request with or without cookies. This is
                    311:                 * problematic, as the cookie is part of AUTH payload data.
                    312:                 */
                    313:                this->last_cookie = now;
                    314:                return TRUE;
                    315:        }
                    316:        return FALSE;
                    317: }
                    318: 
                    319: /**
                    320:  * Check if we should drop IKE_SA_INIT because of cookie/overload checking
                    321:  */
                    322: static bool drop_ike_sa_init(private_receiver_t *this, message_t *message)
                    323: {
                    324:        u_int half_open;
                    325:        uint32_t now;
                    326: 
                    327:        now = time_monotonic(NULL);
                    328:        half_open = charon->ike_sa_manager->get_half_open_count(
                    329:                                                                                charon->ike_sa_manager, NULL, TRUE);
                    330: 
                    331:        /* check for cookies in IKEv2 */
                    332:        if (message->get_major_version(message) == IKEV2_MAJOR_VERSION &&
                    333:                cookie_required(this, half_open, now) && !check_cookie(this, message))
                    334:        {
                    335:                chunk_t cookie;
                    336: 
                    337:                DBG2(DBG_NET, "received packet from: %#H to %#H",
                    338:                         message->get_source(message),
                    339:                         message->get_destination(message));
                    340:                if (!cookie_build(this, message, now - this->secret_offset,
                    341:                                                  chunk_from_thing(this->secret), &cookie))
                    342:                {
                    343:                        return TRUE;
                    344:                }
                    345:                DBG2(DBG_NET, "sending COOKIE notify to %H",
                    346:                         message->get_source(message));
                    347:                send_notify(message, IKEV2_MAJOR_VERSION, IKE_SA_INIT, COOKIE, cookie);
                    348:                chunk_free(&cookie);
                    349:                if (++this->secret_used > COOKIE_REUSE)
                    350:                {
                    351:                        char secret[SECRET_LENGTH];
                    352: 
                    353:                        DBG1(DBG_NET, "generating new cookie secret after %d uses",
                    354:                                 this->secret_used);
                    355:                        if (this->rng->get_bytes(this->rng, SECRET_LENGTH, secret))
                    356:                        {
                    357:                                memcpy(this->secret_old, this->secret, SECRET_LENGTH);
                    358:                                memcpy(this->secret, secret, SECRET_LENGTH);
                    359:                                memwipe(secret, SECRET_LENGTH);
                    360:                                this->secret_switch = now;
                    361:                                this->secret_used = 0;
                    362:                        }
                    363:                        else
                    364:                        {
                    365:                                DBG1(DBG_NET, "failed to allocated cookie secret, keeping old");
                    366:                        }
                    367:                }
                    368:                return TRUE;
                    369:        }
                    370: 
                    371:        /* check if peer has too many IKE_SAs half open */
                    372:        if (this->block_threshold &&
                    373:                charon->ike_sa_manager->get_half_open_count(charon->ike_sa_manager,
                    374:                                message->get_source(message), TRUE) >= this->block_threshold)
                    375:        {
                    376:                DBG1(DBG_NET, "ignoring IKE_SA setup from %H, "
                    377:                         "peer too aggressive", message->get_source(message));
                    378:                return TRUE;
                    379:        }
                    380: 
                    381:        /* check if global half open IKE_SA limit reached */
                    382:        if (this->init_limit_half_open &&
                    383:            half_open >= this->init_limit_half_open)
                    384:        {
                    385:                DBG1(DBG_NET, "ignoring IKE_SA setup from %H, half open IKE_SA "
                    386:                         "count of %d exceeds limit of %d", message->get_source(message),
                    387:                         half_open, this->init_limit_half_open);
                    388:                return TRUE;
                    389:        }
                    390: 
                    391:        /* check if job load acceptable */
                    392:        if (this->init_limit_job_load)
                    393:        {
                    394:                u_int jobs = 0, i;
                    395: 
                    396:                for (i = 0; i < JOB_PRIO_MAX; i++)
                    397:                {
                    398:                        jobs += lib->processor->get_job_load(lib->processor, i);
                    399:                }
                    400:                if (jobs > this->init_limit_job_load)
                    401:                {
                    402:                        DBG1(DBG_NET, "ignoring IKE_SA setup from %H, job load of %d "
                    403:                                 "exceeds limit of %d", message->get_source(message),
                    404:                                 jobs, this->init_limit_job_load);
                    405:                        return TRUE;
                    406:                }
                    407:        }
                    408:        return FALSE;
                    409: }
                    410: 
                    411: /**
                    412:  * Job callback to receive packets
                    413:  */
                    414: static job_requeue_t receive_packets(private_receiver_t *this)
                    415: {
                    416:        ike_sa_id_t *id;
                    417:        packet_t *packet;
                    418:        message_t *message;
                    419:        host_t *src, *dst;
                    420:        status_t status;
                    421:        bool supported = TRUE;
                    422:        chunk_t data, marker = chunk_from_chars(0x00, 0x00, 0x00, 0x00);
                    423: 
                    424:        /* read in a packet */
                    425:        status = charon->socket->receive(charon->socket, &packet);
                    426:        if (status == NOT_SUPPORTED)
                    427:        {
                    428:                return JOB_REQUEUE_NONE;
                    429:        }
                    430:        else if (status != SUCCESS)
                    431:        {
                    432:                DBG2(DBG_NET, "receiving from socket failed!");
                    433:                return JOB_REQUEUE_FAIR;
                    434:        }
                    435: 
                    436:        data = packet->get_data(packet);
                    437:        if (data.len == 1 && data.ptr[0] == 0xFF)
                    438:        {       /* silently drop NAT-T keepalives */
                    439:                packet->destroy(packet);
                    440:                return JOB_REQUEUE_DIRECT;
                    441:        }
                    442:        else if (data.len < marker.len)
                    443:        {       /* drop packets that are too small */
                    444:                DBG3(DBG_NET, "received packet is too short (%d bytes)", data.len);
                    445:                packet->destroy(packet);
                    446:                return JOB_REQUEUE_DIRECT;
                    447:        }
                    448: 
                    449:        dst = packet->get_destination(packet);
                    450:        src = packet->get_source(packet);
                    451:        if (!charon->kernel->all_interfaces_usable(charon->kernel)
                    452:                && !charon->kernel->get_interface(charon->kernel, dst, NULL))
                    453:        {
                    454:                DBG3(DBG_NET, "received packet from %#H to %#H on ignored interface",
                    455:                         src, dst);
                    456:                packet->destroy(packet);
                    457:                return JOB_REQUEUE_DIRECT;
                    458:        }
                    459: 
                    460:        /* if neither source nor destination port is 500 we assume an IKE packet
                    461:         * with Non-ESP marker or an ESP packet */
                    462:        if (dst->get_port(dst) != IKEV2_UDP_PORT &&
                    463:                src->get_port(src) != IKEV2_UDP_PORT)
                    464:        {
                    465:                if (memeq(data.ptr, marker.ptr, marker.len))
                    466:                {       /* remove Non-ESP marker */
                    467:                        packet->skip_bytes(packet, marker.len);
                    468:                }
                    469:                else
                    470:                {       /* this seems to be an ESP packet */
                    471:                        this->esp_cb_mutex->lock(this->esp_cb_mutex);
                    472:                        if (this->esp_cb.cb)
                    473:                        {
                    474:                                this->esp_cb.cb(this->esp_cb.data, packet);
                    475:                        }
                    476:                        else
                    477:                        {
                    478:                                packet->destroy(packet);
                    479:                        }
                    480:                        this->esp_cb_mutex->unlock(this->esp_cb_mutex);
                    481:                        return JOB_REQUEUE_DIRECT;
                    482:                }
                    483:        }
                    484: 
                    485:        /* parse message header */
                    486:        message = message_create_from_packet(packet);
                    487:        if (message->parse_header(message) != SUCCESS)
                    488:        {
                    489:                DBG1(DBG_NET, "received invalid IKE header from %H - ignored",
                    490:                         packet->get_source(packet));
                    491:                charon->bus->alert(charon->bus, ALERT_PARSE_ERROR_HEADER, message);
                    492:                message->destroy(message);
                    493:                return JOB_REQUEUE_DIRECT;
                    494:        }
                    495: 
                    496:        /* check IKE major version */
                    497:        switch (message->get_major_version(message))
                    498:        {
                    499:                case IKEV2_MAJOR_VERSION:
                    500: #ifndef USE_IKEV2
                    501:                        if (message->get_exchange_type(message) == IKE_SA_INIT &&
                    502:                                message->get_request(message))
                    503:                        {
                    504:                                send_notify(message, IKEV1_MAJOR_VERSION, INFORMATIONAL_V1,
                    505:                                                        INVALID_MAJOR_VERSION, chunk_empty);
                    506:                                supported = FALSE;
                    507:                        }
                    508: #endif /* USE_IKEV2 */
                    509:                        break;
                    510:                case IKEV1_MAJOR_VERSION:
                    511: #ifndef USE_IKEV1
                    512:                        if (message->get_exchange_type(message) == ID_PROT ||
                    513:                                message->get_exchange_type(message) == AGGRESSIVE)
                    514:                        {
                    515:                                send_notify(message, IKEV2_MAJOR_VERSION, INFORMATIONAL,
                    516:                                                        INVALID_MAJOR_VERSION, chunk_empty);
                    517:                                supported = FALSE;
                    518:                        }
                    519: #endif /* USE_IKEV1 */
                    520:                        break;
                    521:                default:
                    522: #ifdef USE_IKEV2
                    523:                        send_notify(message, IKEV2_MAJOR_VERSION,
                    524:                                                message->get_exchange_type(message),
                    525:                                                INVALID_MAJOR_VERSION, chunk_empty);
                    526: #elif defined(USE_IKEV1)
                    527:                        send_notify(message, IKEV1_MAJOR_VERSION, INFORMATIONAL_V1,
                    528:                                                INVALID_MAJOR_VERSION, chunk_empty);
                    529: #endif /* USE_IKEV1 */
                    530:                        supported = FALSE;
                    531:                        break;
                    532:        }
                    533:        if (!supported)
                    534:        {
                    535:                DBG1(DBG_NET, "received unsupported IKE version %d.%d from %H, sending "
                    536:                         "INVALID_MAJOR_VERSION", message->get_major_version(message),
                    537:                         message->get_minor_version(message), packet->get_source(packet));
                    538:                message->destroy(message);
                    539:                return JOB_REQUEUE_DIRECT;
                    540:        }
                    541:        if (message->get_request(message) &&
                    542:                message->get_exchange_type(message) == IKE_SA_INIT)
                    543:        {
                    544:                id = message->get_ike_sa_id(message);
                    545:                if (this->initiator_only || !id->is_initiator(id) ||
                    546:                        drop_ike_sa_init(this, message))
                    547:                {
                    548:                        message->destroy(message);
                    549:                        return JOB_REQUEUE_DIRECT;
                    550:                }
                    551:        }
                    552:        if (message->get_exchange_type(message) == ID_PROT ||
                    553:                message->get_exchange_type(message) == AGGRESSIVE)
                    554:        {
                    555:                id = message->get_ike_sa_id(message);
                    556:                if (id->get_responder_spi(id) == 0 &&
                    557:                   (this->initiator_only || drop_ike_sa_init(this, message)))
                    558:                {
                    559:                        message->destroy(message);
                    560:                        return JOB_REQUEUE_DIRECT;
                    561:                }
                    562:        }
                    563: 
                    564:        if (this->receive_delay)
                    565:        {
                    566:                if (this->receive_delay_type == 0 ||
                    567:                        this->receive_delay_type == message->get_exchange_type(message))
                    568:                {
                    569:                        if ((message->get_request(message) && this->receive_delay_request) ||
                    570:                                (!message->get_request(message) && this->receive_delay_response))
                    571:                        {
                    572:                                DBG1(DBG_NET, "using receive delay: %dms",
                    573:                                         this->receive_delay);
                    574:                                lib->scheduler->schedule_job_ms(lib->scheduler,
                    575:                                                                (job_t*)process_message_job_create(message),
                    576:                                                                this->receive_delay);
                    577:                                return JOB_REQUEUE_DIRECT;
                    578:                        }
                    579:                }
                    580:        }
                    581:        lib->processor->queue_job(lib->processor,
                    582:                                                          (job_t*)process_message_job_create(message));
                    583:        return JOB_REQUEUE_DIRECT;
                    584: }
                    585: 
                    586: METHOD(receiver_t, add_esp_cb, void,
                    587:        private_receiver_t *this, receiver_esp_cb_t callback, void *data)
                    588: {
                    589:        this->esp_cb_mutex->lock(this->esp_cb_mutex);
                    590:        this->esp_cb.cb = callback;
                    591:        this->esp_cb.data = data;
                    592:        this->esp_cb_mutex->unlock(this->esp_cb_mutex);
                    593: }
                    594: 
                    595: METHOD(receiver_t, del_esp_cb, void,
                    596:        private_receiver_t *this, receiver_esp_cb_t callback)
                    597: {
                    598:        this->esp_cb_mutex->lock(this->esp_cb_mutex);
                    599:        if (this->esp_cb.cb == callback)
                    600:        {
                    601:                this->esp_cb.cb = NULL;
                    602:                this->esp_cb.data = NULL;
                    603:        }
                    604:        this->esp_cb_mutex->unlock(this->esp_cb_mutex);
                    605: }
                    606: 
                    607: METHOD(receiver_t, destroy, void,
                    608:        private_receiver_t *this)
                    609: {
                    610:        this->rng->destroy(this->rng);
                    611:        this->hasher->destroy(this->hasher);
                    612:        this->esp_cb_mutex->destroy(this->esp_cb_mutex);
                    613:        free(this);
                    614: }
                    615: 
                    616: /*
                    617:  * Described in header.
                    618:  */
                    619: receiver_t *receiver_create()
                    620: {
                    621:        private_receiver_t *this;
                    622:        uint32_t now = time_monotonic(NULL);
                    623: 
                    624:        INIT(this,
                    625:                .public = {
                    626:                        .add_esp_cb = _add_esp_cb,
                    627:                        .del_esp_cb = _del_esp_cb,
                    628:                        .destroy = _destroy,
                    629:                },
                    630:                .esp_cb_mutex = mutex_create(MUTEX_TYPE_DEFAULT),
                    631:                .secret_switch = now,
                    632:                .secret_offset = random() % now,
                    633:        );
                    634: 
                    635:        if (lib->settings->get_bool(lib->settings,
                    636:                                                                "%s.dos_protection", TRUE, lib->ns))
                    637:        {
                    638:                this->cookie_threshold = lib->settings->get_int(lib->settings,
                    639:                                        "%s.cookie_threshold", COOKIE_THRESHOLD_DEFAULT, lib->ns);
                    640:                this->block_threshold = lib->settings->get_int(lib->settings,
                    641:                                        "%s.block_threshold", BLOCK_THRESHOLD_DEFAULT, lib->ns);
                    642:        }
                    643:        this->init_limit_job_load = lib->settings->get_int(lib->settings,
                    644:                                        "%s.init_limit_job_load", 0, lib->ns);
                    645:        this->init_limit_half_open = lib->settings->get_int(lib->settings,
                    646:                                        "%s.init_limit_half_open", 0, lib->ns);
                    647:        this->receive_delay = lib->settings->get_int(lib->settings,
                    648:                                        "%s.receive_delay", 0, lib->ns);
                    649:        this->receive_delay_type = lib->settings->get_int(lib->settings,
                    650:                                        "%s.receive_delay_type", 0, lib->ns);
                    651:        this->receive_delay_request = lib->settings->get_bool(lib->settings,
                    652:                                        "%s.receive_delay_request", TRUE, lib->ns);
                    653:        this->receive_delay_response = lib->settings->get_bool(lib->settings,
                    654:                                        "%s.receive_delay_response", TRUE, lib->ns);
                    655:        this->initiator_only = lib->settings->get_bool(lib->settings,
                    656:                                        "%s.initiator_only", FALSE, lib->ns);
                    657: 
                    658:        this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
                    659:        if (!this->hasher)
                    660:        {
                    661:                DBG1(DBG_NET, "creating cookie hasher failed, no hashers supported");
                    662:                free(this);
                    663:                return NULL;
                    664:        }
                    665:        this->rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
                    666:        if (!this->rng)
                    667:        {
                    668:                DBG1(DBG_NET, "creating cookie RNG failed, no RNG supported");
                    669:                this->hasher->destroy(this->hasher);
                    670:                free(this);
                    671:                return NULL;
                    672:        }
                    673:        if (!this->rng->get_bytes(this->rng, SECRET_LENGTH, this->secret))
                    674:        {
                    675:                DBG1(DBG_NET, "creating cookie secret failed");
                    676:                destroy(this);
                    677:                return NULL;
                    678:        }
                    679:        memcpy(this->secret_old, this->secret, SECRET_LENGTH);
                    680: 
                    681:        lib->processor->queue_job(lib->processor,
                    682:                (job_t*)callback_job_create_with_prio((callback_job_cb_t)receive_packets,
                    683:                        this, NULL, (callback_job_cancel_t)return_false, JOB_PRIO_CRITICAL));
                    684: 
                    685:        return &this->public;
                    686: }

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