f6563a290b5f2405a3ad783e2f8a94a9722bb041
[oweals/gnunet.git] / src / cadet / cadet_api_list_peers.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2011, 2017 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.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 /**
36  * Ugly legacy hack.
37  */
38 struct GNUNET_CADET_PeersLister
39 {
40
41   /**
42    * Monitor callback
43    */
44   GNUNET_CADET_PeersCB peers_cb;
45
46   /**
47    * Info callback closure for @c info_cb.
48    */
49   void *peers_cb_cls;
50 };
51
52
53 /**
54  * Send message of @a type to CADET service of @a h
55  *
56  * @param h handle to CADET service
57  * @param type message type of trivial information request to send
58  */
59 static void
60 send_info_request (struct GNUNET_CADET_Handle *h,
61                    uint16_t type)
62 {
63   struct GNUNET_MessageHeader *msg;
64   struct GNUNET_MQ_Envelope *env;
65
66   env = GNUNET_MQ_msg (msg,
67                        type);
68   GNUNET_MQ_send (h->mq,
69                   env);
70 }
71
72
73 /**
74  * Check that message received from CADET service is well-formed.
75  *
76  * @param cls the `struct GNUNET_CADET_Handle`
77  * @param message the message we got
78  * @return #GNUNET_OK if the message is well-formed,
79  *         #GNUNET_SYSERR otherwise
80  */
81 static int
82 check_get_peers (void *cls,
83                  const struct GNUNET_MessageHeader *message)
84 {
85   size_t esize;
86
87   (void) cls;
88   esize = ntohs (message->size);
89   if (sizeof (struct GNUNET_CADET_LocalInfoPeer) == esize)
90     return GNUNET_OK;
91   if (sizeof (struct GNUNET_MessageHeader) == esize)
92     return GNUNET_OK;
93   return GNUNET_SYSERR;
94 }
95
96
97 /**
98  * Process a local reply about info on all tunnels, pass info to the user.
99  *
100  * @param cls Closure (Cadet handle).
101  * @param msg Message itself.
102  */
103 static void
104 handle_get_peers (void *cls,
105                   const struct GNUNET_MessageHeader *msg)
106 {
107   struct GNUNET_CADET_Handle *h = cls;
108   const struct GNUNET_CADET_LocalInfoPeer *info =
109     (const struct GNUNET_CADET_LocalInfoPeer *) msg;
110
111   if (NULL == h->info_cb.peers_cb)
112     return;
113   if (sizeof (struct GNUNET_CADET_LocalInfoPeer) == ntohs (msg->size))
114     h->info_cb.peers_cb (h->info_cls,
115                          &info->destination,
116                          (int) ntohs (info->tunnel),
117                          (unsigned int) ntohs (info->paths),
118                          0);
119   else
120     h->info_cb.peers_cb (h->info_cls,
121                          NULL,
122                          0,
123                          0,
124                          0);
125 }
126
127
128 static void
129 reconnect (void *cls)
130 {
131   struct GNUNET_CADET_ListTunnels *lt = cls;
132   struct GNUNET_MQ_MessageHandler *handlers[] = {
133      GNUNET_MQ_hd_var_size (get_peers,
134                            GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS,
135                            struct GNUNET_MessageHeader,
136                            h),
137     GNUNET_MQ_handler_end ()
138   }
139   struct GNUNET_MessageHeader *msg;
140   struct GNUNET_MQ_Envelope *env;
141
142   cm->mq = GNUNET_CLIENT_connect (cm->cfg,
143                                   "cadet",
144                                   handlers,
145                                   &error_handler,
146                                   cm);
147                                  
148   env = GNUNET_MQ_msg (msg,
149                        type);
150   GNUNET_MQ_send (cm->mq,
151                   env);
152 }
153
154
155 /**
156  * Request information about peers known to the running cadet service.
157  * The callback will be called for every peer known to the service.
158  * Only one info request (of any kind) can be active at once.
159  *
160  * WARNING: unstable API, likely to change in the future!
161  *
162  * @param h Handle to the cadet peer.
163  * @param callback Function to call with the requested data.
164  * @param callback_cls Closure for @c callback.
165  * @return #GNUNET_OK / #GNUNET_SYSERR
166  */
167 struct GNUNET_CADET_PeersLister *
168 GNUNET_CADET_list_peers (const struct GNUNET_CONFIGURATION_Handle *cfg,
169                          GNUNET_CADET_PeersCB callback,
170                          void *callback_cls)
171 {
172   if (NULL != h->info_cb.peers_cb)
173   {
174     GNUNET_break (0);
175     return GNUNET_SYSERR;
176   }
177   send_info_request (h,
178                      GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS);
179   h->info_cb.peers_cb = callback;
180   h->info_cls = callback_cls;
181   return GNUNET_OK;
182 }
183
184
185 /**
186  * Cancel a peer info request. The callback will not be called (anymore).
187  *
188  * WARNING: unstable API, likely to change in the future!
189  *
190  * @param h Cadet handle.
191  * @return Closure given to GNUNET_CADET_get_peers().
192  */
193 void *
194 GNUNET_CADET_list_peers_cancel (struct GNUNET_CADET_PeersLister *pl)
195 {
196   void *cls = h->info_cls;
197
198   h->info_cb.peers_cb = NULL;
199   h->info_cls = NULL;
200   return cls;
201 }
202
203
204
205
206