aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/documentation/Makefile.am3
-rw-r--r--doc/documentation/chapters/installation.texi30
-rw-r--r--doc/documentation/chapters/user.texi179
-rw-r--r--doc/documentation/images/gns.dot42
-rw-r--r--src/dht/gnunet_dht_profiler.c681
-rw-r--r--src/namestore/gnunet-namestore.c62
-rw-r--r--src/namestore/test_namestore_api_monitoring.c5
-rw-r--r--src/namestore/test_namestore_api_monitoring_existing.c55
-rw-r--r--src/topology/friends.c3
-rw-r--r--src/zonemaster/gnunet-service-zonemaster.c16
10 files changed, 468 insertions, 608 deletions
diff --git a/doc/documentation/Makefile.am b/doc/documentation/Makefile.am
index 991b1926b..1bd25f773 100644
--- a/doc/documentation/Makefile.am
+++ b/doc/documentation/Makefile.am
@@ -44,7 +44,8 @@ dist_infoimage_DATA = \
44 images/daemon_lego_block.svg \ 44 images/daemon_lego_block.svg \
45 images/lego_stack.svg \ 45 images/lego_stack.svg \
46 images/service_lego_block.svg \ 46 images/service_lego_block.svg \
47 images/structure.dot 47 images/structure.dot \
48 images/gns.dot
48 49
49# images/$(wildcard *.png) \ 50# images/$(wildcard *.png) \
50# images/$(wildcard *.svg) 51# images/$(wildcard *.svg)
diff --git a/doc/documentation/chapters/installation.texi b/doc/documentation/chapters/installation.texi
index 3a76fb162..6eb1a88a0 100644
--- a/doc/documentation/chapters/installation.texi
+++ b/doc/documentation/chapters/installation.texi
@@ -3290,7 +3290,6 @@ and @code{[transport-https_client]} section of the configuration:
3290* GNS Proxy Setup:: 3290* GNS Proxy Setup::
3291* Setup of the GNS CA:: 3291* Setup of the GNS CA::
3292* Testing the GNS setup:: 3292* Testing the GNS setup::
3293* Automatic Shortening in the GNU Name System::
3294@end menu 3293@end menu
3295 3294
3296 3295
@@ -3526,8 +3525,11 @@ Now for testing purposes we can create some records in our zone to test
3526the SSL functionality of the proxy: 3525the SSL functionality of the proxy:
3527 3526
3528@example 3527@example
3529$ gnunet-namestore -a -e "1 d" -n "homepage" -t A -V 131.159.74.67 3528$ gnunet-identity -C test
3530$ gnunet-namestore -a -e "1 d" -n "homepage" -t LEHO -V "gnunet.org" 3529$ gnunet-namestore -a -e "1 d" -n "homepage" \
3530 -t A -V 131.159.74.67 -z test
3531$ gnunet-namestore -a -e "1 d" -n "homepage" \
3532 -t LEHO -V "gnunet.org" -z test
3531@end example 3533@end example
3532 3534
3533@noindent 3535@noindent
@@ -3544,7 +3546,7 @@ If you use @command{Firefox} (or one of its deriviates/forks such as
3544Icecat) you also have to go to @code{about:config} and set the key 3546Icecat) you also have to go to @code{about:config} and set the key
3545@code{network.proxy.socks_remote_dns} to @code{true}. 3547@code{network.proxy.socks_remote_dns} to @code{true}.
3546 3548
3547When you visit @code{https://homepage.gnu/}, you should get to the 3549When you visit @code{https://homepage.test/}, you should get to the
3548@code{https://gnunet.org/} frontpage and the browser (with the correctly 3550@code{https://gnunet.org/} frontpage and the browser (with the correctly
3549configured proxy) should give you a valid SSL certificate for 3551configured proxy) should give you a valid SSL certificate for
3550@code{homepage.gnu} and no warnings. It should look like this: 3552@code{homepage.gnu} and no warnings. It should look like this:
@@ -3552,26 +3554,6 @@ configured proxy) should give you a valid SSL certificate for
3552@c FIXME: Image does not exist, create it or save it from Drupal? 3554@c FIXME: Image does not exist, create it or save it from Drupal?
3553@c @image{images/gnunethpgns.png,5in,, picture of homepage.gnu in Webbrowser} 3555@c @image{images/gnunethpgns.png,5in,, picture of homepage.gnu in Webbrowser}
3554 3556
3555@node Automatic Shortening in the GNU Name System
3556@subsubsection Automatic Shortening in the GNU Name System
3557
3558This page describes a possible option for 'automatic name shortening',
3559which you can choose to enable with the GNU Name System.
3560
3561When GNS encounters a name for the first time, it can use the 'NICK'
3562record of the originating zone to automatically generate a name for the
3563zone. If automatic shortening is enabled, those auto-generated names will
3564be placed (as private records) into your personal 'shorten' zone (to
3565prevent confusion with manually selected names).
3566Then, in the future, if the same name is encountered again, GNS will
3567display the shortened name instead (the first time, the long name will
3568still be used as shortening typically happens asynchronously as looking up
3569the 'NICK' record takes some time). Using this feature can be a convenient
3570way to avoid very long @code{.gnu} names; however, note that names from
3571the shorten-zone are assigned on a first-come-first-serve basis and should
3572not be trusted. Furthermore, if you enable this feature, you will no
3573longer see the full delegation chain for zones once shortening has been
3574applied.
3575 3557
3576@node Configuring the GNUnet VPN 3558@node Configuring the GNUnet VPN
3577@subsection Configuring the GNUnet VPN 3559@subsection Configuring the GNUnet VPN
diff --git a/doc/documentation/chapters/user.texi b/doc/documentation/chapters/user.texi
index 8ce8b52e2..6063392ac 100644
--- a/doc/documentation/chapters/user.texi
+++ b/doc/documentation/chapters/user.texi
@@ -1466,47 +1466,42 @@ the user. This results in non-unique name-value mappings as
1466 1466
1467 1467
1468@menu 1468@menu
1469* Creating a Zone::
1469* Maintaining your own Zones:: 1470* Maintaining your own Zones::
1470* Obtaining your Zone Key:: 1471* Obtaining your Zone Key::
1471* Adding Links to Other Zones:: 1472* Adding Links to Other Zones::
1472* The Three Local Zones of GNS:: 1473* Using Public Keys as Top Level Domains::
1473* The Master Zone::
1474* The Private Zone::
1475* The Shorten Zone::
1476* The ZKEY Top Level Domain in GNS::
1477* Resource Records in GNS:: 1474* Resource Records in GNS::
1475* Synchronizing with legacy DNS::
1478@end menu 1476@end menu
1479 1477
1480 1478
1481@node Maintaining your own Zones 1479@node Creating a Zone
1482@subsection Maintaining your own Zones 1480@subsection Creating a Zone
1483 1481
1484To setup your GNS system you must execute: 1482To use GNS, you probably should create at least one zone of your own.
1483You can create any number of zones using the gnunet-identity tool
1484using:
1485 1485
1486@example 1486@example
1487$ gnunet-gns-import.sh 1487$ gnunet-identity -C "myzone"
1488@end example 1488@end example
1489 1489
1490@noindent 1490Henceforth, on your system you control the TLD ``myzone''.
1491This will boostrap your zones and create the necessary key material. 1491
1492Your keys can be listed using the @command{gnunet-identity} 1492All of your zones can be listed using the @command{gnunet-identity}
1493command line tool: 1493command line tool as well:
1494 1494
1495@example 1495@example
1496$ gnunet-identity -d 1496$ gnunet-identity -d
1497@end example 1497@end example
1498 1498
1499@noindent 1499@node Maintaining your own Zones
1500You can arbitrarily create your own zones using the gnunet-identity 1500@subsection Maintaining your own Zones
1501tool using:
1502
1503@example
1504$ gnunet-identity -C "new_zone"
1505@end example
1506 1501
1507@noindent 1502@noindent
1508Now you can add (or edit, or remove) records in your GNS zone using the 1503Now you can add (or edit, or remove) records in your GNS zone using the
1509@command{gnunet-setup} GUI or using the @command{gnunet-namestore} 1504@command{gnunet-namestore-gtk} GUI or using the @command{gnunet-namestore}
1510command-line tool. 1505command-line tool.
1511In either case, your records will be stored in an SQL database under 1506In either case, your records will be stored in an SQL database under
1512control of the @command{gnunet-service-namestore}. 1507control of the @command{gnunet-service-namestore}.
@@ -1518,21 +1513,21 @@ if they are marked as private.
1518To provide a short example for editing your own zone, suppose you 1513To provide a short example for editing your own zone, suppose you
1519have your own web server with the IP @code{1.2.3.4}. Then you can put an 1514have your own web server with the IP @code{1.2.3.4}. Then you can put an
1520@code{A} record (@code{A} records in DNS are for IPv4 IP addresses) 1515@code{A} record (@code{A} records in DNS are for IPv4 IP addresses)
1521into your local zone using the command: 1516into your local zone ``myzone'' using the command:
1522 1517
1523@example 1518@example
1524$ gnunet-namestore -z master-zone -a -n www -t A -V 1.2.3.4 -e never 1519$ gnunet-namestore -z myzone -a -n www -t A -V 1.2.3.4 -e never
1525@end example 1520@end example
1526 1521
1527@noindent 1522@noindent
1528Afterwards, you will be able to access your webpage under "www.gnu" 1523Afterwards, you will be able to access your webpage under "www.myzone"
1529(assuming your webserver does not use virtual hosting, if it does, 1524(assuming your webserver does not use virtual hosting, if it does,
1530please read up on setting up the GNS proxy). 1525please read up on setting up the GNS proxy).
1531 1526
1532Similar commands will work for other types of DNS and GNS records, 1527Similar commands will work for other types of DNS and GNS records,
1533the syntax largely depending on the type of the record. 1528the syntax largely depending on the type of the record.
1534Naturally, most users may find editing the zones using the 1529Naturally, most users may find editing the zones using the
1535@command{gnunet-setup} GUI to be easier. 1530@command{gnunet-namestore-gtk} GUI to be easier.
1536 1531
1537@node Obtaining your Zone Key 1532@node Obtaining your Zone Key
1538@subsection Obtaining your Zone Key 1533@subsection Obtaining your Zone Key
@@ -1546,7 +1541,7 @@ give it to others so that they can securely link to you.
1546You can usually get the hash of your public key using 1541You can usually get the hash of your public key using
1547 1542
1548@example 1543@example
1549$ gnunet-identity -d $options | grep master-zone | awk '@{print $3@}' 1544$ gnunet-identity -d $options | grep myzone | awk '@{print $3@}'
1550@end example 1545@end example
1551 1546
1552@noindent 1547@noindent
@@ -1557,10 +1552,10 @@ DC3SEECJORPHQNVRH965A6N74B1M37S721IG4RBQ15PJLLPJKUE0
1557@end example 1552@end example
1558 1553
1559@noindent 1554@noindent
1560Alternatively, you can obtain a QR code with your zone key AND 1555Alternatively, you can obtain a QR code with your zone key AND your
1561your pseudonym from gnunet-gtk. The QR code is displayed in the 1556pseudonym from gnunet-namestore-gtk. The QR code is displayed in the
1562GNS tab and can be stored to disk using the Save as button next 1557main window and can be stored to disk using the ``Save as'' button
1563to the image. 1558next to the image.
1564 1559
1565@node Adding Links to Other Zones 1560@node Adding Links to Other Zones
1566@subsection Adding Links to Other Zones 1561@subsection Adding Links to Other Zones
@@ -1576,89 +1571,37 @@ You can then delegate resolution of names to Bob's zone by adding
1576a PKEY record to their local zone: 1571a PKEY record to their local zone:
1577 1572
1578@example 1573@example
1579$ gnunet-namestore -a -n bob --type PKEY -V XXXX -e never 1574$ gnunet-namestore -a -n bob --type PKEY -V XXXX -e never -Z myzone
1580@end example 1575@end example
1581 1576
1582@noindent 1577@noindent
1583Note that XXXX in the command above must be replaced with the 1578Note that ``XXXX'' in the command above must be replaced with the hash
1584hash of Bob's public key (the output your friend obtained using 1579of Bob's public key (the output your friend obtained using the
1585the gnunet-identity command from the previous section and told you, 1580@command{gnunet-identity} command from the previous section and told
1586for example by giving you a business card containing this 1581you, for example by giving you a business card containing this
1587information as a QR code). 1582information as a QR code).
1588 1583
1589Assuming Bob has an A record for their website under the name of 1584Assuming Bob has an ``A'' record for their website under the name of
1590www in his zone, you can then access Bob's website under 1585``www'' in his zone, you can then access Bob's website under
1591www.bob.gnu --- as well as any (public) GNS record that Bob has 1586``www.bob.myzone'' --- as well as any (public) GNS record that Bob has
1592in their zone by replacing www with the respective name of the 1587in their zone by replacing www with the respective name of the
1593record in Bob's zone. 1588record in Bob's zone.
1594 1589
1595@c themselves? themself? 1590@c themselves? themself?
1596Furthermore, if Bob has themselves a (public) delegation to Carol's 1591Furthermore, if Bob has themselves a (public) delegation to Carol's
1597zone under "carol", you can access Carol's records under 1592zone under "carol", you can access Carol's records under
1598NAME.carol.bob.gnu (where NAME is the name of Carol's record you 1593``NAME.carol.bob.myzone'' (where ``NAME'' is the name of Carol's
1599want to access). 1594record you want to access).
1600
1601@node The Three Local Zones of GNS
1602@subsection The Three Local Zones of GNS
1603 1595
1604Each user GNS has control over three zones. Each of the zones
1605has a different purpose. These zones are the
1606 1596
1607@itemize @bullet 1597@node Using Public Keys as Top Level Domains
1608 1598@subsection Using Public Keys as Top Level Domains
1609@item master zone,
1610@item private zone, and the
1611@item shorten zone.
1612@end itemize
1613 1599
1614@node The Master Zone
1615@subsection The Master Zone
1616 1600
1617 1601GNS also assumes responsibility for any name that uses in a well-formed
1618The master zone is your personal TLD. Names within the @code{.gnu} 1602public key for the TLD. Names ending this way are then resolved by querying
1619namespace are resolved relative to this zone. You can arbitrarily 1603the respective zone. Such public key TLDs are expected to be used under rare
1620add records to this zone and selectively publish those records. 1604circumstances where globally unique names are required, and for
1621
1622@node The Private Zone
1623@subsection The Private Zone
1624
1625
1626The private zone is a subzone (or subdomain in DNS terms) of your
1627master zone. It should be used for records that you want to keep
1628private. For example @code{bank.private.gnu}. The key idea is that
1629you want to keep your private records separate, if just to know
1630that those names are not available to other users.
1631
1632@node The Shorten Zone
1633@subsection The Shorten Zone
1634
1635
1636The shorten zone can either be a subzone of the master zone or the
1637private zone. It is different from the other zones in that GNS
1638will automatically populate this zone with other users' zones based
1639on their PSEU records whenever you resolve a name.
1640
1641For example if you go to
1642@code{@uref{http://www.bob.alice.dave.gnu/, www.bob.alice.dave.gnu}},
1643GNS will try to import @code{bob} into your shorten zone. Having
1644obtained Bob's PKEY from @code{alice.dave.gnu}, GNS will lookup the
1645PSEU record for @code{+} in Bob's zone. If it exists and the specified
1646pseudonym is not taken, Bob's PKEY will be automatically added under
1647that pseudonym (i.e. "bob") into your shorten zone. From then on,
1648Bob's webpage will also be available for you as
1649@code{@uref{http://www.bob.short.gnu/, www.bob.short.gnu}}.
1650This feature is called @b{automatic name shortening} and is supposed to
1651keep GNS names as short and memorable as possible.
1652
1653@node The ZKEY Top Level Domain in GNS
1654@subsection The ZKEY Top Level Domain in GNS
1655
1656
1657GNS also provides a secure and globally unique namespace under the .zkey
1658top-level domain. A name in the .zkey TLD corresponds to the (printable)
1659public key of a zone. Names in the .zkey TLD are then resolved by querying
1660the respective zone. The .zkey TLD is expected to be used under rare
1661circumstances where globally unique names are required and for
1662integration with legacy systems. 1605integration with legacy systems.
1663 1606
1664@node Resource Records in GNS 1607@node Resource Records in GNS
@@ -1682,7 +1625,7 @@ to the current authoritative zone. The extended processing of those
1682names will expand the ".+" with the correct delegation chain to the 1625names will expand the ".+" with the correct delegation chain to the
1683authoritative zone (replacing ".+" with the name of the location 1626authoritative zone (replacing ".+" with the name of the location
1684where the name was encountered) and hence generate a 1627where the name was encountered) and hence generate a
1685valid @code{.gnu} name. 1628valid GNS name.
1686 1629
1687GNS currently supports the following record types: 1630GNS currently supports the following record types:
1688 1631
@@ -1703,21 +1646,23 @@ GNS currently supports the following record types:
1703 1646
1704A NICK record is used to give a zone a name. With a NICK record, you can 1647A NICK record is used to give a zone a name. With a NICK record, you can
1705essentially specify how you would like to be called. GNS expects this 1648essentially specify how you would like to be called. GNS expects this
1706record under the name "+" in the zone's database (NAMESTORE); however, 1649record under the empty label ``@atchar{}'' in the zone's database (NAMESTORE); however,
1707it will then automatically be copied into each record set, so that 1650it will then automatically be copied into each record set, so that
1708clients never need to do a separate lookup to discover the NICK record. 1651clients never need to do a separate lookup to discover the NICK record.
1652Also, users do not usually have to worry about setting the NICK record:
1653it is automatically set to the local name of the TLD.
1709 1654
1710@b{Example}@ 1655@b{Example}@
1711 1656
1712@example 1657@example
1713Name: +; RRType: NICK; Value: bob 1658Name: @atchar{}; RRType: NICK; Value: bob
1714@end example 1659@end example
1715 1660
1716@noindent 1661@noindent
1717This record in Bob's zone will tell other users that this zone wants 1662This record in Bob's zone will tell other users that this zone wants
1718to be referred to as 'bob'. Note that nobody is obliged to call Bob's 1663to be referred to as 'bob'. Note that nobody is obliged to call Bob's
1719zone 'bob' in their own zones. It can be seen as a 1664zone 'bob' in their own zones. It can be seen as a
1720recommendation ("Please call me 'bob'"). 1665recommendation ("Please call this zone 'bob'").
1721 1666
1722@node PKEY 1667@node PKEY
1723@subsubsection PKEY 1668@subsubsection PKEY
@@ -1864,6 +1809,36 @@ should use the ZKEY zone as the destination hostname and
1864GNS-enabled mail servers should be configured to accept 1809GNS-enabled mail servers should be configured to accept
1865e-mails to the ZKEY-zones of all local users. 1810e-mails to the ZKEY-zones of all local users.
1866 1811
1812@node Synchronizing with legacy DNS
1813@subsection Synchronizing with legacy DNS
1814
1815If you want to support GNS but the master database for a zone
1816is only available and maintained in DNS, GNUnet includes the
1817@command{gnunet-zoneimport} tool to monitor a DNS zone and
1818automatically import records into GNS. Today, the tool does
1819not yet support DNS AF(X)R, as we initially used it on the
1820``.fr'' zone which does not allow us to perform a DNS zone
1821transfer. Instead, @command{gnunet-zoneimport} reads a list
1822of DNS domain names from @code{stdin}, issues DNS queries for
1823each, converts the obtained records (if possible) and stores
1824the result in the namestore.
1825
1826@image{images/gns,6in,, picture of DNS-GNS data flow}
1827
1828The zonemaster service then takes the records from the namestore,
1829publishes them into the DHT which makes the result available to the
1830GNS resolver. In the GNS configuration, non-local zones can be
1831configured to be intercepted by specifying ``.tld = PUBLICKEY'' in the
1832configuration file in the ``[gns]'' section.
1833
1834Note that the namestore by default also populates the namecache.
1835This pre-population is cryptographically expensive. Thus, on
1836systems that only serve to import a large (millions of records)
1837DNS zone and that do not have a local gns service in use, it
1838is thus advisable to disable the namecache by setting the
1839option ``DISABLE'' to ``YES'' in section ``[namecache]''.
1840
1841
1867@node Using the Virtual Public Network 1842@node Using the Virtual Public Network
1868@section Using the Virtual Public Network 1843@section Using the Virtual Public Network
1869 1844
diff --git a/doc/documentation/images/gns.dot b/doc/documentation/images/gns.dot
new file mode 100644
index 000000000..55b05d482
--- /dev/null
+++ b/doc/documentation/images/gns.dot
@@ -0,0 +1,42 @@
1// house = interface towards application
2// circle (default) = storage
3// diamond = stateless tool
4// box = legacy system
5
6// this is what we have...o
7digraph dataflow {
8splines = true;
9
10 DNS [shape="box"];
11 import [label="gnunet-zoneimport", shape="diamond"];
12 namestore;
13 namecache;
14 gns [shape="diamond"];
15 dns2gns [shape="house"];
16 cmdline [label="gnunet-gns", shape="house"];
17 libnss_gns [shape="house"];
18 proxy [label="gnunet-gns-proxy", shape="house"];
19 dht;
20 zonemaster [shape="diamond"];
21
22 DNS -> import [label="import"];
23 import -> namestore [label="export"];
24
25 namestore -> zonemaster [label="notifies"];
26 zonemaster -> dht [label="publishes"];
27
28 namestore -> namecache [label="pre-populates"];
29
30
31
32 libnss_gns -> cmdline [label="invokes"];
33 cmdline -> gns [label="lookup"];
34
35 dns2gns -> gns [label="lookup"];
36
37 proxy -> gns [label="lookup"];
38
39 gns -> namecache [label="uses"];
40 gns -> dht [label="queries"];
41
42}
diff --git a/src/dht/gnunet_dht_profiler.c b/src/dht/gnunet_dht_profiler.c
index a8807bea8..12e99f65d 100644
--- a/src/dht/gnunet_dht_profiler.c
+++ b/src/dht/gnunet_dht_profiler.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2014 GNUnet e.V. 3 Copyright (C) 2014, 2018 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 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 6 it under the terms of the GNU General Public License as published
@@ -29,8 +29,8 @@
29#include "gnunet_testbed_service.h" 29#include "gnunet_testbed_service.h"
30#include "gnunet_dht_service.h" 30#include "gnunet_dht_service.h"
31 31
32#define INFO(...) \ 32#define MESSAGE(...) \
33 GNUNET_log (GNUNET_ERROR_TYPE_INFO, __VA_ARGS__) 33 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, __VA_ARGS__)
34 34
35#define DEBUG(...) \ 35#define DEBUG(...) \
36 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__) 36 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
@@ -38,7 +38,7 @@
38/** 38/**
39 * Number of peers which should perform a PUT out of 100 peers 39 * Number of peers which should perform a PUT out of 100 peers
40 */ 40 */
41#define PUT_PROBABILITY 50 41static unsigned int put_probability = 100;
42 42
43/** 43/**
44 * Configuration 44 * Configuration
@@ -121,7 +121,12 @@ struct ActiveContext
121 /** 121 /**
122 * Delay task 122 * Delay task
123 */ 123 */
124 struct GNUNET_SCHEDULER_Task * delay_task; 124 struct GNUNET_SCHEDULER_Task *delay_task;
125
126 /**
127 * How many puts should we still issue?
128 */
129 unsigned int put_count;
125 130
126 /** 131 /**
127 * The size of the @e put_data 132 * The size of the @e put_data
@@ -183,17 +188,17 @@ static unsigned int n_dht;
183/** 188/**
184 * Number of DHT PUTs made 189 * Number of DHT PUTs made
185 */ 190 */
186static unsigned int n_puts; 191static unsigned long long n_puts;
187 192
188/** 193/**
189 * Number of DHT PUTs succeeded 194 * Number of DHT PUTs to be made per peer.
190 */ 195 */
191static unsigned int n_puts_ok; 196static unsigned int num_puts_per_peer = 1;
192 197
193/** 198/**
194 * Number of DHT PUTs failed 199 * Number of DHT PUTs succeeded
195 */ 200 */
196static unsigned int n_puts_fail; 201static unsigned long long n_puts_ok;
197 202
198/** 203/**
199 * Number of DHT GETs made 204 * Number of DHT GETs made
@@ -226,11 +231,6 @@ static unsigned int max_searches;
226static struct GNUNET_TESTBED_Operation *bandwidth_stats_op; 231static struct GNUNET_TESTBED_Operation *bandwidth_stats_op;
227 232
228/** 233/**
229 * To get successor stats.
230 */
231static struct GNUNET_TESTBED_Operation *successor_stats_op;
232
233/**
234 * Testbed peer handles. 234 * Testbed peer handles.
235 */ 235 */
236static struct GNUNET_TESTBED_Peer **testbed_handles; 236static struct GNUNET_TESTBED_Peer **testbed_handles;
@@ -266,42 +266,6 @@ static unsigned int total_put_path_length;
266static unsigned int total_get_path_length; 266static unsigned int total_get_path_length;
267 267
268/** 268/**
269 * Hashmap to store pair of peer and its corresponding successor.
270 */
271static struct GNUNET_CONTAINER_MultiHashMap *successor_peer_hashmap;
272
273/**
274 * Key to start the lookup on successor_peer_hashmap.
275 */
276static struct GNUNET_HashCode *start_key;
277
278/**
279 * Flag used to get the start_key.
280 */
281static int flag = 0;
282
283/**
284 * Task to collect peer and its current successor statistics.
285 */
286static struct GNUNET_SCHEDULER_Task * successor_stats_task;
287
288/**
289 * Closure for successor_stats_task.
290 */
291struct Collect_Stat_Context
292{
293 /**
294 * Current Peer Context.
295 */
296 struct Context *service_connect_ctx;
297
298 /**
299 * Testbed operation acting on this peer
300 */
301 struct GNUNET_TESTBED_Operation *op;
302};
303
304/**
305 * List of all the peers contexts. 269 * List of all the peers contexts.
306 */ 270 */
307struct Context **peer_contexts = NULL; 271struct Context **peer_contexts = NULL;
@@ -327,20 +291,6 @@ static enum
327 */ 291 */
328static int in_shutdown = 0; 292static int in_shutdown = 0;
329 293
330/**
331 * Total number of times to check if circle is formed or not.
332 */
333static unsigned int tries;
334
335
336/**
337 * Task that collects successor statistics from all the peers.
338 *
339 * @param cls
340 */
341static void
342collect_stats (void *cls);
343
344 294
345/** 295/**
346 * Connect to DHT services of active peers 296 * Connect to DHT services of active peers
@@ -358,12 +308,11 @@ static void
358do_shutdown (void *cls) 308do_shutdown (void *cls)
359{ 309{
360 struct ActiveContext *ac; 310 struct ActiveContext *ac;
361 unsigned int cnt;
362 311
363 in_shutdown = GNUNET_YES; 312 in_shutdown = GNUNET_YES;
364 if (NULL != a_ctx) 313 if (NULL != a_ctx)
365 { 314 {
366 for (cnt=0; cnt < num_peers; cnt++) 315 for (unsigned int cnt=0; cnt < num_peers; cnt++)
367 { 316 {
368 /* Cleanup active context if this peer is an active peer */ 317 /* Cleanup active context if this peer is an active peer */
369 ac = a_ctx[cnt].ac; 318 ac = a_ctx[cnt].ac;
@@ -392,16 +341,6 @@ do_shutdown (void *cls)
392 GNUNET_TESTBED_operation_done (bandwidth_stats_op); 341 GNUNET_TESTBED_operation_done (bandwidth_stats_op);
393 bandwidth_stats_op = NULL; 342 bandwidth_stats_op = NULL;
394 } 343 }
395 if (NULL != successor_stats_op)
396 {
397 GNUNET_TESTBED_operation_done (successor_stats_op);
398 successor_stats_op = NULL;
399 }
400 if (NULL != successor_stats_task)
401 {
402 GNUNET_SCHEDULER_cancel (successor_stats_task);
403 successor_stats_task = NULL;
404 }
405 GNUNET_free_non_null (a_ac); 344 GNUNET_free_non_null (a_ac);
406} 345}
407 346
@@ -420,10 +359,13 @@ bandwidth_stats_cont (void *cls,
420 struct GNUNET_TESTBED_Operation *op, 359 struct GNUNET_TESTBED_Operation *op,
421 const char *emsg) 360 const char *emsg)
422{ 361{
423 INFO ("# Outgoing bandwidth: %llu\n", 362 MESSAGE ("# Outgoing bandwidth: %llu\n",
424 (unsigned long long) outgoing_bandwidth); 363 (unsigned long long) outgoing_bandwidth);
425 INFO ("# Incoming bandwidth: %llu\n", 364 MESSAGE ("# Incoming bandwidth: %llu\n",
426 (unsigned long long) incoming_bandwidth); 365 (unsigned long long) incoming_bandwidth);
366 fprintf (stderr,
367 "Benchmark done. Collect data via gnunet-statisics, then press ENTER to exit.\n");
368 getchar ();
427 GNUNET_SCHEDULER_shutdown (); 369 GNUNET_SCHEDULER_shutdown ();
428} 370}
429 371
@@ -447,40 +389,48 @@ bandwidth_stats_iterator (void *cls,
447 uint64_t value, 389 uint64_t value,
448 int is_persistent) 390 int is_persistent)
449{ 391{
450 static const char *s_sent = "# Bytes transmitted to other peers"; 392 static const char *s_sent = "# Bytes transmitted to other peers";
451 static const char *s_recv = "# Bytes received from other peers"; 393 static const char *s_recv = "# Bytes received from other peers";
452
453 if (0 == strncmp (s_sent, name, strlen (s_sent)))
454 outgoing_bandwidth = outgoing_bandwidth + value;
455 else if (0 == strncmp(s_recv, name, strlen (s_recv)))
456 incoming_bandwidth = incoming_bandwidth + value;
457 394
458 return GNUNET_OK; 395 if (0 == strncmp (s_sent, name, strlen (s_sent)))
396 outgoing_bandwidth = outgoing_bandwidth + value;
397 else if (0 == strncmp(s_recv, name, strlen (s_recv)))
398 incoming_bandwidth = incoming_bandwidth + value;
399 return GNUNET_OK;
459} 400}
460 401
461 402
462static void 403static void
463summarize () 404summarize ()
464{ 405{
465 INFO ("# PUTS made: %u\n", n_puts); 406 MESSAGE ("# PUTS started: %llu\n",
466 INFO ("# PUTS succeeded: %u\n", n_puts_ok); 407 n_puts);
467 INFO ("# PUTS failed: %u\n", n_puts_fail); 408 MESSAGE ("# PUTS succeeded: %llu\n",
468 INFO ("# GETS made: %u\n", n_gets); 409 n_puts_ok);
469 INFO ("# GETS succeeded: %u\n", n_gets_ok); 410 MESSAGE ("# GETS made: %u\n",
470 INFO ("# GETS failed: %u\n", n_gets_fail); 411 n_gets);
471 INFO ("# average_put_path_length: %f\n", average_put_path_length); 412 MESSAGE ("# GETS succeeded: %u\n",
472 INFO ("# average_get_path_length: %f\n", average_get_path_length); 413 n_gets_ok);
414 MESSAGE ("# GETS failed: %u\n",
415 n_gets_fail);
416 MESSAGE ("# average_put_path_length: %f\n",
417 average_put_path_length);
418 MESSAGE ("# average_get_path_length: %f\n",
419 average_get_path_length);
473 420
474 if (NULL == testbed_handles) 421 if (NULL == testbed_handles)
475 { 422 {
476 INFO ("No peers found\n"); 423 MESSAGE ("No peers found\n");
477 return; 424 return;
478 } 425 }
479 /* Collect Stats*/ 426 /* Collect Stats*/
480 bandwidth_stats_op = GNUNET_TESTBED_get_statistics (n_active, testbed_handles, 427 bandwidth_stats_op = GNUNET_TESTBED_get_statistics (n_active,
481 "dht", NULL, 428 testbed_handles,
482 bandwidth_stats_iterator, 429 "dht",
483 bandwidth_stats_cont, NULL); 430 NULL,
431 bandwidth_stats_iterator,
432 bandwidth_stats_cont,
433 NULL);
484} 434}
485 435
486 436
@@ -547,9 +497,12 @@ get_iter (void *cls,
547 struct Context *ctx = ac->ctx; 497 struct Context *ctx = ac->ctx;
548 498
549 /* Check the keys of put and get match or not. */ 499 /* Check the keys of put and get match or not. */
550 GNUNET_assert (0 == memcmp (key, &get_ac->hash, sizeof (struct GNUNET_HashCode))); 500 GNUNET_assert (0 == memcmp (key,
501 &get_ac->hash,
502 sizeof (struct GNUNET_HashCode)));
551 /* we found the data we are looking for */ 503 /* we found the data we are looking for */
552 DEBUG ("We found a GET request; %u remaining\n", n_gets - (n_gets_fail + n_gets_ok)); //FIXME: It always prints 1. 504 DEBUG ("We found a GET request; %u remaining\n",
505 n_gets - (n_gets_fail + n_gets_ok)); //FIXME: It always prints 1.
553 n_gets_ok++; 506 n_gets_ok++;
554 get_ac->nrefs--; 507 get_ac->nrefs--;
555 GNUNET_DHT_get_stop (ac->dht_get); 508 GNUNET_DHT_get_stop (ac->dht_get);
@@ -591,79 +544,67 @@ delayed_get (void *cls)
591 get_ac = NULL; 544 get_ac = NULL;
592 while (1) 545 while (1)
593 { 546 {
594 r = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, n_active); 547 r = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
548 n_active);
595 get_ac = &a_ac[r]; 549 get_ac = &a_ac[r];
596 if (NULL != get_ac->put_data) 550 if (NULL != get_ac->put_data)
597 break; 551 break;
598 } 552 }
599 get_ac->nrefs++; 553 get_ac->nrefs++;
600 ac->get_ac = get_ac; 554 ac->get_ac = get_ac;
601 DEBUG ("GET_REQUEST_START key %s \n", GNUNET_h2s((struct GNUNET_HashCode *)ac->put_data)); 555 DEBUG ("GET_REQUEST_START key %s \n",
556 GNUNET_h2s((struct GNUNET_HashCode *) ac->put_data));
602 ac->dht_get = GNUNET_DHT_get_start (ac->dht, 557 ac->dht_get = GNUNET_DHT_get_start (ac->dht,
603 GNUNET_BLOCK_TYPE_TEST, 558 GNUNET_BLOCK_TYPE_TEST,
604 &get_ac->hash, 559 &get_ac->hash,
605 1, /* replication level */ 560 1, /* replication level */
606 GNUNET_DHT_RO_NONE, 561 GNUNET_DHT_RO_NONE,
607 NULL, 0, /* extended query and size */ 562 NULL,
608 get_iter, ac); /* GET iterator and closure 563 0, /* extended query and size */
609 */ 564 get_iter,
565 ac); /* GET iterator and closure */
610 n_gets++; 566 n_gets++;
611 567
612 /* schedule the timeout task for GET */ 568 /* schedule the timeout task for GET */
613 ac->delay_task = GNUNET_SCHEDULER_add_delayed (timeout, &cancel_get, ac); 569 ac->delay_task = GNUNET_SCHEDULER_add_delayed (timeout,
570 &cancel_get,
571 ac);
614} 572}
615 573
616 574
617/** 575/**
618 * Task to teardown the dht connection. We do it as a task because calling 576 * Task to do DHT PUTs. If the "put_count" hits zero,
619 * GNUNET_DHT_disconnect() from put_continutation_callback seems illegal (the 577 * we stop the TESTBED operation (connection to DHT)
620 * put_continuation_callback() is getting called again synchronously). Also, 578 * so that others PUTs have a chance.
621 * only free the operation when we are not shutting down; the shutdown task will
622 * clear the operation during shutdown.
623 * 579 *
624 * @param cls the context 580 * @param cls the active context
625 */ 581 */
626static void 582static void
627teardown_dht_connection (void *cls) 583delayed_put (void *cls);
628{
629 struct Context *ctx = cls;
630 struct GNUNET_TESTBED_Operation *op;
631
632 GNUNET_assert (NULL != ctx);
633 GNUNET_assert (NULL != (op = ctx->op));
634 ctx->op = NULL;
635 GNUNET_TESTBED_operation_done (op);
636}
637 584
638 585
639/** 586/**
640 * Queue up a delayed task for doing DHT GET 587 * Conclude individual PUT operation, schedule the
588 * next one.
641 * 589 *
642 * @param cls the active context 590 * @param cls the active context
643 * @param success #GNUNET_OK if the PUT was transmitted,
644 * #GNUNET_NO on timeout,
645 * #GNUNET_SYSERR on disconnect from service
646 * after the PUT message was transmitted
647 * (so we don't know if it was received or not)
648 */ 591 */
649static void 592static void
650put_cont (void *cls, int success) 593put_cont (void *cls)
651{ 594{
652 struct ActiveContext *ac = cls; 595 struct ActiveContext *ac = cls;
653 struct Context *ctx = ac->ctx;
654 596
655 ac->dht_put = NULL; 597 ac->dht_put = NULL;
656 if (success) 598 n_puts_ok++;
657 n_puts_ok++; 599 ac->delay_task = GNUNET_SCHEDULER_add_now (&delayed_put,
658 else 600 ac);
659 n_puts_fail++;
660 GNUNET_assert (NULL != ctx);
661 (void) GNUNET_SCHEDULER_add_now (&teardown_dht_connection, ctx);
662} 601}
663 602
664 603
665/** 604/**
666 * Task to do DHT PUTs 605 * Task to do DHT PUTs. If the "put_count" hits zero,
606 * we stop the TESTBED operation (connection to DHT)
607 * so that others PUTs have a chance.
667 * 608 *
668 * @param cls the active context 609 * @param cls the active context
669 */ 610 */
@@ -673,16 +614,33 @@ delayed_put (void *cls)
673 struct ActiveContext *ac = cls; 614 struct ActiveContext *ac = cls;
674 615
675 ac->delay_task = NULL; 616 ac->delay_task = NULL;
617 if (0 == ac->put_count)
618 {
619 struct Context *ctx = ac->ctx;
620 struct GNUNET_TESTBED_Operation *op;
621
622 GNUNET_assert (NULL != ctx);
623 op = ctx->op;
624 ctx->op = NULL;
625 GNUNET_TESTBED_operation_done (op);
626 return;
627 }
628
629
676 /* Generate and DHT PUT some random data */ 630 /* Generate and DHT PUT some random data */
677 ac->put_data_size = 16; /* minimum */ 631 ac->put_data_size = 16; /* minimum */
678 ac->put_data_size += GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 632 ac->put_data_size += GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
679 (63*1024)); 633 (63*1024));
680 ac->put_data = GNUNET_malloc (ac->put_data_size); 634 ac->put_data = GNUNET_malloc (ac->put_data_size);
681 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, 635 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
682 ac->put_data, ac->put_data_size); 636 ac->put_data,
683 GNUNET_CRYPTO_hash (ac->put_data, ac->put_data_size, &ac->hash); 637 ac->put_data_size);
638 GNUNET_CRYPTO_hash (ac->put_data,
639 ac->put_data_size,
640 &ac->hash);
684 DEBUG ("PUT_REQUEST_START key %s\n", 641 DEBUG ("PUT_REQUEST_START key %s\n",
685 GNUNET_h2s((struct GNUNET_HashCode *)ac->put_data)); 642 GNUNET_h2s ((struct GNUNET_HashCode *)ac->put_data));
643 ac->put_count--;
686 ac->dht_put = GNUNET_DHT_put (ac->dht, 644 ac->dht_put = GNUNET_DHT_put (ac->dht,
687 &ac->hash, 645 &ac->hash,
688 replication, 646 replication,
@@ -691,7 +649,8 @@ delayed_put (void *cls)
691 ac->put_data_size, 649 ac->put_data_size,
692 ac->put_data, 650 ac->put_data,
693 GNUNET_TIME_UNIT_FOREVER_ABS, /* expiration time */ 651 GNUNET_TIME_UNIT_FOREVER_ABS, /* expiration time */
694 &put_cont, ac); /* continuation and its closure */ 652 &put_cont,
653 ac); /* continuation and its closure */
695 n_puts++; 654 n_puts++;
696} 655}
697 656
@@ -720,7 +679,9 @@ dht_connected (void *cls,
720 ac->dht = (struct GNUNET_DHT_Handle *) ca_result; 679 ac->dht = (struct GNUNET_DHT_Handle *) ca_result;
721 if (NULL != emsg) 680 if (NULL != emsg)
722 { 681 {
723 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Connection to DHT service failed: %s\n", emsg); 682 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
683 "Connection to DHT service failed: %s\n",
684 emsg);
724 GNUNET_TESTBED_operation_done (ctx->op); /* Calls dht_disconnect() */ 685 GNUNET_TESTBED_operation_done (ctx->op); /* Calls dht_disconnect() */
725 ctx->op = NULL; 686 ctx->op = NULL;
726 return; 687 return;
@@ -728,24 +689,31 @@ dht_connected (void *cls,
728 switch (mode) 689 switch (mode)
729 { 690 {
730 case MODE_PUT: 691 case MODE_PUT:
731 { 692 {
732 struct GNUNET_TIME_Relative peer_delay_put; 693 struct GNUNET_TIME_Relative peer_delay_put;
733 peer_delay_put.rel_value_us = 694
734 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, 695 peer_delay_put.rel_value_us =
735 delay_put.rel_value_us); 696 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
736 ac->delay_task = GNUNET_SCHEDULER_add_delayed (peer_delay_put, &delayed_put, ac); 697 delay_put.rel_value_us);
737 break; 698 ac->put_count = num_puts_per_peer;
738 } 699 ac->delay_task = GNUNET_SCHEDULER_add_delayed (peer_delay_put,
700 &delayed_put,
701 ac);
702 break;
703 }
739 case MODE_GET: 704 case MODE_GET:
740 { 705 {
741 struct GNUNET_TIME_Relative peer_delay_get; 706 struct GNUNET_TIME_Relative peer_delay_get;
742 peer_delay_get.rel_value_us = 707
743 delay_get.rel_value_us + 708 peer_delay_get.rel_value_us =
744 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, 709 delay_get.rel_value_us +
745 delay_get.rel_value_us); 710 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
746 ac->delay_task = GNUNET_SCHEDULER_add_delayed (peer_delay_get, &delayed_get, ac); 711 delay_get.rel_value_us);
747 break; 712 ac->delay_task = GNUNET_SCHEDULER_add_delayed (peer_delay_get,
748 } 713 &delayed_get,
714 ac);
715 break;
716 }
749 } 717 }
750} 718}
751 719
@@ -760,10 +728,12 @@ dht_connected (void *cls,
760 * @return service handle to return in 'op_result', NULL on error 728 * @return service handle to return in 'op_result', NULL on error
761 */ 729 */
762static void * 730static void *
763dht_connect (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg) 731dht_connect (void *cls,
732 const struct GNUNET_CONFIGURATION_Handle *cfg)
764{ 733{
765 n_dht++; 734 n_dht++;
766 return GNUNET_DHT_connect (cfg, 10); 735 return GNUNET_DHT_connect (cfg,
736 10);
767} 737}
768 738
769 739
@@ -775,7 +745,8 @@ dht_connect (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg)
775 * @param op_result service handle returned from the connect adapter 745 * @param op_result service handle returned from the connect adapter
776 */ 746 */
777static void 747static void
778dht_disconnect (void *cls, void *op_result) 748dht_disconnect (void *cls,
749 void *op_result)
779{ 750{
780 struct ActiveContext *ac = cls; 751 struct ActiveContext *ac = cls;
781 752
@@ -791,11 +762,10 @@ dht_disconnect (void *cls, void *op_result)
791 switch (mode) 762 switch (mode)
792 { 763 {
793 case MODE_PUT: 764 case MODE_PUT:
794 if ((n_puts_ok + n_puts_fail) != n_active) 765 if (n_puts_ok != n_active * num_puts_per_peer)
795 return; 766 return;
796 /* Start GETs if all PUTs have been made */ 767 /* Start GETs if all PUTs have been made */
797 mode = MODE_GET; 768 mode = MODE_GET;
798 //(void) GNUNET_SCHEDULER_add_now (&call_start_profiling, NULL);
799 start_profiling (); 769 start_profiling ();
800 return; 770 return;
801 case MODE_GET: 771 case MODE_GET:
@@ -805,6 +775,7 @@ dht_disconnect (void *cls, void *op_result)
805 } 775 }
806} 776}
807 777
778
808/** 779/**
809 * Connect to DHT services of active peers 780 * Connect to DHT services of active peers
810 */ 781 */
@@ -812,229 +783,22 @@ static void
812start_profiling() 783start_profiling()
813{ 784{
814 struct Context *ctx; 785 struct Context *ctx;
815 unsigned int i;
816 786
817 DEBUG("GNUNET_TESTBED_service_connect \n"); 787 DEBUG ("GNUNET_TESTBED_service_connect\n");
818 GNUNET_break (GNUNET_YES != in_shutdown); 788 GNUNET_break (GNUNET_YES != in_shutdown);
819 for(i = 0; i < n_active; i++) 789 for (unsigned int i = 0; i < n_active; i++)
820 { 790 {
821 struct ActiveContext *ac = &a_ac[i]; 791 struct ActiveContext *ac = &a_ac[i];
822 GNUNET_assert (NULL != (ctx = ac->ctx)); 792 GNUNET_assert (NULL != (ctx = ac->ctx));
823 GNUNET_assert (NULL == ctx->op); 793 GNUNET_assert (NULL == ctx->op);
824 ctx->op = 794 ctx->op = GNUNET_TESTBED_service_connect (ctx,
825 GNUNET_TESTBED_service_connect (ctx, 795 ctx->peer,
826 ctx->peer, 796 "dht",
827 "dht", 797 &dht_connected, ac,
828 &dht_connected, ac, 798 &dht_connect,
829 &dht_connect, 799 &dht_disconnect,
830 &dht_disconnect, 800 ac);
831 ac);
832 }
833}
834
835/**
836 * Start collecting relevant statistics. If ENABLE_MALICIOUS set, first
837 * set the malicious peers. If not, then start with PUT operation on active
838 * peers.
839 */
840static void
841start_func()
842{
843 start_profiling();
844}
845
846
847/**
848 * Remove entry from successor peer hashmap.
849 * @param cls closure
850 * @param key current public key
851 * @param value value in the hash map
852 * @return #GNUNET_YES if we should continue to iterate,
853 * #GNUNET_NO if not.
854 */
855static int
856hashmap_iterate_remove(void *cls,
857 const struct GNUNET_HashCode *key,
858 void *value)
859{
860 GNUNET_assert (GNUNET_YES ==
861 GNUNET_CONTAINER_multihashmap_remove(successor_peer_hashmap, key, value));
862 return GNUNET_YES;
863}
864
865
866/**
867 * Stats callback. Iterate over the hashmap and check if all th peers form
868 * a virtual ring topology.
869 *
870 * @param cls closure
871 * @param op the operation that has been finished
872 * @param emsg error message in case the operation has failed; will be NULL if
873 * operation has executed successfully.
874 */
875static void
876successor_stats_cont (void *cls,
877 struct GNUNET_TESTBED_Operation *op,
878 const char *emsg)
879{
880 struct GNUNET_HashCode *val;
881 struct GNUNET_HashCode *start_val;
882 struct GNUNET_HashCode *key;
883 int count;
884
885 /* Don't schedule the task till we are looking for circle here. */
886 successor_stats_task = NULL;
887 GNUNET_TESTBED_operation_done (successor_stats_op);
888 successor_stats_op = NULL;
889 if (0 == max_searches)
890 {
891 start_func ();
892 return;
893 }
894
895 GNUNET_assert (NULL != start_key);
896 start_val = GNUNET_CONTAINER_multihashmap_get (successor_peer_hashmap,
897 start_key);
898 GNUNET_assert (NULL != start_val);
899 val = start_val;
900 for (count = 0; count < num_peers; count++)
901 {
902 key = val;
903 val = GNUNET_CONTAINER_multihashmap_get (successor_peer_hashmap,
904 key);
905 if (NULL == val)
906 break;
907 /* Remove the entry from hashmap. This is done to take care of loop. */
908 if (GNUNET_NO ==
909 GNUNET_CONTAINER_multihashmap_remove (successor_peer_hashmap,
910 key, val))
911 {
912 DEBUG ("Failed to remove entry from hashmap\n");
913 break;
914 }
915 /* If a peer has its own identity as its successor. */
916 if (0 == memcmp(key, val, sizeof (struct GNUNET_HashCode)))
917 break;
918 }
919
920 GNUNET_assert (GNUNET_SYSERR !=
921 GNUNET_CONTAINER_multihashmap_iterate (successor_peer_hashmap,
922 &hashmap_iterate_remove,
923 NULL));
924
925 successor_peer_hashmap = GNUNET_CONTAINER_multihashmap_create (num_peers,
926 GNUNET_NO);
927 if ((start_val == val) && (count == num_peers))
928 {
929 DEBUG ("CIRCLE COMPLETED after %u tries", tries);
930 if(NULL == successor_stats_task)
931 {
932 start_func();
933 }
934 return;
935 }
936 if (max_searches == ++tries)
937 {
938 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
939 "Maximum tries %u exceeded while checking successor TOTAL TRIES %u"
940 " circle formation. Exiting\n",
941 max_searches,tries);
942 start_func();
943 return;
944 }
945 flag = 0;
946 successor_stats_task
947 = GNUNET_SCHEDULER_add_delayed (delay_stats,
948 &collect_stats,
949 cls);
950}
951
952
953/**
954 * Process successor statistic values.
955 *
956 * @param cls closure
957 * @param peer the peer the statistic belong to
958 * @param subsystem name of subsystem that created the statistic
959 * @param name the name of the datum
960 * @param value the current value
961 * @param is_persistent GNUNET_YES if the value is persistent, GNUNET_NO if not
962 * @return GNUNET_OK to continue, GNUNET_SYSERR to abort iteration
963 */
964static int
965successor_stats_iterator (void *cls,
966 const struct GNUNET_TESTBED_Peer *peer,
967 const char *subsystem,
968 const char *name,
969 uint64_t value,
970 int is_persistent)
971{
972 static const char *key_string = "XDHT";
973 if (0 == max_searches)
974 return GNUNET_OK;
975
976 if (0 == strncmp (key_string, name, strlen (key_string)))
977 {
978 char *my_id_str;
979 char successor_str[13];
980 char truncated_my_id_str[13];
981 char truncated_successor_str[13];
982 struct GNUNET_HashCode *my_id_key;
983 struct GNUNET_HashCode *succ_key;
984
985 strtok((char *)name,":");
986 my_id_str = strtok(NULL,":");
987
988 strncpy(truncated_my_id_str, my_id_str, 12);
989 truncated_my_id_str[12] = '\0';
990 my_id_key = GNUNET_new(struct GNUNET_HashCode);
991 GNUNET_CRYPTO_hash (truncated_my_id_str, sizeof(truncated_my_id_str),my_id_key);
992 GNUNET_STRINGS_data_to_string(&value, sizeof(uint64_t), successor_str, 13);
993 strncpy(truncated_successor_str, successor_str, 12);
994 truncated_successor_str[12] ='\0';
995
996 succ_key = GNUNET_new(struct GNUNET_HashCode);
997 GNUNET_CRYPTO_hash (truncated_successor_str, sizeof(truncated_successor_str),succ_key);
998
999 if (0 == flag)
1000 {
1001 GNUNET_assert(NULL != my_id_key);
1002 start_key = my_id_key;
1003 GNUNET_assert(NULL != start_key);
1004 flag = 1;
1005 }
1006 GNUNET_CONTAINER_multihashmap_put (successor_peer_hashmap,
1007 my_id_key, (void *)succ_key,
1008 GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE);
1009 } 801 }
1010
1011 return GNUNET_OK;
1012}
1013
1014
1015/*
1016 * Task that collects peer and its corresponding successors.
1017 *
1018 * @param cls Closure (NULL).
1019 */
1020static void
1021collect_stats (void *cls)
1022{
1023 successor_stats_task = NULL;
1024 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1025 "Start collecting statistics...\n");
1026 GNUNET_assert(NULL != testbed_handles);
1027
1028 if (0 != max_searches)
1029 successor_peer_hashmap
1030 = GNUNET_CONTAINER_multihashmap_create (num_peers,
1031 GNUNET_NO);
1032 successor_stats_op
1033 = GNUNET_TESTBED_get_statistics (num_peers, testbed_handles,
1034 "dht", NULL,
1035 successor_stats_iterator,
1036 successor_stats_cont, cls);
1037 GNUNET_assert (NULL != successor_stats_op);
1038} 802}
1039 803
1040 804
@@ -1058,19 +822,11 @@ service_started (void *cls,
1058 GNUNET_TESTBED_operation_done (ctx->op); 822 GNUNET_TESTBED_operation_done (ctx->op);
1059 ctx->op = NULL; 823 ctx->op = NULL;
1060 peers_started++; 824 peers_started++;
1061 DEBUG("Peers Started = %d; num_peers = %d \n", peers_started, num_peers); 825 DEBUG ("Peers Started = %d; num_peers = %d \n",
1062 if (NULL == successor_stats_task && peers_started == num_peers) 826 peers_started,
1063 { 827 num_peers);
1064 DEBUG("successor_stats_task \n"); 828 if (peers_started == num_peers)
1065 struct Collect_Stat_Context *collect_stat_cls = GNUNET_new(struct Collect_Stat_Context); 829 start_profiling ();
1066 collect_stat_cls->service_connect_ctx = cls;
1067 collect_stat_cls->op = op;
1068
1069 successor_stats_task
1070 = GNUNET_SCHEDULER_add_delayed (delay_stats,
1071 &collect_stats,
1072 collect_stat_cls);
1073 }
1074} 830}
1075 831
1076 832
@@ -1088,36 +844,40 @@ service_started (void *cls,
1088static void 844static void
1089test_run (void *cls, 845test_run (void *cls,
1090 struct GNUNET_TESTBED_RunHandle *h, 846 struct GNUNET_TESTBED_RunHandle *h,
1091 unsigned int num_peers, struct GNUNET_TESTBED_Peer **peers, 847 unsigned int num_peers,
848 struct GNUNET_TESTBED_Peer **peers,
1092 unsigned int links_succeeded, 849 unsigned int links_succeeded,
1093 unsigned int links_failed) 850 unsigned int links_failed)
1094{ 851{
1095 unsigned int cnt;
1096 unsigned int ac_cnt; 852 unsigned int ac_cnt;
853
1097 testbed_handles = peers; 854 testbed_handles = peers;
1098 if (NULL == peers) 855 if (NULL == peers)
1099 { 856 {
1100 /* exit */ 857 /* exit */
1101 GNUNET_assert (0); 858 GNUNET_assert (0);
1102 } 859 }
1103 INFO ("%u peers started\n", num_peers); 860 MESSAGE ("%u peers started\n",
1104 a_ctx = GNUNET_malloc (sizeof (struct Context) * num_peers); 861 num_peers);
1105 862 a_ctx = GNUNET_new_array (num_peers,
863 struct Context);
1106 /* select the peers which actively participate in profiling */ 864 /* select the peers which actively participate in profiling */
1107 n_active = num_peers * PUT_PROBABILITY / 100; 865 n_active = num_peers * put_probability / 100;
1108 if (0 == n_active) 866 if (0 == n_active)
1109 { 867 {
1110 GNUNET_SCHEDULER_shutdown (); 868 GNUNET_SCHEDULER_shutdown ();
1111 GNUNET_free (a_ctx); 869 GNUNET_free (a_ctx);
870 a_ctx = NULL;
1112 return; 871 return;
1113 } 872 }
1114 873
1115 a_ac = GNUNET_malloc (n_active * sizeof (struct ActiveContext)); 874 a_ac = GNUNET_new_array (n_active,
875 struct ActiveContext);
1116 ac_cnt = 0; 876 ac_cnt = 0;
1117 for (cnt = 0; cnt < num_peers && ac_cnt < n_active; cnt++) 877 for (unsigned int cnt = 0; cnt < num_peers && ac_cnt < n_active; cnt++)
1118 { 878 {
1119 if ((GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 100) >= 879 if (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
1120 PUT_PROBABILITY)) 880 100) >= put_probability)
1121 continue; 881 continue;
1122 882
1123 a_ctx[cnt].ac = &a_ac[ac_cnt]; 883 a_ctx[cnt].ac = &a_ac[ac_cnt];
@@ -1125,10 +885,11 @@ test_run (void *cls,
1125 ac_cnt++; 885 ac_cnt++;
1126 } 886 }
1127 n_active = ac_cnt; 887 n_active = ac_cnt;
1128 INFO ("Active peers: %u\n", n_active); 888 MESSAGE ("Active peers: %u\n",
889 n_active);
1129 890
1130 /* start DHT service on all peers */ 891 /* start DHT service on all peers */
1131 for (cnt = 0; cnt < num_peers; cnt++) 892 for (unsigned int cnt = 0; cnt < num_peers; cnt++)
1132 { 893 {
1133 a_ctx[cnt].peer = peers[cnt]; 894 a_ctx[cnt].peer = peers[cnt];
1134 a_ctx[cnt].op = GNUNET_TESTBED_peer_manage_service (&a_ctx[cnt], 895 a_ctx[cnt].op = GNUNET_TESTBED_peer_manage_service (&a_ctx[cnt],
@@ -1150,7 +911,9 @@ test_run (void *cls,
1150 * @param config configuration 911 * @param config configuration
1151 */ 912 */
1152static void 913static void
1153run (void *cls, char *const *args, const char *cfgfile, 914run (void *cls,
915 char *const *args,
916 const char *cfgfile,
1154 const struct GNUNET_CONFIGURATION_Handle *config) 917 const struct GNUNET_CONFIGURATION_Handle *config)
1155{ 918{
1156 uint64_t event_mask; 919 uint64_t event_mask;
@@ -1164,8 +927,14 @@ run (void *cls, char *const *args, const char *cfgfile,
1164 } 927 }
1165 cfg = GNUNET_CONFIGURATION_dup (config); 928 cfg = GNUNET_CONFIGURATION_dup (config);
1166 event_mask = 0; 929 event_mask = 0;
1167 GNUNET_TESTBED_run (hosts_file, cfg, num_peers, event_mask, NULL, 930 GNUNET_TESTBED_run (hosts_file,
1168 NULL, &test_run, NULL); 931 cfg,
932 num_peers,
933 event_mask,
934 NULL,
935 NULL,
936 &test_run,
937 NULL);
1169 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, 938 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
1170 NULL); 939 NULL);
1171} 940}
@@ -1177,63 +946,68 @@ run (void *cls, char *const *args, const char *cfgfile,
1177 * @return 0 on success 946 * @return 0 on success
1178 */ 947 */
1179int 948int
1180main (int argc, char *const *argv) 949main (int argc,
950 char *const *argv)
1181{ 951{
1182 int rc; 952 int rc;
1183
1184 struct GNUNET_GETOPT_CommandLineOption options[] = { 953 struct GNUNET_GETOPT_CommandLineOption options[] = {
1185 GNUNET_GETOPT_option_uint ('n', 954 GNUNET_GETOPT_option_uint ('n',
1186 "peers", 955 "peers",
1187 "COUNT", 956 "COUNT",
1188 gettext_noop ("number of peers to start"), 957 gettext_noop ("number of peers to start"),
1189 &num_peers), 958 &num_peers),
1190 959 GNUNET_GETOPT_option_uint ('p',
960 "peer-put-count",
961 "COUNT",
962 gettext_noop ("number of PUTs to perform per peer"),
963 &num_puts_per_peer),
1191 GNUNET_GETOPT_option_uint ('s', 964 GNUNET_GETOPT_option_uint ('s',
1192 "searches", 965 "searches",
1193 "COUNT", 966 "COUNT",
1194 gettext_noop ("maximum number of times we try to search for successor circle formation (0 for R5N)"), 967 gettext_noop ("maximum number of times we try to search for successor circle formation (0 for R5N)"),
1195 &max_searches), 968 &max_searches),
1196
1197 GNUNET_GETOPT_option_string ('H', 969 GNUNET_GETOPT_option_string ('H',
1198 "hosts", 970 "hosts",
1199 "FILENAME", 971 "FILENAME",
1200 gettext_noop ("name of the file with the login information for the testbed"), 972 gettext_noop ("name of the file with the login information for the testbed"),
1201 &hosts_file), 973 &hosts_file),
1202
1203 GNUNET_GETOPT_option_relative_time ('D', 974 GNUNET_GETOPT_option_relative_time ('D',
1204 "delay", 975 "delay",
1205 "DELAY", 976 "DELAY",
1206 gettext_noop ("delay between rounds for collecting statistics (default: 30 sec)"), 977 gettext_noop ("delay between rounds for collecting statistics (default: 30 sec)"),
1207 &delay_stats), 978 &delay_stats),
1208
1209 GNUNET_GETOPT_option_relative_time ('P', 979 GNUNET_GETOPT_option_relative_time ('P',
1210 "PUT-delay", 980 "PUT-delay",
1211 "DELAY", 981 "DELAY",
1212 gettext_noop ("delay to start doing PUTs (default: 1 sec)"), 982 gettext_noop ("delay to start doing PUTs (default: 1 sec)"),
1213 &delay_put), 983 &delay_put),
1214
1215 GNUNET_GETOPT_option_relative_time ('G', 984 GNUNET_GETOPT_option_relative_time ('G',
1216 "GET-delay", 985 "GET-delay",
1217 "DELAY", 986 "DELAY",
1218 gettext_noop ("delay to start doing GETs (default: 5 min)"), 987 gettext_noop ("delay to start doing GETs (default: 5 min)"),
1219 &delay_get), 988 &delay_get),
1220 GNUNET_GETOPT_option_uint ('r', 989 GNUNET_GETOPT_option_uint ('r',
1221 "replication", 990 "replication",
1222 "DEGREE", 991 "DEGREE",
1223 gettext_noop ("replication degree for DHT PUTs"), 992 gettext_noop ("replication degree for DHT PUTs"),
1224 &replication), 993 &replication),
1225 994 GNUNET_GETOPT_option_uint ('R',
1226 995 "random-chance",
996 "PROBABILITY",
997 gettext_noop ("chance that a peer is selected at random for PUTs"),
998 &put_probability),
1227 GNUNET_GETOPT_option_relative_time ('t', 999 GNUNET_GETOPT_option_relative_time ('t',
1228 "timeout", 1000 "timeout",
1229 "TIMEOUT", 1001 "TIMEOUT",
1230 gettext_noop ("timeout for DHT PUT and GET requests (default: 1 min)"), 1002 gettext_noop ("timeout for DHT PUT and GET requests (default: 1 min)"),
1231 &timeout), 1003 &timeout),
1232 GNUNET_GETOPT_OPTION_END 1004 GNUNET_GETOPT_OPTION_END
1233 }; 1005 };
1234 1006
1235 max_searches = 5; 1007 max_searches = 5;
1236 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) 1008 if (GNUNET_OK !=
1009 GNUNET_STRINGS_get_utf8_args (argc, argv,
1010 &argc, &argv))
1237 return 2; 1011 return 2;
1238 /* set default delays */ 1012 /* set default delays */
1239 delay_stats = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10); 1013 delay_stats = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10);
@@ -1243,10 +1017,13 @@ main (int argc, char *const *argv)
1243 replication = 1; /* default replication */ 1017 replication = 1; /* default replication */
1244 rc = 0; 1018 rc = 0;
1245 if (GNUNET_OK != 1019 if (GNUNET_OK !=
1246 GNUNET_PROGRAM_run (argc, argv, "dht-profiler", 1020 GNUNET_PROGRAM_run (argc,
1247 gettext_noop 1021 argv,
1248 ("Measure quality and performance of the DHT service."), 1022 "gnunet-dht-profiler",
1249 options, &run, NULL)) 1023 gettext_noop ("Measure quality and performance of the DHT service."),
1024 options,
1025 &run,
1026 NULL))
1250 rc = 1; 1027 rc = 1;
1251 return rc; 1028 return rc;
1252} 1029}
diff --git a/src/namestore/gnunet-namestore.c b/src/namestore/gnunet-namestore.c
index d329dcb3b..32b1a39d0 100644
--- a/src/namestore/gnunet-namestore.c
+++ b/src/namestore/gnunet-namestore.c
@@ -374,16 +374,12 @@ zone_iteration_error_cb (void *cls)
374/** 374/**
375 * Process a record that was stored in the namestore. 375 * Process a record that was stored in the namestore.
376 * 376 *
377 * @param cls closure
378 * @param zone_key private key of the zone
379 * @param rname name that is being mapped (at most 255 characters long) 377 * @param rname name that is being mapped (at most 255 characters long)
380 * @param rd_len number of entries in @a rd array 378 * @param rd_len number of entries in @a rd array
381 * @param rd array of records with data to store 379 * @param rd array of records with data to store
382 */ 380 */
383static void 381static void
384display_record (void *cls, 382display_record (const char *rname,
385 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
386 const char *rname,
387 unsigned int rd_len, 383 unsigned int rd_len,
388 const struct GNUNET_GNSRECORD_Data *rd) 384 const struct GNUNET_GNSRECORD_Data *rd)
389{ 385{
@@ -393,8 +389,6 @@ display_record (void *cls,
393 struct GNUNET_TIME_Absolute at; 389 struct GNUNET_TIME_Absolute at;
394 struct GNUNET_TIME_Relative rt; 390 struct GNUNET_TIME_Relative rt;
395 391
396 (void) cls;
397 (void) zone_key;
398 if ( (NULL != name) && 392 if ( (NULL != name) &&
399 (0 != strcmp (name, rname)) ) 393 (0 != strcmp (name, rname)) )
400 { 394 {
@@ -442,12 +436,62 @@ display_record (void *cls,
442 GNUNET_free (s); 436 GNUNET_free (s);
443 } 437 }
444 FPRINTF (stdout, "%s", "\n"); 438 FPRINTF (stdout, "%s", "\n");
439}
440
441
442/**
443 * Process a record that was stored in the namestore.
444 *
445 * @param cls closure
446 * @param zone_key private key of the zone
447 * @param rname name that is being mapped (at most 255 characters long)
448 * @param rd_len number of entries in @a rd array
449 * @param rd array of records with data to store
450 */
451static void
452display_record_iterator (void *cls,
453 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
454 const char *rname,
455 unsigned int rd_len,
456 const struct GNUNET_GNSRECORD_Data *rd)
457{
458 (void) cls;
459 (void) zone_key;
460 display_record (rname,
461 rd_len,
462 rd);
445 GNUNET_NAMESTORE_zone_iterator_next (list_it, 463 GNUNET_NAMESTORE_zone_iterator_next (list_it,
446 1); 464 1);
447} 465}
448 466
449 467
450/** 468/**
469 * Process a record that was stored in the namestore.
470 *
471 * @param cls closure
472 * @param zone_key private key of the zone
473 * @param rname name that is being mapped (at most 255 characters long)
474 * @param rd_len number of entries in @a rd array
475 * @param rd array of records with data to store
476 */
477static void
478display_record_monitor (void *cls,
479 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
480 const char *rname,
481 unsigned int rd_len,
482 const struct GNUNET_GNSRECORD_Data *rd)
483{
484 (void) cls;
485 (void) zone_key;
486 display_record (rname,
487 rd_len,
488 rd);
489 GNUNET_NAMESTORE_zone_monitor_next (zm,
490 1);
491}
492
493
494/**
451 * Function called once we are in sync in monitor mode. 495 * Function called once we are in sync in monitor mode.
452 * 496 *
453 * @param cls NULL 497 * @param cls NULL
@@ -956,7 +1000,7 @@ identity_cb (void *cls,
956 &zone_pkey, 1000 &zone_pkey,
957 &zone_iteration_error_cb, 1001 &zone_iteration_error_cb,
958 NULL, 1002 NULL,
959 &display_record, 1003 &display_record_iterator,
960 NULL, 1004 NULL,
961 &zone_iteration_finished, 1005 &zone_iteration_finished,
962 NULL); 1006 NULL);
@@ -1054,7 +1098,7 @@ identity_cb (void *cls,
1054 GNUNET_YES, 1098 GNUNET_YES,
1055 &monitor_error_cb, 1099 &monitor_error_cb,
1056 NULL, 1100 NULL,
1057 &display_record, 1101 &display_record_monitor,
1058 NULL, 1102 NULL,
1059 &sync_cb, 1103 &sync_cb,
1060 NULL); 1104 NULL);
diff --git a/src/namestore/test_namestore_api_monitoring.c b/src/namestore/test_namestore_api_monitoring.c
index f6d4fe226..cd38b2c80 100644
--- a/src/namestore/test_namestore_api_monitoring.c
+++ b/src/namestore/test_namestore_api_monitoring.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2013 GNUnet e.V. 3 Copyright (C) 2013, 2018 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 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 6 it under the terms of the GNU General Public License as published
@@ -192,7 +192,8 @@ zone_proc (void *cls,
192 GNUNET_break (0); 192 GNUNET_break (0);
193 fail = GNUNET_YES; 193 fail = GNUNET_YES;
194 } 194 }
195 195 GNUNET_NAMESTORE_zone_monitor_next (zm,
196 1);
196 if (2 == ++returned_records) 197 if (2 == ++returned_records)
197 { 198 {
198 if (endbadly_task != NULL) 199 if (endbadly_task != NULL)
diff --git a/src/namestore/test_namestore_api_monitoring_existing.c b/src/namestore/test_namestore_api_monitoring_existing.c
index 17f726eb1..f6a74609e 100644
--- a/src/namestore/test_namestore_api_monitoring_existing.c
+++ b/src/namestore/test_namestore_api_monitoring_existing.c
@@ -159,19 +159,24 @@ zone_proc (void *cls,
159 "Comparing results name %s\n", 159 "Comparing results name %s\n",
160 name); 160 name);
161 161
162 if (0 != memcmp (zone_key, privkey, sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey))) 162 if (0 != memcmp (zone_key,
163 privkey,
164 sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)))
163 { 165 {
164 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 166 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
165 "Monitoring returned wrong zone key\n"); 167 "Monitoring returned wrong zone key\n");
166 GNUNET_break (0); 168 GNUNET_break (0);
167 GNUNET_SCHEDULER_cancel (endbadly_task); 169 GNUNET_SCHEDULER_cancel (endbadly_task);
168 endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL); 170 endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly,
171 NULL);
169 return; 172 return;
170 } 173 }
171 174
172 if (0 == strcmp (name, s_name_1)) 175 if (0 == strcmp (name, s_name_1))
173 { 176 {
174 if (GNUNET_YES != GNUNET_GNSRECORD_records_cmp(rd, s_rd_1)) 177 if (GNUNET_YES !=
178 GNUNET_GNSRECORD_records_cmp (rd,
179 s_rd_1))
175 { 180 {
176 GNUNET_break (0); 181 GNUNET_break (0);
177 fail = GNUNET_YES; 182 fail = GNUNET_YES;
@@ -179,7 +184,9 @@ zone_proc (void *cls,
179 } 184 }
180 else if (0 == strcmp (name, s_name_2)) 185 else if (0 == strcmp (name, s_name_2))
181 { 186 {
182 if (GNUNET_YES != GNUNET_GNSRECORD_records_cmp(rd, s_rd_2)) 187 if (GNUNET_YES !=
188 GNUNET_GNSRECORD_records_cmp (rd,
189 s_rd_2))
183 { 190 {
184 GNUNET_break (0); 191 GNUNET_break (0);
185 fail = GNUNET_YES; 192 fail = GNUNET_YES;
@@ -192,7 +199,8 @@ zone_proc (void *cls,
192 GNUNET_break (0); 199 GNUNET_break (0);
193 fail = GNUNET_YES; 200 fail = GNUNET_YES;
194 } 201 }
195 202 GNUNET_NAMESTORE_zone_monitor_next (zm,
203 1);
196 if (2 == ++returned_records) 204 if (2 == ++returned_records)
197 { 205 {
198 if (endbadly_task != NULL) 206 if (endbadly_task != NULL)
@@ -201,9 +209,11 @@ zone_proc (void *cls,
201 endbadly_task = NULL; 209 endbadly_task = NULL;
202 } 210 }
203 if (GNUNET_YES == fail) 211 if (GNUNET_YES == fail)
204 GNUNET_SCHEDULER_add_now (&endbadly, NULL); 212 GNUNET_SCHEDULER_add_now (&endbadly,
213 NULL);
205 else 214 else
206 GNUNET_SCHEDULER_add_now (&end, NULL); 215 GNUNET_SCHEDULER_add_now (&end,
216 NULL);
207 } 217 }
208} 218}
209 219
@@ -223,7 +233,9 @@ sync_cb (void *cls)
223 233
224 234
225static void 235static void
226put_cont (void *cls, int32_t success, const char *emsg) 236put_cont (void *cls,
237 int32_t success,
238 const char *emsg)
227{ 239{
228 static int c = 0; 240 static int c = 0;
229 char *label = cls; 241 char *label = cls;
@@ -238,11 +250,15 @@ put_cont (void *cls, int32_t success, const char *emsg)
238 if (success == GNUNET_OK) 250 if (success == GNUNET_OK)
239 { 251 {
240 c++; 252 c++;
241 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record %u: `%s'\n", c, label); 253 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
254 "Created record %u: `%s'\n",
255 c,
256 label);
242 } 257 }
243 else 258 else
244 { 259 {
245 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to created records\n"); 260 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
261 "Failed to created records\n");
246 GNUNET_break (0); 262 GNUNET_break (0);
247 GNUNET_SCHEDULER_cancel (endbadly_task); 263 GNUNET_SCHEDULER_cancel (endbadly_task);
248 endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL); 264 endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL);
@@ -262,9 +278,11 @@ put_cont (void *cls, int32_t success, const char *emsg)
262 NULL); 278 NULL);
263 if (NULL == zm) 279 if (NULL == zm)
264 { 280 {
265 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to create zone monitor\n"); 281 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
282 "Failed to create zone monitor\n");
266 GNUNET_break (0); 283 GNUNET_break (0);
267 endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL); 284 endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly,
285 NULL);
268 return; 286 return;
269 } 287 }
270 } 288 }
@@ -354,14 +372,17 @@ run (void *cls,
354 GNUNET_assert (NULL != (ns_ops[0] = GNUNET_NAMESTORE_records_store(nsh, privkey, s_name_1, 372 GNUNET_assert (NULL != (ns_ops[0] = GNUNET_NAMESTORE_records_store(nsh, privkey, s_name_1,
355 1, s_rd_1, &put_cont, s_name_1))); 373 1, s_rd_1, &put_cont, s_name_1)));
356 374
357
358 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 2 \n"); 375 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 2 \n");
359 GNUNET_asprintf(&s_name_2, "dummy2"); 376 GNUNET_asprintf(&s_name_2, "dummy2");
360 s_rd_2 = create_record(1); 377 s_rd_2 = create_record(1);
361 GNUNET_assert (NULL != (ns_ops[1] = GNUNET_NAMESTORE_records_store(nsh, privkey, s_name_2, 378 GNUNET_assert (NULL != (ns_ops[1] =
362 1, s_rd_2, &put_cont, s_name_2))); 379 GNUNET_NAMESTORE_records_store (nsh,
363 380 privkey,
364 381 s_name_2,
382 1,
383 s_rd_2,
384 &put_cont,
385 s_name_2)));
365} 386}
366 387
367 388
diff --git a/src/topology/friends.c b/src/topology/friends.c
index cdfedbc81..a9a1f1498 100644
--- a/src/topology/friends.c
+++ b/src/topology/friends.c
@@ -55,7 +55,8 @@ GNUNET_FRIENDS_parse (const struct GNUNET_CONFIGURATION_Handle *cfg,
55 &fn)) 55 &fn))
56 { 56 {
57 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, 57 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
58 "topology", "FRIENDS"); 58 "topology",
59 "FRIENDS");
59 return GNUNET_SYSERR; 60 return GNUNET_SYSERR;
60 } 61 }
61 if (GNUNET_SYSERR == 62 if (GNUNET_SYSERR ==
diff --git a/src/zonemaster/gnunet-service-zonemaster.c b/src/zonemaster/gnunet-service-zonemaster.c
index 7129cf44f..cbb890589 100644
--- a/src/zonemaster/gnunet-service-zonemaster.c
+++ b/src/zonemaster/gnunet-service-zonemaster.c
@@ -60,6 +60,12 @@
60#define DHT_QUEUE_LIMIT 2000 60#define DHT_QUEUE_LIMIT 2000
61 61
62/** 62/**
63 * How many events may the namestore give us before it has to wait
64 * for us to keep up?
65 */
66#define NAMESTORE_QUEUE_LIMIT 50
67
68/**
63 * The initial interval in milliseconds btween puts in 69 * The initial interval in milliseconds btween puts in
64 * a zone iteration 70 * a zone iteration
65 */ 71 */
@@ -374,6 +380,8 @@ dht_put_monitor_continuation (void *cls)
374{ 380{
375 struct DhtPutActivity *ma = cls; 381 struct DhtPutActivity *ma = cls;
376 382
383 GNUNET_NAMESTORE_zone_monitor_next (zmon,
384 1);
377 ma_queue_length--; 385 ma_queue_length--;
378 GNUNET_CONTAINER_DLL_remove (ma_head, 386 GNUNET_CONTAINER_DLL_remove (ma_head,
379 ma_tail, 387 ma_tail,
@@ -924,7 +932,11 @@ handle_monitor_event (void *cls,
924 rd_count, 932 rd_count,
925 rd_public); 933 rd_public);
926 if (0 == rd_public_count) 934 if (0 == rd_public_count)
935 {
936 GNUNET_NAMESTORE_zone_monitor_next (zmon,
937 1);
927 return; /* nothing to do */ 938 return; /* nothing to do */
939 }
928 num_public_records++; 940 num_public_records++;
929 ma = GNUNET_new (struct DhtPutActivity); 941 ma = GNUNET_new (struct DhtPutActivity);
930 ma->start_date = GNUNET_TIME_absolute_get (); 942 ma->start_date = GNUNET_TIME_absolute_get ();
@@ -938,6 +950,8 @@ handle_monitor_event (void *cls,
938 { 950 {
939 /* PUT failed, do not remember operation */ 951 /* PUT failed, do not remember operation */
940 GNUNET_free (ma); 952 GNUNET_free (ma);
953 GNUNET_NAMESTORE_zone_monitor_next (zmon,
954 1);
941 return; 955 return;
942 } 956 }
943 GNUNET_CONTAINER_DLL_insert_tail (ma_head, 957 GNUNET_CONTAINER_DLL_insert_tail (ma_head,
@@ -1097,6 +1111,8 @@ run (void *cls,
1097 NULL, 1111 NULL,
1098 &monitor_sync_event, 1112 &monitor_sync_event,
1099 NULL); 1113 NULL);
1114 GNUNET_NAMESTORE_zone_monitor_next (zmon,
1115 NAMESTORE_QUEUE_LIMIT - 1);
1100 GNUNET_break (NULL != zmon); 1116 GNUNET_break (NULL != zmon);
1101 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, 1117 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
1102 NULL); 1118 NULL);