fix log calls
[oweals/gnunet.git] / src / multicast / test_multicast_multipeer.c
1 /*
2  * This file is part of GNUnet
3  * Copyright (C) 2013 GNUnet e.V.
4  *
5  * GNUnet is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published
7  * by the Free Software Foundation; either version 3, or (at your
8  * 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  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with GNUnet; see the file COPYING.  If not, write to the
17  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20
21 /**
22  * @file multicast/test_multicast_multipeers.c
23  * @brief Tests for the Multicast API with multiple peers.
24  * @author xrs
25  */
26
27 #include <inttypes.h>
28
29 #include "platform.h"
30 #include "gnunet_crypto_lib.h"
31 #include "gnunet_common.h"
32 #include "gnunet_util_lib.h"
33 #include "gnunet_testbed_service.h"
34 #include "gnunet_multicast_service.h"
35
36 #define NUM_PEERS 2
37
38 static struct GNUNET_TESTBED_Operation *op0;
39 static struct GNUNET_TESTBED_Operation *op1;
40 static struct GNUNET_TESTBED_Peer **peers;
41
42 static struct GNUNET_SCHEDULER_Task *timeout_tid;
43
44 static struct GNUNET_MULTICAST_Origin *origin;
45
46 struct GNUNET_CRYPTO_EddsaPrivateKey *group_key;
47 struct GNUNET_CRYPTO_EddsaPublicKey group_pub_key;
48
49 struct GNUNET_CRYPTO_EcdsaPrivateKey *member_key;
50 struct GNUNET_CRYPTO_EcdsaPublicKey member_pub_key;
51
52
53 enum
54 {
55   TEST_INIT          = 0,
56   TEST_ORIGIN_START  = 1,
57   TEST_MEMBER_JOIN   = 2,
58 } test;
59
60
61 /**
62  * Global result for testcase.
63  */
64 static int result;
65
66
67 /**
68  * Function run on CTRL-C or shutdown (i.e. success/timeout/etc.).
69  * Cleans up.
70  */
71 static void
72 shutdown_task (void *cls)
73 {
74   if (NULL != op0)
75   {
76     GNUNET_TESTBED_operation_done (op0);
77     op0 = NULL;
78   }
79   if (NULL != op1)
80   {
81     GNUNET_TESTBED_operation_done (op1);
82     op1 = NULL;
83   }
84   if (NULL != timeout_tid)
85     {
86       GNUNET_SCHEDULER_cancel (timeout_tid);
87       timeout_tid = NULL;
88     }
89 }
90
91
92 static void
93 timeout_task (void *cls)
94 {
95   timeout_tid = NULL;
96   GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
97               "Timeout!\n");
98   result = GNUNET_SYSERR;
99   GNUNET_SCHEDULER_shutdown ();
100 }
101
102 static void
103 pi_cb (void *cls,
104        struct GNUNET_TESTBED_Operation *op,
105        const struct GNUNET_TESTBED_PeerInformation *pinfo,
106        const char *emsg)
107 {
108 }
109
110 static void 
111 member_join_request (void *cls,
112                      const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key,
113                      const struct GNUNET_MessageHeader *join_msg,
114                      struct GNUNET_MULTICAST_JoinHandle *jh)
115 {
116   GNUNET_log (GNUNET_ERROR_TYPE_INFO, 
117               "Member sent a join request.");
118   
119 }
120
121
122 static void 
123 member_join_decision (void *cls,
124                       int is_admitted,
125                       const struct GNUNET_PeerIdentity *peer,
126                       uint16_t relay_count,
127                       const struct GNUNET_PeerIdentity *relays,
128                       const struct GNUNET_MessageHeader *join_msg)
129 {
130   GNUNET_log (GNUNET_ERROR_TYPE_INFO, 
131               "Member received a decision from origin: ...");
132   
133 }
134
135 static void 
136 member_replay_frag ()
137 {
138   GNUNET_log (GNUNET_ERROR_TYPE_INFO, 
139               "member replay frag...");
140 }
141
142 static void 
143 member_replay_msg () 
144 {
145   GNUNET_log (GNUNET_ERROR_TYPE_INFO, 
146               "member replay msg...");
147 }
148
149 static void 
150 member_message () 
151 {
152   GNUNET_log (GNUNET_ERROR_TYPE_INFO, 
153               "member message...");
154 }
155
156 static void 
157 origin_join_request (void *cls,
158                  const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key,
159                  const struct GNUNET_MessageHeader *join_msg,
160                  struct GNUNET_MULTICAST_JoinHandle *jh) 
161 {
162   GNUNET_log (GNUNET_ERROR_TYPE_INFO, 
163               "yey, got a join request. Let's see who it is.");
164
165   result = GNUNET_OK;
166 }
167
168 static void 
169 origin_replay_frag (void *cls,
170                 const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key,
171                 uint64_t fragment_id,
172                 uint64_t flags,
173                 struct GNUNET_MULTICAST_ReplayHandle *rh)
174 {
175   
176 }
177
178 static void 
179 origin_replay_msg (void *cls,
180                const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key,
181                uint64_t message_id,
182                uint64_t fragment_offset,
183                uint64_t flags,
184                struct GNUNET_MULTICAST_ReplayHandle *rh) 
185 {
186   
187   GNUNET_log (GNUNET_ERROR_TYPE_INFO, "origin replay msg\n");
188 }
189
190 static void
191 origin_request (void *cls,
192             const struct GNUNET_MULTICAST_RequestHeader *req)
193 {
194   GNUNET_log (GNUNET_ERROR_TYPE_INFO, "origin request msg\n");
195   
196 }
197
198 static void
199 origin_message (void *cls,
200             const struct GNUNET_MULTICAST_MessageHeader *msg) 
201 {
202 }
203
204
205 static void
206 service_connect1 (void *cls,
207                   struct GNUNET_TESTBED_Operation *op,
208                   void *ca_result,
209                   const char *emsg)
210 {
211   struct GNUNET_MULTICAST_Member *member = ca_result; 
212
213   if (NULL != member)
214     GNUNET_log (GNUNET_ERROR_TYPE_INFO, "connected to multicast service of member\n");
215   else 
216     result = GNUNET_SYSERR;
217 }
218
219 static void
220 multicast_da1 (void *cls,
221                void * op_result)
222 {
223   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
224               "disconnecting from multicast service of member\n");
225 }
226
227
228 static void *
229 multicast_ca1 (void *cls,
230                const struct GNUNET_CONFIGURATION_Handle *cfg)
231 {
232   struct GNUNET_MessageHeader *join_msg;
233   const struct GNUNET_PeerIdentity *peer_id_origin;
234   struct GNUNET_HashCode pub_hash;
235   
236   GNUNET_log (GNUNET_ERROR_TYPE_INFO, "connecting to multicast service of member...\n");
237   
238   // Get members keys
239   member_key = GNUNET_CRYPTO_ecdsa_key_create ();
240   GNUNET_CRYPTO_ecdsa_key_get_public (member_key, &member_pub_key);
241   
242   // Get GNUnet identity of origin
243   peer_id_origin = GNUNET_TESTBED_peer_get_information (peers[0],
244                                                 GNUNET_TESTBED_PIT_IDENTITY,
245                                                 pi_cb,
246                                                 NULL);
247
248   GNUNET_assert(NULL != peer_id_origin);
249
250   GNUNET_CRYPTO_hash (&peer_id_origin, sizeof (peer_id_origin), &pub_hash);
251   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
252               "member: id of origin is %s\n",
253               GNUNET_h2s (&pub_hash));
254   
255   char data[] = "Hello Mr. Smith!";
256   uint8_t data_size = strlen (data) + 1;
257   join_msg = GNUNET_malloc (sizeof (join_msg) + data_size);
258   join_msg->size = htons (sizeof (join_msg) + data_size);
259   join_msg->type = htons (123);
260   GNUNET_memcpy (&join_msg[1], data, data_size);
261   
262   return GNUNET_MULTICAST_member_join (cfg,
263                                        &group_pub_key,
264                                        member_key,
265                                        peer_id_origin,
266                                        0,
267                                        NULL,
268                                        join_msg, /* join message */
269                                        member_join_request,
270                                        member_join_decision,
271                                        member_replay_frag,
272                                        member_replay_msg,
273                                        member_message,
274                                        NULL);
275 }
276
277
278 /**
279  * Test logic of peer "0" being origin starts here.
280  *
281  * @param cls closure, for the example: NULL
282  * @param op should be equal to "dht_op"
283  * @param ca_result result of the connect operation, the
284  *        connection to the DHT service
285  * @param emsg error message, if testbed somehow failed to
286  *        connect to the DHT.
287  */
288 static void
289 service_connect0 (void *cls,
290                   struct GNUNET_TESTBED_Operation *op,
291                   void *ca_result,
292                   const char *emsg)
293 {
294   struct GNUNET_MULTICAST_Origin *origin = ca_result;
295
296   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
297               "connected to multicast service of origin\n");
298
299   /* Connection to service successful. Here we'd usually do something with
300    * the service. */
301   result = GNUNET_OK;
302   //GNUNET_SCHEDULER_shutdown (); /* Also kills the testbed */
303 }
304
305
306
307 /**
308  * Function run when service multicast has started and is providing us
309  * with a configuration file.
310  */
311 static void * 
312 multicast_ca0 (void *cls,
313                const struct GNUNET_CONFIGURATION_Handle *cfg)
314 {
315   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
316               "connecting to multicast service of origin...\n");
317               
318   group_key = GNUNET_CRYPTO_eddsa_key_create ();
319   GNUNET_CRYPTO_eddsa_key_get_public (group_key, &group_pub_key);
320               
321   return GNUNET_MULTICAST_origin_start (cfg,
322                                         group_key,
323                                         0,
324                                         origin_join_request,
325                                         origin_replay_frag,
326                                         origin_replay_msg,
327                                         origin_request,
328                                         origin_message,
329                                         NULL);
330 }
331
332 static void
333 multicast_da0 (void *cls,
334                void *op_result)
335 {
336   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
337               "disconnecting from multicast service of origin\n");
338
339 }
340
341 /**
342  * Main function inovked from TESTBED once all of the
343  * peers are up and running.  This one then connects
344  * just to the multicast service of peer 0 and 1.
345  * Peer 0 is going to be origin.
346  * Peer 1 is going to be one member.
347  * Origin will start a multicast group and the member will try to join it.
348  * After that we execute some multicast test.
349  *
350  * @param cls closure
351  * @param h the run handle
352  * @param peers started peers for the test
353  * @param num_peers size of the 'peers' array
354  * @param links_succeeded number of links between peers that were created
355  * @param links_failed number of links testbed was unable to establish
356  */
357 static void
358 testbed_master (void *cls,
359      struct GNUNET_TESTBED_RunHandle *h,
360      unsigned int num_peers,
361      struct GNUNET_TESTBED_Peer **p,
362      unsigned int links_succeeded,
363      unsigned int links_failed)
364 {
365   /* Testbed is ready with peers running and connected in a pre-defined overlay
366      topology (FIXME)  */
367      
368   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
369               "connected to testbed_master()\n");
370               
371   peers = p;
372
373   /* connect to a peers service */
374   op0 = GNUNET_TESTBED_service_connect
375       (NULL,                    /* Closure for operation */
376        peers[0],                /* The peer whose service to connect to */
377        "multicast",             /* The name of the service */
378        service_connect0,   /* callback to call after a handle to service
379                                    is opened */
380        NULL,                    /* closure for the above callback */
381        multicast_ca0,      /* callback to call with peer's configuration;
382                                    this should open the needed service connection */
383        multicast_da0,     /* callback to be called when closing the
384                                    opened service connection */
385        NULL);                   /* closure for the above two callbacks */
386   
387   op1 = GNUNET_TESTBED_service_connect
388       (NULL,                    /* Closure for operation */
389        peers[1],                /* The peer whose service to connect to */
390        "multicast",             /* The name of the service */
391        service_connect1,   /* callback to call after a handle to service
392                                    is opened */
393        NULL,                    /* closure for the above callback */
394        multicast_ca1,      /* callback to call with peer's configuration;
395                                    this should open the needed service connection */
396        multicast_da1,     /* callback to be called when closing the
397                                    opened service connection */
398        NULL);                   /* closure for the above two callbacks */
399   
400   GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); /* Schedule a new task on shutdown */
401   
402   /* Schedule the shutdown task with a delay of a few 1econds */
403   timeout_tid = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 3),
404                                               &timeout_task, NULL);
405 }
406
407
408 int
409 main (int argc, char *argv[])
410 {
411   int ret;
412
413   result = GNUNET_SYSERR;
414   ret = GNUNET_TESTBED_test_run
415       ("test-multicast-multipeer",  /* test case name */
416        "test_multicast.conf", /* template configuration */
417        NUM_PEERS,       /* number of peers to start */
418        0LL, /* Event mask - set to 0 for no event notifications */
419        NULL, /* Controller event callback */
420        NULL, /* Closure for controller event callback */
421        testbed_master, /* continuation callback to be called when testbed setup is complete */
422        NULL); /* Closure for the test_master callback */
423   if ( (GNUNET_OK != ret) || (GNUNET_OK != result) )
424     return 1;
425   return 0;
426 }
427
428 /* end of test_multicast_multipeer.c */