starting with #5385 in earnest
[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 /**
131  * Request information about tunnels of the running cadet peer.
132  * The callback will be called for every tunnel of the service.
133  * Only one info request (of any kind) can be active at once.
134  *
135  * WARNING: unstable API, likely to change in the future!
136  *
137  * @param h Handle to the cadet peer.
138  * @param callback Function to call with the requested data.
139  * @param callback_cls Closure for @c callback.
140  * @return #GNUNET_OK / #GNUNET_SYSERR
141  */
142 int
143 GNUNET_CADET_list_tunnels (const struct GNUNET_CONFIGURATION_Handle *cfg,
144                            GNUNET_CADET_TunnelsCB callback,
145                            void *callback_cls)
146 {
147
148       GNUNET_MQ_hd_var_size (get_tunnels,
149                            GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS,
150                            struct GNUNET_MessageHeader,
151                            h),
152     GNUNET_MQ_hd_var_size (get_tunnel,
153                            GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL,
154                            struct GNUNET_CADET_LocalInfoTunnel,
155                            h),
156     GNUNET_MQ_handler_end ()
157
158   if (NULL != h->info_cb.tunnels_cb)
159   {
160     GNUNET_break (0);
161     return GNUNET_SYSERR;
162   }
163   send_info_request (h,
164                      GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS);
165   h->info_cb.tunnels_cb = callback;
166   h->info_cls = callback_cls;
167   return GNUNET_OK;
168 }
169
170
171 /**
172  * Cancel a monitor request. The monitor callback will not be called.
173  *
174  * @param h Cadet handle.
175  * @return Closure given to GNUNET_CADET_list_tunnels().
176  */
177 void *
178 GNUNET_CADET_list_tunnels_cancel (struct GNUNET_CADET_ListTunnels *lt)
179 {
180   void *cls = h->info_cls;
181
182   h->info_cb.tunnels_cb = NULL;
183   h->info_cls = NULL;
184   return cls;
185 }
186
187