diff options
author | Yves-Alexis Perez <corsac@debian.org> | 2016-07-16 15:19:53 +0200 |
---|---|---|
committer | Yves-Alexis Perez <corsac@debian.org> | 2016-07-16 15:19:53 +0200 |
commit | bf372706c469764d59e9f29c39e3ecbebd72b8d2 (patch) | |
tree | 0f0e296e2d50e4a7faf99ae6fa428d2681e81ea1 /src/libcharon/sa/ikev1/task_manager_v1.c | |
parent | 518dd33c94e041db0444c7d1f33da363bb8e3faf (diff) | |
download | vyos-strongswan-bf372706c469764d59e9f29c39e3ecbebd72b8d2.tar.gz vyos-strongswan-bf372706c469764d59e9f29c39e3ecbebd72b8d2.zip |
Imported Upstream version 5.5.0
Diffstat (limited to 'src/libcharon/sa/ikev1/task_manager_v1.c')
-rw-r--r-- | src/libcharon/sa/ikev1/task_manager_v1.c | 100 |
1 files changed, 61 insertions, 39 deletions
diff --git a/src/libcharon/sa/ikev1/task_manager_v1.c b/src/libcharon/sa/ikev1/task_manager_v1.c index 3c601a4fa..b0c4f5f84 100644 --- a/src/libcharon/sa/ikev1/task_manager_v1.c +++ b/src/libcharon/sa/ikev1/task_manager_v1.c @@ -1,7 +1,7 @@ /* - * Copyright (C) 2007-2015 Tobias Brunner + * Copyright (C) 2007-2016 Tobias Brunner * Copyright (C) 2007-2011 Martin Willi - * Hochschule fuer Technik Rapperswil + * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -67,7 +67,7 @@ struct exchange_t { /** * Message ID used for this transaction */ - u_int32_t mid; + uint32_t mid; /** * generated packet for retransmission @@ -104,12 +104,12 @@ struct private_task_manager_t { /** * Message ID of the last response */ - u_int32_t mid; + uint32_t mid; /** * Hash of a previously received message */ - u_int32_t hash; + uint32_t hash; /** * packet(s) for retransmission @@ -119,7 +119,7 @@ struct private_task_manager_t { /** * Sequence number of the last sent message */ - u_int32_t seqnr; + uint32_t seqnr; /** * how many times we have retransmitted so far @@ -135,12 +135,12 @@ struct private_task_manager_t { /** * Message ID of the exchange */ - u_int32_t mid; + uint32_t mid; /** * Hashes of old responses we can ignore */ - u_int32_t old_hashes[MAX_OLD_HASHES]; + uint32_t old_hashes[MAX_OLD_HASHES]; /** * Position in old hash array @@ -150,7 +150,7 @@ struct private_task_manager_t { /** * Sequence number of the last sent message */ - u_int32_t seqnr; + uint32_t seqnr; /** * how many times we have retransmitted so far @@ -212,12 +212,12 @@ struct private_task_manager_t { /** * Sequence number for sending DPD requests */ - u_int32_t dpd_send; + uint32_t dpd_send; /** * Sequence number for received DPD requests */ - u_int32_t dpd_recv; + uint32_t dpd_recv; }; /** @@ -341,11 +341,11 @@ static bool generate_message(private_task_manager_t *this, message_t *message, /** * Retransmit a packet (or its fragments) */ -static status_t retransmit_packet(private_task_manager_t *this, u_int32_t seqnr, +static status_t retransmit_packet(private_task_manager_t *this, uint32_t seqnr, u_int mid, u_int retransmitted, array_t *packets) { packet_t *packet; - u_int32_t t; + uint32_t t; array_get(packets, 0, &packet); if (retransmitted > this->retransmit_tries) @@ -354,14 +354,15 @@ static status_t retransmit_packet(private_task_manager_t *this, u_int32_t seqnr, charon->bus->alert(charon->bus, ALERT_RETRANSMIT_SEND_TIMEOUT, packet); return DESTROY_ME; } - t = (u_int32_t)(this->retransmit_timeout * 1000.0 * + t = (uint32_t)(this->retransmit_timeout * 1000.0 * pow(this->retransmit_base, retransmitted)); if (retransmitted) { DBG1(DBG_IKE, "sending retransmit %u of %s message ID %u, seq %u", retransmitted, seqnr < RESPONDING_SEQ ? "request" : "response", mid, seqnr < RESPONDING_SEQ ? seqnr : seqnr - RESPONDING_SEQ); - charon->bus->alert(charon->bus, ALERT_RETRANSMIT_SEND, packet); + charon->bus->alert(charon->bus, ALERT_RETRANSMIT_SEND, packet, + retransmitted); } send_packets(this, packets); lib->scheduler->schedule_job_ms(lib->scheduler, (job_t*) @@ -370,7 +371,7 @@ static status_t retransmit_packet(private_task_manager_t *this, u_int32_t seqnr, } METHOD(task_manager_t, retransmit, status_t, - private_task_manager_t *this, u_int32_t seqnr) + private_task_manager_t *this, uint32_t seqnr) { status_t status = SUCCESS; @@ -514,26 +515,26 @@ METHOD(task_manager_t, initiate, status_t, new_mid = TRUE; break; } - if (!mode_config_expected(this) && - activate_task(this, TASK_QUICK_MODE)) + if (activate_task(this, TASK_ISAKMP_DELETE)) { - exchange = QUICK_MODE; + exchange = INFORMATIONAL_V1; new_mid = TRUE; break; } - if (activate_task(this, TASK_INFORMATIONAL)) + if (activate_task(this, TASK_QUICK_DELETE)) { exchange = INFORMATIONAL_V1; new_mid = TRUE; break; } - if (activate_task(this, TASK_QUICK_DELETE)) + if (!mode_config_expected(this) && + activate_task(this, TASK_QUICK_MODE)) { - exchange = INFORMATIONAL_V1; + exchange = QUICK_MODE; new_mid = TRUE; break; } - if (activate_task(this, TASK_ISAKMP_DELETE)) + if (activate_task(this, TASK_INFORMATIONAL)) { exchange = INFORMATIONAL_V1; new_mid = TRUE; @@ -807,7 +808,7 @@ static void send_notify(private_task_manager_t *this, message_t *request, message_t *response; array_t *packets = NULL; host_t *me, *other; - u_int32_t mid; + uint32_t mid; if (request->get_exchange_type(request) == INFORMATIONAL_V1) { /* don't respond to INFORMATIONAL requests to avoid a notify war */ @@ -857,7 +858,7 @@ static bool process_dpd(private_task_manager_t *this, message_t *message) { notify_payload_t *notify; notify_type_t type; - u_int32_t seq; + uint32_t seq; chunk_t data; type = DPD_R_U_THERE; @@ -910,7 +911,7 @@ static bool process_dpd(private_task_manager_t *this, message_t *message) * Check if we already have a quick mode task queued for the exchange with the * given message ID */ -static bool have_quick_mode_task(private_task_manager_t *this, u_int32_t mid) +static bool have_quick_mode_task(private_task_manager_t *this, uint32_t mid) { enumerator_t *enumerator; quick_mode_t *qm; @@ -935,9 +936,9 @@ static bool have_quick_mode_task(private_task_manager_t *this, u_int32_t mid) } /** - * Check if we still have an aggressive mode task queued + * Check if we still have a specific task queued */ -static bool have_aggressive_mode_task(private_task_manager_t *this) +static bool have_task_queued(private_task_manager_t *this, task_type_t type) { enumerator_t *enumerator; task_t *task; @@ -946,7 +947,7 @@ static bool have_aggressive_mode_task(private_task_manager_t *this) enumerator = this->passive_tasks->create_enumerator(this->passive_tasks); while (enumerator->enumerate(enumerator, &task)) { - if (task->get_type(task) == TASK_AGGRESSIVE_MODE) + if (task->get_type(task) == type) { found = TRUE; break; @@ -1180,6 +1181,12 @@ static status_t process_response(private_task_manager_t *this, } enumerator->destroy(enumerator); + if (this->initiating.retransmitted) + { + packet_t *packet = NULL; + array_get(this->initiating.packets, 0, &packet); + charon->bus->alert(charon->bus, ALERT_RETRANSMIT_SEND_CLEARED, packet); + } this->initiating.type = EXCHANGE_TYPE_UNDEFINED; clear_packets(this->initiating.packets); @@ -1305,7 +1312,7 @@ static status_t queue_message(private_task_manager_t *this, message_t *msg) METHOD(task_manager_t, process_message, status_t, private_task_manager_t *this, message_t *msg) { - u_int32_t hash, mid, i; + uint32_t hash, mid, i; host_t *me, *other; status_t status; @@ -1405,7 +1412,7 @@ METHOD(task_manager_t, process_message, status_t, /* drop XAuth/Mode Config/Quick Mode messages until we received the last * Aggressive Mode message. since Informational messages are not * retransmitted we queue them. */ - if (have_aggressive_mode_task(this)) + if (have_task_queued(this, TASK_AGGRESSIVE_MODE)) { if (msg->get_exchange_type(msg) == INFORMATIONAL_V1) { @@ -1427,6 +1434,13 @@ METHOD(task_manager_t, process_message, status_t, return queue_message(this, msg); } + /* some peers send INITIAL_CONTACT notifies during XAuth, cache it */ + if (have_task_queued(this, TASK_XAUTH) && + msg->get_exchange_type(msg) == INFORMATIONAL_V1) + { + return queue_message(this, msg); + } + msg->set_request(msg, TRUE); charon->bus->message(charon->bus, msg, TRUE, FALSE); status = parse_message(this, msg); @@ -1499,8 +1513,8 @@ static bool has_queued(private_task_manager_t *this, task_type_t type) return found; } -METHOD(task_manager_t, queue_task, void, - private_task_manager_t *this, task_t *task) +METHOD(task_manager_t, queue_task_delayed, void, + private_task_manager_t *this, task_t *task, uint32_t delay) { task_type_t type = task->get_type(task); @@ -1521,6 +1535,12 @@ METHOD(task_manager_t, queue_task, void, this->queued_tasks->insert_last(this->queued_tasks, task); } +METHOD(task_manager_t, queue_task, void, + private_task_manager_t *this, task_t *task) +{ + queue_task_delayed(this, task, 0); +} + METHOD(task_manager_t, queue_ike, void, private_task_manager_t *this) { @@ -1660,7 +1680,7 @@ METHOD(task_manager_t, queue_mobike, void, } METHOD(task_manager_t, queue_child, void, - private_task_manager_t *this, child_cfg_t *cfg, u_int32_t reqid, + private_task_manager_t *this, child_cfg_t *cfg, uint32_t reqid, traffic_selector_t *tsi, traffic_selector_t *tsr) { quick_mode_t *task; @@ -1739,7 +1759,7 @@ static traffic_selector_t* get_first_ts(child_sa_t *child_sa, bool local) } METHOD(task_manager_t, queue_child_rekey, void, - private_task_manager_t *this, protocol_id_t protocol, u_int32_t spi) + private_task_manager_t *this, protocol_id_t protocol, uint32_t spi) { child_sa_t *child_sa; child_cfg_t *cfg; @@ -1754,6 +1774,7 @@ METHOD(task_manager_t, queue_child_rekey, void, { if (is_redundant(this, child_sa)) { + child_sa->set_state(child_sa, CHILD_REKEYED); queue_task(this, (task_t*)quick_delete_create(this->ike_sa, protocol, spi, FALSE, FALSE)); } @@ -1774,7 +1795,7 @@ METHOD(task_manager_t, queue_child_rekey, void, } METHOD(task_manager_t, queue_child_delete, void, - private_task_manager_t *this, protocol_id_t protocol, u_int32_t spi, + private_task_manager_t *this, protocol_id_t protocol, uint32_t spi, bool expired) { queue_task(this, (task_t*)quick_delete_create(this->ike_sa, protocol, @@ -1785,7 +1806,7 @@ METHOD(task_manager_t, queue_dpd, void, private_task_manager_t *this) { peer_cfg_t *peer_cfg; - u_int32_t t, retransmit; + uint32_t t, retransmit; queue_task(this, (task_t*)isakmp_dpd_create(this->ike_sa, DPD_R_U_THERE, this->dpd_send++)); @@ -1798,7 +1819,7 @@ METHOD(task_manager_t, queue_dpd, void, /* use the same timeout as a retransmitting IKE message would have */ for (retransmit = 0; retransmit <= this->retransmit_tries; retransmit++) { - t += (u_int32_t)(this->retransmit_timeout * 1000.0 * + t += (uint32_t)(this->retransmit_timeout * 1000.0 * pow(this->retransmit_base, retransmit)); } } @@ -1871,7 +1892,7 @@ METHOD(task_manager_t, incr_mid, void, } METHOD(task_manager_t, reset, void, - private_task_manager_t *this, u_int32_t initiate, u_int32_t respond) + private_task_manager_t *this, uint32_t initiate, uint32_t respond) { enumerator_t *enumerator; task_t *task; @@ -1960,6 +1981,7 @@ task_manager_v1_t *task_manager_v1_create(ike_sa_t *ike_sa) .task_manager = { .process_message = _process_message, .queue_task = _queue_task, + .queue_task_delayed = _queue_task_delayed, .queue_ike = _queue_ike, .queue_ike_rekey = _queue_ike_rekey, .queue_ike_reauth = _queue_ike_reauth, |