From 35cb0d276e25f59a74279af07907912676eca5de Mon Sep 17 00:00:00 2001 From: Denis Vinogradov Date: Mon, 29 Jun 2020 12:36:52 +0900 Subject: [PATCH] configurable retransmit tries added Change-Id: I2ed22b327b699a821daee00cd082ffe4cfb7c7d5 Signed-off-by: Denis Vinogradov --- src/libcharon/config/peer_cfg.c | 94 ++++++++++++++++++++ src/libcharon/config/peer_cfg.h | 20 +++++ src/libcharon/plugins/stroke/stroke_config.c | 6 ++ src/libcharon/sa/ikev2/task_manager_v2.c | 31 +++++-- src/libcharon/sa/task_manager.h | 15 +--- src/stroke/stroke_msg.h | 5 ++ 6 files changed, 150 insertions(+), 21 deletions(-) diff --git a/src/libcharon/config/peer_cfg.c b/src/libcharon/config/peer_cfg.c index 3b72d18..c0178bb 100755 --- a/src/libcharon/config/peer_cfg.c +++ b/src/libcharon/config/peer_cfg.c @@ -213,6 +213,16 @@ struct private_peer_cfg_t { /** Rekey on roaming preference flag */ int rekey_pref; + + /** Retransmit parameters */ + double retransmit_timeout; + double retransmit_base; + int retransmit_retries; + + /** Handover retransmit parameters */ + double retransmit_timeout_handover; + double retransmit_base_handover; + int retransmit_retries_handover; #endif }; @@ -845,6 +855,78 @@ METHOD(peer_cfg_t, get_do_rekey_on_roam, int, { return this->rekey_pref; } + +METHOD(peer_cfg_t, set_retransmit_timeout, void, + private_peer_cfg_t *this, float timeout) +{ + this->retransmit_timeout = (double)timeout; +} + +METHOD(peer_cfg_t, get_retransmit_timeout, double, + private_peer_cfg_t *this) +{ + return this->retransmit_timeout; +} + +METHOD(peer_cfg_t, set_retransmit_base, void, + private_peer_cfg_t *this, float base) +{ + this->retransmit_base = (double)base; +} + +METHOD(peer_cfg_t, get_retransmit_base, double, + private_peer_cfg_t *this) +{ + return this->retransmit_base; +} + +METHOD(peer_cfg_t, set_retransmit_retries, void, + private_peer_cfg_t *this, int count) +{ + this->retransmit_retries = count; +} + +METHOD(peer_cfg_t, get_retransmit_retries, int, + private_peer_cfg_t *this) +{ + return this->retransmit_retries; +} + +METHOD(peer_cfg_t, set_retransmit_timeout_handover, void, + private_peer_cfg_t *this, float timeout) +{ + this->retransmit_timeout_handover = (double)timeout; +} + +METHOD(peer_cfg_t, get_retransmit_timeout_handover, double, + private_peer_cfg_t *this) +{ + return this->retransmit_timeout_handover; +} + +METHOD(peer_cfg_t, set_retransmit_base_handover, void, + private_peer_cfg_t *this, float base) +{ + this->retransmit_base_handover = (double)base; +} + +METHOD(peer_cfg_t, get_retransmit_base_handover, double, + private_peer_cfg_t *this) +{ + return this->retransmit_base_handover; +} + +METHOD(peer_cfg_t, set_retransmit_retries_handover, void, + private_peer_cfg_t *this, int count) +{ + this->retransmit_retries_handover = count; +} + +METHOD(peer_cfg_t, get_retransmit_retries_handover, int, + private_peer_cfg_t *this) +{ + return this->retransmit_retries_handover; +} #endif METHOD(peer_cfg_t, destroy, void, @@ -939,6 +1021,18 @@ peer_cfg_t *peer_cfg_create(char *name, ike_cfg_t *ike_cfg, .get_interface = _get_interface_name, .set_do_rekey_on_roam = _set_do_rekey_on_roam, .is_rekey_preferred = _get_do_rekey_on_roam, + .set_retransmit_timeout = _set_retransmit_timeout, + .get_retransmit_timeout = _get_retransmit_timeout, + .set_retransmit_base = _set_retransmit_base, + .get_retransmit_base = _get_retransmit_base, + .set_retransmit_retries = _set_retransmit_retries, + .get_retransmit_retries = _get_retransmit_retries, + .set_retransmit_timeout_handover = _set_retransmit_timeout_handover, + .get_retransmit_timeout_handover = _get_retransmit_timeout_handover, + .set_retransmit_base_handover = _set_retransmit_base_handover, + .get_retransmit_base_handover = _get_retransmit_base_handover, + .set_retransmit_retries_handover = _set_retransmit_retries_handover, + .get_retransmit_retries_handover = _get_retransmit_retries_handover, #endif #ifdef ME .is_mediation = _is_mediation, diff --git a/src/libcharon/config/peer_cfg.h b/src/libcharon/config/peer_cfg.h index 5991760..b060981 100755 --- a/src/libcharon/config/peer_cfg.h +++ b/src/libcharon/config/peer_cfg.h @@ -446,6 +446,26 @@ struct peer_cfg_t { * Get rekey preferred flag */ int (*is_rekey_preferred)(peer_cfg_t *this); + + /** + * Set retransmit parameters + */ + void (*set_retransmit_timeout)(peer_cfg_t *this, float timeout); + void (*set_retransmit_base)(peer_cfg_t *this, float base); + void (*set_retransmit_retries)(peer_cfg_t *this, int count); + void (*set_retransmit_timeout_handover)(peer_cfg_t *this, float timeout); + void (*set_retransmit_base_handover)(peer_cfg_t *this, float base); + void (*set_retransmit_retries_handover)(peer_cfg_t *this, int count); + + /** + * Get retransmit parameters + */ + double (*get_retransmit_timeout)(peer_cfg_t *this); + double (*get_retransmit_base)(peer_cfg_t *this); + int (*get_retransmit_retries)(peer_cfg_t *this); + double (*get_retransmit_timeout_handover)(peer_cfg_t *this); + double (*get_retransmit_base_handover)(peer_cfg_t *this); + int (*get_retransmit_retries_handover)(peer_cfg_t *this); #endif }; diff --git a/src/libcharon/plugins/stroke/stroke_config.c b/src/libcharon/plugins/stroke/stroke_config.c index 2d784d8..e00f67c 100755 --- a/src/libcharon/plugins/stroke/stroke_config.c +++ b/src/libcharon/plugins/stroke/stroke_config.c @@ -900,6 +900,12 @@ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this, peer_cfg->set_handover(peer_cfg, handover); peer_cfg->set_use_original_ts(peer_cfg, msg->add_conn.options & OPT_USE_ORIGINAL_TS); peer_cfg->set_do_rekey_on_roam(peer_cfg, msg->add_conn.options & OPT_DO_REKEY_ON_ROAM); + peer_cfg->set_retransmit_timeout(peer_cfg, msg->add_conn.retransmit.timeout); + peer_cfg->set_retransmit_base(peer_cfg, msg->add_conn.retransmit.base); + peer_cfg->set_retransmit_retries(peer_cfg, msg->add_conn.retransmit.tries); + peer_cfg->set_retransmit_timeout_handover(peer_cfg, msg->add_conn.retransmit_handover.timeout); + peer_cfg->set_retransmit_base_handover(peer_cfg, msg->add_conn.retransmit_handover.base); + peer_cfg->set_retransmit_retries_handover(peer_cfg, msg->add_conn.retransmit_handover.tries); #endif return peer_cfg; } diff --git a/src/libcharon/sa/ikev2/task_manager_v2.c b/src/libcharon/sa/ikev2/task_manager_v2.c index 59cad4c..ff656e4 100755 --- a/src/libcharon/sa/ikev2/task_manager_v2.c +++ b/src/libcharon/sa/ikev2/task_manager_v2.c @@ -145,6 +145,7 @@ struct private_task_manager_t { */ bool reset; +#ifndef VOWIFI_CFG /** * Number of times we retransmit messages before giving up */ @@ -169,6 +170,7 @@ struct private_task_manager_t { * Limit retransmit timeout to this value */ uint32_t retransmit_limit; +#endif /** * Use make-before-break instead of break-before-make reauth? @@ -358,26 +360,38 @@ METHOD(task_manager_t, retransmit, status_t, if (!mobike || !mobike->is_probing(mobike)) { #ifdef VOWIFI_CFG + double retransmit_timeout = RETRANSMIT_TIMEOUT; double base = RETRANSMIT_BASE; - u_int max_tries = RETRANSMIT_TRIES; + u_int max_tries = RETRANSMIT_TRIES; - if (this->ike_sa->is_handover(this->ike_sa)) + peer_cfg_t *peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa); + if (peer_cfg) { - base = HO_RETRANSMIT_BASE; - max_tries = HO_RETRANSMIT_TRIES; + if (this->ike_sa->is_handover(this->ike_sa)) + { + retransmit_timeout = peer_cfg->get_retransmit_timeout_handover(peer_cfg); + base = peer_cfg->get_retransmit_base_handover(peer_cfg); + max_tries = peer_cfg->get_retransmit_retries_handover(peer_cfg); + } + else + { + retransmit_timeout = peer_cfg->get_retransmit_timeout(peer_cfg); + base = peer_cfg->get_retransmit_base(peer_cfg); + max_tries = peer_cfg->get_retransmit_retries(peer_cfg); + } } DBG1(DBG_IKE, "Retries: %d, range: %d\n", this->initiating.retransmitted, max_tries); if (this->initiating.retransmitted <= max_tries) { - timeout = (u_int32_t)(this->retransmit_timeout * 1000.0 * + timeout = (u_int32_t)(retransmit_timeout * 1000.0 * pow(base, this->initiating.retransmitted)); + } #else if (this->initiating.retransmitted <= this->retransmit_tries) { timeout = (uint32_t)(this->retransmit_timeout * 1000.0 * pow(this->retransmit_base, this->initiating.retransmitted)); -#endif if (this->retransmit_limit) { timeout = min(timeout, this->retransmit_limit); @@ -388,6 +402,7 @@ METHOD(task_manager_t, retransmit, status_t, timeout -= max_jitter * (random() / (RAND_MAX + 1.0)); } } +#endif else { DBG1(DBG_IKE, "giving up after %d retransmits", @@ -418,7 +433,7 @@ METHOD(task_manager_t, retransmit, status_t, "deferred"); #ifdef VOWIFI_CFG /* do not try to wait next attempt if we are already done and all failed */ - if (this->initiating.retransmitted >= this->retransmit_tries) + if (this->initiating.retransmitted >= max_tries) { DBG1(DBG_IKE, "giving up after %d retransmits", this->initiating.retransmitted); @@ -2384,6 +2399,7 @@ task_manager_v2_t *task_manager_v2_create(ike_sa_t *ike_sa) .queued_tasks = array_create(0, 0), .active_tasks = array_create(0, 0), .passive_tasks = array_create(0, 0), +#ifndef VOWIFI_CFG .retransmit_tries = lib->settings->get_int(lib->settings, "%s.retransmit_tries", RETRANSMIT_TRIES, lib->ns), .retransmit_timeout = lib->settings->get_double(lib->settings, @@ -2394,6 +2410,7 @@ task_manager_v2_t *task_manager_v2_create(ike_sa_t *ike_sa) "%s.retransmit_jitter", 0, lib->ns), RETRANSMIT_JITTER_MAX), .retransmit_limit = lib->settings->get_int(lib->settings, "%s.retransmit_limit", 0, lib->ns) * 1000, +#endif .make_before_break = lib->settings->get_bool(lib->settings, "%s.make_before_break", FALSE, lib->ns), ); diff --git a/src/libcharon/sa/task_manager.h b/src/libcharon/sa/task_manager.h index aa653f8..c357d50 100755 --- a/src/libcharon/sa/task_manager.h +++ b/src/libcharon/sa/task_manager.h @@ -35,31 +35,18 @@ typedef enum task_queue_t task_queue_t; /** * First retransmit timeout in seconds. */ -#ifdef VOWIFI_CFG -#define RETRANSMIT_TIMEOUT 1.0 -#else #define RETRANSMIT_TIMEOUT 4.0 -#endif /** * Base which is raised to the power of the retransmission try. */ -#ifdef VOWIFI_CFG -#define RETRANSMIT_BASE 2.0 -#define HO_RETRANSMIT_BASE 1.0 -#else #define RETRANSMIT_BASE 1.8 -#endif /** * Number of retransmits done before giving up. */ -#ifdef VOWIFI_CFG -#define RETRANSMIT_TRIES 3 -#define HO_RETRANSMIT_TRIES 1 -#else #define RETRANSMIT_TRIES 5 -#endif + /** * Maximum jitter in percent. */ diff --git a/src/stroke/stroke_msg.h b/src/stroke/stroke_msg.h index 5ad240f..51a34a5 100755 --- a/src/stroke/stroke_msg.h +++ b/src/stroke/stroke_msg.h @@ -322,6 +322,11 @@ struct stroke_msg_t { operator_type_t opr_type; char *pcscf; char *imei; + struct { + float timeout; + float base; + int tries; + } retransmit, retransmit_handover; int keepalive_interval; #define OPT_USE_ORIGINAL_TS 0x00000001 -- 2.20.1