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
;
56 * Implementation of connection_store_t.get_connection_by_hosts.
58 static connection_t
*get_connection_by_hosts(private_local_connection_store_t
*this, host_t
*my_host
, host_t
*other_host
)
66 prio_t best_prio
= PRIO_UNDEFINED
;
69 connection_t
*candidate
;
70 connection_t
*found
= NULL
;
72 this->logger
->log(this->logger
, CONTROL
|LEVEL1
, "searching connection for host pair %s...%s",
73 my_host
->get_address(my_host
), other_host
->get_address(other_host
));
75 iterator
= this->connections
->create_iterator(this->connections
, TRUE
);
77 /* determine closest matching connection */
78 while (iterator
->has_next(iterator
))
80 host_t
*candidate_my_host
;
81 host_t
*candidate_other_host
;
83 iterator
->current(iterator
, (void**)&candidate
);
85 candidate_my_host
= candidate
->get_my_host(candidate
);
86 candidate_other_host
= candidate
->get_other_host(candidate
);
88 /* my_host addresses must match*/
89 if (my_host
->ip_equals(my_host
, candidate_my_host
))
91 prio_t prio
= PRIO_UNDEFINED
;
93 /* exact match of peer host address or wildcard address? */
94 if (other_host
->ip_equals(other_host
, candidate_other_host
))
96 prio
|= PRIO_ADDR_MATCH
;
98 else if (candidate_other_host
->is_anyaddr(candidate_other_host
))
100 prio
|= PRIO_ADDR_ANY
;
103 this->logger
->log(this->logger
, CONTROL
|LEVEL2
,
104 "candidate connection \"%s\": %s...%s (prio=%d)",
105 candidate
->get_name(candidate
),
106 candidate_my_host
->get_address(candidate_my_host
),
107 candidate_other_host
->get_address(candidate_other_host
),
110 if (prio
> best_prio
)
117 iterator
->destroy(iterator
);
121 host_t
*found_my_host
= found
->get_my_host(found
);
122 host_t
*found_other_host
= found
->get_other_host(found
);
124 this->logger
->log(this->logger
, CONTROL
|LEVEL1
,
125 "found matching connection \"%s\": %s...%s (prio=%d)",
126 found
->get_name(found
),
127 found_my_host
->get_address(found_my_host
),
128 found_other_host
->get_address(found_other_host
),
131 found
= found
->clone(found
);
132 if (best_prio
& PRIO_ADDR_ANY
)
134 /* replace %any by the peer's address */
135 found
->update_other_host(found
, other_host
->clone(other_host
));
142 * Implementation of connection_store_t.get_connection_by_ids.
144 static connection_t
*get_connection_by_ids(private_local_connection_store_t
*this, identification_t
*my_id
, identification_t
*other_id
)
146 iterator_t
*iterator
;
147 connection_t
*current
, *found
= NULL
;
149 this->logger
->log(this->logger
, CONTROL
|LEVEL1
, "getting config for ids %s - %s",
150 my_id
->get_string(my_id
), other_id
->get_string(other_id
));
152 iterator
= this->connections
->create_iterator(this->connections
, TRUE
);
153 while (iterator
->has_next(iterator
))
155 identification_t
*config_my_id
, *config_other_id
;
157 iterator
->current(iterator
, (void**)¤t
);
159 config_my_id
= current
->get_my_id(current
);
160 config_other_id
= current
->get_other_id(current
);
162 /* first check if ids are equal
163 * TODO: Add wildcard checks */
164 if (config_other_id
->equals(config_other_id
, other_id
) &&
165 config_my_id
->equals(config_my_id
, my_id
))
167 this->logger
->log(this->logger
, CONTROL
|LEVEL2
, "config entry with remote id %s",
168 config_other_id
->get_string(config_other_id
));
169 found
= current
->clone(current
);
173 iterator
->destroy(iterator
);
179 * Implementation of connection_store_t.get_connection_by_name.
181 static connection_t
*get_connection_by_name(private_local_connection_store_t
*this, char *name
)
183 iterator_t
*iterator
;
184 connection_t
*current
, *found
= NULL
;
186 iterator
= this->connections
->create_iterator(this->connections
, TRUE
);
187 while (iterator
->has_next(iterator
))
189 iterator
->current(iterator
, (void**)¤t
);
190 if (strcmp(name
, current
->get_name(current
)) == 0)
192 found
= current
->clone(current
);
196 iterator
->destroy(iterator
);
202 * Implementation of connection_store_t.add_connection.
204 static status_t
add_connection(private_local_connection_store_t
*this, connection_t
*connection
)
206 this->connections
->insert_last(this->connections
, connection
);
211 * Implementation of connection_store_t.log_connections.
213 void log_connections(private_local_connection_store_t
*this, logger_t
*logger
, char *name
)
215 iterator_t
*iterator
;
216 connection_t
*current
, *found
= NULL
;
220 logger
= this->logger
;
223 logger
->log(logger
, CONTROL
, "templates:");
225 iterator
= this->connections
->create_iterator(this->connections
, TRUE
);
226 while (iterator
->has_next(iterator
))
228 iterator
->current(iterator
, (void**)¤t
);
229 if (!name
|| strcmp(name
, current
->get_name(current
)) == 0)
231 identification_t
*my_id
, *other_id
;
232 host_t
*my_host
, *other_host
;
233 my_id
= current
->get_my_id(current
);
234 other_id
= current
->get_other_id(current
);
235 my_host
= current
->get_my_host(current
);
236 other_host
= current
->get_other_host(current
);
237 logger
->log(logger
, CONTROL
, " \"%s\": %s[%s]...%s[%s]",
238 current
->get_name(current
),
239 my_host
->get_address(my_host
), my_id
->get_string(my_id
),
240 other_host
->get_address(other_host
), other_id
->get_string(other_id
));
243 iterator
->destroy(iterator
);
247 * Implementation of connection_store_t.destroy.
249 static void destroy (private_local_connection_store_t
*this)
251 connection_t
*connection
;
253 while (this->connections
->remove_last(this->connections
, (void**)&connection
) == SUCCESS
)
255 connection
->destroy(connection
);
257 this->connections
->destroy(this->connections
);
262 * Described in header.
264 local_connection_store_t
* local_connection_store_create(void)
266 private_local_connection_store_t
*this = malloc_thing(private_local_connection_store_t
);
268 this->public.connection_store
.get_connection_by_hosts
= (connection_t
*(*)(connection_store_t
*,host_t
*,host_t
*))get_connection_by_hosts
;
269 this->public.connection_store
.get_connection_by_ids
= (connection_t
*(*)(connection_store_t
*,identification_t
*,identification_t
*))get_connection_by_ids
;
270 this->public.connection_store
.get_connection_by_name
= (connection_t
*(*)(connection_store_t
*,char*))get_connection_by_name
;
271 this->public.connection_store
.add_connection
= (status_t(*)(connection_store_t
*,connection_t
*))add_connection
;
272 this->public.connection_store
.log_connections
= (void(*)(connection_store_t
*,logger_t
*,char*))log_connections
;
273 this->public.connection_store
.destroy
= (void(*)(connection_store_t
*))destroy
;
275 /* private variables */
276 this->connections
= linked_list_create();
277 this->logger
= logger_manager
->get_logger(logger_manager
, CONFIG
);
279 return (&this->public);