aboutsummaryrefslogtreecommitdiff
path: root/src/cadet
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2017-03-11 12:58:13 +0100
committerChristian Grothoff <christian@grothoff.org>2017-03-11 12:58:13 +0100
commitb05d9b4b7cead622dce8342daa5556b76647bc31 (patch)
tree2bfc7873d4193d0196770d64eaffcbc6855def2e /src/cadet
parentbcf3298c5eb79dd98bfc8ccf58793703aac70f49 (diff)
downloadgnunet-b05d9b4b7cead622dce8342daa5556b76647bc31.tar.gz
gnunet-b05d9b4b7cead622dce8342daa5556b76647bc31.zip
remove old CADET testcases
Diffstat (limited to 'src/cadet')
-rw-r--r--src/cadet/Makefile.am95
-rw-r--r--src/cadet/cadet_path.c363
-rw-r--r--src/cadet/cadet_path.h226
-rw-r--r--src/cadet/test_cadet.c1162
-rw-r--r--src/cadet/test_cadet_local.c351
-rw-r--r--src/cadet/test_cadet_single.c354
6 files changed, 1 insertions, 2550 deletions
diff --git a/src/cadet/Makefile.am b/src/cadet/Makefile.am
index 518646664..c33a653b0 100644
--- a/src/cadet/Makefile.am
+++ b/src/cadet/Makefile.am
@@ -116,25 +116,7 @@ check_PROGRAMS = \
116 test_cadet_5_speed_ack_new \ 116 test_cadet_5_speed_ack_new \
117 test_cadet_5_speed_reliable_new \ 117 test_cadet_5_speed_reliable_new \
118 test_cadet_5_speed_reliable_backwards_new \ 118 test_cadet_5_speed_reliable_backwards_new \
119 test_cadet_5_speed_backwards_new \ 119 test_cadet_5_speed_backwards_new
120 test_cadet_single \
121 test_cadet_local \
122 test_cadet_2_forward \
123 test_cadet_2_signal \
124 test_cadet_2_keepalive \
125 test_cadet_2_speed \
126 test_cadet_2_speed_ack \
127 test_cadet_2_speed_backwards \
128 test_cadet_2_speed_reliable \
129 test_cadet_2_speed_reliable_backwards \
130 test_cadet_5_forward \
131 test_cadet_5_signal \
132 test_cadet_5_keepalive \
133 test_cadet_5_speed \
134 test_cadet_5_speed_ack \
135 test_cadet_5_speed_reliable \
136 test_cadet_5_speed_reliable_backwards \
137 test_cadet_5_speed_backwards
138endif 120endif
139 121
140ld_cadet_test_lib = \ 122ld_cadet_test_lib = \
@@ -156,15 +138,6 @@ gnunet_cadet_profiler_SOURCES = \
156gnunet_cadet_profiler_LDADD = $(ld_cadet_test_lib) 138gnunet_cadet_profiler_LDADD = $(ld_cadet_test_lib)
157 139
158 140
159test_cadet_single_SOURCES = \
160 test_cadet_single.c
161test_cadet_single_LDADD = $(ld_cadet_test_lib)
162
163test_cadet_local_SOURCES = \
164 test_cadet_local.c
165test_cadet_local_LDADD = $(ld_cadet_test_lib)
166
167
168test_cadet_local_mq_SOURCES = \ 141test_cadet_local_mq_SOURCES = \
169 test_cadet_local_mq.c 142 test_cadet_local_mq.c
170test_cadet_local_mq_LDADD = \ 143test_cadet_local_mq_LDADD = \
@@ -172,73 +145,7 @@ test_cadet_local_mq_LDADD = \
172 $(top_builddir)/src/testing/libgnunettesting.la \ 145 $(top_builddir)/src/testing/libgnunettesting.la \
173 $(top_builddir)/src/util/libgnunetutil.la 146 $(top_builddir)/src/util/libgnunetutil.la
174 147
175test_cadet_2_forward_SOURCES = \
176 test_cadet.c
177test_cadet_2_forward_LDADD = $(ld_cadet_test_lib)
178
179test_cadet_2_signal_SOURCES = \
180 test_cadet.c
181test_cadet_2_signal_LDADD = $(ld_cadet_test_lib)
182
183test_cadet_2_keepalive_SOURCES = \
184 test_cadet.c
185test_cadet_2_keepalive_LDADD = $(ld_cadet_test_lib)
186
187test_cadet_2_speed_SOURCES = \
188 test_cadet.c
189test_cadet_2_speed_LDADD = $(ld_cadet_test_lib)
190
191test_cadet_2_speed_ack_SOURCES = \
192 test_cadet.c
193test_cadet_2_speed_ack_LDADD = $(ld_cadet_test_lib)
194
195test_cadet_2_speed_backwards_SOURCES = \
196 test_cadet.c
197test_cadet_2_speed_backwards_LDADD = $(ld_cadet_test_lib)
198
199test_cadet_2_speed_reliable_SOURCES = \
200 test_cadet.c
201test_cadet_2_speed_reliable_LDADD = $(ld_cadet_test_lib)
202
203test_cadet_2_speed_reliable_backwards_SOURCES = \
204 test_cadet.c
205test_cadet_2_speed_reliable_backwards_LDADD = $(ld_cadet_test_lib)
206
207
208test_cadet_5_forward_SOURCES = \
209 test_cadet.c
210test_cadet_5_forward_LDADD = $(ld_cadet_test_lib)
211
212test_cadet_5_signal_SOURCES = \
213 test_cadet.c
214test_cadet_5_signal_LDADD = $(ld_cadet_test_lib)
215
216test_cadet_5_keepalive_SOURCES = \
217 test_cadet.c
218test_cadet_5_keepalive_LDADD = $(ld_cadet_test_lib)
219
220test_cadet_5_speed_SOURCES = \
221 test_cadet.c
222test_cadet_5_speed_LDADD = $(ld_cadet_test_lib)
223
224test_cadet_5_speed_ack_SOURCES = \
225 test_cadet.c
226test_cadet_5_speed_ack_LDADD = $(ld_cadet_test_lib)
227
228test_cadet_5_speed_backwards_SOURCES = \
229 test_cadet.c
230test_cadet_5_speed_backwards_LDADD = $(ld_cadet_test_lib)
231
232test_cadet_5_speed_reliable_SOURCES = \
233 test_cadet.c
234test_cadet_5_speed_reliable_LDADD = $(ld_cadet_test_lib)
235
236test_cadet_5_speed_reliable_backwards_SOURCES = \
237 test_cadet.c
238test_cadet_5_speed_reliable_backwards_LDADD = $(ld_cadet_test_lib)
239
240 148
241# NEW TESTS
242libgnunetcadettestnew_la_SOURCES = \ 149libgnunetcadettestnew_la_SOURCES = \
243 cadet_test_lib_new.c cadet_test_lib_new.h 150 cadet_test_lib_new.c cadet_test_lib_new.h
244libgnunetcadettestnew_la_LIBADD = \ 151libgnunetcadettestnew_la_LIBADD = \
diff --git a/src/cadet/cadet_path.c b/src/cadet/cadet_path.c
deleted file mode 100644
index 79a498805..000000000
--- a/src/cadet/cadet_path.c
+++ /dev/null
@@ -1,363 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2001 - 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 cadet/cadet_path.c
23 * @brief Path handling functions
24 * @author Bartlomiej Polot
25 */
26
27#include "cadet.h"
28#include "cadet_path.h"
29#include "gnunet-service-cadet_peer.h"
30
31#define LOG(level, ...) GNUNET_log_from (level,"cadet-pth",__VA_ARGS__)
32
33
34/**
35 * @brief Destroy a path after some time has past.
36 * Removes the path from the peer (must not be used for direct paths).
37 *
38 * @param cls Closure (path to destroy).
39 */
40static void
41path_destroy_delayed (void *cls)
42{
43 struct CadetPeerPath *path = cls;
44 struct CadetPeer *peer;
45
46 path->path_delete = NULL;
47 LOG (GNUNET_ERROR_TYPE_DEBUG,
48 "Destroy delayed %p (%u)\n",
49 path,
50 path->length);
51 GNUNET_assert (2 < path->length);
52 peer = GCP_get_short (path->peers[path->length - 1],
53 GNUNET_NO);
54 GNUNET_assert (NULL != peer);
55 GCP_remove_path (peer, path);
56}
57
58
59/**
60 * Create a new path
61 *
62 * @param length How many hops will the path have.
63 * @return A newly allocated path with a peer array of the specified length.
64 */
65struct CadetPeerPath *
66path_new (unsigned int length)
67{
68 struct CadetPeerPath *p;
69
70 p = GNUNET_new (struct CadetPeerPath);
71 if (length > 0)
72 {
73 p->length = length;
74 p->peers = GNUNET_malloc (length * sizeof (GNUNET_PEER_Id));
75 }
76 LOG (GNUNET_ERROR_TYPE_DEBUG, "New path %p (%u)\n", p, p->length);
77 return p;
78}
79
80
81/**
82 * Invert the path
83 *
84 * @param path the path to invert
85 */
86void
87path_invert (struct CadetPeerPath *path)
88{
89 GNUNET_PEER_Id aux;
90 unsigned int i;
91
92 for (i = 0; i < path->length / 2; i++)
93 {
94 aux = path->peers[i];
95 path->peers[i] = path->peers[path->length - i - 1];
96 path->peers[path->length - i - 1] = aux;
97 }
98}
99
100
101/**
102 * Duplicate a path, incrementing short peer's rc.
103 *
104 * @param path The path to duplicate.
105 */
106struct CadetPeerPath *
107path_duplicate (const struct CadetPeerPath *path)
108{
109 struct CadetPeerPath *aux;
110 unsigned int i;
111
112 aux = path_new (path->length);
113 GNUNET_memcpy (aux->peers,
114 path->peers,
115 path->length * sizeof (GNUNET_PEER_Id));
116 for (i = 0; i < aux->length; i++)
117 GNUNET_PEER_change_rc (aux->peers[i], 1);
118 return aux;
119}
120
121
122/**
123 * Get the length of a path.
124 *
125 * @param path The path to measure, with the local peer at any point of it.
126 *
127 * @return Number of hops to reach destination.
128 * UINT_MAX in case the peer is not in the path.
129 */
130unsigned int
131path_get_length (struct CadetPeerPath *path)
132{
133 if (NULL == path)
134 return UINT_MAX;
135 return path->length;
136}
137
138
139
140/**
141 * Mark path as invalid: keep it aroud for a while to avoid trying it in a loop.
142 *
143 * Never invalidates a two-hop (direct) path, only a core handler can do that.
144 *
145 * Rationale: DHT_get sometimes returns bad cached results, for instance,
146 * on a locally cached result where the PUT followed a path that is no longer
147 * current. The path must remain "known and marked as invalid" for a while.
148 *
149 * @param p Path to invalidate.
150 */
151void
152path_invalidate (struct CadetPeerPath *p)
153{
154 if (NULL != p->path_delete)
155 return;
156
157 LOG (GNUNET_ERROR_TYPE_DEBUG,
158 "Invalidating path %p (%u)\n",
159 p,
160 p->length);
161 p->path_delete
162 = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
163 &path_destroy_delayed, p);
164}
165
166
167/**
168 * Builds a path from a PeerIdentity array.
169 *
170 * @param peers PeerIdentity array.
171 * @param size Size of the @c peers array.
172 * @param myid ID of local peer, to find @c own_pos.
173 * @param own_pos Output parameter: own position in the path.
174 *
175 * @return Fixed and shortened path.
176 */
177struct CadetPeerPath *
178path_build_from_peer_ids (struct GNUNET_PeerIdentity *peers,
179 unsigned int size,
180 GNUNET_PEER_Id myid,
181 unsigned int *own_pos)
182{
183 struct CadetPeerPath *path;
184 GNUNET_PEER_Id shortid;
185 unsigned int i;
186 unsigned int j;
187 unsigned int offset;
188
189 /* Create path */
190 LOG (GNUNET_ERROR_TYPE_DEBUG, " Creating path...\n");
191 path = path_new (size);
192 *own_pos = 0;
193 offset = 0;
194 for (i = 0; i < size; i++)
195 {
196 LOG (GNUNET_ERROR_TYPE_DEBUG, " - %u: taking %s\n",
197 i, GNUNET_i2s (&peers[i]));
198 shortid = GNUNET_PEER_intern (&peers[i]);
199
200 /* Check for loops / duplicates */
201 for (j = 0; j < i - offset; j++)
202 {
203 if (path->peers[j] == shortid)
204 {
205 LOG (GNUNET_ERROR_TYPE_DEBUG, " already exists at pos %u\n", j);
206 offset = i - j;
207 LOG (GNUNET_ERROR_TYPE_DEBUG, " offset now %u\n", offset);
208 GNUNET_PEER_change_rc (shortid, -1);
209 }
210 }
211 LOG (GNUNET_ERROR_TYPE_DEBUG, " storing at %u\n", i - offset);
212 path->peers[i - offset] = shortid;
213 if (path->peers[i - offset] == myid)
214 *own_pos = i - offset;
215 }
216 path->length -= offset;
217
218 if (path->peers[*own_pos] != myid)
219 {
220 /* create path: self not found in path through self */
221 GNUNET_break_op (0);
222 path_destroy (path);
223 return NULL;
224 }
225
226 return path;
227}
228
229
230/**
231 * Test if two paths are equivalent (equal or revese of each other).
232 *
233 * @param p1 First path
234 * @param p2 Second path
235 *
236 * @return #GNUNET_YES if both paths are equivalent
237 * #GNUNET_NO otherwise
238 */
239int
240path_equivalent (const struct CadetPeerPath *p1,
241 const struct CadetPeerPath *p2)
242{
243 unsigned int i;
244 unsigned int l;
245 unsigned int half;
246
247 if (NULL == p1 || NULL == p2)
248 return GNUNET_NO;
249
250 if (p1->length != p2->length)
251 return GNUNET_NO;
252
253 l = p1->length;
254 if (0 == memcmp (p1->peers, p2->peers, sizeof (p1->peers[0]) * l))
255 return GNUNET_YES;
256
257 half = l / 2;
258 l = l - 1;
259 for (i = 0; i <= half; i++)
260 if (p1->peers[i] != p2->peers[l - i])
261 return GNUNET_NO;
262
263 return GNUNET_YES;
264}
265
266
267/**
268 * Test if a path is valid (or at least not known to be invalid).
269 *
270 * @param path Path to test.
271 *
272 * @return #GNUNET_YES If the path is valid or unknown,
273 * #GNUNET_NO If the path is known to be invalid.
274 */
275int
276path_is_valid (const struct CadetPeerPath *path)
277{
278 return (NULL == path->path_delete);
279}
280
281
282/**
283 * Destroy the path and free any allocated resources linked to it
284 *
285 * @param p the path to destroy
286 *
287 * @return #GNUNET_OK on success
288 */
289int
290path_destroy (struct CadetPeerPath *p)
291{
292 if (NULL == p)
293 return GNUNET_OK;
294
295 LOG (GNUNET_ERROR_TYPE_DEBUG,
296 "destroying path %p (%u)\n",
297 p,
298 p->length);
299 GNUNET_PEER_decrement_rcs (p->peers, p->length);
300 GNUNET_free_non_null (p->peers);
301 if (NULL != p->path_delete)
302 GNUNET_SCHEDULER_cancel (p->path_delete);
303 GNUNET_free (p);
304 return GNUNET_OK;
305}
306
307
308/**
309 * Compare two paths.
310 *
311 * @param p1 First path.
312 * @param p2 Second path.
313 *
314 * @return > 0 if p1 is longer, or the first differing PEER_Id is higher on p1.
315 * < 0 if p2 is longer, or the first differing PEER_Id is higher on p2.
316 * 0 if they are identical.
317 */
318int
319path_cmp (const struct CadetPeerPath *p1,
320 const struct CadetPeerPath *p2)
321{
322 if (p1->length > p2->length)
323 return 1;
324
325 if (p1->length < p2->length)
326 return -1;
327
328 return memcmp (p1->peers,
329 p2->peers,
330 sizeof (GNUNET_PEER_Id) * p1->length);
331}
332
333
334char *
335path_2s (struct CadetPeerPath *p)
336{
337 char *s;
338 char *old;
339 unsigned int i;
340
341 old = GNUNET_strdup ("");
342 for (i = 0; i < p->length; i++)
343 {
344 GNUNET_asprintf (&s, "%s %s",
345 old, GNUNET_i2s (GNUNET_PEER_resolve2 (p->peers[i])));
346 GNUNET_free_non_null (old);
347 old = s;
348 }
349 return old;
350}
351
352
353void
354path_debug (struct CadetPeerPath *p)
355{
356 unsigned int i;
357
358 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "PATH:\n");
359 for (i = 0; i < p->length; i++)
360 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " %s\n",
361 GNUNET_i2s (GNUNET_PEER_resolve2 (p->peers[i])));
362 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "END\n");
363}
diff --git a/src/cadet/cadet_path.h b/src/cadet/cadet_path.h
deleted file mode 100644
index bb68eec42..000000000
--- a/src/cadet/cadet_path.h
+++ /dev/null
@@ -1,226 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2001 - 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 cadet/cadet_path.h
23 * @brief Path handling functions
24 * @author Bartlomiej Polot
25 */
26
27#ifndef CADET_PATH_H_
28#define CADET_PATH_H_
29
30#ifdef __cplusplus
31extern "C"
32{
33 #if 0 /* keep Emacsens' auto-indent happy */
34}
35#endif
36#endif
37
38
39/******************************************************************************/
40/************************ DATA STRUCTURES ****************************/
41/******************************************************************************/
42
43/**
44 * Information regarding a possible path to reach a single peer
45 */
46struct CadetPeerPath
47{
48
49 /**
50 * Linked list
51 */
52 struct CadetPeerPath *next;
53 struct CadetPeerPath *prev;
54
55 /**
56 * List of all the peers that form the path from origin to target.
57 */
58 GNUNET_PEER_Id *peers;
59
60 /**
61 * Number of peers (hops) in the path
62 */
63 unsigned int length;
64
65 /**
66 * User defined data store.
67 */
68 struct CadetConnection *c;
69
70 /**
71 * Path's score, how reliable is the path.
72 */
73// int score;
74
75 /**
76 * Task to delete the path.
77 * We tried it, it didn't work, don't try again in a while.
78 */
79 struct GNUNET_SCHEDULER_Task * path_delete;
80
81};
82
83/******************************************************************************/
84/************************* FUNCTIONS *****************************/
85/******************************************************************************/
86
87/**
88 * Create a new path.
89 *
90 * @param length How many hops will the path have.
91 *
92 * @return A newly allocated path with a peer array of the specified length.
93 */
94struct CadetPeerPath *
95path_new (unsigned int length);
96
97
98/**
99 * Invert the path.
100 *
101 * @param path The path to invert.
102 */
103void
104path_invert (struct CadetPeerPath *path);
105
106
107/**
108 * Duplicate a path, incrementing short peer's rc.
109 *
110 * @param path The path to duplicate.
111 */
112struct CadetPeerPath *
113path_duplicate (const struct CadetPeerPath *path);
114
115
116/**
117 * Get the length of a path.
118 *
119 * @param path The path to measure, with the local peer at any point of it.
120 *
121 * @return Number of hops to reach destination.
122 * UINT_MAX in case the peer is not in the path.
123 */
124unsigned int
125path_get_length (struct CadetPeerPath *path);
126
127/**
128 * Mark path as invalid: keep it aroud for a while to avoid trying it in a loop.
129 *
130 * DHT_get sometimes returns bad cached results, for instance, on a locally
131 * cached result where the PUT followed a path that is no longer current.
132 *
133 * @param p Path to invalidate.
134 */
135void
136path_invalidate (struct CadetPeerPath *p);
137
138/**
139 * Test if two paths are equivalent (equal or revese of each other).
140 *
141 * @param p1 First path
142 * @param p2 Second path
143 *
144 * @return GNUNET_YES if both paths are equivalent
145 * GNUNET_NO otherwise
146 */
147int
148path_equivalent (const struct CadetPeerPath *p1,
149 const struct CadetPeerPath *p2);
150
151/**
152 * Test if a path is valid (or at least not known to be invalid).
153 *
154 * @param path Path to test.
155 *
156 * @return #GNUNET_YES If the path is valid or unknown,
157 * #GNUNET_NO If the path is known to be invalid.
158 */
159int
160path_is_valid (const struct CadetPeerPath *path);
161
162/**
163 * Destroy the path and free any allocated resources linked to it
164 *
165 * @param p the path to destroy
166 *
167 * @return GNUNET_OK on success
168 */
169int
170path_destroy (struct CadetPeerPath *p);
171
172/**
173 * Compare two paths.
174 *
175 * @param p1 First path.
176 * @param p2 Second path.
177 *
178 * @return > 0 if p1 is longer, or the first differing PEER_Id is higher on p1.
179 * < 0 if p2 is longer, or the first differing PEER_Id is higher on p2.
180 * 0 if they are identical.
181 */
182int
183path_cmp (const struct CadetPeerPath *p1, const struct CadetPeerPath *p2);
184
185/**
186 * Builds a path from a PeerIdentity array.
187 *
188 * @param peers PeerIdentity array.
189 * @param size Size of the @c peers array.
190 * @param myid ID of local peer, to find @c own_pos.
191 * @param own_pos Output parameter: own position in the path.
192 *
193 * @return Fixed and shortened path.
194 */
195struct CadetPeerPath *
196path_build_from_peer_ids (struct GNUNET_PeerIdentity *peers,
197 unsigned int size,
198 GNUNET_PEER_Id myid,
199 unsigned int *own_pos);
200
201/**
202 * Path -> allocated one line string. Caller must free.
203 *
204 * @param p Path.
205 */
206char *
207path_2s (struct CadetPeerPath *p);
208
209/**
210 * Print info about the path for debug.
211 *
212 * @param p Path to debug.
213 */
214void
215path_debug (struct CadetPeerPath *p);
216
217#if 0 /* keep Emacsens' auto-indent happy */
218{
219 #endif
220 #ifdef __cplusplus
221}
222#endif
223
224
225/* ifndef CADET_PATH_H */
226#endif
diff --git a/src/cadet/test_cadet.c b/src/cadet/test_cadet.c
deleted file mode 100644
index e57c01be2..000000000
--- a/src/cadet/test_cadet.c
+++ /dev/null
@@ -1,1162 +0,0 @@
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
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 * @file cadet/test_cadet.c
22 * @author Bart Polot
23 * @author Christian Grothoff
24 * @brief Test for the cadet service: retransmission of traffic.
25 */
26#include <stdio.h>
27#include "platform.h"
28#include "cadet_test_lib.h"
29#include "gnunet_cadet_service.h"
30#include "gnunet_statistics_service.h"
31#include <gauger.h>
32
33
34/**
35 * How many messages to send
36 */
37#define TOTAL_PACKETS 500 /* Cannot exceed 64k! */
38
39/**
40 * How long until we give up on connecting the peers?
41 */
42#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 120)
43
44/**
45 * Time to wait for stuff that should be rather fast
46 */
47#define SHORT_TIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 20)
48
49/**
50 * DIFFERENT TESTS TO RUN
51 */
52#define SETUP 0
53#define FORWARD 1
54#define KEEPALIVE 2
55#define SPEED 3
56#define SPEED_ACK 4
57#define SPEED_REL 8
58#define P2P_SIGNAL 10
59
60/**
61 * Which test are we running?
62 */
63static int test;
64
65/**
66 * String with test name
67 */
68static char *test_name;
69
70/**
71 * Flag to send traffic leaf->root in speed tests to test BCK_ACK logic.
72 */
73static int test_backwards = GNUNET_NO;
74
75/**
76 * How many events have happened
77 */
78static int ok;
79
80/**
81 * Number of events expected to conclude the test successfully.
82 */
83static int ok_goal;
84
85/**
86 * Size of each test packet
87 */
88static size_t size_payload = sizeof (struct GNUNET_MessageHeader) + sizeof (uint32_t);
89
90/**
91 * Operation to get peer ids.
92 */
93static struct GNUNET_TESTBED_Operation *t_op[2];
94
95/**
96 * Peer ids.
97 */
98static struct GNUNET_PeerIdentity *p_id[2];
99
100/**
101 * Port ID
102 */
103static struct GNUNET_HashCode port;
104
105/**
106 * Peer ids counter.
107 */
108static unsigned int p_ids;
109
110/**
111 * Is the setup initialized?
112 */
113static int initialized;
114
115/**
116 * Number of payload packes sent.
117 */
118static int data_sent;
119
120/**
121 * Number of payload packets received.
122 */
123static int data_received;
124
125/**
126 * Number of payload packed acknowledgements sent.
127 */
128static int ack_sent;
129
130/**
131 * Number of payload packed explicitly (app level) acknowledged.
132 */
133static int ack_received;
134
135/**
136 * Total number of peers asked to run.
137 */
138static unsigned long long peers_requested;
139
140/**
141 * Number of currently running peers (should be same as @c peers_requested).
142 */
143static unsigned long long peers_running;
144
145/**
146 * Test context (to shut down).
147 */
148struct GNUNET_CADET_TEST_Context *test_ctx;
149
150/**
151 * Task called to disconnect peers.
152 */
153static struct GNUNET_SCHEDULER_Task *disconnect_task;
154
155/**
156 * Task To perform tests
157 */
158static struct GNUNET_SCHEDULER_Task *test_task;
159
160/**
161 * Task runnining #data_task().
162 */
163static struct GNUNET_SCHEDULER_Task *data_job;
164
165/**
166 * Cadet handle for the root peer
167 */
168static struct GNUNET_CADET_Handle *h1;
169
170/**
171 * Cadet handle for the first leaf peer
172 */
173static struct GNUNET_CADET_Handle *h2;
174
175/**
176 * Channel handle for the root peer
177 */
178static struct GNUNET_CADET_Channel *ch;
179
180/**
181 * Channel handle for the dest peer
182 */
183static struct GNUNET_CADET_Channel *incoming_ch;
184
185/**
186 * Transmit handle for root data calls
187 */
188static struct GNUNET_CADET_TransmitHandle *th;
189
190/**
191 * Transmit handle for root data calls
192 */
193static struct GNUNET_CADET_TransmitHandle *incoming_th;
194
195
196/**
197 * Time we started the data transmission (after channel has been established
198 * and initilized).
199 */
200static struct GNUNET_TIME_Absolute start_time;
201
202/**
203 * Peers handle.
204 */
205static struct GNUNET_TESTBED_Peer **testbed_peers;
206
207/**
208 * Statistics operation handle.
209 */
210static struct GNUNET_TESTBED_Operation *stats_op;
211
212/**
213 * Keepalives sent.
214 */
215static unsigned int ka_sent;
216
217/**
218 * Keepalives received.
219 */
220static unsigned int ka_received;
221
222/**
223 * How many messages were dropped by CADET because of full buffers?
224 */
225static unsigned int msg_dropped;
226
227
228/**
229 * Get the client number considered as the "target" or "receiver", depending on
230 * the test type and size.
231 *
232 * @return Peer # of the target client, either 0 (for backward tests) or
233 * the last peer in the line (for other tests).
234 */
235static unsigned int
236get_expected_target ()
237{
238 if (SPEED == test && GNUNET_YES == test_backwards)
239 return 0;
240 else
241 return peers_requested - 1;
242}
243
244
245/**
246 * Show the results of the test (banwidth acheived) and log them to GAUGER
247 */
248static void
249show_end_data (void)
250{
251 static struct GNUNET_TIME_Absolute end_time;
252 static struct GNUNET_TIME_Relative total_time;
253
254 end_time = GNUNET_TIME_absolute_get();
255 total_time = GNUNET_TIME_absolute_get_difference(start_time, end_time);
256 FPRINTF (stderr, "\nResults of test \"%s\"\n", test_name);
257 FPRINTF (stderr, "Test time %s\n",
258 GNUNET_STRINGS_relative_time_to_string (total_time,
259 GNUNET_YES));
260 FPRINTF (stderr, "Test bandwidth: %f kb/s\n",
261 4 * TOTAL_PACKETS * 1.0 / (total_time.rel_value_us / 1000)); // 4bytes * ms
262 FPRINTF (stderr, "Test throughput: %f packets/s\n\n",
263 TOTAL_PACKETS * 1000.0 / (total_time.rel_value_us / 1000)); // packets * ms
264 GAUGER ("CADET", test_name,
265 TOTAL_PACKETS * 1000.0 / (total_time.rel_value_us / 1000),
266 "packets/s");
267}
268
269
270/**
271 * Disconnect from cadet services af all peers, call shutdown.
272 *
273 * @param cls Closure (line number from which termination was requested).
274 * @param tc Task Context.
275 */
276static void
277disconnect_cadet_peers (void *cls)
278{
279 long line = (long) cls;
280 unsigned int i;
281
282 disconnect_task = NULL;
283 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
284 "disconnecting cadet service of peers, called from line %ld\n",
285 line);
286 for (i = 0; i < 2; i++)
287 {
288 GNUNET_TESTBED_operation_done (t_op[i]);
289 }
290 if (NULL != ch)
291 {
292 if (NULL != th)
293 {
294 GNUNET_CADET_notify_transmit_ready_cancel (th);
295 th = NULL;
296 }
297 GNUNET_CADET_channel_destroy (ch);
298 ch = NULL;
299 }
300 if (NULL != incoming_ch)
301 {
302 if (NULL != incoming_th)
303 {
304 GNUNET_CADET_notify_transmit_ready_cancel (incoming_th);
305 incoming_th = NULL;
306 }
307 GNUNET_CADET_channel_destroy (incoming_ch);
308 incoming_ch = NULL;
309 }
310 GNUNET_CADET_TEST_cleanup (test_ctx);
311 GNUNET_SCHEDULER_shutdown ();
312}
313
314
315/**
316 * Shut down peergroup, clean up.
317 *
318 * @param cls Closure (unused).
319 * @param tc Task Context.
320 */
321static void
322shutdown_task (void *cls)
323{
324 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ending test.\n");
325 if (NULL != data_job)
326 {
327 GNUNET_SCHEDULER_cancel (data_job);
328 data_job = NULL;
329 }
330 if (NULL != test_task)
331 {
332 GNUNET_SCHEDULER_cancel (test_task);
333 test_task = NULL;
334 }
335 if (NULL != disconnect_task)
336 {
337 GNUNET_SCHEDULER_cancel (disconnect_task);
338 disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_cadet_peers,
339 (void *) __LINE__);
340 }
341}
342
343
344/**
345 * Stats callback. Finish the stats testbed operation and when all stats have
346 * been iterated, shutdown the test.
347 *
348 * @param cls Closure (line number from which termination was requested).
349 * @param op the operation that has been finished
350 * @param emsg error message in case the operation has failed; will be NULL if
351 * operation has executed successfully.
352 */
353static void
354stats_cont (void *cls,
355 struct GNUNET_TESTBED_Operation *op,
356 const char *emsg)
357{
358 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
359 " KA sent: %u, KA received: %u\n",
360 ka_sent,
361 ka_received);
362 if ( (KEEPALIVE == test) &&
363 ( (ka_sent < 2) ||
364 (ka_sent > ka_received + 1)) )
365 {
366 GNUNET_break (0);
367 ok--;
368 }
369 GNUNET_TESTBED_operation_done (stats_op);
370
371 if (NULL != disconnect_task)
372 GNUNET_SCHEDULER_cancel (disconnect_task);
373 disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_cadet_peers,
374 cls);
375}
376
377
378/**
379 * Process statistic values.
380 *
381 * @param cls closure (line number, unused)
382 * @param peer the peer the statistic belong to
383 * @param subsystem name of subsystem that created the statistic
384 * @param name the name of the datum
385 * @param value the current value
386 * @param is_persistent #GNUNET_YES if the value is persistent, #GNUNET_NO if not
387 * @return #GNUNET_OK to continue, #GNUNET_SYSERR to abort iteration
388 */
389static int
390stats_iterator (void *cls,
391 const struct GNUNET_TESTBED_Peer *peer,
392 const char *subsystem,
393 const char *name,
394 uint64_t value,
395 int is_persistent)
396{
397 static const char *s_sent = "# keepalives sent";
398 static const char *s_recv = "# keepalives received";
399 static const char *rdrops = "# messages dropped due to full buffer";
400 static const char *cdrops = "# messages dropped due to slow client";
401 uint32_t i;
402
403 i = GNUNET_TESTBED_get_index (peer);
404 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
405 "STATS PEER %u - %s [%s]: %llu\n",
406 i,
407 subsystem,
408 name,
409 (unsigned long long) value);
410 if (0 == strncmp (s_sent, name, strlen (s_sent)) && 0 == i)
411 ka_sent = value;
412 if (0 == strncmp(s_recv, name, strlen (s_recv)) && peers_requested - 1 == i)
413 ka_received = value;
414 if (0 == strncmp(rdrops, name, strlen (rdrops)))
415 msg_dropped += value;
416 if (0 == strncmp(cdrops, name, strlen (cdrops)))
417 msg_dropped += value;
418
419 return GNUNET_OK;
420}
421
422
423/**
424 * Task to gather all statistics.
425 *
426 * @param cls Closure (NULL).
427 */
428static void
429gather_stats_and_exit (void *cls)
430{
431 long l = (long) cls;
432
433 disconnect_task = NULL;
434 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
435 "gathering statistics from line %d\n",
436 (int) l);
437 if (NULL != ch)
438 {
439 if (NULL != th)
440 {
441 GNUNET_CADET_notify_transmit_ready_cancel (th);
442 th = NULL;
443 }
444 GNUNET_CADET_channel_destroy (ch);
445 ch = NULL;
446 }
447 stats_op = GNUNET_TESTBED_get_statistics (peers_running, testbed_peers,
448 "cadet", NULL,
449 &stats_iterator, stats_cont, cls);
450}
451
452
453
454/**
455 * Abort test: schedule disconnect and shutdown immediately
456 *
457 * @param line Line in the code the abort is requested from (__LINE__).
458 */
459static void
460abort_test (long line)
461{
462 if (NULL != disconnect_task)
463 {
464 GNUNET_SCHEDULER_cancel (disconnect_task);
465 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
466 "Aborting test from %ld\n", line);
467 disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_cadet_peers,
468 (void *) line);
469 }
470}
471
472/**
473 * Transmit ready callback.
474 *
475 * @param cls Closure (message type).
476 * @param size Size of the tranmist buffer.
477 * @param buf Pointer to the beginning of the buffer.
478 *
479 * @return Number of bytes written to buf.
480 */
481static size_t
482tmt_rdy (void *cls, size_t size, void *buf);
483
484
485/**
486 * Task to request a new data transmission.
487 *
488 * @param cls Closure (peer #).
489 */
490static void
491data_task (void *cls)
492{
493 struct GNUNET_CADET_Channel *channel;
494 static struct GNUNET_CADET_TransmitHandle **pth;
495 long src;
496
497 data_job = NULL;
498 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Data task\n");
499 if (GNUNET_YES == test_backwards)
500 {
501 channel = incoming_ch;
502 pth = &incoming_th;
503 src = peers_requested - 1;
504 }
505 else
506 {
507 channel = ch;
508 pth = &th;
509 src = 0;
510 }
511
512 GNUNET_assert (NULL != channel);
513 GNUNET_assert (NULL == *pth);
514
515 *pth = GNUNET_CADET_notify_transmit_ready (channel, GNUNET_NO,
516 GNUNET_TIME_UNIT_FOREVER_REL,
517 size_payload + data_sent,
518 &tmt_rdy, (void *) src);
519 if (NULL == *pth)
520 {
521 unsigned long i = (unsigned long) cls;
522
523 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Retransmission\n");
524 if (0 == i)
525 {
526 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, " in 1 ms\n");
527 data_job = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MILLISECONDS,
528 &data_task, (void *) 1L);
529 }
530 else
531 {
532 i++;
533 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
534 "in %llu ms\n",
535 (unsigned long long) i);
536 data_job = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS,
537 i),
538 &data_task, (void *) i);
539 }
540 }
541}
542
543
544/**
545 * Transmit ready callback
546 *
547 * @param cls Closure (peer # which is sending the data).
548 * @param size Size of the buffer we have.
549 * @param buf Buffer to copy data to.
550 */
551static size_t
552tmt_rdy (void *cls, size_t size, void *buf)
553{
554 struct GNUNET_MessageHeader *msg = buf;
555 size_t msg_size;
556 uint32_t *data;
557 long id = (long) cls;
558 unsigned int counter;
559
560 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
561 "tmt_rdy on %ld, filling buffer\n",
562 id);
563 if (0 == id)
564 th = NULL;
565 else if ((peers_requested - 1) == id)
566 incoming_th = NULL;
567 else
568 GNUNET_assert (0);
569 counter = get_expected_target () == id ? ack_sent : data_sent;
570 msg_size = size_payload + counter;
571 GNUNET_assert (msg_size > sizeof (struct GNUNET_MessageHeader));
572 if ( (size < msg_size) ||
573 (NULL == buf) )
574 {
575 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
576 "size %u, buf %p, data_sent %u, ack_received %u\n",
577 (unsigned int) size,
578 buf,
579 data_sent,
580 ack_received);
581 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ok %u, ok goal %u\n", ok, ok_goal);
582 GNUNET_break (ok >= ok_goal - 2);
583
584 return 0;
585 }
586 msg->size = htons (msg_size);
587 msg->type = htons (GNUNET_MESSAGE_TYPE_DUMMY);
588 data = (uint32_t *) &msg[1];
589 *data = htonl (counter);
590 if (GNUNET_NO == initialized)
591 {
592 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
593 "sending initializer\n");
594 msg_size = size_payload + 1000;
595 msg->size = htons (msg_size);
596 if (SPEED_ACK == test)
597 data_sent++;
598 }
599 else if ( (SPEED == test) ||
600 (SPEED_ACK == test) )
601 {
602 if (get_expected_target() == id)
603 ack_sent++;
604 else
605 data_sent++;
606 counter++;
607 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
608 " Sent message %u size %u\n",
609 counter,
610 (unsigned int) msg_size);
611 if ( (data_sent < TOTAL_PACKETS) &&
612 (SPEED == test) )
613 {
614 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
615 " Scheduling message %d\n",
616 counter + 1);
617 data_job = GNUNET_SCHEDULER_add_now (&data_task, NULL);
618 }
619 }
620
621 return msg_size;
622}
623
624
625/**
626 * Function is called whenever a message is received.
627 *
628 * @param cls closure (set from GNUNET_CADET_connect(), peer number)
629 * @param channel connection to the other end
630 * @param channel_ctx place to store local state associated with the channel
631 * @param message the actual message
632 * @return #GNUNET_OK to keep the connection open,
633 * #GNUNET_SYSERR to close it (signal serious error)
634 */
635static int
636data_callback (void *cls,
637 struct GNUNET_CADET_Channel *channel,
638 void **channel_ctx,
639 const struct GNUNET_MessageHeader *message)
640{
641 struct GNUNET_CADET_TransmitHandle **pth;
642 long client = (long) cls;
643 long expected_target_client;
644 uint32_t *data;
645 uint32_t payload;
646 unsigned int counter;
647
648 ok++;
649 counter = get_expected_target () == client ? data_received : ack_received;
650
651 GNUNET_CADET_receive_done (channel);
652
653 if ((ok % 10) == 0)
654 {
655 if (NULL != disconnect_task)
656 {
657 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
658 " reschedule timeout\n");
659 GNUNET_SCHEDULER_cancel (disconnect_task);
660 disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME,
661 &gather_stats_and_exit,
662 (void *) __LINE__);
663 }
664 }
665
666 switch (client)
667 {
668 case 0L:
669 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Root client got a message!\n");
670 GNUNET_assert (channel == ch);
671 pth = &th;
672 break;
673 case 1L:
674 case 4L:
675 GNUNET_assert (client == peers_requested - 1);
676 GNUNET_assert (channel == incoming_ch);
677 pth = &incoming_th;
678 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Leaf client %ld got a message.\n",
679 client);
680 break;
681 default:
682 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Client %ld not valid.\n", client);
683 GNUNET_assert (0);
684 }
685 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " ok: (%d/%d)\n", ok, ok_goal);
686 data = (uint32_t *) &message[1];
687 payload = ntohl (*data);
688 if (payload == counter)
689 {
690 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " payload as expected: %u\n", payload);
691 }
692 else
693 {
694 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, " payload %u, expected: %u\n",
695 payload, counter);
696 }
697 expected_target_client = get_expected_target ();
698
699 if (GNUNET_NO == initialized)
700 {
701 initialized = GNUNET_YES;
702 start_time = GNUNET_TIME_absolute_get ();
703 if (SPEED == test)
704 {
705 GNUNET_assert (peers_requested - 1 == client);
706 data_job = GNUNET_SCHEDULER_add_now (&data_task, NULL);
707 return GNUNET_OK;
708 }
709 }
710
711 counter++;
712 if (client == expected_target_client) /* Normally 4 */
713 {
714 data_received++;
715 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " received data %u\n", data_received);
716 if (SPEED != test || (ok_goal - 2) == ok)
717 {
718 /* Send ACK */
719 GNUNET_assert (NULL == *pth);
720 *pth = GNUNET_CADET_notify_transmit_ready (channel, GNUNET_NO,
721 GNUNET_TIME_UNIT_FOREVER_REL,
722 size_payload + ack_sent,
723 &tmt_rdy, (void *) client);
724 return GNUNET_OK;
725 }
726 else
727 {
728 if (data_received < TOTAL_PACKETS)
729 return GNUNET_OK;
730 }
731 }
732 else /* Normally 0 */
733 {
734 if (SPEED_ACK == test || SPEED == test)
735 {
736 ack_received++;
737 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " received ack %u\n", ack_received);
738 /* send more data */
739 GNUNET_assert (NULL == *pth);
740 *pth = GNUNET_CADET_notify_transmit_ready (channel, GNUNET_NO,
741 GNUNET_TIME_UNIT_FOREVER_REL,
742 size_payload + data_sent,
743 &tmt_rdy, (void *) client);
744 if (ack_received < TOTAL_PACKETS && SPEED != test)
745 return GNUNET_OK;
746 if (ok == 2 && SPEED == test)
747 return GNUNET_OK;
748 show_end_data();
749 }
750 if (test == P2P_SIGNAL)
751 {
752 if (NULL != incoming_th)
753 {
754 GNUNET_CADET_notify_transmit_ready_cancel (incoming_th);
755 incoming_th = NULL;
756 }
757 GNUNET_CADET_channel_destroy (incoming_ch);
758 incoming_ch = NULL;
759 }
760 else
761 {
762 if (NULL != th)
763 {
764 GNUNET_CADET_notify_transmit_ready_cancel (th);
765 th = NULL;
766 }
767 GNUNET_CADET_channel_destroy (ch);
768 ch = NULL;
769 }
770 }
771
772 return GNUNET_OK;
773}
774
775
776/**
777 * Data handlers for every message type of CADET's payload.
778 * {callback_function, message_type, size_expected}
779 */
780static struct GNUNET_CADET_MessageHandler handlers[] = {
781 {&data_callback,
782 GNUNET_MESSAGE_TYPE_DUMMY,
783 sizeof (struct GNUNET_MessageHeader)},
784 {NULL, 0, 0}
785};
786
787
788/**
789 * Method called whenever another peer has added us to a channel
790 * the other peer initiated.
791 *
792 * @param cls Closure.
793 * @param channel New handle to the channel.
794 * @param initiator Peer that started the channel.
795 * @param port Port this channel is connected to.
796 * @param options channel option flags
797 * @return Initial channel context for the channel
798 * (can be NULL -- that's not an error).
799 */
800static void *
801incoming_channel (void *cls,
802 struct GNUNET_CADET_Channel *channel,
803 const struct GNUNET_PeerIdentity *initiator,
804 const struct GNUNET_HashCode *port,
805 enum GNUNET_CADET_ChannelOption options)
806{
807 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
808 "Incoming channel from %s to peer %d:%s\n",
809 GNUNET_i2s (initiator),
810 (int) (long) cls, GNUNET_h2s (port));
811 ok++;
812 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " ok: %d\n", ok);
813 if ((long) cls == peers_requested - 1)
814 {
815 if (NULL != incoming_ch)
816 {
817 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
818 "Duplicate incoming channel for client %lu\n",
819 (long) cls);
820 GNUNET_break(0);
821 }
822 incoming_ch = channel;
823 }
824 else
825 {
826 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
827 "Incoming channel for unexpected peer #%lu\n",
828 (long) cls);
829 GNUNET_break (0);
830 }
831 if (NULL != disconnect_task)
832 {
833 GNUNET_SCHEDULER_cancel (disconnect_task);
834 disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME,
835 &gather_stats_and_exit,
836 (void *) __LINE__);
837 }
838
839 return NULL;
840}
841
842
843/**
844 * Function called whenever an inbound channel is destroyed. Should clean up
845 * any associated state.
846 *
847 * @param cls closure (set from GNUNET_CADET_connect, peer number)
848 * @param channel connection to the other end (henceforth invalid)
849 * @param channel_ctx place where local state associated
850 * with the channel is stored
851 */
852static void
853channel_cleaner (void *cls,
854 const struct GNUNET_CADET_Channel *channel,
855 void *channel_ctx)
856{
857 long i = (long) cls;
858
859 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
860 "Incoming channel disconnected at peer %ld\n",
861 i);
862 if (peers_running - 1 == i)
863 {
864 ok++;
865 GNUNET_break (channel == incoming_ch);
866 incoming_ch = NULL;
867 }
868 else if (0L == i)
869 {
870 if (P2P_SIGNAL == test)
871 {
872 ok++;
873 }
874 GNUNET_break (channel == ch);
875 ch = NULL;
876 }
877 else
878 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
879 "Unknown peer! %d\n",
880 (int) i);
881 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " ok: %d\n", ok);
882
883 if (NULL != disconnect_task)
884 {
885 GNUNET_SCHEDULER_cancel (disconnect_task);
886 disconnect_task = GNUNET_SCHEDULER_add_now (&gather_stats_and_exit,
887 (void *) __LINE__);
888 }
889}
890
891
892/**
893 * START THE TESTCASE ITSELF, AS WE ARE CONNECTED TO THE CADET SERVICES.
894 *
895 * Testcase continues when the root receives confirmation of connected peers,
896 * on callback function ch.
897 *
898 * @param cls Closure (unused).
899 */
900static void
901do_test (void *cls)
902{
903 enum GNUNET_CADET_ChannelOption flags;
904
905 test_task = NULL;
906 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
907 "do_test\n");
908 if (NULL != disconnect_task)
909 {
910 GNUNET_SCHEDULER_cancel (disconnect_task);
911 disconnect_task = NULL;
912 }
913
914 flags = GNUNET_CADET_OPTION_DEFAULT;
915 if (SPEED_REL == test)
916 {
917 test = SPEED;
918 flags |= GNUNET_CADET_OPTION_RELIABLE;
919 }
920
921 ch = GNUNET_CADET_channel_create (h1,
922 NULL,
923 p_id[1],
924 &port,
925 flags);
926
927 disconnect_task
928 = GNUNET_SCHEDULER_add_delayed (SHORT_TIME,
929 &gather_stats_and_exit,
930 (void *) __LINE__);
931 if (KEEPALIVE == test)
932 return; /* Don't send any data. */
933
934 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
935 "Sending data initializer...\n");
936 data_received = 0;
937 data_sent = 0;
938 ack_received = 0;
939 ack_sent = 0;
940 th = GNUNET_CADET_notify_transmit_ready (ch,
941 GNUNET_NO,
942 GNUNET_TIME_UNIT_FOREVER_REL,
943 size_payload + 1000,
944 &tmt_rdy, (void *) 0L);
945}
946
947
948/**
949 * Callback to be called when the requested peer information is available
950 *
951 * @param cls the closure from GNUNET_TESTBED_peer_get_information()
952 * @param op the operation this callback corresponds to
953 * @param pinfo the result; will be NULL if the operation has failed
954 * @param emsg error message if the operation has failed;
955 * NULL if the operation is successfull
956 */
957static void
958pi_cb (void *cls,
959 struct GNUNET_TESTBED_Operation *op,
960 const struct GNUNET_TESTBED_PeerInformation *pinfo,
961 const char *emsg)
962{
963 long i = (long) cls;
964
965 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
966 "id callback for %ld\n", i);
967
968 if ( (NULL == pinfo) ||
969 (NULL != emsg) )
970 {
971 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
972 "pi_cb: %s\n", emsg);
973 abort_test (__LINE__);
974 return;
975 }
976 p_id[i] = pinfo->result.id;
977 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
978 " id: %s\n", GNUNET_i2s (p_id[i]));
979 p_ids++;
980 if (p_ids < 2)
981 return;
982 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
983 "Got all IDs, starting test\n");
984 test_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
985 &do_test,
986 NULL);
987}
988
989
990/**
991 * test main: start test when all peers are connected
992 *
993 * @param cls Closure.
994 * @param ctx Argument to give to GNUNET_CADET_TEST_cleanup on test end.
995 * @param num_peers Number of peers that are running.
996 * @param peers Array of peers.
997 * @param cadetes Handle to each of the CADETs of the peers.
998 */
999static void
1000tmain (void *cls,
1001 struct GNUNET_CADET_TEST_Context *ctx,
1002 unsigned int num_peers,
1003 struct GNUNET_TESTBED_Peer **peers,
1004 struct GNUNET_CADET_Handle **cadets)
1005{
1006 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test main\n");
1007 ok = 0;
1008 test_ctx = ctx;
1009 peers_running = num_peers;
1010 GNUNET_assert (peers_running == peers_requested);
1011 testbed_peers = peers;
1012 h1 = cadets[0];
1013 h2 = cadets[num_peers - 1];
1014 disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME,
1015 &disconnect_cadet_peers,
1016 (void *) __LINE__);
1017 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL);
1018 t_op[0] = GNUNET_TESTBED_peer_get_information (peers[0],
1019 GNUNET_TESTBED_PIT_IDENTITY,
1020 &pi_cb, (void *) 0L);
1021 t_op[1] = GNUNET_TESTBED_peer_get_information (peers[num_peers - 1],
1022 GNUNET_TESTBED_PIT_IDENTITY,
1023 &pi_cb, (void *) 1L);
1024 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "requested peer ids\n");
1025}
1026
1027
1028/**
1029 * Main: start test
1030 */
1031int
1032main (int argc, char *argv[])
1033{
1034 initialized = GNUNET_NO;
1035 static const struct GNUNET_HashCode *ports[2];
1036 const char *config_file;
1037 char port_id[] = "test port";
1038 GNUNET_CRYPTO_hash (port_id, sizeof (port_id), &port);
1039
1040 GNUNET_log_setup ("test", "DEBUG", NULL);
1041 config_file = "test_cadet.conf";
1042
1043 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Start\n");
1044
1045 /* Find out requested size */
1046 if (strstr (argv[0], "_2_") != NULL)
1047 {
1048 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "DIRECT CONNECTIONs\n");
1049 peers_requested = 2;
1050 }
1051 else if (strstr (argv[0], "_5_") != NULL)
1052 {
1053 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "5 PEER LINE\n");
1054 peers_requested = 5;
1055 }
1056 else
1057 {
1058 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "SIZE UNKNOWN, USING 2\n");
1059 peers_requested = 2;
1060 }
1061
1062 /* Find out requested test */
1063 if (strstr (argv[0], "_forward") != NULL)
1064 {
1065 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "FORWARD\n");
1066 test = FORWARD;
1067 test_name = "unicast";
1068 ok_goal = 4;
1069 }
1070 else if (strstr (argv[0], "_signal") != NULL)
1071 {
1072 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "SIGNAL\n");
1073 test = P2P_SIGNAL;
1074 test_name = "signal";
1075 ok_goal = 4;
1076 }
1077 else if (strstr (argv[0], "_speed_ack") != NULL)
1078 {
1079 /* Test is supposed to generate the following callbacks:
1080 * 1 incoming channel (@dest)
1081 * TOTAL_PACKETS received data packet (@dest)
1082 * TOTAL_PACKETS received data packet (@orig)
1083 * 1 received channel destroy (@dest)
1084 */
1085 ok_goal = TOTAL_PACKETS * 2 + 2;
1086 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "SPEED_ACK\n");
1087 test = SPEED_ACK;
1088 test_name = "speed ack";
1089 }
1090 else if (strstr (argv[0], "_speed") != NULL)
1091 {
1092 /* Test is supposed to generate the following callbacks:
1093 * 1 incoming channel (@dest)
1094 * 1 initial packet (@dest)
1095 * TOTAL_PACKETS received data packet (@dest)
1096 * 1 received data packet (@orig)
1097 * 1 received channel destroy (@dest)
1098 */
1099 ok_goal = TOTAL_PACKETS + 4;
1100 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "SPEED\n");
1101 if (strstr (argv[0], "_reliable") != NULL)
1102 {
1103 test = SPEED_REL;
1104 test_name = "speed reliable";
1105 config_file = "test_cadet_drop.conf";
1106 }
1107 else
1108 {
1109 test = SPEED;
1110 test_name = "speed";
1111 }
1112 }
1113 else if (strstr (argv[0], "_keepalive") != NULL)
1114 {
1115 test = KEEPALIVE;
1116 /* Test is supposed to generate the following callbacks:
1117 * 1 incoming channel (@dest)
1118 * [wait]
1119 * 1 received channel destroy (@dest)
1120 */
1121 ok_goal = 2;
1122 }
1123 else
1124 {
1125 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "UNKNOWN\n");
1126 test = SETUP;
1127 ok_goal = 0;
1128 }
1129
1130 if (strstr (argv[0], "backwards") != NULL)
1131 {
1132 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "BACKWARDS (LEAF TO ROOT)\n");
1133 test_backwards = GNUNET_YES;
1134 GNUNET_asprintf (&test_name, "backwards %s", test_name);
1135 }
1136
1137 p_ids = 0;
1138 ports[0] = &port;
1139 ports[1] = NULL;
1140 GNUNET_CADET_TEST_run ("test_cadet_small",
1141 config_file,
1142 peers_requested,
1143 &tmain,
1144 NULL, /* tmain cls */
1145 &incoming_channel,
1146 &channel_cleaner,
1147 handlers,
1148 ports);
1149 if (NULL != strstr (argv[0], "_reliable"))
1150 msg_dropped = 0; /* dropped should be retransmitted */
1151
1152 if (ok_goal > ok - msg_dropped)
1153 {
1154 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1155 "FAILED! (%d/%d)\n", ok, ok_goal);
1156 return 1;
1157 }
1158 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "success\n");
1159 return 0;
1160}
1161
1162/* end of test_cadet.c */
diff --git a/src/cadet/test_cadet_local.c b/src/cadet/test_cadet_local.c
deleted file mode 100644
index 2b915ab81..000000000
--- a/src/cadet/test_cadet_local.c
+++ /dev/null
@@ -1,351 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2011 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 cadet/test_cadet_local.c
23 * @brief test cadet local: test of cadet channels 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_cadet_service.h"
32
33struct GNUNET_TESTING_Peer *me;
34
35static struct GNUNET_CADET_Handle *cadet_peer_1;
36
37static struct GNUNET_CADET_Handle *cadet_peer_2;
38
39static struct GNUNET_CADET_Channel *ch;
40
41static int result = GNUNET_OK;
42
43static int got_data = GNUNET_NO;
44
45static struct GNUNET_SCHEDULER_Task *abort_task;
46
47static struct GNUNET_SCHEDULER_Task *connect_task;
48
49static struct GNUNET_CADET_TransmitHandle *mth;
50
51
52/**
53 * Connect to other client and send data
54 *
55 * @param cls Closue (unused).
56 */
57static void
58do_connect (void *cls);
59
60
61/**
62 * Shutdown nicely
63 */
64static void
65do_shutdown (void *cls)
66{
67 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
68 "shutdown\n");
69 if (NULL != abort_task)
70 {
71 GNUNET_SCHEDULER_cancel (abort_task);
72 abort_task = NULL;
73 }
74 if (NULL != ch)
75 {
76 GNUNET_CADET_channel_destroy (ch);
77 ch = NULL;
78 }
79 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
80 "Disconnect client 1\n");
81 if (NULL != cadet_peer_1)
82 {
83 GNUNET_CADET_disconnect (cadet_peer_1);
84 cadet_peer_1 = NULL;
85 }
86 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
87 "Disconnect client 2\n");
88 if (NULL != cadet_peer_2)
89 {
90 GNUNET_CADET_disconnect (cadet_peer_2);
91 cadet_peer_2 = NULL;
92 }
93 if (NULL != connect_task)
94 {
95 GNUNET_SCHEDULER_cancel (connect_task);
96 connect_task = NULL;
97 }
98}
99
100
101/**
102 * Something went wrong and timed out. Kill everything and set error flag
103 */
104static void
105do_abort (void *cls)
106{
107 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ABORT\n");
108 result = GNUNET_SYSERR;
109 abort_task = NULL;
110 GNUNET_SCHEDULER_shutdown ();
111}
112
113
114/**
115 * Function is called whenever a message is received.
116 *
117 * @param cls closure (set from GNUNET_CADET_connect)
118 * @param channel connection to the other end
119 * @param channel_ctx place to store local state associated with the channel
120 * @param message the actual message
121 * @return #GNUNET_OK to keep the connection open,
122 * #GNUNET_SYSERR to close it (signal serious error)
123 */
124static int
125data_callback (void *cls,
126 struct GNUNET_CADET_Channel *channel,
127 void **channel_ctx,
128 const struct GNUNET_MessageHeader *message)
129{
130 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
131 "Data callback! Shutting down.\n");
132 got_data = GNUNET_YES;
133 GNUNET_SCHEDULER_shutdown ();
134 GNUNET_CADET_receive_done (channel);
135 return GNUNET_OK;
136}
137
138
139/**
140 * Method called whenever another peer has added us to a channel
141 * the other peer initiated.
142 *
143 * @param cls closure
144 * @param channel new handle to the channel
145 * @param initiator peer that started the channel
146 * @param port port number
147 * @param options channel options
148 * @return initial channel context for the channel
149 * (can be NULL -- that's not an error)
150 */
151static void *
152inbound_channel (void *cls,
153 struct GNUNET_CADET_Channel *channel,
154 const struct GNUNET_PeerIdentity *initiator,
155 const struct GNUNET_HashCode *port,
156 enum GNUNET_CADET_ChannelOption options)
157{
158 long id = (long) cls;
159
160 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
161 "received incoming channel on peer %d, port %s\n",
162 (int) id,
163 GNUNET_h2s (port));
164 if (id != 2L)
165 {
166 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
167 "wrong peer\n");
168 result = GNUNET_SYSERR;
169 }
170 return NULL;
171}
172
173
174/**
175 * Function called whenever an channel is destroyed. Should clean up
176 * any associated state.
177 *
178 * @param cls closure (set from GNUNET_CADET_connect)
179 * @param channel connection to the other end (henceforth invalid)
180 * @param channel_ctx place where local state associated
181 * with the channel is stored
182 */
183static void
184channel_end (void *cls,
185 const struct GNUNET_CADET_Channel *channel,
186 void *channel_ctx)
187{
188 long id = (long) cls;
189
190 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
191 "incoming channel closed at peer %ld\n",
192 id);
193 if (NULL != mth)
194 {
195 GNUNET_CADET_notify_transmit_ready_cancel (mth);
196 mth = NULL;
197 }
198 if (channel == ch)
199 ch = NULL;
200 if (GNUNET_NO == got_data)
201 {
202 if (NULL == connect_task)
203 connect_task
204 = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
205 2),
206 &do_connect,
207 NULL);
208 }
209}
210
211
212/**
213 * Handler array for traffic received on peer1
214 */
215static struct GNUNET_CADET_MessageHandler handlers1[] = {
216 {&data_callback, 1, 0},
217 {NULL, 0, 0}
218};
219
220
221/**
222 * Handler array for traffic received on peer2 (none expected)
223 */
224static struct GNUNET_CADET_MessageHandler handlers2[] = {
225 {&data_callback, 1, 0},
226 {NULL, 0, 0}
227};
228
229
230/**
231 * Data send callback: fillbuffer with test packet.
232 *
233 * @param cls Closure (unused).
234 * @param size Buffer size.
235 * @param buf Buffer to fill.
236 *
237 * @return size of test packet.
238 */
239static size_t
240do_send (void *cls, size_t size, void *buf)
241{
242 struct GNUNET_MessageHeader *m = buf;
243
244 mth = NULL;
245 if (NULL == buf)
246 {
247 GNUNET_break (0);
248 result = GNUNET_SYSERR;
249 return 0;
250 }
251 m->size = htons (sizeof (struct GNUNET_MessageHeader));
252 m->type = htons (1);
253 GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader));
254 return sizeof (struct GNUNET_MessageHeader);
255}
256
257
258/**
259 * Connect to other client and send data
260 *
261 * @param cls Closue (unused).
262 */
263static void
264do_connect (void *cls)
265{
266 struct GNUNET_PeerIdentity id;
267
268 connect_task = NULL;
269 GNUNET_TESTING_peer_get_identity (me, &id);
270 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
271 "CONNECT BY PORT\n");
272 ch = GNUNET_CADET_channel_create (cadet_peer_1,
273 NULL,
274 &id, GC_u2h (1),
275 GNUNET_CADET_OPTION_DEFAULT);
276 mth = GNUNET_CADET_notify_transmit_ready (ch, GNUNET_NO,
277 GNUNET_TIME_UNIT_FOREVER_REL,
278 sizeof (struct GNUNET_MessageHeader),
279 &do_send, NULL);
280}
281
282
283/**
284 * Initialize framework and start test
285 *
286 * @param cls Closure (unused).
287 * @param cfg Configuration handle.
288 * @param peer Testing peer handle.
289 */
290static void
291run (void *cls,
292 const struct GNUNET_CONFIGURATION_Handle *cfg,
293 struct GNUNET_TESTING_Peer *peer)
294{
295 me = peer;
296 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
297 NULL);
298 abort_task =
299 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
300 (GNUNET_TIME_UNIT_SECONDS, 15),
301 &do_abort,
302 NULL);
303 cadet_peer_1 = GNUNET_CADET_connect (cfg, /* configuration */
304 (void *) 1L, /* cls */
305 &channel_end, /* channel end hndlr */
306 handlers1); /* traffic handlers */
307 cadet_peer_2 = GNUNET_CADET_connect (cfg, /* configuration */
308 (void *) 2L, /* cls */
309 &channel_end, /* channel end hndlr */
310 handlers2); /* traffic handlers */
311
312 if ( (NULL == cadet_peer_1) ||
313 (NULL == cadet_peer_2) )
314 {
315 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
316 "Couldn't connect to cadet :(\n");
317 result = GNUNET_SYSERR;
318 GNUNET_SCHEDULER_shutdown ();
319 return;
320 }
321 GNUNET_CADET_open_port (cadet_peer_2,
322 GC_u2h (1),
323 &inbound_channel,
324 (void *) 2L);
325 if (NULL == connect_task)
326 connect_task
327 = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
328 2),
329 &do_connect,
330 NULL);
331}
332
333
334/**
335 * Main
336 */
337int
338main (int argc, char *argv[])
339{
340 if (0 != GNUNET_TESTING_peer_run ("test-cadet-local",
341 "test_cadet.conf",
342 &run, NULL))
343 {
344 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "run failed\n");
345 return 2;
346 }
347 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Final result: %d\n", result);
348 return (result == GNUNET_OK) ? 0 : 1;
349}
350
351/* end of test_cadet_local_1.c */
diff --git a/src/cadet/test_cadet_single.c b/src/cadet/test_cadet_single.c
deleted file mode 100644
index b45b0af5d..000000000
--- a/src/cadet/test_cadet_single.c
+++ /dev/null
@@ -1,354 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2011 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 cadet/test_cadet_single.c
23 * @brief test cadet single: test of cadet channels with just one client
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_cadet_service.h"
32
33#define REPETITIONS 5
34#define DATA_SIZE 35000
35
36struct GNUNET_TESTING_Peer *me;
37
38static struct GNUNET_CADET_Handle *cadet;
39
40static struct GNUNET_CADET_Channel *ch1;
41
42static struct GNUNET_CADET_Channel *ch2;
43
44static int result;
45
46static struct GNUNET_SCHEDULER_Task *abort_task;
47
48static struct GNUNET_SCHEDULER_Task *connect_task;
49
50static unsigned int repetition;
51
52static struct GNUNET_CADET_TransmitHandle *nth;
53
54static struct GNUNET_CADET_Port *port;
55
56
57/* forward declaration */
58static size_t
59do_send (void *cls, size_t size, void *buf);
60
61
62/**
63 * Shutdown nicely
64 */
65static void
66do_shutdown (void *cls)
67{
68 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
69 "shutdown\n");
70 if (NULL != port)
71 {
72 GNUNET_CADET_close_port (port);
73 port = NULL;
74 }
75 if (NULL != nth)
76 {
77 GNUNET_CADET_notify_transmit_ready_cancel (nth);
78 nth = NULL;
79 }
80 if (NULL != abort_task)
81 {
82 GNUNET_SCHEDULER_cancel (abort_task);
83 abort_task = NULL;
84 }
85 if (NULL != connect_task)
86 {
87 GNUNET_SCHEDULER_cancel (connect_task);
88 connect_task = NULL;
89 }
90 if (NULL != ch1)
91 {
92 GNUNET_CADET_channel_destroy (ch1);
93 ch1 = NULL;
94 }
95 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
96 "Disconnect clients\n");
97 if (NULL != cadet)
98 {
99 GNUNET_CADET_disconnect (cadet);
100 cadet = NULL;
101 }
102 else
103 {
104 GNUNET_break (0);
105 }
106}
107
108
109/**
110 * Something went wrong and timed out. Kill everything and set error flag
111 */
112static void
113do_abort (void *cls)
114{
115 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ABORT\n");
116 result = GNUNET_SYSERR;
117 abort_task = NULL;
118 GNUNET_SCHEDULER_shutdown ();
119}
120
121
122/**
123 * Function is called whenever a message is received.
124 *
125 * @param cls closure (set from GNUNET_CADET_connect)
126 * @param channel connection to the other end
127 * @param channel_ctx place to store local state associated with the channel
128 * @param message the actual message
129 * @return #GNUNET_OK to keep the connection open,
130 * #GNUNET_SYSERR to close it (signal serious error)
131 */
132static int
133data_callback (void *cls,
134 struct GNUNET_CADET_Channel *channel,
135 void **channel_ctx,
136 const struct GNUNET_MessageHeader *message)
137{
138 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
139 "Data callback! Repetition %u/%u\n",
140 repetition, REPETITIONS);
141 repetition++;
142 if (repetition < REPETITIONS)
143 {
144 struct GNUNET_CADET_Channel *my_channel;
145 if (0 == repetition % 2)
146 my_channel = ch1;
147 else
148 my_channel = ch2;
149 nth = GNUNET_CADET_notify_transmit_ready (my_channel,
150 GNUNET_NO,
151 GNUNET_TIME_UNIT_FOREVER_REL,
152 sizeof (struct GNUNET_MessageHeader)
153 + DATA_SIZE,
154 &do_send, NULL);
155 GNUNET_CADET_receive_done (channel);
156 return GNUNET_OK;
157 }
158 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
159 "All data OK. Destroying channel.\n");
160 GNUNET_assert (NULL == nth);
161 GNUNET_CADET_channel_destroy (ch1);
162 ch1 = NULL;
163 return GNUNET_OK;
164}
165
166
167/**
168 * Method called whenever another peer has added us to a channel
169 * the other peer initiated.
170 *
171 * @param cls closure
172 * @param channel new handle to the channel
173 * @param initiator peer that started the channel
174 * @param port port number
175 * @param options channel option flags
176 * @return initial channel context for the channel
177 * (can be NULL -- that's not an error)
178 */
179static void *
180inbound_channel (void *cls,
181 struct GNUNET_CADET_Channel *channel,
182 const struct GNUNET_PeerIdentity *initiator,
183 const struct GNUNET_HashCode *port,
184 enum GNUNET_CADET_ChannelOption options)
185{
186 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
187 "received incoming channel on port %s\n",
188 GNUNET_h2s (port));
189 ch2 = channel;
190 return NULL;
191}
192
193
194/**
195 * Function called whenever an inbound channel is destroyed. Should clean up
196 * any associated state.
197 *
198 * @param cls closure (set from GNUNET_CADET_connect)
199 * @param channel connection to the other end (henceforth invalid)
200 * @param channel_ctx place where local state associated
201 * with the channel is stored
202 */
203static void
204channel_end (void *cls,
205 const struct GNUNET_CADET_Channel *channel,
206 void *channel_ctx)
207{
208 long id = (long) cls;
209
210 nth = NULL;
211 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
212 "incoming channel closed at peer %ld\n",
213 id);
214 if ( (REPETITIONS == repetition) &&
215 (channel == ch2) )
216 {
217 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
218 "everything fine! finishing!\n");
219 result = GNUNET_OK;
220 GNUNET_SCHEDULER_shutdown ();
221 }
222 if (channel == ch2)
223 ch2 = NULL;
224 if (channel == ch1)
225 ch1 = NULL;
226}
227
228
229/**
230 * Handler array for traffic received on peer1
231 */
232static struct GNUNET_CADET_MessageHandler handlers1[] = {
233 {&data_callback, 1, 0},
234 {NULL, 0, 0}
235};
236
237
238/**
239 * Data send callback: fillbuffer with test packet.
240 *
241 * @param cls Closure (unused).
242 * @param size Buffer size.
243 * @param buf Buffer to fill.
244 * @return size of test packet.
245 */
246static size_t
247do_send (void *cls, size_t size, void *buf)
248{
249 struct GNUNET_MessageHeader *m = buf;
250
251 nth = NULL;
252 if (NULL == buf)
253 {
254 GNUNET_break (0);
255 result = GNUNET_SYSERR;
256 return 0;
257 }
258 m->size = htons (sizeof (struct GNUNET_MessageHeader) + DATA_SIZE);
259 m->type = htons (1);
260 memset (&m[1], 0, DATA_SIZE);
261 GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader) + DATA_SIZE);
262 return sizeof (struct GNUNET_MessageHeader) + DATA_SIZE;
263}
264
265/**
266 * Connect to other client and send data
267 *
268 * @param cls Closue (unused).
269 */
270static void
271do_connect (void *cls)
272{
273 struct GNUNET_PeerIdentity id;
274 size_t size = sizeof (struct GNUNET_MessageHeader) + DATA_SIZE;
275
276 connect_task = NULL;
277 GNUNET_TESTING_peer_get_identity (me, &id);
278 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CONNECT BY PORT\n");
279 ch1 = GNUNET_CADET_channel_create (cadet, NULL, &id, GC_u2h (1),
280 GNUNET_CADET_OPTION_DEFAULT);
281 nth = GNUNET_CADET_notify_transmit_ready (ch1,
282 GNUNET_NO,
283 GNUNET_TIME_UNIT_FOREVER_REL,
284 size,
285 &do_send,
286 NULL);
287}
288
289
290/**
291 * Initialize framework and start test
292 *
293 * @param cls Closure (unused).
294 * @param cfg Configuration handle.
295 * @param peer Testing peer handle.
296 */
297static void
298run (void *cls,
299 const struct GNUNET_CONFIGURATION_Handle *cfg,
300 struct GNUNET_TESTING_Peer *peer)
301{
302 me = peer;
303 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
304 abort_task =
305 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
306 (GNUNET_TIME_UNIT_SECONDS, 15), &do_abort,
307 NULL);
308 cadet = GNUNET_CADET_connect (cfg, /* configuration */
309 (void *) 1L, /* cls */
310 &channel_end, /* inbound end hndlr */
311 handlers1); /* traffic handlers */
312 port = GNUNET_CADET_open_port (cadet,
313 GC_u2h (1),
314 &inbound_channel,
315 (void *) 1L);
316
317
318 if (NULL == cadet)
319 {
320 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
321 "Couldn't connect to cadet :(\n");
322 result = GNUNET_SYSERR;
323 return;
324 }
325 connect_task
326 = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
327 &do_connect,
328 NULL);
329}
330
331
332/**
333 * Main
334 */
335int
336main (int argc,
337 char *argv[])
338{
339 result = GNUNET_NO;
340 if (0 != GNUNET_TESTING_peer_run ("test-cadet-local",
341 "test_cadet.conf",
342 &run, NULL))
343 {
344 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
345 "run failed\n");
346 return 2;
347 }
348 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
349 "Final result: %d\n",
350 result);
351 return (result == GNUNET_OK) ? 0 : 1;
352}
353
354/* end of test_cadet_single.c */