*/
u_int retransmit_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 that doesn't
+ * make much sense without retransmit_limit anyway.
+ */
+ u_int retransmit_tries_max;
+
/**
* Retransmission timeout
*/
u_int mid, u_int retransmitted, array_t *packets)
{
packet_t *packet;
- uint32_t t, max_jitter;
+ uint32_t t = UINT32_MAX, max_jitter;
array_get(packets, 0, &packet);
if (retransmitted > this->retransmit_tries)
charon->bus->alert(charon->bus, ALERT_RETRANSMIT_SEND_TIMEOUT, packet);
return DESTROY_ME;
}
- t = (uint32_t)(this->retransmit_timeout * 1000.0 *
- pow(this->retransmit_base, retransmitted));
+ if (this->retransmit_tries_max &&
+ 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);
}
this->dpd_send &= 0x7FFFFFFF;
+ if (this->retransmit_base > 1)
+ { /* 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;
}
*/
u_int retransmit_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 that doesn't
+ * make much sense without retransmit_limit anyway.
+ */
+ u_int retransmit_tries_max;
+
/**
* Retransmission timeout
*/
if (message_id == this->initiating.mid &&
array_count(this->initiating.packets))
{
- uint32_t timeout, max_jitter;
+ uint32_t timeout = UINT32_MAX, max_jitter;
job_t *job;
enumerator_t *enumerator;
packet_t *packet;
if (!mobike || !mobike->is_probing(mobike))
{
- if (this->initiating.retransmitted <= this->retransmit_tries)
- {
- 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));
- }
- }
- else
+ if (this->initiating.retransmitted > this->retransmit_tries)
{
DBG1(DBG_IKE, "giving up after %d retransmits",
this->initiating.retransmitted - 1);
packet);
return DESTROY_ME;
}
-
+ if (this->retransmit_tries_max &&
+ this->initiating.retransmitted <= this->retransmit_tries_max)
+ {
+ 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)
{
DBG1(DBG_IKE, "retransmit %d of request with message ID %d",
"%s.make_before_break", FALSE, lib->ns),
);
+ if (this->retransmit_base > 1)
+ { /* 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;
}
u_int task_manager_total_retransmit_timeout()
{
double timeout, base, limit = 0, total = 0;
- int tries, i;
+ int tries, max_tries = 0, i;
tries = lib->settings->get_int(lib->settings, "%s.retransmit_tries",
RETRANSMIT_TRIES, 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++)
{
- double interval = timeout * pow(base, i);
+ double interval = UINT32_MAX/1000.0;
+ if (max_tries && i <= max_tries)
+ {
+ interval = timeout * pow(base, i);
+ }
if (limit)
{
interval = min(interval, limit);