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