4 * @brief Implementation of connection_t.
9 * Copyright (C) 2005-2006 Martin Willi
10 * Copyright (C) 2005 Jan Hutter
11 * Hochschule fuer Technik Rapperswil
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26 #include <config/connections/connection.h>
27 #include <utils/linked_list.h>
29 ENUM(cert_policy_names
, CERT_ALWAYS_SEND
, CERT_NEVER_SEND
,
35 typedef struct private_connection_t private_connection_t
;
38 * Private data of an connection_t object
40 struct private_connection_t
{
48 * Number of references hold by others to this connection
53 * Name of the connection
58 * Does charon handle this connection? Or can he ignore it?
63 * should we send a certificate request?
65 cert_policy_t certreq_policy
;
68 * should we send a certificates?
70 cert_policy_t cert_policy
;
75 identification_t
*my_id
;
78 * Host information of my host.
83 * Host information of other host.
88 * Interval to send DPD liveness checks on inactivity
93 * Number of retransmission sequences to send bevore giving up
95 u_int32_t keyingtries
;
100 linked_list_t
*proposals
;
103 * Time before an SA gets invalid
105 u_int32_t soft_lifetime
;
108 * Time before an SA gets rekeyed
110 u_int32_t hard_lifetime
;
113 * Use full reauthentication instead of rekeying
118 * Time, which specifies the range of a random value
119 * substracted from soft_lifetime.
125 * Implementation of connection_t.get_name.
127 static char *get_name (private_connection_t
*this)
133 * Implementation of connection_t.is_ikev2.
135 static bool is_ikev2 (private_connection_t
*this)
141 * Implementation of connection_t.get_certreq_policy.
143 static cert_policy_t
get_certreq_policy (private_connection_t
*this)
145 return this->certreq_policy
;
149 * Implementation of connection_t.get_cert_policy.
151 static cert_policy_t
get_cert_policy (private_connection_t
*this)
153 return this->cert_policy
;
157 * Implementation of connection_t.get_my_host.
159 static host_t
*get_my_host (private_connection_t
*this)
161 return this->my_host
;
165 * Implementation of connection_t.get_other_host.
167 static host_t
*get_other_host (private_connection_t
*this)
169 return this->other_host
;
173 * Implementation of connection_t.get_proposals.
175 static linked_list_t
* get_proposals(private_connection_t
*this)
177 iterator_t
*iterator
;
179 linked_list_t
*proposals
= linked_list_create();
181 iterator
= this->proposals
->create_iterator(this->proposals
, TRUE
);
182 while (iterator
->iterate(iterator
, (void**)¤t
))
184 current
= current
->clone(current
);
185 proposals
->insert_last(proposals
, (void*)current
);
187 iterator
->destroy(iterator
);
193 * Implementation of connection_t.select_proposal.
195 static proposal_t
*select_proposal(private_connection_t
*this, linked_list_t
*proposals
)
197 iterator_t
*stored_iter
, *supplied_iter
;
198 proposal_t
*stored
, *supplied
, *selected
;
200 stored_iter
= this->proposals
->create_iterator(this->proposals
, TRUE
);
201 supplied_iter
= proposals
->create_iterator(proposals
, TRUE
);
203 /* compare all stored proposals with all supplied. Stored ones are preferred. */
204 while (stored_iter
->iterate(stored_iter
, (void**)&stored
))
206 supplied_iter
->reset(supplied_iter
);
208 while (supplied_iter
->iterate(supplied_iter
, (void**)&supplied
))
210 selected
= stored
->select(stored
, supplied
);
213 /* they match, return */
214 stored_iter
->destroy(stored_iter
);
215 supplied_iter
->destroy(supplied_iter
);
220 /* no proposal match :-(, will result in a NO_PROPOSAL_CHOSEN... */
221 stored_iter
->destroy(stored_iter
);
222 supplied_iter
->destroy(supplied_iter
);
228 * Implementation of connection_t.add_proposal.
230 static void add_proposal(private_connection_t
*this, proposal_t
*proposal
)
232 this->proposals
->insert_last(this->proposals
, proposal
);
236 * Implementation of connection_t.get_dpd_delay.
238 static u_int32_t
get_dpd_delay(private_connection_t
*this)
240 return this->dpd_delay
;
244 * Implementation of connection_t.get_keyingtries.
246 static u_int32_t
get_keyingtries(private_connection_t
*this)
248 return this->keyingtries
;
252 * Implementation of connection_t.get_dh_group.
254 static diffie_hellman_group_t
get_dh_group(private_connection_t
*this)
256 iterator_t
*iterator
;
257 proposal_t
*proposal
;
259 diffie_hellman_group_t dh_group
= MODP_NONE
;
261 iterator
= this->proposals
->create_iterator(this->proposals
, TRUE
);
262 while (iterator
->iterate(iterator
, (void**)&proposal
))
264 if (proposal
->get_algorithm(proposal
, DIFFIE_HELLMAN_GROUP
, &algo
))
266 dh_group
= algo
->algorithm
;
270 iterator
->destroy(iterator
);
275 * Implementation of connection_t.check_dh_group.
277 static bool check_dh_group(private_connection_t
*this, diffie_hellman_group_t dh_group
)
279 iterator_t
*prop_iter
, *alg_iter
;
280 proposal_t
*proposal
;
283 prop_iter
= this->proposals
->create_iterator(this->proposals
, TRUE
);
284 while (prop_iter
->iterate(prop_iter
, (void**)&proposal
))
286 alg_iter
= proposal
->create_algorithm_iterator(proposal
, DIFFIE_HELLMAN_GROUP
);
287 while (alg_iter
->iterate(alg_iter
, (void**)&algo
))
289 if (algo
->algorithm
== dh_group
)
291 prop_iter
->destroy(prop_iter
);
292 alg_iter
->destroy(alg_iter
);
296 alg_iter
->destroy(alg_iter
);
298 prop_iter
->destroy(prop_iter
);
302 * Implementation of connection_t.get_soft_lifetime
304 static u_int32_t
get_soft_lifetime(private_connection_t
*this)
306 if (this->jitter
== 0)
308 return this->soft_lifetime
;
310 return this->soft_lifetime
- (random() % this->jitter
);
314 * Implementation of connection_t.get_hard_lifetime.
316 static u_int32_t
get_hard_lifetime(private_connection_t
*this)
318 return this->hard_lifetime
;
322 * Implementation of connection_t.get_reauth.
324 static bool get_reauth(private_connection_t
*this)
330 * Implementation of connection_t.get_ref.
332 static void get_ref(private_connection_t
*this)
334 ref_get(&this->refcount
);
338 * Implementation of connection_t.destroy.
340 static void destroy(private_connection_t
*this)
342 if (ref_put(&this->refcount
))
344 this->proposals
->destroy_offset(this->proposals
, offsetof(proposal_t
, destroy
));
345 this->my_host
->destroy(this->my_host
);
346 this->other_host
->destroy(this->other_host
);
353 * Described in header.
355 connection_t
* connection_create(char *name
, bool ikev2
,
356 cert_policy_t cert_policy
,
357 cert_policy_t certreq_policy
,
358 host_t
*my_host
, host_t
*other_host
,
359 u_int32_t dpd_delay
, bool reauth
,
360 u_int32_t keyingtries
,
361 u_int32_t hard_lifetime
,
362 u_int32_t soft_lifetime
, u_int32_t jitter
)
364 private_connection_t
*this = malloc_thing(private_connection_t
);
366 /* public functions */
367 this->public.get_name
= (char*(*)(connection_t
*))get_name
;
368 this->public.is_ikev2
= (bool(*)(connection_t
*))is_ikev2
;
369 this->public.get_cert_policy
= (cert_policy_t(*)(connection_t
*))get_cert_policy
;
370 this->public.get_certreq_policy
= (cert_policy_t(*)(connection_t
*))get_certreq_policy
;
371 this->public.get_my_host
= (host_t
*(*)(connection_t
*))get_my_host
;
372 this->public.get_other_host
= (host_t
*(*)(connection_t
*))get_other_host
;
373 this->public.get_proposals
= (linked_list_t
*(*)(connection_t
*))get_proposals
;
374 this->public.select_proposal
= (proposal_t
*(*)(connection_t
*,linked_list_t
*))select_proposal
;
375 this->public.add_proposal
= (void(*)(connection_t
*, proposal_t
*)) add_proposal
;
376 this->public.get_dpd_delay
= (u_int32_t(*)(connection_t
*)) get_dpd_delay
;
377 this->public.get_reauth
= (bool(*)(connection_t
*)) get_reauth
;
378 this->public.get_keyingtries
= (u_int32_t(*)(connection_t
*)) get_keyingtries
;
379 this->public.get_dh_group
= (diffie_hellman_group_t(*)(connection_t
*)) get_dh_group
;
380 this->public.check_dh_group
= (bool(*)(connection_t
*,diffie_hellman_group_t
)) check_dh_group
;
381 this->public.get_soft_lifetime
= (u_int32_t (*) (connection_t
*))get_soft_lifetime
;
382 this->public.get_hard_lifetime
= (u_int32_t (*) (connection_t
*))get_hard_lifetime
;
383 this->public.get_ref
= (void(*)(connection_t
*))get_ref
;
384 this->public.destroy
= (void(*)(connection_t
*))destroy
;
386 /* private variables */
388 this->name
= strdup(name
);
390 this->cert_policy
= cert_policy
;
391 this->certreq_policy
= certreq_policy
;
392 this->my_host
= my_host
;
393 this->other_host
= other_host
;
394 this->dpd_delay
= dpd_delay
;
395 this->reauth
= reauth
;
396 this->keyingtries
= keyingtries
;
397 this->hard_lifetime
= hard_lifetime
;
398 this->soft_lifetime
= soft_lifetime
;
399 this->jitter
= jitter
;
401 this->proposals
= linked_list_create();
403 return &this->public;