- fixes, debug
[oweals/gnunet.git] / src / mesh / test_mesh2_local.c
1 /*
2      This file is part of GNUnet.
3      (C) 2011 Christian Grothoff (and other contributing authors)
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., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21 /**
22  * @file mesh/test_mesh2_local.c
23  * @brief test mesh2 local: test of mesh2 tunnels with just one peer
24  * @author Bartlomiej Polot
25  */
26
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
29 #include "gnunet_dht_service.h"
30 #include "gnunet_testing_lib.h"
31 #include "gnunet_mesh2_service.h"
32
33 struct GNUNET_TESTING_Peer *me;
34
35 static struct GNUNET_MESH_Handle *mesh_peer_1;
36
37 static struct GNUNET_MESH_Handle *mesh_peer_2;
38
39 static struct GNUNET_MESH_Tunnel *t;
40
41 static int result = GNUNET_OK;
42
43 static GNUNET_SCHEDULER_TaskIdentifier abort_task;
44
45 static GNUNET_SCHEDULER_TaskIdentifier shutdown_task;
46
47
48 /**
49  * Shutdown nicely
50  */
51 static void
52 do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
53 {
54   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: shutdown\n");
55   if (0 != abort_task)
56   {
57     GNUNET_SCHEDULER_cancel (abort_task);
58   }
59   if (NULL != t)
60   {
61     GNUNET_MESH_tunnel_destroy(t);
62   }
63   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: D1\n");
64   if (NULL != mesh_peer_1)
65   {
66     GNUNET_MESH_disconnect (mesh_peer_1);
67   }
68   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: D2\n");
69   if (NULL != mesh_peer_2)
70   {
71     GNUNET_MESH_disconnect (mesh_peer_2);
72   }
73 }
74
75
76 /**
77  * Something went wrong and timed out. Kill everything and set error flag
78  */
79 static void
80 do_abort (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
81 {
82   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: ABORT\n");
83   result = GNUNET_SYSERR;
84   abort_task = GNUNET_SCHEDULER_NO_TASK;
85   if (GNUNET_SCHEDULER_NO_TASK != shutdown_task)
86   {
87     GNUNET_SCHEDULER_cancel (shutdown_task);
88     shutdown_task = GNUNET_SCHEDULER_NO_TASK;
89   }
90   do_shutdown (cls, tc);
91 }
92
93
94 /**
95  * Function is called whenever a message is received.
96  *
97  * @param cls closure (set from GNUNET_MESH_connect)
98  * @param tunnel connection to the other end
99  * @param tunnel_ctx place to store local state associated with the tunnel
100  * @param sender who sent the message
101  * @param message the actual message
102  * 
103  * @return GNUNET_OK to keep the connection open,
104  *         GNUNET_SYSERR to close it (signal serious error)
105  */
106 static int
107 data_callback (void *cls, struct GNUNET_MESH_Tunnel *tunnel, void **tunnel_ctx,
108                const struct GNUNET_PeerIdentity *sender,
109                const struct GNUNET_MessageHeader *message)
110 {
111   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Data callback\n");
112   if (GNUNET_SCHEDULER_NO_TASK != shutdown_task)
113     GNUNET_SCHEDULER_cancel (shutdown_task);
114   shutdown_task =
115     GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &do_shutdown,
116                                   NULL);
117   GNUNET_MESH_receive_done (tunnel);
118   return GNUNET_OK;
119 }
120
121
122 /**
123  * Method called whenever another peer has added us to a tunnel
124  * the other peer initiated.
125  *
126  * @param cls closure
127  * @param tunnel new handle to the tunnel
128  * @param initiator peer that started the tunnel
129  * @param port port number
130  * @return initial tunnel context for the tunnel (can be NULL -- that's not an error)
131  */
132 static void *
133 inbound_tunnel (void *cls, struct GNUNET_MESH_Tunnel *tunnel,
134                 const struct GNUNET_PeerIdentity *initiator,
135                 uint32_t port)
136 {
137   long id = (long) cls;
138
139   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
140               "test: received incoming tunnel on peer %d, port %u\n",
141               id, port);
142   if (id != 2L)
143   {
144     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
145                 "test: wrong peer\n");
146     result = GNUNET_SYSERR;
147   }
148   return NULL;
149 }
150
151
152 /**
153  * Function called whenever an inbound tunnel is destroyed.  Should clean up
154  * any associated state.
155  *
156  * @param cls closure (set from GNUNET_MESH_connect)
157  * @param tunnel connection to the other end (henceforth invalid)
158  * @param tunnel_ctx place where local state associated
159  *                   with the tunnel is stored
160  */
161 static void
162 inbound_end (void *cls, const struct GNUNET_MESH_Tunnel *tunnel,
163              void *tunnel_ctx)
164 {
165   long id = (long) cls;
166
167   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: incoming tunnel closed\n");
168   if (id != 2)
169   {
170     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
171                 "test: received closing tunnel on peer != 2\n");
172     result = GNUNET_SYSERR;
173   }
174 }
175
176
177 /**
178  * Handler array for traffic received on peer1
179  */
180 static struct GNUNET_MESH_MessageHandler handlers1[] = {
181   {&data_callback, 1, 0},
182   {NULL, 0, 0}
183 };
184
185
186 /**
187  * Handler array for traffic received on peer2 (none expected)
188  */
189 static struct GNUNET_MESH_MessageHandler handlers2[] = {
190   {&data_callback, 1, 0},
191   {NULL, 0, 0}
192 };
193
194 static size_t
195 do_send (void *cls, size_t size, void *buf)
196 {
197   struct GNUNET_MessageHeader *m = buf;
198
199   if (NULL == buf)
200   {
201     GNUNET_break (0);
202     result = GNUNET_SYSERR;
203     return 0;
204   }
205   m->size = htons (sizeof (struct GNUNET_MessageHeader));
206   m->type = htons (1);
207   GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader));
208   return sizeof (struct GNUNET_MessageHeader);
209 }
210
211 /**
212  * Start looking for a peer by type
213  */
214 static void
215 do_find (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
216 {
217   struct GNUNET_PeerIdentity id;
218
219   GNUNET_TESTING_peer_get_identity (me, &id);
220   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: CONNECT BY PORT\n");
221   t = GNUNET_MESH_tunnel_create (mesh_peer_1, NULL, &id, 1);
222   GNUNET_MESH_notify_transmit_ready (t, GNUNET_NO,
223                                      GNUNET_TIME_UNIT_FOREVER_REL,
224                                      sizeof (struct GNUNET_MessageHeader),
225                                      &do_send, NULL);
226 }
227
228
229 /**
230  * Initialize framework and start test
231  */
232 static void
233 run (void *cls, 
234      const struct GNUNET_CONFIGURATION_Handle *cfg,
235      struct GNUNET_TESTING_Peer *peer)
236 {
237   static uint32_t ports[] = {1, 0};
238
239   me = peer;
240   abort_task =
241       GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
242                                     (GNUNET_TIME_UNIT_SECONDS, 15), &do_abort,
243                                     NULL);
244   mesh_peer_1 = GNUNET_MESH_connect (cfg,       /* configuration */
245                                      (void *) 1L,     /* cls */
246                                      &inbound_tunnel,   /* inbound new hndlr */
247                                      &inbound_end,      /* inbound end hndlr */
248                                      handlers1, /* traffic handlers */
249                                      NULL);     /* ports offered */
250
251   mesh_peer_2 = GNUNET_MESH_connect (cfg,       /* configuration */
252                                      (void *) 2L,     /* cls */
253                                      &inbound_tunnel,   /* inbound new hndlr */
254                                      &inbound_end,      /* inbound end hndlr */
255                                      handlers2, /* traffic handlers */
256                                      ports);     /* ports offered */
257   if (NULL == mesh_peer_1 || NULL == mesh_peer_2)
258   {
259     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "test: Couldn't connect to mesh :(\n");
260     result = GNUNET_SYSERR;
261     return;
262   }
263   else
264   {
265     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: YAY! CONNECTED TO MESH :D\n");
266   }
267   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &do_find, NULL);
268 }
269
270
271 /**
272  * Main
273  */
274 int
275 main (int argc, char *argv[])
276 {
277   if (0 != GNUNET_TESTING_peer_run ("test-mesh-local-1",
278                                     "test_mesh2.conf",
279                                 &run, NULL))
280     return 1;
281   return (result == GNUNET_OK) ? 0 : 1;
282 }
283
284 /* end of test_mesh_local_1.c */