]>
Commit | Line | Data |
---|---|---|
c60c7694 | 1 | /* |
4505e3c0 | 2 | * Copyright (C) 2013-2018 Tobias Brunner |
c60c7694 | 3 | * Copyright (C) 2006 Martin Willi |
19ef2aec TB |
4 | * |
5 | * Copyright (C) secunet Security Networks AG | |
c60c7694 MW |
6 | * |
7 | * This program is free software; you can redistribute it and/or modify it | |
8 | * under the terms of the GNU General Public License as published by the | |
9 | * Free Software Foundation; either version 2 of the License, or (at your | |
10 | * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. | |
11 | * | |
12 | * This program is distributed in the hope that it will be useful, but | |
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
14 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 | * for more details. | |
552cc11b MW |
16 | */ |
17 | ||
18 | /** | |
19 | * @defgroup task_manager task_manager | |
20 | * @{ @ingroup sa | |
c60c7694 MW |
21 | */ |
22 | ||
23 | #ifndef TASK_MANAGER_H_ | |
24 | #define TASK_MANAGER_H_ | |
25 | ||
26 | typedef struct task_manager_t task_manager_t; | |
665c18bd | 27 | typedef enum task_queue_t task_queue_t; |
c60c7694 | 28 | |
b09ca747 MW |
29 | #include <limits.h> |
30 | ||
c60c7694 MW |
31 | #include <library.h> |
32 | #include <encoding/message.h> | |
33 | #include <sa/ike_sa.h> | |
15a682f4 | 34 | #include <sa/task.h> |
c60c7694 | 35 | |
3b138b84 | 36 | /** |
bc6ff2fc | 37 | * First retransmit timeout in seconds. |
3b138b84 | 38 | */ |
bc6ff2fc | 39 | #define RETRANSMIT_TIMEOUT 4.0 |
3b138b84 MW |
40 | |
41 | /** | |
42 | * Base which is raised to the power of the retransmission try. | |
3b138b84 MW |
43 | */ |
44 | #define RETRANSMIT_BASE 1.8 | |
45 | ||
46 | /** | |
47 | * Number of retransmits done before giving up. | |
3b138b84 MW |
48 | */ |
49 | #define RETRANSMIT_TRIES 5 | |
50 | ||
389e4b8e TB |
51 | /** |
52 | * Maximum jitter in percent. | |
53 | */ | |
54 | #define RETRANSMIT_JITTER_MAX 20 | |
55 | ||
f215e919 MW |
56 | /** |
57 | * Interval for mobike routability checks in ms. | |
f215e919 | 58 | */ |
d30498ed | 59 | #define ROUTABILITY_CHECK_INTERVAL 2500 |
f215e919 MW |
60 | |
61 | /** | |
62 | * Number of routability checks before giving up | |
f215e919 | 63 | */ |
d30498ed | 64 | #define ROUTABILITY_CHECK_TRIES 10 |
f215e919 | 65 | |
665c18bd MW |
66 | /** |
67 | * Type of task queues the task manager uses to handle tasks | |
68 | */ | |
69 | enum task_queue_t { | |
70 | /** tasks currently active, initiated by us */ | |
71 | TASK_QUEUE_ACTIVE, | |
72 | /** passive tasks initiated by the remote peer */ | |
73 | TASK_QUEUE_PASSIVE, | |
74 | /** tasks queued for initiated, but not yet activated */ | |
75 | TASK_QUEUE_QUEUED, | |
76 | }; | |
3b138b84 | 77 | |
c60c7694 | 78 | /** |
552cc11b | 79 | * The task manager, juggles task and handles message exchanges. |
c60c7694 MW |
80 | * |
81 | * On incoming requests, the task manager creates new tasks on demand and | |
82 | * juggles the request through all available tasks. Each task inspects the | |
83 | * request and adds payloads as necessary to the response. | |
84 | * On outgoing requests, the task manager delivers the request through the tasks | |
85 | * to build it, the response gets processed by each task to complete. | |
86 | * The task manager has an internal Queue to store task which should get | |
87 | * completed. | |
88 | * For the initial IKE_SA setup, several tasks are queued: One for the | |
89 | * unauthenticated IKE_SA setup, one for authentication, one for CHILD_SA setup | |
2db6d5b8 | 90 | * and maybe one for virtual IP assignment. |
7daf5226 | 91 | * The task manager is also responsible for retransmission. It uses a backoff |
3b138b84 MW |
92 | * algorithm. The timeout is calculated using |
93 | * RETRANSMIT_TIMEOUT * (RETRANSMIT_BASE ** try). | |
94 | * When try reaches RETRANSMIT_TRIES, retransmission is given up. | |
95 | * | |
96 | * Using an initial TIMEOUT of 4s, a BASE of 1.8, and 5 TRIES gives us: | |
97 | * @verbatim | |
98 | | relative | absolute | |
99 | --------------------------------------------------------- | |
100 | 4s * (1.8 ** 0) = 4s 4s | |
101 | 4s * (1.8 ** 1) = 7s 11s | |
102 | 4s * (1.8 ** 2) = 13s 24s | |
103 | 4s * (1.8 ** 3) = 23s 47s | |
104 | 4s * (1.8 ** 4) = 42s 89s | |
105 | 4s * (1.8 ** 5) = 76s 165s | |
7daf5226 | 106 | |
1490ff4d | 107 | @endverbatim |
3b138b84 | 108 | * The peer is considered dead after 2min 45s when no reply comes in. |
c60c7694 MW |
109 | */ |
110 | struct task_manager_t { | |
111 | ||
112 | /** | |
552cc11b | 113 | * Process an incoming message. |
7daf5226 | 114 | * |
c60c7694 MW |
115 | * @param message message to add payloads to |
116 | * @return | |
41faec07 | 117 | * - DESTROY_ME if IKE_SA must be closed |
c60c7694 MW |
118 | * - SUCCESS otherwise |
119 | */ | |
120 | status_t (*process_message) (task_manager_t *this, message_t *message); | |
121 | ||
122 | /** | |
552cc11b | 123 | * Initiate an exchange with the currently queued tasks. |
c60c7694 MW |
124 | */ |
125 | status_t (*initiate) (task_manager_t *this); | |
126 | ||
127 | /** | |
552cc11b | 128 | * Queue a task in the manager. |
c60c7694 | 129 | * |
c60c7694 MW |
130 | * @param task task to queue |
131 | */ | |
208678e6 TB |
132 | void (*queue_task)(task_manager_t *this, task_t *task); |
133 | ||
134 | /** | |
135 | * Queue a task in the manager, but delay its initiation for at least the | |
136 | * given number of seconds. | |
137 | * | |
138 | * @param task task to queue | |
139 | * @param delay minimum delay in s before initiating the task | |
140 | */ | |
141 | void (*queue_task_delayed)(task_manager_t *this, task_t *task, | |
142 | uint32_t delay); | |
c60c7694 | 143 | |
a60daa07 MW |
144 | /** |
145 | * Queue IKE_SA establishing tasks. | |
146 | */ | |
147 | void (*queue_ike)(task_manager_t *this); | |
148 | ||
dab60d64 MW |
149 | /** |
150 | * Queue IKE_SA rekey tasks. | |
151 | */ | |
152 | void (*queue_ike_rekey)(task_manager_t *this); | |
153 | ||
cedb412e MW |
154 | /** |
155 | * Queue IKE_SA reauth tasks. | |
156 | */ | |
157 | void (*queue_ike_reauth)(task_manager_t *this); | |
158 | ||
873df908 MW |
159 | /** |
160 | * Queue MOBIKE task | |
161 | * | |
162 | * @param roam TRUE to switch to new address | |
163 | * @param address TRUE to include address list update | |
164 | */ | |
165 | void (*queue_mobike)(task_manager_t *this, bool roam, bool address); | |
166 | ||
3ed148b3 MW |
167 | /** |
168 | * Queue IKE_SA delete tasks. | |
169 | */ | |
170 | void (*queue_ike_delete)(task_manager_t *this); | |
171 | ||
fe43d9a2 MW |
172 | /** |
173 | * Queue CHILD_SA establishing tasks. | |
174 | * | |
175 | * @param cfg CHILD_SA config to establish | |
7f30e1ae | 176 | * @param args optional arguments for the initiation |
fe43d9a2 | 177 | */ |
7f30e1ae TB |
178 | void (*queue_child)(task_manager_t *this, child_cfg_t *cfg, |
179 | child_init_args_t *args); | |
fe43d9a2 | 180 | |
463a73cc MW |
181 | /** |
182 | * Queue CHILD_SA rekeying tasks. | |
183 | * | |
184 | * @param protocol CHILD_SA protocol, AH|ESP | |
185 | * @param spi CHILD_SA SPI to rekey | |
186 | */ | |
187 | void (*queue_child_rekey)(task_manager_t *this, protocol_id_t protocol, | |
b12c53ce | 188 | uint32_t spi); |
463a73cc | 189 | |
83c5fda0 MW |
190 | /** |
191 | * Queue CHILD_SA delete tasks. | |
192 | * | |
193 | * @param protocol CHILD_SA protocol, AH|ESP | |
194 | * @param spi CHILD_SA SPI to rekey | |
3a925f74 | 195 | * @param expired TRUE if SA already expired |
83c5fda0 MW |
196 | */ |
197 | void (*queue_child_delete)(task_manager_t *this, protocol_id_t protocol, | |
b12c53ce | 198 | uint32_t spi, bool expired); |
83c5fda0 | 199 | |
244d715d MW |
200 | /** |
201 | * Queue liveness checking tasks. | |
202 | */ | |
203 | void (*queue_dpd)(task_manager_t *this); | |
204 | ||
c60c7694 | 205 | /** |
552cc11b | 206 | * Retransmit a request if it hasn't been acknowledged yet. |
c60c7694 MW |
207 | * |
208 | * A return value of INVALID_STATE means that the message was already | |
209 | * acknowledged and has not to be retransmitted. A return value of SUCCESS | |
210 | * means retransmission was required and the message has been resent. | |
7daf5226 | 211 | * |
c60c7694 MW |
212 | * @param message_id ID of the message to retransmit |
213 | * @return | |
41faec07 | 214 | * - INVALID_STATE if retransmission not required |
c60c7694 MW |
215 | * - SUCCESS if retransmission sent |
216 | */ | |
b12c53ce | 217 | status_t (*retransmit) (task_manager_t *this, uint32_t message_id); |
7daf5226 | 218 | |
c60c7694 | 219 | /** |
68db844f | 220 | * Migrate all queued tasks from other to this. |
c60c7694 MW |
221 | * |
222 | * To rekey or reestablish an IKE_SA completely, all queued or active | |
223 | * tasks should get migrated to the new IKE_SA. | |
7daf5226 | 224 | * |
c60c7694 MW |
225 | * @param other manager which gives away its tasks |
226 | */ | |
227 | void (*adopt_tasks) (task_manager_t *this, task_manager_t *other); | |
7daf5226 | 228 | |
c67de660 MW |
229 | /** |
230 | * Increment a message ID counter, in- or outbound. | |
231 | * | |
232 | * If a message is processed outside of the manager, this call increments | |
233 | * the message ID counters of the task manager. | |
234 | * | |
b3ab7a48 | 235 | * @param initiate TRUE to increment the initiating ID |
c67de660 MW |
236 | */ |
237 | void (*incr_mid)(task_manager_t *this, bool initiate); | |
238 | ||
05a2be82 TB |
239 | /** |
240 | * Get the current message ID counter, in- or outbound. | |
241 | * | |
242 | * @param initiate TRUE to get the initiating ID | |
243 | * @return current message ID | |
244 | */ | |
245 | uint32_t (*get_mid)(task_manager_t *this, bool initiate); | |
246 | ||
c60c7694 | 247 | /** |
552cc11b | 248 | * Reset message ID counters of the task manager. |
c60c7694 MW |
249 | * |
250 | * The IKEv2 protocol requires to restart exchanges with message IDs | |
251 | * reset to zero (INVALID_KE_PAYLOAD, COOKIES, ...). The reset() method | |
252 | * resets the message IDs and resets all active tasks using the migrate() | |
253 | * method. | |
b09ca747 | 254 | * Use a value of UINT_MAX to keep the current message ID. |
fd6fbf17 MW |
255 | * For IKEv1, the arguments do not set the message ID, but the DPD sequence |
256 | * number counters. | |
b09ca747 | 257 | * |
fd6fbf17 MW |
258 | * @param initiate message ID / DPD seq to initiate exchanges (send) |
259 | * @param respond message ID / DPD seq to respond to exchanges (expect) | |
c60c7694 | 260 | */ |
05a2be82 | 261 | void (*reset)(task_manager_t *this, uint32_t initiate, uint32_t respond); |
7daf5226 | 262 | |
c60c7694 | 263 | /** |
552cc11b | 264 | * Check if we are currently waiting for a reply. |
c60c7694 | 265 | * |
c60c7694 MW |
266 | * @return TRUE if we are waiting, FALSE otherwise |
267 | */ | |
268 | bool (*busy) (task_manager_t *this); | |
7daf5226 | 269 | |
665c18bd MW |
270 | /** |
271 | * Create an enumerator over tasks in a specific queue. | |
272 | * | |
273 | * @param queue queue to create an enumerator over | |
274 | * @return enumerator over task_t | |
275 | */ | |
276 | enumerator_t* (*create_task_enumerator)(task_manager_t *this, | |
277 | task_queue_t queue); | |
278 | ||
b1908994 | 279 | /** |
4505e3c0 TB |
280 | * Remove the task the given enumerator points to. |
281 | * | |
b3ab7a48 | 282 | * @note This should be used with caution, in particular, for tasks in the |
4505e3c0 TB |
283 | * active and passive queues. |
284 | * | |
285 | * @param enumerator enumerator created with the method above | |
286 | */ | |
287 | void (*remove_task)(task_manager_t *this, enumerator_t *enumerator); | |
288 | ||
289 | /** | |
b1908994 TE |
290 | * Flush all tasks, regardless of the queue. |
291 | */ | |
292 | void (*flush)(task_manager_t *this); | |
293 | ||
a5c79960 | 294 | /** |
f6aafb30 | 295 | * Flush a queue, canceling all tasks. |
a5c79960 MW |
296 | * |
297 | * @param queue queue to flush | |
298 | */ | |
299 | void (*flush_queue)(task_manager_t *this, task_queue_t queue); | |
300 | ||
c60c7694 | 301 | /** |
552cc11b | 302 | * Destroy the task_manager_t. |
c60c7694 MW |
303 | */ |
304 | void (*destroy) (task_manager_t *this); | |
305 | }; | |
306 | ||
bfbd3af8 TB |
307 | /** |
308 | * Calculate total timeout of the retransmission mechanism. | |
309 | * | |
310 | * This is affected by modifications of retransmit_base, retransmit_timeout, | |
311 | * retransmit_limit or retransmit_tries. The resulting value can then be used | |
312 | * e.g. in kernel plugins to set the system's acquire timeout properly. | |
313 | * | |
314 | * @return calculated total retransmission timeout in seconds | |
315 | */ | |
316 | u_int task_manager_total_retransmit_timeout(); | |
317 | ||
558f79f7 MW |
318 | /** |
319 | * Create a task manager instance for the correct IKE version. | |
320 | * | |
321 | * @param ike_sa IKE_SA to create a task manager for | |
322 | * @return task manager implementation for IKE version | |
323 | */ | |
324 | task_manager_t *task_manager_create(ike_sa_t *ike_sa); | |
325 | ||
1490ff4d | 326 | #endif /** TASK_MANAGER_H_ @}*/ |