plugin_gnsrecord_conversation.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /*
  2. This file is part of GNUnet
  3. (C) 2013 Christian Grothoff (and other contributing authors)
  4. GNUnet is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published
  6. by the Free Software Foundation; either version 3, or (at your
  7. 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. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNUnet; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  15. Boston, MA 02111-1307, USA.
  16. */
  17. /**
  18. * @file conversation/plugin_gnsrecord_conversation.c
  19. * @brief gnsrecord plugin to provide the API for fundamental GNS records
  20. * This includes the VPN record because GNS resolution
  21. * is expected to understand VPN records and (if needed)
  22. * map the result to A/AAAA.
  23. * @author Christian Grothoff
  24. */
  25. #include "platform.h"
  26. #include "gnunet_util_lib.h"
  27. #include "gnunet_gnsrecord_lib.h"
  28. #include "gnunet_conversation_service.h"
  29. #include "gnunet_gnsrecord_plugin.h"
  30. /**
  31. * Convert the 'value' of a record to a string.
  32. *
  33. * @param cls closure, unused
  34. * @param type type of the record
  35. * @param data value in binary encoding
  36. * @param data_size number of bytes in @a data
  37. * @return NULL on error, otherwise human-readable representation of the value
  38. */
  39. static char *
  40. conversation_value_to_string (void *cls,
  41. uint32_t type,
  42. const void *data,
  43. size_t data_size)
  44. {
  45. switch (type)
  46. {
  47. case GNUNET_GNSRECORD_TYPE_PHONE:
  48. {
  49. const struct GNUNET_CONVERSATION_PhoneRecord *pr;
  50. char *ret;
  51. char *pkey;
  52. if (data_size != sizeof (struct GNUNET_CONVERSATION_PhoneRecord))
  53. return NULL;
  54. pr = data;
  55. if (0 != ntohl (pr->version))
  56. return NULL;
  57. pkey = GNUNET_CRYPTO_eddsa_public_key_to_string (&pr->peer.public_key);
  58. GNUNET_asprintf (&ret,
  59. "%u-%s",
  60. ntohl (pr->line),
  61. pkey);
  62. GNUNET_free (pkey);
  63. return ret;
  64. }
  65. default:
  66. return NULL;
  67. }
  68. }
  69. /**
  70. * Convert human-readable version of a 'value' of a record to the binary
  71. * representation.
  72. *
  73. * @param cls closure, unused
  74. * @param type type of the record
  75. * @param s human-readable string
  76. * @param data set to value in binary encoding (will be allocated)
  77. * @param data_size set to number of bytes in @a data
  78. * @return #GNUNET_OK on success
  79. */
  80. static int
  81. conversation_string_to_value (void *cls,
  82. uint32_t type,
  83. const char *s,
  84. void **data,
  85. size_t *data_size)
  86. {
  87. if (NULL == s)
  88. return GNUNET_SYSERR;
  89. switch (type)
  90. {
  91. case GNUNET_GNSRECORD_TYPE_PHONE:
  92. {
  93. struct GNUNET_CONVERSATION_PhoneRecord *pr;
  94. unsigned int line;
  95. const char *dash;
  96. struct GNUNET_PeerIdentity peer;
  97. if ( (NULL == (dash = strchr (s, '-'))) ||
  98. (1 != sscanf (s, "%u-", &line)) ||
  99. (GNUNET_OK !=
  100. GNUNET_CRYPTO_eddsa_public_key_from_string (dash + 1,
  101. strlen (dash + 1),
  102. &peer.public_key)) )
  103. {
  104. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  105. _("Unable to parse PHONE record `%s'\n"),
  106. s);
  107. return GNUNET_SYSERR;
  108. }
  109. pr = GNUNET_new (struct GNUNET_CONVERSATION_PhoneRecord);
  110. pr->version = htonl (0);
  111. pr->line = htonl ((uint32_t) line);
  112. pr->peer = peer;
  113. *data = pr;
  114. *data_size = sizeof (struct GNUNET_CONVERSATION_PhoneRecord);
  115. return GNUNET_OK;
  116. }
  117. default:
  118. return GNUNET_SYSERR;
  119. }
  120. }
  121. /**
  122. * Mapping of record type numbers to human-readable
  123. * record type names.
  124. */
  125. static struct {
  126. const char *name;
  127. uint32_t number;
  128. } name_map[] = {
  129. { "PHONE", GNUNET_GNSRECORD_TYPE_PHONE },
  130. { NULL, UINT32_MAX }
  131. };
  132. /**
  133. * Convert a type name (i.e. "AAAA") to the corresponding number.
  134. *
  135. * @param cls closure, unused
  136. * @param gns_typename name to convert
  137. * @return corresponding number, UINT32_MAX on error
  138. */
  139. static uint32_t
  140. conversation_typename_to_number (void *cls,
  141. const char *gns_typename)
  142. {
  143. unsigned int i;
  144. i=0;
  145. while ( (name_map[i].name != NULL) &&
  146. (0 != strcasecmp (gns_typename, name_map[i].name)) )
  147. i++;
  148. return name_map[i].number;
  149. }
  150. /**
  151. * Convert a type number (i.e. 1) to the corresponding type string (i.e. "A")
  152. *
  153. * @param cls closure, unused
  154. * @param type number of a type to convert
  155. * @return corresponding typestring, NULL on error
  156. */
  157. static const char *
  158. conversation_number_to_typename (void *cls,
  159. uint32_t type)
  160. {
  161. unsigned int i;
  162. i=0;
  163. while ( (name_map[i].name != NULL) &&
  164. (type != name_map[i].number) )
  165. i++;
  166. return name_map[i].name;
  167. }
  168. /**
  169. * Entry point for the plugin.
  170. *
  171. * @param cls NULL
  172. * @return the exported block API
  173. */
  174. void *
  175. libgnunet_plugin_gnsrecord_conversation_init (void *cls)
  176. {
  177. struct GNUNET_GNSRECORD_PluginFunctions *api;
  178. api = GNUNET_new (struct GNUNET_GNSRECORD_PluginFunctions);
  179. api->value_to_string = &conversation_value_to_string;
  180. api->string_to_value = &conversation_string_to_value;
  181. api->typename_to_number = &conversation_typename_to_number;
  182. api->number_to_typename = &conversation_number_to_typename;
  183. return api;
  184. }
  185. /**
  186. * Exit point from the plugin.
  187. *
  188. * @param cls the return value from #libgnunet_plugin_block_test_init
  189. * @return NULL
  190. */
  191. void *
  192. libgnunet_plugin_gnsrecord_conversation_done (void *cls)
  193. {
  194. struct GNUNET_GNSRECORD_PluginFunctions *api = cls;
  195. GNUNET_free (api);
  196. return NULL;
  197. }
  198. /* end of plugin_gnsrecord_conversation.c */