aboutsummaryrefslogtreecommitdiff
path: root/src/testbed/testbed_api_topology.c
diff options
context:
space:
mode:
authorSree Harsha Totakura <totakura@in.tum.de>2014-01-06 16:37:21 +0000
committerSree Harsha Totakura <totakura@in.tum.de>2014-01-06 16:37:21 +0000
commit57cba940bf568f0337bfc1a8cffb8542a78e8b1e (patch)
treeb49ba4518fffd16997d7163aa578cf04e41fdaae /src/testbed/testbed_api_topology.c
parentf15d774da10fa73be8c43982b438f55e576a6936 (diff)
downloadgnunet-57cba940bf568f0337bfc1a8cffb8542a78e8b1e.tar.gz
gnunet-57cba940bf568f0337bfc1a8cffb8542a78e8b1e.zip
- underlay topology generation
Diffstat (limited to 'src/testbed/testbed_api_topology.c')
-rw-r--r--src/testbed/testbed_api_topology.c651
1 files changed, 531 insertions, 120 deletions
diff --git a/src/testbed/testbed_api_topology.c b/src/testbed/testbed_api_topology.c
index d4eaec0c5..99ab76f8b 100644
--- a/src/testbed/testbed_api_topology.c
+++ b/src/testbed/testbed_api_topology.c
@@ -78,6 +78,38 @@ struct OverlayLink
78}; 78};
79 79
80 80
81/**
82 * Representation of an underlay link
83 */
84struct UnderlayLink
85{
86 /**
87 * position of peer A's handle in peers array
88 */
89 uint32_t A;
90
91 /**
92 * position of peer B's handle in peers array
93 */
94 uint32_t B;
95
96 /**
97 * Bandwidth of the link in bytes per second
98 */
99 uint32_t bandwidth;
100
101 /**
102 * Latency of the link in milliseconds
103 */
104 uint32_t latency;
105
106 /**
107 * Loss in the link in percentage of message dropped
108 */
109 uint32_t loss;
110};
111
112
81struct RetryListEntry 113struct RetryListEntry
82{ 114{
83 /** 115 /**
@@ -98,9 +130,9 @@ struct RetryListEntry
98 130
99 131
100/** 132/**
101 * Context information for topology operations 133 * Context information for overlay topologies
102 */ 134 */
103struct TopologyContext 135struct TopologyContextOverlay
104{ 136{
105 /** 137 /**
106 * The array of peers 138 * The array of peers
@@ -138,16 +170,6 @@ struct TopologyContext
138 struct RetryListEntry *rl_tail; 170 struct RetryListEntry *rl_tail;
139 171
140 /** 172 /**
141 * The number of peers
142 */
143 unsigned int num_peers;
144
145 /**
146 * The size of the link array
147 */
148 unsigned int link_array_size;
149
150 /**
151 * How many retries to do before we give up 173 * How many retries to do before we give up
152 */ 174 */
153 unsigned int retry_cnt; 175 unsigned int retry_cnt;
@@ -175,6 +197,66 @@ struct TopologyContext
175 197
176 198
177/** 199/**
200 * Topology context information for underlay topologies
201 */
202struct TopologyContextUnderlay
203{
204 /**
205 * The link array
206 */
207 struct UnderlayLink *link_array;
208};
209
210
211/**
212 * Context information for topology operations
213 */
214struct TopologyContext
215{
216 /**
217 * The type of this context
218 */
219 enum {
220
221 /**
222 * Type for underlay topology
223 */
224 TOPOLOGYCONTEXT_TYPE_UNDERLAY = 0,
225
226 /**
227 * Type for overlay topology
228 */
229 TOPOLOGYCONTEXT_TYPE_OVERLAY
230
231 } type;
232
233 union {
234
235 /**
236 * Topology context information for overlay topology
237 */
238 struct TopologyContextOverlay overlay;
239
240 /**
241 * Topology context information for underlay topology
242 */
243 struct TopologyContextUnderlay underlay;
244 } u;
245
246 /**
247 * The number of peers
248 */
249 unsigned int num_peers;
250
251 /**
252 * The size of the link array
253 */
254 unsigned int link_array_size;
255
256};
257
258
259/**
178 * A array of names representing topologies. Should be in sync with enum 260 * A array of names representing topologies. Should be in sync with enum
179 * GNUNET_TESTBED_TopologyOption 261 * GNUNET_TESTBED_TopologyOption
180 */ 262 */
@@ -222,7 +304,9 @@ const char *topology_strings[] = {
222 "INTERNAT", 304 "INTERNAT",
223 305
224 /** 306 /**
225 * Scale free topology. No options. 307 * Scale free topology. Followed by the maximum number of links a node can
308 * have (unsigned int); and the number of links a new node should have when
309 * it is added to the network (unsigned int)
226 */ 310 */
227 "SCALE_FREE", 311 "SCALE_FREE",
228 312
@@ -262,50 +346,53 @@ overlay_link_completed (void *cls, struct GNUNET_TESTBED_Operation *op,
262{ 346{
263 struct OverlayLink *link = cls; 347 struct OverlayLink *link = cls;
264 struct TopologyContext *tc; 348 struct TopologyContext *tc;
349 struct TopologyContextOverlay *overlay;
265 struct RetryListEntry *retry_entry; 350 struct RetryListEntry *retry_entry;
266 351
267 GNUNET_assert (op == link->op); 352 GNUNET_assert (op == link->op);
268 GNUNET_TESTBED_operation_done (op); 353 GNUNET_TESTBED_operation_done (op);
269 link->op = NULL; 354 link->op = NULL;
270 tc = link->tc; 355 tc = link->tc;
356 GNUNET_assert (TOPOLOGYCONTEXT_TYPE_OVERLAY == tc->type);
357 overlay = &tc->u.overlay;
271 if (NULL != emsg) 358 if (NULL != emsg)
272 { 359 {
273 tc->nfailures++; 360 overlay->nfailures++;
274 if (0 != tc->retry_cnt) 361 if (0 != overlay->retry_cnt)
275 { 362 {
276 LOG (GNUNET_ERROR_TYPE_WARNING, 363 LOG (GNUNET_ERROR_TYPE_WARNING,
277 "Error while establishing a link: %s -- Retrying\n", emsg); 364 "Error while establishing a link: %s -- Retrying\n", emsg);
278 retry_entry = GNUNET_new (struct RetryListEntry); 365 retry_entry = GNUNET_new (struct RetryListEntry);
279 retry_entry->link = link; 366 retry_entry->link = link;
280 GNUNET_CONTAINER_DLL_insert_tail (tc->rl_head, tc->rl_tail, retry_entry); 367 GNUNET_CONTAINER_DLL_insert_tail (overlay->rl_head, overlay->rl_tail, retry_entry);
281 } 368 }
282 } 369 }
283 else 370 else
284 tc->nsuccess++; 371 overlay->nsuccess++;
285 tc->ncompleted++; 372 overlay->ncompleted++;
286 if (tc->ncompleted < tc->nlinks) 373 if (overlay->ncompleted < overlay->nlinks)
287 return; 374 return;
288 if ((0 != tc->retry_cnt) && (NULL != tc->rl_head)) 375 if ((0 != overlay->retry_cnt) && (NULL != overlay->rl_head))
289 { 376 {
290 tc->retry_cnt--; 377 overlay->retry_cnt--;
291 tc->ncompleted = 0; 378 overlay->ncompleted = 0;
292 tc->nlinks = 0; 379 overlay->nlinks = 0;
293 while (NULL != (retry_entry = tc->rl_head)) 380 while (NULL != (retry_entry = overlay->rl_head))
294 { 381 {
295 link = retry_entry->link; 382 link = retry_entry->link;
296 link->op = 383 link->op =
297 GNUNET_TESTBED_overlay_connect (tc->op_cls, &overlay_link_completed, 384 GNUNET_TESTBED_overlay_connect (overlay->op_cls, &overlay_link_completed,
298 link, tc->peers[link->A], 385 link, overlay->peers[link->A],
299 tc->peers[link->B]); 386 overlay->peers[link->B]);
300 tc->nlinks++; 387 overlay->nlinks++;
301 GNUNET_CONTAINER_DLL_remove (tc->rl_head, tc->rl_tail, retry_entry); 388 GNUNET_CONTAINER_DLL_remove (overlay->rl_head, overlay->rl_tail, retry_entry);
302 GNUNET_free (retry_entry); 389 GNUNET_free (retry_entry);
303 } 390 }
304 return; 391 return;
305 } 392 }
306 if (NULL != tc->comp_cb) 393 if (NULL != overlay->comp_cb)
307 { 394 {
308 tc->comp_cb (tc->comp_cb_cls, tc->nsuccess, tc->nfailures); 395 overlay->comp_cb (overlay->comp_cb_cls, overlay->nsuccess, overlay->nfailures);
309 } 396 }
310} 397}
311 398
@@ -320,16 +407,19 @@ static void
320opstart_overlay_configure_topology (void *cls) 407opstart_overlay_configure_topology (void *cls)
321{ 408{
322 struct TopologyContext *tc = cls; 409 struct TopologyContext *tc = cls;
410 struct TopologyContextOverlay *overlay;
323 unsigned int p; 411 unsigned int p;
324 412
325 tc->nlinks = tc->link_array_size; 413 GNUNET_assert (TOPOLOGYCONTEXT_TYPE_OVERLAY == tc->type);
414 overlay = &tc->u.overlay;
415 overlay->nlinks = tc->link_array_size;
326 for (p = 0; p < tc->link_array_size; p++) 416 for (p = 0; p < tc->link_array_size; p++)
327 { 417 {
328 tc->link_array[p].op = 418 overlay->link_array[p].op =
329 GNUNET_TESTBED_overlay_connect (tc->op_cls, &overlay_link_completed, 419 GNUNET_TESTBED_overlay_connect (overlay->op_cls, &overlay_link_completed,
330 &tc->link_array[p], 420 &overlay->link_array[p],
331 tc->peers[tc->link_array[p].A], 421 overlay->peers[overlay->link_array[p].A],
332 tc->peers[tc->link_array[p].B]); 422 overlay->peers[overlay->link_array[p].B]);
333 } 423 }
334} 424}
335 425
@@ -343,20 +433,23 @@ static void
343oprelease_overlay_configure_topology (void *cls) 433oprelease_overlay_configure_topology (void *cls)
344{ 434{
345 struct TopologyContext *tc = cls; 435 struct TopologyContext *tc = cls;
436 struct TopologyContextOverlay *overlay;
346 struct RetryListEntry *retry_entry; 437 struct RetryListEntry *retry_entry;
347 unsigned int p; 438 unsigned int p;
348 439
349 while (NULL != (retry_entry = tc->rl_head)) 440 GNUNET_assert (TOPOLOGYCONTEXT_TYPE_OVERLAY == tc->type);
441 overlay = &tc->u.overlay;
442 while (NULL != (retry_entry = overlay->rl_head))
350 { 443 {
351 GNUNET_CONTAINER_DLL_remove (tc->rl_head, tc->rl_tail, retry_entry); 444 GNUNET_CONTAINER_DLL_remove (overlay->rl_head, overlay->rl_tail, retry_entry);
352 GNUNET_free (retry_entry); 445 GNUNET_free (retry_entry);
353 } 446 }
354 if (NULL != tc->link_array) 447 if (NULL != overlay->link_array)
355 { 448 {
356 for (p = 0; p < tc->link_array_size; p++) 449 for (p = 0; p < tc->link_array_size; p++)
357 if (NULL != tc->link_array[p].op) 450 if (NULL != overlay->link_array[p].op)
358 GNUNET_TESTBED_operation_done (tc->link_array[p].op); 451 GNUNET_TESTBED_operation_done (overlay->link_array[p].op);
359 GNUNET_free (tc->link_array); 452 GNUNET_free (overlay->link_array);
360 } 453 }
361 GNUNET_free (tc); 454 GNUNET_free (tc);
362} 455}
@@ -365,22 +458,47 @@ oprelease_overlay_configure_topology (void *cls)
365/** 458/**
366 * Populates the OverlayLink structure. 459 * Populates the OverlayLink structure.
367 * 460 *
368 * @param link the OverlayLink 461 * @param offset the offset of the link array to use
369 * @param A the peer A. Should be different from B 462 * @param A the peer A. Should be different from B
370 * @param B the peer B. Should be different from A 463 * @param B the peer B. Should be different from A
371 * @param tc the TopologyContext 464 * @param tc the TopologyContext
372 * @return 465 * @return
373 */ 466 */
374static void 467static void
375make_link (struct OverlayLink *link, uint32_t A, uint32_t B, 468make_link (unsigned int offset, uint32_t A, uint32_t B,
376 struct TopologyContext *tc) 469 struct TopologyContext *tc)
377{ 470{
378 GNUNET_assert (A != B); 471 GNUNET_assert (A != B);
379 LOG (GNUNET_ERROR_TYPE_DEBUG, "Connecting peer %u to %u\n", B, A); 472 switch (tc->type)
380 link->A = A; 473 {
381 link->B = B; 474 case TOPOLOGYCONTEXT_TYPE_OVERLAY:
382 link->op = NULL; 475 {
383 link->tc = tc; 476 struct TopologyContextOverlay *overlay;
477 struct OverlayLink *olink;
478
479 overlay = &tc->u.overlay;
480 GNUNET_assert (offset < tc->link_array_size);
481 olink = &overlay->link_array[offset];
482 LOG (GNUNET_ERROR_TYPE_DEBUG, "Connecting peer %u to %u\n", B, A);
483 olink->A = A;
484 olink->B = B;
485 olink->op = NULL;
486 olink->tc = tc;
487 }
488 break;
489 case TOPOLOGYCONTEXT_TYPE_UNDERLAY:
490 {
491 struct TopologyContextUnderlay *underlay;
492 struct UnderlayLink *ulink;
493
494 underlay = &tc->u.underlay;
495 GNUNET_assert (offset < tc->link_array_size);
496 ulink = &underlay->link_array[offset];
497 ulink->A = A;
498 ulink->B = B;
499 }
500 break;
501 }
384} 502}
385 503
386 504
@@ -395,10 +513,29 @@ gen_topo_line (struct TopologyContext *tc)
395 unsigned int cnt; 513 unsigned int cnt;
396 514
397 tc->link_array_size = tc->num_peers - 1; 515 tc->link_array_size = tc->num_peers - 1;
398 tc->link_array = 516 switch (tc->type)
399 GNUNET_malloc (sizeof (struct OverlayLink) * tc->link_array_size); 517 {
400 for (cnt = 0; cnt < (tc->num_peers - 1); cnt++) 518 case TOPOLOGYCONTEXT_TYPE_OVERLAY:
401 make_link (&tc->link_array[cnt], cnt, cnt + 1, tc); 519 {
520 struct TopologyContextOverlay *overlay;
521
522 overlay = &tc->u.overlay;
523 overlay->link_array =
524 GNUNET_malloc (sizeof (struct OverlayLink) * tc->link_array_size);
525 }
526 break;
527 case TOPOLOGYCONTEXT_TYPE_UNDERLAY:
528 {
529 struct TopologyContextUnderlay *underlay;
530
531 underlay = &tc->u.underlay;
532 underlay->link_array =
533 GNUNET_malloc (sizeof (struct UnderlayLink) * tc->link_array_size);
534 }
535 break;
536 }
537 for (cnt = 0; cnt < (tc->link_array_size); cnt++)
538 make_link (cnt, cnt, cnt + 1, tc);
402} 539}
403 540
404 541
@@ -412,11 +549,30 @@ gen_topo_ring (struct TopologyContext *tc)
412{ 549{
413 gen_topo_line (tc); 550 gen_topo_line (tc);
414 tc->link_array_size++; 551 tc->link_array_size++;
415 tc->link_array = 552 switch (tc->type)
416 GNUNET_realloc (tc->link_array, 553 {
417 sizeof (struct OverlayLink) * tc->link_array_size); 554 case TOPOLOGYCONTEXT_TYPE_OVERLAY:
418 make_link (&tc->link_array[tc->link_array_size - 1], tc->num_peers - 1, 0, 555 {
419 tc); 556 struct TopologyContextOverlay *overlay;
557
558 overlay = &tc->u.overlay;
559 overlay->link_array =
560 GNUNET_realloc (overlay->link_array, sizeof (struct OverlayLink) *
561 tc->link_array_size);
562 }
563 break;
564 case TOPOLOGYCONTEXT_TYPE_UNDERLAY:
565 {
566 struct TopologyContextUnderlay *underlay;
567
568 underlay = &tc->u.underlay;
569 underlay->link_array =
570 GNUNET_realloc (underlay->link_array, sizeof (struct UnderlayLink) *
571 tc->link_array_size);
572 }
573 break;
574 }
575 make_link (tc->link_array_size - 1, tc->num_peers - 1, 0, tc);
420} 576}
421 577
422 578
@@ -495,20 +651,39 @@ gen_topo_2dtorus (struct TopologyContext *tc)
495 651
496 tc->link_array_size = 652 tc->link_array_size =
497 GNUNET_TESTBED_2dtorus_calc_links (tc->num_peers, &rows, &rows_len); 653 GNUNET_TESTBED_2dtorus_calc_links (tc->num_peers, &rows, &rows_len);
498 tc->link_array = 654 switch (tc->type)
499 GNUNET_malloc (sizeof (struct OverlayLink) * tc->link_array_size); 655 {
656 case TOPOLOGYCONTEXT_TYPE_OVERLAY:
657 {
658 struct TopologyContextOverlay *overlay;
659
660 overlay = &tc->u.overlay;
661 overlay->link_array =
662 GNUNET_malloc (sizeof (struct OverlayLink) * tc->link_array_size);
663 }
664 break;
665 case TOPOLOGYCONTEXT_TYPE_UNDERLAY:
666 {
667 struct TopologyContextUnderlay *underlay;
668
669 underlay = &tc->u.underlay;
670 underlay->link_array =
671 GNUNET_malloc (sizeof (struct UnderlayLink) * tc->link_array_size);
672 break;
673 }
674 }
500 cnt = 0; 675 cnt = 0;
501 offset = 0; 676 offset = 0;
502 for (y = 0; y < rows; y++) 677 for (y = 0; y < rows; y++)
503 { 678 {
504 for (x = 0; x < rows_len[y] - 1; x++) 679 for (x = 0; x < rows_len[y] - 1; x++)
505 { 680 {
506 make_link (&tc->link_array[cnt], offset + x, offset + x + 1, tc); 681 make_link (cnt, offset + x, offset + x + 1, tc);
507 cnt++; 682 cnt++;
508 } 683 }
509 if (0 == x) 684 if (0 == x)
510 break; 685 break;
511 make_link (&tc->link_array[cnt], offset + x, offset, tc); 686 make_link (cnt, offset + x, offset, tc);
512 cnt++; 687 cnt++;
513 offset += rows_len[y]; 688 offset += rows_len[y];
514 } 689 }
@@ -520,14 +695,13 @@ gen_topo_2dtorus (struct TopologyContext *tc)
520 if (x >= rows_len[y + 1]) 695 if (x >= rows_len[y + 1])
521 break; 696 break;
522 GNUNET_assert (x < rows_len[y + 1]); 697 GNUNET_assert (x < rows_len[y + 1]);
523 make_link (&tc->link_array[cnt], offset + x, offset + rows_len[y] + x, 698 make_link (cnt, offset + x, offset + rows_len[y] + x, tc);
524 tc);
525 offset += rows_len[y]; 699 offset += rows_len[y];
526 cnt++; 700 cnt++;
527 } 701 }
528 if (0 == offset) 702 if (0 == offset)
529 break; 703 break;
530 make_link (&tc->link_array[cnt], offset + x, x, tc); 704 make_link (cnt, offset + x, x, tc);
531 cnt++; 705 cnt++;
532 } 706 }
533 GNUNET_assert (cnt == tc->link_array_size); 707 GNUNET_assert (cnt == tc->link_array_size);
@@ -553,20 +727,52 @@ gen_topo_random (struct TopologyContext *tc, unsigned int links, int append)
553 727
554 if (GNUNET_YES == append) 728 if (GNUNET_YES == append)
555 { 729 {
556 GNUNET_assert ((0 < tc->link_array_size) && (NULL != tc->link_array));
557 index = tc->link_array_size; 730 index = tc->link_array_size;
558 tc->link_array_size += links; 731 tc->link_array_size += links;
559 tc->link_array =
560 GNUNET_realloc (tc->link_array,
561 sizeof (struct OverlayLink) * tc->link_array_size);
562 } 732 }
563 else 733 else
564 { 734 {
565 GNUNET_assert ((0 == tc->link_array_size) && (NULL == tc->link_array));
566 index = 0; 735 index = 0;
567 tc->link_array_size = links; 736 tc->link_array_size = links;
568 tc->link_array = 737 }
569 GNUNET_malloc (sizeof (struct OverlayLink) * tc->link_array_size); 738 switch (tc->type)
739 {
740 case TOPOLOGYCONTEXT_TYPE_OVERLAY:
741 {
742 struct TopologyContextOverlay *overlay;
743
744 overlay = &tc->u.overlay;
745 if (GNUNET_YES != append)
746 {
747 GNUNET_assert (NULL == overlay->link_array);
748 overlay->link_array =
749 GNUNET_malloc (sizeof (struct OverlayLink) * tc->link_array_size);
750 break;
751 }
752 GNUNET_assert ((0 < tc->link_array_size) && (NULL != overlay->link_array));
753 overlay->link_array =
754 GNUNET_realloc (overlay->link_array,
755 sizeof (struct OverlayLink) * tc->link_array_size);
756 break;
757 }
758 case TOPOLOGYCONTEXT_TYPE_UNDERLAY:
759 {
760 struct TopologyContextUnderlay *underlay;
761
762 underlay = &tc->u.underlay;
763 if (GNUNET_YES != append)
764 {
765 GNUNET_assert (NULL == underlay->link_array);
766 underlay->link_array =
767 GNUNET_malloc (sizeof (struct UnderlayLink) * tc->link_array_size);
768 break;
769 }
770 GNUNET_assert ((0 < tc->link_array_size) && (NULL != underlay->link_array));
771 underlay->link_array =
772 GNUNET_realloc (underlay->link_array,
773 sizeof (struct UnderlayLink) * tc->link_array_size);
774 break;
775 }
570 } 776 }
571 for (cnt = 0; cnt < links; cnt++) 777 for (cnt = 0; cnt < links; cnt++)
572 { 778 {
@@ -578,7 +784,7 @@ gen_topo_random (struct TopologyContext *tc, unsigned int links, int append)
578 GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, tc->num_peers); 784 GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, tc->num_peers);
579 } 785 }
580 while (A_rand == B_rand); 786 while (A_rand == B_rand);
581 make_link (&tc->link_array[index + cnt], A_rand, B_rand, tc); 787 make_link (index+cnt, A_rand, B_rand, tc);
582 } 788 }
583} 789}
584 790
@@ -594,7 +800,7 @@ gen_topo_random (struct TopologyContext *tc, unsigned int links, int append)
594 * network 800 * network
595 */ 801 */
596static void 802static void
597gen_scale_free (struct TopologyContext *tc, uint16_t cap, uint8_t m) 803gen_topo_scale_free (struct TopologyContext *tc, uint16_t cap, uint8_t m)
598{ 804{
599 unsigned int *deg; 805 unsigned int *deg;
600 unsigned int *etab; 806 unsigned int *etab;
@@ -610,13 +816,32 @@ gen_scale_free (struct TopologyContext *tc, uint16_t cap, uint8_t m)
610 816
611 etaboff = 0; 817 etaboff = 0;
612 tc->link_array_size = tc->num_peers * m; 818 tc->link_array_size = tc->num_peers * m;
613 tc->link_array = GNUNET_malloc_large (sizeof (struct OverlayLink) * 819 switch (tc->type)
614 tc->link_array_size); 820 {
821 case TOPOLOGYCONTEXT_TYPE_OVERLAY:
822 {
823 struct TopologyContextOverlay *overlay;
824
825 overlay = &tc->u.overlay;
826 overlay->link_array = GNUNET_malloc_large (sizeof (struct OverlayLink) *
827 tc->link_array_size);
828 }
829 break;
830 case TOPOLOGYCONTEXT_TYPE_UNDERLAY:
831 {
832 struct TopologyContextUnderlay *underlay;
833
834 underlay = &tc->u.underlay;
835 underlay->link_array = GNUNET_malloc_large (sizeof (struct UnderlayLink) *
836 tc->link_array_size);
837 }
838 break;
839 }
615 etab = GNUNET_malloc_large (sizeof (unsigned int) * 2 * tc->link_array_size); 840 etab = GNUNET_malloc_large (sizeof (unsigned int) * 2 * tc->link_array_size);
616 deg = GNUNET_malloc (sizeof (unsigned int) * tc->num_peers); 841 deg = GNUNET_malloc (sizeof (unsigned int) * tc->num_peers);
617 used = GNUNET_malloc (sizeof (unsigned int) * m); 842 used = GNUNET_malloc (sizeof (unsigned int) * m);
618 /* start by connecting peer 1 to peer 0 */ 843 /* start by connecting peer 1 to peer 0 */
619 make_link (&tc->link_array[0], 0, 1, tc); 844 make_link (0, 0, 1, tc);
620 deg[0]++; 845 deg[0]++;
621 deg[1]++; 846 deg[1]++;
622 etab[etaboff++] = 0; 847 etab[etaboff++] = 0;
@@ -654,7 +879,7 @@ gen_scale_free (struct TopologyContext *tc, uint16_t cap, uint8_t m)
654 for (cnt2 = 0; cnt2 < cnt; cnt2++) 879 for (cnt2 = 0; cnt2 < cnt; cnt2++)
655 if (random_peer == used[cnt2]) 880 if (random_peer == used[cnt2])
656 goto redo; 881 goto redo;
657 make_link (&tc->link_array[links + cnt], random_peer, peer, tc); 882 make_link (links + cnt, random_peer, peer, tc);
658 deg[random_peer]++; 883 deg[random_peer]++;
659 deg[peer]++; 884 deg[peer]++;
660 used[cnt] = random_peer; 885 used[cnt] = random_peer;
@@ -671,9 +896,27 @@ gen_scale_free (struct TopologyContext *tc, uint16_t cap, uint8_t m)
671 GNUNET_free (deg); 896 GNUNET_free (deg);
672 GNUNET_assert (links <= tc->link_array_size); 897 GNUNET_assert (links <= tc->link_array_size);
673 tc->link_array_size = links; 898 tc->link_array_size = links;
674 tc->link_array = 899 switch (tc->type)
675 GNUNET_realloc (tc->link_array, 900 {
676 sizeof (struct OverlayLink) * tc->link_array_size); 901 case TOPOLOGYCONTEXT_TYPE_OVERLAY:
902 {
903 struct TopologyContextOverlay *overlay;
904
905 overlay = &tc->u.overlay;
906 overlay->link_array =
907 GNUNET_realloc (overlay->link_array, sizeof (struct OverlayLink) * tc->link_array_size);
908 }
909 break;
910 case TOPOLOGYCONTEXT_TYPE_UNDERLAY:
911 {
912 struct TopologyContextUnderlay *underlay;
913
914 underlay = &tc->u.underlay;
915 underlay->link_array =
916 GNUNET_realloc (underlay->link_array, sizeof (struct UnderlayLink) * tc->link_array_size);
917 }
918 break;
919 }
677} 920}
678 921
679 922
@@ -798,12 +1041,31 @@ gen_topo_from_file (struct TopologyContext *tc, const char *filename)
798 if (peer_id != other_peer_id) 1041 if (peer_id != other_peer_id)
799 { 1042 {
800 tc->link_array_size++; 1043 tc->link_array_size++;
801 tc->link_array = 1044 switch (tc->type)
802 GNUNET_realloc (tc->link_array, 1045 {
803 sizeof (struct OverlayLink) * tc->link_array_size); 1046 case TOPOLOGYCONTEXT_TYPE_OVERLAY:
1047 {
1048 struct TopologyContextOverlay *overlay;
1049
1050 overlay = &tc->u.overlay;
1051 overlay->link_array =
1052 GNUNET_realloc (overlay->link_array,
1053 sizeof (struct OverlayLink) * tc->link_array_size);
1054 }
1055 break;
1056 case TOPOLOGYCONTEXT_TYPE_UNDERLAY:
1057 {
1058 struct TopologyContextUnderlay *underlay;
1059
1060 underlay = &tc->u.underlay;
1061 underlay->link_array =
1062 GNUNET_realloc (underlay->link_array,
1063 sizeof (struct UnderlayLink) * tc->link_array_size);
1064 }
1065 break;
1066 }
804 offset += end - &data[offset]; 1067 offset += end - &data[offset];
805 make_link (&tc->link_array[tc->link_array_size - 1], peer_id, 1068 make_link (tc->link_array_size - 1, peer_id, other_peer_id, tc);
806 other_peer_id, tc);
807 } 1069 }
808 else 1070 else
809 LOG (GNUNET_ERROR_TYPE_WARNING, 1071 LOG (GNUNET_ERROR_TYPE_WARNING,
@@ -829,8 +1091,74 @@ _exit:
829 { 1091 {
830 LOG (GNUNET_ERROR_TYPE_WARNING, "Removing link data read from the file\n"); 1092 LOG (GNUNET_ERROR_TYPE_WARNING, "Removing link data read from the file\n");
831 tc->link_array_size = 0; 1093 tc->link_array_size = 0;
832 GNUNET_free_non_null (tc->link_array); 1094 switch (tc->type)
833 tc->link_array = NULL; 1095 {
1096 case TOPOLOGYCONTEXT_TYPE_OVERLAY:
1097 {
1098 struct TopologyContextOverlay *overlay;
1099
1100 overlay = &tc->u.overlay;
1101 GNUNET_free_non_null (overlay->link_array);
1102 overlay->link_array = NULL;
1103 }
1104 break;
1105 case TOPOLOGYCONTEXT_TYPE_UNDERLAY:
1106 {
1107 struct TopologyContextUnderlay *underlay;
1108
1109 underlay = &tc->u.underlay;
1110 GNUNET_free_non_null (underlay->link_array);
1111 underlay->link_array = NULL;
1112 }
1113 break;
1114 }
1115 }
1116}
1117
1118
1119/**
1120 * Generates clique topology
1121 *
1122 * @param tc the topology context
1123 */
1124static void
1125gen_topo_clique (struct TopologyContext *tc)
1126{
1127 unsigned int cnt;
1128 unsigned int offset;
1129 unsigned int neighbour;
1130
1131 tc->link_array_size = tc->num_peers * (tc->num_peers - 1);
1132 switch (tc->type)
1133 {
1134 case TOPOLOGYCONTEXT_TYPE_OVERLAY:
1135 {
1136 struct TopologyContextOverlay *overlay;
1137
1138 overlay = &tc->u.overlay;
1139 overlay->link_array = GNUNET_malloc (sizeof (struct OverlayLink) *
1140 tc->link_array_size);
1141 }
1142 break;
1143 case TOPOLOGYCONTEXT_TYPE_UNDERLAY:
1144 {
1145 struct TopologyContextUnderlay *underlay;
1146
1147 underlay = &tc->u.underlay;
1148 underlay->link_array = GNUNET_malloc (sizeof (struct UnderlayLink) *
1149 tc->link_array_size);
1150 }
1151 }
1152 offset = 0;
1153 for (cnt = 0; cnt < tc->num_peers; cnt++)
1154 {
1155 for (neighbour = 0; neighbour < tc->num_peers; neighbour++)
1156 {
1157 if (neighbour == cnt)
1158 continue;
1159 make_link (offset, cnt, neighbour, tc);
1160 offset++;
1161 }
834 } 1162 }
835} 1163}
836 1164
@@ -915,21 +1243,23 @@ GNUNET_TESTBED_overlay_configure_topology_va (void *op_cls,
915 va_list va) 1243 va_list va)
916{ 1244{
917 struct TopologyContext *tc; 1245 struct TopologyContext *tc;
1246 struct TopologyContextOverlay *overlay;
918 struct GNUNET_TESTBED_Operation *op; 1247 struct GNUNET_TESTBED_Operation *op;
919 struct GNUNET_TESTBED_Controller *c; 1248 struct GNUNET_TESTBED_Controller *c;
920 enum GNUNET_TESTBED_TopologyOption secondary_option; 1249 enum GNUNET_TESTBED_TopologyOption secondary_option;
921 unsigned int cnt;
922 1250
923 if (num_peers < 2) 1251 if (num_peers < 2)
924 return NULL; 1252 return NULL;
925 c = peers[0]->controller; 1253 c = peers[0]->controller;
926 tc = GNUNET_new (struct TopologyContext); 1254 tc = GNUNET_new (struct TopologyContext);
927 tc->peers = peers; 1255 tc->type = TOPOLOGYCONTEXT_TYPE_OVERLAY;
1256 overlay = &tc->u.overlay;
1257 overlay->peers = peers;
928 tc->num_peers = num_peers; 1258 tc->num_peers = num_peers;
929 tc->op_cls = op_cls; 1259 overlay->op_cls = op_cls;
930 tc->retry_cnt = DEFAULT_RETRY_CNT; 1260 overlay->retry_cnt = DEFAULT_RETRY_CNT;
931 tc->comp_cb = comp_cb; 1261 overlay->comp_cb = comp_cb;
932 tc->comp_cb_cls = comp_cb_cls; 1262 overlay->comp_cb_cls = comp_cb_cls;
933 switch (topo) 1263 switch (topo)
934 { 1264 {
935 case GNUNET_TESTBED_TOPOLOGY_LINE: 1265 case GNUNET_TESTBED_TOPOLOGY_LINE:
@@ -946,28 +1276,7 @@ GNUNET_TESTBED_overlay_configure_topology_va (void *op_cls,
946 gen_topo_random (tc, va_arg (va, unsigned int), GNUNET_YES); 1276 gen_topo_random (tc, va_arg (va, unsigned int), GNUNET_YES);
947 break; 1277 break;
948 case GNUNET_TESTBED_TOPOLOGY_CLIQUE: 1278 case GNUNET_TESTBED_TOPOLOGY_CLIQUE:
949 tc->link_array_size = num_peers * (num_peers - 1); 1279 gen_topo_clique (tc);
950 tc->link_array =
951 GNUNET_malloc (sizeof (struct OverlayLink) * tc->link_array_size);
952 {
953 unsigned int offset;
954
955 offset = 0;
956 for (cnt = 0; cnt < num_peers; cnt++)
957 {
958 unsigned int neighbour;
959
960 for (neighbour = 0; neighbour < num_peers; neighbour++)
961 {
962 if (neighbour == cnt)
963 continue;
964 tc->link_array[offset].A = cnt;
965 tc->link_array[offset].B = neighbour;
966 tc->link_array[offset].tc = tc;
967 offset++;
968 }
969 }
970 }
971 break; 1280 break;
972 case GNUNET_TESTBED_TOPOLOGY_2D_TORUS: 1281 case GNUNET_TESTBED_TOPOLOGY_2D_TORUS:
973 gen_topo_2dtorus (tc); 1282 gen_topo_2dtorus (tc);
@@ -984,7 +1293,7 @@ GNUNET_TESTBED_overlay_configure_topology_va (void *op_cls,
984 1293
985 cap = (uint16_t) va_arg (va, unsigned int); 1294 cap = (uint16_t) va_arg (va, unsigned int);
986 m = (uint8_t) va_arg (va, unsigned int); 1295 m = (uint8_t) va_arg (va, unsigned int);
987 gen_scale_free (tc, cap, m); 1296 gen_topo_scale_free (tc, cap, m);
988 } 1297 }
989 break; 1298 break;
990 case GNUNET_TESTBED_TOPOLOGY_FROM_FILE: 1299 case GNUNET_TESTBED_TOPOLOGY_FROM_FILE:
@@ -1009,14 +1318,14 @@ GNUNET_TESTBED_overlay_configure_topology_va (void *op_cls,
1009 switch (secondary_option) 1318 switch (secondary_option)
1010 { 1319 {
1011 case GNUNET_TESTBED_TOPOLOGY_RETRY_CNT: 1320 case GNUNET_TESTBED_TOPOLOGY_RETRY_CNT:
1012 tc->retry_cnt = va_arg (va, unsigned int); 1321 overlay->retry_cnt = va_arg (va, unsigned int);
1013 break; 1322 break;
1014 case GNUNET_TESTBED_TOPOLOGY_OPTION_END: 1323 case GNUNET_TESTBED_TOPOLOGY_OPTION_END:
1015 break; 1324 break;
1016 default: 1325 default:
1017 GNUNET_break (0); /* Should not use any other option apart from 1326 GNUNET_break (0); /* Should not use any other option apart from
1018 * the ones handled here */ 1327 * the ones handled here */
1019 GNUNET_free_non_null (tc->link_array); 1328 GNUNET_free_non_null (overlay->link_array);
1020 GNUNET_free (tc); 1329 GNUNET_free (tc);
1021 return NULL; 1330 return NULL;
1022 } 1331 }
@@ -1125,4 +1434,106 @@ GNUNET_TESTBED_topology_to_str_ (enum GNUNET_TESTBED_TopologyOption topology)
1125 return GNUNET_strdup (topology_strings[topology]); 1434 return GNUNET_strdup (topology_strings[topology]);
1126} 1435}
1127 1436
1437
1438/**
1439 * Function to construct an underlay topology
1440 *
1441 * @param num_peers the number of peers for which the topology should be
1442 * generated
1443 * @param proc the underlay link processor callback. Will be called for each
1444 * underlay link generated unless a previous call to this callback
1445 * returned GNUNET_SYSERR. Cannot be NULL.
1446 * @param cls closure for proc
1447 * @param ... variable arguments denoting the topology and its parameters. They
1448 * should start with the type of topology to generate followed by their
1449 * options.
1450 * @return GNUNET_OK if underlay link generation is successful; GNUNET_SYSERR
1451 * upon error in generating the underlay or if any calls to the
1452 * underlay link processor returned GNUNET_SYSERR
1453 */
1454int
1455GNUNET_TESTBED_underlay_construct_ (int num_peers,
1456 underlay_link_processor proc,
1457 void *cls,
1458 ...)
1459{
1460 struct TopologyContext tc;
1461 struct TopologyContextUnderlay *underlay;
1462 struct UnderlayLink *ulink;
1463 va_list vargs;
1464 enum GNUNET_TESTBED_TopologyOption topology;
1465 unsigned int cnt;
1466 int ret;
1467
1468 GNUNET_assert (NULL != proc);
1469 ret = GNUNET_OK;
1470 memset (&tc, 0, sizeof (tc));
1471 tc.type = TOPOLOGYCONTEXT_TYPE_UNDERLAY;
1472 underlay = &tc.u.underlay;
1473 va_start (vargs, cls);
1474 topology = va_arg (vargs, enum GNUNET_TESTBED_TopologyOption);
1475 switch (topology)
1476 {
1477 case GNUNET_TESTBED_TOPOLOGY_LINE:
1478 gen_topo_line (&tc);
1479 break;
1480 case GNUNET_TESTBED_TOPOLOGY_RING:
1481 gen_topo_ring (&tc);
1482 break;
1483 case GNUNET_TESTBED_TOPOLOGY_CLIQUE:
1484 gen_topo_clique (&tc);
1485 break;
1486 case GNUNET_TESTBED_TOPOLOGY_2D_TORUS:
1487 gen_topo_2dtorus (&tc);
1488 break;
1489 case GNUNET_TESTBED_TOPOLOGY_ERDOS_RENYI:
1490 gen_topo_random (&tc, va_arg (vargs, unsigned int), GNUNET_NO);
1491 break;
1492 case GNUNET_TESTBED_TOPOLOGY_SMALL_WORLD_RING:
1493 gen_topo_ring (&tc);
1494 gen_topo_random (&tc, va_arg (vargs, unsigned int), GNUNET_YES);
1495 break;
1496 case GNUNET_TESTBED_TOPOLOGY_SMALL_WORLD:
1497 gen_topo_2dtorus (&tc);
1498 gen_topo_random (&tc, va_arg (vargs, unsigned int), GNUNET_YES);
1499 break;
1500 case GNUNET_TESTBED_TOPOLOGY_FROM_FILE:
1501 {
1502 const char *filename;
1503 filename = va_arg (vargs, char *);
1504 GNUNET_assert (NULL != filename);
1505 gen_topo_from_file (&tc, filename);
1506 }
1507 break;
1508 case GNUNET_TESTBED_TOPOLOGY_SCALE_FREE:
1509 {
1510 uint16_t cap;
1511 uint8_t m;
1512 cap = (uint16_t) va_arg (vargs, unsigned int);
1513 m = (uint8_t) va_arg (vargs, unsigned int);
1514 gen_topo_scale_free (&tc, cap, m);
1515 }
1516 break;
1517 default:
1518 GNUNET_assert (0);
1519 }
1520 va_end (vargs);
1521 for (cnt = 0; cnt < tc.link_array_size; cnt++)
1522 {
1523 ulink = &underlay->link_array[cnt];
1524 if (GNUNET_SYSERR == proc (cls,
1525 ulink->A,
1526 ulink->B,
1527 ulink->bandwidth,
1528 ulink->latency,
1529 ulink->loss))
1530 {
1531 ret = GNUNET_SYSERR;
1532 break;
1533 }
1534 }
1535 GNUNET_free_non_null (underlay->link_array);
1536 return ret;
1537}
1538
1128/* end of testbed_api_topology.c */ 1539/* end of testbed_api_topology.c */