Annotation of embedaddon/strongswan/src/libcharon/network/receiver.c, revision 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>