(no commit message)
[strongswan.git] / src / charon / config / connections / local_connection_store.c
1 /**
2 * @file local_connection_store.c
3 *
4 * @brief Implementation of local_connection_store_t.
5 *
6 */
7
8 /*
9 * Copyright (C) 2006 Martin Willi
10 * Hochschule fuer Technik Rapperswil
11 *
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>.
16 *
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
20 * for more details.
21 */
22
23 #include <string.h>
24
25 #include "local_connection_store.h"
26
27 #include <utils/linked_list.h>
28 #include <utils/logger_manager.h>
29
30
31 typedef struct private_local_connection_store_t private_local_connection_store_t;
32
33 /**
34 * Private data of an local_connection_store_t object
35 */
36 struct private_local_connection_store_t {
37
38 /**
39 * Public part
40 */
41 local_connection_store_t public;
42
43 /**
44 * stored connection
45 */
46 linked_list_t *connections;
47
48 /**
49 * Assigned logger
50 */
51 logger_t *logger;
52 };
53
54
55 /**
56 * Implementation of connection_store_t.get_connection_by_hosts.
57 */
58 static connection_t *get_connection_by_hosts(private_local_connection_store_t *this, host_t *my_host, host_t *other_host)
59 {
60 iterator_t *iterator;
61 connection_t *current, *found = NULL;
62
63 this->logger->log(this->logger, CONTROL|LEVEL1, "getting config for hosts %s - %s",
64 my_host->get_address(my_host), other_host->get_address(other_host));
65
66 iterator = this->connections->create_iterator(this->connections, TRUE);
67 while (iterator->has_next(iterator))
68 {
69 host_t *config_my_host, *config_other_host;
70
71 iterator->current(iterator, (void**)&current);
72
73 config_my_host = current->get_my_host(current);
74 config_other_host = current->get_other_host(current);
75
76 /* first check if ip is equal */
77 if(config_other_host->ip_equals(config_other_host, other_host))
78 {
79 this->logger->log(this->logger, CONTROL|LEVEL2, "config entry with remote host %s",
80 config_other_host->get_address(config_other_host));
81 /* could be right one, check my_host for default route*/
82 if (config_my_host->is_default_route(config_my_host))
83 {
84 found = current->clone(current);
85 break;
86 }
87 /* check now if host informations are the same */
88 else if (config_my_host->ip_equals(config_my_host,my_host))
89 {
90 found = current->clone(current);
91 break;
92 }
93
94 }
95 /* Then check for wildcard hosts!
96 * TODO
97 * actually its only checked if other host with default route can be found! */
98 else if (config_other_host->is_default_route(config_other_host))
99 {
100 /* could be right one, check my_host for default route*/
101 if (config_my_host->is_default_route(config_my_host))
102 {
103 found = current->clone(current);
104 break;
105 }
106 /* check now if host informations are the same */
107 else if (config_my_host->ip_equals(config_my_host,my_host))
108 {
109 found = current->clone(current);
110 break;
111 }
112 }
113 }
114 iterator->destroy(iterator);
115
116 /* apply hosts as they are supplied since my_host may be %defaultroute, and other_host may be %any. */
117 if (found)
118 {
119 found->update_my_host(found, my_host->clone(my_host));
120 found->update_other_host(found, other_host->clone(other_host));
121 }
122
123 return found;
124 }
125
126 /**
127 * Implementation of connection_store_t.get_connection_by_ids.
128 */
129 static connection_t *get_connection_by_ids(private_local_connection_store_t *this, identification_t *my_id, identification_t *other_id)
130 {
131 iterator_t *iterator;
132 connection_t *current, *found = NULL;
133
134 this->logger->log(this->logger, CONTROL|LEVEL1, "getting config for ids %s - %s",
135 my_id->get_string(my_id), other_id->get_string(other_id));
136
137 iterator = this->connections->create_iterator(this->connections, TRUE);
138 while (iterator->has_next(iterator))
139 {
140 identification_t *config_my_id, *config_other_id;
141
142 iterator->current(iterator, (void**)&current);
143
144 config_my_id = current->get_my_id(current);
145 config_other_id = current->get_other_id(current);
146
147 /* first check if ids are equal
148 * TODO: Add wildcard checks */
149 if (config_other_id->equals(config_other_id, other_id) &&
150 config_my_id->equals(config_my_id, my_id))
151 {
152 this->logger->log(this->logger, CONTROL|LEVEL2, "config entry with remote id %s",
153 config_other_id->get_string(config_other_id));
154 found = current->clone(current);
155 break;
156 }
157 }
158 iterator->destroy(iterator);
159
160 return found;
161 }
162
163 /**
164 * Implementation of connection_store_t.get_connection_by_name.
165 */
166 static connection_t *get_connection_by_name(private_local_connection_store_t *this, char *name)
167 {
168 iterator_t *iterator;
169 connection_t *current, *found = NULL;
170
171 iterator = this->connections->create_iterator(this->connections, TRUE);
172 while (iterator->has_next(iterator))
173 {
174 iterator->current(iterator, (void**)&current);
175 if (strcmp(name, current->get_name(current)) == 0)
176 {
177 found = current->clone(current);
178 break;
179 }
180 }
181 iterator->destroy(iterator);
182
183 return found;
184 }
185
186 /**
187 * Implementation of connection_store_t.add_connection.
188 */
189 static status_t add_connection(private_local_connection_store_t *this, connection_t *connection)
190 {
191 this->connections->insert_last(this->connections, connection);
192 return SUCCESS;
193 }
194
195 /**
196 * Implementation of connection_store_t.destroy.
197 */
198 static void destroy (private_local_connection_store_t *this)
199 {
200 connection_t *connection;
201
202 while (this->connections->remove_last(this->connections, (void**)&connection) == SUCCESS)
203 {
204 connection->destroy(connection);
205 }
206 this->connections->destroy(this->connections);
207 free(this);
208 }
209
210 /**
211 * Described in header.
212 */
213 local_connection_store_t * local_connection_store_create(void)
214 {
215 private_local_connection_store_t *this = malloc_thing(private_local_connection_store_t);
216
217 this->public.connection_store.get_connection_by_hosts = (connection_t*(*)(connection_store_t*,host_t*,host_t*))get_connection_by_hosts;
218 this->public.connection_store.get_connection_by_ids = (connection_t*(*)(connection_store_t*,identification_t*,identification_t*))get_connection_by_ids;
219 this->public.connection_store.get_connection_by_name = (connection_t*(*)(connection_store_t*,char*))get_connection_by_name;
220 this->public.connection_store.add_connection = (status_t(*)(connection_store_t*,connection_t*))add_connection;
221 this->public.connection_store.destroy = (void(*)(connection_store_t*))destroy;
222
223 /* private variables */
224 this->connections = linked_list_create();
225 this->logger = logger_manager->get_logger(logger_manager, CONFIG);
226
227 return (&this->public);
228 }