ike: Use optional jitter to calculate retransmission timeouts
Also adds an optional limit to avoid very high retransmission timeouts with high numbers of retries.
This commit is contained in:
parent
d140b3bd3f
commit
389e4b8e67
|
@ -311,6 +311,13 @@ charon.retransmit_timeout = 4.0
|
|||
charon.retransmit_tries = 5
|
||||
Number of times to retransmit a packet before giving up.
|
||||
|
||||
charon.retransmit_jitter = 0
|
||||
Maximum jitter in percent to apply randomly to calculated retransmission
|
||||
timeout (0 to disable).
|
||||
|
||||
charon.retransmit_limit = 0
|
||||
Upper limit in seconds for calculated retransmission timeout (0 to disable).
|
||||
|
||||
charon.retry_initiate_interval = 0
|
||||
Interval in seconds to use when retrying to initiate an IKE_SA (e.g. if DNS
|
||||
resolution failed), 0 to disable retries.
|
||||
|
|
|
@ -408,6 +408,8 @@ using the three keys listed below:
|
|||
.BR charon.retransmit_base " [1.8]"
|
||||
.BR charon.retransmit_timeout " [4.0]"
|
||||
.BR charon.retransmit_tries " [5]"
|
||||
.BR charon.retransmit_jitter " [0]"
|
||||
.BR charon.retransmit_limit " [0]"
|
||||
.fi
|
||||
.RE
|
||||
.PP
|
||||
|
@ -419,7 +421,15 @@ The following algorithm is used to calculate the timeout:
|
|||
.PP
|
||||
Where
|
||||
.I n
|
||||
is the current retransmission count.
|
||||
is the current retransmission count. The calculated timeout can't exceed the
|
||||
configured retransmit_limit (if any), which is useful if the number of retries
|
||||
is high.
|
||||
.PP
|
||||
If a jitter in percent is configured, the timeout is modified as follows:
|
||||
.PP
|
||||
.EX
|
||||
relative timeout -= random(0, retransmit_jitter * relative timeout)
|
||||
.EE
|
||||
.PP
|
||||
Using the default values, packets are retransmitted in:
|
||||
|
||||
|
|
|
@ -209,6 +209,16 @@ struct private_task_manager_t {
|
|||
*/
|
||||
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
|
||||
*/
|
||||
|
@ -345,7 +355,7 @@ 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;
|
||||
uint32_t t;
|
||||
uint32_t t, max_jitter;
|
||||
|
||||
array_get(packets, 0, &packet);
|
||||
if (retransmitted > this->retransmit_tries)
|
||||
|
@ -356,6 +366,15 @@ static status_t retransmit_packet(private_task_manager_t *this, uint32_t seqnr,
|
|||
}
|
||||
t = (uint32_t)(this->retransmit_timeout * 1000.0 *
|
||||
pow(this->retransmit_base, retransmitted));
|
||||
if (this->retransmit_jitter)
|
||||
{
|
||||
max_jitter = (t / 100.0) * this->retransmit_jitter;
|
||||
t -= max_jitter * (random() / (RAND_MAX + 1.0));
|
||||
}
|
||||
if (this->retransmit_limit)
|
||||
{
|
||||
t = min(t, this->retransmit_limit);
|
||||
}
|
||||
if (retransmitted)
|
||||
{
|
||||
DBG1(DBG_IKE, "sending retransmit %u of %s message ID %u, seq %u",
|
||||
|
@ -2034,11 +2053,15 @@ task_manager_v1_t *task_manager_v1_create(ike_sa_t *ike_sa)
|
|||
.active_tasks = linked_list_create(),
|
||||
.passive_tasks = linked_list_create(),
|
||||
.retransmit_tries = lib->settings->get_int(lib->settings,
|
||||
"%s.retransmit_tries", RETRANSMIT_TRIES, lib->ns),
|
||||
"%s.retransmit_tries", RETRANSMIT_TRIES, lib->ns),
|
||||
.retransmit_timeout = lib->settings->get_double(lib->settings,
|
||||
"%s.retransmit_timeout", RETRANSMIT_TIMEOUT, lib->ns),
|
||||
"%s.retransmit_timeout", RETRANSMIT_TIMEOUT, lib->ns),
|
||||
.retransmit_base = lib->settings->get_double(lib->settings,
|
||||
"%s.retransmit_base", RETRANSMIT_BASE, lib->ns),
|
||||
"%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)
|
||||
|
|
|
@ -160,6 +160,16 @@ struct private_task_manager_t {
|
|||
*/
|
||||
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?
|
||||
*/
|
||||
|
@ -321,7 +331,7 @@ METHOD(task_manager_t, retransmit, status_t,
|
|||
if (message_id == this->initiating.mid &&
|
||||
array_count(this->initiating.packets))
|
||||
{
|
||||
uint32_t timeout;
|
||||
uint32_t timeout, max_jitter;
|
||||
job_t *job;
|
||||
enumerator_t *enumerator;
|
||||
packet_t *packet;
|
||||
|
@ -351,6 +361,16 @@ METHOD(task_manager_t, retransmit, status_t,
|
|||
{
|
||||
timeout = (uint32_t)(this->retransmit_timeout * 1000.0 *
|
||||
pow(this->retransmit_base, this->initiating.retransmitted));
|
||||
|
||||
if (this->retransmit_jitter)
|
||||
{
|
||||
max_jitter = (timeout / 100.0) * this->retransmit_jitter;
|
||||
timeout -= max_jitter * (random() / (RAND_MAX + 1.0));
|
||||
}
|
||||
if (this->retransmit_limit)
|
||||
{
|
||||
timeout = min(timeout, this->retransmit_limit);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2151,6 +2171,10 @@ task_manager_v2_t *task_manager_v2_create(ike_sa_t *ike_sa)
|
|||
"%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,
|
||||
"%s.make_before_break", FALSE, lib->ns),
|
||||
);
|
||||
|
|
|
@ -47,6 +47,11 @@ typedef enum task_queue_t task_queue_t;
|
|||
*/
|
||||
#define RETRANSMIT_TRIES 5
|
||||
|
||||
/**
|
||||
* Maximum jitter in percent.
|
||||
*/
|
||||
#define RETRANSMIT_JITTER_MAX 20
|
||||
|
||||
/**
|
||||
* Interval for mobike routability checks in ms.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue