]> git.ipfire.org Git - thirdparty/strongswan.git/blob - src/libcharon/sa/task_manager.c
quick-mode: Get a reference when adopting the reqid of a rekeyed CHILD_SA
[thirdparty/strongswan.git] / src / libcharon / sa / task_manager.c
1 /*
2 * Copyright (C) 2011-2023 Tobias Brunner
3 *
4 * Copyright (C) secunet Security Networks AG
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17 #include "task_manager.h"
18
19 #include <math.h>
20 #include <sa/ikev1/task_manager_v1.h>
21 #include <sa/ikev2/task_manager_v2.h>
22
23 /*
24 * Described in header
25 */
26 void retransmission_parse_default(retransmission_t *settings)
27 {
28 settings->timeout = lib->settings->get_double(lib->settings,
29 "%s.retransmit_timeout", RETRANSMIT_TIMEOUT, lib->ns);
30 settings->base = lib->settings->get_double(lib->settings,
31 "%s.retransmit_base", RETRANSMIT_BASE, lib->ns);
32 settings->jitter = min(lib->settings->get_int(lib->settings,
33 "%s.retransmit_jitter", 0, lib->ns), RETRANSMIT_JITTER_MAX);
34 settings->limit = lib->settings->get_int(lib->settings,
35 "%s.retransmit_limit", 0, lib->ns) * 1000;
36 settings->tries = lib->settings->get_int(lib->settings,
37 "%s.retransmit_tries", RETRANSMIT_TRIES, lib->ns);
38
39 if (settings->base > 1)
40 { /* based on 1000 * timeout * base^try */
41 settings->max_tries = log(UINT32_MAX/
42 (1000.0 * settings->timeout))/
43 log(settings->base);
44 }
45 }
46
47 /*
48 * Described in header
49 */
50 uint32_t retransmission_timeout(retransmission_t *settings, u_int try,
51 bool randomize)
52 {
53 double timeout = UINT32_MAX, max_jitter;
54
55 if (!settings->max_tries || try <= settings->max_tries)
56 {
57 timeout = settings->timeout * 1000.0 * pow(settings->base, try);
58 }
59 if (settings->limit)
60 {
61 timeout = min(timeout, settings->limit);
62 }
63 if (randomize && settings->jitter)
64 {
65 max_jitter = (timeout / 100.0) * settings->jitter;
66 timeout -= max_jitter * (random() / (RAND_MAX + 1.0));
67 }
68 return (uint32_t)timeout;
69 }
70
71 /*
72 * Described in header
73 */
74 u_int retransmission_timeout_total(retransmission_t *settings)
75 {
76 double total = 0;
77 int i;
78
79 for (i = 0; i <= settings->tries; i++)
80 {
81 total += retransmission_timeout(settings, i, FALSE) / 1000.0;
82 }
83 return (u_int)total;
84 }
85
86 /*
87 * See header
88 */
89 task_manager_t *task_manager_create(ike_sa_t *ike_sa)
90 {
91 switch (ike_sa->get_version(ike_sa))
92 {
93 case IKEV1:
94 #ifdef USE_IKEV1
95 return &task_manager_v1_create(ike_sa)->task_manager;
96 #endif
97 break;
98 case IKEV2:
99 #ifdef USE_IKEV2
100 return &task_manager_v2_create(ike_sa)->task_manager;
101 #endif
102 break;
103 default:
104 break;
105 }
106 return NULL;
107 }