fix ftbfs
[oweals/gnunet.git] / src / transport / transport-testing2.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 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 /**
22  * @file transport/transport-testing2.c
23  * @brief functions related to testing-tng
24  * @author Christian Grothoff
25  * @author Julius Bünger
26  */
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
29 #include "gnunet_protocols.h"
30 #include "gnunet_constants.h"
31 #include "transport-testing2.h"
32 #include "gnunet_ats_transport_service.h"
33 #include "gnunet_signatures.h"
34 #include "transport.h"
35
36
37 #define LOG(kind,...) GNUNET_log_from (kind, "transport-testing2", __VA_ARGS__)
38
39
40 struct GNUNET_TRANSPORT_TESTING_TransportCommunicatorHandle
41 {
42   /**
43    * @brief Handle to the configuration
44    */
45   struct GNUNET_CONFIGURATION_Handle *cfg;
46
47   /**
48    * @brief File name of configuration file
49    */
50   char *cfg_filename;
51
52   /**
53    * @brief Handle to the transport service
54    */
55   struct GNUNET_SERVICE_Handle *tsh;
56
57   /**
58    * @brief Task that will be run on shutdown to stop and clean transport
59    * service
60    */
61   struct GNUNET_SCHEDULER_Task *ts_shutdown_task;
62
63   /**
64    * @brief Handle to the client
65    */
66   struct GNUNET_SERVICE_Client *client;
67
68   /**
69    * @brief Process of the communicator
70    */
71   struct GNUNET_OS_Process *c_proc;
72
73   /**
74    * @brief Task that will be run on shutdown to stop and clean communicator
75    */
76   struct GNUNET_SCHEDULER_Task *c_shutdown_task;
77
78   /* Callbacks + Closures */
79   /**
80    * @brief Callback called when a new communicator connects
81    */
82   GNUNET_TRANSPORT_TESTING_CommunicatorAvailableCallback communicator_available;
83
84   /**
85    * @brief Closure to the callback
86    */
87   void *communicator_available_cls;
88 };
89
90
91 /**
92  * @brief Check whether incoming msg indicating available communicator is
93  * correct
94  *
95  * @param cls Closure
96  * @param msg Message struct
97  *
98  * @return GNUNET_YES in case message is correct
99  */
100 static int
101 check_communicator_available (void *cls,
102     const struct GNUNET_TRANSPORT_CommunicatorAvailableMessage *msg)
103 {
104   uint16_t size;
105
106   size = ntohs (msg->header.size) - sizeof (*msg);
107   if (0 == size)
108     return GNUNET_OK; /* receive-only communicator */
109   GNUNET_MQ_check_zero_termination (msg);
110   return GNUNET_OK;
111 }
112
113
114 /**
115  * @brief Handle new communicator
116  *
117  * @param cls Closure
118  * @param msg Message struct
119  */
120 static void
121 handle_communicator_available (void *cls,
122     const struct GNUNET_TRANSPORT_CommunicatorAvailableMessage *msg)
123 {
124   struct GNUNET_TRANSPORT_TESTING_TransportCommunicatorHandle *tc_h = cls;
125   uint16_t size;
126
127   size = ntohs (msg->header.size) - sizeof (*msg);
128   if (0 == size)
129     return; /* receive-only communicator */
130   if (NULL != tc_h->communicator_available)
131   {
132     LOG (GNUNET_ERROR_TYPE_DEBUG,
133         "calling communicator_available()\n");
134     tc_h->communicator_available (tc_h->communicator_available_cls, msg);
135   }
136   GNUNET_SERVICE_client_continue (tc_h->client);
137 }
138
139
140 /**
141  * @brief Shut down the service
142  *
143  * @param cls Closure - Handle to the service
144  */
145 static void
146 shutdown_service (void *cls)
147 {
148   struct GNUNET_SERVICE_Handle *h = cls;
149
150   GNUNET_SERVICE_stop (h);
151 }
152
153
154 /**
155  * @brief Callback called when new Client (Communicator) connects
156  *
157  * @param cls Closure - TransporCommmunicator Handle
158  * @param client Client
159  * @param mq Messagequeue
160  *
161  * @return TransportCommunicator Handle
162  */
163 static void *
164 connect_cb (void *cls,
165             struct GNUNET_SERVICE_Client *client,
166             struct GNUNET_MQ_Handle *mq)
167 {
168   struct GNUNET_TRANSPORT_TESTING_TransportCommunicatorHandle *tc_h = cls;
169
170   LOG (GNUNET_ERROR_TYPE_DEBUG,
171       "Client connected.\n");
172   tc_h->client = client;
173   return tc_h;
174 }
175
176
177 /**
178  * @brief Callback called when Client disconnects
179  *
180  * @param cls Closure - TransportCommunicator Handle
181  * @param client Client
182  * @param internal_cls TransporCommmunicator Handle
183  */
184 static void
185 disconnect_cb (void *cls,
186                struct GNUNET_SERVICE_Client *client,
187                void *internal_cls)
188 {
189   struct GNUNET_TRANSPORT_TESTING_TransportCommunicatorHandle *tc_h = cls;
190
191   LOG (GNUNET_ERROR_TYPE_DEBUG,
192       "Client disconnected.\n");
193   tc_h->client = NULL;
194 }
195
196
197 /**
198  * @brief Start the communicator part of the transport service
199  *
200  * @param communicator_available Callback to be called when a new communicator
201  * becomes available
202  * @param cfg Configuration
203  */
204 static void
205 transport_communicator_start (struct GNUNET_TRANSPORT_TESTING_TransportCommunicatorHandle *tc_h)
206 {
207   struct GNUNET_MQ_MessageHandler mh[] = {
208     GNUNET_MQ_hd_var_size (communicator_available,
209         GNUNET_MESSAGE_TYPE_TRANSPORT_NEW_COMMUNICATOR,
210         struct GNUNET_TRANSPORT_CommunicatorAvailableMessage,
211         &tc_h),
212     //GNUNET_MQ_hd_var_size (communicator_backchannel,
213     //    GNUNET_MESSAGE_TYPE_TRANSPORT_COMMUNICATOR_BACKCHANNEL,
214     //    struct GNUNET_TRANSPORT_CommunicatorBackchannel,
215     //    NULL),
216     //GNUNET_MQ_hd_var_size (add_address,
217     //    GNUNET_MESSAGE_TYPE_TRANSPORT_ADD_ADDRESS,
218     //    struct GNUNET_TRANSPORT_AddAddressMessage,
219     //    NULL),
220     //GNUNET_MQ_hd_fixed_size (del_address,
221     //                         GNUNET_MESSAGE_TYPE_TRANSPORT_DEL_ADDRESS,
222     //                         struct GNUNET_TRANSPORT_DelAddressMessage,
223     //                         NULL),
224     //GNUNET_MQ_hd_var_size (incoming_msg,
225     //    GNUNET_MESSAGE_TYPE_TRANSPORT_INCOMING_MSG,
226     //    struct GNUNET_TRANSPORT_IncomingMessage,
227     //    NULL),
228     //GNUNET_MQ_hd_fixed_size (queue_create_ok,
229     //      GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_CREATE_OK,
230     //      struct GNUNET_TRANSPORT_CreateQueueResponse,
231     //      NULL),
232     //GNUNET_MQ_hd_fixed_size (queue_create_fail,
233     //      GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_CREATE_FAIL,
234     //      struct GNUNET_TRANSPORT_CreateQueueResponse,
235     //      NULL),
236     //GNUNET_MQ_hd_var_size (add_queue_message,
237     //    GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_SETUP,
238     //    struct GNUNET_TRANSPORT_AddQueueMessage,
239     //    NULL),
240     //GNUNET_MQ_hd_fixed_size (del_queue_message,
241     //                         GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_TEARDOWN,
242     //                         struct GNUNET_TRANSPORT_DelQueueMessage,
243     //                         NULL),
244     //GNUNET_MQ_hd_fixed_size (send_message_ack,
245     //                         GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_MSG_ACK,
246     //                         struct GNUNET_TRANSPORT_SendMessageToAck,
247     //                         NULL),
248   };
249   struct GNUNET_SERVICE_Handle *h;
250
251   h = GNUNET_SERVICE_start ("transport",
252                             tc_h->cfg,
253                             &connect_cb,
254                             &disconnect_cb,
255                             tc_h,
256                             mh);
257   if (NULL == h)
258     LOG (GNUNET_ERROR_TYPE_ERROR,
259          "Failed starting service!\n");
260   else
261   {
262     LOG (GNUNET_ERROR_TYPE_DEBUG,
263         "Started service\n");
264     /* TODO */ GNUNET_SCHEDULER_add_shutdown (&shutdown_service, h);
265   }
266 }
267
268
269 /**
270  * @brief Task run at shutdown to kill communicator and clean up
271  *
272  * @param cls Closure - Process of communicator
273  */
274 static void
275 shutdown_communicator (void *cls)
276 {
277   struct GNUNET_OS_Process *proc = cls;
278
279   if (GNUNET_OK != GNUNET_OS_process_kill (proc,
280                                            SIGTERM))
281   {
282     LOG (GNUNET_ERROR_TYPE_WARNING,
283         "Error shutting down communicator with SIGERM, trying SIGKILL\n");
284     if (GNUNET_OK != GNUNET_OS_process_kill (proc,
285                                              SIGKILL))
286     {
287       LOG (GNUNET_ERROR_TYPE_ERROR,
288           "Error shutting down communicator with SIGERM and SIGKILL\n");
289     }
290   }
291   GNUNET_OS_process_destroy (proc);
292 }
293
294
295 /**
296  * @brief Start the communicator
297  *
298  * @param cfgname Name of the communicator
299  */
300 static void
301 communicator_start (struct GNUNET_TRANSPORT_TESTING_TransportCommunicatorHandle *tc_h)
302 {
303   char *binary;
304
305   LOG (GNUNET_ERROR_TYPE_DEBUG,
306       "communicator_start\n");
307   binary = GNUNET_OS_get_libexec_binary_path ("gnunet-communicator-unix");
308   tc_h->c_proc =
309     GNUNET_OS_start_process (GNUNET_YES,
310                              GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
311                              NULL, NULL, NULL,
312                              binary,
313                              "./gnunet-communicator-unix",
314                              "-c",
315                              tc_h->cfg_filename,
316                              NULL);
317   if (NULL == tc_h->c_proc)
318   {
319     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
320                 "Failed to start communicator!");
321     return;
322   }
323   LOG (GNUNET_ERROR_TYPE_DEBUG,
324       "started communicator\n");
325   GNUNET_free (binary);
326   /* TODO */ GNUNET_SCHEDULER_add_shutdown (&shutdown_communicator,
327                                             tc_h->c_proc);
328 }
329
330
331 /**
332  * @brief Start communicator part of transport service and communicator
333  *
334  * @param service_name Name of the service
335  * @param cfg Configuration handle
336  * @param communicator_available Callback that is called when a new
337  * communicator becomes available
338  * @param cb_cls Closure to @p communicator_available
339  *
340  * @return Handle to the communicator duo
341  */
342 struct GNUNET_TRANSPORT_TESTING_TransportCommunicatorHandle *
343 GNUNET_TRANSPORT_TESTING_transport_communicator_service_start
344   (const char *service_name,
345    const char *cfg_filename,
346    GNUNET_TRANSPORT_TESTING_CommunicatorAvailableCallback communicator_available,
347    //GNUNET_TRANSPORT_TESTING_Callback2 cb2,
348    //GNUNET_TRANSPORT_TESTING_Callback3 cb3,
349    //GNUNET_TRANSPORT_TESTING_Callback4 cb4,
350    void *cb_cls)
351 {
352   struct GNUNET_TRANSPORT_TESTING_TransportCommunicatorHandle *tc_h;
353
354   tc_h = GNUNET_new (struct GNUNET_TRANSPORT_TESTING_TransportCommunicatorHandle);
355   tc_h->cfg_filename = GNUNET_strdup (cfg_filename);
356   tc_h->cfg = GNUNET_CONFIGURATION_create ();
357   if ( (GNUNET_SYSERR ==
358         GNUNET_CONFIGURATION_load (tc_h->cfg,
359                                    cfg_filename)) )
360   {
361     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
362                 _("Malformed configuration file `%s', exit ...\n"),
363                   cfg_filename);
364     return NULL;
365   }
366   tc_h->communicator_available = communicator_available;
367   tc_h->communicator_available_cls = cb_cls;
368
369   /* Start communicator part of service */
370   transport_communicator_start (tc_h);
371
372   /* Schedule start communicator */
373   communicator_start (tc_h);
374   return tc_h;
375 }
376
377 //void
378 //GNUNET_TRANSPORT_TESTING_transport_communicator_open_queue
379 //  (struct GNUNET_TRANSPORT_TESTING_TransportCommunicatorHandle *tch,
380 //   const char *address);
381 //
382 //struct GNUNET_TRANSPORT_TESTING_TransportCommunicatorTransmission *
383 //GNUNET_TRANSPORT_TESTING_transport_communicator_send
384 //  (struct GNUNET_TRANSPORT_TESTING_TransportCommunicatorQueue *tcq,
385 //   const struct GNUNET_MessageHeader *hdr,
386 //   GNUNET_TRANSPORT_TESTING_SuccessStatus cb, void *cb_cls);
387