-remove debug message
[oweals/gnunet.git] / src / cadet / cadet_api_list_peers.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2011, 2017, 2019 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      SPDX-License-Identifier: AGPL3.0-or-later
19  */
20 /**
21  * @file cadet/cadet_api_list_peers.c
22  * @brief cadet api: client implementation of cadet service
23  * @author Bartlomiej Polot
24  * @author Christian Grothoff
25  */
26 #include "platform.h"
27 #include "gnunet_util_lib.h"
28 #include "gnunet_constants.h"
29 #include "gnunet_cadet_service.h"
30 #include "cadet.h"
31 #include "cadet_protocol.h"
32
33
34 /**
35  * Operation handle.
36  */
37 struct GNUNET_CADET_PeersLister
38 {
39   /**
40    * Monitor callback
41    */
42   GNUNET_CADET_PeersCB peers_cb;
43
44   /**
45    * Info callback closure for @c info_cb.
46    */
47   void *peers_cb_cls;
48
49   /**
50    * Message queue to talk to CADET service.
51    */
52   struct GNUNET_MQ_Handle *mq;
53
54   /**
55    * Configuration we use.
56    */
57   const struct GNUNET_CONFIGURATION_Handle *cfg;
58
59   /**
60    * Task to reconnect.
61    */
62   struct GNUNET_SCHEDULER_Task *reconnect_task;
63
64   /**
65    * Backoff for reconnect attempts.
66    */
67   struct GNUNET_TIME_Relative backoff;
68 };
69
70
71 /**
72  * Process a local reply about info on all tunnels, pass info to the user.
73  *
74  * @param cls a `struct GNUNET_CADET_PeersLister`
75  * @param info Message itself.
76  */
77 static void
78 handle_get_peers (void *cls,
79                   const struct GNUNET_CADET_LocalInfoPeers *info)
80 {
81   struct GNUNET_CADET_PeersLister *pl = cls;
82   struct GNUNET_CADET_PeerListEntry ple;
83
84   ple.peer = info->destination;
85   ple.have_tunnel = (int) ntohs (info->tunnel);
86   ple.n_paths = (unsigned int) ntohs (info->paths);
87   ple.best_path_length = (unsigned int) ntohl (info->best_path_length);
88   pl->peers_cb (pl->peers_cb_cls,
89                 &ple);
90 }
91
92
93 /**
94  * Process a end of list reply about info on all peers.
95  *
96  * @param cls a `struct GNUNET_CADET_PeersLister`
97  * @param msg Message itself.
98  */
99 static void
100 handle_get_peers_end (void *cls,
101                       const struct GNUNET_MessageHeader *msg)
102 {
103   struct GNUNET_CADET_PeersLister *pl = cls;
104
105   (void) msg;
106
107   pl->peers_cb (pl->peers_cb_cls,
108                 NULL);
109   GNUNET_CADET_list_peers_cancel (pl);
110 }
111
112
113 /**
114  * Reconnect to the service and try again.
115  *
116  * @param cls a `struct GNUNET_CADET_PeersLister` operation
117  */
118 static void
119 reconnect (void *cls);
120
121
122 /**
123  * Function called on connection trouble.  Reconnects.
124  *
125  * @param cls a `struct GNUNET_CADET_PeersLister`
126  * @param error error code from MQ
127  */
128 static void
129 error_handler (void *cls,
130                enum GNUNET_MQ_Error error)
131 {
132   struct GNUNET_CADET_PeersLister *pl = cls;
133
134   GNUNET_MQ_destroy (pl->mq);
135   pl->mq = NULL;
136   pl->backoff = GNUNET_TIME_randomized_backoff (pl->backoff,
137                                                 GNUNET_TIME_UNIT_MINUTES);
138   pl->reconnect_task = GNUNET_SCHEDULER_add_delayed (pl->backoff,
139                                                      &reconnect,
140                                                      pl);
141 }
142
143
144 /**
145  * Reconnect to the service and try again.
146  *
147  * @param cls a `struct GNUNET_CADET_PeersLister` operation
148  */
149 static void
150 reconnect (void *cls)
151 {
152   struct GNUNET_CADET_PeersLister *pl = cls;
153   struct GNUNET_MQ_MessageHandler handlers[] = {
154     GNUNET_MQ_hd_fixed_size (get_peers,
155                              GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS,
156                              struct GNUNET_CADET_LocalInfoPeers,
157                              pl),
158     GNUNET_MQ_hd_fixed_size (get_peers_end,
159                              GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS_END,
160                              struct GNUNET_MessageHeader,
161                              pl),
162     GNUNET_MQ_handler_end ()
163   };
164   struct GNUNET_MessageHeader *msg;
165   struct GNUNET_MQ_Envelope *env;
166
167   pl->reconnect_task = NULL;
168   pl->mq = GNUNET_CLIENT_connect (pl->cfg,
169                                   "cadet",
170                                   handlers,
171                                   &error_handler,
172                                   pl);
173   if (NULL == pl->mq)
174     return;
175   env = GNUNET_MQ_msg (msg,
176                        GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_PEERS);
177   GNUNET_MQ_send (pl->mq,
178                   env);
179 }
180
181
182 /**
183  * Request information about peers known to the running cadet service.
184  * The callback will be called for every peer known to the service.
185  * Only one info request (of any kind) can be active at once.
186  *
187  * @param cfg configuration to use
188  * @param callback Function to call with the requested data.
189  * @param callback_cls Closure for @c callback.
190  * @return NULL on error
191  */
192 struct GNUNET_CADET_PeersLister *
193 GNUNET_CADET_list_peers (const struct GNUNET_CONFIGURATION_Handle *cfg,
194                          GNUNET_CADET_PeersCB callback,
195                          void *callback_cls)
196 {
197   struct GNUNET_CADET_PeersLister *pl;
198
199   if (NULL == callback)
200   {
201     GNUNET_break (0);
202     return NULL;
203   }
204   pl = GNUNET_new (struct GNUNET_CADET_PeersLister);
205   pl->peers_cb = callback;
206   pl->peers_cb_cls = callback_cls;
207   pl->cfg = cfg;
208   reconnect (pl);
209   if (NULL == pl->mq)
210   {
211     GNUNET_free (pl);
212     return NULL;
213   }
214   return pl;
215 }
216
217
218 /**
219  * Cancel a peer info request. The callback will not be called (anymore).
220  *
221  * @param pl operation handle
222  * @return Closure given to GNUNET_CADET_get_peers().
223  */
224 void *
225 GNUNET_CADET_list_peers_cancel (struct GNUNET_CADET_PeersLister *pl)
226 {
227   void *ret = pl->peers_cb_cls;
228
229   if (NULL != pl->mq)
230     GNUNET_MQ_destroy (pl->mq);
231   if (NULL != pl->reconnect_task)
232     GNUNET_SCHEDULER_cancel (pl->reconnect_task);
233   GNUNET_free (pl);
234   return ret;
235 }
236
237
238 /* end of cadet_api_list_peers.c */