aboutsummaryrefslogtreecommitdiff
path: root/src/testbed/testbed_api_topology.c
diff options
context:
space:
mode:
authorSree Harsha Totakura <totakura@in.tum.de>2013-09-12 13:32:04 +0000
committerSree Harsha Totakura <totakura@in.tum.de>2013-09-12 13:32:04 +0000
commit224724b31899b27141c4afcd91832e0cfd388118 (patch)
tree35810f8108956de28db162e1938765fe6279e387 /src/testbed/testbed_api_topology.c
parent5e386faf4368257a99b4b6cfb34e2b7afa1248f0 (diff)
downloadgnunet-224724b31899b27141c4afcd91832e0cfd388118.tar.gz
gnunet-224724b31899b27141c4afcd91832e0cfd388118.zip
- fix likely possible nonterminating loop for small `cap'
Diffstat (limited to 'src/testbed/testbed_api_topology.c')
-rw-r--r--src/testbed/testbed_api_topology.c43
1 files changed, 32 insertions, 11 deletions
diff --git a/src/testbed/testbed_api_topology.c b/src/testbed/testbed_api_topology.c
index a6dd51fd2..d506ee7e3 100644
--- a/src/testbed/testbed_api_topology.c
+++ b/src/testbed/testbed_api_topology.c
@@ -596,17 +596,20 @@ gen_topo_random (struct TopologyContext *tc, unsigned int links, int append)
596static void 596static void
597gen_scale_free (struct TopologyContext *tc, uint16_t cap, uint8_t m) 597gen_scale_free (struct TopologyContext *tc, uint16_t cap, uint8_t m)
598{ 598{
599 unsigned int *deg;
600 unsigned int *etab;
601 unsigned int *used;
602 unsigned int etaboff;
599 unsigned int cnt; 603 unsigned int cnt;
600 unsigned int cnt2; 604 unsigned int cnt2;
601 unsigned int peer; 605 unsigned int peer;
602 unsigned int random_peer; 606 unsigned int random_peer;
603 unsigned int *deg;
604 unsigned int *etab;
605 unsigned int *used;
606 unsigned int links; 607 unsigned int links;
607 unsigned int random; 608 unsigned int off;
609 unsigned int redo_threshold;
608 610
609 links = 0; 611 links = 0;
612 etaboff = 0;
610 tc->link_array_size = tc->num_peers * m; 613 tc->link_array_size = tc->num_peers * m;
611 tc->link_array = GNUNET_malloc_large (sizeof (struct OverlayLink) * 614 tc->link_array = GNUNET_malloc_large (sizeof (struct OverlayLink) *
612 tc->link_array_size); 615 tc->link_array_size);
@@ -617,8 +620,8 @@ gen_scale_free (struct TopologyContext *tc, uint16_t cap, uint8_t m)
617 make_link (&tc->link_array[0], 0, 1, tc); 620 make_link (&tc->link_array[0], 0, 1, tc);
618 deg[0]++; 621 deg[0]++;
619 deg[1]++; 622 deg[1]++;
620 etab[2 * links] = 0; 623 etab[etaboff++] = 0;
621 etab[(2 * links) + 1] = 1; 624 etab[etaboff++] = 1;
622 links = 1; 625 links = 1;
623 for (peer = 2; peer < tc->num_peers; peer++) 626 for (peer = 2; peer < tc->num_peers; peer++)
624 { 627 {
@@ -626,23 +629,41 @@ gen_scale_free (struct TopologyContext *tc, uint16_t cap, uint8_t m)
626 continue; 629 continue;
627 for (cnt = 0; cnt < GNUNET_MIN (peer, m); cnt++) 630 for (cnt = 0; cnt < GNUNET_MIN (peer, m); cnt++)
628 { 631 {
632 redo_threshold = 0;
629 redo: 633 redo:
630 random = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, (2 * links)); 634 off = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, etaboff);
631 random_peer = etab[random]; 635 random_peer = etab[off];
632 if (cap < deg[random_peer]) 636 if (cap < deg[random_peer])
637 {
638 if (++redo_threshold > GNUNET_MAX (1, cap / 2))
639 {
640 redo_threshold = 0;
641 off = 0;
642 for (cnt2 = 0; cnt2 < etaboff; cnt2++)
643 {
644 if (random_peer == etab[cnt2])
645 {
646 off++;
647 continue;
648 }
649 etab[cnt2 - off] = etab[cnt2];
650 }
651 etaboff -= off;
652 }
633 goto redo; 653 goto redo;
654 }
634 for (cnt2 = 0; cnt2 < cnt; cnt2++) 655 for (cnt2 = 0; cnt2 < cnt; cnt2++)
635 if (random_peer == used[cnt2]) 656 if (random_peer == used[cnt2])
636 goto redo; 657 goto redo;
637 make_link (&tc->link_array[links + cnt], etab[random], peer, tc); 658 make_link (&tc->link_array[links + cnt], random_peer, peer, tc);
638 deg[random_peer]++; 659 deg[random_peer]++;
639 deg[peer]++; 660 deg[peer]++;
640 used[cnt] = random_peer; 661 used[cnt] = random_peer;
641 } 662 }
642 for (cnt = 0; cnt < GNUNET_MIN (peer, m); cnt++) 663 for (cnt = 0; cnt < GNUNET_MIN (peer, m); cnt++)
643 { 664 {
644 etab[(2 * links) + cnt] = used[cnt]; 665 etab[etaboff++] = used[cnt];
645 etab[(2 * links) + cnt + 1] = peer; 666 etab[etaboff++] = peer;
646 } 667 }
647 links += GNUNET_MIN (peer, m); 668 links += GNUNET_MIN (peer, m);
648 } 669 }