]> git.ipfire.org Git - thirdparty/strongswan.git/blob - src/libcharon/plugins/tnc_imc/tnc_imc_manager.c
Use thread save settings alloc_str function where appropriate
[thirdparty/strongswan.git] / src / libcharon / plugins / tnc_imc / tnc_imc_manager.c
1 /*
2 * Copyright (C) 2006 Mike McCauley
3 * Copyright (C) 2010 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "tnc_imc_manager.h"
17
18 #include <tnc/imc/imc_manager.h>
19 #include <tnc/tncifimc.h>
20
21 #include <debug.h>
22 #include <library.h>
23 #include <utils/linked_list.h>
24
25 typedef struct private_tnc_imc_manager_t private_tnc_imc_manager_t;
26
27 /**
28 * Private data of an imc_manager_t object.
29 */
30 struct private_tnc_imc_manager_t {
31
32 /**
33 * Public members of imc_manager_t.
34 */
35 imc_manager_t public;
36
37 /**
38 * Linked list of IMCs
39 */
40 linked_list_t *imcs;
41
42 /**
43 * Next IMC ID to be assigned
44 */
45 TNC_IMCID next_imc_id;
46
47 /**
48 * Preferred language
49 */
50 char *preferred_language;
51 };
52
53 METHOD(imc_manager_t, add, bool,
54 private_tnc_imc_manager_t *this, imc_t *imc)
55 {
56 TNC_Version version;
57
58 /* Initialize the module */
59 imc->set_id(imc, this->next_imc_id);
60 if (imc->initialize(imc->get_id(imc), TNC_IFIMC_VERSION_1,
61 TNC_IFIMC_VERSION_1, &version) != TNC_RESULT_SUCCESS)
62 {
63 DBG1(DBG_TNC, "IMC \"%s\" failed to initialize", imc->get_name(imc));
64 return FALSE;
65 }
66 this->imcs->insert_last(this->imcs, imc);
67 this->next_imc_id++;
68
69 if (imc->provide_bind_function(imc->get_id(imc), TNC_TNCC_BindFunction)
70 != TNC_RESULT_SUCCESS)
71 {
72 DBG1(DBG_TNC, "IMC \"%s\" failed to obtain bind function",
73 imc->get_name(imc));
74 this->imcs->remove_last(this->imcs, (void**)&imc);
75 return FALSE;
76 }
77
78 return TRUE;
79 }
80
81 METHOD(imc_manager_t, remove_, imc_t*,
82 private_tnc_imc_manager_t *this, TNC_IMCID id)
83 {
84 enumerator_t *enumerator;
85 imc_t *imc;
86
87 enumerator = this->imcs->create_enumerator(this->imcs);
88 while (enumerator->enumerate(enumerator, &imc))
89 {
90 if (id == imc->get_id(imc))
91 {
92 this->imcs->remove_at(this->imcs, enumerator);
93 return imc;
94 }
95 }
96 enumerator->destroy(enumerator);
97 return NULL;
98 }
99
100 METHOD(imc_manager_t, get_preferred_language, char*,
101 private_tnc_imc_manager_t *this)
102 {
103 return this->preferred_language;
104 }
105
106 METHOD(imc_manager_t, notify_connection_change, void,
107 private_tnc_imc_manager_t *this, TNC_ConnectionID id,
108 TNC_ConnectionState state)
109 {
110 enumerator_t *enumerator;
111 imc_t *imc;
112
113 enumerator = this->imcs->create_enumerator(this->imcs);
114 while (enumerator->enumerate(enumerator, &imc))
115 {
116 if (imc->notify_connection_change)
117 {
118 imc->notify_connection_change(imc->get_id(imc), id, state);
119 }
120 }
121 enumerator->destroy(enumerator);
122 }
123
124 METHOD(imc_manager_t, begin_handshake, void,
125 private_tnc_imc_manager_t *this, TNC_ConnectionID id)
126 {
127 enumerator_t *enumerator;
128 imc_t *imc;
129
130 enumerator = this->imcs->create_enumerator(this->imcs);
131 while (enumerator->enumerate(enumerator, &imc))
132 {
133 imc->begin_handshake(imc->get_id(imc), id);
134 }
135 enumerator->destroy(enumerator);
136 }
137
138 METHOD(imc_manager_t, set_message_types, TNC_Result,
139 private_tnc_imc_manager_t *this, TNC_IMCID id,
140 TNC_MessageTypeList supported_types,
141 TNC_UInt32 type_count)
142 {
143 enumerator_t *enumerator;
144 imc_t *imc;
145 TNC_Result result = TNC_RESULT_FATAL;
146
147 enumerator = this->imcs->create_enumerator(this->imcs);
148 while (enumerator->enumerate(enumerator, &imc))
149 {
150 if (id == imc->get_id(imc))
151 {
152 imc->set_message_types(imc, supported_types, type_count);
153 result = TNC_RESULT_SUCCESS;
154 break;
155 }
156 }
157 enumerator->destroy(enumerator);
158 return result;
159 }
160
161 METHOD(imc_manager_t, receive_message, void,
162 private_tnc_imc_manager_t *this, TNC_ConnectionID connection_id,
163 TNC_BufferReference message,
164 TNC_UInt32 message_len,
165 TNC_MessageType message_type)
166 {
167 enumerator_t *enumerator;
168 imc_t *imc;
169
170 enumerator = this->imcs->create_enumerator(this->imcs);
171 while (enumerator->enumerate(enumerator, &imc))
172 {
173 if (imc->receive_message && imc->type_supported(imc, message_type))
174 {
175 imc->receive_message(imc->get_id(imc), connection_id,
176 message, message_len, message_type);
177 }
178 }
179 enumerator->destroy(enumerator);
180 }
181
182 METHOD(imc_manager_t, batch_ending, void,
183 private_tnc_imc_manager_t *this, TNC_ConnectionID id)
184 {
185 enumerator_t *enumerator;
186 imc_t *imc;
187
188 enumerator = this->imcs->create_enumerator(this->imcs);
189 while (enumerator->enumerate(enumerator, &imc))
190 {
191 if (imc->batch_ending)
192 {
193 imc->batch_ending(imc->get_id(imc), id);
194 }
195 }
196 enumerator->destroy(enumerator);
197 }
198
199 METHOD(imc_manager_t, destroy, void,
200 private_tnc_imc_manager_t *this)
201 {
202 imc_t *imc;
203
204 while (this->imcs->remove_last(this->imcs, (void**)&imc) == SUCCESS)
205 {
206 if (imc->terminate &&
207 imc->terminate(imc->get_id(imc)) != TNC_RESULT_SUCCESS)
208 {
209 DBG1(DBG_TNC, "IMC \"%s\" not terminated successfully",
210 imc->get_name(imc));
211 }
212 imc->destroy(imc);
213 }
214 this->imcs->destroy(this->imcs);
215 free(this->preferred_language);
216 free(this);
217 }
218
219 /**
220 * Described in header.
221 */
222 imc_manager_t* tnc_imc_manager_create(void)
223 {
224 private_tnc_imc_manager_t *this;
225
226 INIT(this,
227 .public = {
228 .add = _add,
229 .remove = _remove_, /* avoid name conflict with stdio.h */
230 .get_preferred_language = _get_preferred_language,
231 .notify_connection_change = _notify_connection_change,
232 .begin_handshake = _begin_handshake,
233 .set_message_types = _set_message_types,
234 .receive_message = _receive_message,
235 .batch_ending = _batch_ending,
236 .destroy = _destroy,
237 },
238 .imcs = linked_list_create(),
239 .next_imc_id = 1,
240 .preferred_language = lib->settings->alloc_str(lib->settings,
241 "charon.plugins.tnc-imc.preferred_language", "en");
242 );
243
244 return &this->public;
245 }