implemented receive_message() function
[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 struct private_tnc_imc_manager_t {
28
29 /**
30 * Public members of imc_manager_t.
31 */
32 imc_manager_t public;
33
34 /**
35 * Linked list of IMCs
36 */
37 linked_list_t *imcs;
38
39 /**
40 * Next IMC ID to be assigned
41 */
42 TNC_IMCID next_imc_id;
43 };
44
45 METHOD(imc_manager_t, add, bool,
46 private_tnc_imc_manager_t *this, imc_t *imc)
47 {
48 TNC_Version version;
49
50 /* Initialize the module */
51 imc->set_id(imc, this->next_imc_id);
52 if (imc->initialize(imc->get_id(imc), TNC_IFIMC_VERSION_1,
53 TNC_IFIMC_VERSION_1, &version) != TNC_RESULT_SUCCESS)
54 {
55 DBG1(DBG_TNC, "could not initialize IMC '%s'",
56 imc->get_name(imc));
57 return FALSE;
58 }
59 if (imc->provide_bind_function(imc->get_id(imc), TNC_TNCC_BindFunction)
60 != TNC_RESULT_SUCCESS)
61 {
62 DBG1(DBG_TNC, "could not provide bind function for IMC '%s'",
63 imc->get_name(imc));
64 return FALSE;
65 }
66 this->imcs->insert_last(this->imcs, imc);
67 this->next_imc_id++;
68
69 return TRUE;
70 }
71
72 METHOD(imc_manager_t, notify_connection_change, void,
73 private_tnc_imc_manager_t *this, TNC_ConnectionID id,
74 TNC_ConnectionState state)
75 {
76 enumerator_t *enumerator;
77 imc_t *imc;
78
79 enumerator = this->imcs->create_enumerator(this->imcs);
80 while (enumerator->enumerate(enumerator, &imc))
81 {
82 if (imc->notify_connection_change)
83 {
84 imc->notify_connection_change(imc->get_id(imc), id, state);
85 }
86 }
87 enumerator->destroy(enumerator);
88 }
89
90 METHOD(imc_manager_t, begin_handshake, void,
91 private_tnc_imc_manager_t *this, TNC_ConnectionID id)
92 {
93 enumerator_t *enumerator;
94 imc_t *imc;
95
96 enumerator = this->imcs->create_enumerator(this->imcs);
97 while (enumerator->enumerate(enumerator, &imc))
98 {
99 imc->begin_handshake(imc->get_id(imc), id);
100 }
101 enumerator->destroy(enumerator);
102 }
103
104 METHOD(imc_manager_t, set_message_types, TNC_Result,
105 private_tnc_imc_manager_t *this, TNC_IMCID id,
106 TNC_MessageTypeList supported_types,
107 TNC_UInt32 type_count)
108 {
109 enumerator_t *enumerator;
110 imc_t *imc;
111 TNC_Result result = TNC_RESULT_FATAL;
112
113 enumerator = this->imcs->create_enumerator(this->imcs);
114 while (enumerator->enumerate(enumerator, &imc))
115 {
116 if (id == imc->get_id(imc))
117 {
118 imc->set_message_types(imc, supported_types, type_count);
119 result = TNC_RESULT_SUCCESS;
120 break;
121 }
122 }
123 enumerator->destroy(enumerator);
124 return result;
125 }
126
127 METHOD(imc_manager_t, receive_message, void,
128 private_tnc_imc_manager_t *this, TNC_ConnectionID connection_id,
129 TNC_BufferReference message,
130 TNC_UInt32 message_len,
131 TNC_MessageType message_type)
132 {
133 enumerator_t *enumerator;
134 imc_t *imc;
135
136 enumerator = this->imcs->create_enumerator(this->imcs);
137 while (enumerator->enumerate(enumerator, &imc))
138 {
139 if (imc->receive_message && imc->type_supported(imc, message_type))
140 {
141 imc->receive_message(imc->get_id(imc), connection_id,
142 message, message_len, message_type);
143 }
144 }
145 enumerator->destroy(enumerator);
146 }
147
148 METHOD(imc_manager_t, destroy, void,
149 private_tnc_imc_manager_t *this)
150 {
151 imc_t *imc;
152
153 while (this->imcs->remove_last(this->imcs, (void**)&imc) == SUCCESS)
154 {
155 if (imc->terminate &&
156 imc->terminate(imc->get_id(imc)) != TNC_RESULT_SUCCESS)
157 {
158 DBG1(DBG_TNC, "IMC '%s' not terminated successfully",
159 imc->get_name(imc));
160 }
161 imc->destroy(imc);
162 }
163 this->imcs->destroy(this->imcs);
164 free(this);
165 }
166
167 /**
168 * Described in header.
169 */
170 imc_manager_t* tnc_imc_manager_create(void)
171 {
172 private_tnc_imc_manager_t *this;
173
174 INIT(this,
175 .public = {
176 .add = _add,
177 .notify_connection_change = _notify_connection_change,
178 .begin_handshake = _begin_handshake,
179 .set_message_types = _set_message_types,
180 .receive_message = _receive_message,
181 .destroy = _destroy,
182 },
183 .imcs = linked_list_create(),
184 .next_imc_id = 1,
185 );
186
187
188 return &this->public;
189 }
190
191