--- embedaddon/strongswan/src/libcharon/sa/ikev1/task_manager_v1.c 2020/06/03 09:46:45 1.1.1.1 +++ embedaddon/strongswan/src/libcharon/sa/ikev1/task_manager_v1.c 2021/03/17 00:20:09 1.1.1.2 @@ -200,6 +200,14 @@ struct private_task_manager_t { 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 */ double retransmit_timeout; @@ -355,7 +363,7 @@ static status_t retransmit_packet(private_task_manager 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) @@ -364,8 +372,12 @@ static status_t retransmit_packet(private_task_manager 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); @@ -392,7 +404,7 @@ static status_t retransmit_packet(private_task_manager METHOD(task_manager_t, retransmit, status_t, private_task_manager_t *this, uint32_t seqnr) { - status_t status = SUCCESS; + status_t status = INVALID_STATE; if (seqnr == this->initiating.seqnr && array_count(this->initiating.packets)) @@ -1396,7 +1408,7 @@ METHOD(task_manager_t, process_message, status_t, } this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND, time_monotonic(NULL)); - this->ike_sa->update_hosts(this->ike_sa, me, other, TRUE); + this->ike_sa->update_hosts(this->ike_sa, me, other, UPDATE_HOSTS_FORCE_ADDRS); charon->bus->message(charon->bus, msg, TRUE, TRUE); if (process_response(this, msg) != SUCCESS) { @@ -1516,7 +1528,7 @@ METHOD(task_manager_t, process_message, status_t, "%s.half_open_timeout", HALF_OPEN_IKE_SA_TIMEOUT, lib->ns)); } - this->ike_sa->update_hosts(this->ike_sa, me, other, TRUE); + this->ike_sa->update_hosts(this->ike_sa, me, other, UPDATE_HOSTS_FORCE_ADDRS); charon->bus->message(charon->bus, msg, TRUE, TRUE); if (process_request(this, msg) != SUCCESS) { @@ -1624,7 +1636,7 @@ METHOD(task_manager_t, queue_ike_reauth, void, ike_sa_t *new; host_t *host; - new = charon->ike_sa_manager->checkout_new(charon->ike_sa_manager, + new = charon->ike_sa_manager->create_new(charon->ike_sa_manager, this->ike_sa->get_version(this->ike_sa), TRUE); if (!new) { /* shouldn't happen */ @@ -2141,5 +2153,11 @@ task_manager_v1_t *task_manager_v1_create(ike_sa_t *ik } 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; }