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
25 #include <utils/linked_list.h>
26 #include <utils/identification.h>
27 #include <utils/logger.h>
29 typedef struct private_policy_t private_policy_t
;
32 * Private data of an policy_t object
34 struct private_policy_t
{
42 * Name of the policy, used to query it
47 * id to use to identify us
49 identification_t
*my_id
;
52 * allowed id for other
54 identification_t
*other_id
;
57 * list for all proposals
59 linked_list_t
*proposals
;
62 * list for traffic selectors for my site
67 * list for traffic selectors for others site
69 linked_list_t
*other_ts
;
72 * select_traffic_selectors for both
74 linked_list_t
*(*select_traffic_selectors
) (private_policy_t
*,linked_list_t
*,linked_list_t
*);
78 * Implementation of policy_t.get_name
80 static char *get_name(private_policy_t
*this)
86 * Implementation of policy_t.get_my_id
88 static identification_t
*get_my_id(private_policy_t
*this)
94 * Implementation of policy_t.get_other_id
96 static identification_t
*get_other_id(private_policy_t
*this)
98 return this->other_id
;
102 * Implementation of policy_t.update_my_id
104 static void update_my_id(private_policy_t
*this, identification_t
*my_id
)
106 this->my_id
->destroy(this->my_id
);
111 * Implementation of policy_t.update_other_id
113 static void update_other_id(private_policy_t
*this, identification_t
*other_id
)
115 this->other_id
->destroy(this->other_id
);
116 this->other_id
= other_id
;
120 * Helper function which does the work for policy_t.update_my_ts and update_other_ts
122 static void update_ts(linked_list_t
* list
, host_t
*new_host
)
124 traffic_selector_t
*ts
;
125 iterator_t
*iterator
;
127 iterator
= list
->create_iterator(list
, TRUE
);
128 while (iterator
->has_next(iterator
))
130 iterator
->current(iterator
, (void**)&ts
);
131 ts
->update_address_range(ts
, new_host
);
133 iterator
->destroy(iterator
);
137 * Implementation of policy_t.update_my_id
139 static void update_my_ts(private_policy_t
*this, host_t
*my_host
)
141 update_ts(this->my_ts
, my_host
);
145 * Implementation of policy_t.update_other_ts
147 static void update_other_ts(private_policy_t
*this, host_t
*my_host
)
149 update_ts(this->other_ts
, my_host
);
153 * Implementation of policy_t.get_my_traffic_selectors
155 static linked_list_t
*get_my_traffic_selectors(private_policy_t
*this)
161 * Implementation of policy_t.get_other_traffic_selectors
163 static linked_list_t
*get_other_traffic_selectors(private_policy_t
*this, traffic_selector_t
**traffic_selectors
[])
165 return this->other_ts
;
169 * Implementation of private_policy_t.select_my_traffic_selectors
171 static linked_list_t
*select_my_traffic_selectors(private_policy_t
*this, linked_list_t
*supplied
)
173 return this->select_traffic_selectors(this, this->my_ts
, supplied
);
177 * Implementation of private_policy_t.select_other_traffic_selectors
179 static linked_list_t
*select_other_traffic_selectors(private_policy_t
*this, linked_list_t
*supplied
)
181 return this->select_traffic_selectors(this, this->other_ts
, supplied
);
184 * Implementation of private_policy_t.select_traffic_selectors
186 static linked_list_t
*select_traffic_selectors(private_policy_t
*this, linked_list_t
*stored
, linked_list_t
*supplied
)
188 iterator_t
*supplied_iter
, *stored_iter
;
189 traffic_selector_t
*supplied_ts
, *stored_ts
, *selected_ts
;
190 linked_list_t
*selected
= linked_list_create();
193 stored_iter
= stored
->create_iterator(stored
, TRUE
);
194 supplied_iter
= supplied
->create_iterator(supplied
, TRUE
);
196 /* iterate over all stored selectors */
197 while (stored_iter
->has_next(stored_iter
))
199 stored_iter
->current(stored_iter
, (void**)&stored_ts
);
201 supplied_iter
->reset(supplied_iter
);
202 /* iterate over all supplied traffic selectors */
203 while (supplied_iter
->has_next(supplied_iter
))
205 supplied_iter
->current(supplied_iter
, (void**)&supplied_ts
);
207 selected_ts
= stored_ts
->get_subset(stored_ts
, supplied_ts
);
210 /* got a match, add to list */
211 selected
->insert_last(selected
, (void*)selected_ts
);
215 stored_iter
->destroy(stored_iter
);
216 supplied_iter
->destroy(supplied_iter
);
222 * Implementation of policy_t.get_proposal_iterator
224 static linked_list_t
*get_proposals(private_policy_t
*this)
226 return this->proposals
;
230 * Implementation of policy_t.select_proposal
232 static proposal_t
*select_proposal(private_policy_t
*this, linked_list_t
*proposals
)
234 iterator_t
*stored_iter
, *supplied_iter
;
235 proposal_t
*stored
, *supplied
, *selected
;
237 stored_iter
= this->proposals
->create_iterator(this->proposals
, TRUE
);
238 supplied_iter
= proposals
->create_iterator(proposals
, TRUE
);
240 /* compare all stored proposals with all supplied. Stored ones are preferred. */
241 while (stored_iter
->has_next(stored_iter
))
243 supplied_iter
->reset(supplied_iter
);
244 stored_iter
->current(stored_iter
, (void**)&stored
);
246 while (supplied_iter
->has_next(supplied_iter
))
248 supplied_iter
->current(supplied_iter
, (void**)&supplied
);
249 selected
= stored
->select(stored
, supplied
);
252 /* they match, return */
253 stored_iter
->destroy(stored_iter
);
254 supplied_iter
->destroy(supplied_iter
);
260 /* no proposal match :-(, will result in a NO_PROPOSAL_CHOSEN... */
261 stored_iter
->destroy(stored_iter
);
262 supplied_iter
->destroy(supplied_iter
);
268 * Implementation of policy_t.add_my_traffic_selector
270 static void add_my_traffic_selector(private_policy_t
*this, traffic_selector_t
*traffic_selector
)
272 this->my_ts
->insert_last(this->my_ts
, (void*)traffic_selector
);
276 * Implementation of policy_t.add_other_traffic_selector
278 static void add_other_traffic_selector(private_policy_t
*this, traffic_selector_t
*traffic_selector
)
280 this->other_ts
->insert_last(this->other_ts
, (void*)traffic_selector
);
284 * Implementation of policy_t.add_proposal
286 static void add_proposal(private_policy_t
*this, proposal_t
*proposal
)
288 this->proposals
->insert_last(this->proposals
, (void*)proposal
);
292 * Implementation of policy_t.get_soft_lifetime
294 static u_int32_t
get_soft_lifetime(policy_t
*this)
296 return 0; /*5 + random() % 5; */
300 * Implementation of policy_t.get_hard_lifetime
302 static u_int32_t
get_hard_lifetime(policy_t
*this)
308 * Implements policy_t.clone.
310 static policy_t
*clone(private_policy_t
*this)
312 private_policy_t
*clone
= (private_policy_t
*)policy_create(this->name
,
313 this->my_id
->clone(this->my_id
),
314 this->other_id
->clone(this->other_id
));
315 iterator_t
*iterator
;
316 proposal_t
*proposal
;
317 traffic_selector_t
*ts
;
319 /* clone all proposals */
320 iterator
= this->proposals
->create_iterator(this->proposals
, TRUE
);
321 while (iterator
->has_next(iterator
))
323 iterator
->current(iterator
, (void**)&proposal
);
324 proposal
= proposal
->clone(proposal
);
325 clone
->proposals
->insert_last(clone
->proposals
, (void*)proposal
);
327 iterator
->destroy(iterator
);
329 /* clone all local traffic selectors */
330 iterator
= this->my_ts
->create_iterator(this->my_ts
, TRUE
);
331 while (iterator
->has_next(iterator
))
333 iterator
->current(iterator
, (void**)&ts
);
335 clone
->my_ts
->insert_last(clone
->my_ts
, (void*)ts
);
337 iterator
->destroy(iterator
);
339 /* clone all remote traffic selectors */
340 iterator
= this->other_ts
->create_iterator(this->other_ts
, TRUE
);
341 while (iterator
->has_next(iterator
))
343 iterator
->current(iterator
, (void**)&ts
);
345 clone
->other_ts
->insert_last(clone
->other_ts
, (void*)ts
);
347 iterator
->destroy(iterator
);
349 return &clone
->public;
353 * Implements policy_t.destroy.
355 static status_t
destroy(private_policy_t
*this)
357 proposal_t
*proposal
;
358 traffic_selector_t
*traffic_selector
;
361 /* delete proposals */
362 while(this->proposals
->remove_last(this->proposals
, (void**)&proposal
) == SUCCESS
)
364 proposal
->destroy(proposal
);
366 this->proposals
->destroy(this->proposals
);
368 /* delete traffic selectors */
369 while(this->my_ts
->remove_last(this->my_ts
, (void**)&traffic_selector
) == SUCCESS
)
371 traffic_selector
->destroy(traffic_selector
);
373 this->my_ts
->destroy(this->my_ts
);
375 /* delete traffic selectors */
376 while(this->other_ts
->remove_last(this->other_ts
, (void**)&traffic_selector
) == SUCCESS
)
378 traffic_selector
->destroy(traffic_selector
);
380 this->other_ts
->destroy(this->other_ts
);
383 this->my_id
->destroy(this->my_id
);
384 this->other_id
->destroy(this->other_id
);
392 * Described in header-file
394 policy_t
*policy_create(char *name
, identification_t
*my_id
, identification_t
*other_id
)
396 private_policy_t
*this = malloc_thing(private_policy_t
);
398 /* public functions */
399 this->public.get_name
= (char *(*)(policy_t
*))get_name
;
400 this->public.get_my_id
= (identification_t
*(*)(policy_t
*))get_my_id
;
401 this->public.get_other_id
= (identification_t
*(*)(policy_t
*))get_other_id
;
402 this->public.update_my_id
= (void(*)(policy_t
*,identification_t
*))update_my_id
;
403 this->public.update_other_id
= (void(*)(policy_t
*,identification_t
*))update_other_id
;
404 this->public.update_my_ts
= (void(*)(policy_t
*,host_t
*))update_my_ts
;
405 this->public.update_other_ts
= (void(*)(policy_t
*,host_t
*))update_other_ts
;
406 this->public.get_my_traffic_selectors
= (linked_list_t
*(*)(policy_t
*))get_my_traffic_selectors
;
407 this->public.select_my_traffic_selectors
= (linked_list_t
*(*)(policy_t
*,linked_list_t
*))select_my_traffic_selectors
;
408 this->public.get_other_traffic_selectors
= (linked_list_t
*(*)(policy_t
*))get_other_traffic_selectors
;
409 this->public.select_other_traffic_selectors
= (linked_list_t
*(*)(policy_t
*,linked_list_t
*))select_other_traffic_selectors
;
410 this->public.get_proposals
= (linked_list_t
*(*)(policy_t
*))get_proposals
;
411 this->public.select_proposal
= (proposal_t
*(*)(policy_t
*,linked_list_t
*))select_proposal
;
412 this->public.add_my_traffic_selector
= (void(*)(policy_t
*,traffic_selector_t
*))add_my_traffic_selector
;
413 this->public.add_other_traffic_selector
= (void(*)(policy_t
*,traffic_selector_t
*))add_other_traffic_selector
;
414 this->public.add_proposal
= (void(*)(policy_t
*,proposal_t
*))add_proposal
;
415 this->public.get_soft_lifetime
= (u_int32_t (*) (policy_t
*))get_soft_lifetime
;
416 this->public.get_hard_lifetime
= (u_int32_t (*) (policy_t
*))get_hard_lifetime
;
417 this->public.clone
= (policy_t
*(*)(policy_t
*))clone
;
418 this->public.destroy
= (void(*)(policy_t
*))destroy
;
420 /* apply init values */
422 this->other_id
= other_id
;
423 this->name
= strdup(name
);
425 /* init private members*/
426 this->select_traffic_selectors
= select_traffic_selectors
;
427 this->proposals
= linked_list_create();
428 this->my_ts
= linked_list_create();
429 this->other_ts
= linked_list_create();
431 return (&this->public);