fixed some rekey collision issues
[strongswan.git] / src / charon / config / configuration.c
1 /**
2 * @file configuration.c
3 *
4 * @brief Implementation of configuration_t.
5 *
6 */
7
8 /*
9 * Copyright (C) 2006 Martin Willi
10 * Hochschule fuer Technik Rapperswil
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
21 */
22
23 #include <stdlib.h>
24 #include <math.h>
25
26 #include "configuration.h"
27
28 #include <library.h>
29
30 /**
31 * Timeout in milliseconds after that a half open IKE_SA gets deleted.
32 */
33 #define HALF_OPEN_IKE_SA_TIMEOUT 30000
34
35 /**
36 * Retransmission uses a backoff algorithm. The timeout is calculated using
37 * TIMEOUT * (BASE ** try).
38 * When try reaches TRIES, retransmission is given up.
39 *
40 * Using an initial TIMEOUT of 4s, a BASE of 1.8, and 5 TRIES gives us:
41 *
42 * | relative | absolute
43 * ---------------------------------------------------------
44 * 4s * (1.8 ** (0 % 5)) = 4s 4s
45 * 4s * (1.8 ** (1 % 5)) = 7s 11s
46 * 4s * (1.8 ** (2 % 5)) = 13s 24s
47 * 4s * (1.8 ** (3 % 5)) = 23s 47s
48 * 4s * (1.8 ** (4 % 5)) = 42s 89s
49 * 4s * (1.8 ** (5 % 5)) = 76s 165s
50 *
51 * The peer is considered dead after 2min 45s when no reply comes in.
52 */
53
54 /**
55 * First retransmit timeout in milliseconds.
56 * Timeout value is increasing in each retransmit round.
57 */
58 #define RETRANSMIT_TIMEOUT 4000
59
60 /**
61 * Base which is raised to the power of the retransmission count.
62 */
63 #define RETRANSMIT_BASE 1.8
64
65 /**
66 * Number of retransmits done in a retransmit sequence
67 */
68 #define RETRANSMIT_TRIES 5
69
70 /**
71 * Keepalive interval in seconds.
72 */
73 #define KEEPALIVE_INTERVAL 20
74
75 /**
76 * retry interval in seconds.
77 */
78 #define RETRY_INTERVAL 15
79
80 /**
81 * jitter to user for retrying
82 */
83 #define RETRY_JITTER 5
84
85
86 typedef struct private_configuration_t private_configuration_t;
87
88 /**
89 * Private data of an configuration_t object.
90 */
91 struct private_configuration_t {
92
93 /**
94 * Public part of configuration_t object.
95 */
96 configuration_t public;
97
98 };
99
100 /**
101 * Implementation of configuration_t.get_retransmit_timeout.
102 */
103 static u_int32_t get_retransmit_timeout (private_configuration_t *this,
104 u_int32_t retransmit_count)
105 {
106 if (retransmit_count > RETRANSMIT_TRIES)
107 {
108 /* give up */
109 return 0;
110 }
111 return (u_int32_t)
112 (RETRANSMIT_TIMEOUT * pow(RETRANSMIT_BASE, retransmit_count));
113 }
114
115 /**
116 * Implementation of configuration_t.get_half_open_ike_sa_timeout.
117 */
118 static u_int32_t get_half_open_ike_sa_timeout (private_configuration_t *this)
119 {
120 return HALF_OPEN_IKE_SA_TIMEOUT;
121 }
122
123 /**
124 * Implementation of configuration_t.get_keepalive_interval.
125 */
126 static u_int32_t get_keepalive_interval (private_configuration_t *this)
127 {
128 return KEEPALIVE_INTERVAL;
129 }
130
131 /**
132 * Implementation of configuration_t.get_retry_interval.
133 */
134 static u_int32_t get_retry_interval (private_configuration_t *this)
135 {
136 return RETRY_INTERVAL - (random() % RETRY_JITTER);
137 }
138
139 /**
140 * Implementation of configuration_t.destroy.
141 */
142 static void destroy(private_configuration_t *this)
143 {
144 free(this);
145 }
146
147 /*
148 * Described in header-file
149 */
150 configuration_t *configuration_create()
151 {
152 private_configuration_t *this = malloc_thing(private_configuration_t);
153
154 /* public functions */
155 this->public.destroy = (void(*)(configuration_t*))destroy;
156 this->public.get_retransmit_timeout = (u_int32_t (*) (configuration_t*,u_int32_t))get_retransmit_timeout;
157 this->public.get_half_open_ike_sa_timeout = (u_int32_t (*) (configuration_t*)) get_half_open_ike_sa_timeout;
158 this->public.get_keepalive_interval = (u_int32_t (*) (configuration_t*)) get_keepalive_interval;
159 this->public.get_retry_interval = (u_int32_t (*) (configuration_t*)) get_retry_interval;
160
161 return (&this->public);
162 }