4 * @brief Implementation of policy_t.
9 * Copyright (C) 2005 Jan Hutter, Martin Willi
10 * Hochschule fuer Technik Rapperswil
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>.
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
28 #include <utils/linked_list.h>
29 #include <utils/identification.h>
30 #include <utils/logger.h>
32 typedef struct private_policy_t private_policy_t
;
35 * Private data of an policy_t object
37 struct private_policy_t
{
45 * Name of the policy, used to query it
50 * id to use to identify us
52 identification_t
*my_id
;
55 * allowed id for other
57 identification_t
*other_id
;
60 * list for all proposals
62 linked_list_t
*proposals
;
65 * list for traffic selectors for my site
70 * list for traffic selectors for others site
72 linked_list_t
*other_ts
;
75 * select_traffic_selectors for both
77 linked_list_t
*(*select_traffic_selectors
) (private_policy_t
*,linked_list_t
*,linked_list_t
*);
81 * Implementation of policy_t.get_name
83 static char *get_name(private_policy_t
*this)
89 * Implementation of policy_t.get_my_id
91 static identification_t
*get_my_id(private_policy_t
*this)
97 * Implementation of policy_t.get_other_id
99 static identification_t
*get_other_id(private_policy_t
*this)
101 return this->other_id
;
105 * Implementation of policy_t.update_my_id
107 static void update_my_id(private_policy_t
*this, identification_t
*my_id
)
109 this->my_id
->destroy(this->my_id
);
114 * Implementation of policy_t.update_other_id
116 static void update_other_id(private_policy_t
*this, identification_t
*other_id
)
118 this->other_id
->destroy(this->other_id
);
119 this->other_id
= other_id
;
123 * Helper function which does the work for policy_t.update_my_ts and update_other_ts
125 static void update_ts(linked_list_t
* list
, host_t
*new_host
)
127 traffic_selector_t
*ts
;
128 iterator_t
*iterator
;
130 iterator
= list
->create_iterator(list
, TRUE
);
131 while (iterator
->has_next(iterator
))
133 iterator
->current(iterator
, (void**)&ts
);
134 ts
->update_address_range(ts
, new_host
);
136 iterator
->destroy(iterator
);
140 * Implementation of policy_t.update_my_id
142 static void update_my_ts(private_policy_t
*this, host_t
*my_host
)
144 update_ts(this->my_ts
, my_host
);
148 * Implementation of policy_t.update_other_ts
150 static void update_other_ts(private_policy_t
*this, host_t
*my_host
)
152 update_ts(this->other_ts
, my_host
);
156 * Implementation of policy_t.get_my_traffic_selectors
158 static linked_list_t
*get_my_traffic_selectors(private_policy_t
*this)
164 * Implementation of policy_t.get_other_traffic_selectors
166 static linked_list_t
*get_other_traffic_selectors(private_policy_t
*this, traffic_selector_t
**traffic_selectors
[])
168 return this->other_ts
;
172 * Implementation of private_policy_t.select_my_traffic_selectors
174 static linked_list_t
*select_my_traffic_selectors(private_policy_t
*this, linked_list_t
*supplied
)
176 return this->select_traffic_selectors(this, this->my_ts
, supplied
);
180 * Implementation of private_policy_t.select_other_traffic_selectors
182 static linked_list_t
*select_other_traffic_selectors(private_policy_t
*this, linked_list_t
*supplied
)
184 return this->select_traffic_selectors(this, this->other_ts
, supplied
);
187 * Implementation of private_policy_t.select_traffic_selectors
189 static linked_list_t
*select_traffic_selectors(private_policy_t
*this, linked_list_t
*stored
, linked_list_t
*supplied
)
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();
196 stored_iter
= stored
->create_iterator(stored
, TRUE
);
197 supplied_iter
= supplied
->create_iterator(supplied
, TRUE
);
199 /* iterate over all stored selectors */
200 while (stored_iter
->has_next(stored_iter
))
202 stored_iter
->current(stored_iter
, (void**)&stored_ts
);
204 supplied_iter
->reset(supplied_iter
);
205 /* iterate over all supplied traffic selectors */
206 while (supplied_iter
->has_next(supplied_iter
))
208 supplied_iter
->current(supplied_iter
, (void**)&supplied_ts
);
210 selected_ts
= stored_ts
->get_subset(stored_ts
, supplied_ts
);
213 /* got a match, add to list */
214 selected
->insert_last(selected
, (void*)selected_ts
);
218 stored_iter
->destroy(stored_iter
);
219 supplied_iter
->destroy(supplied_iter
);
225 * Implementation of policy_t.get_proposal_iterator
227 static linked_list_t
*get_proposals(private_policy_t
*this)
229 return this->proposals
;
233 * Implementation of policy_t.select_proposal
235 static proposal_t
*select_proposal(private_policy_t
*this, linked_list_t
*proposals
)
237 iterator_t
*stored_iter
, *supplied_iter
;
238 proposal_t
*stored
, *supplied
, *selected
;
240 stored_iter
= this->proposals
->create_iterator(this->proposals
, TRUE
);
241 supplied_iter
= proposals
->create_iterator(proposals
, TRUE
);
243 /* compare all stored proposals with all supplied. Stored ones are preferred. */
244 while (stored_iter
->has_next(stored_iter
))
246 supplied_iter
->reset(supplied_iter
);
247 stored_iter
->current(stored_iter
, (void**)&stored
);
249 while (supplied_iter
->has_next(supplied_iter
))
251 supplied_iter
->current(supplied_iter
, (void**)&supplied
);
252 selected
= stored
->select(stored
, supplied
);
255 /* they match, return */
256 stored_iter
->destroy(stored_iter
);
257 supplied_iter
->destroy(supplied_iter
);
263 /* no proposal match :-(, will result in a NO_PROPOSAL_CHOSEN... */
264 stored_iter
->destroy(stored_iter
);
265 supplied_iter
->destroy(supplied_iter
);
271 * Implementation of policy_t.add_my_traffic_selector
273 static void add_my_traffic_selector(private_policy_t
*this, traffic_selector_t
*traffic_selector
)
275 this->my_ts
->insert_last(this->my_ts
, (void*)traffic_selector
);
279 * Implementation of policy_t.add_other_traffic_selector
281 static void add_other_traffic_selector(private_policy_t
*this, traffic_selector_t
*traffic_selector
)
283 this->other_ts
->insert_last(this->other_ts
, (void*)traffic_selector
);
287 * Implementation of policy_t.add_proposal
289 static void add_proposal(private_policy_t
*this, proposal_t
*proposal
)
291 this->proposals
->insert_last(this->proposals
, (void*)proposal
);
295 * Implementation of policy_t.get_soft_lifetime
297 static u_int32_t
get_soft_lifetime(policy_t
*this)
300 return 0; //5 + random() % 3;
304 * Implementation of policy_t.get_hard_lifetime
306 static u_int32_t
get_hard_lifetime(policy_t
*this)
312 * Implements policy_t.clone.
314 static policy_t
*clone(private_policy_t
*this)
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
;
323 /* clone all proposals */
324 iterator
= this->proposals
->create_iterator(this->proposals
, TRUE
);
325 while (iterator
->has_next(iterator
))
327 iterator
->current(iterator
, (void**)&proposal
);
328 proposal
= proposal
->clone(proposal
);
329 clone
->proposals
->insert_last(clone
->proposals
, (void*)proposal
);
331 iterator
->destroy(iterator
);
333 /* clone all local traffic selectors */
334 iterator
= this->my_ts
->create_iterator(this->my_ts
, TRUE
);
335 while (iterator
->has_next(iterator
))
337 iterator
->current(iterator
, (void**)&ts
);
339 clone
->my_ts
->insert_last(clone
->my_ts
, (void*)ts
);
341 iterator
->destroy(iterator
);
343 /* clone all remote traffic selectors */
344 iterator
= this->other_ts
->create_iterator(this->other_ts
, TRUE
);
345 while (iterator
->has_next(iterator
))
347 iterator
->current(iterator
, (void**)&ts
);
349 clone
->other_ts
->insert_last(clone
->other_ts
, (void*)ts
);
351 iterator
->destroy(iterator
);
353 return &clone
->public;
357 * Implements policy_t.destroy.
359 static status_t
destroy(private_policy_t
*this)
361 proposal_t
*proposal
;
362 traffic_selector_t
*traffic_selector
;
365 /* delete proposals */
366 while(this->proposals
->remove_last(this->proposals
, (void**)&proposal
) == SUCCESS
)
368 proposal
->destroy(proposal
);
370 this->proposals
->destroy(this->proposals
);
372 /* delete traffic selectors */
373 while(this->my_ts
->remove_last(this->my_ts
, (void**)&traffic_selector
) == SUCCESS
)
375 traffic_selector
->destroy(traffic_selector
);
377 this->my_ts
->destroy(this->my_ts
);
379 /* delete traffic selectors */
380 while(this->other_ts
->remove_last(this->other_ts
, (void**)&traffic_selector
) == SUCCESS
)
382 traffic_selector
->destroy(traffic_selector
);
384 this->other_ts
->destroy(this->other_ts
);
387 this->my_id
->destroy(this->my_id
);
388 this->other_id
->destroy(this->other_id
);
396 * Described in header-file
398 policy_t
*policy_create(char *name
, identification_t
*my_id
, identification_t
*other_id
)
400 private_policy_t
*this = malloc_thing(private_policy_t
);
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
;
424 /* apply init values */
426 this->other_id
= other_id
;
427 this->name
= strdup(name
);
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();
435 return (&this->public);