ike: Use a struct to store retransmission settings
The calculation of the timeout is also shared now and the total timeout in seconds is corrected in case retransmit_base is <= 1. This could make it easier in the future to apply different retransmission settings to messages/exchanges.
This commit is contained in:
@@ -56,15 +56,17 @@ METHOD(plugin_t, get_features, int,
|
|||||||
METHOD(plugin_t, reload, bool,
|
METHOD(plugin_t, reload, bool,
|
||||||
private_kernel_netlink_plugin_t *this)
|
private_kernel_netlink_plugin_t *this)
|
||||||
{
|
{
|
||||||
|
retransmission_t settings;
|
||||||
u_int timeout;
|
u_int timeout;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
|
|
||||||
f = fopen("/proc/sys/net/core/xfrm_acq_expires", "w");
|
f = fopen("/proc/sys/net/core/xfrm_acq_expires", "w");
|
||||||
if (f)
|
if (f)
|
||||||
{
|
{
|
||||||
|
retransmission_parse_default(&settings);
|
||||||
timeout = lib->settings->get_int(lib->settings,
|
timeout = lib->settings->get_int(lib->settings,
|
||||||
"%s.plugins.kernel-netlink.xfrm_acq_expires",
|
"%s.plugins.kernel-netlink.xfrm_acq_expires",
|
||||||
task_manager_total_retransmit_timeout(), lib->ns);
|
retransmission_timeout_total(&settings), lib->ns);
|
||||||
fprintf(f, "%u", timeout);
|
fprintf(f, "%u", timeout);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -196,37 +196,9 @@ struct private_task_manager_t {
|
|||||||
message_t *queued;
|
message_t *queued;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of times we retransmit messages before giving up
|
* Retransmision settings.
|
||||||
*/
|
*/
|
||||||
u_int retransmit_tries;
|
retransmission_t retransmit;
|
||||||
|
|
||||||
/**
|
|
||||||
* Maximum number of tries possible with current retransmission settings
|
|
||||||
* before overflowing the range of uint32_t, which we use for the timeout.
|
|
||||||
* Note that UINT32_MAX milliseconds equal nearly 50 days, so that doesn't
|
|
||||||
* make much sense without retransmit_limit anyway.
|
|
||||||
*/
|
|
||||||
u_int retransmit_tries_max;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retransmission timeout
|
|
||||||
*/
|
|
||||||
double retransmit_timeout;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base to calculate retransmission timeout
|
|
||||||
*/
|
|
||||||
double retransmit_base;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Jitter to apply to calculated retransmit timeout (in percent)
|
|
||||||
*/
|
|
||||||
u_int retransmit_jitter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Limit retransmit timeout to this value
|
|
||||||
*/
|
|
||||||
uint32_t retransmit_limit;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sequence number for sending DPD requests
|
* Sequence number for sending DPD requests
|
||||||
@@ -364,30 +336,16 @@ static status_t retransmit_packet(private_task_manager_t *this, uint32_t seqnr,
|
|||||||
u_int mid, u_int retransmitted, array_t *packets)
|
u_int mid, u_int retransmitted, array_t *packets)
|
||||||
{
|
{
|
||||||
packet_t *packet;
|
packet_t *packet;
|
||||||
uint32_t t = UINT32_MAX, max_jitter;
|
uint32_t t;
|
||||||
|
|
||||||
array_get(packets, 0, &packet);
|
array_get(packets, 0, &packet);
|
||||||
if (retransmitted > this->retransmit_tries)
|
if (retransmitted > this->retransmit.tries)
|
||||||
{
|
{
|
||||||
DBG1(DBG_IKE, "giving up after %u retransmits", retransmitted - 1);
|
DBG1(DBG_IKE, "giving up after %u retransmits", retransmitted - 1);
|
||||||
charon->bus->alert(charon->bus, ALERT_RETRANSMIT_SEND_TIMEOUT, packet);
|
charon->bus->alert(charon->bus, ALERT_RETRANSMIT_SEND_TIMEOUT, packet);
|
||||||
return DESTROY_ME;
|
return DESTROY_ME;
|
||||||
}
|
}
|
||||||
if (!this->retransmit_tries_max ||
|
t = retransmission_timeout(&this->retransmit, retransmitted, TRUE);
|
||||||
retransmitted <= this->retransmit_tries_max)
|
|
||||||
{
|
|
||||||
t = (uint32_t)(this->retransmit_timeout * 1000.0 *
|
|
||||||
pow(this->retransmit_base, retransmitted));
|
|
||||||
}
|
|
||||||
if (this->retransmit_limit)
|
|
||||||
{
|
|
||||||
t = min(t, this->retransmit_limit);
|
|
||||||
}
|
|
||||||
if (this->retransmit_jitter)
|
|
||||||
{
|
|
||||||
max_jitter = (t / 100.0) * this->retransmit_jitter;
|
|
||||||
t -= max_jitter * (random() / (RAND_MAX + 1.0));
|
|
||||||
}
|
|
||||||
if (retransmitted)
|
if (retransmitted)
|
||||||
{
|
{
|
||||||
DBG1(DBG_IKE, "sending retransmit %u of %s message ID %u, seq %u",
|
DBG1(DBG_IKE, "sending retransmit %u of %s message ID %u, seq %u",
|
||||||
@@ -1893,10 +1851,9 @@ METHOD(task_manager_t, queue_dpd, void,
|
|||||||
if (t == 0)
|
if (t == 0)
|
||||||
{
|
{
|
||||||
/* use the same timeout as a retransmitting IKE message would have */
|
/* use the same timeout as a retransmitting IKE message would have */
|
||||||
for (retransmit = 0; retransmit <= this->retransmit_tries; retransmit++)
|
for (retransmit = 0; retransmit <= this->retransmit.tries; retransmit++)
|
||||||
{
|
{
|
||||||
t += (uint32_t)(this->retransmit_timeout * 1000.0 *
|
t += retransmission_timeout(&this->retransmit, retransmit, FALSE);
|
||||||
pow(this->retransmit_base, retransmit));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* compensate for the already elapsed dpd delay */
|
/* compensate for the already elapsed dpd delay */
|
||||||
@@ -2132,16 +2089,6 @@ task_manager_v1_t *task_manager_v1_create(ike_sa_t *ike_sa)
|
|||||||
.queued_tasks = linked_list_create(),
|
.queued_tasks = linked_list_create(),
|
||||||
.active_tasks = linked_list_create(),
|
.active_tasks = linked_list_create(),
|
||||||
.passive_tasks = linked_list_create(),
|
.passive_tasks = linked_list_create(),
|
||||||
.retransmit_tries = lib->settings->get_int(lib->settings,
|
|
||||||
"%s.retransmit_tries", RETRANSMIT_TRIES, lib->ns),
|
|
||||||
.retransmit_timeout = lib->settings->get_double(lib->settings,
|
|
||||||
"%s.retransmit_timeout", RETRANSMIT_TIMEOUT, lib->ns),
|
|
||||||
.retransmit_base = lib->settings->get_double(lib->settings,
|
|
||||||
"%s.retransmit_base", RETRANSMIT_BASE, lib->ns),
|
|
||||||
.retransmit_jitter = min(lib->settings->get_int(lib->settings,
|
|
||||||
"%s.retransmit_jitter", 0, lib->ns), RETRANSMIT_JITTER_MAX),
|
|
||||||
.retransmit_limit = lib->settings->get_int(lib->settings,
|
|
||||||
"%s.retransmit_limit", 0, lib->ns) * 1000,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!this->rng)
|
if (!this->rng)
|
||||||
@@ -2159,11 +2106,7 @@ task_manager_v1_t *task_manager_v1_create(ike_sa_t *ike_sa)
|
|||||||
}
|
}
|
||||||
this->dpd_send &= 0x7FFFFFFF;
|
this->dpd_send &= 0x7FFFFFFF;
|
||||||
|
|
||||||
if (this->retransmit_base > 1)
|
retransmission_parse_default(&this->retransmit);
|
||||||
{ /* based on 1000 * timeout * base^try */
|
|
||||||
this->retransmit_tries_max = log(UINT32_MAX/
|
|
||||||
(1000.0 * this->retransmit_timeout))/
|
|
||||||
log(this->retransmit_base);
|
|
||||||
}
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -165,37 +165,9 @@ struct private_task_manager_t {
|
|||||||
bool reset;
|
bool reset;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of times we retransmit messages before giving up
|
* Retransmission settings.
|
||||||
*/
|
*/
|
||||||
u_int retransmit_tries;
|
retransmission_t retransmit;
|
||||||
|
|
||||||
/**
|
|
||||||
* Maximum number of tries possible with current retransmission settings
|
|
||||||
* before overflowing the range of uint32_t, which we use for the timeout.
|
|
||||||
* Note that UINT32_MAX milliseconds equal nearly 50 days, so that doesn't
|
|
||||||
* make much sense without retransmit_limit anyway.
|
|
||||||
*/
|
|
||||||
u_int retransmit_tries_max;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retransmission timeout
|
|
||||||
*/
|
|
||||||
double retransmit_timeout;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base to calculate retransmission timeout
|
|
||||||
*/
|
|
||||||
double retransmit_base;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Jitter to apply to calculated retransmit timeout (in percent)
|
|
||||||
*/
|
|
||||||
u_int retransmit_jitter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Limit retransmit timeout to this value
|
|
||||||
*/
|
|
||||||
uint32_t retransmit_limit;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use make-before-break instead of break-before-make reauth?
|
* Use make-before-break instead of break-before-make reauth?
|
||||||
@@ -358,7 +330,7 @@ METHOD(task_manager_t, retransmit, status_t,
|
|||||||
if (message_id == this->initiating.mid &&
|
if (message_id == this->initiating.mid &&
|
||||||
array_count(this->initiating.packets))
|
array_count(this->initiating.packets))
|
||||||
{
|
{
|
||||||
uint32_t timeout = UINT32_MAX, max_jitter;
|
uint32_t timeout;
|
||||||
job_t *job;
|
job_t *job;
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
packet_t *packet;
|
packet_t *packet;
|
||||||
@@ -384,7 +356,7 @@ METHOD(task_manager_t, retransmit, status_t,
|
|||||||
|
|
||||||
if (!mobike || !mobike->is_probing(mobike))
|
if (!mobike || !mobike->is_probing(mobike))
|
||||||
{
|
{
|
||||||
if (this->initiating.retransmitted > this->retransmit_tries)
|
if (this->initiating.retransmitted > this->retransmit.tries)
|
||||||
{
|
{
|
||||||
DBG1(DBG_IKE, "giving up after %d retransmits",
|
DBG1(DBG_IKE, "giving up after %d retransmits",
|
||||||
this->initiating.retransmitted - 1);
|
this->initiating.retransmitted - 1);
|
||||||
@@ -392,21 +364,8 @@ METHOD(task_manager_t, retransmit, status_t,
|
|||||||
packet);
|
packet);
|
||||||
return DESTROY_ME;
|
return DESTROY_ME;
|
||||||
}
|
}
|
||||||
if (!this->retransmit_tries_max ||
|
timeout = retransmission_timeout(&this->retransmit,
|
||||||
this->initiating.retransmitted <= this->retransmit_tries_max)
|
this->initiating.retransmitted, TRUE);
|
||||||
{
|
|
||||||
timeout = (uint32_t)(this->retransmit_timeout * 1000.0 *
|
|
||||||
pow(this->retransmit_base, this->initiating.retransmitted));
|
|
||||||
}
|
|
||||||
if (this->retransmit_limit)
|
|
||||||
{
|
|
||||||
timeout = min(timeout, this->retransmit_limit);
|
|
||||||
}
|
|
||||||
if (this->retransmit_jitter)
|
|
||||||
{
|
|
||||||
max_jitter = (timeout / 100.0) * this->retransmit_jitter;
|
|
||||||
timeout -= max_jitter * (random() / (RAND_MAX + 1.0));
|
|
||||||
}
|
|
||||||
if (this->initiating.retransmitted)
|
if (this->initiating.retransmitted)
|
||||||
{
|
{
|
||||||
DBG1(DBG_IKE, "retransmit %d of request with message ID %d",
|
DBG1(DBG_IKE, "retransmit %d of request with message ID %d",
|
||||||
@@ -2625,25 +2584,11 @@ task_manager_v2_t *task_manager_v2_create(ike_sa_t *ike_sa)
|
|||||||
.queued_tasks = array_create(0, 0),
|
.queued_tasks = array_create(0, 0),
|
||||||
.active_tasks = array_create(0, 0),
|
.active_tasks = array_create(0, 0),
|
||||||
.passive_tasks = array_create(0, 0),
|
.passive_tasks = array_create(0, 0),
|
||||||
.retransmit_tries = lib->settings->get_int(lib->settings,
|
|
||||||
"%s.retransmit_tries", RETRANSMIT_TRIES, lib->ns),
|
|
||||||
.retransmit_timeout = lib->settings->get_double(lib->settings,
|
|
||||||
"%s.retransmit_timeout", RETRANSMIT_TIMEOUT, lib->ns),
|
|
||||||
.retransmit_base = lib->settings->get_double(lib->settings,
|
|
||||||
"%s.retransmit_base", RETRANSMIT_BASE, lib->ns),
|
|
||||||
.retransmit_jitter = min(lib->settings->get_int(lib->settings,
|
|
||||||
"%s.retransmit_jitter", 0, lib->ns), RETRANSMIT_JITTER_MAX),
|
|
||||||
.retransmit_limit = lib->settings->get_int(lib->settings,
|
|
||||||
"%s.retransmit_limit", 0, lib->ns) * 1000,
|
|
||||||
.make_before_break = lib->settings->get_bool(lib->settings,
|
.make_before_break = lib->settings->get_bool(lib->settings,
|
||||||
"%s.make_before_break", FALSE, lib->ns),
|
"%s.make_before_break", FALSE, lib->ns),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (this->retransmit_base > 1)
|
retransmission_parse_default(&this->retransmit);
|
||||||
{ /* based on 1000 * timeout * base^try */
|
|
||||||
this->retransmit_tries_max = log(UINT32_MAX/
|
|
||||||
(1000.0 * this->retransmit_timeout))/
|
|
||||||
log(this->retransmit_base);
|
|
||||||
}
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2011 Tobias Brunner
|
* Copyright (C) 2011-2023 Tobias Brunner
|
||||||
*
|
*
|
||||||
* Copyright (C) secunet Security Networks AG
|
* Copyright (C) secunet Security Networks AG
|
||||||
*
|
*
|
||||||
@@ -21,39 +21,64 @@
|
|||||||
#include <sa/ikev2/task_manager_v2.h>
|
#include <sa/ikev2/task_manager_v2.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* See header
|
* Described in header
|
||||||
*/
|
*/
|
||||||
u_int task_manager_total_retransmit_timeout()
|
void retransmission_parse_default(retransmission_t *settings)
|
||||||
{
|
{
|
||||||
double timeout, base, limit = 0, total = 0;
|
settings->timeout = lib->settings->get_double(lib->settings,
|
||||||
int tries, max_tries = 0, i;
|
"%s.retransmit_timeout", RETRANSMIT_TIMEOUT, lib->ns);
|
||||||
|
settings->base = lib->settings->get_double(lib->settings,
|
||||||
|
"%s.retransmit_base", RETRANSMIT_BASE, lib->ns);
|
||||||
|
settings->jitter = min(lib->settings->get_int(lib->settings,
|
||||||
|
"%s.retransmit_jitter", 0, lib->ns), RETRANSMIT_JITTER_MAX);
|
||||||
|
settings->limit = lib->settings->get_int(lib->settings,
|
||||||
|
"%s.retransmit_limit", 0, lib->ns) * 1000;
|
||||||
|
settings->tries = lib->settings->get_int(lib->settings,
|
||||||
|
"%s.retransmit_tries", RETRANSMIT_TRIES, lib->ns);
|
||||||
|
|
||||||
tries = lib->settings->get_int(lib->settings, "%s.retransmit_tries",
|
if (settings->base > 1)
|
||||||
RETRANSMIT_TRIES, lib->ns);
|
{ /* based on 1000 * timeout * base^try */
|
||||||
base = lib->settings->get_double(lib->settings, "%s.retransmit_base",
|
settings->max_tries = log(UINT32_MAX/
|
||||||
RETRANSMIT_BASE, lib->ns);
|
(1000.0 * settings->timeout))/
|
||||||
timeout = lib->settings->get_double(lib->settings, "%s.retransmit_timeout",
|
log(settings->base);
|
||||||
RETRANSMIT_TIMEOUT, lib->ns);
|
|
||||||
limit = lib->settings->get_double(lib->settings, "%s.retransmit_limit",
|
|
||||||
0, lib->ns);
|
|
||||||
|
|
||||||
if (base > 1)
|
|
||||||
{
|
|
||||||
max_tries = log(UINT32_MAX/(1000.0 * timeout))/log(base);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i <= tries; i++)
|
/*
|
||||||
|
* Described in header
|
||||||
|
*/
|
||||||
|
uint32_t retransmission_timeout(retransmission_t *settings, u_int try,
|
||||||
|
bool randomize)
|
||||||
|
{
|
||||||
|
double timeout = UINT32_MAX, max_jitter;
|
||||||
|
|
||||||
|
if (!settings->max_tries || try <= settings->max_tries)
|
||||||
{
|
{
|
||||||
double interval = UINT32_MAX/1000.0;
|
timeout = settings->timeout * 1000.0 * pow(settings->base, try);
|
||||||
if (max_tries && i <= max_tries)
|
}
|
||||||
{
|
if (settings->limit)
|
||||||
interval = timeout * pow(base, i);
|
{
|
||||||
}
|
timeout = min(timeout, settings->limit);
|
||||||
if (limit)
|
}
|
||||||
{
|
if (randomize && settings->jitter)
|
||||||
interval = min(interval, limit);
|
{
|
||||||
}
|
max_jitter = (timeout / 100.0) * settings->jitter;
|
||||||
total += interval;
|
timeout -= max_jitter * (random() / (RAND_MAX + 1.0));
|
||||||
|
}
|
||||||
|
return (uint32_t)timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Described in header
|
||||||
|
*/
|
||||||
|
u_int retransmission_timeout_total(retransmission_t *settings)
|
||||||
|
{
|
||||||
|
double total = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i <= settings->tries; i++)
|
||||||
|
{
|
||||||
|
total += retransmission_timeout(settings, i, FALSE) / 1000.0;
|
||||||
}
|
}
|
||||||
return (u_int)total;
|
return (u_int)total;
|
||||||
}
|
}
|
||||||
@@ -80,4 +105,3 @@ task_manager_t *task_manager_create(ike_sa_t *ike_sa)
|
|||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2013-2018 Tobias Brunner
|
* Copyright (C) 2013-2023 Tobias Brunner
|
||||||
* Copyright (C) 2006 Martin Willi
|
* Copyright (C) 2006 Martin Willi
|
||||||
*
|
*
|
||||||
* Copyright (C) secunet Security Networks AG
|
* Copyright (C) secunet Security Networks AG
|
||||||
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
typedef struct task_manager_t task_manager_t;
|
typedef struct task_manager_t task_manager_t;
|
||||||
typedef enum task_queue_t task_queue_t;
|
typedef enum task_queue_t task_queue_t;
|
||||||
|
typedef struct retransmission_t retransmission_t;
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
@@ -63,6 +64,49 @@ typedef enum task_queue_t task_queue_t;
|
|||||||
*/
|
*/
|
||||||
#define ROUTABILITY_CHECK_TRIES 10
|
#define ROUTABILITY_CHECK_TRIES 10
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retransmission settings.
|
||||||
|
*
|
||||||
|
* See retransmission_timeout() for details on the calculation.
|
||||||
|
*/
|
||||||
|
struct retransmission_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timeout in seconds.
|
||||||
|
*/
|
||||||
|
double timeout;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base that's raised to the power of the retransmission try to calculate
|
||||||
|
* the timeout.
|
||||||
|
*/
|
||||||
|
double base;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Limit for the calculated timeout (in ms).
|
||||||
|
*/
|
||||||
|
uint32_t limit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum jitter to apply to calculated timeout (in percent). A random
|
||||||
|
* amount of value this will be subtracted from the calculated timeout.
|
||||||
|
*/
|
||||||
|
u_int jitter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of tries.
|
||||||
|
*/
|
||||||
|
u_int tries;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum number of tries possible with current retransmission settings
|
||||||
|
* before overflowing the range of uint32_t, which we use for the timeout.
|
||||||
|
* Note that UINT32_MAX milliseconds equal nearly 50 days, so using a high
|
||||||
|
* number of retransmits doesn't make much sense without `limit` anyway.
|
||||||
|
*/
|
||||||
|
u_int max_tries;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type of task queues the task manager uses to handle tasks
|
* Type of task queues the task manager uses to handle tasks
|
||||||
*/
|
*/
|
||||||
@@ -88,24 +132,8 @@ enum task_queue_t {
|
|||||||
* For the initial IKE_SA setup, several tasks are queued: One for the
|
* For the initial IKE_SA setup, several tasks are queued: One for the
|
||||||
* unauthenticated IKE_SA setup, one for authentication, one for CHILD_SA setup
|
* unauthenticated IKE_SA setup, one for authentication, one for CHILD_SA setup
|
||||||
* and maybe one for virtual IP assignment.
|
* and maybe one for virtual IP assignment.
|
||||||
* The task manager is also responsible for retransmission. It uses a backoff
|
* The task manager is also responsible for retransmission (see
|
||||||
* algorithm. The timeout is calculated using
|
* retransmission_timeout() for details).
|
||||||
* RETRANSMIT_TIMEOUT * (RETRANSMIT_BASE ** try).
|
|
||||||
* When try reaches RETRANSMIT_TRIES, retransmission is given up.
|
|
||||||
*
|
|
||||||
* Using an initial TIMEOUT of 4s, a BASE of 1.8, and 5 TRIES gives us:
|
|
||||||
* @verbatim
|
|
||||||
| relative | absolute
|
|
||||||
---------------------------------------------------------
|
|
||||||
4s * (1.8 ** 0) = 4s 4s
|
|
||||||
4s * (1.8 ** 1) = 7s 11s
|
|
||||||
4s * (1.8 ** 2) = 13s 24s
|
|
||||||
4s * (1.8 ** 3) = 23s 47s
|
|
||||||
4s * (1.8 ** 4) = 42s 89s
|
|
||||||
4s * (1.8 ** 5) = 76s 165s
|
|
||||||
|
|
||||||
@endverbatim
|
|
||||||
* The peer is considered dead after 2min 45s when no reply comes in.
|
|
||||||
*/
|
*/
|
||||||
struct task_manager_t {
|
struct task_manager_t {
|
||||||
|
|
||||||
@@ -305,15 +333,55 @@ struct task_manager_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate total timeout of the retransmission mechanism.
|
* Parse the default retransmission settings.
|
||||||
*
|
*
|
||||||
* This is affected by modifications of retransmit_base, retransmit_timeout,
|
* @param settings retransmission settings that are filled in
|
||||||
* retransmit_limit or retransmit_tries. The resulting value can then be used
|
*/
|
||||||
* e.g. in kernel plugins to set the system's acquire timeout properly.
|
void retransmission_parse_default(retransmission_t *settings);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the retransmission timeout in ms based on the given settings and
|
||||||
|
* try.
|
||||||
*
|
*
|
||||||
|
* An exponential backoff algorithm is used. The timeout for each retransmit
|
||||||
|
* is calculated as follows: min(timeout * (base ** try), limit)
|
||||||
|
* From the result a random value (of at most jitter percent) is optionally
|
||||||
|
* subtracted.
|
||||||
|
*
|
||||||
|
* Using an initial timeout of 4s, a base of 1.8, and 5 tries gives us:
|
||||||
|
* @verbatim
|
||||||
|
| relative | absolute
|
||||||
|
---------------------------------------------------------
|
||||||
|
4s * (1.8 ** 0) = 4s 4s
|
||||||
|
4s * (1.8 ** 1) = 7s 11s
|
||||||
|
4s * (1.8 ** 2) = 13s 24s
|
||||||
|
4s * (1.8 ** 3) = 23s 47s
|
||||||
|
4s * (1.8 ** 4) = 42s 89s
|
||||||
|
4s * (1.8 ** 5) = 76s 165s
|
||||||
|
|
||||||
|
@endverbatim
|
||||||
|
* So the peer is considered dead after 2min 45s when no reply is received.
|
||||||
|
*
|
||||||
|
* @param settings retransmission settings
|
||||||
|
* @param try zero-based try to send a packet
|
||||||
|
* @param randomize whether to apply jitter
|
||||||
|
* @return timeout for next retransmit in ms
|
||||||
|
*/
|
||||||
|
uint32_t retransmission_timeout(retransmission_t *settings, u_int try,
|
||||||
|
bool randomize);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate total timeout in s for the given retransmission settings (ignoring
|
||||||
|
* jitter).
|
||||||
|
*
|
||||||
|
* This is affected by modifications of base, timeout, limit and tries. The
|
||||||
|
* resulting value can then be used e.g. in kernel plugins to set the system's
|
||||||
|
* acquire timeout properly.
|
||||||
|
*
|
||||||
|
* @param settings retransmission settings
|
||||||
* @return calculated total retransmission timeout in seconds
|
* @return calculated total retransmission timeout in seconds
|
||||||
*/
|
*/
|
||||||
u_int task_manager_total_retransmit_timeout();
|
u_int retransmission_timeout_total(retransmission_t *settings);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a task manager instance for the correct IKE version.
|
* Create a task manager instance for the correct IKE version.
|
||||||
|
|||||||
Reference in New Issue
Block a user