]>
Commit | Line | Data |
---|---|---|
d45ec1de | 1 | /** |
16b9a73c | 2 | * @file policy.c |
d45ec1de | 3 | * |
16b9a73c | 4 | * @brief Implementation of policy_t. |
d45ec1de MW |
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 | ||
16b9a73c | 23 | #include "policy.h" |
d45ec1de MW |
24 | |
25 | #include <utils/linked_list.h> | |
ca060d4c | 26 | #include <utils/identification.h> |
7fa8decb | 27 | #include <utils/logger.h> |
d45ec1de | 28 | |
16b9a73c | 29 | typedef struct private_policy_t private_policy_t; |
d45ec1de MW |
30 | |
31 | /** | |
16b9a73c | 32 | * Private data of an policy_t object |
d45ec1de | 33 | */ |
16b9a73c | 34 | struct private_policy_t { |
d45ec1de MW |
35 | |
36 | /** | |
37 | * Public part | |
38 | */ | |
16b9a73c | 39 | policy_t public; |
d45ec1de MW |
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 | ||
d45ec1de MW |
51 | /** |
52 | * list for all proposals | |
53 | */ | |
54 | linked_list_t *proposals; | |
55 | ||
56 | /** | |
a527a426 | 57 | * list for traffic selectors for my site |
d45ec1de | 58 | */ |
a527a426 | 59 | linked_list_t *my_ts; |
257fa503 MW |
60 | |
61 | /** | |
a527a426 | 62 | * list for traffic selectors for others site |
257fa503 | 63 | */ |
a527a426 | 64 | linked_list_t *other_ts; |
257fa503 MW |
65 | |
66 | /** | |
67 | * select_traffic_selectors for both | |
68 | */ | |
16b9a73c | 69 | linked_list_t *(*select_traffic_selectors) (private_policy_t *,linked_list_t*,linked_list_t*); |
d45ec1de MW |
70 | }; |
71 | ||
ca060d4c | 72 | /** |
16b9a73c | 73 | * Implementation of policy_t.get_my_id |
ca060d4c | 74 | */ |
16b9a73c | 75 | static identification_t *get_my_id(private_policy_t *this) |
d45ec1de MW |
76 | { |
77 | return this->my_id; | |
78 | } | |
79 | ||
ca060d4c | 80 | /** |
16b9a73c | 81 | * Implementation of policy_t.get_other_id |
ca060d4c | 82 | */ |
16b9a73c | 83 | static identification_t *get_other_id(private_policy_t *this) |
d45ec1de MW |
84 | { |
85 | return this->other_id; | |
86 | } | |
87 | ||
87a217f9 MW |
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 | ||
ca060d4c | 139 | /** |
16b9a73c | 140 | * Implementation of policy_t.get_my_traffic_selectors |
ca060d4c | 141 | */ |
16b9a73c | 142 | static linked_list_t *get_my_traffic_selectors(private_policy_t *this) |
257fa503 | 143 | { |
a527a426 | 144 | return this->my_ts; |
257fa503 MW |
145 | } |
146 | ||
147 | /** | |
16b9a73c | 148 | * Implementation of policy_t.get_other_traffic_selectors |
257fa503 | 149 | */ |
16b9a73c | 150 | static linked_list_t *get_other_traffic_selectors(private_policy_t *this, traffic_selector_t **traffic_selectors[]) |
257fa503 | 151 | { |
a527a426 | 152 | return this->other_ts; |
d45ec1de MW |
153 | } |
154 | ||
ca060d4c | 155 | /** |
16b9a73c | 156 | * Implementation of private_policy_t.select_my_traffic_selectors |
ca060d4c | 157 | */ |
16b9a73c | 158 | static linked_list_t *select_my_traffic_selectors(private_policy_t *this, linked_list_t *supplied) |
257fa503 | 159 | { |
a527a426 | 160 | return this->select_traffic_selectors(this, this->my_ts, supplied); |
257fa503 MW |
161 | } |
162 | ||
163 | /** | |
16b9a73c | 164 | * Implementation of private_policy_t.select_other_traffic_selectors |
257fa503 | 165 | */ |
16b9a73c | 166 | static linked_list_t *select_other_traffic_selectors(private_policy_t *this, linked_list_t *supplied) |
257fa503 | 167 | { |
a527a426 | 168 | return this->select_traffic_selectors(this, this->other_ts, supplied); |
257fa503 MW |
169 | } |
170 | /** | |
16b9a73c | 171 | * Implementation of private_policy_t.select_traffic_selectors |
257fa503 | 172 | */ |
16b9a73c | 173 | static linked_list_t *select_traffic_selectors(private_policy_t *this, linked_list_t *stored, linked_list_t *supplied) |
d45ec1de | 174 | { |
a527a426 MW |
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 | ||
d45ec1de | 179 | |
a527a426 MW |
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)) | |
d45ec1de | 185 | { |
a527a426 MW |
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)) | |
d45ec1de | 191 | { |
a527a426 MW |
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) | |
d45ec1de | 196 | { |
a527a426 MW |
197 | /* got a match, add to list */ |
198 | selected->insert_last(selected, (void*)selected_ts); | |
d45ec1de MW |
199 | } |
200 | } | |
201 | } | |
a527a426 MW |
202 | stored_iter->destroy(stored_iter); |
203 | supplied_iter->destroy(supplied_iter); | |
d45ec1de | 204 | |
a527a426 | 205 | return selected; |
d45ec1de | 206 | } |
ca060d4c MW |
207 | |
208 | /** | |
16b9a73c | 209 | * Implementation of policy_t.get_proposal_iterator |
ca060d4c | 210 | */ |
16b9a73c | 211 | static linked_list_t *get_proposals(private_policy_t *this) |
d45ec1de | 212 | { |
c06dbbab | 213 | return this->proposals; |
d45ec1de MW |
214 | } |
215 | ||
ca060d4c | 216 | /** |
16b9a73c | 217 | * Implementation of policy_t.select_proposal |
ca060d4c | 218 | */ |
16b9a73c | 219 | static proposal_t *select_proposal(private_policy_t *this, linked_list_t *proposals) |
d45ec1de | 220 | { |
384efc76 | 221 | iterator_t *stored_iter, *supplied_iter; |
ce461bbd | 222 | proposal_t *stored, *supplied, *selected; |
7fa8decb | 223 | |
384efc76 MW |
224 | stored_iter = this->proposals->create_iterator(this->proposals, TRUE); |
225 | supplied_iter = proposals->create_iterator(proposals, TRUE); | |
d45ec1de | 226 | |
384efc76 MW |
227 | /* compare all stored proposals with all supplied. Stored ones are preferred. */ |
228 | while (stored_iter->has_next(stored_iter)) | |
d45ec1de | 229 | { |
384efc76 MW |
230 | supplied_iter->reset(supplied_iter); |
231 | stored_iter->current(stored_iter, (void**)&stored); | |
7fa8decb | 232 | |
384efc76 MW |
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) | |
d45ec1de | 238 | { |
384efc76 MW |
239 | /* they match, return */ |
240 | stored_iter->destroy(stored_iter); | |
241 | supplied_iter->destroy(supplied_iter); | |
242 | return selected; | |
d45ec1de MW |
243 | } |
244 | } | |
245 | } | |
ccf783d2 | 246 | |
384efc76 MW |
247 | /* no proposal match :-(, will result in a NO_PROPOSAL_CHOSEN... */ |
248 | stored_iter->destroy(stored_iter); | |
249 | supplied_iter->destroy(supplied_iter); | |
ca060d4c | 250 | |
384efc76 | 251 | return NULL; |
d45ec1de | 252 | } |
ca060d4c MW |
253 | |
254 | /** | |
16b9a73c | 255 | * Implementation of policy_t.add_my_traffic_selector |
ca060d4c | 256 | */ |
16b9a73c | 257 | static void add_my_traffic_selector(private_policy_t *this, traffic_selector_t *traffic_selector) |
d45ec1de | 258 | { |
a527a426 | 259 | this->my_ts->insert_last(this->my_ts, (void*)traffic_selector); |
257fa503 MW |
260 | } |
261 | ||
262 | /** | |
16b9a73c | 263 | * Implementation of policy_t.add_other_traffic_selector |
257fa503 | 264 | */ |
16b9a73c | 265 | static void add_other_traffic_selector(private_policy_t *this, traffic_selector_t *traffic_selector) |
257fa503 | 266 | { |
a527a426 | 267 | this->other_ts->insert_last(this->other_ts, (void*)traffic_selector); |
d45ec1de MW |
268 | } |
269 | ||
ca060d4c | 270 | /** |
16b9a73c | 271 | * Implementation of policy_t.add_proposal |
ca060d4c | 272 | */ |
16b9a73c | 273 | static void add_proposal(private_policy_t *this, proposal_t *proposal) |
d45ec1de | 274 | { |
384efc76 | 275 | this->proposals->insert_last(this->proposals, (void*)proposal); |
d45ec1de MW |
276 | } |
277 | ||
278 | /** | |
16b9a73c | 279 | * Implements policy_t.destroy. |
d45ec1de | 280 | */ |
16b9a73c | 281 | static status_t destroy(private_policy_t *this) |
d45ec1de | 282 | { |
ce461bbd | 283 | proposal_t *proposal; |
d45ec1de MW |
284 | traffic_selector_t *traffic_selector; |
285 | ||
ca060d4c | 286 | |
d45ec1de | 287 | /* delete proposals */ |
dfa6e086 | 288 | while(this->proposals->remove_last(this->proposals, (void**)&proposal) == SUCCESS) |
d45ec1de | 289 | { |
384efc76 | 290 | proposal->destroy(proposal); |
d45ec1de MW |
291 | } |
292 | this->proposals->destroy(this->proposals); | |
293 | ||
294 | /* delete traffic selectors */ | |
a527a426 | 295 | while(this->my_ts->remove_last(this->my_ts, (void**)&traffic_selector) == SUCCESS) |
257fa503 | 296 | { |
257fa503 MW |
297 | traffic_selector->destroy(traffic_selector); |
298 | } | |
a527a426 | 299 | this->my_ts->destroy(this->my_ts); |
257fa503 MW |
300 | |
301 | /* delete traffic selectors */ | |
a527a426 | 302 | while(this->other_ts->remove_last(this->other_ts, (void**)&traffic_selector) == SUCCESS) |
d45ec1de | 303 | { |
712db4bf | 304 | traffic_selector->destroy(traffic_selector); |
d45ec1de | 305 | } |
a527a426 | 306 | this->other_ts->destroy(this->other_ts); |
d45ec1de | 307 | |
ca060d4c MW |
308 | /* delete ids */ |
309 | this->my_id->destroy(this->my_id); | |
310 | this->other_id->destroy(this->other_id); | |
311 | ||
5113680f | 312 | free(this); |
d45ec1de MW |
313 | return SUCCESS; |
314 | } | |
315 | ||
87a217f9 MW |
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 | ||
d45ec1de MW |
360 | /* |
361 | * Described in header-file | |
362 | */ | |
16b9a73c | 363 | policy_t *policy_create(identification_t *my_id, identification_t *other_id) |
d45ec1de | 364 | { |
5113680f | 365 | private_policy_t *this = malloc_thing(private_policy_t); |
d45ec1de MW |
366 | |
367 | /* public functions */ | |
16b9a73c MW |
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; | |
87a217f9 MW |
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; | |
16b9a73c MW |
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; | |
87a217f9 | 383 | this->public.clone = (policy_t*(*)(policy_t*))clone; |
16b9a73c | 384 | this->public.destroy = (void(*)(policy_t*))destroy; |
ca060d4c MW |
385 | |
386 | /* apply init values */ | |
16b9a73c MW |
387 | this->my_id = my_id; |
388 | this->other_id = other_id; | |
ca060d4c MW |
389 | |
390 | /* init private members*/ | |
257fa503 | 391 | this->select_traffic_selectors = select_traffic_selectors; |
d45ec1de | 392 | this->proposals = linked_list_create(); |
a527a426 MW |
393 | this->my_ts = linked_list_create(); |
394 | this->other_ts = linked_list_create(); | |
d45ec1de MW |
395 | |
396 | return (&this->public); | |
397 | } |