more work on 5385
[oweals/gnunet.git] / src / cadet / cadet_api_list_tunnels.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_ListTunnels
39 {
40
41   /**
42    * Monitor callback
43    */
44   GNUNET_CADET_TunnelsCB tunnels_cb;
45
46   /**
47    * Info callback closure for @c tunnels_cb.
48    */
49   void *tunnels_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_tunnels (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_LocalInfoTunnel) == 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 message Message itself.
102  */
103 static void
104 handle_get_tunnels (void *cls,
105                     const struct GNUNET_MessageHeader *msg)
106 {
107   struct GNUNET_CADET_Handle *h = cls;
108   const struct GNUNET_CADET_LocalInfoTunnel *info =
109     (const struct GNUNET_CADET_LocalInfoTunnel *) msg;
110
111   if (NULL == h->info_cb.tunnels_cb)
112     return;
113   if (sizeof (struct GNUNET_CADET_LocalInfoTunnel) == ntohs (msg->size))
114     h->info_cb.tunnels_cb (h->info_cls,
115                            &info->destination,
116                            ntohl (info->channels),
117                            ntohl (info->connections),
118                            ntohs (info->estate),
119                            ntohs (info->cstate));
120   else
121     h->info_cb.tunnels_cb (h->info_cls,
122                            NULL,
123                            0,
124                            0,
125                            0,
126                            0);
127 }
128
129
130 static void
131 reconnect (void *cls)
132 {
133   struct GNUNET_CADET_ListTunnels *lt = cls;
134   struct GNUNET_MQ_MessageHandler *handlers[] = {
135     GNUNET_MQ_hd_var_size (get_tunnels,
136                            GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS,
137                            struct GNUNET_MessageHeader,
138                            h),
139     GNUNET_MQ_handler_end ()
140   }
141   struct GNUNET_MessageHeader *msg;
142   struct GNUNET_MQ_Envelope *env;
143
144   cm->mq = GNUNET_CLIENT_connect (cm->cfg,
145                                   "cadet",
146                                   handlers,
147                                   &error_handler,
148                                   cm);
149                                  
150   env = GNUNET_MQ_msg (msg,
151                        type);
152   GNUNET_MQ_send (cm->mq,
153                   env);
154 }
155
156
157 /**
158  * Request information about tunnels of the running cadet peer.
159  * The callback will be called for every tunnel of the service.
160  * Only one info request (of any kind) can be active at once.
161  *
162  * WARNING: unstable API, likely to change in the future!
163  *
164  * @param h Handle to the cadet peer.
165  * @param callback Function to call with the requested data.
166  * @param callback_cls Closure for @c callback.
167  * @return #GNUNET_OK / #GNUNET_SYSERR
168  */
169 struct GNUNET_CADET_ListTunnels *
170 GNUNET_CADET_list_tunnels (const struct GNUNET_CONFIGURATION_Handle *cfg,
171                            GNUNET_CADET_TunnelsCB callback,
172                            void *callback_cls)
173 {
174
175   if (NULL != h->info_cb.tunnels_cb)
176   {
177     GNUNET_break (0);
178     return GNUNET_SYSERR;
179   }
180   send_info_request (h,
181                      GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS);
182   h->info_cb.tunnels_cb = callback;
183   h->info_cls = callback_cls;
184   return GNUNET_OK;
185 }
186
187
188 /**
189  * Cancel a monitor request. The monitor callback will not be called.
190  *
191  * @param h Cadet 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 *cls = h->info_cls;
198
199   h->info_cb.tunnels_cb = NULL;
200   h->info_cls = NULL;
201   return cls;
202 }
203
204