gnsrecord.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2009-2013 GNUnet e.V.
  4. GNUnet is free software: you can redistribute it and/or modify it
  5. under the terms of the GNU Affero General Public License as published
  6. by the Free Software Foundation, either version 3 of the License,
  7. or (at your option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Affero General Public License for more details.
  12. You should have received a copy of the GNU Affero General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. SPDX-License-Identifier: AGPL3.0-or-later
  15. */
  16. /**
  17. * @file gnsrecord/gnsrecord.c
  18. * @brief API to access GNS record data
  19. * @author Martin Schanzenbach
  20. * @author Matthias Wachs
  21. * @author Christian Grothoff
  22. */
  23. #include "platform.h"
  24. #include "gnunet_util_lib.h"
  25. #include "gnunet_constants.h"
  26. #include "gnunet_gnsrecord_lib.h"
  27. #include "gnunet_gnsrecord_plugin.h"
  28. #include "gnunet_tun_lib.h"
  29. #define LOG(kind, ...) GNUNET_log_from (kind, "gnsrecord", __VA_ARGS__)
  30. /**
  31. * Handle for a plugin.
  32. */
  33. struct Plugin
  34. {
  35. /**
  36. * Name of the shared library.
  37. */
  38. char *library_name;
  39. /**
  40. * Plugin API.
  41. */
  42. struct GNUNET_GNSRECORD_PluginFunctions *api;
  43. };
  44. /**
  45. * Array of our plugins.
  46. */
  47. static struct Plugin **gns_plugins;
  48. /**
  49. * Size of the 'plugins' array.
  50. */
  51. static unsigned int num_plugins;
  52. /**
  53. * Global to mark if we've run the initialization.
  54. */
  55. static int once;
  56. /**
  57. * Add a plugin to the list managed by the block library.
  58. *
  59. * @param cls NULL
  60. * @param library_name name of the plugin
  61. * @param lib_ret the plugin API
  62. */
  63. static void
  64. add_plugin (void *cls,
  65. const char *library_name,
  66. void *lib_ret)
  67. {
  68. struct GNUNET_GNSRECORD_PluginFunctions *api = lib_ret;
  69. struct Plugin *plugin;
  70. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  71. "Loading block plugin `%s'\n",
  72. library_name);
  73. plugin = GNUNET_new (struct Plugin);
  74. plugin->api = api;
  75. plugin->library_name = GNUNET_strdup (library_name);
  76. GNUNET_array_append (gns_plugins, num_plugins, plugin);
  77. }
  78. /**
  79. * Loads all plugins (lazy initialization).
  80. */
  81. static void
  82. init ()
  83. {
  84. if (1 == once)
  85. return;
  86. once = 1;
  87. GNUNET_PLUGIN_load_all ("libgnunet_plugin_gnsrecord_", NULL,
  88. &add_plugin, NULL);
  89. }
  90. /**
  91. * Dual function to #init().
  92. */
  93. void __attribute__ ((destructor))
  94. GNSRECORD_fini ()
  95. {
  96. struct Plugin *plugin;
  97. for (unsigned int i = 0; i < num_plugins; i++)
  98. {
  99. plugin = gns_plugins[i];
  100. GNUNET_break (NULL ==
  101. GNUNET_PLUGIN_unload (plugin->library_name,
  102. plugin->api));
  103. GNUNET_free (plugin->library_name);
  104. GNUNET_free (plugin);
  105. }
  106. GNUNET_free_non_null (gns_plugins);
  107. gns_plugins = NULL;
  108. once = 0;
  109. num_plugins = 0;
  110. }
  111. /**
  112. * Convert the 'value' of a record to a string.
  113. *
  114. * @param type type of the record
  115. * @param data value in binary encoding
  116. * @param data_size number of bytes in @a data
  117. * @return NULL on error, otherwise human-readable representation of the value
  118. */
  119. char *
  120. GNUNET_GNSRECORD_value_to_string (uint32_t type,
  121. const void *data,
  122. size_t data_size)
  123. {
  124. struct Plugin *plugin;
  125. char *ret;
  126. init ();
  127. for (unsigned int i = 0; i < num_plugins; i++)
  128. {
  129. plugin = gns_plugins[i];
  130. if (NULL != (ret = plugin->api->value_to_string (plugin->api->cls,
  131. type,
  132. data,
  133. data_size)))
  134. return ret;
  135. }
  136. return NULL;
  137. }
  138. /**
  139. * Convert human-readable version of a 'value' of a record to the binary
  140. * representation.
  141. *
  142. * @param type type of the record
  143. * @param s human-readable string
  144. * @param data set to value in binary encoding (will be allocated)
  145. * @param data_size set to number of bytes in @a data
  146. * @return #GNUNET_OK on success
  147. */
  148. int
  149. GNUNET_GNSRECORD_string_to_value (uint32_t type,
  150. const char *s,
  151. void **data,
  152. size_t *data_size)
  153. {
  154. struct Plugin *plugin;
  155. init ();
  156. for (unsigned int i = 0; i < num_plugins; i++)
  157. {
  158. plugin = gns_plugins[i];
  159. if (GNUNET_OK == plugin->api->string_to_value (plugin->api->cls,
  160. type,
  161. s,
  162. data,
  163. data_size))
  164. return GNUNET_OK;
  165. }
  166. return GNUNET_SYSERR;
  167. }
  168. /**
  169. * Convert a type name (i.e. "AAAA") to the corresponding number.
  170. *
  171. * @param dns_typename name to convert
  172. * @return corresponding number, UINT32_MAX on error
  173. */
  174. uint32_t
  175. GNUNET_GNSRECORD_typename_to_number (const char *dns_typename)
  176. {
  177. struct Plugin *plugin;
  178. uint32_t ret;
  179. if (0 == strcasecmp (dns_typename,
  180. "ANY"))
  181. return GNUNET_GNSRECORD_TYPE_ANY;
  182. init ();
  183. for (unsigned int i = 0; i < num_plugins; i++)
  184. {
  185. plugin = gns_plugins[i];
  186. if (UINT32_MAX != (ret = plugin->api->typename_to_number (plugin->api->cls,
  187. dns_typename)))
  188. return ret;
  189. }
  190. return UINT32_MAX;
  191. }
  192. /**
  193. * Convert a type number (i.e. 1) to the corresponding type string (i.e. "A")
  194. *
  195. * @param type number of a type to convert
  196. * @return corresponding typestring, NULL on error
  197. */
  198. const char *
  199. GNUNET_GNSRECORD_number_to_typename (uint32_t type)
  200. {
  201. struct Plugin *plugin;
  202. const char *ret;
  203. if (GNUNET_GNSRECORD_TYPE_ANY == type)
  204. return "ANY";
  205. init ();
  206. for (unsigned int i = 0; i < num_plugins; i++)
  207. {
  208. plugin = gns_plugins[i];
  209. if (NULL != (ret = plugin->api->number_to_typename (plugin->api->cls,
  210. type)))
  211. return ret;
  212. }
  213. return NULL;
  214. }
  215. /* end of gnsrecord.c */