aboutsummaryrefslogtreecommitdiff
path: root/src/transport/transport-testing.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/transport-testing.c')
-rw-r--r--src/transport/transport-testing.c302
1 files changed, 199 insertions, 103 deletions
diff --git a/src/transport/transport-testing.c b/src/transport/transport-testing.c
index 08bcd5c4e..036fff9e4 100644
--- a/src/transport/transport-testing.c
+++ b/src/transport/transport-testing.c
@@ -27,67 +27,58 @@
27 27
28#include "transport-testing.h" 28#include "transport-testing.h"
29 29
30struct ConnectingContext 30#define VERBOSE GNUNET_EXTRA_LOGGING
31{
32 struct PeerContext *p1;
33 struct PeerContext *p2;
34 GNUNET_SCHEDULER_TaskIdentifier tct;
35 GNUNET_TRANSPORT_TESTING_connect_cb cb;
36 void *cb_cls;
37 struct GNUNET_TRANSPORT_Handle *th_p1;
38 struct GNUNET_TRANSPORT_Handle *th_p2;
39 int p1_c;
40 int p2_c;
41};
42 31
43static void 32struct PeerContext *
44exchange_hello_last (void *cb_cls, const struct GNUNET_MessageHeader *message); 33find_peer_context_by_pc ( struct TransportTestingHandle *tth,
45static void 34 struct PeerContext *p)
46exchange_hello (void *cb_cls, const struct GNUNET_MessageHeader *message);
47
48static void
49notify_connect_internal (void *cls, const struct GNUNET_PeerIdentity *peer,
50 const struct GNUNET_TRANSPORT_ATS_Information *ats,
51 uint32_t ats_count)
52{ 35{
53 struct ConnectingContext *cc = cls; 36 struct PeerContext * t = tth->p_head;
54
55 GNUNET_assert (cc != NULL);
56 37
57 if (0 == 38 while (t != NULL)
58 memcmp (&(*peer).hashPubKey, &cc->p1->id.hashPubKey,
59 sizeof (GNUNET_HashCode)))
60 {
61 if (cc->p1_c == GNUNET_NO)
62 cc->p1_c = GNUNET_YES;
63 }
64 if (0 ==
65 memcmp (&(*peer).hashPubKey, &cc->p2->id.hashPubKey,
66 sizeof (GNUNET_HashCode)))
67 { 39 {
68 if (cc->p2_c == GNUNET_NO) 40 if (p == t)
69 cc->p2_c = GNUNET_YES; 41 break;
42 t = t->next;
70 } 43 }
71 44
72 if ((cc->p2_c == GNUNET_YES) && (cc->p2_c == GNUNET_YES)) 45 return t;
73 { 46}
74 /* clean up */
75 GNUNET_TRANSPORT_get_hello_cancel (cc->p1->ghh);
76 GNUNET_TRANSPORT_get_hello_cancel (cc->p2->ghh);
77 47
78 if (cc->tct != GNUNET_SCHEDULER_NO_TASK)
79 GNUNET_SCHEDULER_cancel (cc->tct);
80 48
81 cc->tct = GNUNET_SCHEDULER_NO_TASK; 49struct PeerContext *
50find_peer_context ( struct TransportTestingHandle *tth,
51 const struct GNUNET_PeerIdentity *peer)
52{
53 struct PeerContext * t = tth->p_head;
54
55 while (t != NULL)
56 {
57 if (0 == memcmp (&t->id, peer, sizeof (struct GNUNET_PeerIdentity)))
58 break;
59 t = t->next;
60 }
82 61
83 GNUNET_TRANSPORT_disconnect (cc->th_p1); 62 return t;
84 GNUNET_TRANSPORT_disconnect (cc->th_p2); 63}
85 64
86 if (cc->cb != NULL) 65struct ConnectingContext *
87 cc->cb (cc->p1, cc->p2, cc->cb_cls); 66find_connecting_context ( struct TransportTestingHandle *tth,
67 struct PeerContext *p1,
68 struct PeerContext * p2)
69{
70 struct ConnectingContext * cc = tth->cc_head;
88 71
89 GNUNET_free (cc); 72 while (cc != NULL)
73 {
74 if ((cc->p1 == p1) && (cc->p2 == p2))
75 break;
76 if ((cc->p1 == p2) && (cc->p2 == p1))
77 break;
78 cc = cc->next;
90 } 79 }
80
81 return cc;
91} 82}
92 83
93static void 84static void
@@ -96,17 +87,63 @@ notify_connect (void *cls, const struct GNUNET_PeerIdentity *peer,
96 uint32_t ats_count) 87 uint32_t ats_count)
97{ 88{
98 struct PeerContext *p = cls; 89 struct PeerContext *p = cls;
90 /* Find PeerContext */
91 struct PeerContext * p2 = find_peer_context (p->tth, peer);
99 92
100 if (p == NULL) 93 if (p == NULL)
101 return; 94 return;
102 if (p->nc != NULL) 95 if (p->nc != NULL)
103 p->nc (p->cb_cls, peer, ats, ats_count); 96 p->nc (p->cb_cls, peer, ats, ats_count);
97
98#if VERBOSE
99 char * p2_s;
100 if (p2 != NULL)
101 GNUNET_asprintf(&p2_s, "%u (`%s')", p2->no, GNUNET_i2s (&p2->id));
102 else
103 GNUNET_asprintf(&p2_s, "`%s'", GNUNET_i2s (peer));
104 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-testing",
105 "Peers %s connected to peer %u (`%s')\n",
106 p2_s,
107 p->no, GNUNET_i2s (&p->id));
108 GNUNET_free (p2_s);
109#endif
110
111
112 /* Find ConnectingContext */
113 struct ConnectingContext * cc = find_connecting_context(p->tth, p, p2);
114 if (cc == NULL)
115 return;
116
117 if (p == cc->p1)
118 cc->p1_c = GNUNET_YES;
119
120 if (p == cc->p2)
121 cc->p2_c = GNUNET_YES;
122
123 if ((cc->p1_c == GNUNET_YES) && (cc->p2_c == GNUNET_YES))
124 {
125 cc->cb (cc->p1, cc->p2, cc->cb_cls);
126 GNUNET_TRANSPORT_TESTING_connect_peers_cancel(p->tth, cc);
127 }
104} 128}
105 129
106static void 130static void
107notify_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) 131notify_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
108{ 132{
109 struct PeerContext *p = cls; 133 struct PeerContext *p = cls;
134 /* Find PeerContext */
135 struct PeerContext * p2 = find_peer_context (p->tth, peer);
136
137 char * p2_s;
138 if (p2 != NULL)
139 GNUNET_asprintf(&p2_s, "%u (`%s')", p2->no, GNUNET_i2s (&p2->id));
140 else
141 GNUNET_asprintf(&p2_s, "`%s'", GNUNET_i2s (peer));
142 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-testing",
143 "Peers %s disconnected from peer %u (`%s')\n",
144 p2_s,
145 p->no, GNUNET_i2s (&p->id));
146 GNUNET_free (p2_s);
110 147
111 if (p == NULL) 148 if (p == NULL)
112 return; 149 return;
@@ -128,46 +165,38 @@ notify_receive (void *cls, const struct GNUNET_PeerIdentity *peer,
128 p->rec (p->cb_cls, peer, message, ats, ats_count); 165 p->rec (p->cb_cls, peer, message, ats, ats_count);
129} 166}
130 167
131
132static void 168static void
133exchange_hello_last (void *cb_cls, const struct GNUNET_MessageHeader *message) 169get_hello (void *cb_cls, const struct GNUNET_MessageHeader *message)
134{ 170{
135 struct ConnectingContext *cc = cb_cls; 171 struct PeerContext *p = cb_cls;
136 struct PeerContext *me = cc->p2;
137
138 //struct PeerContext *p1 = cc->p1;
139 172
140 GNUNET_assert (message != NULL); 173 GNUNET_assert (message != NULL);
141 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
142 "Exchanging HELLO of size %d with peer (%s)!\n",
143 (int) GNUNET_HELLO_size ((const struct GNUNET_HELLO_Message *)
144 message), GNUNET_i2s (&me->id));
145 GNUNET_assert (GNUNET_OK == 174 GNUNET_assert (GNUNET_OK ==
146 GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) 175 GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *)
147 message, &me->id)); 176 message, &p->id));
148 GNUNET_TRANSPORT_offer_hello (cc->th_p1, message, NULL, NULL);
149}
150 177
178 if (p->hello != NULL)
179 GNUNET_free (p->hello);
151 180
152static void 181 size_t size = GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *) message);
153exchange_hello (void *cb_cls, const struct GNUNET_MessageHeader *message) 182 p->hello = GNUNET_malloc (size);
154{ 183 memcpy (p->hello,
155 struct ConnectingContext *cc = cb_cls; 184 (const struct GNUNET_HELLO_Message *) message,
156 struct PeerContext *me = cc->p1; 185 size);
157
158 //struct PeerContext *p2 = cc->p2;
159 186
160 GNUNET_assert (message != NULL); 187 if (p->start_cb != NULL)
161 GNUNET_assert (GNUNET_OK == 188 {
162 GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) 189#if VERBOSE
163 message, &me->id)); 190 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-testing",
164 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 191 "Peer %u (`%s') successfully started\n",
165 "Exchanging HELLO of size %d from peer %s!\n", 192 p->no, GNUNET_i2s (&p->id), size);
166 (int) GNUNET_HELLO_size ((const struct GNUNET_HELLO_Message *) 193#endif
167 message), GNUNET_i2s (&me->id)); 194 p->start_cb(p, p->cb_cls);
168 GNUNET_TRANSPORT_offer_hello (cc->th_p2, message, NULL, NULL); 195 p->start_cb = NULL;
196 }
169} 197}
170 198
199
171static void 200static void
172try_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 201try_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
173{ 202{
@@ -179,10 +208,15 @@ try_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
179 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) 208 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
180 return; 209 return;
181 210
182 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Asking peers to connect...\n"); 211 char * p2_s = strdup(GNUNET_i2s (&p2->id));
183 /* FIXME: 'pX.id' may still be all-zeros here... */ 212 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-testing",
213 "Asking peers %u (`%s') to connect peer %u (`%s')\n",
214 p1->no, GNUNET_i2s (&p1->id), p2->no, p2_s);
215 GNUNET_free (p2_s);
216
217 GNUNET_TRANSPORT_offer_hello (cc->th_p1,
218 (const struct GNUNET_MessageHeader *) cc->p2->hello, NULL, NULL);
184 GNUNET_TRANSPORT_try_connect (cc->th_p1, &p2->id); 219 GNUNET_TRANSPORT_try_connect (cc->th_p1, &p2->id);
185 GNUNET_TRANSPORT_try_connect (cc->th_p2, &p1->id);
186 220
187 cc->tct = 221 cc->tct =
188 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &try_connect, cc); 222 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &try_connect, cc);
@@ -198,15 +232,19 @@ try_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
198 * @return the peer context 232 * @return the peer context
199 */ 233 */
200struct PeerContext * 234struct PeerContext *
201GNUNET_TRANSPORT_TESTING_start_peer (const char *cfgname, 235GNUNET_TRANSPORT_TESTING_start_peer (struct TransportTestingHandle * tth,
236 const char *cfgname,
237 int peer_id,
202 GNUNET_TRANSPORT_ReceiveCallback rec, 238 GNUNET_TRANSPORT_ReceiveCallback rec,
203 GNUNET_TRANSPORT_NotifyConnect nc, 239 GNUNET_TRANSPORT_NotifyConnect nc,
204 GNUNET_TRANSPORT_NotifyDisconnect nd, 240 GNUNET_TRANSPORT_NotifyDisconnect nd,
241 GNUNET_TRANSPORT_TESTING_start_cb start_cb,
205 void *cb_cls) 242 void *cb_cls)
206{ 243{
207 if (GNUNET_DISK_file_test (cfgname) == GNUNET_NO) 244 if (GNUNET_DISK_file_test (cfgname) == GNUNET_NO)
208 { 245 {
209 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "File not found: `%s' \n", cfgname); 246 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "transport-testing",
247 "File not found: `%s' \n", cfgname);
210 return NULL; 248 return NULL;
211 } 249 }
212 250
@@ -229,9 +267,13 @@ GNUNET_TRANSPORT_TESTING_start_peer (const char *cfgname,
229 "-L", "ERROR", 267 "-L", "ERROR",
230#endif 268#endif
231 NULL); 269 NULL);
270
271 p->no = peer_id;
272 p->tth = tth;
232 p->nc = nc; 273 p->nc = nc;
233 p->nd = nd; 274 p->nd = nd;
234 p->rec = rec; 275 p->rec = rec;
276 p->start_cb = start_cb;
235 if (cb_cls != NULL) 277 if (cb_cls != NULL)
236 p->cb_cls = cb_cls; 278 p->cb_cls = cb_cls;
237 else 279 else
@@ -241,6 +283,12 @@ GNUNET_TRANSPORT_TESTING_start_peer (const char *cfgname,
241 GNUNET_TRANSPORT_connect (p->cfg, NULL, p, &notify_receive, 283 GNUNET_TRANSPORT_connect (p->cfg, NULL, p, &notify_receive,
242 &notify_connect, &notify_disconnect); 284 &notify_connect, &notify_disconnect);
243 GNUNET_assert (p->th != NULL); 285 GNUNET_assert (p->th != NULL);
286
287 p->ghh = GNUNET_TRANSPORT_get_hello (p->th, &get_hello, p);
288 GNUNET_assert (p->ghh != NULL);
289
290 GNUNET_CONTAINER_DLL_insert(tth->p_head, tth->p_tail, p);
291
244 return p; 292 return p;
245} 293}
246 294
@@ -249,9 +297,15 @@ GNUNET_TRANSPORT_TESTING_start_peer (const char *cfgname,
249 * @param p the peer 297 * @param p the peer
250 */ 298 */
251void 299void
252GNUNET_TRANSPORT_TESTING_stop_peer (struct PeerContext *p) 300GNUNET_TRANSPORT_TESTING_stop_peer (struct TransportTestingHandle * tth,
301 struct PeerContext *p)
253{ 302{
254 GNUNET_assert (p != NULL); 303 GNUNET_assert (p != NULL);
304
305 if (p->ghh != NULL)
306 GNUNET_TRANSPORT_get_hello_cancel (p->ghh);
307 p->ghh = NULL;
308
255 if (p->th != NULL) 309 if (p->th != NULL)
256 GNUNET_TRANSPORT_disconnect (p->th); 310 GNUNET_TRANSPORT_disconnect (p->th);
257 311
@@ -263,22 +317,29 @@ GNUNET_TRANSPORT_TESTING_stop_peer (struct PeerContext *p)
263 GNUNET_OS_process_close (p->arm_proc); 317 GNUNET_OS_process_close (p->arm_proc);
264 p->arm_proc = NULL; 318 p->arm_proc = NULL;
265 } 319 }
320
266 if (p->servicehome != NULL) 321 if (p->servicehome != NULL)
267 { 322 {
268 GNUNET_DISK_directory_remove (p->servicehome); 323 GNUNET_DISK_directory_remove (p->servicehome);
269 GNUNET_free (p->servicehome); 324 GNUNET_free (p->servicehome);
270 } 325 }
271 326
327 if (p->hello != NULL)
328 GNUNET_free (p->hello);
329
272 if (p->cfg != NULL) 330 if (p->cfg != NULL)
273 GNUNET_CONFIGURATION_destroy (p->cfg); 331 GNUNET_CONFIGURATION_destroy (p->cfg);
332
333 GNUNET_CONTAINER_DLL_remove (tth->p_head, tth->p_tail, p);
334
274 GNUNET_free (p); 335 GNUNET_free (p);
275 p = NULL; 336 p = NULL;
276} 337}
277 338
278/** 339/**
279 * Connect the two given peers and call the callback when both peers report the 340 * Initiate peer p1 to connect to peer p2
280 * inbound connect. Remarks: start_peer's notify_connect callback can be called 341 * Get peer p2's HELLO and offer it to p1
281 * before. 342 * p1 then tries to connect to p2
282 * @param p1 peer 1 343 * @param p1 peer 1
283 * @param p2 peer 2 344 * @param p2 peer 2
284 * @param cb the callback to call 345 * @param cb the callback to call
@@ -286,10 +347,12 @@ GNUNET_TRANSPORT_TESTING_stop_peer (struct PeerContext *p)
286 * @return connect context 347 * @return connect context
287 */ 348 */
288GNUNET_TRANSPORT_TESTING_ConnectRequest 349GNUNET_TRANSPORT_TESTING_ConnectRequest
289GNUNET_TRANSPORT_TESTING_connect_peers (struct PeerContext *p1, 350GNUNET_TRANSPORT_TESTING_connect_peers (struct TransportTestingHandle * tth,
351 struct PeerContext *p1,
290 struct PeerContext *p2, 352 struct PeerContext *p2,
291 GNUNET_TRANSPORT_TESTING_connect_cb cb, 353 GNUNET_TRANSPORT_TESTING_connect_cb cb,
292 void *cb_cls) 354 void *cb_cls)
355
293{ 356{
294 struct ConnectingContext *cc = 357 struct ConnectingContext *cc =
295 GNUNET_malloc (sizeof (struct ConnectingContext)); 358 GNUNET_malloc (sizeof (struct ConnectingContext));
@@ -303,22 +366,23 @@ GNUNET_TRANSPORT_TESTING_connect_peers (struct PeerContext *p1,
303 cc->cb = cb; 366 cc->cb = cb;
304 cc->cb_cls = cb_cls; 367 cc->cb_cls = cb_cls;
305 368
306 cc->th_p1 = 369 cc->th_p1 = p1->th;
307 GNUNET_TRANSPORT_connect (cc->p1->cfg, NULL, cc, NULL, 370 /* GNUNET_TRANSPORT_connect (cc->p1->cfg, NULL, cc, NULL,
308 &notify_connect_internal, NULL); 371 &notify_connect_internal, NULL);*/
309 372
310 cc->th_p2 = 373 cc->th_p2 = p2->th;
311 GNUNET_TRANSPORT_connect (cc->p2->cfg, NULL, cc, NULL, 374 /* GNUNET_TRANSPORT_connect (cc->p2->cfg, NULL, cc, NULL,
312 &notify_connect_internal, NULL); 375 &notify_connect_internal, NULL);*/
313 376
314 GNUNET_assert (cc->th_p1 != NULL); 377 GNUNET_assert (cc->th_p1 != NULL);
315 GNUNET_assert (cc->th_p2 != NULL); 378 GNUNET_assert (cc->th_p2 != NULL);
316 379
317 p1->ghh = GNUNET_TRANSPORT_get_hello (cc->th_p1, &exchange_hello, cc); 380 GNUNET_CONTAINER_DLL_insert (tth->cc_head, tth->cc_tail, cc);
318 p2->ghh = GNUNET_TRANSPORT_get_hello (cc->th_p2, &exchange_hello_last, cc);
319 381
320 cc->tct = GNUNET_SCHEDULER_add_now (&try_connect, cc); 382 cc->tct = GNUNET_SCHEDULER_add_now (&try_connect, cc);
321 return cc; 383 return cc;
384
385
322} 386}
323 387
324/** 388/**
@@ -327,25 +391,57 @@ GNUNET_TRANSPORT_TESTING_connect_peers (struct PeerContext *p1,
327 * @param cc a connect request handle 391 * @param cc a connect request handle
328 */ 392 */
329void GNUNET_TRANSPORT_TESTING_connect_peers_cancel 393void GNUNET_TRANSPORT_TESTING_connect_peers_cancel
330 (GNUNET_TRANSPORT_TESTING_ConnectRequest ccr) 394 (struct TransportTestingHandle * tth,
395 GNUNET_TRANSPORT_TESTING_ConnectRequest ccr)
331{ 396{
332 struct ConnectingContext *cc = ccr; 397 struct ConnectingContext *cc = ccr;
333 398
334 /* clean up */
335 GNUNET_TRANSPORT_get_hello_cancel (cc->p1->ghh);
336 GNUNET_TRANSPORT_get_hello_cancel (cc->p2->ghh);
337
338 if (cc->tct != GNUNET_SCHEDULER_NO_TASK) 399 if (cc->tct != GNUNET_SCHEDULER_NO_TASK)
339 GNUNET_SCHEDULER_cancel (cc->tct); 400 GNUNET_SCHEDULER_cancel (cc->tct);
340 401
341 cc->tct = GNUNET_SCHEDULER_NO_TASK; 402 cc->tct = GNUNET_SCHEDULER_NO_TASK;
342 403
343 GNUNET_TRANSPORT_disconnect (cc->th_p1); 404 GNUNET_CONTAINER_DLL_remove (tth->cc_head, tth->cc_tail, cc);
344 GNUNET_TRANSPORT_disconnect (cc->th_p2);
345 405
346 GNUNET_free (cc); 406 GNUNET_free (cc);
347} 407}
348 408
409void
410GNUNET_TRANSPORT_TESTING_done (struct TransportTestingHandle * tth)
411{
412 struct ConnectingContext *cc = tth->cc_head;
413 struct ConnectingContext *ct = NULL;
414 struct PeerContext *p = tth->p_head;
415 struct PeerContext *t = NULL;
416 while (cc != NULL)
417 {
418 ct = cc->next;
419 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "transport-testing",
420 "Developer forgot to cancel connect request!\n");
421 GNUNET_TRANSPORT_TESTING_connect_peers_cancel(tth, cc);
422 cc = ct;
423 }
424
425 while (p != NULL)
426 {
427 t = p->next;
428 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "transport-testing",
429 "Developer forgot to stop peer!\n");
430 GNUNET_TRANSPORT_TESTING_stop_peer (tth, p);
431 p = t;
432 }
433
434 GNUNET_free (tth);
435}
436
437struct TransportTestingHandle *
438GNUNET_TRANSPORT_TESTING_init ()
439{
440 struct TransportTestingHandle * tth = GNUNET_malloc (sizeof (struct TransportTestingHandle));
441
442 return tth;
443}
444
349 445
350/* 446/*
351 * Some utility functions 447 * Some utility functions