fixed compile warnings when using -Wall
[strongswan.git] / src / charon / config / policies / policy.c
1 /**
2 * @file policy.c
3 *
4 * @brief Implementation of policy_t.
5 *
6 */
7
8 /*
9 * Copyright (C) 2005 Jan Hutter, 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 <time.h>
24 #include <string.h>
25
26 #include "policy.h"
27
28 #include <utils/linked_list.h>
29 #include <utils/identification.h>
30 #include <utils/logger.h>
31
32 typedef struct private_policy_t private_policy_t;
33
34 /**
35 * Private data of an policy_t object
36 */
37 struct private_policy_t {
38
39 /**
40 * Public part
41 */
42 policy_t public;
43
44 /**
45 * Name of the policy, used to query it
46 */
47 char *name;
48
49 /**
50 * id to use to identify us
51 */
52 identification_t *my_id;
53
54 /**
55 * allowed id for other
56 */
57 identification_t *other_id;
58
59 /**
60 * list for all proposals
61 */
62 linked_list_t *proposals;
63
64 /**
65 * list for traffic selectors for my site
66 */
67 linked_list_t *my_ts;
68
69 /**
70 * list for traffic selectors for others site
71 */
72 linked_list_t *other_ts;
73
74 /**
75 * select_traffic_selectors for both
76 */
77 linked_list_t *(*select_traffic_selectors) (private_policy_t *,linked_list_t*,linked_list_t*);
78 };
79
80 /**
81 * Implementation of policy_t.get_name
82 */
83 static char *get_name(private_policy_t *this)
84 {
85 return this->name;
86 }
87
88 /**
89 * Implementation of policy_t.get_my_id
90 */
91 static identification_t *get_my_id(private_policy_t *this)
92 {
93 return this->my_id;
94 }
95
96 /**
97 * Implementation of policy_t.get_other_id
98 */
99 static identification_t *get_other_id(private_policy_t *this)
100 {
101 return this->other_id;
102 }
103
104 /**
105 * Implementation of policy_t.update_my_id
106 */
107 static void update_my_id(private_policy_t *this, identification_t *my_id)
108 {
109 this->my_id->destroy(this->my_id);
110 this->my_id = my_id;
111 }
112
113 /**
114 * Implementation of policy_t.update_other_id
115 */
116 static void update_other_id(private_policy_t *this, identification_t *other_id)
117 {
118 this->other_id->destroy(this->other_id);
119 this->other_id = other_id;
120 }
121
122 /**
123 * Helper function which does the work for policy_t.update_my_ts and update_other_ts
124 */
125 static void update_ts(linked_list_t* list, host_t *new_host)
126 {
127 traffic_selector_t *ts;
128 iterator_t *iterator;
129
130 iterator = list->create_iterator(list, TRUE);
131 while (iterator->has_next(iterator))
132 {
133 iterator->current(iterator, (void**)&ts);
134 ts->update_address_range(ts, new_host);
135 }
136 iterator->destroy(iterator);
137 }
138
139 /**
140 * Implementation of policy_t.update_my_id
141 */
142 static void update_my_ts(private_policy_t *this, host_t *my_host)
143 {
144 update_ts(this->my_ts, my_host);
145 }
146
147 /**
148 * Implementation of policy_t.update_other_ts
149 */
150 static void update_other_ts(private_policy_t *this, host_t *my_host)
151 {
152 update_ts(this->other_ts, my_host);
153 }
154
155 /**
156 * Implementation of policy_t.get_my_traffic_selectors
157 */
158 static linked_list_t *get_my_traffic_selectors(private_policy_t *this)
159 {
160 return this->my_ts;
161 }
162
163 /**
164 * Implementation of policy_t.get_other_traffic_selectors
165 */
166 static linked_list_t *get_other_traffic_selectors(private_policy_t *this, traffic_selector_t **traffic_selectors[])
167 {
168 return this->other_ts;
169 }
170
171 /**
172 * Implementation of private_policy_t.select_my_traffic_selectors
173 */
174 static linked_list_t *select_my_traffic_selectors(private_policy_t *this, linked_list_t *supplied)
175 {
176 return this->select_traffic_selectors(this, this->my_ts, supplied);
177 }
178
179 /**
180 * Implementation of private_policy_t.select_other_traffic_selectors
181 */
182 static linked_list_t *select_other_traffic_selectors(private_policy_t *this, linked_list_t *supplied)
183 {
184 return this->select_traffic_selectors(this, this->other_ts, supplied);
185 }
186 /**
187 * Implementation of private_policy_t.select_traffic_selectors
188 */
189 static linked_list_t *select_traffic_selectors(private_policy_t *this, linked_list_t *stored, linked_list_t *supplied)
190 {
191 iterator_t *supplied_iter, *stored_iter;
192 traffic_selector_t *supplied_ts, *stored_ts, *selected_ts;
193 linked_list_t *selected = linked_list_create();
194
195
196 stored_iter = stored->create_iterator(stored, TRUE);
197 supplied_iter = supplied->create_iterator(supplied, TRUE);
198
199 /* iterate over all stored selectors */
200 while (stored_iter->has_next(stored_iter))
201 {
202 stored_iter->current(stored_iter, (void**)&stored_ts);
203
204 supplied_iter->reset(supplied_iter);
205 /* iterate over all supplied traffic selectors */
206 while (supplied_iter->has_next(supplied_iter))
207 {
208 supplied_iter->current(supplied_iter, (void**)&supplied_ts);
209
210 selected_ts = stored_ts->get_subset(stored_ts, supplied_ts);
211 if (selected_ts)
212 {
213 /* got a match, add to list */
214 selected->insert_last(selected, (void*)selected_ts);
215 }
216 }
217 }
218 stored_iter->destroy(stored_iter);
219 supplied_iter->destroy(supplied_iter);
220
221 return selected;
222 }
223
224 /**
225 * Implementation of policy_t.get_proposal_iterator
226 */
227 static linked_list_t *get_proposals(private_policy_t *this)
228 {
229 return this->proposals;
230 }
231
232 /**
233 * Implementation of policy_t.select_proposal
234 */
235 static proposal_t *select_proposal(private_policy_t *this, linked_list_t *proposals)
236 {
237 iterator_t *stored_iter, *supplied_iter;
238 proposal_t *stored, *supplied, *selected;
239
240 stored_iter = this->proposals->create_iterator(this->proposals, TRUE);
241 supplied_iter = proposals->create_iterator(proposals, TRUE);
242
243 /* compare all stored proposals with all supplied. Stored ones are preferred. */
244 while (stored_iter->has_next(stored_iter))
245 {
246 supplied_iter->reset(supplied_iter);
247 stored_iter->current(stored_iter, (void**)&stored);
248
249 while (supplied_iter->has_next(supplied_iter))
250 {
251 supplied_iter->current(supplied_iter, (void**)&supplied);
252 selected = stored->select(stored, supplied);
253 if (selected)
254 {
255 /* they match, return */
256 stored_iter->destroy(stored_iter);
257 supplied_iter->destroy(supplied_iter);
258 return selected;
259 }
260 }
261 }
262
263 /* no proposal match :-(, will result in a NO_PROPOSAL_CHOSEN... */
264 stored_iter->destroy(stored_iter);
265 supplied_iter->destroy(supplied_iter);
266
267 return NULL;
268 }
269
270 /**
271 * Implementation of policy_t.add_my_traffic_selector
272 */
273 static void add_my_traffic_selector(private_policy_t *this, traffic_selector_t *traffic_selector)
274 {
275 this->my_ts->insert_last(this->my_ts, (void*)traffic_selector);
276 }
277
278 /**
279 * Implementation of policy_t.add_other_traffic_selector
280 */
281 static void add_other_traffic_selector(private_policy_t *this, traffic_selector_t *traffic_selector)
282 {
283 this->other_ts->insert_last(this->other_ts, (void*)traffic_selector);
284 }
285
286 /**
287 * Implementation of policy_t.add_proposal
288 */
289 static void add_proposal(private_policy_t *this, proposal_t *proposal)
290 {
291 this->proposals->insert_last(this->proposals, (void*)proposal);
292 }
293
294 /**
295 * Implementation of policy_t.get_soft_lifetime
296 */
297 static u_int32_t get_soft_lifetime(policy_t *this)
298 {
299 srandom(time(NULL));
300 return 0; //5 + random() % 3;
301 }
302
303 /**
304 * Implementation of policy_t.get_hard_lifetime
305 */
306 static u_int32_t get_hard_lifetime(policy_t *this)
307 {
308 return 0; //9;
309 }
310
311 /**
312 * Implements policy_t.clone.
313 */
314 static policy_t *clone(private_policy_t *this)
315 {
316 private_policy_t *clone = (private_policy_t*)policy_create(this->name,
317 this->my_id->clone(this->my_id),
318 this->other_id->clone(this->other_id));
319 iterator_t *iterator;
320 proposal_t *proposal;
321 traffic_selector_t *ts;
322
323 /* clone all proposals */
324 iterator = this->proposals->create_iterator(this->proposals, TRUE);
325 while (iterator->has_next(iterator))
326 {
327 iterator->current(iterator, (void**)&proposal);
328 proposal = proposal->clone(proposal);
329 clone->proposals->insert_last(clone->proposals, (void*)proposal);
330 }
331 iterator->destroy(iterator);
332
333 /* clone all local traffic selectors */
334 iterator = this->my_ts->create_iterator(this->my_ts, TRUE);
335 while (iterator->has_next(iterator))
336 {
337 iterator->current(iterator, (void**)&ts);
338 ts = ts->clone(ts);
339 clone->my_ts->insert_last(clone->my_ts, (void*)ts);
340 }
341 iterator->destroy(iterator);
342
343 /* clone all remote traffic selectors */
344 iterator = this->other_ts->create_iterator(this->other_ts, TRUE);
345 while (iterator->has_next(iterator))
346 {
347 iterator->current(iterator, (void**)&ts);
348 ts = ts->clone(ts);
349 clone->other_ts->insert_last(clone->other_ts, (void*)ts);
350 }
351 iterator->destroy(iterator);
352
353 return &clone->public;
354 }
355
356 /**
357 * Implements policy_t.destroy.
358 */
359 static status_t destroy(private_policy_t *this)
360 {
361 proposal_t *proposal;
362 traffic_selector_t *traffic_selector;
363
364
365 /* delete proposals */
366 while(this->proposals->remove_last(this->proposals, (void**)&proposal) == SUCCESS)
367 {
368 proposal->destroy(proposal);
369 }
370 this->proposals->destroy(this->proposals);
371
372 /* delete traffic selectors */
373 while(this->my_ts->remove_last(this->my_ts, (void**)&traffic_selector) == SUCCESS)
374 {
375 traffic_selector->destroy(traffic_selector);
376 }
377 this->my_ts->destroy(this->my_ts);
378
379 /* delete traffic selectors */
380 while(this->other_ts->remove_last(this->other_ts, (void**)&traffic_selector) == SUCCESS)
381 {
382 traffic_selector->destroy(traffic_selector);
383 }
384 this->other_ts->destroy(this->other_ts);
385
386 /* delete ids */
387 this->my_id->destroy(this->my_id);
388 this->other_id->destroy(this->other_id);
389
390 free(this->name);
391 free(this);
392 return SUCCESS;
393 }
394
395 /*
396 * Described in header-file
397 */
398 policy_t *policy_create(char *name, identification_t *my_id, identification_t *other_id)
399 {
400 private_policy_t *this = malloc_thing(private_policy_t);
401
402 /* public functions */
403 this->public.get_name = (char *(*)(policy_t*))get_name;
404 this->public.get_my_id = (identification_t*(*)(policy_t*))get_my_id;
405 this->public.get_other_id = (identification_t*(*)(policy_t*))get_other_id;
406 this->public.update_my_id = (void(*)(policy_t*,identification_t*))update_my_id;
407 this->public.update_other_id = (void(*)(policy_t*,identification_t*))update_other_id;
408 this->public.update_my_ts = (void(*)(policy_t*,host_t*))update_my_ts;
409 this->public.update_other_ts = (void(*)(policy_t*,host_t*))update_other_ts;
410 this->public.get_my_traffic_selectors = (linked_list_t*(*)(policy_t*))get_my_traffic_selectors;
411 this->public.select_my_traffic_selectors = (linked_list_t*(*)(policy_t*,linked_list_t*))select_my_traffic_selectors;
412 this->public.get_other_traffic_selectors = (linked_list_t*(*)(policy_t*))get_other_traffic_selectors;
413 this->public.select_other_traffic_selectors = (linked_list_t*(*)(policy_t*,linked_list_t*))select_other_traffic_selectors;
414 this->public.get_proposals = (linked_list_t*(*)(policy_t*))get_proposals;
415 this->public.select_proposal = (proposal_t*(*)(policy_t*,linked_list_t*))select_proposal;
416 this->public.add_my_traffic_selector = (void(*)(policy_t*,traffic_selector_t*))add_my_traffic_selector;
417 this->public.add_other_traffic_selector = (void(*)(policy_t*,traffic_selector_t*))add_other_traffic_selector;
418 this->public.add_proposal = (void(*)(policy_t*,proposal_t*))add_proposal;
419 this->public.get_soft_lifetime = (u_int32_t (*) (policy_t *))get_soft_lifetime;
420 this->public.get_hard_lifetime = (u_int32_t (*) (policy_t *))get_hard_lifetime;
421 this->public.clone = (policy_t*(*)(policy_t*))clone;
422 this->public.destroy = (void(*)(policy_t*))destroy;
423
424 /* apply init values */
425 this->my_id = my_id;
426 this->other_id = other_id;
427 this->name = strdup(name);
428
429 /* init private members*/
430 this->select_traffic_selectors = select_traffic_selectors;
431 this->proposals = linked_list_create();
432 this->my_ts = linked_list_create();
433 this->other_ts = linked_list_create();
434
435 return (&this->public);
436 }