2 * @file local_connection_store.c
4 * @brief Implementation of local_connection_store_t.
9 * Copyright (C) 2006 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 "local_connection_store.h"
27 #include <utils/linked_list.h>
28 #include <utils/logger_manager.h>
31 typedef struct private_local_connection_store_t private_local_connection_store_t
;
34 * Private data of an local_connection_store_t object
36 struct private_local_connection_store_t
{
41 local_connection_store_t
public;
46 linked_list_t
*connections
;
49 * Mutex to exclusivly access connection list
51 pthread_mutex_t mutex
;
61 * Implementation of connection_store_t.get_connection_by_hosts.
63 static connection_t
*get_connection_by_hosts(private_local_connection_store_t
*this, host_t
*my_host
, host_t
*other_host
)
71 prio_t best_prio
= PRIO_UNDEFINED
;
74 connection_t
*candidate
;
75 connection_t
*found
= NULL
;
77 this->logger
->log(this->logger
, CONTROL
|LEVEL1
, "looking for connection for host pair %s...%s",
78 my_host
->get_string(my_host
), other_host
->get_string(other_host
));
80 pthread_mutex_lock(&(this->mutex
));
81 iterator
= this->connections
->create_iterator(this->connections
, TRUE
);
82 /* determine closest matching connection */
83 while (iterator
->has_next(iterator
))
85 host_t
*candidate_my_host
;
86 host_t
*candidate_other_host
;
88 iterator
->current(iterator
, (void**)&candidate
);
90 candidate_my_host
= candidate
->get_my_host(candidate
);
91 candidate_other_host
= candidate
->get_other_host(candidate
);
93 /* my_host addresses must match*/
94 if (my_host
->ip_equals(my_host
, candidate_my_host
))
96 prio_t prio
= PRIO_UNDEFINED
;
98 /* exact match of peer host address or wildcard address? */
99 if (other_host
->ip_equals(other_host
, candidate_other_host
))
101 prio
|= PRIO_ADDR_MATCH
;
103 else if (candidate_other_host
->is_anyaddr(candidate_other_host
))
105 prio
|= PRIO_ADDR_ANY
;
108 this->logger
->log(this->logger
, CONTROL
|LEVEL2
,
109 "candidate connection \"%s\": %s...%s (prio=%d)",
110 candidate
->get_name(candidate
),
111 candidate_my_host
->get_string(candidate_my_host
),
112 candidate_other_host
->get_string(candidate_other_host
),
115 if (prio
> best_prio
)
122 iterator
->destroy(iterator
);
126 host_t
*found_my_host
= found
->get_my_host(found
);
127 host_t
*found_other_host
= found
->get_other_host(found
);
129 this->logger
->log(this->logger
, CONTROL
,
130 "found matching connection \"%s\": %s...%s (prio=%d)",
131 found
->get_name(found
),
132 found_my_host
->get_string(found_my_host
),
133 found_other_host
->get_string(found_other_host
),
136 /* give out a new reference to it */
137 found
->get_ref(found
);
139 pthread_mutex_unlock(&(this->mutex
));
144 * Implementation of connection_store_t.get_connection_by_name.
146 static connection_t
*get_connection_by_name(private_local_connection_store_t
*this, char *name
)
148 iterator_t
*iterator
;
149 connection_t
*current
, *found
= NULL
;
151 pthread_mutex_lock(&(this->mutex
));
152 iterator
= this->connections
->create_iterator(this->connections
, TRUE
);
153 while (iterator
->has_next(iterator
))
155 iterator
->current(iterator
, (void**)¤t
);
156 if (strcmp(name
, current
->get_name(current
)) == 0)
162 iterator
->destroy(iterator
);
163 pthread_mutex_unlock(&(this->mutex
));
167 /* get a new reference for it */
168 found
->get_ref(found
);
174 * Implementation of connection_store_t.delete_connection.
176 static status_t
delete_connection(private_local_connection_store_t
*this, char *name
)
178 iterator_t
*iterator
;
179 connection_t
*current
;
182 pthread_mutex_lock(&(this->mutex
));
183 iterator
= this->connections
->create_iterator(this->connections
, TRUE
);
184 while (iterator
->has_next(iterator
))
186 iterator
->current(iterator
, (void **)¤t
);
187 if (strcmp(current
->get_name(current
), name
) == 0)
189 /* remove connection from list, and destroy it */
190 iterator
->remove(iterator
);
191 current
->destroy(current
);
196 iterator
->destroy(iterator
);
197 pthread_mutex_unlock(&(this->mutex
));
206 * Implementation of connection_store_t.add_connection.
208 static status_t
add_connection(private_local_connection_store_t
*this, connection_t
*connection
)
210 pthread_mutex_lock(&(this->mutex
));
211 this->connections
->insert_last(this->connections
, connection
);
212 pthread_mutex_unlock(&(this->mutex
));
217 * Implementation of connection_store_t.log_connections.
219 void log_connections(private_local_connection_store_t
*this, logger_t
*logger
, char *name
)
221 iterator_t
*iterator
;
222 connection_t
*current
;
226 logger
= this->logger
;
229 pthread_mutex_lock(&(this->mutex
));
231 iterator
= this->connections
->create_iterator(this->connections
, TRUE
);
233 if (iterator
->get_count(iterator
))
235 logger
->log(logger
, CONTROL
, "Templates:");
237 while (iterator
->has_next(iterator
))
239 iterator
->current(iterator
, (void**)¤t
);
240 if (current
->is_ikev2(current
) && ( name
== NULL
|| streq(name
, current
->get_name(current
))))
242 host_t
*my_host
= current
->get_my_host(current
);
243 host_t
*other_host
= current
->get_other_host(current
);
245 logger
->log(logger
, CONTROL
, " \"%s\": %s...%s",
246 current
->get_name(current
),
247 my_host
->get_string(my_host
),
248 other_host
->get_string(other_host
));
251 iterator
->destroy(iterator
);
252 pthread_mutex_unlock(&(this->mutex
));
256 * Implementation of connection_store_t.destroy.
258 static void destroy (private_local_connection_store_t
*this)
260 connection_t
*connection
;
262 pthread_mutex_lock(&(this->mutex
));
263 while (this->connections
->remove_last(this->connections
, (void**)&connection
) == SUCCESS
)
265 connection
->destroy(connection
);
267 this->connections
->destroy(this->connections
);
268 pthread_mutex_unlock(&(this->mutex
));
273 * Described in header.
275 local_connection_store_t
* local_connection_store_create(void)
277 private_local_connection_store_t
*this = malloc_thing(private_local_connection_store_t
);
279 this->public.connection_store
.get_connection_by_hosts
= (connection_t
*(*)(connection_store_t
*,host_t
*,host_t
*))get_connection_by_hosts
;
280 this->public.connection_store
.get_connection_by_name
= (connection_t
*(*)(connection_store_t
*,char*))get_connection_by_name
;
281 this->public.connection_store
.delete_connection
= (status_t(*)(connection_store_t
*,char*))delete_connection
;
282 this->public.connection_store
.add_connection
= (status_t(*)(connection_store_t
*,connection_t
*))add_connection
;
283 this->public.connection_store
.log_connections
= (void(*)(connection_store_t
*,logger_t
*,char*))log_connections
;
284 this->public.connection_store
.destroy
= (void(*)(connection_store_t
*))destroy
;
286 /* private variables */
287 this->connections
= linked_list_create();
288 this->logger
= logger_manager
->get_logger(logger_manager
, CONFIG
);
289 pthread_mutex_init(&(this->mutex
), NULL
);
291 return (&this->public);