cadet_api_list_tunnels.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2011, 2017, 2019 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 cadet/cadet_api_list_tunnels.c
  18. * @brief cadet api: client implementation of cadet service
  19. * @author Bartlomiej Polot
  20. * @author Christian Grothoff
  21. */
  22. #include "platform.h"
  23. #include "gnunet_util_lib.h"
  24. #include "gnunet_constants.h"
  25. #include "gnunet_cadet_service.h"
  26. #include "cadet.h"
  27. #include "cadet_protocol.h"
  28. /**
  29. * Operation handle.
  30. */
  31. struct GNUNET_CADET_ListTunnels
  32. {
  33. /**
  34. * Monitor callback
  35. */
  36. GNUNET_CADET_TunnelsCB tunnels_cb;
  37. /**
  38. * Info callback closure for @c tunnels_cb.
  39. */
  40. void *tunnels_cb_cls;
  41. /**
  42. * Message queue to talk to CADET service.
  43. */
  44. struct GNUNET_MQ_Handle *mq;
  45. /**
  46. * Configuration we use.
  47. */
  48. const struct GNUNET_CONFIGURATION_Handle *cfg;
  49. /**
  50. * Task to reconnect.
  51. */
  52. struct GNUNET_SCHEDULER_Task *reconnect_task;
  53. /**
  54. * Backoff for reconnect attempts.
  55. */
  56. struct GNUNET_TIME_Relative backoff;
  57. };
  58. /**
  59. * Process a local reply about info on all tunnels, pass info to the user.
  60. *
  61. * @param cls a `struct GNUNET_CADET_ListTunnels *`
  62. * @param info Message itself.
  63. */
  64. static void
  65. handle_get_tunnels (void *cls,
  66. const struct GNUNET_CADET_LocalInfoTunnel *info)
  67. {
  68. struct GNUNET_CADET_ListTunnels *lt = cls;
  69. struct GNUNET_CADET_TunnelDetails td;
  70. td.peer = info->destination;
  71. td.channels = ntohl (info->channels);
  72. td.connections = ntohl (info->connections);
  73. td.estate = ntohs (info->estate);
  74. td.cstate = ntohs (info->cstate);
  75. lt->tunnels_cb (lt->tunnels_cb_cls,
  76. &td);
  77. }
  78. /**
  79. * Process a local reply about info on all tunnels, pass info to the user.
  80. *
  81. * @param cls a `struct GNUNET_CADET_ListTunnels *`
  82. * @param message Message itself.
  83. */
  84. static void
  85. handle_get_tunnels_end (void *cls,
  86. const struct GNUNET_MessageHeader *msg)
  87. {
  88. struct GNUNET_CADET_ListTunnels *lt = cls;
  89. (void) msg;
  90. lt->tunnels_cb (lt->tunnels_cb_cls,
  91. NULL);
  92. GNUNET_CADET_list_tunnels_cancel (lt);
  93. }
  94. /**
  95. * Reconnect to the service and try again.
  96. *
  97. * @param cls a `struct GNUNET_CADET_ListTunnels` operation
  98. */
  99. static void
  100. reconnect (void *cls);
  101. /**
  102. * Function called on connection trouble. Reconnects.
  103. *
  104. * @param cls a `struct GNUNET_CADET_ListTunnels`
  105. * @param error error code from MQ
  106. */
  107. static void
  108. error_handler (void *cls,
  109. enum GNUNET_MQ_Error error)
  110. {
  111. struct GNUNET_CADET_ListTunnels *lt = cls;
  112. GNUNET_MQ_destroy (lt->mq);
  113. lt->mq = NULL;
  114. lt->backoff = GNUNET_TIME_randomized_backoff (lt->backoff,
  115. GNUNET_TIME_UNIT_MINUTES);
  116. lt->reconnect_task = GNUNET_SCHEDULER_add_delayed (lt->backoff,
  117. &reconnect,
  118. lt);
  119. }
  120. /**
  121. * Reconnect to the service and try again.
  122. *
  123. * @param cls a `struct GNUNET_CADET_ListTunnels` operation
  124. */
  125. static void
  126. reconnect (void *cls)
  127. {
  128. struct GNUNET_CADET_ListTunnels *lt = cls;
  129. struct GNUNET_MQ_MessageHandler handlers[] = {
  130. GNUNET_MQ_hd_fixed_size (get_tunnels,
  131. GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS,
  132. struct GNUNET_CADET_LocalInfoTunnel,
  133. lt),
  134. GNUNET_MQ_hd_fixed_size (get_tunnels_end,
  135. GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS_END,
  136. struct GNUNET_MessageHeader,
  137. lt),
  138. GNUNET_MQ_handler_end ()
  139. };
  140. struct GNUNET_MessageHeader *msg;
  141. struct GNUNET_MQ_Envelope *env;
  142. lt->reconnect_task = NULL;
  143. lt->mq = GNUNET_CLIENT_connect (lt->cfg,
  144. "cadet",
  145. handlers,
  146. &error_handler,
  147. lt);
  148. if (NULL == lt->mq)
  149. return;
  150. env = GNUNET_MQ_msg (msg,
  151. GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_TUNNELS);
  152. GNUNET_MQ_send (lt->mq,
  153. env);
  154. }
  155. /**
  156. * Request information about tunnels of the running cadet peer.
  157. * The callback will be called for every tunnel of the service.
  158. * Only one info request (of any kind) can be active at once.
  159. *
  160. * @param cfg configuration to use
  161. * @param callback Function to call with the requested data.
  162. * @param callback_cls Closure for @c callback.
  163. * @return NULL on error
  164. */
  165. struct GNUNET_CADET_ListTunnels *
  166. GNUNET_CADET_list_tunnels (const struct GNUNET_CONFIGURATION_Handle *cfg,
  167. GNUNET_CADET_TunnelsCB callback,
  168. void *callback_cls)
  169. {
  170. struct GNUNET_CADET_ListTunnels *lt;
  171. if (NULL == callback)
  172. {
  173. GNUNET_break (0);
  174. return NULL;
  175. }
  176. lt = GNUNET_new (struct GNUNET_CADET_ListTunnels);
  177. lt->tunnels_cb = callback;
  178. lt->tunnels_cb_cls = callback_cls;
  179. lt->cfg = cfg;
  180. reconnect (lt);
  181. if (NULL == lt->mq)
  182. {
  183. GNUNET_free (lt);
  184. return NULL;
  185. }
  186. return lt;
  187. }
  188. /**
  189. * Cancel a monitor request. The monitor callback will not be called.
  190. *
  191. * @param lt operation handle
  192. * @return Closure given to GNUNET_CADET_list_tunnels().
  193. */
  194. void *
  195. GNUNET_CADET_list_tunnels_cancel (struct GNUNET_CADET_ListTunnels *lt)
  196. {
  197. void *ret = lt->tunnels_cb_cls;
  198. if (NULL != lt->mq)
  199. GNUNET_MQ_destroy (lt->mq);
  200. if (NULL != lt->reconnect_task)
  201. GNUNET_SCHEDULER_cancel (lt->reconnect_task);
  202. GNUNET_free (lt);
  203. return ret;
  204. }
  205. /* end of cadet_api_list_tunnels.c */