2 * Copyright (C) 2010 Andreas Steffen
3 * HSR Hochschule fuer Technik Rapperswil
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>.
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
16 #include "tnccs_manager.h"
19 #include <utils/linked_list.h>
20 #include <threading/rwlock.h>
22 typedef struct private_tnccs_manager_t private_tnccs_manager_t
;
23 typedef struct tnccs_entry_t tnccs_entry_t
;
24 typedef struct tnccs_connection_entry_t tnccs_connection_entry_t
;
27 * TNCCS constructor entry
29 struct tnccs_entry_t
{
37 * constructor function to create instance
39 tnccs_constructor_t constructor
;
43 * TNCCS connection entry
45 struct tnccs_connection_entry_t
{
57 /** TNCCS send message function
60 tnccs_send_message_t send_message
;
62 /** TNCS provide recommendation function
65 tnccs_provide_recommendation_t provide_recommendation
;
69 * private data of tnccs_manager
71 struct private_tnccs_manager_t
{
76 tnccs_manager_t
public;
79 * list of TNCCS protocol entries
81 linked_list_t
*protocols
;
84 * rwlock to lock the TNCCS protocol entries
86 rwlock_t
*protocol_lock
;
89 * connection ID counter
91 TNC_ConnectionID connection_id
;
94 * list of TNCCS connection entries
96 linked_list_t
*connections
;
99 * rwlock to lock TNCCS connection entries
101 rwlock_t
*connection_lock
;
105 METHOD(tnccs_manager_t
, add_method
, void,
106 private_tnccs_manager_t
*this, tnccs_type_t type
,
107 tnccs_constructor_t constructor
)
109 tnccs_entry_t
*entry
;
111 entry
= malloc_thing(tnccs_entry_t
);
113 entry
->constructor
= constructor
;
115 this->protocol_lock
->write_lock(this->protocol_lock
);
116 this->protocols
->insert_last(this->protocols
, entry
);
117 this->protocol_lock
->unlock(this->protocol_lock
);
120 METHOD(tnccs_manager_t
, remove_method
, void,
121 private_tnccs_manager_t
*this, tnccs_constructor_t constructor
)
123 enumerator_t
*enumerator
;
124 tnccs_entry_t
*entry
;
126 this->protocol_lock
->write_lock(this->protocol_lock
);
127 enumerator
= this->protocols
->create_enumerator(this->protocols
);
128 while (enumerator
->enumerate(enumerator
, &entry
))
130 if (constructor
== entry
->constructor
)
132 this->protocols
->remove_at(this->protocols
, enumerator
);
136 enumerator
->destroy(enumerator
);
137 this->protocol_lock
->unlock(this->protocol_lock
);
140 METHOD(tnccs_manager_t
, create_instance
, tnccs_t
*,
141 private_tnccs_manager_t
*this, tnccs_type_t type
, bool is_server
)
143 enumerator_t
*enumerator
;
144 tnccs_entry_t
*entry
;
145 tnccs_t
*protocol
= NULL
;
147 this->protocol_lock
->read_lock(this->protocol_lock
);
148 enumerator
= this->protocols
->create_enumerator(this->protocols
);
149 while (enumerator
->enumerate(enumerator
, &entry
))
151 if (type
== entry
->type
)
153 protocol
= entry
->constructor(is_server
);
160 enumerator
->destroy(enumerator
);
161 this->protocol_lock
->unlock(this->protocol_lock
);
166 METHOD(tnccs_manager_t
, create_connection
, TNC_ConnectionID
,
167 private_tnccs_manager_t
*this, tnccs_t
*tnccs
,
168 tnccs_send_message_t send_message
,
169 tnccs_provide_recommendation_t provide_recommendation
)
171 tnccs_connection_entry_t
*entry
;
173 entry
= malloc_thing(tnccs_connection_entry_t
);
174 entry
->tnccs
= tnccs
;
175 entry
->send_message
= send_message
;
176 entry
->provide_recommendation
= provide_recommendation
;
178 this->connection_lock
->write_lock(this->connection_lock
);
179 entry
->id
= ++this->connection_id
;
180 this->connections
->insert_last(this->connections
, entry
);
181 this->connection_lock
->unlock(this->connection_lock
);
183 DBG1(DBG_TNC
, "assigned TNCCS Connection ID %u", entry
->id
);
187 METHOD(tnccs_manager_t
, remove_connection
, void,
188 private_tnccs_manager_t
*this, TNC_ConnectionID id
)
190 enumerator_t
*enumerator
;
191 tnccs_connection_entry_t
*entry
;
193 this->connection_lock
->write_lock(this->connection_lock
);
194 enumerator
= this->connections
->create_enumerator(this->connections
);
195 while (enumerator
->enumerate(enumerator
, &entry
))
199 this->connections
->remove_at(this->connections
, enumerator
);
201 DBG1(DBG_TNC
, "removed TNCCS Connection ID %u", id
);
204 enumerator
->destroy(enumerator
);
205 this->connection_lock
->unlock(this->connection_lock
);
208 METHOD(tnccs_manager_t
, send_message
, TNC_Result
,
209 private_tnccs_manager_t
*this, TNC_ConnectionID id
,
210 TNC_BufferReference message
,
211 TNC_UInt32 message_len
,
212 TNC_MessageType message_type
)
214 enumerator_t
*enumerator
;
215 tnccs_connection_entry_t
*entry
;
216 tnccs_send_message_t send_message
= NULL
;
217 tnccs_t
*tnccs
= NULL
;
219 this->connection_lock
->read_lock(this->connection_lock
);
220 enumerator
= this->connections
->create_enumerator(this->connections
);
221 while (enumerator
->enumerate(enumerator
, &entry
))
225 tnccs
= entry
->tnccs
;
226 send_message
= entry
->send_message
;
230 enumerator
->destroy(enumerator
);
231 this->connection_lock
->unlock(this->connection_lock
);
233 if (tnccs
&& send_message
)
235 send_message(tnccs
, message
, message_len
, message_type
);
236 return TNC_RESULT_SUCCESS
;
238 return TNC_RESULT_FATAL
;
241 METHOD(tnccs_manager_t
, provide_recommendation
, TNC_Result
,
242 private_tnccs_manager_t
*this, TNC_IMVID imv_id
,
244 TNC_IMV_Action_Recommendation recommendation
,
245 TNC_IMV_Evaluation_Result evaluation
)
247 enumerator_t
*enumerator
;
248 tnccs_connection_entry_t
*entry
;
249 tnccs_provide_recommendation_t provide_recommendation
= NULL
;
250 tnccs_t
*tnccs
= NULL
;
252 this->connection_lock
->read_lock(this->connection_lock
);
253 enumerator
= this->connections
->create_enumerator(this->connections
);
254 while (enumerator
->enumerate(enumerator
, &entry
))
258 tnccs
= entry
->tnccs
;
259 provide_recommendation
= entry
->provide_recommendation
;
263 enumerator
->destroy(enumerator
);
264 this->connection_lock
->unlock(this->connection_lock
);
266 if (tnccs
&& provide_recommendation
)
268 provide_recommendation(tnccs
, imv_id
, recommendation
, evaluation
);
269 return TNC_RESULT_SUCCESS
;
271 return TNC_RESULT_FATAL
;
274 METHOD(tnccs_manager_t
, destroy
, void,
275 private_tnccs_manager_t
*this)
277 this->protocols
->destroy_function(this->protocols
, free
);
278 this->protocol_lock
->destroy(this->protocol_lock
);
279 this->connections
->destroy_function(this->connections
, free
);
280 this->connection_lock
->destroy(this->connection_lock
);
287 tnccs_manager_t
*tnccs_manager_create()
289 private_tnccs_manager_t
*this;
293 .add_method
= _add_method
,
294 .remove_method
= _remove_method
,
295 .create_instance
= _create_instance
,
296 .create_connection
= _create_connection
,
297 .remove_connection
= _remove_connection
,
298 .send_message
= _send_message
,
299 .provide_recommendation
= _provide_recommendation
,
302 .protocols
= linked_list_create(),
303 .connections
= linked_list_create(),
304 .protocol_lock
= rwlock_create(RWLOCK_TYPE_DEFAULT
),
305 .connection_lock
= rwlock_create(RWLOCK_TYPE_DEFAULT
),
308 return &this->public;