transport_api_address_to_string.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. /*
  2. This file is part of GNUnet.
  3. (C) 2009-2014 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 transport/transport_api_address_to_string.c
  19. * @author Christian Grothoff
  20. * @brief enable clients to convert addresses to human readable strings
  21. */
  22. #include "platform.h"
  23. #include "gnunet_util_lib.h"
  24. #include "gnunet_arm_service.h"
  25. #include "gnunet_hello_lib.h"
  26. #include "gnunet_protocols.h"
  27. #include "gnunet_transport_service.h"
  28. #include "transport.h"
  29. /**
  30. * Context for the address lookup.
  31. */
  32. struct GNUNET_TRANSPORT_AddressToStringContext
  33. {
  34. /**
  35. * Function to call with the human-readable address.
  36. */
  37. GNUNET_TRANSPORT_AddressToStringCallback cb;
  38. /**
  39. * Closure for @e cb.
  40. */
  41. void *cb_cls;
  42. /**
  43. * Connection to the service.
  44. */
  45. struct GNUNET_CLIENT_Connection *client;
  46. };
  47. /**
  48. * Function called with responses from the service.
  49. *
  50. * @param cls our `struct GNUNET_TRANSPORT_AddressToStringContext *`
  51. * @param msg NULL on timeout or error, otherwise presumably a
  52. * message with the human-readable address
  53. */
  54. static void
  55. address_response_processor (void *cls,
  56. const struct GNUNET_MessageHeader *msg)
  57. {
  58. struct GNUNET_TRANSPORT_AddressToStringContext *alucb = cls;
  59. const struct AddressToStringResultMessage *atsm;
  60. const char *address;
  61. uint16_t size;
  62. int result;
  63. uint32_t addr_len;
  64. if (NULL == msg)
  65. {
  66. alucb->cb (alucb->cb_cls,
  67. NULL,
  68. GNUNET_SYSERR);
  69. GNUNET_TRANSPORT_address_to_string_cancel (alucb);
  70. return;
  71. }
  72. GNUNET_break (ntohs (msg->type) ==
  73. GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_TO_STRING_REPLY);
  74. size = ntohs (msg->size);
  75. if (size < sizeof (struct AddressToStringResultMessage))
  76. {
  77. GNUNET_break (0);
  78. alucb->cb (alucb->cb_cls,
  79. NULL,
  80. GNUNET_SYSERR);
  81. GNUNET_TRANSPORT_address_to_string_cancel (alucb);
  82. return;
  83. }
  84. atsm = (const struct AddressToStringResultMessage *) msg;
  85. result = (int) ntohl (atsm->res);
  86. addr_len = ntohl (atsm->addr_len);
  87. if (GNUNET_SYSERR == result)
  88. {
  89. /* expect more replies; as this is not the last
  90. call, we must pass the empty string for the address */
  91. alucb->cb (alucb->cb_cls,
  92. "",
  93. GNUNET_NO);
  94. GNUNET_CLIENT_receive (alucb->client,
  95. &address_response_processor,
  96. alucb,
  97. GNUNET_TIME_UNIT_FOREVER_REL);
  98. return;
  99. }
  100. if (size == (sizeof (struct AddressToStringResultMessage)))
  101. {
  102. if (GNUNET_OK != result)
  103. {
  104. GNUNET_break (0);
  105. alucb->cb (alucb->cb_cls,
  106. NULL,
  107. GNUNET_SYSERR);
  108. GNUNET_CLIENT_disconnect (alucb->client);
  109. GNUNET_free (alucb);
  110. return;
  111. }
  112. /* we are done (successfully, without communication errors) */
  113. alucb->cb (alucb->cb_cls,
  114. NULL,
  115. GNUNET_OK);
  116. GNUNET_TRANSPORT_address_to_string_cancel (alucb);
  117. return;
  118. }
  119. address = (const char *) &atsm[1];
  120. if ( (addr_len > (size - (sizeof (struct AddressToStringResultMessage)))) ||
  121. (address[addr_len -1] != '\0') )
  122. {
  123. /* invalid reply */
  124. GNUNET_break (0);
  125. alucb->cb (alucb->cb_cls,
  126. NULL,
  127. GNUNET_SYSERR);
  128. GNUNET_TRANSPORT_address_to_string_cancel (alucb);
  129. return;
  130. }
  131. /* expect more replies */
  132. GNUNET_CLIENT_receive (alucb->client,
  133. &address_response_processor,
  134. alucb,
  135. GNUNET_TIME_UNIT_FOREVER_REL);
  136. /* return normal reply to caller */
  137. alucb->cb (alucb->cb_cls,
  138. address,
  139. GNUNET_OK);
  140. }
  141. /**
  142. * Convert a binary address into a human readable address.
  143. *
  144. * @param cfg configuration to use
  145. * @param address address to convert (binary format)
  146. * @param numeric should (IP) addresses be displayed in numeric form
  147. * (otherwise do reverse DNS lookup)
  148. * @param timeout how long is the lookup allowed to take at most
  149. * @param aluc function to call with the results
  150. * @param aluc_cls closure for @a aluc
  151. * @return handle to cancel the operation, NULL on error
  152. */
  153. struct GNUNET_TRANSPORT_AddressToStringContext *
  154. GNUNET_TRANSPORT_address_to_string (const struct GNUNET_CONFIGURATION_Handle *cfg,
  155. const struct GNUNET_HELLO_Address *address,
  156. int numeric,
  157. struct GNUNET_TIME_Relative timeout,
  158. GNUNET_TRANSPORT_AddressToStringCallback aluc,
  159. void *aluc_cls)
  160. {
  161. size_t len;
  162. size_t alen;
  163. size_t slen;
  164. struct AddressLookupMessage *msg;
  165. struct GNUNET_TRANSPORT_AddressToStringContext *alc;
  166. struct GNUNET_CLIENT_Connection *client;
  167. char *addrbuf;
  168. GNUNET_assert (NULL != address);
  169. alen = address->address_length;
  170. slen = strlen (address->transport_name) + 1;
  171. len = sizeof (struct AddressLookupMessage) + alen + slen;
  172. if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
  173. {
  174. GNUNET_break (0);
  175. return NULL;
  176. }
  177. client = GNUNET_CLIENT_connect ("transport", cfg);
  178. if (NULL == client)
  179. return NULL;
  180. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  181. "Client %p tries to resolve for peer `%s'address len %u \n",
  182. client,
  183. GNUNET_i2s (&address->peer),
  184. address->address_length);
  185. msg = GNUNET_malloc (len);
  186. msg->header.size = htons (len);
  187. msg->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_TO_STRING);
  188. msg->numeric_only = htons ((int16_t) numeric);
  189. msg->addrlen = htons ((uint16_t) alen);
  190. msg->timeout = GNUNET_TIME_relative_hton (timeout);
  191. addrbuf = (char *) &msg[1];
  192. memcpy (addrbuf,
  193. address->address,
  194. alen);
  195. memcpy (&addrbuf[alen],
  196. address->transport_name,
  197. slen);
  198. alc = GNUNET_new (struct GNUNET_TRANSPORT_AddressToStringContext);
  199. alc->cb = aluc;
  200. alc->cb_cls = aluc_cls;
  201. alc->client = client;
  202. GNUNET_assert (GNUNET_OK ==
  203. GNUNET_CLIENT_transmit_and_get_response (client,
  204. &msg->header,
  205. GNUNET_TIME_UNIT_FOREVER_REL,
  206. GNUNET_YES,
  207. &address_response_processor,
  208. alc));
  209. GNUNET_free (msg);
  210. return alc;
  211. }
  212. /**
  213. * Cancel request for address conversion.
  214. *
  215. * @param pic the context handle
  216. */
  217. void
  218. GNUNET_TRANSPORT_address_to_string_cancel (struct GNUNET_TRANSPORT_AddressToStringContext *pic)
  219. {
  220. GNUNET_CLIENT_disconnect (pic->client);
  221. GNUNET_free (pic);
  222. }
  223. /* end of transport_api_address_to_string.c */