aboutsummaryrefslogtreecommitdiff
path: root/src/reclaim-attribute/reclaim_attribute.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/reclaim-attribute/reclaim_attribute.c')
-rw-r--r--src/reclaim-attribute/reclaim_attribute.c448
1 files changed, 448 insertions, 0 deletions
diff --git a/src/reclaim-attribute/reclaim_attribute.c b/src/reclaim-attribute/reclaim_attribute.c
new file mode 100644
index 000000000..1ffa9618f
--- /dev/null
+++ b/src/reclaim-attribute/reclaim_attribute.c
@@ -0,0 +1,448 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2010-2015 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19/**
20 * @file reclaim-attribute/reclaim_attribute.c
21 * @brief helper library to manage identity attributes
22 * @author Martin Schanzenbach
23 */
24#include "platform.h"
25#include "gnunet_util_lib.h"
26#include "reclaim_attribute.h"
27#include "gnunet_reclaim_attribute_plugin.h"
28
29/**
30 * Handle for a plugin
31 */
32struct Plugin
33{
34 /**
35 * Name of the plugin
36 */
37 char *library_name;
38
39 /**
40 * Plugin API
41 */
42 struct GNUNET_RECLAIM_ATTRIBUTE_PluginFunctions *api;
43};
44
45/**
46 * Plugins
47 */
48static struct Plugin **attr_plugins;
49
50/**
51 * Number of plugins
52 */
53static unsigned int num_plugins;
54
55/**
56 * Init canary
57 */
58static int initialized;
59
60/**
61 * Add a plugin
62 */
63static void
64add_plugin (void* cls,
65 const char *library_name,
66 void *lib_ret)
67{
68 struct GNUNET_RECLAIM_ATTRIBUTE_PluginFunctions *api = lib_ret;
69 struct Plugin *plugin;
70
71 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
72 "Loading attribute plugin `%s'\n",
73 library_name);
74 plugin = GNUNET_new (struct Plugin);
75 plugin->api = api;
76 plugin->library_name = GNUNET_strdup (library_name);
77 GNUNET_array_append (attr_plugins, num_plugins, plugin);
78}
79
80/**
81 * Load plugins
82 */
83static void
84init()
85{
86 if (GNUNET_YES == initialized)
87 return;
88 initialized = GNUNET_YES;
89 GNUNET_PLUGIN_load_all ("libgnunet_plugin_reclaim_attribute_", NULL,
90 &add_plugin, NULL);
91}
92
93/**
94 * Convert a type name to the corresponding number
95 *
96 * @param typename name to convert
97 * @return corresponding number, UINT32_MAX on error
98 */
99uint32_t
100GNUNET_RECLAIM_ATTRIBUTE_typename_to_number (const char *typename)
101{
102 unsigned int i;
103 struct Plugin *plugin;
104 uint32_t ret;
105
106 init ();
107 for (i = 0; i < num_plugins; i++)
108 {
109 plugin = attr_plugins[i];
110 if (UINT32_MAX != (ret = plugin->api->typename_to_number (plugin->api->cls,
111 typename)))
112 return ret;
113 }
114 return UINT32_MAX;
115}
116
117/**
118 * Convert a type number to the corresponding type string
119 *
120 * @param type number of a type
121 * @return corresponding typestring, NULL on error
122 */
123const char*
124GNUNET_RECLAIM_ATTRIBUTE_number_to_typename (uint32_t type)
125{
126 unsigned int i;
127 struct Plugin *plugin;
128 const char *ret;
129
130 init ();
131 for (i = 0; i < num_plugins; i++)
132 {
133 plugin = attr_plugins[i];
134 if (NULL != (ret = plugin->api->number_to_typename (plugin->api->cls,
135 type)))
136 return ret;
137 }
138 return NULL;
139}
140
141/**
142 * Convert human-readable version of a 'claim' of an attribute to the binary
143 * representation
144 *
145 * @param type type of the claim
146 * @param s human-readable string
147 * @param data set to value in binary encoding (will be allocated)
148 * @param data_size set to number of bytes in @a data
149 * @return #GNUNET_OK on success
150 */
151int
152GNUNET_RECLAIM_ATTRIBUTE_string_to_value (uint32_t type,
153 const char *s,
154 void **data,
155 size_t *data_size)
156{
157 unsigned int i;
158 struct Plugin *plugin;
159
160 init ();
161 for (i = 0; i < num_plugins; i++)
162 {
163 plugin = attr_plugins[i];
164 if (GNUNET_OK == plugin->api->string_to_value (plugin->api->cls,
165 type,
166 s,
167 data,
168 data_size))
169 return GNUNET_OK;
170 }
171 return GNUNET_SYSERR;
172}
173
174/**
175 * Convert the 'claim' of an attribute to a string
176 *
177 * @param type the type of attribute
178 * @param data claim in binary encoding
179 * @param data_size number of bytes in @a data
180 * @return NULL on error, otherwise human-readable representation of the claim
181 */
182char *
183GNUNET_RECLAIM_ATTRIBUTE_value_to_string (uint32_t type,
184 const void* data,
185 size_t data_size)
186{
187 unsigned int i;
188 struct Plugin *plugin;
189 char *ret;
190
191 init();
192 for (i = 0; i < num_plugins; i++)
193 {
194 plugin = attr_plugins[i];
195 if (NULL != (ret = plugin->api->value_to_string (plugin->api->cls,
196 type,
197 data,
198 data_size)))
199 return ret;
200 }
201 return NULL;
202}
203
204/**
205 * Create a new attribute.
206 *
207 * @param attr_name the attribute name
208 * @param type the attribute type
209 * @param data the attribute value
210 * @param data_size the attribute value size
211 * @return the new attribute
212 */
213struct GNUNET_RECLAIM_ATTRIBUTE_Claim *
214GNUNET_RECLAIM_ATTRIBUTE_claim_new (const char* attr_name,
215 uint32_t type,
216 const void* data,
217 size_t data_size)
218{
219 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr;
220 char *write_ptr;
221 char *attr_name_tmp = GNUNET_strdup (attr_name);
222
223 GNUNET_STRINGS_utf8_tolower (attr_name, attr_name_tmp);
224
225 attr = GNUNET_malloc (sizeof (struct GNUNET_RECLAIM_ATTRIBUTE_Claim) +
226 strlen (attr_name_tmp) + 1 +
227 data_size);
228 attr->type = type;
229 attr->data_size = data_size;
230 attr->version = 0;
231 write_ptr = (char*)&attr[1];
232 GNUNET_memcpy (write_ptr,
233 attr_name_tmp,
234 strlen (attr_name_tmp) + 1);
235 attr->name = write_ptr;
236 write_ptr += strlen (attr->name) + 1;
237 GNUNET_memcpy (write_ptr,
238 data,
239 data_size);
240 attr->data = write_ptr;
241 GNUNET_free (attr_name_tmp);
242 return attr;
243}
244
245/**
246 * Add a new claim list entry.
247 *
248 * @param claim_list the attribute name
249 * @param attr_name the attribute name
250 * @param type the attribute type
251 * @param data the attribute value
252 * @param data_size the attribute value size
253 * @return
254 */
255void
256GNUNET_RECLAIM_ATTRIBUTE_list_add (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *claim_list,
257 const char* attr_name,
258 uint32_t type,
259 const void* data,
260 size_t data_size)
261{
262 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
263 le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
264 le->claim = GNUNET_RECLAIM_ATTRIBUTE_claim_new (attr_name,
265 type,
266 data,
267 data_size);
268 GNUNET_CONTAINER_DLL_insert (claim_list->list_head,
269 claim_list->list_tail,
270 le);
271}
272
273size_t
274GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size (const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs)
275{
276 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
277 size_t len = 0;
278 for (le = attrs->list_head; NULL != le; le = le->next)
279 len += GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (le->claim);
280 return len;
281}
282
283size_t
284GNUNET_RECLAIM_ATTRIBUTE_list_serialize (const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
285 char *result)
286{
287 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
288 size_t len;
289 size_t total_len;
290 char* write_ptr;
291
292 write_ptr = result;
293 total_len = 0;
294 for (le = attrs->list_head; NULL != le; le = le->next)
295 {
296 len = GNUNET_RECLAIM_ATTRIBUTE_serialize (le->claim,
297 write_ptr);
298 total_len += len;
299 write_ptr += len;
300 }
301 return total_len;
302}
303
304struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *
305GNUNET_RECLAIM_ATTRIBUTE_list_deserialize (const char* data,
306 size_t data_size)
307{
308 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
309 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
310 size_t attr_len;
311 const char* read_ptr;
312
313 if (data_size < sizeof (struct Attribute))
314 return NULL;
315
316 attrs = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList);
317 read_ptr = data;
318 while (((data + data_size) - read_ptr) >= sizeof (struct Attribute))
319 {
320
321 le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
322 le->claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize (read_ptr,
323 data_size - (read_ptr - data));
324 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
325 "Deserialized attribute %s\n", le->claim->name);
326 GNUNET_CONTAINER_DLL_insert (attrs->list_head,
327 attrs->list_tail,
328 le);
329 attr_len = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (le->claim);
330 read_ptr += attr_len;
331 }
332 return attrs;
333}
334
335struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList*
336GNUNET_RECLAIM_ATTRIBUTE_list_dup (const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs)
337{
338 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
339 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *result_le;
340 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *result;
341
342 result = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList);
343 for (le = attrs->list_head; NULL != le; le = le->next)
344 {
345 result_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
346 result_le->claim = GNUNET_RECLAIM_ATTRIBUTE_claim_new (le->claim->name,
347 le->claim->type,
348 le->claim->data,
349 le->claim->data_size);
350 GNUNET_CONTAINER_DLL_insert (result->list_head,
351 result->list_tail,
352 result_le);
353 }
354 return result;
355}
356
357
358void
359GNUNET_RECLAIM_ATTRIBUTE_list_destroy (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs)
360{
361 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
362 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *tmp_le;
363
364 for (le = attrs->list_head; NULL != le;)
365 {
366 GNUNET_free (le->claim);
367 tmp_le = le;
368 le = le->next;
369 GNUNET_free (tmp_le);
370 }
371 GNUNET_free (attrs);
372
373}
374
375size_t
376GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
377{
378 return sizeof (struct Attribute)
379 + strlen (attr->name)
380 + attr->data_size;
381}
382
383size_t
384GNUNET_RECLAIM_ATTRIBUTE_serialize (const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
385 char *result)
386{
387 size_t data_len_ser;
388 size_t name_len;
389 struct Attribute *attr_ser;
390 char* write_ptr;
391
392 attr_ser = (struct Attribute*)result;
393 attr_ser->attribute_type = htons (attr->type);
394 attr_ser->attribute_version = htonl (attr->version);
395 name_len = strlen (attr->name);
396 attr_ser->name_len = htons (name_len);
397 write_ptr = (char*)&attr_ser[1];
398 GNUNET_memcpy (write_ptr, attr->name, name_len);
399 write_ptr += name_len;
400 //TODO plugin-ize
401 //data_len_ser = plugin->serialize_attribute_value (attr,
402 // &attr_ser[1]);
403 data_len_ser = attr->data_size;
404 GNUNET_memcpy (write_ptr, attr->data, attr->data_size);
405 attr_ser->data_size = htons (data_len_ser);
406
407 return sizeof (struct Attribute) + strlen (attr->name) + attr->data_size;
408}
409
410struct GNUNET_RECLAIM_ATTRIBUTE_Claim *
411GNUNET_RECLAIM_ATTRIBUTE_deserialize (const char* data,
412 size_t data_size)
413{
414 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr;
415 struct Attribute *attr_ser;
416 size_t data_len;
417 size_t name_len;
418 char* write_ptr;
419
420 if (data_size < sizeof (struct Attribute))
421 return NULL;
422
423 attr_ser = (struct Attribute*)data;
424 data_len = ntohs (attr_ser->data_size);
425 name_len = ntohs (attr_ser->name_len);
426 attr = GNUNET_malloc (sizeof (struct GNUNET_RECLAIM_ATTRIBUTE_Claim)
427 + data_len + name_len + 1);
428 attr->type = ntohs (attr_ser->attribute_type);
429 attr->version = ntohl (attr_ser->attribute_version);
430 attr->data_size = ntohs (attr_ser->data_size);
431
432 write_ptr = (char*)&attr[1];
433 GNUNET_memcpy (write_ptr,
434 &attr_ser[1],
435 name_len);
436 write_ptr[name_len] = '\0';
437 attr->name = write_ptr;
438
439 write_ptr += name_len + 1;
440 GNUNET_memcpy (write_ptr,
441 (char*)&attr_ser[1] + name_len,
442 attr->data_size);
443 attr->data = write_ptr;
444 return attr;
445
446}
447
448/* end of reclaim_attribute.c */