aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/handbook/chapters/developer.texi332
-rw-r--r--doc/handbook/chapters/installation.texi28
-rw-r--r--doc/handbook/chapters/keyconcepts.texi1
-rw-r--r--doc/handbook/chapters/user.texi273
-rw-r--r--doc/man/gnunet-config.13
-rw-r--r--src/arm/arm_api.c287
-rw-r--r--src/arm/arm_monitor_api.c55
-rw-r--r--src/arm/mockup-service.c49
-rw-r--r--src/core/core_api.c5
-rw-r--r--src/core/core_api_monitor_peers.c34
-rw-r--r--src/core/gnunet-core.c80
-rw-r--r--src/curl/curl.c57
-rw-r--r--src/curl/curl_reschedule.c29
-rw-r--r--src/gns/Makefile.am2
-rw-r--r--src/gns/gnunet-gns-proxy-ca.template303
-rw-r--r--src/gns/gnunet-gns-proxy-setup-ca.in45
-rw-r--r--src/include/gnunet_common.h31
-rw-r--r--src/include/gnunet_container_lib.h1127
-rw-r--r--src/namestore/gnunet-service-namestore.c67
-rw-r--r--src/nse/gnunet-nse.c38
-rw-r--r--src/nse/gnunet-service-nse.c21
-rw-r--r--src/nse/nse_api.c43
-rw-r--r--src/transport/gnunet-service-tng.c243
-rw-r--r--src/util/Makefile.am1
-rw-r--r--src/util/common_logging.c393
-rw-r--r--src/util/container_multiuuidmap.c1015
-rw-r--r--src/util/crypto_random.c84
-rw-r--r--src/util/gnunet-config.c58
-rw-r--r--src/util/gnunet-scrypt.c213
-rw-r--r--src/util/gnunet-uri.c84
-rw-r--r--src/util/test_common_logging_dummy.c59
-rw-r--r--src/util/tun.c163
32 files changed, 3329 insertions, 1894 deletions
diff --git a/doc/handbook/chapters/developer.texi b/doc/handbook/chapters/developer.texi
index 228603cda..a43bd7b37 100644
--- a/doc/handbook/chapters/developer.texi
+++ b/doc/handbook/chapters/developer.texi
@@ -79,6 +79,7 @@ new chapters, sections or insightful comments.
79* File-sharing (FS) Subsystem:: 79* File-sharing (FS) Subsystem::
80* REGEX Subsystem:: 80* REGEX Subsystem::
81* REST Subsystem:: 81* REST Subsystem::
82* RPS Subsystem::
82@end menu 83@end menu
83 84
84@node Developer Introduction 85@node Developer Introduction
@@ -556,7 +557,7 @@ stacked together to construct complex buildings and it is generally easy
556to swap one block for a different one that has the same shape. GNUnet's 557to swap one block for a different one that has the same shape. GNUnet's
557architecture is based on LEGOs: 558architecture is based on LEGOs:
558 559
559@c @image{images/service_lego_block,5in,,picture of a LEGO block stack - 3 APIs as connectors upon Network Protocol on top of a Service} 560@image{images/service_lego_block,5in,,picture of a LEGO block stack - 3 APIs upon IPC/network protocol provided by a service}
560 561
561This chapter documents the GNUnet LEGO system, also known as GNUnet's 562This chapter documents the GNUnet LEGO system, also known as GNUnet's
562system architecture. 563system architecture.
@@ -573,10 +574,14 @@ Like services, they have holes to be filled by APIs of other services.
573Unlike services, daemons do not implement their own network protocol and 574Unlike services, daemons do not implement their own network protocol and
574they have no API: 575they have no API:
575 576
577@image{images/daemon_lego_block,5in,,A daemon in GNUnet is a component that does not offer an API for others to build upon}
578
576The GNUnet system provides a range of services, daemons and user 579The GNUnet system provides a range of services, daemons and user
577interfaces, which are then combined into a layered GNUnet instance (also 580interfaces, which are then combined into a layered GNUnet instance (also
578known as a peer). 581known as a peer).
579 582
583@image{images/service_stack,5in,,A GNUnet peer consists of many layers of services}
584
580Note that while it is generally possible to swap one service for another 585Note that while it is generally possible to swap one service for another
581compatible service, there is often only one implementation. However, 586compatible service, there is often only one implementation. However,
582during development we often have a "new" version of a service in parallel 587during development we often have a "new" version of a service in parallel
@@ -587,7 +592,7 @@ easily investigated by swapping out individual components. This is
587typically achieved by simply changing the name of the "BINARY" in the 592typically achieved by simply changing the name of the "BINARY" in the
588respective configuration section. 593respective configuration section.
589 594
590Key properties of GNUnet services are that they must be separate 595Key properties of GNUnet services are that they must be separate
591processes and that they must protect themselves by applying tight error 596processes and that they must protect themselves by applying tight error
592checking against the network protocol they implement (thereby achieving a 597checking against the network protocol they implement (thereby achieving a
593certain degree of robustness). 598certain degree of robustness).
@@ -1876,7 +1881,6 @@ Testbed API can accessed by including the
1876* Hosts file format:: 1881* Hosts file format::
1877* Topology file format:: 1882* Topology file format::
1878* Testbed Barriers:: 1883* Testbed Barriers::
1879* Automatic large-scale deployment in the PlanetLab testbed::
1880* TESTBED Caveats:: 1884* TESTBED Caveats::
1881@end menu 1885@end menu
1882 1886
@@ -2140,168 +2144,6 @@ message from its upward propagation --- the upward propagation is needed
2140for ensuring that the barrier is reached by all the controllers and the 2144for ensuring that the barrier is reached by all the controllers and the
2141downward propagation is for triggering that the barrier is crossed. 2145downward propagation is for triggering that the barrier is crossed.
2142 2146
2143@cindex PlanetLab testbed
2144@node Automatic large-scale deployment in the PlanetLab testbed
2145@subsection Automatic large-scale deployment in the PlanetLab testbed
2146
2147PlanetLab is a testbed for computer networking and distributed systems
2148research. It was established in 2002 and as of June 2010 was composed of
21491090 nodes at 507 sites worldwide.
2150
2151To automate the GNUnet we created a set of automation tools to simplify
2152the large-scale deployment. We provide you a set of scripts you can use
2153to deploy GNUnet on a set of nodes and manage your installation.
2154
2155Please also check @uref{https://old.gnunet.org/installation-fedora8-svn} and
2156@uref{https://old.gnunet.org/installation-fedora12-svn} to find detailed
2157instructions how to install GNUnet on a PlanetLab node.
2158
2159
2160@c ***********************************************************************
2161@menu
2162* PlanetLab Automation for Fedora8 nodes::
2163* Install buildslave on PlanetLab nodes running fedora core 8::
2164* Setup a new PlanetLab testbed using GPLMT::
2165* Why do i get an ssh error when using the regex profiler?::
2166@end menu
2167
2168@node PlanetLab Automation for Fedora8 nodes
2169@subsubsection PlanetLab Automation for Fedora8 nodes
2170
2171@c ***********************************************************************
2172@node Install buildslave on PlanetLab nodes running fedora core 8
2173@subsubsection Install buildslave on PlanetLab nodes running fedora core 8
2174@c ** Actually this is a subsubsubsection, but must be fixed differently
2175@c ** as subsubsection is the lowest.
2176
2177Since most of the PlanetLab nodes are running the very old Fedora core 8
2178image, installing the buildslave software is quite some pain. For our
2179PlanetLab testbed we figured out how to install the buildslave software
2180best.
2181
2182@c This is a very terrible way to suggest installing software.
2183@c FIXME: Is there an official, safer way instead of blind-piping a
2184@c script?
2185@c FIXME: Use newer pypi URLs below.
2186Install Distribute for Python:
2187
2188@example
2189curl http://python-distribute.org/distribute_setup.py | sudo python
2190@end example
2191
2192Install Distribute for zope.interface <= 3.8.0 (4.0 and 4.0.1 will not
2193work):
2194
2195@example
2196export PYPI=@value{PYPI-URL}
2197wget $PYPI/z/zope.interface/zope.interface-3.8.0.tar.gz
2198tar xzvf zope.interface-3.8.0.tar.gz
2199cd zope.interface-3.8.0
2200sudo python setup.py install
2201@end example
2202
2203Install the buildslave software (0.8.6 was the latest version):
2204
2205@example
2206export GCODE="http://buildbot.googlecode.com/files"
2207wget $GCODE/buildbot-slave-0.8.6p1.tar.gz
2208tar xvfz buildbot-slave-0.8.6p1.tar.gz
2209cd buildslave-0.8.6p1
2210sudo python setup.py install
2211@end example
2212
2213The setup will download the matching twisted package and install it.
2214It will also try to install the latest version of zope.interface which
2215will fail to install. Buildslave will work anyway since version 3.8.0
2216was installed before!
2217
2218@c ***********************************************************************
2219@node Setup a new PlanetLab testbed using GPLMT
2220@subsubsection Setup a new PlanetLab testbed using GPLMT
2221
2222@itemize @bullet
2223@item Get a new slice and assign nodes
2224Ask your PlanetLab PI to give you a new slice and assign the nodes you
2225need
2226@item Install a buildmaster
2227You can stick to the buildbot documentation:@
2228@uref{http://buildbot.net/buildbot/docs/current/manual/installation.html}
2229@item Install the buildslave software on all nodes
2230To install the buildslave on all nodes assigned to your slice you can use
2231the tasklist @code{install_buildslave_fc8.xml} provided with GPLMT:
2232
2233@example
2234./gplmt.py -c contrib/tumple_gnunet.conf -t \
2235contrib/tasklists/install_buildslave_fc8.xml -a -p <planetlab password>
2236@end example
2237
2238@item Create the buildmaster configuration and the slave setup commands
2239
2240The master and the and the slaves have need to have credentials and the
2241master has to have all nodes configured. This can be done with the
2242@file{create_buildbot_configuration.py} script in the @file{scripts}
2243directory.
2244
2245This scripts takes a list of nodes retrieved directly from PlanetLab or
2246read from a file and a configuration template and creates:
2247
2248@itemize @bullet
2249@item a tasklist which can be executed with gplmt to setup the slaves
2250@item a master.cfg file containing a PlanetLab nodes
2251@end itemize
2252
2253A configuration template is included in the <contrib>, most important is
2254that the script replaces the following tags in the template:
2255
2256%GPLMT_BUILDER_DEFINITION :@ GPLMT_BUILDER_SUMMARY@ GPLMT_SLAVES@
2257%GPLMT_SCHEDULER_BUILDERS
2258
2259Create configuration for all nodes assigned to a slice:
2260
2261@example
2262./create_buildbot_configuration.py -u <planetlab username> \
2263-p <planetlab password> -s <slice> -m <buildmaster+port> \
2264-t <template>
2265@end example
2266
2267Create configuration for some nodes in a file:
2268
2269@example
2270./create_buildbot_configuration.p -f <node_file> \
2271-m <buildmaster+port> -t <template>
2272@end example
2273
2274@item Copy the @file{master.cfg} to the buildmaster and start it
2275Use @code{buildbot start <basedir>} to start the server
2276@item Setup the buildslaves
2277@end itemize
2278
2279@c ***********************************************************************
2280@node Why do i get an ssh error when using the regex profiler?
2281@subsubsection Why do i get an ssh error when using the regex profiler?
2282
2283Why do i get an ssh error "Permission denied (publickey,password)." when
2284using the regex profiler although passwordless ssh to localhost works
2285using publickey and ssh-agent?
2286
2287You have to generate a public/private-key pair with no password:@
2288@code{ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_localhost}@
2289and then add the following to your ~/.ssh/config file:
2290
2291@code{Host 127.0.0.1@ IdentityFile ~/.ssh/id_localhost}
2292
2293now make sure your hostsfile looks like
2294
2295@example
2296[USERNAME]@@127.0.0.1:22@
2297[USERNAME]@@127.0.0.1:22
2298@end example
2299
2300You can test your setup by running @code{ssh 127.0.0.1} in a
2301terminal and then in the opened session run it again.
2302If you were not asked for a password on either login,
2303then you should be good to go.
2304
2305@cindex TESTBED Caveats 2147@cindex TESTBED Caveats
2306@node TESTBED Caveats 2148@node TESTBED Caveats
2307@subsection TESTBED Caveats 2149@subsection TESTBED Caveats
@@ -8126,9 +7968,9 @@ future.
8126@node Conversions between DNS and GNS 7968@node Conversions between DNS and GNS
8127@subsubsection Conversions between DNS and GNS 7969@subsubsection Conversions between DNS and GNS
8128 7970
8129The differences between the two name systems lies in the details 7971The differences between the two name systems lies in the details and is not
8130and is not always transparent. 7972always transparent. For instance an SRV record is converted to a BOX record
8131For instance an SRV record is converted to a GNS only BOX record. 7973which is unique to GNS.
8132 7974
8133This is done by converting to a BOX record from an existing SRV record: 7975This is done by converting to a BOX record from an existing SRV record:
8134 7976
@@ -8141,7 +7983,7 @@ _sip._tcp.example.com. 14000 IN SRV 0 0 5060 www.example.com.
814114000 BOX n 5060 6 33 0 0 5060 www.example.com 798314000 BOX n 5060 6 33 0 0 5060 www.example.com
8142@end example 7984@end example
8143 7985
8144Other records that have such a transformation is the MX record type, 7986Other records that need to undergo such transformation is the MX record type,
8145as well as the SOA record type. 7987as well as the SOA record type.
8146 7988
8147Transformation of a SOA record into GNS works as described in the 7989Transformation of a SOA record into GNS works as described in the
@@ -8156,8 +7998,9 @@ following example. Very important to note are the rname and mname keys.
8156 604800 ; expire 7998 604800 ; expire
8157 600 ) ; ttl 7999 600 ) ; ttl
8158# Recordline for adding the record 8000# Recordline for adding the record
8159$ gnunet-namestore -z example.com -a -n @ -t SOA -V rname=master.example.com \ 8001$ gnunet-namestore -z example.com -a -n @ -t SOA -V \
8160 mname=hostmaster.example.com 2017030300,3600,1800,604800,600 -e 7200s 8002 rname=master.example.com mname=hostmaster.example.com \
8003 2017030300,3600,1800,604800,600 -e 7200s
8161@end example 8004@end example
8162 8005
8163The transformation of MX records is done in a simple way. 8006The transformation of MX records is done in a simple way.
@@ -8166,10 +8009,10 @@ The transformation of MX records is done in a simple way.
8166$ gnunet-namestore -z example.com -n mail -R 3600 MX n 10,mail 8009$ gnunet-namestore -z example.com -n mail -R 3600 MX n 10,mail
8167@end example 8010@end example
8168 8011
8169Finally, one of the biggest struggling points were the NS records that are found 8012Finally, one of the biggest struggling points were the NS records that are
8170in top level domain zones. The intended behaviour for those is to add GNS2DNS 8013found in top level domain zones. The intended behaviour for those is to add
8171records for those so that gnunet-gns can resolve records for those domains on 8014GNS2DNS records for those so that gnunet-gns can resolve records for those
8172its own. This requires migration of the DNS GLUE records as well, provided that 8015domains on its own. Those require the values from DNS GLUE records, provided
8173they are within the same zone. 8016they are within the same zone.
8174 8017
8175The following two examples show one record with a GLUE record and the other one 8018The following two examples show one record with a GLUE record and the other one
@@ -8178,10 +8021,12 @@ does not have a GLUE record. This takes place in the 'com' TLD.
8178@example 8021@example
8179# ns1.example.com 86400 IN A 127.0.0.1 8022# ns1.example.com 86400 IN A 127.0.0.1
8180# example.com 86400 IN NS ns1.example.com. 8023# example.com 86400 IN NS ns1.example.com.
8181$ gnunet-namestore -z com -n example -R 86400 GNS2DNS n example.com@@127.0.0.1 8024$ gnunet-namestore -z com -n example -R 86400 GNS2DNS n \
8025 example.com@@127.0.0.1
8182 8026
8183# example.com 86400 IN NS ns1.example.org. 8027# example.com 86400 IN NS ns1.example.org.
8184$ gnunet-namestore -z com -n example -R 86400 GNS2DNS n example.com@@ns1.example.org 8028$ gnunet-namestore -z com -n example -R 86400 GNS2DNS n \
8029 example.com@@ns1.example.org
8185@end example 8030@end example
8186 8031
8187As you can see, one of the GNS2DNS records has an IP address listed and the 8032As you can see, one of the GNS2DNS records has an IP address listed and the
@@ -8204,7 +8049,7 @@ Currently the following record types are supported:
8204@item TXT 8049@item TXT
8205@end itemize 8050@end itemize
8206 8051
8207This is not due to a technical limitation but rather a practical one. The 8052This is not due to technical limitations but rather a practical ones. The
8208problem occurs with DNSSEC enabled DNS zones. As records within those zones are 8053problem occurs with DNSSEC enabled DNS zones. As records within those zones are
8209signed periodically, and every new signature is an update to the zone, there are 8054signed periodically, and every new signature is an update to the zone, there are
8210many revisions of zones. This results in a problem with bigger zones as there 8055many revisions of zones. This results in a problem with bigger zones as there
@@ -8214,16 +8059,22 @@ as they cause a CLI call of the namestore. Furthermore certain record types
8214need transformation into a GNS compatible format which, depending on the record 8059need transformation into a GNS compatible format which, depending on the record
8215type, takes more time. 8060type, takes more time.
8216 8061
8062Further a blacklist was added to drop for instance DNSSEC related records. Also
8063if a record type is neither in the white list nor the blacklist it is considered
8064as a loss of data and a message is shown to the user. This helps with
8065transparency and also with contributing, as the not supported record types can
8066then be added accordingly.
8067
8217@node DNS Zone Size 8068@node DNS Zone Size
8218@subsubsection DNS Zone Size 8069@subsubsection DNS Zone Size
8219
8220Another very big problem exists with very large zones. When migrating a small 8070Another very big problem exists with very large zones. When migrating a small
8221zone the delay between adding of records and their expiry is negligible. However 8071zone the delay between adding of records and their expiry is negligible. However
8222when working with a TLD zone that has more that 1 million records this delay 8072when working with big zones that easily have more than a few million records
8223becomes a problem. 8073this delay becomes a problem.
8224 8074
8225Records will start to expire well before the zone has finished migrating. This 8075Records will start to expire well before the zone has finished migrating. This
8226causes unwanted anomalies when trying to resolve records. 8076is usually not a problem but can cause a high CPU load when a peer is restarted
8077and the records have expired.
8227 8078
8228A good solution has not been found yet. One of the idea that floated around was 8079A good solution has not been found yet. One of the idea that floated around was
8229that the records should be added with the s (shadow) flag to keep the records 8080that the records should be added with the s (shadow) flag to keep the records
@@ -8233,45 +8084,51 @@ of said record(s).
8233 8084
8234Another problem that still persists is how to refresh records. Expired records 8085Another problem that still persists is how to refresh records. Expired records
8235are still displayed when calling gnunet-namestore but do not resolve with 8086are still displayed when calling gnunet-namestore but do not resolve with
8236gnunet-gns. When doing incremental zone transfers this becomes especially 8087gnunet-gns. Zonemaster will sign the expired records again and make sure that
8237apparent. 8088the records are still valid. With a recent change this was fixed as gnunet-gns
8089to improve the suffix lookup which allows for a fast lookup even with thousands
8090of local egos.
8091
8092Currently the pace of adding records in general is around 10 records per second.
8093Crypto is the upper limit for adding of records. The performance of your machine
8094can be tested with the perf_crypto_* tools. There is still a big discrepancy
8095between the pace of Ascension and the theoretical limit.
8238 8096
8239I estimate that the limit lies at about 200'000 records in a zone as this is 8097A performance metric for measuring improvements has not yet been implemented in
8240the limit that my machine is capable of adding within one hour. This was 8098Ascension.
8241calculated by running cProfile on the application with a zone of 5000 records
8242and calculating what abouts a much bigger zones with 8 million records would
8243take. This results in a nice metric of records migrated per hour.
8244 8099
8245@node Performance 8100@node Performance
8246@subsubsection Performance 8101@subsubsection Performance
8247The performance when migrating a zone using the Ascension tool is limited by a 8102The performance when migrating a zone using the Ascension tool is limited by a
8248handful of factors. First of all ascension is written in Python3 and calls the 8103handful of factors. First of all ascension is written in Python3 and calls the
8249CLI tools of GNUnet. Furthermore all the records that are added to the same 8104CLI tools of GNUnet. This is comparable to a fork and exec call which costs a
8105few CPU cycles. Furthermore all the records that are added to the same
8250label are signed using the zones private key. This signing operation is very 8106label are signed using the zones private key. This signing operation is very
8251resource heavy and was optimized during development by adding the '-R' 8107resource heavy and was optimized during development by adding the '-R'
8252(Recordline) option to gnunet-namestore. This allows to add multiple records 8108(Recordline) option to gnunet-namestore which allows to specify multiple records
8253at once using the CLI. 8109using the CLI tool. Assuming that in a TLD zone every domain has at least two
8254 8110name servers this halves the amount of signatures needed.
8255The result of this was a much faster migration of TLD zones, as most records
8256with the same label have two name servers.
8257 8111
8258Another improvement that could be made is with the addition of multiple threads 8112Another improvement that could be made is with the addition of multiple threads
8259when opening the GNUnet CLI tools. This could be implemented by simply creating 8113or using asynchronous subprocesses when opening the GNUnet CLI tools. This could
8260more workers in the program but performance improvements were not tested. 8114be implemented by simply creating more workers in the program but performance
8115improvements were not tested.
8261 8116
8262During the entire development of Ascension sqlite was used as a database 8117Ascension was tested using different hardware and database backends. Performance
8263backend for GNUnet. Other backends have not been tested yet. 8118differences between SQLite and postgresql are marginal and almost non existent.
8119What did make a huge impact on record adding performance was the storage medium.
8120On a traditional mechanical hard drive adding of records were slow compared to a
8121solid state disk.
8264 8122
8265In conclusion there are many bottlenecks still around in the program, namely the 8123In conclusion there are many bottlenecks still around in the program, namely the
8266signing process and the single threaded implementation. In the future a solution 8124single threaded implementation and inefficient, sequential calls of
8267that uses the C API would be cleaner and better. 8125gnunet-namestore. In the future a solution that uses the C API would be cleaner
8126and better.
8268 8127
8269@cindex GNS Namecache 8128@cindex GNS Namecache
8270@node GNS Namecache 8129@node GNS Namecache
8271@section GNS Namecache 8130@section GNS Namecache
8272 8131
8273
8274
8275The NAMECACHE subsystem is responsible for caching (encrypted) resolution 8132The NAMECACHE subsystem is responsible for caching (encrypted) resolution
8276results of the GNU Name System (GNS). GNS makes zone information available 8133results of the GNU Name System (GNS). GNS makes zone information available
8277to other users via the DHT. However, as accessing the DHT for every 8134to other users via the DHT. However, as accessing the DHT for every
@@ -9007,3 +8864,72 @@ so please make sure that endpoints are unambiguous.
9007 8864
9008This is WIP. Endpoints should be documented appropriately. 8865This is WIP. Endpoints should be documented appropriately.
9009Preferably using annotations. 8866Preferably using annotations.
8867
8868
8869@cindex RPS Subsystem
8870@node RPS Subsystem
8871@section RPS Subsystem
8872
8873In literature, Random Peer Sampling (RPS) refers to the problem of
8874reliably drawing random samples from an unstructured p2p network.
8875
8876Doing so in a reliable manner is not only hard because of inherent
8877problems but also because of possible malicious peers that could try to
8878bias the selection.
8879
8880It is useful for all kind of gossip protocols that require the selection
8881of random peers in the whole network like gathering statistics,
8882spreading and aggregating information in the network, load balancing and
8883overlay topology management.
8884
8885The approach chosen in the rps implementation in GNUnet follows the
8886Brahms@uref{https://bib.gnunet.org/full/date.html\#2009_5f0} design.
8887
8888The current state is "work in progress". There are a lot of things that
8889need to be done, primarily finishing the experimental evaluation and a
8890re-design of the API.
8891
8892The abstract idea is to subscribe to connect to/start the rps service
8893and request random peers that will be returned when they represent a
8894random selection from the whole network with high probability.
8895
8896An additional feature to the original Brahms-design is the selection of
8897sub-groups: The GNUnet implementation of rps enables clients to ask for
8898random peers from a group that is defined by a common shared secret.
8899(The secret could of course also be public, depending on the use-case.)
8900
8901Another addition to the original protocol was made: The sampler
8902mechanism that was introduced in Brahms was slightly adapted and used to
8903actually sample the peers and returned to the client.
8904This is necessary as the original design only keeps peers connected to
8905random other peers in the network. In order to return random peers to
8906client requests independently random, they cannot be drawn from the
8907connected peers.
8908The adapted sampler makes sure that each request for random peers is
8909independent from the others.
8910
8911@node Brahms
8912@subsection Brahms
8913The high-level concept of Brahms is two-fold: Combining push-pull gossip
8914with locally fixing a assumed bias using cryptographic min-wise
8915permutations.
8916The central data structure is the view - a peer's current local sample.
8917This view is used to select peers to push to and pull from.
8918This simple mechanism can be biased easily. For this reason Brahms
8919'fixes' the bias by using the so-called sampler. A data structure that
8920takes a list of elements as input and outputs a random one of them
8921independently of the frequency in the input set. Both an element that
8922was put into the sampler a single time and an element that was put into
8923it a million times have the same probability of being the output.
8924This is achieved this is achieved with exploiting min-wise independent
8925permutations. In rps we use HMACs: On the initialisation of a sampler
8926element, a key is chosen at random. On each input the HMAC with the
8927random key is computed. The sampler element keeps the element with the
8928minimal HMAC.
8929
8930In order to fix the bias in the view, a fraction of the elements in the
8931view are sampled through the sampler from the random stream of peer IDs.
8932
8933According to the theoretical analysis of Bortnikov et al. this suffices
8934to keep the network connected and having random peers in the view.
8935
diff --git a/doc/handbook/chapters/installation.texi b/doc/handbook/chapters/installation.texi
index c3b9c6cbc..a508feb6a 100644
--- a/doc/handbook/chapters/installation.texi
+++ b/doc/handbook/chapters/installation.texi
@@ -1727,12 +1727,19 @@ $ gnunet-namestore -a -e "1 d" -n "homepage" \
1727At this point we can start the proxy. Simply execute 1727At this point we can start the proxy. Simply execute
1728 1728
1729@example 1729@example
1730$ gnunet-gns-proxy 1730$ gnunet-arm -i gns-proxy
1731@end example
1732
1733To run the proxy at all times in the future, you should
1734change your configuration as follows:
1735
1736@example
1737$ gnunet-config -s gns-proxy -o AUTOSTART -V YES
1731@end example 1738@end example
1732 1739
1733@noindent 1740@noindent
1734Configure your browser to use this SOCKSv5 proxy on port 7777 and visit 1741Configure your browser to use this SOCKSv5 proxy using
1735this link. 1742@code{localhost} on port 7777.
1736If you use @command{Firefox} (or one of its derivatives/forks such as 1743If you use @command{Firefox} (or one of its derivatives/forks such as
1737Icecat) you also have to go to @code{about:config} and set the key 1744Icecat) you also have to go to @code{about:config} and set the key
1738@code{network.proxy.socks_remote_dns} to @code{true}. 1745@code{network.proxy.socks_remote_dns} to @code{true}.
@@ -1779,10 +1786,21 @@ Keeping a virtual environment helps with keeping things tidy and prevents
1779breaking of Ascension through a future Python update. 1786breaking of Ascension through a future Python update.
1780 1787
1781The advantage of using a virtual environment is, that all the dependencies can 1788The advantage of using a virtual environment is, that all the dependencies can
1782be installed separately in different versions without touching your system 1789be installed separately in different versions without touching your systems
1783Python installation and its dependencies. 1790Python installation and its dependencies.
1784 1791
1785@xref{Migrating an existing DNS zone into GNS}, for usage manual of the tool. 1792Another way to install Ascension on Debian is to install the python3-ascension
1793package. It can be found within the above mentioned Ascension git repository.
1794This also adds a system user ascension and runs a GNUnet peer in the
1795background. Attention: This only works if a recent version of GNUnet is
1796installed on your system. The version number of Ascension is chosen according
1797to the required feature level of GNUnet. I.e. Ascension 0.11.5 is only
1798compatible with GNUnet 0.11.5 and upwards. As Debian's packages for GNUnet are
1799outdated even in experimental, you will need to install GNUnet manually.
1800@xref{Installing GNUnet}
1801
1802Please check @xref{Migrating an existing DNS zone into GNS}, for usage manual
1803of the tool.
1786 1804
1787@node Configuring the GNUnet VPN 1805@node Configuring the GNUnet VPN
1788@subsection Configuring the GNUnet VPN 1806@subsection Configuring the GNUnet VPN
diff --git a/doc/handbook/chapters/keyconcepts.texi b/doc/handbook/chapters/keyconcepts.texi
index 4900ed328..bdfa5b631 100644
--- a/doc/handbook/chapters/keyconcepts.texi
+++ b/doc/handbook/chapters/keyconcepts.texi
@@ -319,3 +319,4 @@ Egos are your "identities" in GNUnet. Any user can assume multiple
319identities, for example to separate their activities online. Egos can 319identities, for example to separate their activities online. Egos can
320correspond to "pseudonyms" or "real-world identities". Technically an 320correspond to "pseudonyms" or "real-world identities". Technically an
321ego is first of all a key pair of a public- and private-key. 321ego is first of all a key pair of a public- and private-key.
322
diff --git a/doc/handbook/chapters/user.texi b/doc/handbook/chapters/user.texi
index 55518bc34..fcf5e7871 100644
--- a/doc/handbook/chapters/user.texi
+++ b/doc/handbook/chapters/user.texi
@@ -526,7 +526,7 @@ shell) and create an entry home-phone in your master zone.
526For the record type, select PHONE. You should then see the 526For the record type, select PHONE. You should then see the
527PHONE dialog: 527PHONE dialog:
528 528
529@c image here 529@image{images/gnunet-namestore-gtk-phone,5in,,Dialog to publish a PHONE record}
530 530
531Note: Do not choose the expiry time to be 'Never'. If you 531Note: Do not choose the expiry time to be 'Never'. If you
532do that, you assert that this record will never change and 532do that, you assert that this record will never change and
@@ -645,7 +645,7 @@ Now, using your normal user (not the @code{gnunet} system user), run
645master zone. For the record type, select @code{VPN}. You should then 645master zone. For the record type, select @code{VPN}. You should then
646see the VPN dialog: 646see the VPN dialog:
647 647
648@c insert image 648@image{images/gnunet-namestore-gtk-vpn,5in,,Dialog to publish a VPN record}
649 649
650Under peer, you need to supply the peer identity of your own peer. You can 650Under peer, you need to supply the peer identity of your own peer. You can
651obtain the respective string by running @command{gnunet-peerinfo -sq} 651obtain the respective string by running @command{gnunet-peerinfo -sq}
@@ -926,7 +926,7 @@ concepts that are used to achieve these goals.
926* Files:: 926* Files::
927* Keywords:: 927* Keywords::
928* Directories:: 928* Directories::
929* Pseudonyms:: 929* Egos and File-Sharing::
930* Namespaces:: 930* Namespaces::
931* Advertisements:: 931* Advertisements::
932* Anonymity level:: 932* Anonymity level::
@@ -984,69 +984,55 @@ typically includes the mime-type, description, a filename and
984other meta information, and possibly even the full original file 984other meta information, and possibly even the full original file
985(if it was small). 985(if it was small).
986 986
987@node Pseudonyms 987@node Egos and File-Sharing
988@subsubsection Pseudonyms 988@subsubsection Egos and File-Sharing
989 989
990When sharing files, it is sometimes desirable to build a reputation as
991a source for quality information. With egos, publishers can
992(cryptographically) sign files, thereby demonstrating that various
993files were published by the same entity. An ego thus allows users to
994link different publication events, thereby deliberately reducing
995anonymity to pseudonymity.
990 996
991@b{Please note that the text in this subsection is outdated and needs} 997Egos used in GNUnet's file-sharing for such pseudonymous publishing
992@b{to be rewritten for version 0.10!} 998also correspond to the egos used to identify and sign zones in the
993@b{This especially concerns the terminology of Pseudonym/Ego/Identity.} 999GNU Name System. However, if the same ego is used for file-sharing
1000and for a GNS zone, this will weaken the privacy assurances provided
1001by the anonymous file-sharing protocol.
994 1002
995Pseudonyms in GNUnet are essentially public-private (RSA) key pairs 1003Note that an ego is NOT bound to a GNUnet peer. There can be multiple
996that allow a GNUnet user to maintain an identity (which may or may not 1004egos for a single user, and users could (theoretically) share
997be detached from their real-life identity). GNUnet's pseudonyms are not 1005the private keys of an ego by copying the respective private keys.
998file-sharing specific --- and they will likely be used by many GNUnet
999applications where a user identity is required.
1000 1006
1001Note that a pseudonym is NOT bound to a GNUnet peer. There can be multiple
1002pseudonyms for a single user, and users could (theoretically) share the
1003private pseudonym keys (currently only out-of-band by knowing which files
1004to copy around).
1005 1007
1006@node Namespaces 1008@node Namespaces
1007@subsubsection Namespaces 1009@subsubsection Namespaces
1008 1010
1011A namespace is a set of files that were signed by the same ego.
1012Today, namespaces are implemented independently of GNS zones, but
1013in the future we plan to merge the two such that a GNS zone can
1014basically contain files using a file-sharing specific record type.
1009 1015
1010@b{Please note that the text in this subsection is outdated and needs} 1016Files (or directories) that have been signed and placed into a
1011@b{to be rewritten for version 0.10!} 1017namespace can be updated. Updates are identified as authentic if the
1012@b{This especially concerns the terminology of Pseudonym/Ego/Identity.} 1018same secret key was used to sign the update.
1013
1014A namespace is a set of files that were signed by the same pseudonym.
1015Files (or directories) that have been signed and placed into a namespace
1016can be updated. Updates are identified as authentic if the same secret
1017key was used to sign the update. Namespaces are also useful to establish
1018a reputation, since all of the content in the namespace comes from the
1019same entity (which does not have to be the same person).
1020 1019
1021@node Advertisements 1020@node Advertisements
1022@subsubsection Advertisements 1021@subsubsection Advertisements
1023 1022
1024
1025@b{Please note that the text in this subsection is outdated and needs}
1026@b{to be rewritten for version 0.10!}
1027@b{This especially concerns the terminology of Pseudonym/Ego/Identity.}
1028
1029Advertisements are used to notify other users about the existence of a 1023Advertisements are used to notify other users about the existence of a
1030namespace. Advertisements are propagated using the normal keyword search. 1024namespace. Advertisements are propagated using the normal keyword
1031When an advertisement is received (in response to a search), the namespace 1025search. When an advertisement is received (in response to a search),
1032is added to the list of namespaces available in the namespace-search 1026the namespace is added to the list of namespaces available in the
1033dialogs of gnunet-fs-gtk and printed by @code{gnunet-identity}. Whenever a 1027namespace-search dialogs of gnunet-fs-gtk and printed by
1034namespace is created, an appropriate advertisement can be generated. 1028@code{gnunet-identity}. Whenever a namespace is created, an
1035The default keyword for the advertising of namespaces is "namespace". 1029appropriate advertisement can be generated. The default keyword for
1036 1030the advertising of namespaces is "namespace".
1037Note that GNUnet differentiates between your pseudonyms (the identities 1031
1038that you control) and namespaces. If you create a pseudonym, you will
1039not automatically see the respective namespace. You first have to create
1040an advertisement for the namespace and find it using keyword
1041search --- even for your own namespaces. The @command{gnunet-identity}
1042tool is currently responsible for both managing pseudonyms and namespaces.
1043This will likely change in the future to reduce the potential for
1044confusion.
1045 1032
1046@node Anonymity level 1033@node Anonymity level
1047@subsubsection Anonymity level 1034@subsubsection Anonymity level
1048 1035
1049
1050The anonymity level determines how hard it should be for an adversary to 1036The anonymity level determines how hard it should be for an adversary to
1051determine the identity of the publisher or the searcher/downloader. An 1037determine the identity of the publisher or the searcher/downloader. An
1052anonymity level of zero means that anonymity is not required. The default 1038anonymity level of zero means that anonymity is not required. The default
@@ -1066,10 +1052,10 @@ delays traffic.
1066While higher anonymity levels may offer better privacy, they can also 1052While higher anonymity levels may offer better privacy, they can also
1067significantly hurt performance. 1053significantly hurt performance.
1068 1054
1055
1069@node Content Priority 1056@node Content Priority
1070@subsubsection Content Priority 1057@subsubsection Content Priority
1071 1058
1072
1073Depending on the peer's configuration, GNUnet peers migrate content 1059Depending on the peer's configuration, GNUnet peers migrate content
1074between peers. Content in this sense are individual blocks of a file, 1060between peers. Content in this sense are individual blocks of a file,
1075not necessarily entire files. When peers run out of space (due to 1061not necessarily entire files. When peers run out of space (due to
@@ -1083,10 +1069,10 @@ lowest priority. The priority of a block is decided by its popularity
1083published locally, the base-priority that was specified by the user 1069published locally, the base-priority that was specified by the user
1084when the block was published initially. 1070when the block was published initially.
1085 1071
1072
1086@node Replication 1073@node Replication
1087@subsubsection Replication 1074@subsubsection Replication
1088 1075
1089
1090When peers migrate content to other systems, the replication level 1076When peers migrate content to other systems, the replication level
1091of a block is used to decide which blocks need to be migrated most 1077of a block is used to decide which blocks need to be migrated most
1092urgently. GNUnet will always push the block with the highest 1078urgently. GNUnet will always push the block with the highest
@@ -1098,99 +1084,37 @@ selection is simply random.
1098@node Namespace Management 1084@node Namespace Management
1099@subsection Namespace Management 1085@subsection Namespace Management
1100 1086
1101 1087The @code{gnunet-identity} tool can be used to create egos.
1102@b{Please note that the text in this subsection is outdated and needs} 1088By default, @code{gnunet-identity -D} simply
1103@b{to be rewritten for version 0.10!} 1089lists all locally available egos.
1104
1105The @code{gnunet-identity} tool can be used to create pseudonyms and
1106to advertise namespaces. By default, @code{gnunet-identity -D} simply
1107lists all locally available pseudonyms.
1108 1090
1109 1091
1110@menu 1092@menu
1111* Creating Pseudonyms:: 1093* Creating Egos::
1112* Deleting Pseudonyms:: 1094* Deleting Egos::
1113* Advertising namespaces::
1114* Namespace names::
1115* Namespace root::
1116@end menu 1095@end menu
1117 1096
1118@node Creating Pseudonyms 1097@node Creating Egos
1119@subsubsection Creating Pseudonyms 1098@subsubsection Creating Egos
1120 1099
1100With the @command{-C NICK} option it can also be used to create a new
1101ego. An ego is the virtual identity of the entity in control of a
1102namespace or GNS zone. Anyone can create any number of egos. The
1103provided NICK name automatically corresponds to a GNU Name System
1104domain name. Thus, henceforth name resolution for any name ending in
1105``.NICK'' will use the NICK's zone. You should avoid using NICKs that
1106collide with well-known DNS names.
1121 1107
1122@b{Please note that the text in this subsection is outdated and needs} 1108@node Deleting Egos
1123@b{to be rewritten for version 0.10!} 1109@subsubsection Deleting Egos
1124@b{This especially concerns the terminology of Pseudonym/Ego/Identity.}
1125 1110
1126With the @command{-C NICK} option it can also be used to 1111With the @command{-D NICK} option egos can be deleted. Once the ego
1127create a new pseudonym. A pseudonym is the virtual identity 1112has been deleted it is impossible to add content to the corresponding
1128of the entity in control of a namespace. Anyone can create 1113namespace or zone. However, the existing GNS zone data is currently
1129any number of pseudonyms. Note that creating a pseudonym can 1114not dropped. This may change in the future.
1130take a few minutes depending on the performance of the machine
1131used.
1132 1115
1133@node Deleting Pseudonyms 1116Deleting the pseudonym does not make the namespace or any content in
1134@subsubsection Deleting Pseudonyms 1117it unavailable.
1135
1136
1137@b{Please note that the text in this subsection is outdated and needs}
1138@b{to be rewritten for version 0.10!}
1139@b{This especially concerns the terminology of Pseudonym/Ego/Identity.}
1140
1141With the @command{-D NICK} option pseudonyms can be deleted.
1142Once the pseudonym has been deleted it is impossible to add
1143content to the corresponding namespace. Deleting the
1144pseudonym does not make the namespace or any content in it
1145unavailable.
1146
1147@node Advertising namespaces
1148@subsubsection Advertising namespaces
1149
1150
1151@b{Please note that the text in this subsection is outdated and needs}
1152@b{to be rewritten for version 0.10!}
1153@b{This especially concerns the terminology of Pseudonym/Ego/Identity.}
1154
1155Each namespace is associated with meta-data that describes
1156the namespace. This meta-data is provided by the user at
1157the time that the namespace is advertised. Advertisements
1158are published under keywords so that they can be found using
1159normal keyword-searches. This way, users can learn about new
1160namespaces without relying on out-of-band communication or directories.
1161A suggested keyword to use for all namespaces is simply "namespace".
1162When a keyword-search finds a namespace advertisement,
1163it is automatically stored in a local list of known namespaces.
1164Users can then associate a rank with the namespace to remember
1165the quality of the content found in it.
1166
1167@node Namespace names
1168@subsubsection Namespace names
1169
1170
1171@b{Please note that the text in this subsection is outdated and needs}
1172@b{to be rewritten for version 0.10!}
1173@b{This especially concerns the terminology of Pseudonym/Ego/Identity.}
1174
1175While the namespace is uniquely identified by its ID, another way
1176to refer to the namespace is to use the NICKNAME.
1177The NICKNAME can be freely chosen by the creator of the namespace and
1178hence conflicts are possible. If a GNUnet client learns about more
1179than one namespace using the same NICKNAME, the ID is appended
1180to the NICKNAME to get a unique identifier.
1181
1182@node Namespace root
1183@subsubsection Namespace root
1184
1185
1186@b{Please note that the text in this subsection is outdated and needs}
1187@b{to be rewritten for version 0.10!}
1188@b{This especially concerns the terminology of Pseudonym/Ego/Identity.}
1189
1190An item of particular interest in the namespace advertisement is
1191the ROOT. The ROOT is the identifier of a designated entry in the
1192namespace. The idea is that the ROOT can be used to advertise an
1193entry point to the content of the namespace.
1194 1118
1195@node File-Sharing URIs 1119@node File-Sharing URIs
1196@subsection File-Sharing URIs 1120@subsection File-Sharing URIs
@@ -1314,12 +1238,12 @@ To publish a file, select "File Sharing" in the menu bar just below the
1314 1238
1315Afterwards, the following publishing dialog will appear: 1239Afterwards, the following publishing dialog will appear:
1316 1240
1317@c Add image here 1241@image{images/gnunet-gtk-0-10-fs-publish,5in,,The gnunet-fs-gtk publishing dialog}
1318 1242
1319In this dialog, select the "Add File" button. This will open a 1243In this dialog, select the "Add File" button. This will open a
1320file selection dialog: 1244file selection dialog:
1321 1245
1322@c Add image here 1246@image{images/gnunet-gtk-0-10-fs-publish-select,5in,,Dialog to select the file to publish (looks may differ for other Gtk+ versions)}
1323 1247
1324Now, you should select a file from your computer to be published on 1248Now, you should select a file from your computer to be published on
1325GNUnet. To see more of GNUnet's features later, you should pick a 1249GNUnet. To see more of GNUnet's features later, you should pick a
@@ -1335,12 +1259,12 @@ and potential errors that might be encountered during processing.
1335After the progress dialog automatically disappears, your file 1259After the progress dialog automatically disappears, your file
1336should now appear in the publishing dialog: 1260should now appear in the publishing dialog:
1337 1261
1338@c Add image here 1262@image{images/gnunet-gtk-0-10-fs-publish-with-file,5in,,Publishing dialog with file added}
1339 1263
1340Now, select the file (by clicking on the file name) and then click 1264Now, select the file (by clicking on the file name) and then click
1341the "Edit" button. This will open the editing dialog: 1265the "Edit" button. This will open the editing dialog:
1342 1266
1343@c Add image here 1267@image{images/gnunet-gtk-0-10-fs-publish-editing,5in,,Editing meta data of a file to be published}
1344 1268
1345In this dialog, you can see many details about your file. In the 1269In this dialog, you can see many details about your file. In the
1346top left area, you can see meta data extracted about the file, 1270top left area, you can see meta data extracted about the file,
@@ -1364,9 +1288,7 @@ You should now be back at the "Publish content on GNUnet" dialog. Select
1364"Execute" in the bottom right to close the dialog and publish your file 1288"Execute" in the bottom right to close the dialog and publish your file
1365on GNUnet! Afterwards, you should see the main dialog with a new area 1289on GNUnet! Afterwards, you should see the main dialog with a new area
1366showing the list of published files (or ongoing publishing operations 1290showing the list of published files (or ongoing publishing operations
1367with progress indicators): 1291with progress indicators).
1368
1369@c Add image here
1370 1292
1371@node gtk-Searching 1293@node gtk-Searching
1372@subsubsection Searching 1294@subsubsection Searching
@@ -1920,33 +1842,42 @@ options:
1920 1842
1921@example 1843@example
1922Ascension 1844Ascension
1923
1924Usage: 1845Usage:
1925 ascension <domain> [-d] [-p] 1846 ascension <domain> [-d] [-p] [-s] [--minimum-ttl=<ttl>] \
1926 ascension <domain> <port> [-d] [-p] 1847 [--dry-run]
1927 ascension <domain> -n <transferns> [-d] [-p] 1848 ascension <domain> <port> [-d] [-p] [-s] \
1928 ascension <domain> -n <transferns> <port> [-d] [-p] 1849 [--minimum-ttl=<ttl>] [--dry-run]
1850 ascension <domain> -n <transferns> [-d] [-p] \
1851 [-s] [--minimum-ttl=<ttl>] [--dry-run]
1852 ascension <domain> -n <transferns> <port> [-d] \
1853 [-p] [-s] [--minimum-ttl=<ttl>] [--dry-run]
1929 ascension -p | --public 1854 ascension -p | --public
1855 ascension -d | --debug
1856 ascension -s | --standalone
1930 ascension -h | --help 1857 ascension -h | --help
1931 ascension -v | --version 1858 ascension -v | --version
1932 1859
1933Options: 1860Options:
1934 <domain> Domain to migrate 1861 <domain> Domain to migrate
1935 <port> Port for zone transfer 1862 <port> Port for zone transfer
1936 <transferns> DNS Server that does the zone transfer 1863 <transferns> DNS Server that does the zone transfer
1937 -p --public Make records public on the DHT 1864 --minimum-ttl=<ttl> Minimum TTL for records to migrate \
1938 -d --debug Enable debugging 1865 [default: 3600]
1939 -h --help Show this screen. 1866 --dry-run Only try if a zone transfer is allowed
1940 -v --version Show version. 1867 -p --public Make records public on the DHT
1868 -s --standalone Run ascension once
1869 -d --debug Enable debugging
1870 -h --help Show this screen.
1871 -v --version Show version.
1941@end example 1872@end example
1942 1873
1943Before you can migrate any zone though, you need to start the GNUnet peer: 1874Before you can migrate any zone though, you need to start a local GNUnet peer:
1944@example 1875@example
1945$ gnunet-arm -s 1876$ gnunet-arm -s
1946@end example 1877@end example
1947 1878
1948To migrate the Syrian top level domain - one of the few top level domains that 1879To migrate the Syrian top level domain - one of the few top level domains that
1949still supports zone transfers - into GNS use the following command: 1880support zone transfers - into GNS use the following command:
1950 1881
1951@example 1882@example
1952$ ascension sy. -n ns1.tld.sy. -p 1883$ ascension sy. -n ns1.tld.sy. -p
@@ -1959,33 +1890,39 @@ Once the zone is migrated, Ascension will output a message telling you, that it
1959will refresh the zone after the time has elapsed. You can resolve the names in 1890will refresh the zone after the time has elapsed. You can resolve the names in
1960the zone directly using GNS or if you want to use it with your browser, check 1891the zone directly using GNS or if you want to use it with your browser, check
1961out the GNS manual section. @ref{Configuring the GNU Name System}. To resolve 1892out the GNS manual section. @ref{Configuring the GNU Name System}. To resolve
1962the records from another system you need the zone PKEY. To get the zone key, 1893the records from another system you need the respective zones PKEY. To get the
1963you can run the following command: 1894zones public key, you can run the following command:
1964 1895
1965@example 1896@example
1966$ gnunet-identity -d | grep ^sy | cut -d " " -f3 1897$ gnunet-identity -dqe sy
1967@end example 1898@end example
1968 1899
1969Where "sy" is the name of the zone you want to migrate. 1900Where "sy" is the name of the zone you want to migrate.
1970 1901
1971As soon as the public flag is implemented, you can share the PKEY of the zone 1902You can share the PKEY of the zone with your friends. They can then resolve
1972with your friends. They can then resolve records in the zone by doing a lookup 1903records in the zone by doing a lookup replacing the zone label with your PKEY:
1973replacing the zone label with your PKEY:
1974 1904
1975@example 1905@example
1976$ gnunet-gns -t SOA -u "@.$PKEY" 1906$ gnunet-gns -t SOA -u "$PKEY"
1977@end example 1907@end example
1978 1908
1979The program will continue to run as a daemon and update once the refresh time 1909The program will continue to run as a daemon and update once the refresh time
1980specified in the zones SOA record has elapsed. 1910specified in the zones SOA record has elapsed.
1981 1911
1982The next step would be to add the PKEY record as a DNScurve style NS record 1912DNSCurve style records are supported in the latest release and they are added
1983into the existing DNS zone to enable clients to detect that this zone has 1913as a PKEY record to be referred to the respective GNS public key. Key
1984already been migrated to GNS and to also have a means of distributing the PKEY 1914distribution is still a problem but provided someone else has a public key
1985seamlessly. 1915under a given label it can be looked up.
1916
1917There is an unofficial Debian package called python3-ascension that adds a
1918system user ascension and runs a GNUnet peer in the background.
1986 1919
1987At this point you might want to write for example a systemd unit file to start 1920Ascension-bind is also an unofficial Debian package that on installation checks
1988and enable the service, so that your zone is migrated automatically. 1921for running DNS zones and whether or not they are transferable using DNS zone
1922transfer (AXFR). It asks the administrator which zones to migrate into GNS and
1923installs a systemd unit file to keep the zone up to date. If you want to
1924migrate different zones you might want to check the unit file from the package
1925as a guide.
1989 1926
1990@node reclaimID Identity Provider 1927@node reclaimID Identity Provider
1991@section reclaimID Identity Provider 1928@section reclaimID Identity Provider
diff --git a/doc/man/gnunet-config.1 b/doc/man/gnunet-config.1
index 0e612fe29..95dc98811 100644
--- a/doc/man/gnunet-config.1
+++ b/doc/man/gnunet-config.1
@@ -30,6 +30,7 @@
30manipulate GNUnet configuration files 30manipulate GNUnet configuration files
31.Sh SYNOPSIS 31.Sh SYNOPSIS
32.Nm 32.Nm
33.Op Fl b Ar BACKEND | Fl \-supported-backend= Ns Ar BACKEND
33.Op Fl c Ar FILENAME | Fl \-config= Ns Ar FILENAME 34.Op Fl c Ar FILENAME | Fl \-config= Ns Ar FILENAME
34.Op Fl f | \-filename 35.Op Fl f | \-filename
35.Op Fl h | \-help 36.Op Fl h | \-help
@@ -44,6 +45,8 @@ manipulate GNUnet configuration files
44.Nm 45.Nm
45can be used to read or modify GNUnet configuration files. 46can be used to read or modify GNUnet configuration files.
46.Bl -tag -width indent 47.Bl -tag -width indent
48.It Fl b Ar BACKEND | Fl \-supported-backend= Ns Ar BACKEND
49Tests whether the specified BACKEND is supported by the current installation. The backend must match the name of a plugin, i.e. "namestore_postgres" for the Postgres database backend of the "NAMESTORE" service. If the BACKEND is supported, gnunet-config will return a status code of 0 (success), otherwise 77 (unsupported). When this option is specified, no other options may be specified. Specifying this option together with other options will cause gnunet-config to return a status code of 1 (error).
47.It Fl c Ar FILENAME | Fl \-config= Ns Ar FILENAME 50.It Fl c Ar FILENAME | Fl \-config= Ns Ar FILENAME
48Use the configuration file FILENAME. 51Use the configuration file FILENAME.
49.It Fl f | \-filename 52.It Fl f | \-filename
diff --git a/src/arm/arm_api.c b/src/arm/arm_api.c
index c8103c877..bf0acbcb9 100644
--- a/src/arm/arm_api.c
+++ b/src/arm/arm_api.c
@@ -30,7 +30,7 @@
30#include "gnunet_protocols.h" 30#include "gnunet_protocols.h"
31#include "arm.h" 31#include "arm.h"
32 32
33#define LOG(kind,...) GNUNET_log_from (kind, "arm-api",__VA_ARGS__) 33#define LOG(kind, ...) GNUNET_log_from (kind, "arm-api", __VA_ARGS__)
34 34
35 35
36/** 36/**
@@ -156,7 +156,6 @@ struct GNUNET_ARM_Handle
156 * Have we detected that ARM is up? 156 * Have we detected that ARM is up?
157 */ 157 */
158 int currently_up; 158 int currently_up;
159
160}; 159};
161 160
162 161
@@ -204,27 +203,19 @@ reconnect_arm_later (struct GNUNET_ARM_Handle *h)
204 h->currently_up = GNUNET_NO; 203 h->currently_up = GNUNET_NO;
205 GNUNET_assert (NULL == h->reconnect_task); 204 GNUNET_assert (NULL == h->reconnect_task);
206 h->reconnect_task = 205 h->reconnect_task =
207 GNUNET_SCHEDULER_add_delayed (h->retry_backoff, 206 GNUNET_SCHEDULER_add_delayed (h->retry_backoff, &reconnect_arm_task, h);
208 &reconnect_arm_task,
209 h);
210 while (NULL != (op = h->operation_pending_head)) 207 while (NULL != (op = h->operation_pending_head))
211 { 208 {
212 if (NULL != op->result_cont) 209 if (NULL != op->result_cont)
213 op->result_cont (op->cont_cls, 210 op->result_cont (op->cont_cls, GNUNET_ARM_REQUEST_DISCONNECTED, 0);
214 GNUNET_ARM_REQUEST_DISCONNECTED,
215 0);
216 if (NULL != op->list_cont) 211 if (NULL != op->list_cont)
217 op->list_cont (op->cont_cls, 212 op->list_cont (op->cont_cls, GNUNET_ARM_REQUEST_DISCONNECTED, 0, NULL);
218 GNUNET_ARM_REQUEST_DISCONNECTED,
219 0,
220 NULL);
221 GNUNET_ARM_operation_cancel (op); 213 GNUNET_ARM_operation_cancel (op);
222 } 214 }
223 GNUNET_assert (NULL == h->operation_pending_head); 215 GNUNET_assert (NULL == h->operation_pending_head);
224 h->retry_backoff = GNUNET_TIME_STD_BACKOFF (h->retry_backoff); 216 h->retry_backoff = GNUNET_TIME_STD_BACKOFF (h->retry_backoff);
225 if (NULL != h->conn_status) 217 if (NULL != h->conn_status)
226 h->conn_status (h->conn_status_cls, 218 h->conn_status (h->conn_status_cls, GNUNET_NO);
227 GNUNET_NO);
228} 219}
229 220
230 221
@@ -236,12 +227,12 @@ reconnect_arm_later (struct GNUNET_ARM_Handle *h)
236 * @return NULL if not found 227 * @return NULL if not found
237 */ 228 */
238static struct GNUNET_ARM_Operation * 229static struct GNUNET_ARM_Operation *
239find_op_by_id (struct GNUNET_ARM_Handle *h, 230find_op_by_id (struct GNUNET_ARM_Handle *h, uint64_t id)
240 uint64_t id)
241{ 231{
242 struct GNUNET_ARM_Operation *result; 232 struct GNUNET_ARM_Operation *result;
243 233
244 for (result = h->operation_pending_head; NULL != result; result = result->next) 234 for (result = h->operation_pending_head; NULL != result;
235 result = result->next)
245 if (id == result->id) 236 if (id == result->id)
246 return result; 237 return result;
247 return NULL; 238 return NULL;
@@ -255,8 +246,7 @@ find_op_by_id (struct GNUNET_ARM_Handle *h,
255 * @param res the message received from the arm service 246 * @param res the message received from the arm service
256 */ 247 */
257static void 248static void
258handle_arm_result (void *cls, 249handle_arm_result (void *cls, const struct GNUNET_ARM_ResultMessage *res)
259 const struct GNUNET_ARM_ResultMessage *res)
260{ 250{
261 struct GNUNET_ARM_Handle *h = cls; 251 struct GNUNET_ARM_Handle *h = cls;
262 struct GNUNET_ARM_Operation *op; 252 struct GNUNET_ARM_Operation *op;
@@ -266,8 +256,7 @@ handle_arm_result (void *cls,
266 void *result_cont_cls; 256 void *result_cont_cls;
267 257
268 id = GNUNET_ntohll (res->arm_msg.request_id); 258 id = GNUNET_ntohll (res->arm_msg.request_id);
269 op = find_op_by_id (h, 259 op = find_op_by_id (h, id);
270 id);
271 if (NULL == op) 260 if (NULL == op)
272 { 261 {
273 LOG (GNUNET_ERROR_TYPE_DEBUG, 262 LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -277,8 +266,7 @@ handle_arm_result (void *cls,
277 } 266 }
278 267
279 result = (enum GNUNET_ARM_Result) ntohl (res->result); 268 result = (enum GNUNET_ARM_Result) ntohl (res->result);
280 if ( (GNUNET_YES == op->is_arm_stop) && 269 if ((GNUNET_YES == op->is_arm_stop) && (GNUNET_ARM_RESULT_STOPPING == result))
281 (GNUNET_ARM_RESULT_STOPPING == result) )
282 { 270 {
283 /* special case: if we are stopping 'gnunet-service-arm', we do not just 271 /* special case: if we are stopping 'gnunet-service-arm', we do not just
284 wait for the result message, but also wait for the service to close 272 wait for the result message, but also wait for the service to close
@@ -289,8 +277,8 @@ handle_arm_result (void *cls,
289 { 277 {
290 GNUNET_break (0); 278 GNUNET_break (0);
291 op->result_cont (h->thm->cont_cls, 279 op->result_cont (h->thm->cont_cls,
292 GNUNET_ARM_REQUEST_SENT_OK, 280 GNUNET_ARM_REQUEST_SENT_OK,
293 GNUNET_ARM_RESULT_IS_NOT_KNOWN); 281 GNUNET_ARM_RESULT_IS_NOT_KNOWN);
294 GNUNET_free (h->thm); 282 GNUNET_free (h->thm);
295 } 283 }
296 GNUNET_CONTAINER_DLL_remove (h->operation_pending_head, 284 GNUNET_CONTAINER_DLL_remove (h->operation_pending_head,
@@ -303,9 +291,7 @@ handle_arm_result (void *cls,
303 result_cont_cls = op->cont_cls; 291 result_cont_cls = op->cont_cls;
304 GNUNET_ARM_operation_cancel (op); 292 GNUNET_ARM_operation_cancel (op);
305 if (NULL != result_cont) 293 if (NULL != result_cont)
306 result_cont (result_cont_cls, 294 result_cont (result_cont_cls, GNUNET_ARM_REQUEST_SENT_OK, result);
307 GNUNET_ARM_REQUEST_SENT_OK,
308 result);
309} 295}
310 296
311 297
@@ -325,6 +311,7 @@ check_arm_list_result (void *cls,
325 uint16_t msize = ntohs (lres->arm_msg.header.size) - sizeof (*lres); 311 uint16_t msize = ntohs (lres->arm_msg.header.size) - sizeof (*lres);
326 uint16_t size_check; 312 uint16_t size_check;
327 313
314 (void) cls;
328 size_check = 0; 315 size_check = 0;
329 for (unsigned int i = 0; i < rcount; i++) 316 for (unsigned int i = 0; i < rcount; i++)
330 { 317 {
@@ -361,8 +348,7 @@ handle_arm_list_result (void *cls,
361 uint64_t id; 348 uint64_t id;
362 349
363 id = GNUNET_ntohll (lres->arm_msg.request_id); 350 id = GNUNET_ntohll (lres->arm_msg.request_id);
364 op = find_op_by_id (h, 351 op = find_op_by_id (h, id);
365 id);
366 if (NULL == op) 352 if (NULL == op)
367 { 353 {
368 LOG (GNUNET_ERROR_TYPE_DEBUG, 354 LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -373,9 +359,7 @@ handle_arm_list_result (void *cls,
373 size_check = 0; 359 size_check = 0;
374 for (unsigned int i = 0; i < rcount; i++) 360 for (unsigned int i = 0; i < rcount; i++)
375 { 361 {
376 const char *end = memchr (pos, 362 const char *end = memchr (pos, 0, msize - size_check);
377 0,
378 msize - size_check);
379 363
380 /* Assert, as this was already checked in #check_arm_list_result() */ 364 /* Assert, as this was already checked in #check_arm_list_result() */
381 GNUNET_assert (NULL != end); 365 GNUNET_assert (NULL != end);
@@ -384,10 +368,7 @@ handle_arm_list_result (void *cls,
384 pos = end + 1; 368 pos = end + 1;
385 } 369 }
386 if (NULL != op->list_cont) 370 if (NULL != op->list_cont)
387 op->list_cont (op->cont_cls, 371 op->list_cont (op->cont_cls, GNUNET_ARM_REQUEST_SENT_OK, rcount, list);
388 GNUNET_ARM_REQUEST_SENT_OK,
389 rcount,
390 list);
391 GNUNET_ARM_operation_cancel (op); 372 GNUNET_ARM_operation_cancel (op);
392} 373}
393 374
@@ -399,19 +380,17 @@ handle_arm_list_result (void *cls,
399 * @param msg message received 380 * @param msg message received
400 */ 381 */
401static void 382static void
402handle_confirm (void *cls, 383handle_confirm (void *cls, const struct GNUNET_MessageHeader *msg)
403 const struct GNUNET_MessageHeader *msg)
404{ 384{
405 struct GNUNET_ARM_Handle *h = cls; 385 struct GNUNET_ARM_Handle *h = cls;
406 386
407 LOG (GNUNET_ERROR_TYPE_DEBUG, 387 (void) msg;
408 "Got confirmation from ARM that we are up!\n"); 388 LOG (GNUNET_ERROR_TYPE_DEBUG, "Got confirmation from ARM that we are up!\n");
409 if (GNUNET_NO == h->currently_up) 389 if (GNUNET_NO == h->currently_up)
410 { 390 {
411 h->currently_up = GNUNET_YES; 391 h->currently_up = GNUNET_YES;
412 if (NULL != h->conn_status) 392 if (NULL != h->conn_status)
413 h->conn_status (h->conn_status_cls, 393 h->conn_status (h->conn_status_cls, GNUNET_YES);
414 GNUNET_YES);
415 } 394 }
416} 395}
417 396
@@ -425,19 +404,19 @@ handle_confirm (void *cls,
425 * @param error error code 404 * @param error error code
426 */ 405 */
427static void 406static void
428mq_error_handler (void *cls, 407mq_error_handler (void *cls, enum GNUNET_MQ_Error error)
429 enum GNUNET_MQ_Error error)
430{ 408{
431 struct GNUNET_ARM_Handle *h = cls; 409 struct GNUNET_ARM_Handle *h = cls;
432 struct GNUNET_ARM_Operation *op; 410 struct GNUNET_ARM_Operation *op;
433 411
412 (void) error;
434 h->currently_up = GNUNET_NO; 413 h->currently_up = GNUNET_NO;
435 if (NULL != (op = h->thm)) 414 if (NULL != (op = h->thm))
436 { 415 {
437 h->thm = NULL; 416 h->thm = NULL;
438 op->result_cont (op->cont_cls, 417 op->result_cont (op->cont_cls,
439 GNUNET_ARM_REQUEST_SENT_OK, 418 GNUNET_ARM_REQUEST_SENT_OK,
440 GNUNET_ARM_RESULT_STOPPED); 419 GNUNET_ARM_RESULT_STOPPED);
441 GNUNET_free (op); 420 GNUNET_free (op);
442 } 421 }
443 reconnect_arm_later (h); 422 reconnect_arm_later (h);
@@ -453,47 +432,37 @@ mq_error_handler (void *cls,
453static int 432static int
454reconnect_arm (struct GNUNET_ARM_Handle *h) 433reconnect_arm (struct GNUNET_ARM_Handle *h)
455{ 434{
456 struct GNUNET_MQ_MessageHandler handlers[] = { 435 struct GNUNET_MQ_MessageHandler handlers[] =
457 GNUNET_MQ_hd_fixed_size (arm_result, 436 {GNUNET_MQ_hd_fixed_size (arm_result,
458 GNUNET_MESSAGE_TYPE_ARM_RESULT, 437 GNUNET_MESSAGE_TYPE_ARM_RESULT,
459 struct GNUNET_ARM_ResultMessage, 438 struct GNUNET_ARM_ResultMessage,
460 h), 439 h),
461 GNUNET_MQ_hd_var_size (arm_list_result, 440 GNUNET_MQ_hd_var_size (arm_list_result,
462 GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT, 441 GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT,
463 struct GNUNET_ARM_ListResultMessage, 442 struct GNUNET_ARM_ListResultMessage,
464 h), 443 h),
465 GNUNET_MQ_hd_fixed_size (confirm, 444 GNUNET_MQ_hd_fixed_size (confirm,
466 GNUNET_MESSAGE_TYPE_ARM_TEST, 445 GNUNET_MESSAGE_TYPE_ARM_TEST,
467 struct GNUNET_MessageHeader, 446 struct GNUNET_MessageHeader,
468 h), 447 h),
469 GNUNET_MQ_handler_end () 448 GNUNET_MQ_handler_end ()};
470 };
471 struct GNUNET_MessageHeader *test; 449 struct GNUNET_MessageHeader *test;
472 struct GNUNET_MQ_Envelope *env; 450 struct GNUNET_MQ_Envelope *env;
473 451
474 if (NULL != h->mq) 452 if (NULL != h->mq)
475 return GNUNET_OK; 453 return GNUNET_OK;
476 GNUNET_assert (GNUNET_NO == h->currently_up); 454 GNUNET_assert (GNUNET_NO == h->currently_up);
477 h->mq = GNUNET_CLIENT_connect (h->cfg, 455 h->mq = GNUNET_CLIENT_connect (h->cfg, "arm", handlers, &mq_error_handler, h);
478 "arm",
479 handlers,
480 &mq_error_handler,
481 h);
482 if (NULL == h->mq) 456 if (NULL == h->mq)
483 { 457 {
484 LOG (GNUNET_ERROR_TYPE_DEBUG, 458 LOG (GNUNET_ERROR_TYPE_DEBUG, "GNUNET_CLIENT_connect returned NULL\n");
485 "GNUNET_CLIENT_connect returned NULL\n");
486 if (NULL != h->conn_status) 459 if (NULL != h->conn_status)
487 h->conn_status (h->conn_status_cls, 460 h->conn_status (h->conn_status_cls, GNUNET_SYSERR);
488 GNUNET_SYSERR);
489 return GNUNET_SYSERR; 461 return GNUNET_SYSERR;
490 } 462 }
491 LOG (GNUNET_ERROR_TYPE_DEBUG, 463 LOG (GNUNET_ERROR_TYPE_DEBUG, "Sending TEST message to ARM\n");
492 "Sending TEST message to ARM\n"); 464 env = GNUNET_MQ_msg (test, GNUNET_MESSAGE_TYPE_ARM_TEST);
493 env = GNUNET_MQ_msg (test, 465 GNUNET_MQ_send (h->mq, env);
494 GNUNET_MESSAGE_TYPE_ARM_TEST);
495 GNUNET_MQ_send (h->mq,
496 env);
497 return GNUNET_OK; 466 return GNUNET_OK;
498} 467}
499 468
@@ -512,7 +481,7 @@ reconnect_arm (struct GNUNET_ARM_Handle *h)
512struct GNUNET_ARM_Handle * 481struct GNUNET_ARM_Handle *
513GNUNET_ARM_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, 482GNUNET_ARM_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
514 GNUNET_ARM_ConnectionStatusCallback conn_status, 483 GNUNET_ARM_ConnectionStatusCallback conn_status,
515 void *conn_status_cls) 484 void *conn_status_cls)
516{ 485{
517 struct GNUNET_ARM_Handle *h; 486 struct GNUNET_ARM_Handle *h;
518 487
@@ -539,22 +508,16 @@ GNUNET_ARM_disconnect (struct GNUNET_ARM_Handle *h)
539{ 508{
540 struct GNUNET_ARM_Operation *op; 509 struct GNUNET_ARM_Operation *op;
541 510
542 LOG (GNUNET_ERROR_TYPE_DEBUG, 511 LOG (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from ARM service\n");
543 "Disconnecting from ARM service\n");
544 while (NULL != (op = h->operation_pending_head)) 512 while (NULL != (op = h->operation_pending_head))
545 { 513 {
546 GNUNET_CONTAINER_DLL_remove (h->operation_pending_head, 514 GNUNET_CONTAINER_DLL_remove (h->operation_pending_head,
547 h->operation_pending_tail, 515 h->operation_pending_tail,
548 op); 516 op);
549 if (NULL != op->result_cont) 517 if (NULL != op->result_cont)
550 op->result_cont (op->cont_cls, 518 op->result_cont (op->cont_cls, GNUNET_ARM_REQUEST_DISCONNECTED, 0);
551 GNUNET_ARM_REQUEST_DISCONNECTED,
552 0);
553 if (NULL != op->list_cont) 519 if (NULL != op->list_cont)
554 op->list_cont (op->cont_cls, 520 op->list_cont (op->cont_cls, GNUNET_ARM_REQUEST_DISCONNECTED, 0, NULL);
555 GNUNET_ARM_REQUEST_DISCONNECTED,
556 0,
557 NULL);
558 if (NULL != op->async) 521 if (NULL != op->async)
559 { 522 {
560 GNUNET_SCHEDULER_cancel (op->async); 523 GNUNET_SCHEDULER_cancel (op->async);
@@ -596,60 +559,43 @@ start_arm_service (struct GNUNET_ARM_Handle *h,
596 char *loprefix; 559 char *loprefix;
597 char *lopostfix; 560 char *lopostfix;
598 561
599 if (GNUNET_OK != 562 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (h->cfg,
600 GNUNET_CONFIGURATION_get_value_string (h->cfg, 563 "arm",
601 "arm", 564 "PREFIX",
602 "PREFIX", 565 &loprefix))
603 &loprefix))
604 loprefix = GNUNET_strdup (""); 566 loprefix = GNUNET_strdup ("");
605 else 567 else
606 loprefix = GNUNET_CONFIGURATION_expand_dollar (h->cfg, 568 loprefix = GNUNET_CONFIGURATION_expand_dollar (h->cfg, loprefix);
607 loprefix); 569 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (h->cfg,
608 if (GNUNET_OK != 570 "arm",
609 GNUNET_CONFIGURATION_get_value_string (h->cfg, 571 "OPTIONS",
610 "arm", 572 &lopostfix))
611 "OPTIONS",
612 &lopostfix))
613 lopostfix = GNUNET_strdup (""); 573 lopostfix = GNUNET_strdup ("");
614 else 574 else
615 lopostfix = GNUNET_CONFIGURATION_expand_dollar (h->cfg, 575 lopostfix = GNUNET_CONFIGURATION_expand_dollar (h->cfg, lopostfix);
616 lopostfix);
617 if (GNUNET_OK != 576 if (GNUNET_OK !=
618 GNUNET_CONFIGURATION_get_value_string (h->cfg, 577 GNUNET_CONFIGURATION_get_value_string (h->cfg, "arm", "BINARY", &cbinary))
619 "arm",
620 "BINARY",
621 &cbinary))
622 { 578 {
623 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING, 579 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING, "arm", "BINARY");
624 "arm",
625 "BINARY");
626 GNUNET_free (loprefix); 580 GNUNET_free (loprefix);
627 GNUNET_free (lopostfix); 581 GNUNET_free (lopostfix);
628 return GNUNET_ARM_RESULT_IS_NOT_KNOWN; 582 return GNUNET_ARM_RESULT_IS_NOT_KNOWN;
629 } 583 }
630 if (GNUNET_OK != 584 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (h->cfg,
631 GNUNET_CONFIGURATION_get_value_filename (h->cfg, 585 "arm",
632 "arm", 586 "CONFIG",
633 "CONFIG", 587 &config))
634 &config))
635 config = NULL; 588 config = NULL;
636 binary = GNUNET_OS_get_libexec_binary_path (cbinary); 589 binary = GNUNET_OS_get_libexec_binary_path (cbinary);
637 GNUNET_asprintf (&quotedbinary, 590 GNUNET_asprintf (&quotedbinary, "\"%s\"", binary);
638 "\"%s\"",
639 binary);
640 GNUNET_free (cbinary); 591 GNUNET_free (cbinary);
641 if ( (GNUNET_YES == 592 if ((GNUNET_YES ==
642 GNUNET_CONFIGURATION_have_value (h->cfg, 593 GNUNET_CONFIGURATION_have_value (h->cfg, "TESTING", "WEAKRANDOM")) &&
643 "TESTING", 594 (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (h->cfg,
644 "WEAKRANDOM")) && 595 "TESTING",
645 (GNUNET_YES == 596 "WEAKRANDOM")) &&
646 GNUNET_CONFIGURATION_get_value_yesno (h->cfg, 597 (GNUNET_NO ==
647 "TESTING", 598 GNUNET_CONFIGURATION_have_value (h->cfg, "TESTING", "HOSTFILE")))
648 "WEAKRANDOM")) &&
649 (GNUNET_NO ==
650 GNUNET_CONFIGURATION_have_value (h->cfg,
651 "TESTING",
652 "HOSTFILE")))
653 { 599 {
654 /* Means we are ONLY running locally */ 600 /* Means we are ONLY running locally */
655 /* we're clearly running a test, don't daemonize */ 601 /* we're clearly running a test, don't daemonize */
@@ -668,7 +614,8 @@ start_arm_service (struct GNUNET_ARM_Handle *h,
668 NULL, 614 NULL,
669 loprefix, 615 loprefix,
670 quotedbinary, 616 quotedbinary,
671 "-c", config, 617 "-c",
618 config,
672 /* no daemonization! */ 619 /* no daemonization! */
673 lopostfix, 620 lopostfix,
674 NULL); 621 NULL);
@@ -683,14 +630,15 @@ start_arm_service (struct GNUNET_ARM_Handle *h,
683 quotedbinary, 630 quotedbinary,
684 "-d", /* do daemonize */ 631 "-d", /* do daemonize */
685 lopostfix, 632 lopostfix,
686 NULL); 633 NULL);
687 else 634 else
688 proc = GNUNET_OS_start_process_s (GNUNET_NO, 635 proc = GNUNET_OS_start_process_s (GNUNET_NO,
689 std_inheritance, 636 std_inheritance,
690 NULL, 637 NULL,
691 loprefix, 638 loprefix,
692 quotedbinary, 639 quotedbinary,
693 "-c", config, 640 "-c",
641 config,
694 "-d", /* do daemonize */ 642 "-d", /* do daemonize */
695 lopostfix, 643 lopostfix,
696 NULL); 644 NULL);
@@ -744,7 +692,7 @@ static struct GNUNET_ARM_Operation *
744change_service (struct GNUNET_ARM_Handle *h, 692change_service (struct GNUNET_ARM_Handle *h,
745 const char *service_name, 693 const char *service_name,
746 GNUNET_ARM_ResultCallback cb, 694 GNUNET_ARM_ResultCallback cb,
747 void *cb_cls, 695 void *cb_cls,
748 uint16_t type) 696 uint16_t type)
749{ 697{
750 struct GNUNET_ARM_Operation *op; 698 struct GNUNET_ARM_Operation *op;
@@ -753,8 +701,7 @@ change_service (struct GNUNET_ARM_Handle *h,
753 struct GNUNET_ARM_Message *msg; 701 struct GNUNET_ARM_Message *msg;
754 702
755 slen = strlen (service_name) + 1; 703 slen = strlen (service_name) + 1;
756 if (slen + sizeof (struct GNUNET_ARM_Message) >= 704 if (slen + sizeof (struct GNUNET_ARM_Message) >= GNUNET_MAX_MESSAGE_SIZE)
757 GNUNET_MAX_MESSAGE_SIZE)
758 { 705 {
759 GNUNET_break (0); 706 GNUNET_break (0);
760 return NULL; 707 return NULL;
@@ -769,16 +716,11 @@ change_service (struct GNUNET_ARM_Handle *h,
769 GNUNET_CONTAINER_DLL_insert_tail (h->operation_pending_head, 716 GNUNET_CONTAINER_DLL_insert_tail (h->operation_pending_head,
770 h->operation_pending_tail, 717 h->operation_pending_tail,
771 op); 718 op);
772 env = GNUNET_MQ_msg_extra (msg, 719 env = GNUNET_MQ_msg_extra (msg, slen, type);
773 slen,
774 type);
775 msg->reserved = htonl (0); 720 msg->reserved = htonl (0);
776 msg->request_id = GNUNET_htonll (op->id); 721 msg->request_id = GNUNET_htonll (op->id);
777 GNUNET_memcpy (&msg[1], 722 GNUNET_memcpy (&msg[1], service_name, slen);
778 service_name, 723 GNUNET_MQ_send (h->mq, env);
779 slen);
780 GNUNET_MQ_send (h->mq,
781 env);
782 return op; 724 return op;
783} 725}
784 726
@@ -802,10 +744,8 @@ notify_running (void *cls)
802 op->result_cont (op->cont_cls, 744 op->result_cont (op->cont_cls,
803 GNUNET_ARM_REQUEST_SENT_OK, 745 GNUNET_ARM_REQUEST_SENT_OK,
804 GNUNET_ARM_RESULT_IS_STARTED_ALREADY); 746 GNUNET_ARM_RESULT_IS_STARTED_ALREADY);
805 if ( (GNUNET_YES == h->currently_up) && 747 if ((GNUNET_YES == h->currently_up) && (NULL != h->conn_status))
806 (NULL != h->conn_status) ) 748 h->conn_status (h->conn_status_cls, GNUNET_YES);
807 h->conn_status (h->conn_status_cls,
808 GNUNET_YES);
809 GNUNET_free (op); 749 GNUNET_free (op);
810} 750}
811 751
@@ -846,20 +786,18 @@ notify_starting (void *cls)
846 * @return handle for the operation, NULL on error 786 * @return handle for the operation, NULL on error
847 */ 787 */
848struct GNUNET_ARM_Operation * 788struct GNUNET_ARM_Operation *
849GNUNET_ARM_request_service_start (struct GNUNET_ARM_Handle *h, 789GNUNET_ARM_request_service_start (
850 const char *service_name, 790 struct GNUNET_ARM_Handle *h,
851 enum GNUNET_OS_InheritStdioFlags std_inheritance, 791 const char *service_name,
852 GNUNET_ARM_ResultCallback cont, 792 enum GNUNET_OS_InheritStdioFlags std_inheritance,
853 void *cont_cls) 793 GNUNET_ARM_ResultCallback cont,
794 void *cont_cls)
854{ 795{
855 struct GNUNET_ARM_Operation *op; 796 struct GNUNET_ARM_Operation *op;
856 enum GNUNET_ARM_Result ret; 797 enum GNUNET_ARM_Result ret;
857 798
858 LOG (GNUNET_ERROR_TYPE_DEBUG, 799 LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting service `%s'\n", service_name);
859 "Starting service `%s'\n", 800 if (0 != strcasecmp ("arm", service_name))
860 service_name);
861 if (0 != strcasecmp ("arm",
862 service_name))
863 return change_service (h, 801 return change_service (h,
864 service_name, 802 service_name,
865 cont, 803 cont,
@@ -874,8 +812,7 @@ GNUNET_ARM_request_service_start (struct GNUNET_ARM_Handle *h,
874 */ 812 */
875 if (GNUNET_YES == h->currently_up) 813 if (GNUNET_YES == h->currently_up)
876 { 814 {
877 LOG (GNUNET_ERROR_TYPE_DEBUG, 815 LOG (GNUNET_ERROR_TYPE_DEBUG, "ARM is already running\n");
878 "ARM is already running\n");
879 op = GNUNET_new (struct GNUNET_ARM_Operation); 816 op = GNUNET_new (struct GNUNET_ARM_Operation);
880 op->h = h; 817 op->h = h;
881 op->result_cont = cont; 818 op->result_cont = cont;
@@ -883,8 +820,7 @@ GNUNET_ARM_request_service_start (struct GNUNET_ARM_Handle *h,
883 GNUNET_CONTAINER_DLL_insert_tail (h->operation_pending_head, 820 GNUNET_CONTAINER_DLL_insert_tail (h->operation_pending_head,
884 h->operation_pending_tail, 821 h->operation_pending_tail,
885 op); 822 op);
886 op->async = GNUNET_SCHEDULER_add_now (&notify_running, 823 op->async = GNUNET_SCHEDULER_add_now (&notify_running, op);
887 op);
888 return op; 824 return op;
889 } 825 }
890 /* This is an inherently uncertain choice, as it is of course 826 /* This is an inherently uncertain choice, as it is of course
@@ -893,10 +829,8 @@ GNUNET_ARM_request_service_start (struct GNUNET_ARM_Handle *h,
893 are unlikely to hammer 'gnunet-arm -s' on a busy system, 829 are unlikely to hammer 'gnunet-arm -s' on a busy system,
894 the above check should catch 99.99% of the cases where ARM 830 the above check should catch 99.99% of the cases where ARM
895 is already running. */ 831 is already running. */
896 LOG (GNUNET_ERROR_TYPE_DEBUG, 832 LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting ARM service\n");
897 "Starting ARM service\n"); 833 ret = start_arm_service (h, std_inheritance);
898 ret = start_arm_service (h,
899 std_inheritance);
900 if (GNUNET_ARM_RESULT_STARTING == ret) 834 if (GNUNET_ARM_RESULT_STARTING == ret)
901 reconnect_arm (h); 835 reconnect_arm (h);
902 op = GNUNET_new (struct GNUNET_ARM_Operation); 836 op = GNUNET_new (struct GNUNET_ARM_Operation);
@@ -907,8 +841,7 @@ GNUNET_ARM_request_service_start (struct GNUNET_ARM_Handle *h,
907 h->operation_pending_tail, 841 h->operation_pending_tail,
908 op); 842 op);
909 op->starting_ret = ret; 843 op->starting_ret = ret;
910 op->async = GNUNET_SCHEDULER_add_now (&notify_starting, 844 op->async = GNUNET_SCHEDULER_add_now (&notify_starting, op);
911 op);
912 return op; 845 return op;
913} 846}
914 847
@@ -929,15 +862,13 @@ GNUNET_ARM_request_service_start (struct GNUNET_ARM_Handle *h,
929 */ 862 */
930struct GNUNET_ARM_Operation * 863struct GNUNET_ARM_Operation *
931GNUNET_ARM_request_service_stop (struct GNUNET_ARM_Handle *h, 864GNUNET_ARM_request_service_stop (struct GNUNET_ARM_Handle *h,
932 const char *service_name, 865 const char *service_name,
933 GNUNET_ARM_ResultCallback cont, 866 GNUNET_ARM_ResultCallback cont,
934 void *cont_cls) 867 void *cont_cls)
935{ 868{
936 struct GNUNET_ARM_Operation *op; 869 struct GNUNET_ARM_Operation *op;
937 870
938 LOG (GNUNET_ERROR_TYPE_DEBUG, 871 LOG (GNUNET_ERROR_TYPE_DEBUG, "Stopping service `%s'\n", service_name);
939 "Stopping service `%s'\n",
940 service_name);
941 op = change_service (h, 872 op = change_service (h,
942 service_name, 873 service_name,
943 cont, 874 cont,
@@ -947,8 +878,7 @@ GNUNET_ARM_request_service_stop (struct GNUNET_ARM_Handle *h,
947 return NULL; 878 return NULL;
948 /* If the service is ARM, set a flag as we will use MQ errors 879 /* If the service is ARM, set a flag as we will use MQ errors
949 to detect that the process is really gone. */ 880 to detect that the process is really gone. */
950 if (0 == strcasecmp (service_name, 881 if (0 == strcasecmp (service_name, "arm"))
951 "arm"))
952 op->is_arm_stop = GNUNET_YES; 882 op->is_arm_stop = GNUNET_YES;
953 return op; 883 return op;
954} 884}
@@ -971,8 +901,7 @@ GNUNET_ARM_request_service_list (struct GNUNET_ARM_Handle *h,
971 struct GNUNET_MQ_Envelope *env; 901 struct GNUNET_MQ_Envelope *env;
972 struct GNUNET_ARM_Message *msg; 902 struct GNUNET_ARM_Message *msg;
973 903
974 LOG (GNUNET_ERROR_TYPE_DEBUG, 904 LOG (GNUNET_ERROR_TYPE_DEBUG, "Requesting LIST from ARM service\n");
975 "Requesting LIST from ARM service\n");
976 if (0 == h->request_id_counter) 905 if (0 == h->request_id_counter)
977 h->request_id_counter++; 906 h->request_id_counter++;
978 op = GNUNET_new (struct GNUNET_ARM_Operation); 907 op = GNUNET_new (struct GNUNET_ARM_Operation);
@@ -983,12 +912,10 @@ GNUNET_ARM_request_service_list (struct GNUNET_ARM_Handle *h,
983 GNUNET_CONTAINER_DLL_insert_tail (h->operation_pending_head, 912 GNUNET_CONTAINER_DLL_insert_tail (h->operation_pending_head,
984 h->operation_pending_tail, 913 h->operation_pending_tail,
985 op); 914 op);
986 env = GNUNET_MQ_msg (msg, 915 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_ARM_LIST);
987 GNUNET_MESSAGE_TYPE_ARM_LIST);
988 msg->reserved = htonl (0); 916 msg->reserved = htonl (0);
989 msg->request_id = GNUNET_htonll (op->id); 917 msg->request_id = GNUNET_htonll (op->id);
990 GNUNET_MQ_send (h->mq, 918 GNUNET_MQ_send (h->mq, env);
991 env);
992 return op; 919 return op;
993} 920}
994 921
diff --git a/src/arm/arm_monitor_api.c b/src/arm/arm_monitor_api.c
index 15f91c036..55b12240f 100644
--- a/src/arm/arm_monitor_api.c
+++ b/src/arm/arm_monitor_api.c
@@ -32,7 +32,7 @@
32 32
33#define INIT_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) 33#define INIT_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
34 34
35#define LOG(kind,...) GNUNET_log_from (kind, "arm-monitor-api",__VA_ARGS__) 35#define LOG(kind, ...) GNUNET_log_from (kind, "arm-monitor-api", __VA_ARGS__)
36 36
37/** 37/**
38 * Handle for interacting with ARM. 38 * Handle for interacting with ARM.
@@ -69,7 +69,6 @@ struct GNUNET_ARM_MonitorHandle
69 * Closure for @e service_status. 69 * Closure for @e service_status.
70 */ 70 */
71 void *service_status_cls; 71 void *service_status_cls;
72
73}; 72};
74 73
75 74
@@ -115,9 +114,9 @@ reconnect_arm_monitor_later (struct GNUNET_ARM_MonitorHandle *h)
115 h->mq = NULL; 114 h->mq = NULL;
116 } 115 }
117 GNUNET_assert (NULL == h->reconnect_task); 116 GNUNET_assert (NULL == h->reconnect_task);
118 h->reconnect_task 117 h->reconnect_task = GNUNET_SCHEDULER_add_delayed (h->retry_backoff,
119 = GNUNET_SCHEDULER_add_delayed (h->retry_backoff, 118 &reconnect_arm_monitor_task,
120 &reconnect_arm_monitor_task, h); 119 h);
121 h->retry_backoff = GNUNET_TIME_STD_BACKOFF (h->retry_backoff); 120 h->retry_backoff = GNUNET_TIME_STD_BACKOFF (h->retry_backoff);
122} 121}
123 122
@@ -130,14 +129,14 @@ reconnect_arm_monitor_later (struct GNUNET_ARM_MonitorHandle *h)
130 * @return #GNUNET_OK if the message is well-formed 129 * @return #GNUNET_OK if the message is well-formed
131 */ 130 */
132static int 131static int
133check_monitor_notify (void *cls, 132check_monitor_notify (void *cls, const struct GNUNET_ARM_StatusMessage *msg)
134 const struct GNUNET_ARM_StatusMessage *msg)
135{ 133{
136 size_t sl = ntohs (msg->header.size) - sizeof (struct GNUNET_ARM_StatusMessage); 134 size_t sl =
135 ntohs (msg->header.size) - sizeof (struct GNUNET_ARM_StatusMessage);
137 const char *name = (const char *) &msg[1]; 136 const char *name = (const char *) &msg[1];
138 137
139 if ( (0 == sl) || 138 (void) cls;
140 ('\0' != name[sl-1]) ) 139 if ((0 == sl) || ('\0' != name[sl - 1]))
141 { 140 {
142 GNUNET_break (0); 141 GNUNET_break (0);
143 return GNUNET_SYSERR; 142 return GNUNET_SYSERR;
@@ -153,8 +152,7 @@ check_monitor_notify (void *cls,
153 * @param res the message received from the arm service 152 * @param res the message received from the arm service
154 */ 153 */
155static void 154static void
156handle_monitor_notify (void *cls, 155handle_monitor_notify (void *cls, const struct GNUNET_ARM_StatusMessage *res)
157 const struct GNUNET_ARM_StatusMessage *res)
158{ 156{
159 struct GNUNET_ARM_MonitorHandle *h = cls; 157 struct GNUNET_ARM_MonitorHandle *h = cls;
160 enum GNUNET_ARM_ServiceStatus status; 158 enum GNUNET_ARM_ServiceStatus status;
@@ -165,9 +163,7 @@ handle_monitor_notify (void *cls,
165 (const char *) &res[1], 163 (const char *) &res[1],
166 (int) status); 164 (int) status);
167 if (NULL != h->service_status) 165 if (NULL != h->service_status)
168 h->service_status (h->service_status_cls, 166 h->service_status (h->service_status_cls, (const char *) &res[1], status);
169 (const char *) &res[1],
170 status);
171} 167}
172 168
173 169
@@ -180,11 +176,11 @@ handle_monitor_notify (void *cls,
180 * @param error error code 176 * @param error error code
181 */ 177 */
182static void 178static void
183mq_error_handler (void *cls, 179mq_error_handler (void *cls, enum GNUNET_MQ_Error error)
184 enum GNUNET_MQ_Error error)
185{ 180{
186 struct GNUNET_ARM_MonitorHandle *h = cls; 181 struct GNUNET_ARM_MonitorHandle *h = cls;
187 182
183 (void) error;
188 reconnect_arm_monitor_later (h); 184 reconnect_arm_monitor_later (h);
189} 185}
190 186
@@ -198,22 +194,17 @@ mq_error_handler (void *cls,
198static int 194static int
199reconnect_arm_monitor (struct GNUNET_ARM_MonitorHandle *h) 195reconnect_arm_monitor (struct GNUNET_ARM_MonitorHandle *h)
200{ 196{
201 struct GNUNET_MQ_MessageHandler handlers[] = { 197 struct GNUNET_MQ_MessageHandler handlers[] =
202 GNUNET_MQ_hd_var_size (monitor_notify, 198 {GNUNET_MQ_hd_var_size (monitor_notify,
203 GNUNET_MESSAGE_TYPE_ARM_STATUS, 199 GNUNET_MESSAGE_TYPE_ARM_STATUS,
204 struct GNUNET_ARM_StatusMessage, 200 struct GNUNET_ARM_StatusMessage,
205 h), 201 h),
206 GNUNET_MQ_handler_end () 202 GNUNET_MQ_handler_end ()};
207 };
208 struct GNUNET_MessageHeader *msg; 203 struct GNUNET_MessageHeader *msg;
209 struct GNUNET_MQ_Envelope *env; 204 struct GNUNET_MQ_Envelope *env;
210 205
211 GNUNET_assert (NULL == h->mq); 206 GNUNET_assert (NULL == h->mq);
212 h->mq = GNUNET_CLIENT_connect (h->cfg, 207 h->mq = GNUNET_CLIENT_connect (h->cfg, "arm", handlers, &mq_error_handler, h);
213 "arm",
214 handlers,
215 &mq_error_handler,
216 h);
217 if (NULL == h->mq) 208 if (NULL == h->mq)
218 { 209 {
219 if (NULL != h->service_status) 210 if (NULL != h->service_status)
@@ -222,10 +213,8 @@ reconnect_arm_monitor (struct GNUNET_ARM_MonitorHandle *h)
222 GNUNET_ARM_SERVICE_STOPPED); 213 GNUNET_ARM_SERVICE_STOPPED);
223 return GNUNET_SYSERR; 214 return GNUNET_SYSERR;
224 } 215 }
225 env = GNUNET_MQ_msg (msg, 216 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_ARM_MONITOR);
226 GNUNET_MESSAGE_TYPE_ARM_MONITOR); 217 GNUNET_MQ_send (h->mq, env);
227 GNUNET_MQ_send (h->mq,
228 env);
229 return GNUNET_OK; 218 return GNUNET_OK;
230} 219}
231 220
diff --git a/src/arm/mockup-service.c b/src/arm/mockup-service.c
index c9f00b5dd..667556314 100644
--- a/src/arm/mockup-service.c
+++ b/src/arm/mockup-service.c
@@ -33,13 +33,13 @@ static int special_ret = 0;
33 * @param message the actual message 33 * @param message the actual message
34 */ 34 */
35static void 35static void
36handle_stop (void *cls, 36handle_stop (void *cls, const struct GNUNET_MessageHeader *message)
37 const struct GNUNET_MessageHeader *message)
38{ 37{
39 struct GNUNET_SERVICE_Client *client = cls; 38 struct GNUNET_SERVICE_Client *client = cls;
40 39
40 (void) message;
41 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 41 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
42 _("Initiating shutdown as requested by client.\n")); 42 _ ("Initiating shutdown as requested by client.\n"));
43 GNUNET_SERVICE_client_persist (client); 43 GNUNET_SERVICE_client_persist (client);
44 GNUNET_SCHEDULER_shutdown (); 44 GNUNET_SCHEDULER_shutdown ();
45 /* ARM won't exponentially increase restart delay if we 45 /* ARM won't exponentially increase restart delay if we
@@ -59,9 +59,11 @@ handle_stop (void *cls,
59 */ 59 */
60static void * 60static void *
61client_connect_cb (void *cls, 61client_connect_cb (void *cls,
62 struct GNUNET_SERVICE_Client *c, 62 struct GNUNET_SERVICE_Client *c,
63 struct GNUNET_MQ_Handle *mq) 63 struct GNUNET_MQ_Handle *mq)
64{ 64{
65 (void) cls;
66 (void) mq;
65 return c; 67 return c;
66} 68}
67 69
@@ -75,9 +77,10 @@ client_connect_cb (void *cls,
75 */ 77 */
76static void 78static void
77client_disconnect_cb (void *cls, 79client_disconnect_cb (void *cls,
78 struct GNUNET_SERVICE_Client *c, 80 struct GNUNET_SERVICE_Client *c,
79 void *internal_cls) 81 void *internal_cls)
80{ 82{
83 (void) cls;
81 GNUNET_assert (c == internal_cls); 84 GNUNET_assert (c == internal_cls);
82} 85}
83 86
@@ -87,6 +90,9 @@ run (void *cls,
87 const struct GNUNET_CONFIGURATION_Handle *cfg, 90 const struct GNUNET_CONFIGURATION_Handle *cfg,
88 struct GNUNET_SERVICE_Handle *service) 91 struct GNUNET_SERVICE_Handle *service)
89{ 92{
93 (void) cls;
94 (void) cfg;
95 (void) service;
90 /* nothing to do */ 96 /* nothing to do */
91} 97}
92 98
@@ -94,25 +100,20 @@ run (void *cls,
94/** 100/**
95 * Define "main" method using service macro. 101 * Define "main" method using service macro.
96 */ 102 */
97GNUNET_SERVICE_MAIN 103GNUNET_SERVICE_MAIN ("do-nothing",
98("do-nothing", 104 GNUNET_SERVICE_OPTION_NONE,
99 GNUNET_SERVICE_OPTION_NONE, 105 &run,
100 &run, 106 &client_connect_cb,
101 &client_connect_cb, 107 &client_disconnect_cb,
102 &client_disconnect_cb, 108 NULL,
103 NULL, 109 GNUNET_MQ_hd_fixed_size (stop,
104 GNUNET_MQ_hd_fixed_size (stop, 110 GNUNET_MESSAGE_TYPE_ARM_STOP,
105 GNUNET_MESSAGE_TYPE_ARM_STOP, 111 struct GNUNET_MessageHeader,
106 struct GNUNET_MessageHeader, 112 NULL),
107 NULL), 113 GNUNET_MQ_handler_end ());
108 GNUNET_MQ_handler_end ());
109 114
110 115
111/** 116/**
112 * MINIMIZE heap size (way below 128k) since this process doesn't need much. 117 * MINIMIZE heap size (way below 128k) since this process doesn't need much.
113 */ 118 */
114void __attribute__ ((destructor)) 119void __attribute__ ((destructor)) GNUNET_mockup_done () { _exit (special_ret); }
115GNUNET_mockup_done ()
116{
117 _exit (special_ret);
118}
diff --git a/src/core/core_api.c b/src/core/core_api.c
index 6381d9097..223677a5b 100644
--- a/src/core/core_api.c
+++ b/src/core/core_api.c
@@ -341,6 +341,7 @@ core_mq_cancel_impl (struct GNUNET_MQ_Handle *mq, void *impl_state)
341{ 341{
342 struct PeerRecord *pr = impl_state; 342 struct PeerRecord *pr = impl_state;
343 343
344 (void) mq;
344 GNUNET_assert (NULL != pr->env); 345 GNUNET_assert (NULL != pr->env);
345 GNUNET_MQ_discard (pr->env); 346 GNUNET_MQ_discard (pr->env);
346 pr->env = NULL; 347 pr->env = NULL;
@@ -359,7 +360,8 @@ static void
359core_mq_error_handler (void *cls, enum GNUNET_MQ_Error error) 360core_mq_error_handler (void *cls, enum GNUNET_MQ_Error error)
360{ 361{
361 /* struct PeerRecord *pr = cls; */ 362 /* struct PeerRecord *pr = cls; */
362 363 (void) cls;
364 (void) error;
363 GNUNET_break_op (0); 365 GNUNET_break_op (0);
364} 366}
365 367
@@ -530,6 +532,7 @@ check_notify_inbound (void *cls, const struct NotifyTrafficMessage *ntm)
530 uint16_t msize; 532 uint16_t msize;
531 const struct GNUNET_MessageHeader *em; 533 const struct GNUNET_MessageHeader *em;
532 534
535 (void) cls;
533 msize = ntohs (ntm->header.size) - sizeof (struct NotifyTrafficMessage); 536 msize = ntohs (ntm->header.size) - sizeof (struct NotifyTrafficMessage);
534 if (msize < sizeof (struct GNUNET_MessageHeader)) 537 if (msize < sizeof (struct GNUNET_MessageHeader))
535 { 538 {
diff --git a/src/core/core_api_monitor_peers.c b/src/core/core_api_monitor_peers.c
index 0ebb94d7b..165f741d2 100644
--- a/src/core/core_api_monitor_peers.c
+++ b/src/core/core_api_monitor_peers.c
@@ -54,7 +54,6 @@ struct GNUNET_CORE_MonitorHandle
54 * Closure for @e peer_cb. 54 * Closure for @e peer_cb.
55 */ 55 */
56 void *peer_cb_cls; 56 void *peer_cb_cls;
57
58}; 57};
59 58
60 59
@@ -77,11 +76,11 @@ reconnect (struct GNUNET_CORE_MonitorHandle *mh);
77 * @param error error code 76 * @param error error code
78 */ 77 */
79static void 78static void
80handle_mq_error (void *cls, 79handle_mq_error (void *cls, enum GNUNET_MQ_Error error)
81 enum GNUNET_MQ_Error error)
82{ 80{
83 struct GNUNET_CORE_MonitorHandle *mh = cls; 81 struct GNUNET_CORE_MonitorHandle *mh = cls;
84 82
83 (void) error;
85 reconnect (mh); 84 reconnect (mh);
86} 85}
87 86
@@ -93,8 +92,7 @@ handle_mq_error (void *cls,
93 * @param mon_message monitor message 92 * @param mon_message monitor message
94 */ 93 */
95static void 94static void
96handle_receive_info (void *cls, 95handle_receive_info (void *cls, const struct MonitorNotifyMessage *mon_message)
97 const struct MonitorNotifyMessage *mon_message)
98{ 96{
99 struct GNUNET_CORE_MonitorHandle *mh = cls; 97 struct GNUNET_CORE_MonitorHandle *mh = cls;
100 98
@@ -114,24 +112,20 @@ handle_receive_info (void *cls,
114static void 112static void
115reconnect (struct GNUNET_CORE_MonitorHandle *mh) 113reconnect (struct GNUNET_CORE_MonitorHandle *mh)
116{ 114{
117 struct GNUNET_MQ_MessageHandler handlers[] = { 115 struct GNUNET_MQ_MessageHandler handlers[] =
118 GNUNET_MQ_hd_fixed_size (receive_info, 116 {GNUNET_MQ_hd_fixed_size (receive_info,
119 GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY, 117 GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY,
120 struct MonitorNotifyMessage, 118 struct MonitorNotifyMessage,
121 mh), 119 mh),
122 GNUNET_MQ_handler_end () 120 GNUNET_MQ_handler_end ()};
123 };
124 struct GNUNET_MQ_Envelope *env; 121 struct GNUNET_MQ_Envelope *env;
125 struct GNUNET_MessageHeader *msg; 122 struct GNUNET_MessageHeader *msg;
126 123
127 if (NULL != mh->mq) 124 if (NULL != mh->mq)
128 GNUNET_MQ_destroy (mh->mq); 125 GNUNET_MQ_destroy (mh->mq);
129 /* FIXME: use backoff? */ 126 /* FIXME: use backoff? */
130 mh->mq = GNUNET_CLIENT_connect (mh->cfg, 127 mh->mq =
131 "core", 128 GNUNET_CLIENT_connect (mh->cfg, "core", handlers, &handle_mq_error, mh);
132 handlers,
133 &handle_mq_error,
134 mh);
135 if (NULL == mh->mq) 129 if (NULL == mh->mq)
136 return; 130 return;
137 /* notify callback about reconnect */ 131 /* notify callback about reconnect */
@@ -140,10 +134,8 @@ reconnect (struct GNUNET_CORE_MonitorHandle *mh)
140 NULL, 134 NULL,
141 GNUNET_CORE_KX_CORE_DISCONNECT, 135 GNUNET_CORE_KX_CORE_DISCONNECT,
142 GNUNET_TIME_UNIT_FOREVER_ABS); 136 GNUNET_TIME_UNIT_FOREVER_ABS);
143 env = GNUNET_MQ_msg (msg, 137 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS);
144 GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS); 138 GNUNET_MQ_send (mh->mq, env);
145 GNUNET_MQ_send (mh->mq,
146 env);
147} 139}
148 140
149 141
diff --git a/src/core/gnunet-core.c b/src/core/gnunet-core.c
index 7180754a9..674da705a 100644
--- a/src/core/gnunet-core.c
+++ b/src/core/gnunet-core.c
@@ -48,6 +48,7 @@ static struct GNUNET_CORE_MonitorHandle *mh;
48static void 48static void
49shutdown_task (void *cls) 49shutdown_task (void *cls)
50{ 50{
51 (void) cls;
51 if (NULL != mh) 52 if (NULL != mh)
52 { 53 {
53 GNUNET_CORE_monitor_stop (mh); 54 GNUNET_CORE_monitor_stop (mh);
@@ -71,13 +72,13 @@ monitor_cb (void *cls,
71 enum GNUNET_CORE_KxState state, 72 enum GNUNET_CORE_KxState state,
72 struct GNUNET_TIME_Absolute timeout) 73 struct GNUNET_TIME_Absolute timeout)
73{ 74{
74 struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get(); 75 struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
75 const char *now_str; 76 const char *now_str;
76 const char *state_str; 77 const char *state_str;
77 78
78 if ( ( (NULL == peer) || 79 (void) cls;
79 (GNUNET_CORE_KX_ITERATION_FINISHED == state) ) && 80 if (((NULL == peer) || (GNUNET_CORE_KX_ITERATION_FINISHED == state)) &&
80 (GNUNET_NO == monitor_connections) ) 81 (GNUNET_NO == monitor_connections))
81 { 82 {
82 GNUNET_SCHEDULER_shutdown (); 83 GNUNET_SCHEDULER_shutdown ();
83 return; 84 return;
@@ -87,42 +88,43 @@ monitor_cb (void *cls,
87 { 88 {
88 case GNUNET_CORE_KX_STATE_DOWN: 89 case GNUNET_CORE_KX_STATE_DOWN:
89 /* should never happen, as we immediately send the key */ 90 /* should never happen, as we immediately send the key */
90 state_str = _("fresh connection"); 91 state_str = _ ("fresh connection");
91 break; 92 break;
92 case GNUNET_CORE_KX_STATE_KEY_SENT: 93 case GNUNET_CORE_KX_STATE_KEY_SENT:
93 state_str = _("key sent"); 94 state_str = _ ("key sent");
94 break; 95 break;
95 case GNUNET_CORE_KX_STATE_KEY_RECEIVED: 96 case GNUNET_CORE_KX_STATE_KEY_RECEIVED:
96 state_str = _("key received"); 97 state_str = _ ("key received");
97 break; 98 break;
98 case GNUNET_CORE_KX_STATE_UP: 99 case GNUNET_CORE_KX_STATE_UP:
99 state_str = _("connection established"); 100 state_str = _ ("connection established");
100 break; 101 break;
101 case GNUNET_CORE_KX_STATE_REKEY_SENT: 102 case GNUNET_CORE_KX_STATE_REKEY_SENT:
102 state_str = _("rekeying"); 103 state_str = _ ("rekeying");
103 break; 104 break;
104 case GNUNET_CORE_KX_PEER_DISCONNECT: 105 case GNUNET_CORE_KX_PEER_DISCONNECT:
105 state_str = _("disconnected"); 106 state_str = _ ("disconnected");
106 break; 107 break;
107 case GNUNET_CORE_KX_ITERATION_FINISHED: 108 case GNUNET_CORE_KX_ITERATION_FINISHED:
108 return; 109 return;
109 case GNUNET_CORE_KX_CORE_DISCONNECT: 110 case GNUNET_CORE_KX_CORE_DISCONNECT:
110 FPRINTF (stderr, 111 FPRINTF (stderr,
111 "%s\n", 112 "%s\n",
112 _("Connection to CORE service lost (reconnecting)")); 113 _ ("Connection to CORE service lost (reconnecting)"));
113 return; 114 return;
114 default: 115 default:
115 state_str = _("unknown state"); 116 state_str = _ ("unknown state");
116 break; 117 break;
117 } 118 }
118 now_str = GNUNET_STRINGS_absolute_time_to_string (now); 119 now_str = GNUNET_STRINGS_absolute_time_to_string (now);
119 FPRINTF (stdout, 120 FPRINTF (stdout,
120 _("%24s: %-30s %4s (timeout in %6s)\n"), 121 _ ("%24s: %-30s %4s (timeout in %6s)\n"),
121 now_str, 122 now_str,
122 state_str, 123 state_str,
123 GNUNET_i2s (peer), 124 GNUNET_i2s (peer),
124 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_remaining (timeout), 125 GNUNET_STRINGS_relative_time_to_string (
125 GNUNET_YES)); 126 GNUNET_TIME_absolute_get_remaining (timeout),
127 GNUNET_YES));
126} 128}
127 129
128 130
@@ -135,24 +137,22 @@ monitor_cb (void *cls,
135 * @param cfg configuration 137 * @param cfg configuration
136 */ 138 */
137static void 139static void
138run (void *cls, char *const *args, const char *cfgfile, 140run (void *cls,
141 char *const *args,
142 const char *cfgfile,
139 const struct GNUNET_CONFIGURATION_Handle *cfg) 143 const struct GNUNET_CONFIGURATION_Handle *cfg)
140{ 144{
145 (void) cls;
146 (void) cfgfile;
141 if (NULL != args[0]) 147 if (NULL != args[0])
142 { 148 {
143 FPRINTF (stderr, 149 FPRINTF (stderr, _ ("Invalid command line argument `%s'\n"), args[0]);
144 _("Invalid command line argument `%s'\n"),
145 args[0]);
146 return; 150 return;
147 } 151 }
148 mh = GNUNET_CORE_monitor_start (cfg, 152 mh = GNUNET_CORE_monitor_start (cfg, &monitor_cb, NULL);
149 &monitor_cb,
150 NULL);
151 if (NULL == mh) 153 if (NULL == mh)
152 { 154 {
153 FPRINTF (stderr, 155 FPRINTF (stderr, "%s", _ ("Failed to connect to CORE service!\n"));
154 "%s",
155 _("Failed to connect to CORE service!\n"));
156 return; 156 return;
157 } 157 }
158 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); 158 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL);
@@ -167,24 +167,28 @@ run (void *cls, char *const *args, const char *cfgfile,
167 * @return 0 ok, 1 on error 167 * @return 0 ok, 1 on error
168 */ 168 */
169int 169int
170main (int argc, 170main (int argc, char *const *argv)
171 char *const *argv)
172{ 171{
173 int res; 172 int res;
174 struct GNUNET_GETOPT_CommandLineOption options[] = { 173 struct GNUNET_GETOPT_CommandLineOption options[] =
175 GNUNET_GETOPT_option_flag ('m', 174 {GNUNET_GETOPT_option_flag (
176 "monitor", 175 'm',
177 gettext_noop ("provide information about all current connections (continuously)"), 176 "monitor",
178 &monitor_connections), 177 gettext_noop (
179 GNUNET_GETOPT_OPTION_END 178 "provide information about all current connections (continuously)"),
180 }; 179 &monitor_connections),
180 GNUNET_GETOPT_OPTION_END};
181 181
182 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) 182 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
183 return 2; 183 return 2;
184 res = GNUNET_PROGRAM_run (argc, argv, "gnunet-core", 184 res = GNUNET_PROGRAM_run (argc,
185 gettext_noop 185 argv,
186 ("Print information about connected peers."), 186 "gnunet-core",
187 options, &run, NULL); 187 gettext_noop (
188 "Print information about connected peers."),
189 options,
190 &run,
191 NULL);
188 192
189 GNUNET_free ((void *) argv); 193 GNUNET_free ((void *) argv);
190 if (GNUNET_OK == res) 194 if (GNUNET_OK == res)
diff --git a/src/curl/curl.c b/src/curl/curl.c
index 749094800..38a1f5fcd 100644
--- a/src/curl/curl.c
+++ b/src/curl/curl.c
@@ -111,7 +111,6 @@ struct GNUNET_CURL_Job
111 * after the job has finished. 111 * after the job has finished.
112 */ 112 */
113 struct curl_slist *job_headers; 113 struct curl_slist *job_headers;
114
115}; 114};
116 115
117 116
@@ -161,7 +160,6 @@ struct GNUNET_CURL_Context
161 * Closure for @e cb. 160 * Closure for @e cb.
162 */ 161 */
163 void *cb_cls; 162 void *cb_cls;
164
165}; 163};
166 164
167 165
@@ -213,7 +211,8 @@ GNUNET_CURL_init (GNUNET_CURL_RescheduleCallback cb, void *cb_cls)
213 * @param header_name name of the header to send. 211 * @param header_name name of the header to send.
214 */ 212 */
215void 213void
216GNUNET_CURL_enable_async_scope_header (struct GNUNET_CURL_Context *ctx, const char *header_name) 214GNUNET_CURL_enable_async_scope_header (struct GNUNET_CURL_Context *ctx,
215 const char *header_name)
217{ 216{
218 ctx->async_scope_id_header = header_name; 217 ctx->async_scope_id_header = header_name;
219} 218}
@@ -279,30 +278,26 @@ download_cb (char *bufptr, size_t size, size_t nitems, void *cls)
279 */ 278 */
280struct GNUNET_CURL_Job * 279struct GNUNET_CURL_Job *
281GNUNET_CURL_job_add2 (struct GNUNET_CURL_Context *ctx, 280GNUNET_CURL_job_add2 (struct GNUNET_CURL_Context *ctx,
282 CURL *eh, 281 CURL *eh,
283 const struct curl_slist *job_headers, 282 const struct curl_slist *job_headers,
284 GNUNET_CURL_JobCompletionCallback jcc, 283 GNUNET_CURL_JobCompletionCallback jcc,
285 void *jcc_cls) 284 void *jcc_cls)
286{ 285{
287 struct GNUNET_CURL_Job *job; 286 struct GNUNET_CURL_Job *job;
288 struct curl_slist *all_headers = NULL; 287 struct curl_slist *all_headers = NULL;
289 288
290 for (const struct curl_slist *curr = job_headers; 289 for (const struct curl_slist *curr = job_headers; curr != NULL;
291 curr != NULL;
292 curr = curr->next) 290 curr = curr->next)
293 { 291 {
294 GNUNET_assert ( 292 GNUNET_assert (NULL !=
295 NULL != (all_headers = 293 (all_headers = curl_slist_append (all_headers, curr->data)));
296 curl_slist_append (all_headers, curr->data)));
297 } 294 }
298 295
299 for (const struct curl_slist *curr = ctx->common_headers; 296 for (const struct curl_slist *curr = ctx->common_headers; curr != NULL;
300 curr != NULL;
301 curr = curr->next) 297 curr = curr->next)
302 { 298 {
303 GNUNET_assert ( 299 GNUNET_assert (NULL !=
304 NULL != (all_headers = 300 (all_headers = curl_slist_append (all_headers, curr->data)));
305 curl_slist_append (all_headers, curr->data)));
306 } 301 }
307 302
308 if (NULL != ctx->async_scope_id_header) 303 if (NULL != ctx->async_scope_id_header)
@@ -313,8 +308,10 @@ GNUNET_CURL_job_add2 (struct GNUNET_CURL_Context *ctx,
313 if (GNUNET_YES == scope.have_scope) 308 if (GNUNET_YES == scope.have_scope)
314 { 309 {
315 char *aid_header = NULL; 310 char *aid_header = NULL;
316 aid_header = GNUNET_STRINGS_data_to_string_alloc (&scope.scope_id, 311 aid_header =
317 sizeof (struct GNUNET_AsyncScopeId)); 312 GNUNET_STRINGS_data_to_string_alloc (&scope.scope_id,
313 sizeof (
314 struct GNUNET_AsyncScopeId));
318 GNUNET_assert (NULL != aid_header); 315 GNUNET_assert (NULL != aid_header);
319 GNUNET_assert (NULL != curl_slist_append (all_headers, aid_header)); 316 GNUNET_assert (NULL != curl_slist_append (all_headers, aid_header));
320 GNUNET_free (aid_header); 317 GNUNET_free (aid_header);
@@ -378,7 +375,9 @@ GNUNET_CURL_job_add (struct GNUNET_CURL_Context *ctx,
378 GNUNET_CURL_JobCompletionCallback jcc, 375 GNUNET_CURL_JobCompletionCallback jcc,
379 void *jcc_cls) 376 void *jcc_cls)
380{ 377{
378 struct GNUNET_CURL_Job *job;
381 struct curl_slist *job_headers = NULL; 379 struct curl_slist *job_headers = NULL;
380
382 if (GNUNET_YES == add_json) 381 if (GNUNET_YES == add_json)
383 { 382 {
384 GNUNET_assert ( 383 GNUNET_assert (
@@ -386,7 +385,9 @@ GNUNET_CURL_job_add (struct GNUNET_CURL_Context *ctx,
386 curl_slist_append (NULL, "Content-Type: application/json"))); 385 curl_slist_append (NULL, "Content-Type: application/json")));
387 } 386 }
388 387
389 return GNUNET_CURL_job_add2 (ctx, eh, job_headers, jcc, jcc_cls); 388 job = GNUNET_CURL_job_add2 (ctx, eh, job_headers, jcc, jcc_cls);
389 curl_slist_free_all (job_headers);
390 return job;
390} 391}
391 392
392 393
@@ -430,9 +431,9 @@ GNUNET_CURL_job_cancel (struct GNUNET_CURL_Job *job)
430 * @return NULL if downloading a JSON reply failed. 431 * @return NULL if downloading a JSON reply failed.
431 */ 432 */
432void * 433void *
433download_get_result (struct GNUNET_CURL_DownloadBuffer *db, 434GNUNET_CURL_download_get_result_ (struct GNUNET_CURL_DownloadBuffer *db,
434 CURL *eh, 435 CURL *eh,
435 long *response_code) 436 long *response_code)
436{ 437{
437 json_t *json; 438 json_t *json;
438 json_error_t error; 439 json_error_t error;
@@ -522,15 +523,16 @@ GNUNET_CURL_perform2 (struct GNUNET_CURL_Context *ctx,
522 GNUNET_CURL_ResponseCleaner rc) 523 GNUNET_CURL_ResponseCleaner rc)
523{ 524{
524 CURLMsg *cmsg; 525 CURLMsg *cmsg;
525 struct GNUNET_CURL_Job *job;
526 int n_running; 526 int n_running;
527 int n_completed; 527 int n_completed;
528 long response_code;
529 void *response;
530 528
531 (void) curl_multi_perform (ctx->multi, &n_running); 529 (void) curl_multi_perform (ctx->multi, &n_running);
532 while (NULL != (cmsg = curl_multi_info_read (ctx->multi, &n_completed))) 530 while (NULL != (cmsg = curl_multi_info_read (ctx->multi, &n_completed)))
533 { 531 {
532 struct GNUNET_CURL_Job *job;
533 long response_code;
534 void *response;
535
534 /* Only documented return value is CURLMSG_DONE */ 536 /* Only documented return value is CURLMSG_DONE */
535 GNUNET_break (CURLMSG_DONE == cmsg->msg); 537 GNUNET_break (CURLMSG_DONE == cmsg->msg);
536 GNUNET_assert (CURLE_OK == curl_easy_getinfo (cmsg->easy_handle, 538 GNUNET_assert (CURLE_OK == curl_easy_getinfo (cmsg->easy_handle,
@@ -619,9 +621,8 @@ GNUNET_CURL_perform2 (struct GNUNET_CURL_Context *ctx,
619void 621void
620GNUNET_CURL_perform (struct GNUNET_CURL_Context *ctx) 622GNUNET_CURL_perform (struct GNUNET_CURL_Context *ctx)
621{ 623{
622
623 GNUNET_CURL_perform2 (ctx, 624 GNUNET_CURL_perform2 (ctx,
624 download_get_result, 625 &GNUNET_CURL_download_get_result_,
625 (GNUNET_CURL_ResponseCleaner) &json_decref); 626 (GNUNET_CURL_ResponseCleaner) &json_decref);
626} 627}
627 628
diff --git a/src/curl/curl_reschedule.c b/src/curl/curl_reschedule.c
index 1b0f2e440..354ba13df 100644
--- a/src/curl/curl_reschedule.c
+++ b/src/curl/curl_reschedule.c
@@ -28,9 +28,9 @@
28#include "gnunet_util_lib.h" 28#include "gnunet_util_lib.h"
29 29
30extern void * 30extern void *
31download_get_result (struct GNUNET_CURL_DownloadBuffer *db, 31GNUNET_CURL_download_get_result_ (struct GNUNET_CURL_DownloadBuffer *db,
32 CURL *eh, 32 CURL *eh,
33 long *response_code); 33 long *response_code);
34 34
35/** 35/**
36 * Closure for #GNUNET_CURL_gnunet_scheduler_reschedule(). 36 * Closure for #GNUNET_CURL_gnunet_scheduler_reschedule().
@@ -105,7 +105,7 @@ GNUNET_CURL_gnunet_rc_create (struct GNUNET_CURL_Context *ctx)
105 105
106 rc = GNUNET_new (struct GNUNET_CURL_RescheduleContext); 106 rc = GNUNET_new (struct GNUNET_CURL_RescheduleContext);
107 rc->ctx = ctx; 107 rc->ctx = ctx;
108 rc->parser = &download_get_result; 108 rc->parser = &GNUNET_CURL_download_get_result_;
109 rc->cleaner = &clean_result; 109 rc->cleaner = &clean_result;
110 return rc; 110 return rc;
111} 111}
@@ -145,9 +145,7 @@ context_task (void *cls)
145 145
146 rc->task = NULL; 146 rc->task = NULL;
147 147
148 GNUNET_CURL_perform2 (rc->ctx, 148 GNUNET_CURL_perform2 (rc->ctx, rc->parser, rc->cleaner);
149 rc->parser,
150 rc->cleaner);
151 max_fd = -1; 149 max_fd = -1;
152 timeout = -1; 150 timeout = -1;
153 FD_ZERO (&read_fd_set); 151 FD_ZERO (&read_fd_set);
@@ -160,18 +158,14 @@ context_task (void *cls)
160 &max_fd, 158 &max_fd,
161 &timeout); 159 &timeout);
162 if (timeout >= 0) 160 if (timeout >= 0)
163 delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 161 delay =
164 timeout); 162 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, timeout);
165 else 163 else
166 delay = GNUNET_TIME_UNIT_FOREVER_REL; 164 delay = GNUNET_TIME_UNIT_FOREVER_REL;
167 rs = GNUNET_NETWORK_fdset_create (); 165 rs = GNUNET_NETWORK_fdset_create ();
168 GNUNET_NETWORK_fdset_copy_native (rs, 166 GNUNET_NETWORK_fdset_copy_native (rs, &read_fd_set, max_fd + 1);
169 &read_fd_set,
170 max_fd + 1);
171 ws = GNUNET_NETWORK_fdset_create (); 167 ws = GNUNET_NETWORK_fdset_create ();
172 GNUNET_NETWORK_fdset_copy_native (ws, 168 GNUNET_NETWORK_fdset_copy_native (ws, &write_fd_set, max_fd + 1);
173 &write_fd_set,
174 max_fd + 1);
175 if (NULL == rc->task) 169 if (NULL == rc->task)
176 rc->task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, 170 rc->task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
177 delay, 171 delay,
@@ -196,12 +190,11 @@ context_task (void *cls)
196void 190void
197GNUNET_CURL_gnunet_scheduler_reschedule (void *cls) 191GNUNET_CURL_gnunet_scheduler_reschedule (void *cls)
198{ 192{
199 struct GNUNET_CURL_RescheduleContext *rc = *(void**) cls; 193 struct GNUNET_CURL_RescheduleContext *rc = *(void **) cls;
200 194
201 if (NULL != rc->task) 195 if (NULL != rc->task)
202 GNUNET_SCHEDULER_cancel (rc->task); 196 GNUNET_SCHEDULER_cancel (rc->task);
203 rc->task = GNUNET_SCHEDULER_add_now (&context_task, 197 rc->task = GNUNET_SCHEDULER_add_now (&context_task, rc);
204 rc);
205} 198}
206 199
207/* end of curl_reschedule.c */ 200/* end of curl_reschedule.c */
diff --git a/src/gns/Makefile.am b/src/gns/Makefile.am
index 0a68e7cba..932b8d218 100644
--- a/src/gns/Makefile.am
+++ b/src/gns/Makefile.am
@@ -81,7 +81,7 @@ noinst_PROGRAMS = \
81 gnunet-gns-benchmark 81 gnunet-gns-benchmark
82 82
83pkgdata_DATA = \ 83pkgdata_DATA = \
84 openssl.cnf 84 gnunet-gns-proxy-ca.template
85 85
86if HAVE_MHD 86if HAVE_MHD
87if LINUX 87if LINUX
diff --git a/src/gns/gnunet-gns-proxy-ca.template b/src/gns/gnunet-gns-proxy-ca.template
new file mode 100644
index 000000000..32ee27fcd
--- /dev/null
+++ b/src/gns/gnunet-gns-proxy-ca.template
@@ -0,0 +1,303 @@
1# X.509 Certificate options
2#
3# DN options
4
5# The organization of the subject.
6organization = "GNU"
7
8# The organizational unit of the subject.
9unit = "GNUnet"
10
11# The locality of the subject.
12locality = World
13
14# The state of the certificate owner.
15# state = "Attiki"
16
17# The country of the subject. Two letter code.
18country = ZZ
19
20# The common name of the certificate owner.
21cn = "GNS Proxy CA"
22
23# A user id of the certificate owner.
24#uid = "clauper"
25
26# Set domain components
27#dc = "name"
28#dc = "domain"
29
30# If the supported DN OIDs are not adequate you can set
31# any OID here.
32# For example set the X.520 Title and the X.520 Pseudonym
33# by using OID and string pairs.
34#dn_oid = "2.5.4.12 Dr."
35#dn_oid = "2.5.4.65 jackal"
36
37# This is deprecated and should not be used in new
38# certificates.
39# pkcs9_email = "none@none.org"
40
41# An alternative way to set the certificate's distinguished name directly
42# is with the "dn" option. The attribute names allowed are:
43# C (country), street, O (organization), OU (unit), title, CN (common name),
44# L (locality), ST (state), placeOfBirth, gender, countryOfCitizenship,
45# countryOfResidence, serialNumber, telephoneNumber, surName, initials,
46# generationQualifier, givenName, pseudonym, dnQualifier, postalCode, name,
47# businessCategory, DC, UID, jurisdictionOfIncorporationLocalityName,
48# jurisdictionOfIncorporationStateOrProvinceName,
49# jurisdictionOfIncorporationCountryName, XmppAddr, and numeric OIDs.
50
51#dn = "cn = Nikos,st = New\, Something,C=GR,surName=Mavrogiannopoulos,2.5.4.9=Arkadias"
52
53# The serial number of the certificate
54# The value is in decimal (i.e. 1963) or hex (i.e. 0x07ab).
55# Comment the field for a random serial number.
56#serial = 007
57
58# In how many days, counting from today, this certificate will expire.
59# Use -1 if there is no expiration date.
60expiration_days = 3650
61
62# Alternatively you may set concrete dates and time. The GNU date string
63# formats are accepted. See:
64# https://www.gnu.org/software/tar/manual/html_node/Date-input-formats.html
65
66#activation_date = "2004-02-29 16:21:42"
67#expiration_date = "2025-02-29 16:24:41"
68
69# X.509 v3 extensions
70
71# A dnsname in case of a WWW server.
72#dns_name = "www.none.org"
73#dns_name = "www.morethanone.org"
74
75# An othername defined by an OID and a hex encoded string
76#other_name = "1.3.6.1.5.2.2 302ca00d1b0b56414e5245494e2e4f5247a11b3019a006020400000002a10f300d1b047269636b1b0561646d696e"
77#other_name_utf8 = "1.2.4.5.6 A UTF8 string"
78#other_name_octet = "1.2.4.5.6 A string that will be encoded as ASN.1 octet string"
79
80# Allows writing an XmppAddr Identifier
81#xmpp_name = juliet@im.example.com
82
83# Names used in PKINIT
84#krb5_principal = user@REALM.COM
85#krb5_principal = HTTP/user@REALM.COM
86
87# A subject alternative name URI
88#uri = "https://www.example.com"
89
90# An IP address in case of a server.
91#ip_address = "192.168.1.1"
92
93# An email in case of a person
94email = "bounce@gnunet.org"
95
96# TLS feature (rfc7633) extension. That can is used to indicate mandatory TLS
97# extension features to be provided by the server. In practice this is used
98# to require the Status Request (extid: 5) extension from the server. That is,
99# to require the server holding this certificate to provide a stapled OCSP response.
100# You can have multiple lines for multiple TLS features.
101
102# To ask for OCSP status request use:
103#tls_feature = 5
104
105# Challenge password used in certificate requests
106challenge_password = 123456
107
108# Password when encrypting a private key
109#password = secret
110
111# An URL that has CRLs (certificate revocation lists)
112# available. Needed in CA certificates.
113#crl_dist_points = "https://www.getcrl.crl/getcrl/"
114
115# Whether this is a CA certificate or not
116ca
117
118# Subject Unique ID (in hex)
119#subject_unique_id = 00153224
120
121# Issuer Unique ID (in hex)
122#issuer_unique_id = 00153225
123
124#### Key usage
125
126# The following key usage flags are used by CAs and end certificates
127
128# Whether this certificate will be used to sign data (needed
129# in TLS DHE ciphersuites). This is the digitalSignature flag
130# in RFC5280 terminology.
131signing_key
132
133# Whether this certificate will be used to encrypt data (needed
134# in TLS RSA ciphersuites). Note that it is preferred to use different
135# keys for encryption and signing. This is the keyEncipherment flag
136# in RFC5280 terminology.
137encryption_key
138
139# Whether this key will be used to sign other certificates. The
140# keyCertSign flag in RFC5280 terminology.
141cert_signing_key
142
143# Whether this key will be used to sign CRLs. The
144# cRLSign flag in RFC5280 terminology.
145#crl_signing_key
146
147# The keyAgreement flag of RFC5280. It's purpose is loosely
148# defined. Not use it unless required by a protocol.
149#key_agreement
150
151# The dataEncipherment flag of RFC5280. It's purpose is loosely
152# defined. Not use it unless required by a protocol.
153#data_encipherment
154
155# The nonRepudiation flag of RFC5280. It's purpose is loosely
156# defined. Not use it unless required by a protocol.
157#non_repudiation
158
159#### Extended key usage (key purposes)
160
161# The following extensions are used in an end certificate
162# to clarify its purpose. Some CAs also use it to indicate
163# the types of certificates they are purposed to sign.
164
165
166# Whether this certificate will be used for a TLS client;
167# this sets the id-kp-clientAuth (1.3.6.1.5.5.7.3.2) of
168# extended key usage.
169#tls_www_client
170
171# Whether this certificate will be used for a TLS server;
172# this sets the id-kp-serverAuth (1.3.6.1.5.5.7.3.1) of
173# extended key usage.
174tls_www_server
175
176# Whether this key will be used to sign code. This sets the
177# id-kp-codeSigning (1.3.6.1.5.5.7.3.3) of extended key usage
178# extension.
179#code_signing_key
180
181# Whether this key will be used to sign OCSP data. This sets the
182# id-kp-OCSPSigning (1.3.6.1.5.5.7.3.9) of extended key usage extension.
183#ocsp_signing_key
184
185# Whether this key will be used for time stamping. This sets the
186# id-kp-timeStamping (1.3.6.1.5.5.7.3.8) of extended key usage extension.
187#time_stamping_key
188
189# Whether this key will be used for email protection. This sets the
190# id-kp-emailProtection (1.3.6.1.5.5.7.3.4) of extended key usage extension.
191#email_protection_key
192
193# Whether this key will be used for IPsec IKE operations (1.3.6.1.5.5.7.3.17).
194#ipsec_ike_key
195
196## adding custom key purpose OIDs
197
198# for microsoft smart card logon
199# key_purpose_oid = 1.3.6.1.4.1.311.20.2.2
200
201# for email protection
202# key_purpose_oid = 1.3.6.1.5.5.7.3.4
203
204# for any purpose (must not be used in intermediate CA certificates)
205# key_purpose_oid = 2.5.29.37.0
206
207### end of key purpose OIDs
208
209### Adding arbitrary extensions
210# This requires to provide the extension OIDs, as well as the extension data in
211# hex format. The following two options are available since GnuTLS 3.5.3.
212#add_extension = "1.2.3.4 0x0AAB01ACFE"
213
214# As above but encode the data as an octet string
215#add_extension = "1.2.3.4 octet_string(0x0AAB01ACFE)"
216
217# For portability critical extensions shouldn't be set to certificates.
218#add_critical_extension = "5.6.7.8 0x1AAB01ACFE"
219
220# When generating a certificate from a certificate
221# request, then honor the extensions stored in the request
222# and store them in the real certificate.
223#honor_crq_extensions
224
225# Alternatively only specific extensions can be copied.
226#honor_crq_ext = 2.5.29.17
227#honor_crq_ext = 2.5.29.15
228
229# Path length contraint. Sets the maximum number of
230# certificates that can be used to certify this certificate.
231# (i.e. the certificate chain length)
232#path_len = -1
233#path_len = 2
234
235# OCSP URI
236# ocsp_uri = https://my.ocsp.server/ocsp
237
238# CA issuers URI
239# ca_issuers_uri = https://my.ca.issuer
240
241# Certificate policies
242#policy1 = 1.3.6.1.4.1.5484.1.10.99.1.0
243#policy1_txt = "This is a long policy to summarize"
244#policy1_url = https://www.example.com/a-policy-to-read
245
246#policy2 = 1.3.6.1.4.1.5484.1.10.99.1.1
247#policy2_txt = "This is a short policy"
248#policy2_url = https://www.example.com/another-policy-to-read
249
250# The number of additional certificates that may appear in a
251# path before the anyPolicy is no longer acceptable.
252#inhibit_anypolicy_skip_certs 1
253
254# Name constraints
255
256# DNS
257#nc_permit_dns = example.com
258#nc_exclude_dns = test.example.com
259
260# EMAIL
261#nc_permit_email = "nmav@ex.net"
262
263# Exclude subdomains of example.com
264#nc_exclude_email = .example.com
265
266# Exclude all e-mail addresses of example.com
267#nc_exclude_email = example.com
268
269# IP
270#nc_permit_ip = 192.168.0.0/16
271#nc_exclude_ip = 192.168.5.0/24
272#nc_permit_ip = fc0a:eef2:e7e7:a56e::/64
273
274
275# Options for proxy certificates
276#proxy_policy_language = 1.3.6.1.5.5.7.21.1
277
278
279# Options for generating a CRL
280
281# The number of days the next CRL update will be due.
282# next CRL update will be in 43 days
283#crl_next_update = 43
284
285# this is the 5th CRL by this CA
286# The value is in decimal (i.e. 1963) or hex (i.e. 0x07ab).
287# Comment the field for a time-based number.
288# Time-based CRL numbers generated in GnuTLS 3.6.3 and later
289# are significantly larger than those generated in previous
290# versions. Since CRL numbers need to be monotonic, you need
291# to specify the CRL number here manually if you intend to
292# downgrade to an earlier version than 3.6.3 after publishing
293# the CRL as it is not possible to specify CRL numbers greater
294# than 2**63-2 using hex notation in those versions.
295#crl_number = 5
296
297# Specify the update dates more precisely.
298#crl_this_update_date = "2004-02-29 16:21:42"
299#crl_next_update_date = "2025-02-29 16:24:41"
300
301# The date that the certificates will be made seen as
302# being revoked.
303#crl_revocation_date = "2025-02-29 16:24:41"
diff --git a/src/gns/gnunet-gns-proxy-setup-ca.in b/src/gns/gnunet-gns-proxy-setup-ca.in
index cd5d8c70f..b19b6c001 100644
--- a/src/gns/gnunet-gns-proxy-setup-ca.in
+++ b/src/gns/gnunet-gns-proxy-setup-ca.in
@@ -133,13 +133,29 @@ generate_ca()
133 133
134 # ------------- openssl 134 # ------------- openssl
135 135
136 GNUTLS_CA_TEMPLATE=@pkgdatadir@/gnunet-gns-proxy-ca.template
136 OPENSSLCFG=@pkgdatadir@/openssl.cnf 137 OPENSSLCFG=@pkgdatadir@/openssl.cnf
137 if test -z "`openssl version`" > /dev/null 138 CERTTOOL=""
139 OPENSSL=0
140 if test -z "`gnutls-certtool --version`" > /dev/null
138 then 141 then
139 warningmsg "'openssl' command not found. Please install it." 142 # We only support gnutls certtool for now
140 infomsg "Cleaning up." 143 if test -z "`certtool --version | grep gnutls`" > /dev/null
141 rm -f $GNSCAKY $GNSCANO $GNSCERT 144 then
142 exit 1 145 warningmsg "'gnutls-certtool' or 'certtool' command not found. Trying openssl."
146 if test -z "`openssl version`" > /dev/null
147 then
148 $OPENSSL=1
149 else
150 warningmsg "Install either gnutls certtool or openssl for certificate generation!"
151 infomsg "Cleaning up."
152 rm -f $GNSCAKY $GNSCERT
153 exit 1
154 fi
155 fi
156 CERTTOOL="certtool"
157 else
158 CERTTOOL="gnutls-certtool"
143 fi 159 fi
144 if [ -n "${GNUNET_CONFIG_FILE}" ]; then 160 if [ -n "${GNUNET_CONFIG_FILE}" ]; then
145 GNUNET_CONFIG="-c ${GNUNET_CONFIG_FILE}" 161 GNUNET_CONFIG="-c ${GNUNET_CONFIG_FILE}"
@@ -149,13 +165,18 @@ generate_ca()
149 GNS_CA_CERT_PEM=`gnunet-config ${GNUNET_CONFIG} -s gns-proxy -o PROXY_CACERT -f ${options}` 165 GNS_CA_CERT_PEM=`gnunet-config ${GNUNET_CONFIG} -s gns-proxy -o PROXY_CACERT -f ${options}`
150 mkdir -p `dirname $GNS_CA_CERT_PEM` 166 mkdir -p `dirname $GNS_CA_CERT_PEM`
151 167
152 openssl req -config $OPENSSLCFG -new -x509 -days 3650 -extensions v3_ca -keyout $GNSCAKY -out $GNSCERT -subj "/C=ZZ/L=World/O=GNU/OU=GNUnet/CN=GNS Proxy CA/emailAddress=bounce@gnunet.org" -passout pass:"GNU Name System" 168 if test 1 -eq $OPENSSL
153 169 then
154 infomsg "Removing passphrase from key" 170 openssl req -config $OPENSSLCFG -new -x509 -days 3650 -extensions v3_ca -keyout $GNSCAKY -out $GNSCERT -subj "/C=ZZ/L=World/O=GNU/OU=GNUnet/CN=GNS Proxy CA/emailAddress=bounce@gnunet.org" -passout pass:"GNU Name System"
155 openssl rsa -passin pass:"GNU Name System" -in $GNSCAKY -out $GNSCANO 171 infomsg "Removing passphrase from key"
156 172 openssl rsa -passin pass:"GNU Name System" -in $GNSCAKY -out $GNSCANO
157 infomsg "Making private key available to gnunet-gns-proxy" 173 cat $GNSCERT $GNSCANO > $GNS_CA_CERT_PEM
158 cat $GNSCERT $GNSCANO > $GNS_CA_CERT_PEM 174 else
175 $CERTTOOL --generate-privkey --outfile $GNSCAKY
176 $CERTTOOL --template $GNUTLS_CA_TEMPLATE --generate-self-signed --load-privkey $GNSCAKY --outfile $GNSCERT
177 infomsg "Making private key available to gnunet-gns-proxy"
178 cat $GNSCERT $GNSCAKY > $GNS_CA_CERT_PEM
179 fi
159} 180}
160 181
161importbrowsers() 182importbrowsers()
diff --git a/src/include/gnunet_common.h b/src/include/gnunet_common.h
index 0fca53b7f..66d0b8ac3 100644
--- a/src/include/gnunet_common.h
+++ b/src/include/gnunet_common.h
@@ -273,6 +273,18 @@ struct GNUNET_ShortHashCode
273 273
274 274
275/** 275/**
276 * A UUID, a 128 bit random value.
277 */
278struct GNUNET_Uuid
279{
280 /**
281 * 128 random bits.
282 */
283 uint32_t value[4];
284};
285
286
287/**
276 * Header for all communications. 288 * Header for all communications.
277 */ 289 */
278struct GNUNET_MessageHeader 290struct GNUNET_MessageHeader
@@ -495,7 +507,6 @@ GNUNET_log_from_nocheck (enum GNUNET_ErrorType kind,
495#define GNUNET_log_from(kind, comp, ...) \ 507#define GNUNET_log_from(kind, comp, ...) \
496 do \ 508 do \
497 { \ 509 { \
498 int log_line = __LINE__; \
499 static int log_call_enabled = GNUNET_LOG_CALL_STATUS; \ 510 static int log_call_enabled = GNUNET_LOG_CALL_STATUS; \
500 if ((GNUNET_EXTRA_LOGGING > 0) || \ 511 if ((GNUNET_EXTRA_LOGGING > 0) || \
501 ((GNUNET_ERROR_TYPE_DEBUG & (kind)) == 0)) \ 512 ((GNUNET_ERROR_TYPE_DEBUG & (kind)) == 0)) \
@@ -506,7 +517,7 @@ GNUNET_log_from_nocheck (enum GNUNET_ErrorType kind,
506 (comp), \ 517 (comp), \
507 __FILE__, \ 518 __FILE__, \
508 __FUNCTION__, \ 519 __FUNCTION__, \
509 log_line); \ 520 __LINE__); \
510 if (GN_UNLIKELY (GNUNET_get_log_skip () > 0)) \ 521 if (GN_UNLIKELY (GNUNET_get_log_skip () > 0)) \
511 { \ 522 { \
512 GNUNET_log_skip (-1, GNUNET_NO); \ 523 GNUNET_log_skip (-1, GNUNET_NO); \
@@ -522,7 +533,6 @@ GNUNET_log_from_nocheck (enum GNUNET_ErrorType kind,
522#define GNUNET_log(kind, ...) \ 533#define GNUNET_log(kind, ...) \
523 do \ 534 do \
524 { \ 535 { \
525 int log_line = __LINE__; \
526 static int log_call_enabled = GNUNET_LOG_CALL_STATUS; \ 536 static int log_call_enabled = GNUNET_LOG_CALL_STATUS; \
527 if ((GNUNET_EXTRA_LOGGING > 0) || \ 537 if ((GNUNET_EXTRA_LOGGING > 0) || \
528 ((GNUNET_ERROR_TYPE_DEBUG & (kind)) == 0)) \ 538 ((GNUNET_ERROR_TYPE_DEBUG & (kind)) == 0)) \
@@ -533,7 +543,7 @@ GNUNET_log_from_nocheck (enum GNUNET_ErrorType kind,
533 NULL, \ 543 NULL, \
534 __FILE__, \ 544 __FILE__, \
535 __FUNCTION__, \ 545 __FUNCTION__, \
536 log_line); \ 546 __LINE__); \
537 if (GN_UNLIKELY (GNUNET_get_log_skip () > 0)) \ 547 if (GN_UNLIKELY (GNUNET_get_log_skip () > 0)) \
538 { \ 548 { \
539 GNUNET_log_skip (-1, GNUNET_NO); \ 549 GNUNET_log_skip (-1, GNUNET_NO); \
@@ -655,6 +665,19 @@ GNUNET_sh2s (const struct GNUNET_ShortHashCode *shc);
655 665
656/** 666/**
657 * @ingroup logging 667 * @ingroup logging
668 * Convert a UUID to a string (for printing debug messages).
669 * This is one of the very few calls in the entire API that is
670 * NOT reentrant!
671 *
672 * @param uuid the UUID
673 * @return string
674 */
675const char *
676GNUNET_uuid2s (const struct GNUNET_Uuid *uuid);
677
678
679/**
680 * @ingroup logging
658 * Convert a hash value to a string (for printing debug messages). 681 * Convert a hash value to a string (for printing debug messages).
659 * This is one of the very few calls in the entire API that is 682 * This is one of the very few calls in the entire API that is
660 * NOT reentrant! 683 * NOT reentrant!
diff --git a/src/include/gnunet_container_lib.h b/src/include/gnunet_container_lib.h
index fee851e1c..fbfbf2d40 100644
--- a/src/include/gnunet_container_lib.h
+++ b/src/include/gnunet_container_lib.h
@@ -84,9 +84,7 @@ GNUNET_try_compression (const char *data,
84 * @return NULL on error, buffer of @a output_size decompressed bytes otherwise 84 * @return NULL on error, buffer of @a output_size decompressed bytes otherwise
85 */ 85 */
86char * 86char *
87GNUNET_decompress (const char *input, 87GNUNET_decompress (const char *input, size_t input_size, size_t output_size);
88 size_t input_size,
89 size_t output_size);
90 88
91 89
92#if HAVE_EXTRACTOR_H 90#if HAVE_EXTRACTOR_H
@@ -101,7 +99,8 @@ GNUNET_decompress (const char *input,
101 * Enumeration defining various sources of keywords. See also 99 * Enumeration defining various sources of keywords. See also
102 * http://dublincore.org/documents/1998/09/dces/ 100 * http://dublincore.org/documents/1998/09/dces/
103 */ 101 */
104enum EXTRACTOR_MetaType { 102enum EXTRACTOR_MetaType
103{
105 EXTRACTOR_METATYPE_RESERVED = 0, 104 EXTRACTOR_METATYPE_RESERVED = 0,
106 EXTRACTOR_METATYPE_MIMETYPE = 1, 105 EXTRACTOR_METATYPE_MIMETYPE = 1,
107 EXTRACTOR_METATYPE_FILENAME = 2, 106 EXTRACTOR_METATYPE_FILENAME = 2,
@@ -131,7 +130,8 @@ enum EXTRACTOR_MetaType {
131/** 130/**
132 * Format in which the extracted meta data is presented. 131 * Format in which the extracted meta data is presented.
133 */ 132 */
134enum EXTRACTOR_MetaFormat { 133enum EXTRACTOR_MetaFormat
134{
135 /** 135 /**
136 * Format is unknown. 136 * Format is unknown.
137 */ 137 */
@@ -173,14 +173,13 @@ enum EXTRACTOR_MetaFormat {
173 * @param data_len number of bytes in @a data 173 * @param data_len number of bytes in @a data
174 * @return 0 to continue extracting, 1 to abort 174 * @return 0 to continue extracting, 1 to abort
175 */ 175 */
176typedef int 176typedef int (*EXTRACTOR_MetaDataProcessor) (void *cls,
177(*EXTRACTOR_MetaDataProcessor) (void *cls, 177 const char *plugin_name,
178 const char *plugin_name, 178 enum EXTRACTOR_MetaType type,
179 enum EXTRACTOR_MetaType type, 179 enum EXTRACTOR_MetaFormat format,
180 enum EXTRACTOR_MetaFormat format, 180 const char *data_mime_type,
181 const char *data_mime_type, 181 const char *data,
182 const char *data, 182 size_t data_len);
183 size_t data_len);
184 183
185#endif 184#endif
186 185
@@ -190,9 +189,8 @@ typedef int
190#endif 189#endif
191 190
192#ifdef __cplusplus 191#ifdef __cplusplus
193extern "C" 192extern "C" {
194{ 193#if 0 /* keep Emacsens' auto-indent happy */
195#if 0 /* keep Emacsens' auto-indent happy */
196} 194}
197#endif 195#endif
198#endif 196#endif
@@ -216,9 +214,8 @@ struct GNUNET_CONTAINER_BloomFilter;
216 * @return #GNUNET_YES if next was updated 214 * @return #GNUNET_YES if next was updated
217 * #GNUNET_NO if there are no more entries 215 * #GNUNET_NO if there are no more entries
218 */ 216 */
219typedef int 217typedef int (*GNUNET_CONTAINER_HashCodeIterator) (void *cls,
220(*GNUNET_CONTAINER_HashCodeIterator) (void *cls, 218 struct GNUNET_HashCode *next);
221 struct GNUNET_HashCode *next);
222 219
223 220
224/** 221/**
@@ -269,9 +266,10 @@ GNUNET_CONTAINER_bloomfilter_init (const char *data,
269 * @return #GNUNET_SYSERR if the data array of the wrong size 266 * @return #GNUNET_SYSERR if the data array of the wrong size
270 */ 267 */
271int 268int
272GNUNET_CONTAINER_bloomfilter_get_raw_data (const struct GNUNET_CONTAINER_BloomFilter *bf, 269GNUNET_CONTAINER_bloomfilter_get_raw_data (
273 char *data, 270 const struct GNUNET_CONTAINER_BloomFilter *bf,
274 size_t size); 271 char *data,
272 size_t size);
275 273
276 274
277/** 275/**
@@ -283,8 +281,9 @@ GNUNET_CONTAINER_bloomfilter_get_raw_data (const struct GNUNET_CONTAINER_BloomFi
283 * @return #GNUNET_YES if the element is in the filter, #GNUNET_NO if not 281 * @return #GNUNET_YES if the element is in the filter, #GNUNET_NO if not
284 */ 282 */
285int 283int
286GNUNET_CONTAINER_bloomfilter_test (const struct GNUNET_CONTAINER_BloomFilter *bf, 284GNUNET_CONTAINER_bloomfilter_test (
287 const struct GNUNET_HashCode *e); 285 const struct GNUNET_CONTAINER_BloomFilter *bf,
286 const struct GNUNET_HashCode *e);
288 287
289 288
290/** 289/**
@@ -319,8 +318,8 @@ GNUNET_CONTAINER_bloomfilter_remove (struct GNUNET_CONTAINER_BloomFilter *bf,
319 * @return copy of bf 318 * @return copy of bf
320 */ 319 */
321struct GNUNET_CONTAINER_BloomFilter * 320struct GNUNET_CONTAINER_BloomFilter *
322GNUNET_CONTAINER_bloomfilter_copy (const struct GNUNET_CONTAINER_BloomFilter *bf); 321GNUNET_CONTAINER_bloomfilter_copy (
323 322 const struct GNUNET_CONTAINER_BloomFilter *bf);
324 323
325 324
326/** 325/**
@@ -342,7 +341,8 @@ GNUNET_CONTAINER_bloomfilter_free (struct GNUNET_CONTAINER_BloomFilter *bf);
342 * @return addresses set per element in the bf 341 * @return addresses set per element in the bf
343 */ 342 */
344size_t 343size_t
345GNUNET_CONTAINER_bloomfilter_get_element_addresses (const struct GNUNET_CONTAINER_BloomFilter *bf); 344GNUNET_CONTAINER_bloomfilter_get_element_addresses (
345 const struct GNUNET_CONTAINER_BloomFilter *bf);
346 346
347 347
348/** 348/**
@@ -353,7 +353,8 @@ GNUNET_CONTAINER_bloomfilter_get_element_addresses (const struct GNUNET_CONTAINE
353 * @return number of bytes used for the data of the bloom filter 353 * @return number of bytes used for the data of the bloom filter
354 */ 354 */
355size_t 355size_t
356GNUNET_CONTAINER_bloomfilter_get_size (const struct GNUNET_CONTAINER_BloomFilter *bf); 356GNUNET_CONTAINER_bloomfilter_get_size (
357 const struct GNUNET_CONTAINER_BloomFilter *bf);
357 358
358 359
359/** 360/**
@@ -380,7 +381,8 @@ GNUNET_CONTAINER_bloomfilter_clear (struct GNUNET_CONTAINER_BloomFilter *bf);
380 */ 381 */
381int 382int
382GNUNET_CONTAINER_bloomfilter_or (struct GNUNET_CONTAINER_BloomFilter *bf, 383GNUNET_CONTAINER_bloomfilter_or (struct GNUNET_CONTAINER_BloomFilter *bf,
383 const char *data, size_t size); 384 const char *data,
385 size_t size);
384 386
385 387
386/** 388/**
@@ -394,8 +396,9 @@ GNUNET_CONTAINER_bloomfilter_or (struct GNUNET_CONTAINER_BloomFilter *bf,
394 * @return #GNUNET_OK on success 396 * @return #GNUNET_OK on success
395 */ 397 */
396int 398int
397GNUNET_CONTAINER_bloomfilter_or2 (struct GNUNET_CONTAINER_BloomFilter *bf, 399GNUNET_CONTAINER_bloomfilter_or2 (
398 const struct GNUNET_CONTAINER_BloomFilter *to_or); 400 struct GNUNET_CONTAINER_BloomFilter *bf,
401 const struct GNUNET_CONTAINER_BloomFilter *to_or);
399 402
400 403
401/** 404/**
@@ -445,7 +448,8 @@ GNUNET_CONTAINER_meta_data_create (void);
445 * @return duplicate meta-data container 448 * @return duplicate meta-data container
446 */ 449 */
447struct GNUNET_CONTAINER_MetaData * 450struct GNUNET_CONTAINER_MetaData *
448GNUNET_CONTAINER_meta_data_duplicate (const struct GNUNET_CONTAINER_MetaData *md); 451GNUNET_CONTAINER_meta_data_duplicate (
452 const struct GNUNET_CONTAINER_MetaData *md);
449 453
450 454
451/** 455/**
@@ -470,8 +474,9 @@ GNUNET_CONTAINER_meta_data_destroy (struct GNUNET_CONTAINER_MetaData *md);
470 * @return #GNUNET_YES if they are equal 474 * @return #GNUNET_YES if they are equal
471 */ 475 */
472int 476int
473GNUNET_CONTAINER_meta_data_test_equal (const struct GNUNET_CONTAINER_MetaData *md1, 477GNUNET_CONTAINER_meta_data_test_equal (
474 const struct GNUNET_CONTAINER_MetaData *md2); 478 const struct GNUNET_CONTAINER_MetaData *md1,
479 const struct GNUNET_CONTAINER_MetaData *md2);
475 480
476 481
477/** 482/**
@@ -551,7 +556,8 @@ GNUNET_CONTAINER_meta_data_clear (struct GNUNET_CONTAINER_MetaData *md);
551 * @param md metadata to modify 556 * @param md metadata to modify
552 */ 557 */
553void 558void
554GNUNET_CONTAINER_meta_data_add_publication_date (struct GNUNET_CONTAINER_MetaData *md); 559GNUNET_CONTAINER_meta_data_add_publication_date (
560 struct GNUNET_CONTAINER_MetaData *md);
555 561
556 562
557/** 563/**
@@ -582,8 +588,9 @@ GNUNET_CONTAINER_meta_data_iterate (const struct GNUNET_CONTAINER_MetaData *md,
582 * @return NULL if no entry was found 588 * @return NULL if no entry was found
583 */ 589 */
584char * 590char *
585GNUNET_CONTAINER_meta_data_get_by_type (const struct GNUNET_CONTAINER_MetaData *md, 591GNUNET_CONTAINER_meta_data_get_by_type (
586 enum EXTRACTOR_MetaType type); 592 const struct GNUNET_CONTAINER_MetaData *md,
593 enum EXTRACTOR_MetaType type);
587 594
588 595
589/** 596/**
@@ -599,8 +606,9 @@ GNUNET_CONTAINER_meta_data_get_by_type (const struct GNUNET_CONTAINER_MetaData *
599 * otherwise client is responsible for freeing the value! 606 * otherwise client is responsible for freeing the value!
600 */ 607 */
601char * 608char *
602GNUNET_CONTAINER_meta_data_get_first_by_types (const struct GNUNET_CONTAINER_MetaData *md, 609GNUNET_CONTAINER_meta_data_get_first_by_types (
603 ...); 610 const struct GNUNET_CONTAINER_MetaData *md,
611 ...);
604 612
605/** 613/**
606 * @ingroup metadata 614 * @ingroup metadata
@@ -613,9 +621,9 @@ GNUNET_CONTAINER_meta_data_get_first_by_types (const struct GNUNET_CONTAINER_Met
613 * @return number of bytes in thumbnail, 0 if not available 621 * @return number of bytes in thumbnail, 0 if not available
614 */ 622 */
615size_t 623size_t
616GNUNET_CONTAINER_meta_data_get_thumbnail (const struct GNUNET_CONTAINER_MetaData *md, 624GNUNET_CONTAINER_meta_data_get_thumbnail (
617 unsigned char **thumb); 625 const struct GNUNET_CONTAINER_MetaData *md,
618 626 unsigned char **thumb);
619 627
620 628
621/** 629/**
@@ -661,10 +669,11 @@ enum GNUNET_CONTAINER_MetaDataSerializationOptions
661 * space) 669 * space)
662 */ 670 */
663ssize_t 671ssize_t
664GNUNET_CONTAINER_meta_data_serialize (const struct GNUNET_CONTAINER_MetaData *md, 672GNUNET_CONTAINER_meta_data_serialize (
665 char **target, 673 const struct GNUNET_CONTAINER_MetaData *md,
666 size_t max, 674 char **target,
667 enum GNUNET_CONTAINER_MetaDataSerializationOptions opt); 675 size_t max,
676 enum GNUNET_CONTAINER_MetaDataSerializationOptions opt);
668 677
669 678
670/** 679/**
@@ -675,7 +684,8 @@ GNUNET_CONTAINER_meta_data_serialize (const struct GNUNET_CONTAINER_MetaData *md
675 * @return number of bytes needed for serialization, -1 on error 684 * @return number of bytes needed for serialization, -1 on error
676 */ 685 */
677ssize_t 686ssize_t
678GNUNET_CONTAINER_meta_data_get_serialized_size (const struct GNUNET_CONTAINER_MetaData *md); 687GNUNET_CONTAINER_meta_data_get_serialized_size (
688 const struct GNUNET_CONTAINER_MetaData *md);
679 689
680 690
681/** 691/**
@@ -688,8 +698,7 @@ GNUNET_CONTAINER_meta_data_get_serialized_size (const struct GNUNET_CONTAINER_Me
688 * bad format) 698 * bad format)
689 */ 699 */
690struct GNUNET_CONTAINER_MetaData * 700struct GNUNET_CONTAINER_MetaData *
691GNUNET_CONTAINER_meta_data_deserialize (const char *input, 701GNUNET_CONTAINER_meta_data_deserialize (const char *input, size_t size);
692 size_t size);
693 702
694 703
695/* ******************************* HashMap **************************** */ 704/* ******************************* HashMap **************************** */
@@ -759,10 +768,10 @@ enum GNUNET_CONTAINER_MultiHashMapOption
759 * iterate, 768 * iterate,
760 * #GNUNET_NO if not. 769 * #GNUNET_NO if not.
761 */ 770 */
762typedef int 771typedef int (*GNUNET_CONTAINER_HashMapIterator) (
763(*GNUNET_CONTAINER_HashMapIterator) (void *cls, 772 void *cls,
764 const struct GNUNET_HashCode *key, 773 const struct GNUNET_HashCode *key,
765 void *value); 774 void *value);
766 775
767 776
768/** 777/**
@@ -782,8 +791,7 @@ typedef int
782 * @return NULL on error 791 * @return NULL on error
783 */ 792 */
784struct GNUNET_CONTAINER_MultiHashMap * 793struct GNUNET_CONTAINER_MultiHashMap *
785GNUNET_CONTAINER_multihashmap_create (unsigned int len, 794GNUNET_CONTAINER_multihashmap_create (unsigned int len, int do_not_copy_keys);
786 int do_not_copy_keys);
787 795
788 796
789/** 797/**
@@ -794,7 +802,8 @@ GNUNET_CONTAINER_multihashmap_create (unsigned int len,
794 * @param map the map 802 * @param map the map
795 */ 803 */
796void 804void
797GNUNET_CONTAINER_multihashmap_destroy (struct GNUNET_CONTAINER_MultiHashMap *map); 805GNUNET_CONTAINER_multihashmap_destroy (
806 struct GNUNET_CONTAINER_MultiHashMap *map);
798 807
799 808
800/** 809/**
@@ -809,8 +818,9 @@ GNUNET_CONTAINER_multihashmap_destroy (struct GNUNET_CONTAINER_MultiHashMap *map
809 * key-value pairs with value NULL 818 * key-value pairs with value NULL
810 */ 819 */
811void * 820void *
812GNUNET_CONTAINER_multihashmap_get (const struct GNUNET_CONTAINER_MultiHashMap *map, 821GNUNET_CONTAINER_multihashmap_get (
813 const struct GNUNET_HashCode *key); 822 const struct GNUNET_CONTAINER_MultiHashMap *map,
823 const struct GNUNET_HashCode *key);
814 824
815 825
816/** 826/**
@@ -828,7 +838,7 @@ GNUNET_CONTAINER_multihashmap_get (const struct GNUNET_CONTAINER_MultiHashMap *m
828int 838int
829GNUNET_CONTAINER_multihashmap_remove (struct GNUNET_CONTAINER_MultiHashMap *map, 839GNUNET_CONTAINER_multihashmap_remove (struct GNUNET_CONTAINER_MultiHashMap *map,
830 const struct GNUNET_HashCode *key, 840 const struct GNUNET_HashCode *key,
831 const void *value); 841 const void *value);
832 842
833/** 843/**
834 * @ingroup hashmap 844 * @ingroup hashmap
@@ -840,8 +850,9 @@ GNUNET_CONTAINER_multihashmap_remove (struct GNUNET_CONTAINER_MultiHashMap *map,
840 * @return number of values removed 850 * @return number of values removed
841 */ 851 */
842int 852int
843GNUNET_CONTAINER_multihashmap_remove_all (struct GNUNET_CONTAINER_MultiHashMap *map, 853GNUNET_CONTAINER_multihashmap_remove_all (
844 const struct GNUNET_HashCode *key); 854 struct GNUNET_CONTAINER_MultiHashMap *map,
855 const struct GNUNET_HashCode *key);
845 856
846 857
847/** 858/**
@@ -867,8 +878,9 @@ GNUNET_CONTAINER_multihashmap_clear (struct GNUNET_CONTAINER_MultiHashMap *map);
867 * #GNUNET_NO if not 878 * #GNUNET_NO if not
868 */ 879 */
869int 880int
870GNUNET_CONTAINER_multihashmap_contains (const struct GNUNET_CONTAINER_MultiHashMap *map, 881GNUNET_CONTAINER_multihashmap_contains (
871 const struct GNUNET_HashCode * key); 882 const struct GNUNET_CONTAINER_MultiHashMap *map,
883 const struct GNUNET_HashCode *key);
872 884
873 885
874/** 886/**
@@ -883,9 +895,10 @@ GNUNET_CONTAINER_multihashmap_contains (const struct GNUNET_CONTAINER_MultiHashM
883 * #GNUNET_NO if not 895 * #GNUNET_NO if not
884 */ 896 */
885int 897int
886GNUNET_CONTAINER_multihashmap_contains_value (const struct GNUNET_CONTAINER_MultiHashMap *map, 898GNUNET_CONTAINER_multihashmap_contains_value (
887 const struct GNUNET_HashCode *key, 899 const struct GNUNET_CONTAINER_MultiHashMap *map,
888 const void *value); 900 const struct GNUNET_HashCode *key,
901 const void *value);
889 902
890 903
891/** 904/**
@@ -902,11 +915,11 @@ GNUNET_CONTAINER_multihashmap_contains_value (const struct GNUNET_CONTAINER_Mult
902 * value already exists 915 * value already exists
903 */ 916 */
904int 917int
905GNUNET_CONTAINER_multihashmap_put (struct GNUNET_CONTAINER_MultiHashMap *map, 918GNUNET_CONTAINER_multihashmap_put (
906 const struct GNUNET_HashCode *key, 919 struct GNUNET_CONTAINER_MultiHashMap *map,
907 void *value, 920 const struct GNUNET_HashCode *key,
908 enum GNUNET_CONTAINER_MultiHashMapOption 921 void *value,
909 opt); 922 enum GNUNET_CONTAINER_MultiHashMapOption opt);
910 923
911/** 924/**
912 * @ingroup hashmap 925 * @ingroup hashmap
@@ -916,7 +929,8 @@ GNUNET_CONTAINER_multihashmap_put (struct GNUNET_CONTAINER_MultiHashMap *map,
916 * @return the number of key value pairs 929 * @return the number of key value pairs
917 */ 930 */
918unsigned int 931unsigned int
919GNUNET_CONTAINER_multihashmap_size (const struct GNUNET_CONTAINER_MultiHashMap *map); 932GNUNET_CONTAINER_multihashmap_size (
933 const struct GNUNET_CONTAINER_MultiHashMap *map);
920 934
921 935
922/** 936/**
@@ -930,9 +944,10 @@ GNUNET_CONTAINER_multihashmap_size (const struct GNUNET_CONTAINER_MultiHashMap *
930 * #GNUNET_SYSERR if it aborted iteration 944 * #GNUNET_SYSERR if it aborted iteration
931 */ 945 */
932int 946int
933GNUNET_CONTAINER_multihashmap_iterate (struct GNUNET_CONTAINER_MultiHashMap *map, 947GNUNET_CONTAINER_multihashmap_iterate (
934 GNUNET_CONTAINER_HashMapIterator it, 948 struct GNUNET_CONTAINER_MultiHashMap *map,
935 void *it_cls); 949 GNUNET_CONTAINER_HashMapIterator it,
950 void *it_cls);
936 951
937 952
938/** 953/**
@@ -949,7 +964,8 @@ GNUNET_CONTAINER_multihashmap_iterate (struct GNUNET_CONTAINER_MultiHashMap *map
949 * @return an iterator over the given multihashmap @a map 964 * @return an iterator over the given multihashmap @a map
950 */ 965 */
951struct GNUNET_CONTAINER_MultiHashMapIterator * 966struct GNUNET_CONTAINER_MultiHashMapIterator *
952GNUNET_CONTAINER_multihashmap_iterator_create (const struct GNUNET_CONTAINER_MultiHashMap *map); 967GNUNET_CONTAINER_multihashmap_iterator_create (
968 const struct GNUNET_CONTAINER_MultiHashMap *map);
953 969
954 970
955/** 971/**
@@ -968,9 +984,10 @@ GNUNET_CONTAINER_multihashmap_iterator_create (const struct GNUNET_CONTAINER_Mul
968 * #GNUNET_NO if we are out of elements 984 * #GNUNET_NO if we are out of elements
969 */ 985 */
970int 986int
971GNUNET_CONTAINER_multihashmap_iterator_next (struct GNUNET_CONTAINER_MultiHashMapIterator *iter, 987GNUNET_CONTAINER_multihashmap_iterator_next (
972 struct GNUNET_HashCode *key, 988 struct GNUNET_CONTAINER_MultiHashMapIterator *iter,
973 const void **value); 989 struct GNUNET_HashCode *key,
990 const void **value);
974 991
975 992
976/** 993/**
@@ -980,7 +997,8 @@ GNUNET_CONTAINER_multihashmap_iterator_next (struct GNUNET_CONTAINER_MultiHashMa
980 * @param iter the iterator to destroy 997 * @param iter the iterator to destroy
981 */ 998 */
982void 999void
983GNUNET_CONTAINER_multihashmap_iterator_destroy (struct GNUNET_CONTAINER_MultiHashMapIterator *iter); 1000GNUNET_CONTAINER_multihashmap_iterator_destroy (
1001 struct GNUNET_CONTAINER_MultiHashMapIterator *iter);
984 1002
985 1003
986/** 1004/**
@@ -995,10 +1013,11 @@ GNUNET_CONTAINER_multihashmap_iterator_destroy (struct GNUNET_CONTAINER_MultiHas
995 * #GNUNET_SYSERR if it aborted iteration 1013 * #GNUNET_SYSERR if it aborted iteration
996 */ 1014 */
997int 1015int
998GNUNET_CONTAINER_multihashmap_get_multiple (struct GNUNET_CONTAINER_MultiHashMap *map, 1016GNUNET_CONTAINER_multihashmap_get_multiple (
999 const struct GNUNET_HashCode *key, 1017 struct GNUNET_CONTAINER_MultiHashMap *map,
1000 GNUNET_CONTAINER_HashMapIterator it, 1018 const struct GNUNET_HashCode *key,
1001 void *it_cls); 1019 GNUNET_CONTAINER_HashMapIterator it,
1020 void *it_cls);
1002 1021
1003 1022
1004/** 1023/**
@@ -1013,9 +1032,10 @@ GNUNET_CONTAINER_multihashmap_get_multiple (struct GNUNET_CONTAINER_MultiHashMap
1013 * @return the number of key value pairs processed, zero or one. 1032 * @return the number of key value pairs processed, zero or one.
1014 */ 1033 */
1015unsigned int 1034unsigned int
1016GNUNET_CONTAINER_multihashmap_get_random (const struct GNUNET_CONTAINER_MultiHashMap *map, 1035GNUNET_CONTAINER_multihashmap_get_random (
1017 GNUNET_CONTAINER_HashMapIterator it, 1036 const struct GNUNET_CONTAINER_MultiHashMap *map,
1018 void *it_cls); 1037 GNUNET_CONTAINER_HashMapIterator it,
1038 void *it_cls);
1019 1039
1020 1040
1021/* ***************** Version of Multihashmap for peer identities ****************** */ 1041/* ***************** Version of Multihashmap for peer identities ****************** */
@@ -1031,10 +1051,10 @@ GNUNET_CONTAINER_multihashmap_get_random (const struct GNUNET_CONTAINER_MultiHas
1031 * iterate, 1051 * iterate,
1032 * #GNUNET_NO if not. 1052 * #GNUNET_NO if not.
1033 */ 1053 */
1034typedef int 1054typedef int (*GNUNET_CONTAINER_PeerMapIterator) (
1035(*GNUNET_CONTAINER_PeerMapIterator) (void *cls, 1055 void *cls,
1036 const struct GNUNET_PeerIdentity *key, 1056 const struct GNUNET_PeerIdentity *key,
1037 void *value); 1057 void *value);
1038 1058
1039 1059
1040/** 1060/**
@@ -1060,8 +1080,7 @@ struct GNUNET_CONTAINER_MultiPeerMap;
1060 * @return NULL on error 1080 * @return NULL on error
1061 */ 1081 */
1062struct GNUNET_CONTAINER_MultiPeerMap * 1082struct GNUNET_CONTAINER_MultiPeerMap *
1063GNUNET_CONTAINER_multipeermap_create (unsigned int len, 1083GNUNET_CONTAINER_multipeermap_create (unsigned int len, int do_not_copy_keys);
1064 int do_not_copy_keys);
1065 1084
1066 1085
1067/** 1086/**
@@ -1072,7 +1091,8 @@ GNUNET_CONTAINER_multipeermap_create (unsigned int len,
1072 * @param map the map 1091 * @param map the map
1073 */ 1092 */
1074void 1093void
1075GNUNET_CONTAINER_multipeermap_destroy (struct GNUNET_CONTAINER_MultiPeerMap *map); 1094GNUNET_CONTAINER_multipeermap_destroy (
1095 struct GNUNET_CONTAINER_MultiPeerMap *map);
1076 1096
1077 1097
1078/** 1098/**
@@ -1087,8 +1107,9 @@ GNUNET_CONTAINER_multipeermap_destroy (struct GNUNET_CONTAINER_MultiPeerMap *map
1087 * key-value pairs with value NULL 1107 * key-value pairs with value NULL
1088 */ 1108 */
1089void * 1109void *
1090GNUNET_CONTAINER_multipeermap_get (const struct GNUNET_CONTAINER_MultiPeerMap *map, 1110GNUNET_CONTAINER_multipeermap_get (
1091 const struct GNUNET_PeerIdentity *key); 1111 const struct GNUNET_CONTAINER_MultiPeerMap *map,
1112 const struct GNUNET_PeerIdentity *key);
1092 1113
1093 1114
1094/** 1115/**
@@ -1105,8 +1126,8 @@ GNUNET_CONTAINER_multipeermap_get (const struct GNUNET_CONTAINER_MultiPeerMap *m
1105 */ 1126 */
1106int 1127int
1107GNUNET_CONTAINER_multipeermap_remove (struct GNUNET_CONTAINER_MultiPeerMap *map, 1128GNUNET_CONTAINER_multipeermap_remove (struct GNUNET_CONTAINER_MultiPeerMap *map,
1108 const struct GNUNET_PeerIdentity * key, 1129 const struct GNUNET_PeerIdentity *key,
1109 const void *value); 1130 const void *value);
1110 1131
1111/** 1132/**
1112 * @ingroup hashmap 1133 * @ingroup hashmap
@@ -1118,8 +1139,9 @@ GNUNET_CONTAINER_multipeermap_remove (struct GNUNET_CONTAINER_MultiPeerMap *map,
1118 * @return number of values removed 1139 * @return number of values removed
1119 */ 1140 */
1120int 1141int
1121GNUNET_CONTAINER_multipeermap_remove_all (struct GNUNET_CONTAINER_MultiPeerMap *map, 1142GNUNET_CONTAINER_multipeermap_remove_all (
1122 const struct GNUNET_PeerIdentity *key); 1143 struct GNUNET_CONTAINER_MultiPeerMap *map,
1144 const struct GNUNET_PeerIdentity *key);
1123 1145
1124 1146
1125/** 1147/**
@@ -1133,8 +1155,9 @@ GNUNET_CONTAINER_multipeermap_remove_all (struct GNUNET_CONTAINER_MultiPeerMap *
1133 * #GNUNET_NO if not 1155 * #GNUNET_NO if not
1134 */ 1156 */
1135int 1157int
1136GNUNET_CONTAINER_multipeermap_contains (const struct GNUNET_CONTAINER_MultiPeerMap *map, 1158GNUNET_CONTAINER_multipeermap_contains (
1137 const struct GNUNET_PeerIdentity *key); 1159 const struct GNUNET_CONTAINER_MultiPeerMap *map,
1160 const struct GNUNET_PeerIdentity *key);
1138 1161
1139 1162
1140/** 1163/**
@@ -1149,9 +1172,10 @@ GNUNET_CONTAINER_multipeermap_contains (const struct GNUNET_CONTAINER_MultiPeerM
1149 * #GNUNET_NO if not 1172 * #GNUNET_NO if not
1150 */ 1173 */
1151int 1174int
1152GNUNET_CONTAINER_multipeermap_contains_value (const struct GNUNET_CONTAINER_MultiPeerMap *map, 1175GNUNET_CONTAINER_multipeermap_contains_value (
1153 const struct GNUNET_PeerIdentity * key, 1176 const struct GNUNET_CONTAINER_MultiPeerMap *map,
1154 const void *value); 1177 const struct GNUNET_PeerIdentity *key,
1178 const void *value);
1155 1179
1156 1180
1157/** 1181/**
@@ -1168,10 +1192,11 @@ GNUNET_CONTAINER_multipeermap_contains_value (const struct GNUNET_CONTAINER_Mult
1168 * value already exists 1192 * value already exists
1169 */ 1193 */
1170int 1194int
1171GNUNET_CONTAINER_multipeermap_put (struct GNUNET_CONTAINER_MultiPeerMap *map, 1195GNUNET_CONTAINER_multipeermap_put (
1172 const struct GNUNET_PeerIdentity *key, 1196 struct GNUNET_CONTAINER_MultiPeerMap *map,
1173 void *value, 1197 const struct GNUNET_PeerIdentity *key,
1174 enum GNUNET_CONTAINER_MultiHashMapOption opt); 1198 void *value,
1199 enum GNUNET_CONTAINER_MultiHashMapOption opt);
1175 1200
1176 1201
1177/** 1202/**
@@ -1182,7 +1207,8 @@ GNUNET_CONTAINER_multipeermap_put (struct GNUNET_CONTAINER_MultiPeerMap *map,
1182 * @return the number of key value pairs 1207 * @return the number of key value pairs
1183 */ 1208 */
1184unsigned int 1209unsigned int
1185GNUNET_CONTAINER_multipeermap_size (const struct GNUNET_CONTAINER_MultiPeerMap *map); 1210GNUNET_CONTAINER_multipeermap_size (
1211 const struct GNUNET_CONTAINER_MultiPeerMap *map);
1186 1212
1187 1213
1188/** 1214/**
@@ -1196,9 +1222,10 @@ GNUNET_CONTAINER_multipeermap_size (const struct GNUNET_CONTAINER_MultiPeerMap *
1196 * #GNUNET_SYSERR if it aborted iteration 1222 * #GNUNET_SYSERR if it aborted iteration
1197 */ 1223 */
1198int 1224int
1199GNUNET_CONTAINER_multipeermap_iterate (struct GNUNET_CONTAINER_MultiPeerMap *map, 1225GNUNET_CONTAINER_multipeermap_iterate (
1200 GNUNET_CONTAINER_PeerMapIterator it, 1226 struct GNUNET_CONTAINER_MultiPeerMap *map,
1201 void *it_cls); 1227 GNUNET_CONTAINER_PeerMapIterator it,
1228 void *it_cls);
1202 1229
1203 1230
1204struct GNUNET_CONTAINER_MultiPeerMapIterator; 1231struct GNUNET_CONTAINER_MultiPeerMapIterator;
@@ -1216,7 +1243,8 @@ struct GNUNET_CONTAINER_MultiPeerMapIterator;
1216 * @return an iterator over the given multihashmap @a map 1243 * @return an iterator over the given multihashmap @a map
1217 */ 1244 */
1218struct GNUNET_CONTAINER_MultiPeerMapIterator * 1245struct GNUNET_CONTAINER_MultiPeerMapIterator *
1219GNUNET_CONTAINER_multipeermap_iterator_create (const struct GNUNET_CONTAINER_MultiPeerMap *map); 1246GNUNET_CONTAINER_multipeermap_iterator_create (
1247 const struct GNUNET_CONTAINER_MultiPeerMap *map);
1220 1248
1221 1249
1222/** 1250/**
@@ -1235,9 +1263,10 @@ GNUNET_CONTAINER_multipeermap_iterator_create (const struct GNUNET_CONTAINER_Mul
1235 * #GNUNET_NO if we are out of elements 1263 * #GNUNET_NO if we are out of elements
1236 */ 1264 */
1237int 1265int
1238GNUNET_CONTAINER_multipeermap_iterator_next (struct GNUNET_CONTAINER_MultiPeerMapIterator *iter, 1266GNUNET_CONTAINER_multipeermap_iterator_next (
1239 struct GNUNET_PeerIdentity *key, 1267 struct GNUNET_CONTAINER_MultiPeerMapIterator *iter,
1240 const void **value); 1268 struct GNUNET_PeerIdentity *key,
1269 const void **value);
1241 1270
1242 1271
1243/** 1272/**
@@ -1247,7 +1276,8 @@ GNUNET_CONTAINER_multipeermap_iterator_next (struct GNUNET_CONTAINER_MultiPeerMa
1247 * @param iter the iterator to destroy 1276 * @param iter the iterator to destroy
1248 */ 1277 */
1249void 1278void
1250GNUNET_CONTAINER_multipeermap_iterator_destroy (struct GNUNET_CONTAINER_MultiPeerMapIterator *iter); 1279GNUNET_CONTAINER_multipeermap_iterator_destroy (
1280 struct GNUNET_CONTAINER_MultiPeerMapIterator *iter);
1251 1281
1252 1282
1253/** 1283/**
@@ -1262,10 +1292,11 @@ GNUNET_CONTAINER_multipeermap_iterator_destroy (struct GNUNET_CONTAINER_MultiPee
1262 * #GNUNET_SYSERR if it aborted iteration 1292 * #GNUNET_SYSERR if it aborted iteration
1263 */ 1293 */
1264int 1294int
1265GNUNET_CONTAINER_multipeermap_get_multiple (struct GNUNET_CONTAINER_MultiPeerMap *map, 1295GNUNET_CONTAINER_multipeermap_get_multiple (
1266 const struct GNUNET_PeerIdentity *key, 1296 struct GNUNET_CONTAINER_MultiPeerMap *map,
1267 GNUNET_CONTAINER_PeerMapIterator it, 1297 const struct GNUNET_PeerIdentity *key,
1268 void *it_cls); 1298 GNUNET_CONTAINER_PeerMapIterator it,
1299 void *it_cls);
1269 1300
1270 1301
1271/** 1302/**
@@ -1280,9 +1311,10 @@ GNUNET_CONTAINER_multipeermap_get_multiple (struct GNUNET_CONTAINER_MultiPeerMap
1280 * @return the number of key value pairs processed, zero or one. 1311 * @return the number of key value pairs processed, zero or one.
1281 */ 1312 */
1282unsigned int 1313unsigned int
1283GNUNET_CONTAINER_multipeermap_get_random (const struct GNUNET_CONTAINER_MultiPeerMap *map, 1314GNUNET_CONTAINER_multipeermap_get_random (
1284 GNUNET_CONTAINER_PeerMapIterator it, 1315 const struct GNUNET_CONTAINER_MultiPeerMap *map,
1285 void *it_cls); 1316 GNUNET_CONTAINER_PeerMapIterator it,
1317 void *it_cls);
1286 1318
1287 1319
1288/* ***************** Version of Multihashmap for short hashes ****************** */ 1320/* ***************** Version of Multihashmap for short hashes ****************** */
@@ -1298,10 +1330,10 @@ GNUNET_CONTAINER_multipeermap_get_random (const struct GNUNET_CONTAINER_MultiPee
1298 * iterate, 1330 * iterate,
1299 * #GNUNET_NO if not. 1331 * #GNUNET_NO if not.
1300 */ 1332 */
1301typedef int 1333typedef int (*GNUNET_CONTAINER_ShortmapIterator) (
1302(*GNUNET_CONTAINER_ShortmapIterator) (void *cls, 1334 void *cls,
1303 const struct GNUNET_ShortHashCode *key, 1335 const struct GNUNET_ShortHashCode *key,
1304 void *value); 1336 void *value);
1305 1337
1306 1338
1307/** 1339/**
@@ -1327,8 +1359,7 @@ struct GNUNET_CONTAINER_MultiShortmap;
1327 * @return NULL on error 1359 * @return NULL on error
1328 */ 1360 */
1329struct GNUNET_CONTAINER_MultiShortmap * 1361struct GNUNET_CONTAINER_MultiShortmap *
1330GNUNET_CONTAINER_multishortmap_create (unsigned int len, 1362GNUNET_CONTAINER_multishortmap_create (unsigned int len, int do_not_copy_keys);
1331 int do_not_copy_keys);
1332 1363
1333 1364
1334/** 1365/**
@@ -1339,7 +1370,8 @@ GNUNET_CONTAINER_multishortmap_create (unsigned int len,
1339 * @param map the map 1370 * @param map the map
1340 */ 1371 */
1341void 1372void
1342GNUNET_CONTAINER_multishortmap_destroy (struct GNUNET_CONTAINER_MultiShortmap *map); 1373GNUNET_CONTAINER_multishortmap_destroy (
1374 struct GNUNET_CONTAINER_MultiShortmap *map);
1343 1375
1344 1376
1345/** 1377/**
@@ -1354,8 +1386,9 @@ GNUNET_CONTAINER_multishortmap_destroy (struct GNUNET_CONTAINER_MultiShortmap *m
1354 * key-value pairs with value NULL 1386 * key-value pairs with value NULL
1355 */ 1387 */
1356void * 1388void *
1357GNUNET_CONTAINER_multishortmap_get (const struct GNUNET_CONTAINER_MultiShortmap *map, 1389GNUNET_CONTAINER_multishortmap_get (
1358 const struct GNUNET_ShortHashCode *key); 1390 const struct GNUNET_CONTAINER_MultiShortmap *map,
1391 const struct GNUNET_ShortHashCode *key);
1359 1392
1360 1393
1361/** 1394/**
@@ -1371,9 +1404,10 @@ GNUNET_CONTAINER_multishortmap_get (const struct GNUNET_CONTAINER_MultiShortmap
1371 * is not in the map 1404 * is not in the map
1372 */ 1405 */
1373int 1406int
1374GNUNET_CONTAINER_multishortmap_remove (struct GNUNET_CONTAINER_MultiShortmap *map, 1407GNUNET_CONTAINER_multishortmap_remove (
1375 const struct GNUNET_ShortHashCode * key, 1408 struct GNUNET_CONTAINER_MultiShortmap *map,
1376 const void *value); 1409 const struct GNUNET_ShortHashCode *key,
1410 const void *value);
1377 1411
1378/** 1412/**
1379 * @ingroup hashmap 1413 * @ingroup hashmap
@@ -1385,8 +1419,9 @@ GNUNET_CONTAINER_multishortmap_remove (struct GNUNET_CONTAINER_MultiShortmap *ma
1385 * @return number of values removed 1419 * @return number of values removed
1386 */ 1420 */
1387int 1421int
1388GNUNET_CONTAINER_multishortmap_remove_all (struct GNUNET_CONTAINER_MultiShortmap *map, 1422GNUNET_CONTAINER_multishortmap_remove_all (
1389 const struct GNUNET_ShortHashCode *key); 1423 struct GNUNET_CONTAINER_MultiShortmap *map,
1424 const struct GNUNET_ShortHashCode *key);
1390 1425
1391 1426
1392/** 1427/**
@@ -1400,8 +1435,9 @@ GNUNET_CONTAINER_multishortmap_remove_all (struct GNUNET_CONTAINER_MultiShortmap
1400 * #GNUNET_NO if not 1435 * #GNUNET_NO if not
1401 */ 1436 */
1402int 1437int
1403GNUNET_CONTAINER_multishortmap_contains (const struct GNUNET_CONTAINER_MultiShortmap *map, 1438GNUNET_CONTAINER_multishortmap_contains (
1404 const struct GNUNET_ShortHashCode *key); 1439 const struct GNUNET_CONTAINER_MultiShortmap *map,
1440 const struct GNUNET_ShortHashCode *key);
1405 1441
1406 1442
1407/** 1443/**
@@ -1416,9 +1452,10 @@ GNUNET_CONTAINER_multishortmap_contains (const struct GNUNET_CONTAINER_MultiShor
1416 * #GNUNET_NO if not 1452 * #GNUNET_NO if not
1417 */ 1453 */
1418int 1454int
1419GNUNET_CONTAINER_multishortmap_contains_value (const struct GNUNET_CONTAINER_MultiShortmap *map, 1455GNUNET_CONTAINER_multishortmap_contains_value (
1420 const struct GNUNET_ShortHashCode * key, 1456 const struct GNUNET_CONTAINER_MultiShortmap *map,
1421 const void *value); 1457 const struct GNUNET_ShortHashCode *key,
1458 const void *value);
1422 1459
1423 1460
1424/** 1461/**
@@ -1435,10 +1472,11 @@ GNUNET_CONTAINER_multishortmap_contains_value (const struct GNUNET_CONTAINER_Mul
1435 * value already exists 1472 * value already exists
1436 */ 1473 */
1437int 1474int
1438GNUNET_CONTAINER_multishortmap_put (struct GNUNET_CONTAINER_MultiShortmap *map, 1475GNUNET_CONTAINER_multishortmap_put (
1439 const struct GNUNET_ShortHashCode *key, 1476 struct GNUNET_CONTAINER_MultiShortmap *map,
1440 void *value, 1477 const struct GNUNET_ShortHashCode *key,
1441 enum GNUNET_CONTAINER_MultiHashMapOption opt); 1478 void *value,
1479 enum GNUNET_CONTAINER_MultiHashMapOption opt);
1442 1480
1443 1481
1444/** 1482/**
@@ -1449,7 +1487,8 @@ GNUNET_CONTAINER_multishortmap_put (struct GNUNET_CONTAINER_MultiShortmap *map,
1449 * @return the number of key value pairs 1487 * @return the number of key value pairs
1450 */ 1488 */
1451unsigned int 1489unsigned int
1452GNUNET_CONTAINER_multishortmap_size (const struct GNUNET_CONTAINER_MultiShortmap *map); 1490GNUNET_CONTAINER_multishortmap_size (
1491 const struct GNUNET_CONTAINER_MultiShortmap *map);
1453 1492
1454 1493
1455/** 1494/**
@@ -1463,9 +1502,10 @@ GNUNET_CONTAINER_multishortmap_size (const struct GNUNET_CONTAINER_MultiShortmap
1463 * #GNUNET_SYSERR if it aborted iteration 1502 * #GNUNET_SYSERR if it aborted iteration
1464 */ 1503 */
1465int 1504int
1466GNUNET_CONTAINER_multishortmap_iterate (struct GNUNET_CONTAINER_MultiShortmap *map, 1505GNUNET_CONTAINER_multishortmap_iterate (
1467 GNUNET_CONTAINER_ShortmapIterator it, 1506 struct GNUNET_CONTAINER_MultiShortmap *map,
1468 void *it_cls); 1507 GNUNET_CONTAINER_ShortmapIterator it,
1508 void *it_cls);
1469 1509
1470 1510
1471struct GNUNET_CONTAINER_MultiShortmapIterator; 1511struct GNUNET_CONTAINER_MultiShortmapIterator;
@@ -1485,7 +1525,8 @@ struct GNUNET_CONTAINER_MultiShortmapIterator;
1485 * @return an iterator over the given multihashmap @a map 1525 * @return an iterator over the given multihashmap @a map
1486 */ 1526 */
1487struct GNUNET_CONTAINER_MultiShortmapIterator * 1527struct GNUNET_CONTAINER_MultiShortmapIterator *
1488GNUNET_CONTAINER_multishortmap_iterator_create (const struct GNUNET_CONTAINER_MultiShortmap *map); 1528GNUNET_CONTAINER_multishortmap_iterator_create (
1529 const struct GNUNET_CONTAINER_MultiShortmap *map);
1489 1530
1490 1531
1491/** 1532/**
@@ -1504,9 +1545,10 @@ GNUNET_CONTAINER_multishortmap_iterator_create (const struct GNUNET_CONTAINER_Mu
1504 * #GNUNET_NO if we are out of elements 1545 * #GNUNET_NO if we are out of elements
1505 */ 1546 */
1506int 1547int
1507GNUNET_CONTAINER_multishortmap_iterator_next (struct GNUNET_CONTAINER_MultiShortmapIterator *iter, 1548GNUNET_CONTAINER_multishortmap_iterator_next (
1508 struct GNUNET_ShortHashCode *key, 1549 struct GNUNET_CONTAINER_MultiShortmapIterator *iter,
1509 const void **value); 1550 struct GNUNET_ShortHashCode *key,
1551 const void **value);
1510 1552
1511 1553
1512/** 1554/**
@@ -1516,7 +1558,8 @@ GNUNET_CONTAINER_multishortmap_iterator_next (struct GNUNET_CONTAINER_MultiShort
1516 * @param iter the iterator to destroy 1558 * @param iter the iterator to destroy
1517 */ 1559 */
1518void 1560void
1519GNUNET_CONTAINER_multishortmap_iterator_destroy (struct GNUNET_CONTAINER_MultiShortmapIterator *iter); 1561GNUNET_CONTAINER_multishortmap_iterator_destroy (
1562 struct GNUNET_CONTAINER_MultiShortmapIterator *iter);
1520 1563
1521 1564
1522/** 1565/**
@@ -1531,10 +1574,11 @@ GNUNET_CONTAINER_multishortmap_iterator_destroy (struct GNUNET_CONTAINER_MultiSh
1531 * #GNUNET_SYSERR if it aborted iteration 1574 * #GNUNET_SYSERR if it aborted iteration
1532 */ 1575 */
1533int 1576int
1534GNUNET_CONTAINER_multishortmap_get_multiple (struct GNUNET_CONTAINER_MultiShortmap *map, 1577GNUNET_CONTAINER_multishortmap_get_multiple (
1535 const struct GNUNET_ShortHashCode *key, 1578 struct GNUNET_CONTAINER_MultiShortmap *map,
1536 GNUNET_CONTAINER_ShortmapIterator it, 1579 const struct GNUNET_ShortHashCode *key,
1537 void *it_cls); 1580 GNUNET_CONTAINER_ShortmapIterator it,
1581 void *it_cls);
1538 1582
1539 1583
1540/** 1584/**
@@ -1549,9 +1593,292 @@ GNUNET_CONTAINER_multishortmap_get_multiple (struct GNUNET_CONTAINER_MultiShortm
1549 * @return the number of key value pairs processed, zero or one. 1593 * @return the number of key value pairs processed, zero or one.
1550 */ 1594 */
1551unsigned int 1595unsigned int
1552GNUNET_CONTAINER_multishortmap_get_random (const struct GNUNET_CONTAINER_MultiShortmap *map, 1596GNUNET_CONTAINER_multishortmap_get_random (
1553 GNUNET_CONTAINER_ShortmapIterator it, 1597 const struct GNUNET_CONTAINER_MultiShortmap *map,
1554 void *it_cls); 1598 GNUNET_CONTAINER_ShortmapIterator it,
1599 void *it_cls);
1600
1601
1602/* ***************** Version of Multihashmap for UUIDs ****************** */
1603
1604
1605/**
1606 * @ingroup hashmap
1607 * Iterator over uuid map entries.
1608 *
1609 * @param cls closure
1610 * @param key current public key
1611 * @param value value in the hash map
1612 * @return #GNUNET_YES if we should continue to
1613 * iterate,
1614 * #GNUNET_NO if not.
1615 */
1616typedef int (*GNUNET_CONTAINER_MultiUuidmapIterator) (
1617 void *cls,
1618 const struct GNUNET_Uuid *key,
1619 void *value);
1620
1621
1622/**
1623 * Hash map from peer identities to values.
1624 */
1625struct GNUNET_CONTAINER_MultiUuidmap;
1626
1627
1628/**
1629 * @ingroup hashmap
1630 * Create a multi peer map (hash map for public keys of peers).
1631 *
1632 * @param len initial size (map will grow as needed)
1633 * @param do_not_copy_keys #GNUNET_NO is always safe and should be used by default;
1634 * #GNUNET_YES means that on 'put', the 'key' does not have
1635 * to be copied as the destination of the pointer is
1636 * guaranteed to be life as long as the value is stored in
1637 * the hashmap. This can significantly reduce memory
1638 * consumption, but of course is also a recipie for
1639 * heap corruption if the assumption is not true. Only
1640 * use this if (1) memory use is important in this case and
1641 * (2) you have triple-checked that the invariant holds
1642 * @return NULL on error
1643 */
1644struct GNUNET_CONTAINER_MultiUuidmap *
1645GNUNET_CONTAINER_multiuuidmap_create (unsigned int len, int do_not_copy_keys);
1646
1647
1648/**
1649 * @ingroup hashmap
1650 * Destroy a hash map. Will not free any values
1651 * stored in the hash map!
1652 *
1653 * @param map the map
1654 */
1655void
1656GNUNET_CONTAINER_multiuuidmap_destroy (
1657 struct GNUNET_CONTAINER_MultiUuidmap *map);
1658
1659
1660/**
1661 * @ingroup hashmap
1662 * Given a key find a value in the map matching the key.
1663 *
1664 * @param map the map
1665 * @param key what to look for
1666 * @return NULL if no value was found; note that
1667 * this is indistinguishable from values that just
1668 * happen to be NULL; use "contains" to test for
1669 * key-value pairs with value NULL
1670 */
1671void *
1672GNUNET_CONTAINER_multiuuidmap_get (
1673 const struct GNUNET_CONTAINER_MultiUuidmap *map,
1674 const struct GNUNET_Uuid *key);
1675
1676
1677/**
1678 * @ingroup hashmap
1679 * Remove the given key-value pair from the map. Note that if the
1680 * key-value pair is in the map multiple times, only one of the pairs
1681 * will be removed.
1682 *
1683 * @param map the map
1684 * @param key key of the key-value pair
1685 * @param value value of the key-value pair
1686 * @return #GNUNET_YES on success, #GNUNET_NO if the key-value pair
1687 * is not in the map
1688 */
1689int
1690GNUNET_CONTAINER_multiuuidmap_remove (struct GNUNET_CONTAINER_MultiUuidmap *map,
1691 const struct GNUNET_Uuid *key,
1692 const void *value);
1693
1694/**
1695 * @ingroup hashmap
1696 * Remove all entries for the given key from the map.
1697 * Note that the values would not be "freed".
1698 *
1699 * @param map the map
1700 * @param key identifies values to be removed
1701 * @return number of values removed
1702 */
1703int
1704GNUNET_CONTAINER_multiuuidmap_remove_all (
1705 struct GNUNET_CONTAINER_MultiUuidmap *map,
1706 const struct GNUNET_Uuid *key);
1707
1708
1709/**
1710 * @ingroup hashmap
1711 * Check if the map contains any value under the given
1712 * key (including values that are NULL).
1713 *
1714 * @param map the map
1715 * @param key the key to test if a value exists for it
1716 * @return #GNUNET_YES if such a value exists,
1717 * #GNUNET_NO if not
1718 */
1719int
1720GNUNET_CONTAINER_multiuuidmap_contains (
1721 const struct GNUNET_CONTAINER_MultiUuidmap *map,
1722 const struct GNUNET_Uuid *key);
1723
1724
1725/**
1726 * @ingroup hashmap
1727 * Check if the map contains the given value under the given
1728 * key.
1729 *
1730 * @param map the map
1731 * @param key the key to test if a value exists for it
1732 * @param value value to test for
1733 * @return #GNUNET_YES if such a value exists,
1734 * #GNUNET_NO if not
1735 */
1736int
1737GNUNET_CONTAINER_multiuuidmap_contains_value (
1738 const struct GNUNET_CONTAINER_MultiUuidmap *map,
1739 const struct GNUNET_Uuid *key,
1740 const void *value);
1741
1742
1743/**
1744 * @ingroup hashmap
1745 * Store a key-value pair in the map.
1746 *
1747 * @param map the map
1748 * @param key key to use
1749 * @param value value to use
1750 * @param opt options for put
1751 * @return #GNUNET_OK on success,
1752 * #GNUNET_NO if a value was replaced (with REPLACE)
1753 * #GNUNET_SYSERR if #GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY was the option and the
1754 * value already exists
1755 */
1756int
1757GNUNET_CONTAINER_multiuuidmap_put (
1758 struct GNUNET_CONTAINER_MultiUuidmap *map,
1759 const struct GNUNET_Uuid *key,
1760 void *value,
1761 enum GNUNET_CONTAINER_MultiHashMapOption opt);
1762
1763
1764/**
1765 * @ingroup hashmap
1766 * Get the number of key-value pairs in the map.
1767 *
1768 * @param map the map
1769 * @return the number of key value pairs
1770 */
1771unsigned int
1772GNUNET_CONTAINER_multiuuidmap_size (
1773 const struct GNUNET_CONTAINER_MultiUuidmap *map);
1774
1775
1776/**
1777 * @ingroup hashmap
1778 * Iterate over all entries in the map.
1779 *
1780 * @param map the map
1781 * @param it function to call on each entry
1782 * @param it_cls extra argument to @a it
1783 * @return the number of key value pairs processed,
1784 * #GNUNET_SYSERR if it aborted iteration
1785 */
1786int
1787GNUNET_CONTAINER_multiuuidmap_iterate (
1788 struct GNUNET_CONTAINER_MultiUuidmap *map,
1789 GNUNET_CONTAINER_MultiUuidmapIterator it,
1790 void *it_cls);
1791
1792
1793struct GNUNET_CONTAINER_MultiUuidmapIterator;
1794
1795
1796/**
1797 * @ingroup hashmap
1798 * Create an iterator for a multihashmap.
1799 * The iterator can be used to retrieve all the elements in the multihashmap
1800 * one by one, without having to handle all elements at once (in contrast to
1801 * #GNUNET_CONTAINER_multiuuidmap_iterate). Note that the iterator can not be
1802 * used anymore if elements have been removed from @a map after the creation of
1803 * the iterator, or 'map' has been destroyed. Adding elements to @a map may
1804 * result in skipped or repeated elements.
1805 *
1806 * @param map the map to create an iterator for
1807 * @return an iterator over the given multihashmap @a map
1808 */
1809struct GNUNET_CONTAINER_MultiUuidmapIterator *
1810GNUNET_CONTAINER_multiuuidmap_iterator_create (
1811 const struct GNUNET_CONTAINER_MultiUuidmap *map);
1812
1813
1814/**
1815 * @ingroup hashmap
1816 * Retrieve the next element from the hash map at the iterator's
1817 * position. If there are no elements left, #GNUNET_NO is returned,
1818 * and @a key and @a value are not modified. This operation is only
1819 * allowed if no elements have been removed from the multihashmap
1820 * since the creation of @a iter, and the map has not been destroyed.
1821 * Adding elements may result in repeating or skipping elements.
1822 *
1823 * @param iter the iterator to get the next element from
1824 * @param key pointer to store the key in, can be NULL
1825 * @param value pointer to store the value in, can be NULL
1826 * @return #GNUNET_YES we returned an element,
1827 * #GNUNET_NO if we are out of elements
1828 */
1829int
1830GNUNET_CONTAINER_multiuuidmap_iterator_next (
1831 struct GNUNET_CONTAINER_MultiUuidmapIterator *iter,
1832 struct GNUNET_Uuid *key,
1833 const void **value);
1834
1835
1836/**
1837 * @ingroup hashmap
1838 * Destroy a multiuuidmap iterator.
1839 *
1840 * @param iter the iterator to destroy
1841 */
1842void
1843GNUNET_CONTAINER_multiuuidmap_iterator_destroy (
1844 struct GNUNET_CONTAINER_MultiUuidmapIterator *iter);
1845
1846
1847/**
1848 * @ingroup hashmap
1849 * Iterate over all entries in the map that match a particular key.
1850 *
1851 * @param map the map
1852 * @param key public key that the entries must correspond to
1853 * @param it function to call on each entry
1854 * @param it_cls extra argument to @a it
1855 * @return the number of key value pairs processed,
1856 * #GNUNET_SYSERR if it aborted iteration
1857 */
1858int
1859GNUNET_CONTAINER_multiuuidmap_get_multiple (
1860 struct GNUNET_CONTAINER_MultiUuidmap *map,
1861 const struct GNUNET_Uuid *key,
1862 GNUNET_CONTAINER_MultiUuidmapIterator it,
1863 void *it_cls);
1864
1865
1866/**
1867 * @ingroup hashmap
1868 * Call @a it on a random value from the map, or not at all
1869 * if the map is empty. Note that this function has linear
1870 * complexity (in the size of the map).
1871 *
1872 * @param map the map
1873 * @param it function to call on a random entry
1874 * @param it_cls extra argument to @a it
1875 * @return the number of key value pairs processed, zero or one.
1876 */
1877unsigned int
1878GNUNET_CONTAINER_multiuuidmap_get_random (
1879 const struct GNUNET_CONTAINER_MultiUuidmap *map,
1880 GNUNET_CONTAINER_MultiUuidmapIterator it,
1881 void *it_cls);
1555 1882
1556 1883
1557/* Version of multihashmap with 32 bit keys */ 1884/* Version of multihashmap with 32 bit keys */
@@ -1582,10 +1909,9 @@ struct GNUNET_CONTAINER_MultiHashMap32Iterator;
1582 * iterate, 1909 * iterate,
1583 * #GNUNET_NO if not. 1910 * #GNUNET_NO if not.
1584 */ 1911 */
1585typedef int 1912typedef int (*GNUNET_CONTAINER_HashMapIterator32) (void *cls,
1586(*GNUNET_CONTAINER_HashMapIterator32) (void *cls, 1913 uint32_t key,
1587 uint32_t key, 1914 void *value);
1588 void *value);
1589 1915
1590 1916
1591/** 1917/**
@@ -1607,7 +1933,8 @@ GNUNET_CONTAINER_multihashmap32_create (unsigned int len);
1607 * @param map the map 1933 * @param map the map
1608 */ 1934 */
1609void 1935void
1610GNUNET_CONTAINER_multihashmap32_destroy (struct GNUNET_CONTAINER_MultiHashMap32 *map); 1936GNUNET_CONTAINER_multihashmap32_destroy (
1937 struct GNUNET_CONTAINER_MultiHashMap32 *map);
1611 1938
1612 1939
1613/** 1940/**
@@ -1618,8 +1945,8 @@ GNUNET_CONTAINER_multihashmap32_destroy (struct GNUNET_CONTAINER_MultiHashMap32
1618 * @return the number of key value pairs 1945 * @return the number of key value pairs
1619 */ 1946 */
1620unsigned int 1947unsigned int
1621GNUNET_CONTAINER_multihashmap32_size (const struct 1948GNUNET_CONTAINER_multihashmap32_size (
1622 GNUNET_CONTAINER_MultiHashMap32 *map); 1949 const struct GNUNET_CONTAINER_MultiHashMap32 *map);
1623 1950
1624 1951
1625/** 1952/**
@@ -1634,9 +1961,9 @@ GNUNET_CONTAINER_multihashmap32_size (const struct
1634 * key-value pairs with value NULL 1961 * key-value pairs with value NULL
1635 */ 1962 */
1636void * 1963void *
1637GNUNET_CONTAINER_multihashmap32_get (const struct 1964GNUNET_CONTAINER_multihashmap32_get (
1638 GNUNET_CONTAINER_MultiHashMap32 *map, 1965 const struct GNUNET_CONTAINER_MultiHashMap32 *map,
1639 uint32_t key); 1966 uint32_t key);
1640 1967
1641 1968
1642/** 1969/**
@@ -1650,9 +1977,10 @@ GNUNET_CONTAINER_multihashmap32_get (const struct
1650 * #GNUNET_SYSERR if it aborted iteration 1977 * #GNUNET_SYSERR if it aborted iteration
1651 */ 1978 */
1652int 1979int
1653GNUNET_CONTAINER_multihashmap32_iterate (struct GNUNET_CONTAINER_MultiHashMap32 *map, 1980GNUNET_CONTAINER_multihashmap32_iterate (
1654 GNUNET_CONTAINER_HashMapIterator32 it, 1981 struct GNUNET_CONTAINER_MultiHashMap32 *map,
1655 void *it_cls); 1982 GNUNET_CONTAINER_HashMapIterator32 it,
1983 void *it_cls);
1656 1984
1657 1985
1658/** 1986/**
@@ -1668,9 +1996,10 @@ GNUNET_CONTAINER_multihashmap32_iterate (struct GNUNET_CONTAINER_MultiHashMap32
1668 * is not in the map 1996 * is not in the map
1669 */ 1997 */
1670int 1998int
1671GNUNET_CONTAINER_multihashmap32_remove (struct GNUNET_CONTAINER_MultiHashMap32 *map, 1999GNUNET_CONTAINER_multihashmap32_remove (
1672 uint32_t key, 2000 struct GNUNET_CONTAINER_MultiHashMap32 *map,
1673 const void *value); 2001 uint32_t key,
2002 const void *value);
1674 2003
1675 2004
1676/** 2005/**
@@ -1683,8 +2012,9 @@ GNUNET_CONTAINER_multihashmap32_remove (struct GNUNET_CONTAINER_MultiHashMap32 *
1683 * @return number of values removed 2012 * @return number of values removed
1684 */ 2013 */
1685int 2014int
1686GNUNET_CONTAINER_multihashmap32_remove_all (struct GNUNET_CONTAINER_MultiHashMap32 *map, 2015GNUNET_CONTAINER_multihashmap32_remove_all (
1687 uint32_t key); 2016 struct GNUNET_CONTAINER_MultiHashMap32 *map,
2017 uint32_t key);
1688 2018
1689 2019
1690/** 2020/**
@@ -1698,8 +2028,9 @@ GNUNET_CONTAINER_multihashmap32_remove_all (struct GNUNET_CONTAINER_MultiHashMap
1698 * #GNUNET_NO if not 2028 * #GNUNET_NO if not
1699 */ 2029 */
1700int 2030int
1701GNUNET_CONTAINER_multihashmap32_contains (const struct GNUNET_CONTAINER_MultiHashMap32 *map, 2031GNUNET_CONTAINER_multihashmap32_contains (
1702 uint32_t key); 2032 const struct GNUNET_CONTAINER_MultiHashMap32 *map,
2033 uint32_t key);
1703 2034
1704 2035
1705/** 2036/**
@@ -1714,9 +2045,10 @@ GNUNET_CONTAINER_multihashmap32_contains (const struct GNUNET_CONTAINER_MultiHas
1714 * #GNUNET_NO if not 2045 * #GNUNET_NO if not
1715 */ 2046 */
1716int 2047int
1717GNUNET_CONTAINER_multihashmap32_contains_value (const struct GNUNET_CONTAINER_MultiHashMap32 *map, 2048GNUNET_CONTAINER_multihashmap32_contains_value (
1718 uint32_t key, 2049 const struct GNUNET_CONTAINER_MultiHashMap32 *map,
1719 const void *value); 2050 uint32_t key,
2051 const void *value);
1720 2052
1721 2053
1722/** 2054/**
@@ -1733,10 +2065,11 @@ GNUNET_CONTAINER_multihashmap32_contains_value (const struct GNUNET_CONTAINER_Mu
1733 * value already exists 2065 * value already exists
1734 */ 2066 */
1735int 2067int
1736GNUNET_CONTAINER_multihashmap32_put (struct GNUNET_CONTAINER_MultiHashMap32 *map, 2068GNUNET_CONTAINER_multihashmap32_put (
1737 uint32_t key, 2069 struct GNUNET_CONTAINER_MultiHashMap32 *map,
1738 void *value, 2070 uint32_t key,
1739 enum GNUNET_CONTAINER_MultiHashMapOption opt); 2071 void *value,
2072 enum GNUNET_CONTAINER_MultiHashMapOption opt);
1740 2073
1741 2074
1742/** 2075/**
@@ -1751,10 +2084,11 @@ GNUNET_CONTAINER_multihashmap32_put (struct GNUNET_CONTAINER_MultiHashMap32 *map
1751 * #GNUNET_SYSERR if it aborted iteration 2084 * #GNUNET_SYSERR if it aborted iteration
1752 */ 2085 */
1753int 2086int
1754GNUNET_CONTAINER_multihashmap32_get_multiple (struct GNUNET_CONTAINER_MultiHashMap32 *map, 2087GNUNET_CONTAINER_multihashmap32_get_multiple (
1755 uint32_t key, 2088 struct GNUNET_CONTAINER_MultiHashMap32 *map,
1756 GNUNET_CONTAINER_HashMapIterator32 it, 2089 uint32_t key,
1757 void *it_cls); 2090 GNUNET_CONTAINER_HashMapIterator32 it,
2091 void *it_cls);
1758 2092
1759 2093
1760/** 2094/**
@@ -1770,7 +2104,8 @@ GNUNET_CONTAINER_multihashmap32_get_multiple (struct GNUNET_CONTAINER_MultiHashM
1770 * @return an iterator over the given multihashmap map 2104 * @return an iterator over the given multihashmap map
1771 */ 2105 */
1772struct GNUNET_CONTAINER_MultiHashMap32Iterator * 2106struct GNUNET_CONTAINER_MultiHashMap32Iterator *
1773GNUNET_CONTAINER_multihashmap32_iterator_create (const struct GNUNET_CONTAINER_MultiHashMap32 *map); 2107GNUNET_CONTAINER_multihashmap32_iterator_create (
2108 const struct GNUNET_CONTAINER_MultiHashMap32 *map);
1774 2109
1775 2110
1776/** 2111/**
@@ -1788,9 +2123,10 @@ GNUNET_CONTAINER_multihashmap32_iterator_create (const struct GNUNET_CONTAINER_M
1788 * #GNUNET_NO if we are out of elements 2123 * #GNUNET_NO if we are out of elements
1789 */ 2124 */
1790int 2125int
1791GNUNET_CONTAINER_multihashmap32_iterator_next (struct GNUNET_CONTAINER_MultiHashMap32Iterator *iter, 2126GNUNET_CONTAINER_multihashmap32_iterator_next (
1792 uint32_t *key, 2127 struct GNUNET_CONTAINER_MultiHashMap32Iterator *iter,
1793 const void **value); 2128 uint32_t *key,
2129 const void **value);
1794 2130
1795 2131
1796/** 2132/**
@@ -1799,7 +2135,8 @@ GNUNET_CONTAINER_multihashmap32_iterator_next (struct GNUNET_CONTAINER_MultiHash
1799 * @param iter the iterator to destroy 2135 * @param iter the iterator to destroy
1800 */ 2136 */
1801void 2137void
1802GNUNET_CONTAINER_multihashmap32_iterator_destroy (struct GNUNET_CONTAINER_MultiHashMapIterator *iter); 2138GNUNET_CONTAINER_multihashmap32_iterator_destroy (
2139 struct GNUNET_CONTAINER_MultiHashMapIterator *iter);
1803 2140
1804 2141
1805/* ******************** doubly-linked list *************** */ 2142/* ******************** doubly-linked list *************** */
@@ -1814,16 +2151,19 @@ GNUNET_CONTAINER_multihashmap32_iterator_destroy (struct GNUNET_CONTAINER_MultiH
1814 * @param tail pointer to the tail of the DLL 2151 * @param tail pointer to the tail of the DLL
1815 * @param element element to insert 2152 * @param element element to insert
1816 */ 2153 */
1817#define GNUNET_CONTAINER_DLL_insert(head,tail,element) do { \ 2154#define GNUNET_CONTAINER_DLL_insert(head, tail, element) \
1818 GNUNET_assert ( ( (element)->prev == NULL) && ((head) != (element))); \ 2155 do \
1819 GNUNET_assert ( ( (element)->next == NULL) && ((tail) != (element))); \ 2156 { \
1820 (element)->next = (head); \ 2157 GNUNET_assert (((element)->prev == NULL) && ((head) != (element))); \
1821 (element)->prev = NULL; \ 2158 GNUNET_assert (((element)->next == NULL) && ((tail) != (element))); \
1822 if ((tail) == NULL) \ 2159 (element)->next = (head); \
1823 (tail) = element; \ 2160 (element)->prev = NULL; \
1824 else \ 2161 if ((tail) == NULL) \
1825 (head)->prev = element; \ 2162 (tail) = element; \
1826 (head) = (element); } while (0) 2163 else \
2164 (head)->prev = element; \
2165 (head) = (element); \
2166 } while (0)
1827 2167
1828 2168
1829/** 2169/**
@@ -1835,16 +2175,19 @@ GNUNET_CONTAINER_multihashmap32_iterator_destroy (struct GNUNET_CONTAINER_MultiH
1835 * @param tail pointer to the tail of the DLL 2175 * @param tail pointer to the tail of the DLL
1836 * @param element element to insert 2176 * @param element element to insert
1837 */ 2177 */
1838#define GNUNET_CONTAINER_DLL_insert_tail(head,tail,element) do { \ 2178#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element) \
1839 GNUNET_assert ( ( (element)->prev == NULL) && ((head) != (element))); \ 2179 do \
1840 GNUNET_assert ( ( (element)->next == NULL) && ((tail) != (element))); \ 2180 { \
1841 (element)->prev = (tail); \ 2181 GNUNET_assert (((element)->prev == NULL) && ((head) != (element))); \
1842 (element)->next = NULL; \ 2182 GNUNET_assert (((element)->next == NULL) && ((tail) != (element))); \
1843 if ((head) == NULL) \ 2183 (element)->prev = (tail); \
1844 (head) = element; \ 2184 (element)->next = NULL; \
1845 else \ 2185 if ((head) == NULL) \
1846 (tail)->next = element; \ 2186 (head) = element; \
1847 (tail) = (element); } while (0) 2187 else \
2188 (tail)->next = element; \
2189 (tail) = (element); \
2190 } while (0)
1848 2191
1849 2192
1850/** 2193/**
@@ -1857,24 +2200,27 @@ GNUNET_CONTAINER_multihashmap32_iterator_destroy (struct GNUNET_CONTAINER_MultiH
1857 * @param other prior element, NULL for insertion at head of DLL 2200 * @param other prior element, NULL for insertion at head of DLL
1858 * @param element element to insert 2201 * @param element element to insert
1859 */ 2202 */
1860#define GNUNET_CONTAINER_DLL_insert_after(head,tail,other,element) do { \ 2203#define GNUNET_CONTAINER_DLL_insert_after(head, tail, other, element) \
1861 GNUNET_assert ( ( (element)->prev == NULL) && ((head) != (element))); \ 2204 do \
1862 GNUNET_assert ( ( (element)->next == NULL) && ((tail) != (element))); \ 2205 { \
1863 (element)->prev = (other); \ 2206 GNUNET_assert (((element)->prev == NULL) && ((head) != (element))); \
1864 if (NULL == other) \ 2207 GNUNET_assert (((element)->next == NULL) && ((tail) != (element))); \
1865 { \ 2208 (element)->prev = (other); \
1866 (element)->next = (head); \ 2209 if (NULL == other) \
1867 (head) = (element); \ 2210 { \
1868 } \ 2211 (element)->next = (head); \
1869 else \ 2212 (head) = (element); \
1870 { \ 2213 } \
1871 (element)->next = (other)->next; \ 2214 else \
1872 (other)->next = (element); \ 2215 { \
1873 } \ 2216 (element)->next = (other)->next; \
1874 if (NULL == (element)->next) \ 2217 (other)->next = (element); \
1875 (tail) = (element); \ 2218 } \
1876 else \ 2219 if (NULL == (element)->next) \
1877 (element)->next->prev = (element); } while (0) 2220 (tail) = (element); \
2221 else \
2222 (element)->next->prev = (element); \
2223 } while (0)
1878 2224
1879 2225
1880/** 2226/**
@@ -1887,24 +2233,27 @@ GNUNET_CONTAINER_multihashmap32_iterator_destroy (struct GNUNET_CONTAINER_MultiH
1887 * @param other prior element, NULL for insertion at head of DLL 2233 * @param other prior element, NULL for insertion at head of DLL
1888 * @param element element to insert 2234 * @param element element to insert
1889 */ 2235 */
1890#define GNUNET_CONTAINER_DLL_insert_before(head,tail,other,element) do { \ 2236#define GNUNET_CONTAINER_DLL_insert_before(head, tail, other, element) \
1891 GNUNET_assert ( ( (element)->prev == NULL) && ((head) != (element))); \ 2237 do \
1892 GNUNET_assert ( ( (element)->next == NULL) && ((tail) != (element))); \ 2238 { \
1893 (element)->next = (other); \ 2239 GNUNET_assert (((element)->prev == NULL) && ((head) != (element))); \
1894 if (NULL == other) \ 2240 GNUNET_assert (((element)->next == NULL) && ((tail) != (element))); \
1895 { \ 2241 (element)->next = (other); \
1896 (element)->prev = (tail); \ 2242 if (NULL == other) \
1897 (tail) = (element); \ 2243 { \
1898 } \ 2244 (element)->prev = (tail); \
1899 else \ 2245 (tail) = (element); \
1900 { \ 2246 } \
1901 (element)->prev = (other)->prev; \ 2247 else \
1902 (other)->prev = (element); \ 2248 { \
1903 } \ 2249 (element)->prev = (other)->prev; \
1904 if (NULL == (element)->prev) \ 2250 (other)->prev = (element); \
1905 (head) = (element); \ 2251 } \
1906 else \ 2252 if (NULL == (element)->prev) \
1907 (element)->prev->next = (element); } while (0) 2253 (head) = (element); \
2254 else \
2255 (element)->prev->next = (element); \
2256 } while (0)
1908 2257
1909 2258
1910/** 2259/**
@@ -1921,19 +2270,22 @@ GNUNET_CONTAINER_multihashmap32_iterator_destroy (struct GNUNET_CONTAINER_MultiH
1921 * @param tail pointer to the tail of the DLL 2270 * @param tail pointer to the tail of the DLL
1922 * @param element element to remove 2271 * @param element element to remove
1923 */ 2272 */
1924#define GNUNET_CONTAINER_DLL_remove(head,tail,element) do { \ 2273#define GNUNET_CONTAINER_DLL_remove(head, tail, element) \
1925 GNUNET_assert ( ( (element)->prev != NULL) || ((head) == (element))); \ 2274 do \
1926 GNUNET_assert ( ( (element)->next != NULL) || ((tail) == (element))); \ 2275 { \
1927 if ((element)->prev == NULL) \ 2276 GNUNET_assert (((element)->prev != NULL) || ((head) == (element))); \
1928 (head) = (element)->next; \ 2277 GNUNET_assert (((element)->next != NULL) || ((tail) == (element))); \
1929 else \ 2278 if ((element)->prev == NULL) \
1930 (element)->prev->next = (element)->next; \ 2279 (head) = (element)->next; \
1931 if ((element)->next == NULL) \ 2280 else \
1932 (tail) = (element)->prev; \ 2281 (element)->prev->next = (element)->next; \
1933 else \ 2282 if ((element)->next == NULL) \
1934 (element)->next->prev = (element)->prev; \ 2283 (tail) = (element)->prev; \
1935 (element)->next = NULL; \ 2284 else \
1936 (element)->prev = NULL; } while (0) 2285 (element)->next->prev = (element)->prev; \
2286 (element)->next = NULL; \
2287 (element)->prev = NULL; \
2288 } while (0)
1937 2289
1938 2290
1939/* ************ Multi-DLL interface, allows DLL elements to be 2291/* ************ Multi-DLL interface, allows DLL elements to be
@@ -1949,16 +2301,19 @@ GNUNET_CONTAINER_multihashmap32_iterator_destroy (struct GNUNET_CONTAINER_MultiH
1949 * @param tail pointer to the tail of the MDLL 2301 * @param tail pointer to the tail of the MDLL
1950 * @param element element to insert 2302 * @param element element to insert
1951 */ 2303 */
1952#define GNUNET_CONTAINER_MDLL_insert(mdll,head,tail,element) do { \ 2304#define GNUNET_CONTAINER_MDLL_insert(mdll, head, tail, element) \
1953 GNUNET_assert ( ( (element)->prev_##mdll == NULL) && ((head) != (element))); \ 2305 do \
1954 GNUNET_assert ( ( (element)->next_##mdll == NULL) && ((tail) != (element))); \ 2306 { \
1955 (element)->next_##mdll = (head); \ 2307 GNUNET_assert (((element)->prev_##mdll == NULL) && ((head) != (element))); \
1956 (element)->prev_##mdll = NULL; \ 2308 GNUNET_assert (((element)->next_##mdll == NULL) && ((tail) != (element))); \
1957 if ((tail) == NULL) \ 2309 (element)->next_##mdll = (head); \
1958 (tail) = element; \ 2310 (element)->prev_##mdll = NULL; \
1959 else \ 2311 if ((tail) == NULL) \
1960 (head)->prev_##mdll = element; \ 2312 (tail) = element; \
1961 (head) = (element); } while (0) 2313 else \
2314 (head)->prev_##mdll = element; \
2315 (head) = (element); \
2316 } while (0)
1962 2317
1963 2318
1964/** 2319/**
@@ -1971,16 +2326,19 @@ GNUNET_CONTAINER_multihashmap32_iterator_destroy (struct GNUNET_CONTAINER_MultiH
1971 * @param tail pointer to the tail of the MDLL 2326 * @param tail pointer to the tail of the MDLL
1972 * @param element element to insert 2327 * @param element element to insert
1973 */ 2328 */
1974#define GNUNET_CONTAINER_MDLL_insert_tail(mdll,head,tail,element) do { \ 2329#define GNUNET_CONTAINER_MDLL_insert_tail(mdll, head, tail, element) \
1975 GNUNET_assert ( ( (element)->prev_##mdll == NULL) && ((head) != (element))); \ 2330 do \
1976 GNUNET_assert ( ( (element)->next_##mdll == NULL) && ((tail) != (element))); \ 2331 { \
1977 (element)->prev_##mdll = (tail); \ 2332 GNUNET_assert (((element)->prev_##mdll == NULL) && ((head) != (element))); \
1978 (element)->next_##mdll = NULL; \ 2333 GNUNET_assert (((element)->next_##mdll == NULL) && ((tail) != (element))); \
1979 if ((head) == NULL) \ 2334 (element)->prev_##mdll = (tail); \
1980 (head) = element; \ 2335 (element)->next_##mdll = NULL; \
1981 else \ 2336 if ((head) == NULL) \
1982 (tail)->next_##mdll = element; \ 2337 (head) = element; \
1983 (tail) = (element); } while (0) 2338 else \
2339 (tail)->next_##mdll = element; \
2340 (tail) = (element); \
2341 } while (0)
1984 2342
1985 2343
1986/** 2344/**
@@ -1994,24 +2352,27 @@ GNUNET_CONTAINER_multihashmap32_iterator_destroy (struct GNUNET_CONTAINER_MultiH
1994 * @param other prior element, NULL for insertion at head of MDLL 2352 * @param other prior element, NULL for insertion at head of MDLL
1995 * @param element element to insert 2353 * @param element element to insert
1996 */ 2354 */
1997#define GNUNET_CONTAINER_MDLL_insert_after(mdll,head,tail,other,element) do { \ 2355#define GNUNET_CONTAINER_MDLL_insert_after(mdll, head, tail, other, element) \
1998 GNUNET_assert ( ( (element)->prev_##mdll == NULL) && ((head) != (element))); \ 2356 do \
1999 GNUNET_assert ( ( (element)->next_##mdll == NULL) && ((tail) != (element))); \ 2357 { \
2000 (element)->prev_##mdll = (other); \ 2358 GNUNET_assert (((element)->prev_##mdll == NULL) && ((head) != (element))); \
2001 if (NULL == other) \ 2359 GNUNET_assert (((element)->next_##mdll == NULL) && ((tail) != (element))); \
2002 { \ 2360 (element)->prev_##mdll = (other); \
2003 (element)->next_##mdll = (head); \ 2361 if (NULL == other) \
2004 (head) = (element); \ 2362 { \
2005 } \ 2363 (element)->next_##mdll = (head); \
2006 else \ 2364 (head) = (element); \
2007 { \ 2365 } \
2008 (element)->next_##mdll = (other)->next_##mdll; \ 2366 else \
2009 (other)->next_##mdll = (element); \ 2367 { \
2010 } \ 2368 (element)->next_##mdll = (other)->next_##mdll; \
2011 if (NULL == (element)->next_##mdll) \ 2369 (other)->next_##mdll = (element); \
2012 (tail) = (element); \ 2370 } \
2013 else \ 2371 if (NULL == (element)->next_##mdll) \
2014 (element)->next_##mdll->prev_##mdll = (element); } while (0) 2372 (tail) = (element); \
2373 else \
2374 (element)->next_##mdll->prev_##mdll = (element); \
2375 } while (0)
2015 2376
2016 2377
2017/** 2378/**
@@ -2025,24 +2386,27 @@ GNUNET_CONTAINER_multihashmap32_iterator_destroy (struct GNUNET_CONTAINER_MultiH
2025 * @param other prior element, NULL for insertion at head of MDLL 2386 * @param other prior element, NULL for insertion at head of MDLL
2026 * @param element element to insert 2387 * @param element element to insert
2027 */ 2388 */
2028#define GNUNET_CONTAINER_MDLL_insert_before(mdll,head,tail,other,element) do { \ 2389#define GNUNET_CONTAINER_MDLL_insert_before(mdll, head, tail, other, element) \
2029 GNUNET_assert ( ( (element)->prev_##mdll == NULL) && ((head) != (element))); \ 2390 do \
2030 GNUNET_assert ( ( (element)->next_##mdll == NULL) && ((tail) != (element))); \ 2391 { \
2031 (element)->next_##mdll = (other); \ 2392 GNUNET_assert (((element)->prev_##mdll == NULL) && ((head) != (element))); \
2032 if (NULL == other) \ 2393 GNUNET_assert (((element)->next_##mdll == NULL) && ((tail) != (element))); \
2033 { \ 2394 (element)->next_##mdll = (other); \
2034 (element)->prev = (tail); \ 2395 if (NULL == other) \
2035 (tail) = (element); \ 2396 { \
2036 } \ 2397 (element)->prev = (tail); \
2037 else \ 2398 (tail) = (element); \
2038 { \ 2399 } \
2039 (element)->prev_##mdll = (other)->prev_##mdll; \ 2400 else \
2040 (other)->prev_##mdll = (element); \ 2401 { \
2041 } \ 2402 (element)->prev_##mdll = (other)->prev_##mdll; \
2042 if (NULL == (element)->prev_##mdll) \ 2403 (other)->prev_##mdll = (element); \
2043 (head) = (element); \ 2404 } \
2044 else \ 2405 if (NULL == (element)->prev_##mdll) \
2045 (element)->prev_##mdll->next_##mdll = (element); } while (0) 2406 (head) = (element); \
2407 else \
2408 (element)->prev_##mdll->next_##mdll = (element); \
2409 } while (0)
2046 2410
2047 2411
2048/** 2412/**
@@ -2056,20 +2420,22 @@ GNUNET_CONTAINER_multihashmap32_iterator_destroy (struct GNUNET_CONTAINER_MultiH
2056 * @param tail pointer to the tail of the MDLL 2420 * @param tail pointer to the tail of the MDLL
2057 * @param element element to remove 2421 * @param element element to remove
2058 */ 2422 */
2059#define GNUNET_CONTAINER_MDLL_remove(mdll,head,tail,element) do { \ 2423#define GNUNET_CONTAINER_MDLL_remove(mdll, head, tail, element) \
2060 GNUNET_assert ( ( (element)->prev_##mdll != NULL) || ((head) == (element))); \ 2424 do \
2061 GNUNET_assert ( ( (element)->next_##mdll != NULL) || ((tail) == (element))); \ 2425 { \
2062 if ((element)->prev_##mdll == NULL) \ 2426 GNUNET_assert (((element)->prev_##mdll != NULL) || ((head) == (element))); \
2063 (head) = (element)->next_##mdll; \ 2427 GNUNET_assert (((element)->next_##mdll != NULL) || ((tail) == (element))); \
2064 else \ 2428 if ((element)->prev_##mdll == NULL) \
2065 (element)->prev_##mdll->next_##mdll = (element)->next_##mdll; \ 2429 (head) = (element)->next_##mdll; \
2066 if ((element)->next_##mdll == NULL) \ 2430 else \
2067 (tail) = (element)->prev_##mdll; \ 2431 (element)->prev_##mdll->next_##mdll = (element)->next_##mdll; \
2068 else \ 2432 if ((element)->next_##mdll == NULL) \
2069 (element)->next_##mdll->prev_##mdll = (element)->prev_##mdll; \ 2433 (tail) = (element)->prev_##mdll; \
2070 (element)->next_##mdll = NULL; \ 2434 else \
2071 (element)->prev_##mdll = NULL; } while (0) 2435 (element)->next_##mdll->prev_##mdll = (element)->prev_##mdll; \
2072 2436 (element)->next_##mdll = NULL; \
2437 (element)->prev_##mdll = NULL; \
2438 } while (0)
2073 2439
2074 2440
2075/** 2441/**
@@ -2085,44 +2451,36 @@ GNUNET_CONTAINER_multihashmap32_iterator_destroy (struct GNUNET_CONTAINER_MultiH
2085 * @param[in,out] tail tail of DLL 2451 * @param[in,out] tail tail of DLL
2086 * @param element element to insert 2452 * @param element element to insert
2087 */ 2453 */
2088#define GNUNET_CONTAINER_DLL_insert_sorted(TYPE,comparator,comparator_cls,head,tail,element) do { \ 2454#define GNUNET_CONTAINER_DLL_insert_sorted(TYPE, \
2089 if ( (NULL == head) || \ 2455 comparator, \
2090 (0 < comparator (comparator_cls, \ 2456 comparator_cls, \
2091 element, \ 2457 head, \
2092 head)) ) \ 2458 tail, \
2093 { \ 2459 element) \
2094 /* insert at head, element < head */ \ 2460 do \
2095 GNUNET_CONTAINER_DLL_insert (head, \ 2461 { \
2096 tail, \ 2462 if ((NULL == head) || (0 < comparator (comparator_cls, element, head))) \
2097 element); \ 2463 { \
2098 } \ 2464 /* insert at head, element < head */ \
2099 else \ 2465 GNUNET_CONTAINER_DLL_insert (head, tail, element); \
2100 { \ 2466 } \
2101 TYPE *pos; \ 2467 else \
2102 \ 2468 { \
2103 for (pos = head; \ 2469 TYPE *pos; \
2104 NULL != pos; \ 2470 \
2105 pos = pos->next) \ 2471 for (pos = head; NULL != pos; pos = pos->next) \
2106 if (0 < \ 2472 if (0 < comparator (comparator_cls, element, pos)) \
2107 comparator (comparator_cls, \ 2473 break; /* element < pos */ \
2108 element, \ 2474 if (NULL == pos) /* => element > tail */ \
2109 pos)) \ 2475 { \
2110 break; /* element < pos */ \ 2476 GNUNET_CONTAINER_DLL_insert_tail (head, tail, element); \
2111 if (NULL == pos) /* => element > tail */ \ 2477 } \
2112 { \ 2478 else /* prev < element < pos */ \
2113 GNUNET_CONTAINER_DLL_insert_tail (head, \ 2479 { \
2114 tail, \ 2480 GNUNET_CONTAINER_DLL_insert_after (head, tail, pos->prev, element); \
2115 element); \ 2481 } \
2116 } \ 2482 } \
2117 else /* prev < element < pos */ \ 2483 } while (0)
2118 { \
2119 GNUNET_CONTAINER_DLL_insert_after (head, \
2120 tail, \
2121 pos->prev, \
2122 element); \
2123 } \
2124 } \
2125} while (0)
2126 2484
2127 2485
2128/* ******************** Heap *************** */ 2486/* ******************** Heap *************** */
@@ -2236,7 +2594,8 @@ GNUNET_CONTAINER_heap_get_size (const struct GNUNET_CONTAINER_Heap *heap);
2236 * @return cost of the node 2594 * @return cost of the node
2237 */ 2595 */
2238GNUNET_CONTAINER_HeapCostType 2596GNUNET_CONTAINER_HeapCostType
2239GNUNET_CONTAINER_heap_node_get_cost (const struct GNUNET_CONTAINER_HeapNode *node); 2597GNUNET_CONTAINER_heap_node_get_cost (
2598 const struct GNUNET_CONTAINER_HeapNode *node);
2240 2599
2241 2600
2242/** 2601/**
@@ -2250,11 +2609,11 @@ GNUNET_CONTAINER_heap_node_get_cost (const struct GNUNET_CONTAINER_HeapNode *nod
2250 * @return #GNUNET_YES if we should continue to iterate, 2609 * @return #GNUNET_YES if we should continue to iterate,
2251 * #GNUNET_NO if not. 2610 * #GNUNET_NO if not.
2252 */ 2611 */
2253typedef int 2612typedef int (*GNUNET_CONTAINER_HeapIterator) (
2254(*GNUNET_CONTAINER_HeapIterator) (void *cls, 2613 void *cls,
2255 struct GNUNET_CONTAINER_HeapNode *node, 2614 struct GNUNET_CONTAINER_HeapNode *node,
2256 void *element, 2615 void *element,
2257 GNUNET_CONTAINER_HeapCostType cost); 2616 GNUNET_CONTAINER_HeapCostType cost);
2258 2617
2259 2618
2260/** 2619/**
@@ -2335,7 +2694,7 @@ GNUNET_CONTAINER_heap_update_cost (struct GNUNET_CONTAINER_HeapNode *node,
2335 GNUNET_CONTAINER_HeapCostType new_cost); 2694 GNUNET_CONTAINER_HeapCostType new_cost);
2336 2695
2337 2696
2338#if 0 /* keep Emacsens' auto-indent happy */ 2697#if 0 /* keep Emacsens' auto-indent happy */
2339{ 2698{
2340#endif 2699#endif
2341#ifdef __cplusplus 2700#ifdef __cplusplus
diff --git a/src/namestore/gnunet-service-namestore.c b/src/namestore/gnunet-service-namestore.c
index d2a09087e..4d23b91c6 100644
--- a/src/namestore/gnunet-service-namestore.c
+++ b/src/namestore/gnunet-service-namestore.c
@@ -23,12 +23,6 @@
23 * @brief namestore for the GNUnet naming system 23 * @brief namestore for the GNUnet naming system
24 * @author Matthias Wachs 24 * @author Matthias Wachs
25 * @author Christian Grothoff 25 * @author Christian Grothoff
26 *
27 * TODO:
28 * - "get_nick_record" is a bottleneck, introduce a cache to
29 * avoid looking it up again and again (for the same few
30 * zones that the user will typically manage!)
31 * - run testcases, make sure everything works!
32 */ 26 */
33#include "platform.h" 27#include "platform.h"
34#include "gnunet_util_lib.h" 28#include "gnunet_util_lib.h"
@@ -562,13 +556,20 @@ cache_nick (const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
562 } 556 }
563 GNUNET_free_non_null (oldest->rd); 557 GNUNET_free_non_null (oldest->rd);
564 oldest->zone = *zone; 558 oldest->zone = *zone;
565 oldest->rd = GNUNET_malloc (sizeof (*nick) + 559 if (NULL != nick)
566 nick->data_size); 560 {
567 *oldest->rd = *nick; 561 oldest->rd = GNUNET_malloc (sizeof (*nick) +
568 oldest->rd->data = &oldest->rd[1]; 562 nick->data_size);
569 memcpy (&oldest->rd[1], 563 *oldest->rd = *nick;
570 nick->data, 564 oldest->rd->data = &oldest->rd[1];
571 nick->data_size); 565 memcpy (&oldest->rd[1],
566 nick->data,
567 nick->data_size);
568 }
569 else
570 {
571 oldest->rd = NULL;
572 }
572 oldest->last_used = GNUNET_TIME_absolute_get (); 573 oldest->last_used = GNUNET_TIME_absolute_get ();
573} 574}
574 575
@@ -592,8 +593,10 @@ get_nick_record (const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone)
592 struct NickCache *pos = &nick_cache[i]; 593 struct NickCache *pos = &nick_cache[i];
593 if ( (NULL != pos->rd) && 594 if ( (NULL != pos->rd) &&
594 (0 == GNUNET_memcmp (zone, 595 (0 == GNUNET_memcmp (zone,
595 &pos->zone)) ) 596 &pos->zone)) )
596 { 597 {
598 if (NULL == pos->rd)
599 return NULL;
597 nick = GNUNET_malloc (sizeof (*nick) + 600 nick = GNUNET_malloc (sizeof (*nick) +
598 pos->rd->data_size); 601 pos->rd->data_size);
599 *nick = *pos->rd; 602 *nick = *pos->rd;
@@ -615,10 +618,25 @@ get_nick_record (const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone)
615 if ( (GNUNET_OK != res) || 618 if ( (GNUNET_OK != res) ||
616 (NULL == nick) ) 619 (NULL == nick) )
617 { 620 {
618 GNUNET_CRYPTO_ecdsa_key_get_public (zone, &pub); 621 static int do_log = GNUNET_LOG_CALL_STATUS;
619 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, 622
620 "No nick name set for zone `%s'\n", 623 if (0 == do_log)
621 GNUNET_GNSRECORD_z2s (&pub)); 624 do_log
625 = GNUNET_get_log_call_status (GNUNET_ERROR_TYPE_DEBUG,
626 "namestore",
627 __FILE__,
628 __FUNCTION__,
629 __LINE__);
630 if (1 == do_log)
631 {
632 GNUNET_CRYPTO_ecdsa_key_get_public (zone, &pub);
633 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
634 "No nick name set for zone `%s'\n",
635 GNUNET_GNSRECORD_z2s (&pub));
636 }
637 /* update cache */
638 cache_nick (zone,
639 NULL);
622 return NULL; 640 return NULL;
623 } 641 }
624 642
@@ -1603,8 +1621,10 @@ handle_record_store (void *cls,
1603 #GNUNET_GNS_EMPTY_LABEL_AT label */ 1621 #GNUNET_GNS_EMPTY_LABEL_AT label */
1604 struct GNUNET_GNSRECORD_Data rd_clean[GNUNET_NZL(rd_count)]; 1622 struct GNUNET_GNSRECORD_Data rd_clean[GNUNET_NZL(rd_count)];
1605 unsigned int rd_clean_off; 1623 unsigned int rd_clean_off;
1624 int have_nick;
1606 1625
1607 rd_clean_off = 0; 1626 rd_clean_off = 0;
1627 have_nick = GNUNET_NO;
1608 for (unsigned int i=0;i<rd_count;i++) 1628 for (unsigned int i=0;i<rd_count;i++)
1609 { 1629 {
1610 rd_clean[rd_clean_off] = rd[i]; 1630 rd_clean[rd_clean_off] = rd[i];
@@ -1616,8 +1636,19 @@ handle_record_store (void *cls,
1616 if ( (0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, 1636 if ( (0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT,
1617 conv_name)) && 1637 conv_name)) &&
1618 (GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type) ) 1638 (GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type) )
1639 {
1619 cache_nick (&rp_msg->private_key, 1640 cache_nick (&rp_msg->private_key,
1620 &rd[i]); 1641 &rd[i]);
1642 have_nick = GNUNET_YES;
1643 }
1644 }
1645 if ( (0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT,
1646 conv_name)) &&
1647 (GNUNET_NO == have_nick) )
1648 {
1649 /* remove nick record from cache, in case we have one there */
1650 cache_nick (&rp_msg->private_key,
1651 NULL);
1621 } 1652 }
1622 res = GSN_database->store_records (GSN_database->cls, 1653 res = GSN_database->store_records (GSN_database->cls,
1623 &rp_msg->private_key, 1654 &rp_msg->private_key,
diff --git a/src/nse/gnunet-nse.c b/src/nse/gnunet-nse.c
index bf2fe11c3..c8ffa152e 100644
--- a/src/nse/gnunet-nse.c
+++ b/src/nse/gnunet-nse.c
@@ -46,6 +46,7 @@ static int status;
46static void 46static void
47do_shutdown (void *cls) 47do_shutdown (void *cls)
48{ 48{
49 (void) cls;
49 if (NULL != nse) 50 if (NULL != nse)
50 { 51 {
51 GNUNET_NSE_disconnect (nse); 52 GNUNET_NSE_disconnect (nse);
@@ -65,12 +66,14 @@ do_shutdown (void *cls)
65 */ 66 */
66static void 67static void
67handle_estimate (void *cls, 68handle_estimate (void *cls,
68 struct GNUNET_TIME_Absolute timestamp, 69 struct GNUNET_TIME_Absolute timestamp,
69 double estimate, 70 double estimate,
70 double std_dev) 71 double std_dev)
71{ 72{
73 (void) cls;
72 status = 0; 74 status = 0;
73 FPRINTF (stdout, "%llu %f %f %f\n", 75 FPRINTF (stdout,
76 "%llu %f %f %f\n",
74 (unsigned long long) timestamp.abs_value_us, 77 (unsigned long long) timestamp.abs_value_us,
75 GNUNET_NSE_log_estimate_to_n (estimate), 78 GNUNET_NSE_log_estimate_to_n (estimate),
76 estimate, 79 estimate,
@@ -92,11 +95,11 @@ run (void *cls,
92 const char *cfgfile, 95 const char *cfgfile,
93 const struct GNUNET_CONFIGURATION_Handle *cfg) 96 const struct GNUNET_CONFIGURATION_Handle *cfg)
94{ 97{
95 nse = GNUNET_NSE_connect (cfg, 98 (void) cls;
96 &handle_estimate, 99 (void) args;
97 NULL); 100 (void) cfgfile;
98 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, 101 nse = GNUNET_NSE_connect (cfg, &handle_estimate, NULL);
99 NULL); 102 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
100} 103}
101 104
102 105
@@ -106,22 +109,21 @@ run (void *cls,
106 * @return 0 on success 109 * @return 0 on success
107 */ 110 */
108int 111int
109main (int argc, 112main (int argc, char *const *argv)
110 char *const *argv)
111{ 113{
112 static struct GNUNET_GETOPT_CommandLineOption options[] = { 114 static struct GNUNET_GETOPT_CommandLineOption options[] = {
113 GNUNET_GETOPT_OPTION_END 115 GNUNET_GETOPT_OPTION_END};
114 };
115 116
116 status = 1; 117 status = 1;
117 if (GNUNET_OK != 118 if (GNUNET_OK !=
118 GNUNET_PROGRAM_run (argc, 119 GNUNET_PROGRAM_run (argc,
119 argv, 120 argv,
120 "gnunet-nse", 121 "gnunet-nse",
121 gettext_noop 122 gettext_noop (
122 ("Show network size estimates from NSE service."), 123 "Show network size estimates from NSE service."),
123 options, 124 options,
124 &run, NULL)) 125 &run,
126 NULL))
125 return 2; 127 return 2;
126 return status; 128 return status;
127} 129}
diff --git a/src/nse/gnunet-service-nse.c b/src/nse/gnunet-service-nse.c
index 09316dbcf..fd83d2b67 100644
--- a/src/nse/gnunet-service-nse.c
+++ b/src/nse/gnunet-service-nse.c
@@ -430,6 +430,7 @@ handle_start (void *cls, const struct GNUNET_MessageHeader *message)
430 struct GNUNET_NSE_ClientMessage em; 430 struct GNUNET_NSE_ClientMessage em;
431 struct GNUNET_MQ_Envelope *env; 431 struct GNUNET_MQ_Envelope *env;
432 432
433 (void) message;
433 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received START message from client\n"); 434 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received START message from client\n");
434 mq = GNUNET_SERVICE_client_get_mq (client); 435 mq = GNUNET_SERVICE_client_get_mq (client);
435 GNUNET_notification_context_add (nc, mq); 436 GNUNET_notification_context_add (nc, mq);
@@ -717,6 +718,8 @@ schedule_current_round (void *cls,
717 struct NSEPeerEntry *peer_entry = value; 718 struct NSEPeerEntry *peer_entry = value;
718 struct GNUNET_TIME_Relative delay; 719 struct GNUNET_TIME_Relative delay;
719 720
721 (void) cls;
722 (void) key;
720 if (NULL != peer_entry->transmit_task) 723 if (NULL != peer_entry->transmit_task)
721 { 724 {
722 GNUNET_SCHEDULER_cancel (peer_entry->transmit_task); 725 GNUNET_SCHEDULER_cancel (peer_entry->transmit_task);
@@ -749,8 +752,8 @@ static void
749update_flood_message (void *cls) 752update_flood_message (void *cls)
750{ 753{
751 struct GNUNET_TIME_Relative offset; 754 struct GNUNET_TIME_Relative offset;
752 unsigned int i;
753 755
756 (void) cls;
754 flood_task = NULL; 757 flood_task = NULL;
755 offset = GNUNET_TIME_absolute_get_remaining (next_timestamp); 758 offset = GNUNET_TIME_absolute_get_remaining (next_timestamp);
756 if (0 != offset.rel_value_us) 759 if (0 != offset.rel_value_us)
@@ -780,7 +783,7 @@ update_flood_message (void *cls)
780 setup_flood_message (estimate_index, current_timestamp); 783 setup_flood_message (estimate_index, current_timestamp);
781 next_message.matching_bits = htonl (0); /* reset for 'next' round */ 784 next_message.matching_bits = htonl (0); /* reset for 'next' round */
782 hop_count_max = 0; 785 hop_count_max = 0;
783 for (i = 0; i < HISTORY_SIZE; i++) 786 for (unsigned int i = 0; i < HISTORY_SIZE; i++)
784 hop_count_max = 787 hop_count_max =
785 GNUNET_MAX (ntohl (size_estimate_messages[i].hop_count), hop_count_max); 788 GNUNET_MAX (ntohl (size_estimate_messages[i].hop_count), hop_count_max);
786 GNUNET_CONTAINER_multipeermap_iterate (peers, &schedule_current_round, NULL); 789 GNUNET_CONTAINER_multipeermap_iterate (peers, &schedule_current_round, NULL);
@@ -869,6 +872,7 @@ find_proof (void *cls)
869 struct GNUNET_HashCode result; 872 struct GNUNET_HashCode result;
870 unsigned int i; 873 unsigned int i;
871 874
875 (void) cls;
872 proof_task = NULL; 876 proof_task = NULL;
873 GNUNET_memcpy (&buf[sizeof (uint64_t)], 877 GNUNET_memcpy (&buf[sizeof (uint64_t)],
874 &my_identity, 878 &my_identity,
@@ -967,6 +971,7 @@ update_flood_times (void *cls,
967 struct NSEPeerEntry *peer_entry = value; 971 struct NSEPeerEntry *peer_entry = value;
968 struct GNUNET_TIME_Relative delay; 972 struct GNUNET_TIME_Relative delay;
969 973
974 (void) key;
970 if (peer_entry == exclude) 975 if (peer_entry == exclude)
971 return GNUNET_OK; /* trigger of the update */ 976 return GNUNET_OK; /* trigger of the update */
972 if (GNUNET_NO == peer_entry->previous_round) 977 if (GNUNET_NO == peer_entry->previous_round)
@@ -1178,6 +1183,7 @@ handle_core_connect (void *cls,
1178{ 1183{
1179 struct NSEPeerEntry *peer_entry; 1184 struct NSEPeerEntry *peer_entry;
1180 1185
1186 (void) cls;
1181 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1187 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1182 "Peer `%s' connected to us\n", 1188 "Peer `%s' connected to us\n",
1183 GNUNET_i2s (peer)); 1189 GNUNET_i2s (peer));
@@ -1217,6 +1223,7 @@ handle_core_disconnect (void *cls,
1217{ 1223{
1218 struct NSEPeerEntry *pos = internal_cls; 1224 struct NSEPeerEntry *pos = internal_cls;
1219 1225
1226 (void) cls;
1220 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1227 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1221 "Peer `%s' disconnected from us\n", 1228 "Peer `%s' disconnected from us\n",
1222 GNUNET_i2s (peer)); 1229 GNUNET_i2s (peer));
@@ -1243,6 +1250,8 @@ handle_core_disconnect (void *cls,
1243static void 1250static void
1244flush_comp_cb (void *cls, size_t size) 1251flush_comp_cb (void *cls, size_t size)
1245{ 1252{
1253 (void) cls;
1254 (void) size;
1246 GNUNET_TESTBED_LOGGER_disconnect (lh); 1255 GNUNET_TESTBED_LOGGER_disconnect (lh);
1247 lh = NULL; 1256 lh = NULL;
1248} 1257}
@@ -1257,6 +1266,7 @@ flush_comp_cb (void *cls, size_t size)
1257static void 1266static void
1258shutdown_task (void *cls) 1267shutdown_task (void *cls)
1259{ 1268{
1269 (void) cls;
1260 if (NULL != flood_task) 1270 if (NULL != flood_task)
1261 { 1271 {
1262 GNUNET_SCHEDULER_cancel (flood_task); 1272 GNUNET_SCHEDULER_cancel (flood_task);
@@ -1324,6 +1334,7 @@ core_init (void *cls, const struct GNUNET_PeerIdentity *identity)
1324 struct GNUNET_TIME_Absolute now; 1334 struct GNUNET_TIME_Absolute now;
1325 struct GNUNET_TIME_Absolute prev_time; 1335 struct GNUNET_TIME_Absolute prev_time;
1326 1336
1337 (void) cls;
1327 if (NULL == identity) 1338 if (NULL == identity)
1328 { 1339 {
1329 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Connection to core FAILED!\n"); 1340 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Connection to core FAILED!\n");
@@ -1365,6 +1376,7 @@ core_init (void *cls, const struct GNUNET_PeerIdentity *identity)
1365static void 1376static void
1366status_cb (void *cls, int status) 1377status_cb (void *cls, int status)
1367{ 1378{
1379 (void) cls;
1368 logger_test = NULL; 1380 logger_test = NULL;
1369 if (GNUNET_YES != status) 1381 if (GNUNET_YES != status)
1370 { 1382 {
@@ -1402,6 +1414,8 @@ run (void *cls,
1402 char *proof; 1414 char *proof;
1403 struct GNUNET_CRYPTO_EddsaPrivateKey *pk; 1415 struct GNUNET_CRYPTO_EddsaPrivateKey *pk;
1404 1416
1417 (void) cls;
1418 (void) service;
1405 cfg = c; 1419 cfg = c;
1406 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time (cfg, 1420 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time (cfg,
1407 "NSE", 1421 "NSE",
@@ -1524,6 +1538,8 @@ client_connect_cb (void *cls,
1524 struct GNUNET_SERVICE_Client *c, 1538 struct GNUNET_SERVICE_Client *c,
1525 struct GNUNET_MQ_Handle *mq) 1539 struct GNUNET_MQ_Handle *mq)
1526{ 1540{
1541 (void) cls;
1542 (void) mq;
1527 return c; 1543 return c;
1528} 1544}
1529 1545
@@ -1540,6 +1556,7 @@ client_disconnect_cb (void *cls,
1540 struct GNUNET_SERVICE_Client *c, 1556 struct GNUNET_SERVICE_Client *c,
1541 void *internal_cls) 1557 void *internal_cls)
1542{ 1558{
1559 (void) cls;
1543 GNUNET_assert (c == internal_cls); 1560 GNUNET_assert (c == internal_cls);
1544} 1561}
1545 1562
diff --git a/src/nse/nse_api.c b/src/nse/nse_api.c
index e9eaada93..259be75ed 100644
--- a/src/nse/nse_api.c
+++ b/src/nse/nse_api.c
@@ -32,7 +32,7 @@
32#include "gnunet_nse_service.h" 32#include "gnunet_nse_service.h"
33#include "nse.h" 33#include "nse.h"
34 34
35#define LOG(kind,...) GNUNET_log_from (kind, "nse-api",__VA_ARGS__) 35#define LOG(kind, ...) GNUNET_log_from (kind, "nse-api", __VA_ARGS__)
36 36
37/** 37/**
38 * Handle for talking with the NSE service. 38 * Handle for talking with the NSE service.
@@ -68,7 +68,6 @@ struct GNUNET_NSE_Handle
68 * Closure to pass to @e recv_cb callback. 68 * Closure to pass to @e recv_cb callback.
69 */ 69 */
70 void *recv_cb_cls; 70 void *recv_cb_cls;
71
72}; 71};
73 72
74 73
@@ -91,17 +90,15 @@ reconnect (void *cls);
91 * @param error error code 90 * @param error error code
92 */ 91 */
93static void 92static void
94mq_error_handler (void *cls, 93mq_error_handler (void *cls, enum GNUNET_MQ_Error error)
95 enum GNUNET_MQ_Error error)
96{ 94{
97 struct GNUNET_NSE_Handle *h = cls; 95 struct GNUNET_NSE_Handle *h = cls;
98 96
97 (void) error;
99 GNUNET_MQ_destroy (h->mq); 98 GNUNET_MQ_destroy (h->mq);
100 h->mq = NULL; 99 h->mq = NULL;
101 h->reconnect_task 100 h->reconnect_task =
102 = GNUNET_SCHEDULER_add_delayed (h->reconnect_delay, 101 GNUNET_SCHEDULER_add_delayed (h->reconnect_delay, &reconnect, h);
103 &reconnect,
104 h);
105 h->reconnect_delay = GNUNET_TIME_STD_BACKOFF (h->reconnect_delay); 102 h->reconnect_delay = GNUNET_TIME_STD_BACKOFF (h->reconnect_delay);
106} 103}
107 104
@@ -114,8 +111,7 @@ mq_error_handler (void *cls,
114 * @param client_msg message received 111 * @param client_msg message received
115 */ 112 */
116static void 113static void
117handle_estimate (void *cls, 114handle_estimate (void *cls, const struct GNUNET_NSE_ClientMessage *client_msg)
118 const struct GNUNET_NSE_ClientMessage *client_msg)
119{ 115{
120 struct GNUNET_NSE_Handle *h = cls; 116 struct GNUNET_NSE_Handle *h = cls;
121 117
@@ -123,7 +119,7 @@ handle_estimate (void *cls,
123 h->recv_cb (h->recv_cb_cls, 119 h->recv_cb (h->recv_cb_cls,
124 GNUNET_TIME_absolute_ntoh (client_msg->timestamp), 120 GNUNET_TIME_absolute_ntoh (client_msg->timestamp),
125 GNUNET_ntoh_double (client_msg->size_estimate), 121 GNUNET_ntoh_double (client_msg->size_estimate),
126 GNUNET_ntoh_double (client_msg->std_deviation)); 122 GNUNET_ntoh_double (client_msg->std_deviation));
127} 123}
128 124
129 125
@@ -136,13 +132,12 @@ static void
136reconnect (void *cls) 132reconnect (void *cls)
137{ 133{
138 struct GNUNET_NSE_Handle *h = cls; 134 struct GNUNET_NSE_Handle *h = cls;
139 struct GNUNET_MQ_MessageHandler handlers[] = { 135 struct GNUNET_MQ_MessageHandler handlers[] =
140 GNUNET_MQ_hd_fixed_size (estimate, 136 {GNUNET_MQ_hd_fixed_size (estimate,
141 GNUNET_MESSAGE_TYPE_NSE_ESTIMATE, 137 GNUNET_MESSAGE_TYPE_NSE_ESTIMATE,
142 struct GNUNET_NSE_ClientMessage, 138 struct GNUNET_NSE_ClientMessage,
143 h), 139 h),
144 GNUNET_MQ_handler_end () 140 GNUNET_MQ_handler_end ()};
145 };
146 struct GNUNET_MessageHeader *msg; 141 struct GNUNET_MessageHeader *msg;
147 struct GNUNET_MQ_Envelope *env; 142 struct GNUNET_MQ_Envelope *env;
148 143
@@ -150,17 +145,11 @@ reconnect (void *cls)
150 LOG (GNUNET_ERROR_TYPE_DEBUG, 145 LOG (GNUNET_ERROR_TYPE_DEBUG,
151 "Connecting to network size estimation service.\n"); 146 "Connecting to network size estimation service.\n");
152 GNUNET_assert (NULL == h->mq); 147 GNUNET_assert (NULL == h->mq);
153 h->mq = GNUNET_CLIENT_connect (h->cfg, 148 h->mq = GNUNET_CLIENT_connect (h->cfg, "nse", handlers, &mq_error_handler, h);
154 "nse",
155 handlers,
156 &mq_error_handler,
157 h);
158 if (NULL == h->mq) 149 if (NULL == h->mq)
159 return; 150 return;
160 env = GNUNET_MQ_msg (msg, 151 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_NSE_START);
161 GNUNET_MESSAGE_TYPE_NSE_START); 152 GNUNET_MQ_send (h->mq, env);
162 GNUNET_MQ_send (h->mq,
163 env);
164} 153}
165 154
166 155
diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c
index 18a80b3c5..bae187e7c 100644
--- a/src/transport/gnunet-service-tng.c
+++ b/src/transport/gnunet-service-tng.c
@@ -27,71 +27,50 @@
27 * - review retransmission logic, right now there is no smartness there! 27 * - review retransmission logic, right now there is no smartness there!
28 * => congestion control, etc [PERFORMANCE-BASICS] 28 * => congestion control, etc [PERFORMANCE-BASICS]
29 * 29 *
30 * Optimizations: 30 * Optimizations-Statistics:
31 * - Track ACK losses based on ACK-counter [ROUTING]
32 * - Need to track total bandwidth per VirtualLink and adjust how frequently
33 * we send FC messages based on bandwidth-delay-product (and relation
34 * to the window size!). See OPTIMIZE-FC-BDP.
35 * - Consider more statistics in #check_connection_quality() [FIXME-CONQ-STATISTICS]
36 * - Adapt available_fc_window_size, using larger values for high-bandwidth
37 * and high-latency links *if* we have the RAM [GOODPUT / utilization / stalls]
38 * - Set last_window_consum_limit promise properly based on
39 * latency and bandwidth of the respective connection [GOODPUT / utilization / stalls]
40 *
41 * Optimizations-DV:
31 * - When forwarding DV learn messages, if a peer is reached that 42 * - When forwarding DV learn messages, if a peer is reached that
32 * has a *bidirectional* link to the origin beyond 1st hop, 43 * has a *bidirectional* link to the origin beyond 1st hop,
33 * do NOT forward it to peers _other_ than the origin, as 44 * do NOT forward it to peers _other_ than the origin, as
34 * there is clearly a better path directly from the origin to 45 * there is clearly a better path directly from the origin to
35 * whatever else we could reach. 46 * whatever else we could reach.
36 * - AcknowledgementUUIDPs are overkill with 256 bits (128 would do)
37 * => Need 128 bit hash map though! [BANDWIDTH, MEMORY]
38 * - queue_send_msg by API design has to make a copy
39 * of the payload, and route_message on top of that requires a malloc/free.
40 * Change design to approximate "zero" copy better... [CPU]
41 * - could avoid copying body of message into each fragment and keep
42 * fragments as just pointers into the original message and only
43 * fully build fragments just before transmission (optimization, should
44 * reduce CPU and memory use) [CPU, MEMORY]
45 * - if messages are below MTU, consider adding ACKs and other stuff
46 * to the same transmission to avoid tiny messages (requires planning at
47 * receiver, and additional MST-style demultiplex at receiver!) [PACKET COUNT]
48 * - When we passively learned DV (with unconfirmed freshness), we 47 * - When we passively learned DV (with unconfirmed freshness), we
49 * right now add the path to our list but with a zero path_valid_until 48 * right now add the path to our list but with a zero path_valid_until
50 * time and only use it for unconfirmed routes. However, we could consider 49 * time and only use it for unconfirmed routes. However, we could consider
51 * triggering an explicit validation mechansim ourselves, specifically routing 50 * triggering an explicit validation mechansim ourselves, specifically routing
52 * a challenge-response message over the path [ROUTING] 51 * a challenge-response message over the path [ROUTING]
53 * - Track ACK losses based on ACK-counter [ROUTING] 52 * = if available, try to confirm unconfirmed DV paths when trying to establish
54 * - Fragments send over a reliable channel could do without the
55 * AcknowledgementUUIDP altogether, as they won't be acked! [BANDWIDTH]
56 * (-> have 2nd type of acknowledgment message; low priority, as we
57 * do not have an MTU-limited *reliable* communicator)
58 * - Adapt available_fc_window_size, using larger values for high-bandwidth
59 * and high-latency links *if* we have the RAM [GOODPUT / utilization / stalls]
60 * - Set last_window_consum_limit promise properly based on
61 * latency and bandwidth of the respective connection [GOODPUT / utilization / stalls]
62 * - Need to track total bandwidth per VirtualLink and adjust how frequently
63 * we send FC messages based on bandwidth-delay-product (and relation
64 * to the window size!). See OPTIMIZE-FC-BDP.
65 * - if available, try to confirm unconfirmed DV paths when trying to establish
66 * virtual link for a `struct IncomingRequest`. (i.e. if DVH is 53 * virtual link for a `struct IncomingRequest`. (i.e. if DVH is
67 * unconfirmed, incoming requests cause us to try to validate a passively 54 * unconfirmed, incoming requests cause us to try to validate a passively
68 * learned path (requires new message type!)) 55 * learned path (requires new message type!))
69 * 56 *
70 * Design realizations / discussion: 57 * Optimizations-Fragmentation:
71 * - communicators do flow control by calling MQ "notify sent" 58 * - Fragments send over a reliable channel could do without the
72 * when 'ready'. They determine flow implicitly (i.e. TCP blocking) 59 * AcknowledgementUUIDP altogether, as they won't be acked! [BANDWIDTH]
73 * or explicitly via backchannel FC ACKs. As long as the 60 * (-> have 2nd type of acknowledgment message; low priority, as we
74 * channel is not full, they may 'notify sent' even if the other 61 * do not have an MTU-limited *reliable* communicator) [FIXME-FRAG-REL-UUID]
75 * peer has not yet confirmed receipt. The other peer confirming 62 * - if messages are below MTU, consider adding ACKs and other stuff
76 * is _only_ for FC, not for more reliable transmission; reliable 63 * to the same transmission to avoid tiny messages (requires planning at
77 * transmission (i.e. of fragments) is left to _transport_. 64 * receiver, and additional MST-style demultiplex at receiver!) [PACKET COUNT]
78 * - ACKs sent back in uni-directional communicators are done via 65 *
79 * the background channel API; here transport _may_ initially 66 * Optimizations-internals:
80 * broadcast (with bounded # hops) if no path is known; 67 * - queue_send_msg by API design has to make a copy
81 * - transport should _integrate_ DV-routing and build a view of 68 * of the payload, and route_message on top of that requires a malloc/free.
82 * the network; then background channel traffic can be 69 * Change design to approximate "zero" copy better... [CPU]
83 * routed via DV as well as explicit "DV" traffic. 70 * - could avoid copying body of message into each fragment and keep
84 * - background channel is also used for ACKs and NAT traversal support 71 * fragments as just pointers into the original message and only
85 * - transport service is responsible for AEAD'ing the background 72 * fully build fragments just before transmission (optimization, should
86 * channel, timestamps and monotonic time are used against replay 73 * reduce CPU and memory use) [CPU, MEMORY]
87 * of old messages -> peerstore needs to be supplied with
88 * "latest timestamps seen" data
89 * - if transport implements DV, we likely need a 3rd peermap
90 * in addition to ephemerals and (direct) neighbours
91 * ==> check if stuff needs to be moved out of "Neighbour"
92 * - transport should encapsualte core-level messages and do its
93 * own ACKing for RTT/goodput/loss measurements _and_ fragment
94 * for retransmission
95 */ 74 */
96#include "platform.h" 75#include "platform.h"
97#include "gnunet_util_lib.h" 76#include "gnunet_util_lib.h"
@@ -345,9 +324,9 @@ struct MessageUUIDP
345struct AcknowledgementUUIDP 324struct AcknowledgementUUIDP
346{ 325{
347 /** 326 /**
348 * The UUID value. Not actually a hash, but a random value. 327 * The UUID value.
349 */ 328 */
350 struct GNUNET_ShortHashCode value; 329 struct GNUNET_Uuid value;
351}; 330};
352 331
353 332
@@ -1311,18 +1290,6 @@ struct VirtualLink
1311 struct DistanceVector *dv; 1290 struct DistanceVector *dv;
1312 1291
1313 /** 1292 /**
1314 * Last challenge we received from @a n.
1315 * FIXME: where do we need this?
1316 */
1317 struct ChallengeNonceP n_challenge;
1318
1319 /**
1320 * Last challenge we used with @a n for flow control.
1321 * FIXME: where do we need this?
1322 */
1323 struct ChallengeNonceP my_challenge;
1324
1325 /**
1326 * Sender timestamp of @e n_challenge, used to generate out-of-order 1293 * Sender timestamp of @e n_challenge, used to generate out-of-order
1327 * challenges (as sender's timestamps must be monotonically 1294 * challenges (as sender's timestamps must be monotonically
1328 * increasing). FIXME: where do we need this? 1295 * increasing). FIXME: where do we need this?
@@ -2736,7 +2703,7 @@ static struct GNUNET_CONTAINER_MultiPeerMap *ack_cummulators;
2736 * Map of pending acknowledgements, mapping `struct AcknowledgementUUID` to 2703 * Map of pending acknowledgements, mapping `struct AcknowledgementUUID` to
2737 * a `struct PendingAcknowledgement`. 2704 * a `struct PendingAcknowledgement`.
2738 */ 2705 */
2739static struct GNUNET_CONTAINER_MultiShortmap *pending_acks; 2706static struct GNUNET_CONTAINER_MultiUuidmap *pending_acks;
2740 2707
2741/** 2708/**
2742 * Map from PIDs to `struct DistanceVector` entries describing 2709 * Map from PIDs to `struct DistanceVector` entries describing
@@ -2910,9 +2877,9 @@ free_pending_acknowledgement (struct PendingAcknowledgement *pa)
2910 pa->queue = NULL; 2877 pa->queue = NULL;
2911 } 2878 }
2912 GNUNET_assert (GNUNET_YES == 2879 GNUNET_assert (GNUNET_YES ==
2913 GNUNET_CONTAINER_multishortmap_remove (pending_acks, 2880 GNUNET_CONTAINER_multiuuidmap_remove (pending_acks,
2914 &pa->ack_uuid.value, 2881 &pa->ack_uuid.value,
2915 pa)); 2882 pa));
2916 GNUNET_free (pa); 2883 GNUNET_free (pa);
2917} 2884}
2918 2885
@@ -3905,11 +3872,12 @@ client_send_response (struct PendingMessage *pm)
3905{ 3872{
3906 struct TransportClient *tc = pm->client; 3873 struct TransportClient *tc = pm->client;
3907 struct VirtualLink *vl = pm->vl; 3874 struct VirtualLink *vl = pm->vl;
3908 struct GNUNET_MQ_Envelope *env;
3909 struct SendOkMessage *som;
3910 3875
3911 if (NULL != tc) 3876 if (NULL != tc)
3912 { 3877 {
3878 struct GNUNET_MQ_Envelope *env;
3879 struct SendOkMessage *som;
3880
3913 env = GNUNET_MQ_msg (som, GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_OK); 3881 env = GNUNET_MQ_msg (som, GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_OK);
3914 som->peer = vl->target; 3882 som->peer = vl->target;
3915 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3883 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -4225,7 +4193,7 @@ queue_send_msg (struct Queue *queue,
4225 GNUNET_ERROR_TYPE_DEBUG, 4193 GNUNET_ERROR_TYPE_DEBUG,
4226 "Queueing %u bytes of payload for transmission <%llu> on queue %llu to %s\n", 4194 "Queueing %u bytes of payload for transmission <%llu> on queue %llu to %s\n",
4227 (unsigned int) payload_size, 4195 (unsigned int) payload_size,
4228 pm->logging_uuid, 4196 (NULL == pm) ? 0 : pm->logging_uuid,
4229 (unsigned long long) queue->qid, 4197 (unsigned long long) queue->qid,
4230 GNUNET_i2s (&queue->neighbour->pid)); 4198 GNUNET_i2s (&queue->neighbour->pid));
4231 env = GNUNET_MQ_msg_extra (smt, 4199 env = GNUNET_MQ_msg_extra (smt,
@@ -4626,11 +4594,11 @@ encapsulate_for_dv (struct DistanceVector *dv,
4626 char *path; 4594 char *path;
4627 4595
4628 path = GNUNET_strdup (GNUNET_i2s (&GST_my_identity)); 4596 path = GNUNET_strdup (GNUNET_i2s (&GST_my_identity));
4629 for (unsigned int i = 0; i <= num_hops; i++) 4597 for (unsigned int j = 0; j <= num_hops; j++)
4630 { 4598 {
4631 char *tmp; 4599 char *tmp;
4632 4600
4633 GNUNET_asprintf (&tmp, "%s-%s", path, GNUNET_i2s (&dhops[i])); 4601 GNUNET_asprintf (&tmp, "%s-%s", path, GNUNET_i2s (&dhops[j]));
4634 GNUNET_free (path); 4602 GNUNET_free (path);
4635 path = tmp; 4603 path = tmp;
4636 } 4604 }
@@ -5468,7 +5436,7 @@ cummulative_ack (const struct GNUNET_PeerIdentity *pid,
5468 5436
5469 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 5437 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5470 "Scheduling ACK %s for transmission to %s\n", 5438 "Scheduling ACK %s for transmission to %s\n",
5471 GNUNET_sh2s (&ack_uuid->value), 5439 GNUNET_uuid2s (&ack_uuid->value),
5472 GNUNET_i2s (pid)); 5440 GNUNET_i2s (pid));
5473 ac = GNUNET_CONTAINER_multipeermap_get (ack_cummulators, pid); 5441 ac = GNUNET_CONTAINER_multipeermap_get (ack_cummulators, pid);
5474 if (NULL == ac) 5442 if (NULL == ac)
@@ -5743,7 +5711,7 @@ handle_reliability_box (void *cls,
5743 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 5711 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5744 "Received reliability box from %s with UUID %s of type %u\n", 5712 "Received reliability box from %s with UUID %s of type %u\n",
5745 GNUNET_i2s (&cmc->im.sender), 5713 GNUNET_i2s (&cmc->im.sender),
5746 GNUNET_sh2s (&rb->ack_uuid.value), 5714 GNUNET_uuid2s (&rb->ack_uuid.value),
5747 (unsigned int) ntohs (inbox->type)); 5715 (unsigned int) ntohs (inbox->type));
5748 rtt = GNUNET_TIME_UNIT_SECONDS; /* FIXME: should base this on "RTT", but we 5716 rtt = GNUNET_TIME_UNIT_SECONDS; /* FIXME: should base this on "RTT", but we
5749 do not really have an RTT for the 5717 do not really have an RTT for the
@@ -5971,7 +5939,6 @@ handle_reliability_ack (void *cls,
5971{ 5939{
5972 struct CommunicatorMessageContext *cmc = cls; 5940 struct CommunicatorMessageContext *cmc = cls;
5973 const struct TransportCummulativeAckPayloadP *ack; 5941 const struct TransportCummulativeAckPayloadP *ack;
5974 struct PendingAcknowledgement *pa;
5975 unsigned int n_acks; 5942 unsigned int n_acks;
5976 uint32_t ack_counter; 5943 uint32_t ack_counter;
5977 5944
@@ -5980,14 +5947,14 @@ handle_reliability_ack (void *cls,
5980 ack = (const struct TransportCummulativeAckPayloadP *) &ra[1]; 5947 ack = (const struct TransportCummulativeAckPayloadP *) &ra[1];
5981 for (unsigned int i = 0; i < n_acks; i++) 5948 for (unsigned int i = 0; i < n_acks; i++)
5982 { 5949 {
5983 pa = 5950 struct PendingAcknowledgement *pa =
5984 GNUNET_CONTAINER_multishortmap_get (pending_acks, &ack[i].ack_uuid.value); 5951 GNUNET_CONTAINER_multiuuidmap_get (pending_acks, &ack[i].ack_uuid.value);
5985 if (NULL == pa) 5952 if (NULL == pa)
5986 { 5953 {
5987 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 5954 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
5988 "Received ACK from %s with UUID %s which is unknown to us!\n", 5955 "Received ACK from %s with UUID %s which is unknown to us!\n",
5989 GNUNET_i2s (&cmc->im.sender), 5956 GNUNET_i2s (&cmc->im.sender),
5990 GNUNET_sh2s (&ack[i].ack_uuid.value)); 5957 GNUNET_uuid2s (&ack[i].ack_uuid.value));
5991 GNUNET_STATISTICS_update ( 5958 GNUNET_STATISTICS_update (
5992 GST_stats, 5959 GST_stats,
5993 "# FRAGMENT_ACKS dropped, no matching pending message", 5960 "# FRAGMENT_ACKS dropped, no matching pending message",
@@ -5998,7 +5965,7 @@ handle_reliability_ack (void *cls,
5998 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 5965 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5999 "Received ACK from %s with UUID %s\n", 5966 "Received ACK from %s with UUID %s\n",
6000 GNUNET_i2s (&cmc->im.sender), 5967 GNUNET_i2s (&cmc->im.sender),
6001 GNUNET_sh2s (&ack[i].ack_uuid.value)); 5968 GNUNET_uuid2s (&ack[i].ack_uuid.value));
6002 handle_acknowledged (pa, GNUNET_TIME_relative_ntoh (ack[i].ack_delay)); 5969 handle_acknowledged (pa, GNUNET_TIME_relative_ntoh (ack[i].ack_delay));
6003 } 5970 }
6004 5971
@@ -6919,7 +6886,7 @@ handle_dv_learn (void *cls, const struct TransportDVLearnMessage *dvl)
6919 6886
6920 if (0 == (bi_history & (1 << i))) 6887 if (0 == (bi_history & (1 << i)))
6921 break; /* i-th hop not bi-directional, stop learning! */ 6888 break; /* i-th hop not bi-directional, stop learning! */
6922 if (i == nhops) 6889 if (i == nhops - 1)
6923 { 6890 {
6924 path[i + 2] = dvl->initiator; 6891 path[i + 2] = dvl->initiator;
6925 } 6892 }
@@ -7557,89 +7524,6 @@ check_incoming_msg (void *cls,
7557} 7524}
7558 7525
7559 7526
7560#if 0
7561/**
7562 * We received a @a challenge from another peer, check if we can
7563 * increase the flow control window to that peer.
7564 *
7565 * @param vl virtual link
7566 * @param challenge the challenge we received
7567 * @param sender_time when did the peer send the message?
7568 * @param last_window_consum_limit maximum number of kb the sender
7569 * promises to use of the previous window (if any)
7570 */
7571static void
7572update_fc_window (struct VirtualLink *vl,
7573 struct GNUNET_TIME_Absolute sender_time,
7574 uint32_t last_window_consum_limit)
7575{
7576 // FIXME: update to new FC logic
7577 if (0 == GNUNET_memcmp (challenge, &vl->n_challenge))
7578 {
7579 uint32_t avail;
7580
7581 /* Challenge identical to last one, update
7582 @a last_window_consum_limit (to minimum) */
7583 vl->last_fc_window_size_remaining =
7584 GNUNET_MIN (last_window_consum_limit, vl->last_fc_window_size_remaining);
7585 /* window could have shrunk! */
7586 if (vl->available_fc_window_size > vl->last_fc_window_size_remaining)
7587 avail = vl->available_fc_window_size - vl->last_fc_window_size_remaining;
7588 else
7589 avail = 0;
7590 /* guard against integer overflow */
7591 if (vl->incoming_fc_window_size_used + avail >=
7592 vl->incoming_fc_window_size_used)
7593 vl->incoming_fc_window_size = vl->incoming_fc_window_size_used + avail;
7594 else
7595 vl->incoming_fc_window_size = UINT32_MAX;
7596 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
7597 "Updated window to %u/%u kb (%u used) for virtual link to %s!\n",
7598 vl->incoming_fc_window_size,
7599 vl->available_fc_window_size,
7600 vl->incoming_fc_window_size_used,
7601 GNUNET_i2s (&vl->target));
7602 return;
7603 }
7604 if (vl->n_challenge_time.abs_value_us >= sender_time.abs_value_us)
7605 {
7606 GNUNET_STATISTICS_update (GST_stats,
7607 "# Challenges ignored: sender time not increasing",
7608 1,
7609 GNUNET_NO);
7610 return;
7611 }
7612 /* new challenge! */
7613 if (vl->incoming_fc_window_size_used > last_window_consum_limit)
7614 {
7615 /* lying peer: it already used more than it promised it would ever use! */
7616 GNUNET_break_op (0);
7617 last_window_consum_limit = vl->incoming_fc_window_size_used;
7618 }
7619 /* What remains is at most the difference between what we already processed
7620 and what the sender promises to limit itself to. */
7621 vl->last_fc_window_size_remaining =
7622 last_window_consum_limit - vl->incoming_fc_window_size_used;
7623 vl->n_challenge = *challenge;
7624 vl->n_challenge_time = sender_time;
7625 vl->incoming_fc_window_size_used = 0;
7626 /* window could have shrunk! */
7627 if (vl->available_fc_window_size > vl->last_fc_window_size_remaining)
7628 vl->incoming_fc_window_size =
7629 vl->available_fc_window_size - vl->last_fc_window_size_remaining;
7630 else
7631 vl->incoming_fc_window_size = 0;
7632 GNUNET_log (
7633 GNUNET_ERROR_TYPE_DEBUG,
7634 "New window at %u/%u kb (%u left on previous) for virtual link to %s!\n",
7635 vl->incoming_fc_window_size,
7636 vl->available_fc_window_size,
7637 vl->last_fc_window_size_remaining,
7638 GNUNET_i2s (&vl->target));
7639}
7640#endif
7641
7642
7643/** 7527/**
7644 * Closure for #check_known_address. 7528 * Closure for #check_known_address.
7645 */ 7529 */
@@ -8155,7 +8039,6 @@ handle_validation_response (
8155 n->vl = vl; 8039 n->vl = vl;
8156 vl->core_recv_window = RECV_WINDOW_SIZE; 8040 vl->core_recv_window = RECV_WINDOW_SIZE;
8157 vl->available_fc_window_size = DEFAULT_WINDOW_SIZE; 8041 vl->available_fc_window_size = DEFAULT_WINDOW_SIZE;
8158 vl->my_challenge = tvr->challenge;
8159 vl->visibility_task = 8042 vl->visibility_task =
8160 GNUNET_SCHEDULER_add_at (q->validated_until, &check_link_down, vl); 8043 GNUNET_SCHEDULER_add_at (q->validated_until, &check_link_down, vl);
8161 GNUNET_break (GNUNET_YES == 8044 GNUNET_break (GNUNET_YES ==
@@ -8412,7 +8295,7 @@ prepare_pending_acknowledgement (struct Queue *queue,
8412 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, 8295 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
8413 &pa->ack_uuid, 8296 &pa->ack_uuid,
8414 sizeof (pa->ack_uuid)); 8297 sizeof (pa->ack_uuid));
8415 } while (GNUNET_YES != GNUNET_CONTAINER_multishortmap_put ( 8298 } while (GNUNET_YES != GNUNET_CONTAINER_multiuuidmap_put (
8416 pending_acks, 8299 pending_acks,
8417 &pa->ack_uuid.value, 8300 &pa->ack_uuid.value,
8418 pa, 8301 pa,
@@ -8425,7 +8308,7 @@ prepare_pending_acknowledgement (struct Queue *queue,
8425 pa->message_size = pm->bytes_msg; 8308 pa->message_size = pm->bytes_msg;
8426 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 8309 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
8427 "Waiting for ACKnowledgment `%s' for <%llu>\n", 8310 "Waiting for ACKnowledgment `%s' for <%llu>\n",
8428 GNUNET_sh2s (&pa->ack_uuid.value), 8311 GNUNET_uuid2s (&pa->ack_uuid.value),
8429 pm->logging_uuid); 8312 pm->logging_uuid);
8430 return pa; 8313 return pa;
8431} 8314}
@@ -8746,10 +8629,9 @@ select_best_pending_from_link (struct PendingMessageScoreContext *sc,
8746 this queue */) ) 8629 this queue */) )
8747 { 8630 {
8748 frag = GNUNET_YES; 8631 frag = GNUNET_YES;
8749 relb = GNUNET_NO; /* if we fragment, we never also reliability box */
8750 if (GNUNET_TRANSPORT_CC_RELIABLE == queue->tc->details.communicator.cc) 8632 if (GNUNET_TRANSPORT_CC_RELIABLE == queue->tc->details.communicator.cc)
8751 { 8633 {
8752 /* FIXME-OPTIMIZE: we could use an optimized, shorter fragmentation 8634 /* FIXME-FRAG-REL-UUID: we could use an optimized, shorter fragmentation
8753 header without the ACK UUID when using a *reliable* channel! */ 8635 header without the ACK UUID when using a *reliable* channel! */
8754 } 8636 }
8755 real_overhead = overhead + sizeof (struct TransportFragmentBoxMessage); 8637 real_overhead = overhead + sizeof (struct TransportFragmentBoxMessage);
@@ -8946,8 +8828,9 @@ transmit_on_queue (void *cls)
8946 "Fragmentation failed queue %s to %s for <%llu>, trying again\n", 8828 "Fragmentation failed queue %s to %s for <%llu>, trying again\n",
8947 queue->address, 8829 queue->address,
8948 GNUNET_i2s (&n->pid), 8830 GNUNET_i2s (&n->pid),
8949 pm->logging_uuid); 8831 sc.best->logging_uuid);
8950 schedule_transmit_on_queue (queue, GNUNET_SCHEDULER_PRIORITY_DEFAULT); 8832 schedule_transmit_on_queue (queue, GNUNET_SCHEDULER_PRIORITY_DEFAULT);
8833 return;
8951 } 8834 }
8952 } 8835 }
8953 else if (GNUNET_YES == sc.relb) 8836 else if (GNUNET_YES == sc.relb)
@@ -8961,7 +8844,7 @@ transmit_on_queue (void *cls)
8961 "Reliability boxing failed queue %s to %s for <%llu>, trying again\n", 8844 "Reliability boxing failed queue %s to %s for <%llu>, trying again\n",
8962 queue->address, 8845 queue->address,
8963 GNUNET_i2s (&n->pid), 8846 GNUNET_i2s (&n->pid),
8964 pm->logging_uuid); 8847 sc.best->logging_uuid);
8965 schedule_transmit_on_queue (queue, GNUNET_SCHEDULER_PRIORITY_DEFAULT); 8848 schedule_transmit_on_queue (queue, GNUNET_SCHEDULER_PRIORITY_DEFAULT);
8966 return; 8849 return;
8967 } 8850 }
@@ -9442,7 +9325,7 @@ check_connection_quality (void *cls,
9442 ctx->num_queues++; 9325 ctx->num_queues++;
9443 if (0 == ctx->k--) 9326 if (0 == ctx->k--)
9444 ctx->q = q; 9327 ctx->q = q;
9445 /* OPTIMIZE-FIXME: in the future, add reliability / goodput 9328 /* FIXME-CONQ-STATISTICS: in the future, add reliability / goodput
9446 statistics and consider those as well here? */ 9329 statistics and consider those as well here? */
9447 if (q->pd.aged_rtt.rel_value_us < DV_QUALITY_RTT_THRESHOLD.rel_value_us) 9330 if (q->pd.aged_rtt.rel_value_us < DV_QUALITY_RTT_THRESHOLD.rel_value_us)
9448 do_inc = GNUNET_YES; 9331 do_inc = GNUNET_YES;
@@ -10017,9 +9900,7 @@ free_validation_state_cb (void *cls,
10017 * @return #GNUNET_OK (always) 9900 * @return #GNUNET_OK (always)
10018 */ 9901 */
10019static int 9902static int
10020free_pending_ack_cb (void *cls, 9903free_pending_ack_cb (void *cls, const struct GNUNET_Uuid *key, void *value)
10021 const struct GNUNET_ShortHashCode *key,
10022 void *value)
10023{ 9904{
10024 struct PendingAcknowledgement *pa = value; 9905 struct PendingAcknowledgement *pa = value;
10025 9906
@@ -10085,10 +9966,10 @@ do_shutdown (void *cls)
10085 NULL); 9966 NULL);
10086 GNUNET_CONTAINER_multipeermap_destroy (ack_cummulators); 9967 GNUNET_CONTAINER_multipeermap_destroy (ack_cummulators);
10087 ack_cummulators = NULL; 9968 ack_cummulators = NULL;
10088 GNUNET_CONTAINER_multishortmap_iterate (pending_acks, 9969 GNUNET_CONTAINER_multiuuidmap_iterate (pending_acks,
10089 &free_pending_ack_cb, 9970 &free_pending_ack_cb,
10090 NULL); 9971 NULL);
10091 GNUNET_CONTAINER_multishortmap_destroy (pending_acks); 9972 GNUNET_CONTAINER_multiuuidmap_destroy (pending_acks);
10092 pending_acks = NULL; 9973 pending_acks = NULL;
10093 GNUNET_break (0 == GNUNET_CONTAINER_multipeermap_size (neighbours)); 9974 GNUNET_break (0 == GNUNET_CONTAINER_multipeermap_size (neighbours));
10094 GNUNET_CONTAINER_multipeermap_destroy (neighbours); 9975 GNUNET_CONTAINER_multipeermap_destroy (neighbours);
@@ -10142,7 +10023,7 @@ run (void *cls,
10142 hello_mono_time = GNUNET_TIME_absolute_get_monotonic (c); 10023 hello_mono_time = GNUNET_TIME_absolute_get_monotonic (c);
10143 GST_cfg = c; 10024 GST_cfg = c;
10144 backtalkers = GNUNET_CONTAINER_multipeermap_create (16, GNUNET_YES); 10025 backtalkers = GNUNET_CONTAINER_multipeermap_create (16, GNUNET_YES);
10145 pending_acks = GNUNET_CONTAINER_multishortmap_create (32768, GNUNET_YES); 10026 pending_acks = GNUNET_CONTAINER_multiuuidmap_create (32768, GNUNET_YES);
10146 ack_cummulators = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_YES); 10027 ack_cummulators = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_YES);
10147 neighbours = GNUNET_CONTAINER_multipeermap_create (1024, GNUNET_YES); 10028 neighbours = GNUNET_CONTAINER_multipeermap_create (1024, GNUNET_YES);
10148 links = GNUNET_CONTAINER_multipeermap_create (512, GNUNET_YES); 10029 links = GNUNET_CONTAINER_multipeermap_create (512, GNUNET_YES);
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index 8a99197f8..fe5cc6e72 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -78,6 +78,7 @@ libgnunetutil_la_SOURCES = \
78 container_meta_data.c \ 78 container_meta_data.c \
79 container_multihashmap.c \ 79 container_multihashmap.c \
80 container_multishortmap.c \ 80 container_multishortmap.c \
81 container_multiuuidmap.c \
81 container_multipeermap.c \ 82 container_multipeermap.c \
82 container_multihashmap32.c \ 83 container_multihashmap32.c \
83 crypto_symmetric.c \ 84 crypto_symmetric.c \
diff --git a/src/util/common_logging.c b/src/util/common_logging.c
index 5052134f8..b5678e5be 100644
--- a/src/util/common_logging.c
+++ b/src/util/common_logging.c
@@ -107,7 +107,8 @@ static __thread struct GNUNET_AsyncScopeSave current_async_scope;
107 * Note that this message maybe truncated to the first BULK_TRACK_SIZE 107 * Note that this message maybe truncated to the first BULK_TRACK_SIZE
108 * characters, in which case it is NOT 0-terminated! 108 * characters, in which case it is NOT 0-terminated!
109 */ 109 */
110static GNUNET_THREAD_LOCAL char last_bulk[BULK_TRACK_SIZE] __attribute__ ((nonstring)); 110static GNUNET_THREAD_LOCAL char last_bulk[BULK_TRACK_SIZE]
111 __attribute__ ((nonstring));
111 112
112/** 113/**
113 * Type of the last bulk message. 114 * Type of the last bulk message.
@@ -211,7 +212,7 @@ struct LogDef
211}; 212};
212 213
213 214
214#if !defined(GNUNET_CULL_LOGGING) 215#if ! defined(GNUNET_CULL_LOGGING)
215/** 216/**
216 * Dynamic array of logging definitions 217 * Dynamic array of logging definitions
217 */ 218 */
@@ -263,17 +264,17 @@ get_type (const char *log)
263{ 264{
264 if (NULL == log) 265 if (NULL == log)
265 return GNUNET_ERROR_TYPE_UNSPECIFIED; 266 return GNUNET_ERROR_TYPE_UNSPECIFIED;
266 if (0 == strcasecmp (log, _("DEBUG"))) 267 if (0 == strcasecmp (log, _ ("DEBUG")))
267 return GNUNET_ERROR_TYPE_DEBUG; 268 return GNUNET_ERROR_TYPE_DEBUG;
268 if (0 == strcasecmp (log, _("INFO"))) 269 if (0 == strcasecmp (log, _ ("INFO")))
269 return GNUNET_ERROR_TYPE_INFO; 270 return GNUNET_ERROR_TYPE_INFO;
270 if (0 == strcasecmp (log, _("MESSAGE"))) 271 if (0 == strcasecmp (log, _ ("MESSAGE")))
271 return GNUNET_ERROR_TYPE_MESSAGE; 272 return GNUNET_ERROR_TYPE_MESSAGE;
272 if (0 == strcasecmp (log, _("WARNING"))) 273 if (0 == strcasecmp (log, _ ("WARNING")))
273 return GNUNET_ERROR_TYPE_WARNING; 274 return GNUNET_ERROR_TYPE_WARNING;
274 if (0 == strcasecmp (log, _("ERROR"))) 275 if (0 == strcasecmp (log, _ ("ERROR")))
275 return GNUNET_ERROR_TYPE_ERROR; 276 return GNUNET_ERROR_TYPE_ERROR;
276 if (0 == strcasecmp (log, _("NONE"))) 277 if (0 == strcasecmp (log, _ ("NONE")))
277 return GNUNET_ERROR_TYPE_NONE; 278 return GNUNET_ERROR_TYPE_NONE;
278 return GNUNET_ERROR_TYPE_INVALID; 279 return GNUNET_ERROR_TYPE_INVALID;
279} 280}
@@ -292,7 +293,7 @@ GNUNET_abort_ ()
292} 293}
293 294
294 295
295#if !defined(GNUNET_CULL_LOGGING) 296#if ! defined(GNUNET_CULL_LOGGING)
296/** 297/**
297 * Utility function - reallocates logdefs array to be twice as large. 298 * Utility function - reallocates logdefs array to be twice as large.
298 */ 299 */
@@ -353,7 +354,7 @@ setup_log_file (const struct tm *tm)
353 if (0 == strftime (fn, sizeof (fn), log_file_name, tm)) 354 if (0 == strftime (fn, sizeof (fn), log_file_name, tm))
354 return GNUNET_SYSERR; 355 return GNUNET_SYSERR;
355 leftsquare = strrchr (fn, '['); 356 leftsquare = strrchr (fn, '[');
356 if ( (NULL != leftsquare) && (']' == leftsquare[1]) ) 357 if ((NULL != leftsquare) && (']' == leftsquare[1]))
357 { 358 {
358 char *logfile_copy = GNUNET_strdup (fn); 359 char *logfile_copy = GNUNET_strdup (fn);
359 360
@@ -371,8 +372,7 @@ setup_log_file (const struct tm *tm)
371 return GNUNET_OK; /* no change */ 372 return GNUNET_OK; /* no change */
372 log_rotate (last_fn); 373 log_rotate (last_fn);
373 strcpy (last_fn, fn); 374 strcpy (last_fn, fn);
374 if (GNUNET_SYSERR == 375 if (GNUNET_SYSERR == GNUNET_DISK_directory_create_for_file (fn))
375 GNUNET_DISK_directory_create_for_file (fn))
376 { 376 {
377 fprintf (stderr, 377 fprintf (stderr,
378 "Failed to create directory for `%s': %s\n", 378 "Failed to create directory for `%s': %s\n",
@@ -381,14 +381,12 @@ setup_log_file (const struct tm *tm)
381 return GNUNET_SYSERR; 381 return GNUNET_SYSERR;
382 } 382 }
383#if WINDOWS 383#if WINDOWS
384 altlog_fd = OPEN (fn, O_APPEND | 384 altlog_fd =
385 O_BINARY | 385 OPEN (fn, O_APPEND | O_BINARY | O_WRONLY | O_CREAT, _S_IREAD | _S_IWRITE);
386 O_WRONLY | O_CREAT,
387 _S_IREAD | _S_IWRITE);
388#else 386#else
389 altlog_fd = OPEN (fn, O_APPEND | 387 altlog_fd = OPEN (fn,
390 O_WRONLY | O_CREAT, 388 O_APPEND | O_WRONLY | O_CREAT,
391 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 389 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
392#endif 390#endif
393 if (-1 != altlog_fd) 391 if (-1 != altlog_fd)
394 { 392 {
@@ -512,7 +510,7 @@ GNUNET_get_log_call_status (int caller_level,
512 /* We have no definitions to override globally configured log level, 510 /* We have no definitions to override globally configured log level,
513 * so just use it right away. 511 * so just use it right away.
514 */ 512 */
515 if ( (min_level >= 0) && (GNUNET_NO == gnunet_force_log_present) ) 513 if ((min_level >= 0) && (GNUNET_NO == gnunet_force_log_present))
516 return caller_level <= min_level; 514 return caller_level <= min_level;
517 515
518 /* Only look for forced definitions? */ 516 /* Only look for forced definitions? */
@@ -520,7 +518,7 @@ GNUNET_get_log_call_status (int caller_level,
520 for (i = 0; i < logdefs_len; i++) 518 for (i = 0; i < logdefs_len; i++)
521 { 519 {
522 ld = &logdefs[i]; 520 ld = &logdefs[i];
523 if (( (!force_only) || ld->force) && 521 if (((! force_only) || ld->force) &&
524 (line >= ld->from_line && line <= ld->to_line) && 522 (line >= ld->from_line && line <= ld->to_line) &&
525 (0 == regexec (&ld->component_regex, comp, 0, NULL, 0)) && 523 (0 == regexec (&ld->component_regex, comp, 0, NULL, 0)) &&
526 (0 == regexec (&ld->file_regex, file, 0, NULL, 0)) && 524 (0 == regexec (&ld->file_regex, file, 0, NULL, 0)) &&
@@ -591,73 +589,79 @@ parse_definitions (const char *constname, int force)
591 { 589 {
592 switch (p[0]) 590 switch (p[0])
593 { 591 {
594 case ';': /* found a field separator */ 592 case ';': /* found a field separator */
595 p[0] = '\0'; 593 p[0] = '\0';
596 switch (state) 594 switch (state)
597 { 595 {
598 case 0: /* within a component name */ 596 case 0: /* within a component name */
599 comp = start; 597 comp = start;
600 break; 598 break;
601 case 1: /* within a file name */ 599 case 1: /* within a file name */
602 file = start; 600 file = start;
603 break; 601 break;
604 case 2: /* within a function name */ 602 case 2: /* within a function name */
605 /* after a file name there must be a function name */ 603 /* after a file name there must be a function name */
606 function = start; 604 function = start;
607 break; 605 break;
608 case 3: /* within a from-to line range */ 606 case 3: /* within a from-to line range */
609 if (strlen (start) > 0) 607 if (strlen (start) > 0)
610 { 608 {
611 errno = 0; 609 errno = 0;
612 from_line = strtol (start, &t, 10); 610 from_line = strtol (start, &t, 10);
613 if ( (0 != errno) || (from_line < 0) ) 611 if ((0 != errno) || (from_line < 0))
614 { 612 {
615 GNUNET_free (def); 613 GNUNET_free (def);
616 return counter; 614 return counter;
617 } 615 }
618 if ( (t < p) && ('-' == t[0]) ) 616 if ((t < p) && ('-' == t[0]))
619 { 617 {
620 errno = 0; 618 errno = 0;
621 start = t + 1; 619 start = t + 1;
622 to_line = strtol (start, &t, 10); 620 to_line = strtol (start, &t, 10);
623 if ( (0 != errno) || (to_line < 0) || (t != p) ) 621 if ((0 != errno) || (to_line < 0) || (t != p))
624 { 622 {
625 GNUNET_free (def); 623 GNUNET_free (def);
626 return counter; 624 return counter;
627 } 625 }
628 } 626 }
629 else /* one number means "match this line only" */ 627 else /* one number means "match this line only" */
630 to_line = from_line; 628 to_line = from_line;
631 } 629 }
632 else /* default to 0-max */ 630 else /* default to 0-max */
633 { 631 {
634 from_line = 0; 632 from_line = 0;
635 to_line = INT_MAX; 633 to_line = INT_MAX;
636 } 634 }
637 break; 635 break;
638 default: 636 default:
639 fprintf(stderr, 637 fprintf (
640 _("ERROR: Unable to parse log definition: Syntax error at `%s'.\n"), 638 stderr,
641 p); 639 _ ("ERROR: Unable to parse log definition: Syntax error at `%s'.\n"),
640 p);
642 break; 641 break;
643 } 642 }
644 start = p + 1; 643 start = p + 1;
645 state++; 644 state++;
646 break; 645 break;
647 case '\0': /* found EOL */ 646 case '\0': /* found EOL */
648 keep_looking = 0; 647 keep_looking = 0;
649 /* fall through to '/' */ 648 /* fall through to '/' */
650 case '/': /* found a definition separator */ 649 case '/': /* found a definition separator */
651 switch (state) 650 switch (state)
652 { 651 {
653 case 4: /* within a log level */ 652 case 4: /* within a log level */
654 p[0] = '\0'; 653 p[0] = '\0';
655 state = 0; 654 state = 0;
656 level = get_type ((const char *) start); 655 level = get_type ((const char *) start);
657 if ( (GNUNET_ERROR_TYPE_INVALID == level) || 656 if ((GNUNET_ERROR_TYPE_INVALID == level) ||
658 (GNUNET_ERROR_TYPE_UNSPECIFIED == level) || 657 (GNUNET_ERROR_TYPE_UNSPECIFIED == level) ||
659 (0 != add_definition (comp, file, function, from_line, to_line, 658 (0 != add_definition (comp,
660 level, force)) ) 659 file,
660 function,
661 from_line,
662 to_line,
663 level,
664 force)))
661 { 665 {
662 GNUNET_free (def); 666 GNUNET_free (def);
663 return counter; 667 return counter;
@@ -666,9 +670,10 @@ parse_definitions (const char *constname, int force)
666 start = p + 1; 670 start = p + 1;
667 break; 671 break;
668 default: 672 default:
669 fprintf(stderr, 673 fprintf (
670 _("ERROR: Unable to parse log definition: Syntax error at `%s'.\n"), 674 stderr,
671 p); 675 _ ("ERROR: Unable to parse log definition: Syntax error at `%s'.\n"),
676 p);
672 break; 677 break;
673 } 678 }
674 default: 679 default:
@@ -688,7 +693,7 @@ parse_all_definitions ()
688{ 693{
689 if (GNUNET_NO == gnunet_force_log_parsed) 694 if (GNUNET_NO == gnunet_force_log_parsed)
690 gnunet_force_log_present = 695 gnunet_force_log_present =
691 parse_definitions ("GNUNET_FORCE_LOG", 1) > 0 ? GNUNET_YES : GNUNET_NO; 696 parse_definitions ("GNUNET_FORCE_LOG", 1) > 0 ? GNUNET_YES : GNUNET_NO;
692 gnunet_force_log_parsed = GNUNET_YES; 697 gnunet_force_log_parsed = GNUNET_YES;
693 698
694 if (GNUNET_NO == gnunet_log_parsed) 699 if (GNUNET_NO == gnunet_log_parsed)
@@ -707,14 +712,12 @@ parse_all_definitions ()
707 * @return #GNUNET_OK on success 712 * @return #GNUNET_OK on success
708 */ 713 */
709int 714int
710GNUNET_log_setup (const char *comp, 715GNUNET_log_setup (const char *comp, const char *loglevel, const char *logfile)
711 const char *loglevel,
712 const char *logfile)
713{ 716{
714 const char *env_logfile; 717 const char *env_logfile;
715 718
716 min_level = get_type (loglevel); 719 min_level = get_type (loglevel);
717#if !defined(GNUNET_CULL_LOGGING) 720#if ! defined(GNUNET_CULL_LOGGING)
718 parse_all_definitions (); 721 parse_all_definitions ();
719#endif 722#endif
720#ifdef WINDOWS 723#ifdef WINDOWS
@@ -761,8 +764,7 @@ GNUNET_log_setup (const char *comp,
761 * @param logger_cls closure for @a logger 764 * @param logger_cls closure for @a logger
762 */ 765 */
763void 766void
764GNUNET_logger_add (GNUNET_Logger logger, 767GNUNET_logger_add (GNUNET_Logger logger, void *logger_cls)
765 void *logger_cls)
766{ 768{
767 struct CustomLogger *entry; 769 struct CustomLogger *entry;
768 770
@@ -781,8 +783,7 @@ GNUNET_logger_add (GNUNET_Logger logger,
781 * @param logger_cls closure for @a logger 783 * @param logger_cls closure for @a logger
782 */ 784 */
783void 785void
784GNUNET_logger_remove (GNUNET_Logger logger, 786GNUNET_logger_remove (GNUNET_Logger logger, void *logger_cls)
785 void *logger_cls)
786{ 787{
787 struct CustomLogger *pos; 788 struct CustomLogger *pos;
788 struct CustomLogger *prev; 789 struct CustomLogger *prev;
@@ -828,8 +829,7 @@ output_message (enum GNUNET_ErrorType kind,
828 EnterCriticalSection (&output_message_cs); 829 EnterCriticalSection (&output_message_cs);
829#endif 830#endif
830 /* only use the standard logger if no custom loggers are present */ 831 /* only use the standard logger if no custom loggers are present */
831 if ( (NULL != GNUNET_stderr) && 832 if ((NULL != GNUNET_stderr) && (NULL == loggers))
832 (NULL == loggers) )
833 { 833 {
834 if (kind == GNUNET_ERROR_TYPE_MESSAGE) 834 if (kind == GNUNET_ERROR_TYPE_MESSAGE)
835 { 835 {
@@ -841,9 +841,7 @@ output_message (enum GNUNET_ErrorType kind,
841 * this way if the output is going to logfiles or robots 841 * this way if the output is going to logfiles or robots
842 * instead. 842 * instead.
843 */ 843 */
844 FPRINTF (GNUNET_stderr, 844 FPRINTF (GNUNET_stderr, "* %s", msg);
845 "* %s",
846 msg);
847 } 845 }
848 else if (GNUNET_YES == current_async_scope.have_scope) 846 else if (GNUNET_YES == current_async_scope.have_scope)
849 { 847 {
@@ -881,11 +879,7 @@ output_message (enum GNUNET_ErrorType kind,
881 pos = loggers; 879 pos = loggers;
882 while (NULL != pos) 880 while (NULL != pos)
883 { 881 {
884 pos->logger (pos->logger_cls, 882 pos->logger (pos->logger_cls, kind, comp, datestr, msg);
885 kind,
886 comp,
887 datestr,
888 msg);
889 pos = pos->next; 883 pos = pos->next;
890 } 884 }
891#if WINDOWS 885#if WINDOWS
@@ -907,8 +901,7 @@ flush_bulk (const char *datestr)
907 char *last; 901 char *last;
908 const char *ft; 902 const char *ft;
909 903
910 if ( (0 == last_bulk_time.abs_value_us) || 904 if ((0 == last_bulk_time.abs_value_us) || (0 == last_bulk_repeat))
911 (0 == last_bulk_repeat) )
912 return; 905 return;
913 rev = 0; 906 rev = 0;
914 last = memchr (last_bulk, '\0', BULK_TRACK_SIZE); 907 last = memchr (last_bulk, '\0', BULK_TRACK_SIZE);
@@ -921,11 +914,17 @@ flush_bulk (const char *datestr)
921 rev = 1; 914 rev = 1;
922 last[0] = '\0'; 915 last[0] = '\0';
923 } 916 }
924 ft = GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration 917 ft =
925 (last_bulk_time), GNUNET_YES); 918 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (
926 snprintf (msg, sizeof (msg), 919 last_bulk_time),
927 _("Message `%.*s' repeated %u times in the last %s\n"), 920 GNUNET_YES);
928 BULK_TRACK_SIZE, last_bulk, last_bulk_repeat, ft); 921 snprintf (msg,
922 sizeof (msg),
923 _ ("Message `%.*s' repeated %u times in the last %s\n"),
924 BULK_TRACK_SIZE,
925 last_bulk,
926 last_bulk_repeat,
927 ft);
929 if (rev == 1) 928 if (rev == 1)
930 last[0] = '\n'; 929 last[0] = '\n';
931 output_message (last_bulk_kind, last_bulk_comp, datestr, msg); 930 output_message (last_bulk_kind, last_bulk_comp, datestr, msg);
@@ -941,8 +940,7 @@ flush_bulk (const char *datestr)
941 * @param check_reset #GNUNET_YES to assert that the log skip counter is currently zero 940 * @param check_reset #GNUNET_YES to assert that the log skip counter is currently zero
942 */ 941 */
943void 942void
944GNUNET_log_skip (int n, 943GNUNET_log_skip (int n, int check_reset)
945 int check_reset)
946{ 944{
947 int ok; 945 int ok;
948 946
@@ -993,15 +991,10 @@ mylog (enum GNUNET_ErrorType kind,
993 va_list vacp; 991 va_list vacp;
994 992
995 va_copy (vacp, va); 993 va_copy (vacp, va);
996 size = VSNPRINTF (NULL, 994 size = VSNPRINTF (NULL, 0, message, vacp) + 1;
997 0,
998 message,
999 vacp) + 1;
1000 GNUNET_assert (0 != size); 995 GNUNET_assert (0 != size);
1001 va_end (vacp); 996 va_end (vacp);
1002 memset (date, 997 memset (date, 0, DATE_STR_SIZE);
1003 0,
1004 DATE_STR_SIZE);
1005 { 998 {
1006 char buf[size]; 999 char buf[size];
1007 long long offset; 1000 long long offset;
@@ -1022,24 +1015,19 @@ mylog (enum GNUNET_ErrorType kind,
1022 else 1015 else
1023 { 1016 {
1024 if (0 == 1017 if (0 ==
1025 strftime (date2, 1018 strftime (date2, DATE_STR_SIZE, "%b %d %H:%M:%S-%%020llu", tmptr))
1026 DATE_STR_SIZE, 1019 abort ();
1027 "%b %d %H:%M:%S-%%020llu", 1020 if (0 > snprintf (date,
1028 tmptr)) 1021 sizeof (date),
1029 abort (); 1022 date2,
1030 if (0 > 1023 (long long) (pc.QuadPart /
1031 snprintf (date, 1024 (performance_frequency.QuadPart / 1000))))
1032 sizeof (date), 1025 abort ();
1033 date2,
1034 (long long) (pc.QuadPart /
1035 (performance_frequency.QuadPart / 1000))))
1036 abort ();
1037 } 1026 }
1038#else 1027#else
1039 struct timeval timeofday; 1028 struct timeval timeofday;
1040 1029
1041 gettimeofday (&timeofday, 1030 gettimeofday (&timeofday, NULL);
1042 NULL);
1043 offset = GNUNET_TIME_get_offset (); 1031 offset = GNUNET_TIME_get_offset ();
1044 if (offset > 0) 1032 if (offset > 0)
1045 { 1033 {
@@ -1047,80 +1035,59 @@ mylog (enum GNUNET_ErrorType kind,
1047 timeofday.tv_usec += (offset % 1000LL) * 1000LL; 1035 timeofday.tv_usec += (offset % 1000LL) * 1000LL;
1048 if (timeofday.tv_usec > 1000000LL) 1036 if (timeofday.tv_usec > 1000000LL)
1049 { 1037 {
1050 timeofday.tv_usec -= 1000000LL; 1038 timeofday.tv_usec -= 1000000LL;
1051 timeofday.tv_sec++; 1039 timeofday.tv_sec++;
1052 } 1040 }
1053 } 1041 }
1054 else 1042 else
1055 { 1043 {
1056 timeofday.tv_sec += offset / 1000LL; 1044 timeofday.tv_sec += offset / 1000LL;
1057 if (timeofday.tv_usec > - (offset % 1000LL) * 1000LL) 1045 if (timeofday.tv_usec > -(offset % 1000LL) * 1000LL)
1058 { 1046 {
1059 timeofday.tv_usec += (offset % 1000LL) * 1000LL; 1047 timeofday.tv_usec += (offset % 1000LL) * 1000LL;
1060 } 1048 }
1061 else 1049 else
1062 { 1050 {
1063 timeofday.tv_usec += 1000000LL + (offset % 1000LL) * 1000LL; 1051 timeofday.tv_usec += 1000000LL + (offset % 1000LL) * 1000LL;
1064 timeofday.tv_sec--; 1052 timeofday.tv_sec--;
1065 } 1053 }
1066 } 1054 }
1067 tmptr = localtime (&timeofday.tv_sec); 1055 tmptr = localtime (&timeofday.tv_sec);
1068 if (NULL == tmptr) 1056 if (NULL == tmptr)
1069 { 1057 {
1070 strcpy (date, 1058 strcpy (date, "localtime error");
1071 "localtime error");
1072 } 1059 }
1073 else 1060 else
1074 { 1061 {
1075 if (0 == 1062 if (0 == strftime (date2, DATE_STR_SIZE, "%b %d %H:%M:%S-%%06u", tmptr))
1076 strftime (date2, 1063 abort ();
1077 DATE_STR_SIZE, 1064 if (0 > snprintf (date, sizeof (date), date2, timeofday.tv_usec))
1078 "%b %d %H:%M:%S-%%06u", 1065 abort ();
1079 tmptr))
1080 abort ();
1081 if (0 >
1082 snprintf (date,
1083 sizeof (date),
1084 date2,
1085 timeofday.tv_usec))
1086 abort ();
1087 } 1066 }
1088#endif 1067#endif
1089 VSNPRINTF (buf, 1068 VSNPRINTF (buf, size, message, va);
1090 size,
1091 message,
1092 va);
1093#if ! (defined(GNUNET_CULL_LOGGING) || TALER_WALLET_ONLY) 1069#if ! (defined(GNUNET_CULL_LOGGING) || TALER_WALLET_ONLY)
1094 if (NULL != tmptr) 1070 if (NULL != tmptr)
1095 (void) setup_log_file (tmptr); 1071 (void) setup_log_file (tmptr);
1096#endif 1072#endif
1097 if ((0 != (kind & GNUNET_ERROR_TYPE_BULK)) && 1073 if ((0 != (kind & GNUNET_ERROR_TYPE_BULK)) &&
1098 (0 != last_bulk_time.abs_value_us) && 1074 (0 != last_bulk_time.abs_value_us) &&
1099 (0 == strncmp (buf, 1075 (0 == strncmp (buf, last_bulk, sizeof (last_bulk))))
1100 last_bulk,
1101 sizeof (last_bulk))))
1102 { 1076 {
1103 last_bulk_repeat++; 1077 last_bulk_repeat++;
1104 if ( (GNUNET_TIME_absolute_get_duration (last_bulk_time).rel_value_us > 1078 if ((GNUNET_TIME_absolute_get_duration (last_bulk_time).rel_value_us >
1105 BULK_DELAY_THRESHOLD) || 1079 BULK_DELAY_THRESHOLD) ||
1106 (last_bulk_repeat > BULK_REPEAT_THRESHOLD) ) 1080 (last_bulk_repeat > BULK_REPEAT_THRESHOLD))
1107 flush_bulk (date); 1081 flush_bulk (date);
1108 return; 1082 return;
1109 } 1083 }
1110 flush_bulk (date); 1084 flush_bulk (date);
1111 strncpy (last_bulk, 1085 strncpy (last_bulk, buf, sizeof (last_bulk));
1112 buf,
1113 sizeof (last_bulk));
1114 last_bulk_repeat = 0; 1086 last_bulk_repeat = 0;
1115 last_bulk_kind = kind; 1087 last_bulk_kind = kind;
1116 last_bulk_time = GNUNET_TIME_absolute_get (); 1088 last_bulk_time = GNUNET_TIME_absolute_get ();
1117 strncpy (last_bulk_comp, 1089 strncpy (last_bulk_comp, comp, COMP_TRACK_SIZE);
1118 comp, 1090 output_message (kind, comp, date, buf);
1119 COMP_TRACK_SIZE);
1120 output_message (kind,
1121 comp,
1122 date,
1123 buf);
1124 } 1091 }
1125} 1092}
1126 1093
@@ -1133,8 +1100,7 @@ mylog (enum GNUNET_ErrorType kind,
1133 * @param ... arguments for format string 1100 * @param ... arguments for format string
1134 */ 1101 */
1135void 1102void
1136GNUNET_log_nocheck (enum GNUNET_ErrorType kind, 1103GNUNET_log_nocheck (enum GNUNET_ErrorType kind, const char *message, ...)
1137 const char *message, ...)
1138{ 1104{
1139 va_list va; 1105 va_list va;
1140 1106
@@ -1154,8 +1120,10 @@ GNUNET_log_nocheck (enum GNUNET_ErrorType kind,
1154 * @param ... arguments for format string 1120 * @param ... arguments for format string
1155 */ 1121 */
1156void 1122void
1157GNUNET_log_from_nocheck (enum GNUNET_ErrorType kind, const char *comp, 1123GNUNET_log_from_nocheck (enum GNUNET_ErrorType kind,
1158 const char *message, ...) 1124 const char *comp,
1125 const char *message,
1126 ...)
1159{ 1127{
1160 va_list va; 1128 va_list va;
1161 char comp_w_pid[128]; 1129 char comp_w_pid[128];
@@ -1180,18 +1148,18 @@ const char *
1180GNUNET_error_type_to_string (enum GNUNET_ErrorType kind) 1148GNUNET_error_type_to_string (enum GNUNET_ErrorType kind)
1181{ 1149{
1182 if ((kind & GNUNET_ERROR_TYPE_ERROR) > 0) 1150 if ((kind & GNUNET_ERROR_TYPE_ERROR) > 0)
1183 return _("ERROR"); 1151 return _ ("ERROR");
1184 if ((kind & GNUNET_ERROR_TYPE_WARNING) > 0) 1152 if ((kind & GNUNET_ERROR_TYPE_WARNING) > 0)
1185 return _("WARNING"); 1153 return _ ("WARNING");
1186 if ((kind & GNUNET_ERROR_TYPE_MESSAGE) > 0) 1154 if ((kind & GNUNET_ERROR_TYPE_MESSAGE) > 0)
1187 return _("MESSAGE"); 1155 return _ ("MESSAGE");
1188 if ((kind & GNUNET_ERROR_TYPE_INFO) > 0) 1156 if ((kind & GNUNET_ERROR_TYPE_INFO) > 0)
1189 return _("INFO"); 1157 return _ ("INFO");
1190 if ((kind & GNUNET_ERROR_TYPE_DEBUG) > 0) 1158 if ((kind & GNUNET_ERROR_TYPE_DEBUG) > 0)
1191 return _("DEBUG"); 1159 return _ ("DEBUG");
1192 if ((kind & ~GNUNET_ERROR_TYPE_BULK) == 0) 1160 if ((kind & ~GNUNET_ERROR_TYPE_BULK) == 0)
1193 return _("NONE"); 1161 return _ ("NONE");
1194 return _("INVALID"); 1162 return _ ("INVALID");
1195} 1163}
1196 1164
1197 1165
@@ -1202,7 +1170,7 @@ GNUNET_error_type_to_string (enum GNUNET_ErrorType kind)
1202 * @return string form; will be overwritten by next call to GNUNET_h2s. 1170 * @return string form; will be overwritten by next call to GNUNET_h2s.
1203 */ 1171 */
1204const char * 1172const char *
1205GNUNET_h2s (const struct GNUNET_HashCode * hc) 1173GNUNET_h2s (const struct GNUNET_HashCode *hc)
1206{ 1174{
1207 static GNUNET_THREAD_LOCAL struct GNUNET_CRYPTO_HashAsciiEncoded ret; 1175 static GNUNET_THREAD_LOCAL struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1208 1176
@@ -1223,7 +1191,7 @@ GNUNET_h2s (const struct GNUNET_HashCode * hc)
1223 * @return string form; will be overwritten by next call to GNUNET_h2s. 1191 * @return string form; will be overwritten by next call to GNUNET_h2s.
1224 */ 1192 */
1225const char * 1193const char *
1226GNUNET_h2s2 (const struct GNUNET_HashCode * hc) 1194GNUNET_h2s2 (const struct GNUNET_HashCode *hc)
1227{ 1195{
1228 static struct GNUNET_CRYPTO_HashAsciiEncoded ret; 1196 static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1229 1197
@@ -1248,11 +1216,8 @@ GNUNET_p2s (const struct GNUNET_CRYPTO_EddsaPublicKey *p)
1248 static struct GNUNET_CRYPTO_HashAsciiEncoded ret; 1216 static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1249 struct GNUNET_HashCode hc; 1217 struct GNUNET_HashCode hc;
1250 1218
1251 GNUNET_CRYPTO_hash (p, 1219 GNUNET_CRYPTO_hash (p, sizeof (*p), &hc);
1252 sizeof (*p), 1220 GNUNET_CRYPTO_hash_to_enc (&hc, &ret);
1253 &hc);
1254 GNUNET_CRYPTO_hash_to_enc (&hc,
1255 &ret);
1256 ret.encoding[6] = '\0'; 1221 ret.encoding[6] = '\0';
1257 return (const char *) ret.encoding; 1222 return (const char *) ret.encoding;
1258} 1223}
@@ -1273,11 +1238,8 @@ GNUNET_p2s2 (const struct GNUNET_CRYPTO_EddsaPublicKey *p)
1273 static struct GNUNET_CRYPTO_HashAsciiEncoded ret; 1238 static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1274 struct GNUNET_HashCode hc; 1239 struct GNUNET_HashCode hc;
1275 1240
1276 GNUNET_CRYPTO_hash (p, 1241 GNUNET_CRYPTO_hash (p, sizeof (*p), &hc);
1277 sizeof (*p), 1242 GNUNET_CRYPTO_hash_to_enc (&hc, &ret);
1278 &hc);
1279 GNUNET_CRYPTO_hash_to_enc (&hc,
1280 &ret);
1281 ret.encoding[6] = '\0'; 1243 ret.encoding[6] = '\0';
1282 return (const char *) ret.encoding; 1244 return (const char *) ret.encoding;
1283} 1245}
@@ -1298,11 +1260,8 @@ GNUNET_e2s (const struct GNUNET_CRYPTO_EcdhePublicKey *p)
1298 static struct GNUNET_CRYPTO_HashAsciiEncoded ret; 1260 static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1299 struct GNUNET_HashCode hc; 1261 struct GNUNET_HashCode hc;
1300 1262
1301 GNUNET_CRYPTO_hash (p, 1263 GNUNET_CRYPTO_hash (p, sizeof (*p), &hc);
1302 sizeof (*p), 1264 GNUNET_CRYPTO_hash_to_enc (&hc, &ret);
1303 &hc);
1304 GNUNET_CRYPTO_hash_to_enc (&hc,
1305 &ret);
1306 ret.encoding[6] = '\0'; 1265 ret.encoding[6] = '\0';
1307 return (const char *) ret.encoding; 1266 return (const char *) ret.encoding;
1308} 1267}
@@ -1323,11 +1282,8 @@ GNUNET_e2s2 (const struct GNUNET_CRYPTO_EcdhePublicKey *p)
1323 static struct GNUNET_CRYPTO_HashAsciiEncoded ret; 1282 static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1324 struct GNUNET_HashCode hc; 1283 struct GNUNET_HashCode hc;
1325 1284
1326 GNUNET_CRYPTO_hash (p, 1285 GNUNET_CRYPTO_hash (p, sizeof (*p), &hc);
1327 sizeof (*p), 1286 GNUNET_CRYPTO_hash_to_enc (&hc, &ret);
1328 &hc);
1329 GNUNET_CRYPTO_hash_to_enc (&hc,
1330 &ret);
1331 ret.encoding[6] = '\0'; 1287 ret.encoding[6] = '\0';
1332 return (const char *) ret.encoding; 1288 return (const char *) ret.encoding;
1333} 1289}
@@ -1347,10 +1303,27 @@ GNUNET_sh2s (const struct GNUNET_ShortHashCode *shc)
1347{ 1303{
1348 static char buf[64]; 1304 static char buf[64];
1349 1305
1350 GNUNET_STRINGS_data_to_string (shc, 1306 GNUNET_STRINGS_data_to_string (shc, sizeof (*shc), buf, sizeof (buf));
1351 sizeof (*shc), 1307 buf[6] = '\0';
1352 buf, 1308 return (const char *) buf;
1353 sizeof (buf)); 1309}
1310
1311
1312/**
1313 * @ingroup logging
1314 * Convert a UUID to a string (for printing debug messages).
1315 * This is one of the very few calls in the entire API that is
1316 * NOT reentrant!
1317 *
1318 * @param uuid the UUID
1319 * @return string
1320 */
1321const char *
1322GNUNET_uuid2s (const struct GNUNET_Uuid *uuid)
1323{
1324 static char buf[32];
1325
1326 GNUNET_STRINGS_data_to_string (uuid, sizeof (*uuid), buf, sizeof (buf));
1354 buf[6] = '\0'; 1327 buf[6] = '\0';
1355 return (const char *) buf; 1328 return (const char *) buf;
1356} 1329}
@@ -1365,7 +1338,7 @@ GNUNET_sh2s (const struct GNUNET_ShortHashCode *shc)
1365 * @return string form; will be overwritten by next call to GNUNET_h2s_full. 1338 * @return string form; will be overwritten by next call to GNUNET_h2s_full.
1366 */ 1339 */
1367const char * 1340const char *
1368GNUNET_h2s_full (const struct GNUNET_HashCode * hc) 1341GNUNET_h2s_full (const struct GNUNET_HashCode *hc)
1369{ 1342{
1370 static struct GNUNET_CRYPTO_HashAsciiEncoded ret; 1343 static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1371 1344
@@ -1391,9 +1364,7 @@ GNUNET_i2s (const struct GNUNET_PeerIdentity *pid)
1391 if (NULL == pid) 1364 if (NULL == pid)
1392 return "NULL"; 1365 return "NULL";
1393 ret = GNUNET_CRYPTO_eddsa_public_key_to_string (&pid->public_key); 1366 ret = GNUNET_CRYPTO_eddsa_public_key_to_string (&pid->public_key);
1394 strncpy (buf, 1367 strncpy (buf, ret, sizeof (buf) - 1);
1395 ret,
1396 sizeof (buf) - 1);
1397 GNUNET_free (ret); 1368 GNUNET_free (ret);
1398 buf[4] = '\0'; 1369 buf[4] = '\0';
1399 return buf; 1370 return buf;
@@ -1419,9 +1390,7 @@ GNUNET_i2s2 (const struct GNUNET_PeerIdentity *pid)
1419 if (NULL == pid) 1390 if (NULL == pid)
1420 return "NULL"; 1391 return "NULL";
1421 ret = GNUNET_CRYPTO_eddsa_public_key_to_string (&pid->public_key); 1392 ret = GNUNET_CRYPTO_eddsa_public_key_to_string (&pid->public_key);
1422 strncpy (buf, 1393 strncpy (buf, ret, sizeof (buf) - 1);
1423 ret,
1424 sizeof (buf) - 1);
1425 GNUNET_free (ret); 1394 GNUNET_free (ret);
1426 buf[4] = '\0'; 1395 buf[4] = '\0';
1427 return buf; 1396 return buf;
@@ -1459,12 +1428,12 @@ GNUNET_i2s_full (const struct GNUNET_PeerIdentity *pid)
1459 * will be overwritten by next call to #GNUNET_a2s. 1428 * will be overwritten by next call to #GNUNET_a2s.
1460 */ 1429 */
1461const char * 1430const char *
1462GNUNET_a2s (const struct sockaddr *addr, 1431GNUNET_a2s (const struct sockaddr *addr, socklen_t addrlen)
1463 socklen_t addrlen)
1464{ 1432{
1465#ifndef WINDOWS 1433#ifndef WINDOWS
1466#define LEN GNUNET_MAX ((INET6_ADDRSTRLEN + 8), \ 1434#define LEN \
1467 (1 + sizeof (struct sockaddr_un) - sizeof (sa_family_t))) 1435 GNUNET_MAX ((INET6_ADDRSTRLEN + 8), \
1436 (1 + sizeof (struct sockaddr_un) - sizeof (sa_family_t)))
1468#else 1437#else
1469#define LEN (INET6_ADDRSTRLEN + 8) 1438#define LEN (INET6_ADDRSTRLEN + 8)
1470#endif 1439#endif
@@ -1477,24 +1446,18 @@ GNUNET_a2s (const struct sockaddr *addr,
1477 unsigned int off; 1446 unsigned int off;
1478 1447
1479 if (addr == NULL) 1448 if (addr == NULL)
1480 return _("unknown address"); 1449 return _ ("unknown address");
1481 switch (addr->sa_family) 1450 switch (addr->sa_family)
1482 { 1451 {
1483 case AF_INET: 1452 case AF_INET:
1484 if (addrlen != sizeof (struct sockaddr_in)) 1453 if (addrlen != sizeof (struct sockaddr_in))
1485 return "<invalid v4 address>"; 1454 return "<invalid v4 address>";
1486 v4 = (const struct sockaddr_in *) addr; 1455 v4 = (const struct sockaddr_in *) addr;
1487 inet_ntop (AF_INET, 1456 inet_ntop (AF_INET, &v4->sin_addr, buf, INET_ADDRSTRLEN);
1488 &v4->sin_addr,
1489 buf,
1490 INET_ADDRSTRLEN);
1491 if (0 == ntohs (v4->sin_port)) 1457 if (0 == ntohs (v4->sin_port))
1492 return buf; 1458 return buf;
1493 strcat (buf, ":"); 1459 strcat (buf, ":");
1494 GNUNET_snprintf (b2, 1460 GNUNET_snprintf (b2, sizeof (b2), "%u", ntohs (v4->sin_port));
1495 sizeof (b2),
1496 "%u",
1497 ntohs (v4->sin_port));
1498 strcat (buf, b2); 1461 strcat (buf, b2);
1499 return buf; 1462 return buf;
1500 case AF_INET6: 1463 case AF_INET6:
@@ -1502,19 +1465,12 @@ GNUNET_a2s (const struct sockaddr *addr,
1502 return "<invalid v4 address>"; 1465 return "<invalid v4 address>";
1503 v6 = (const struct sockaddr_in6 *) addr; 1466 v6 = (const struct sockaddr_in6 *) addr;
1504 buf[0] = '['; 1467 buf[0] = '[';
1505 inet_ntop (AF_INET6, 1468 inet_ntop (AF_INET6, &v6->sin6_addr, &buf[1], INET6_ADDRSTRLEN);
1506 &v6->sin6_addr,
1507 &buf[1],
1508 INET6_ADDRSTRLEN);
1509 if (0 == ntohs (v6->sin6_port)) 1469 if (0 == ntohs (v6->sin6_port))
1510 return &buf[1]; 1470 return &buf[1];
1511 strcat (buf, "]:"); 1471 strcat (buf, "]:");
1512 GNUNET_snprintf (b2, 1472 GNUNET_snprintf (b2, sizeof (b2), "%u", ntohs (v6->sin6_port));
1513 sizeof (b2), 1473 strcat (buf, b2);
1514 "%u",
1515 ntohs (v6->sin6_port));
1516 strcat (buf,
1517 b2);
1518 return buf; 1474 return buf;
1519 case AF_UNIX: 1475 case AF_UNIX:
1520 if (addrlen <= sizeof (sa_family_t)) 1476 if (addrlen <= sizeof (sa_family_t))
@@ -1532,7 +1488,7 @@ GNUNET_a2s (const struct sockaddr *addr,
1532 &un->sun_path[off]); 1488 &un->sun_path[off]);
1533 return buf; 1489 return buf;
1534 default: 1490 default:
1535 return _("invalid address"); 1491 return _ ("invalid address");
1536 } 1492 }
1537} 1493}
1538 1494
@@ -1546,13 +1502,14 @@ GNUNET_a2s (const struct sockaddr *addr,
1546 */ 1502 */
1547void 1503void
1548GNUNET_log_config_missing (enum GNUNET_ErrorType kind, 1504GNUNET_log_config_missing (enum GNUNET_ErrorType kind,
1549 const char *section, 1505 const char *section,
1550 const char *option) 1506 const char *option)
1551{ 1507{
1552 GNUNET_log (kind, 1508 GNUNET_log (kind,
1553 _("Configuration fails to specify option `%s' in section `%s'!\n"), 1509 _ (
1554 option, 1510 "Configuration fails to specify option `%s' in section `%s'!\n"),
1555 section); 1511 option,
1512 section);
1556} 1513}
1557 1514
1558 1515
@@ -1566,13 +1523,17 @@ GNUNET_log_config_missing (enum GNUNET_ErrorType kind,
1566 */ 1523 */
1567void 1524void
1568GNUNET_log_config_invalid (enum GNUNET_ErrorType kind, 1525GNUNET_log_config_invalid (enum GNUNET_ErrorType kind,
1569 const char *section, 1526 const char *section,
1570 const char *option, 1527 const char *option,
1571 const char *required) 1528 const char *required)
1572{ 1529{
1573 GNUNET_log (kind, 1530 GNUNET_log (
1574 _("Configuration specifies invalid value for option `%s' in section `%s': %s\n"), 1531 kind,
1575 option, section, required); 1532 _ (
1533 "Configuration specifies invalid value for option `%s' in section `%s': %s\n"),
1534 option,
1535 section,
1536 required);
1576} 1537}
1577 1538
1578 1539
@@ -1633,15 +1594,14 @@ GNUNET_async_scope_get (struct GNUNET_AsyncScopeSave *scope_ret)
1633/** 1594/**
1634 * Initializer 1595 * Initializer
1635 */ 1596 */
1636void __attribute__ ((constructor)) 1597void __attribute__ ((constructor)) GNUNET_util_cl_init ()
1637GNUNET_util_cl_init ()
1638{ 1598{
1639 GNUNET_stderr = stderr; 1599 GNUNET_stderr = stderr;
1640#ifdef MINGW 1600#ifdef MINGW
1641 GNInitWinEnv (NULL); 1601 GNInitWinEnv (NULL);
1642#endif 1602#endif
1643#if WINDOWS 1603#if WINDOWS
1644 if (!InitializeCriticalSectionAndSpinCount (&output_message_cs, 0x00000400)) 1604 if (! InitializeCriticalSectionAndSpinCount (&output_message_cs, 0x00000400))
1645 GNUNET_abort_ (); 1605 GNUNET_abort_ ();
1646#endif 1606#endif
1647} 1607}
@@ -1650,8 +1610,7 @@ GNUNET_util_cl_init ()
1650/** 1610/**
1651 * Destructor 1611 * Destructor
1652 */ 1612 */
1653void __attribute__ ((destructor)) 1613void __attribute__ ((destructor)) GNUNET_util_cl_fini ()
1654GNUNET_util_cl_fini ()
1655{ 1614{
1656#if WINDOWS 1615#if WINDOWS
1657 DeleteCriticalSection (&output_message_cs); 1616 DeleteCriticalSection (&output_message_cs);
diff --git a/src/util/container_multiuuidmap.c b/src/util/container_multiuuidmap.c
new file mode 100644
index 000000000..49eb64cfe
--- /dev/null
+++ b/src/util/container_multiuuidmap.c
@@ -0,0 +1,1015 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2008, 2012 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19*/
20/**
21 * @file util/container_multiuuidmap.c
22 * @brief hash map for UUIDs where the same key may be present multiple times
23 * @author Christian Grothoff
24 */
25
26#include "platform.h"
27#include "gnunet_util_lib.h"
28
29#define LOG(kind, ...) \
30 GNUNET_log_from (kind, "util-container-multiuuidmap", __VA_ARGS__)
31
32/**
33 * Maximum recursion depth for callbacks of
34 * #GNUNET_CONTAINER_multihashmap_get_multiple() themselve s
35 * again calling #GNUNET_CONTAINER_multihashmap_get_multiple().
36 * Should be totally excessive, but if violated we die.
37 */
38#define NEXT_CACHE_SIZE 16
39
40
41/**
42 * An entry in the hash map with the full key.
43 */
44struct BigMapEntry
45{
46
47 /**
48 * Value of the entry.
49 */
50 void *value;
51
52 /**
53 * If there is a hash collision, we create a linked list.
54 */
55 struct BigMapEntry *next;
56
57 /**
58 * Key for the entry.
59 */
60 struct GNUNET_Uuid key;
61};
62
63
64/**
65 * An entry in the hash map with just a pointer to the key.
66 */
67struct SmallMapEntry
68{
69
70 /**
71 * Value of the entry.
72 */
73 void *value;
74
75 /**
76 * If there is a hash collision, we create a linked list.
77 */
78 struct SmallMapEntry *next;
79
80 /**
81 * Key for the entry.
82 */
83 const struct GNUNET_Uuid *key;
84};
85
86
87/**
88 * Entry in the map.
89 */
90union MapEntry
91{
92 /**
93 * Variant used if map entries only contain a pointer to the key.
94 */
95 struct SmallMapEntry *sme;
96
97 /**
98 * Variant used if map entries contain the full key.
99 */
100 struct BigMapEntry *bme;
101};
102
103
104/**
105 * Internal representation of the hash map.
106 */
107struct GNUNET_CONTAINER_MultiUuidmap
108{
109 /**
110 * All of our buckets.
111 */
112 union MapEntry *map;
113
114 /**
115 * Number of entries in the map.
116 */
117 unsigned int size;
118
119 /**
120 * Length of the "map" array.
121 */
122 unsigned int map_length;
123
124 /**
125 * #GNUNET_NO if the map entries are of type 'struct BigMapEntry',
126 * #GNUNET_YES if the map entries are of type 'struct SmallMapEntry'.
127 */
128 int use_small_entries;
129
130 /**
131 * Counts the destructive modifications (grow, remove)
132 * to the map, so that iterators can check if they are still valid.
133 */
134 unsigned int modification_counter;
135
136 /**
137 * Map entries indicating iteration positions currently
138 * in use by #GNUNET_CONTAINER_multihashmap_get_multiple().
139 * Only used up to @e next_cache_off.
140 */
141 union MapEntry next_cache[NEXT_CACHE_SIZE];
142
143 /**
144 * Offset of @e next_cache entries in use, must be smaller
145 * than #NEXT_CACHE_SIZE.
146 */
147 unsigned int next_cache_off;
148};
149
150
151/**
152 * Cursor into a multiuuidmap.
153 * Allows to enumerate elements asynchronously.
154 */
155struct GNUNET_CONTAINER_MultiUuidmapIterator
156{
157 /**
158 * Position in the bucket 'idx'
159 */
160 union MapEntry me;
161
162 /**
163 * Current bucket index.
164 */
165 unsigned int idx;
166
167 /**
168 * Modification counter as observed on the map when the iterator
169 * was created.
170 */
171 unsigned int modification_counter;
172
173 /**
174 * Map that we are iterating over.
175 */
176 const struct GNUNET_CONTAINER_MultiUuidmap *map;
177};
178
179
180/**
181 * Create a multi hash map.
182 *
183 * @param len initial size (map will grow as needed)
184 * @param do_not_copy_keys #GNUNET_NO is always safe and should be used by default;
185 * #GNUNET_YES means that on 'put', the 'key' does not have
186 * to be copied as the destination of the pointer is
187 * guaranteed to be life as long as the value is stored in
188 * the hashmap. This can significantly reduce memory
189 * consumption, but of course is also a recipie for
190 * heap corruption if the assumption is not true. Only
191 * use this if (1) memory use is important in this case and
192 * (2) you have triple-checked that the invariant holds
193 * @return NULL on error
194 */
195struct GNUNET_CONTAINER_MultiUuidmap *
196GNUNET_CONTAINER_multiuuidmap_create (unsigned int len, int do_not_copy_keys)
197{
198 struct GNUNET_CONTAINER_MultiUuidmap *map;
199
200 GNUNET_assert (len > 0);
201 map = GNUNET_new (struct GNUNET_CONTAINER_MultiUuidmap);
202 map->map = GNUNET_malloc_large (len * sizeof (union MapEntry));
203 if (NULL == map->map)
204 {
205 GNUNET_free (map);
206 return NULL;
207 }
208 map->map_length = len;
209 map->use_small_entries = do_not_copy_keys;
210 return map;
211}
212
213
214/**
215 * Destroy a hash map. Will not free any values
216 * stored in the hash map!
217 *
218 * @param map the map
219 */
220void
221GNUNET_CONTAINER_multiuuidmap_destroy (
222 struct GNUNET_CONTAINER_MultiUuidmap *map)
223{
224 GNUNET_assert (0 == map->next_cache_off);
225 for (unsigned int i = 0; i < map->map_length; i++)
226 {
227 union MapEntry me;
228
229 me = map->map[i];
230 if (map->use_small_entries)
231 {
232 struct SmallMapEntry *sme;
233 struct SmallMapEntry *nxt;
234
235 nxt = me.sme;
236 while (NULL != (sme = nxt))
237 {
238 nxt = sme->next;
239 GNUNET_free (sme);
240 }
241 me.sme = NULL;
242 }
243 else
244 {
245 struct BigMapEntry *bme;
246 struct BigMapEntry *nxt;
247
248 nxt = me.bme;
249 while (NULL != (bme = nxt))
250 {
251 nxt = bme->next;
252 GNUNET_free (bme);
253 }
254 me.bme = NULL;
255 }
256 }
257 GNUNET_free (map->map);
258 GNUNET_free (map);
259}
260
261
262/**
263 * Compute the index of the bucket for the given key.
264 *
265 * @param map hash map for which to compute the index
266 * @param key what key should the index be computed for
267 * @return offset into the "map" array of "map"
268 */
269static unsigned int
270idx_of (const struct GNUNET_CONTAINER_MultiUuidmap *map,
271 const struct GNUNET_Uuid *key)
272{
273 unsigned int kx;
274
275 GNUNET_assert (NULL != map);
276 GNUNET_memcpy (&kx, key, sizeof (kx));
277 return kx % map->map_length;
278}
279
280
281/**
282 * Get the number of key-value pairs in the map.
283 *
284 * @param map the map
285 * @return the number of key value pairs
286 */
287unsigned int
288GNUNET_CONTAINER_multiuuidmap_size (
289 const struct GNUNET_CONTAINER_MultiUuidmap *map)
290{
291 return map->size;
292}
293
294
295/**
296 * Given a key find a value in the map matching the key.
297 *
298 * @param map the map
299 * @param key what to look for
300 * @return NULL if no value was found; note that
301 * this is indistinguishable from values that just
302 * happen to be NULL; use "contains" to test for
303 * key-value pairs with value NULL
304 */
305void *
306GNUNET_CONTAINER_multiuuidmap_get (
307 const struct GNUNET_CONTAINER_MultiUuidmap *map,
308 const struct GNUNET_Uuid *key)
309{
310 union MapEntry me;
311
312 me = map->map[idx_of (map, key)];
313 if (map->use_small_entries)
314 {
315 for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
316 if (0 == GNUNET_memcmp (key, sme->key))
317 return sme->value;
318 }
319 else
320 {
321 for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
322 if (0 == GNUNET_memcmp (key, &bme->key))
323 return bme->value;
324 }
325 return NULL;
326}
327
328
329/**
330 * Iterate over all entries in the map.
331 *
332 * @param map the map
333 * @param it function to call on each entry
334 * @param it_cls extra argument to @a it
335 * @return the number of key value pairs processed,
336 * #GNUNET_SYSERR if it aborted iteration
337 */
338int
339GNUNET_CONTAINER_multiuuidmap_iterate (
340 struct GNUNET_CONTAINER_MultiUuidmap *map,
341 GNUNET_CONTAINER_MultiUuidmapIterator it,
342 void *it_cls)
343{
344 int count;
345 union MapEntry me;
346 union MapEntry *ce;
347 struct GNUNET_Uuid kc;
348
349 count = 0;
350 GNUNET_assert (NULL != map);
351 ce = &map->next_cache[map->next_cache_off];
352 GNUNET_assert (++map->next_cache_off < NEXT_CACHE_SIZE);
353 for (unsigned int i = 0; i < map->map_length; i++)
354 {
355 me = map->map[i];
356 if (map->use_small_entries)
357 {
358 struct SmallMapEntry *sme;
359
360 ce->sme = me.sme;
361 while (NULL != (sme = ce->sme))
362 {
363 ce->sme = sme->next;
364 if ((NULL != it) && (GNUNET_OK != it (it_cls, sme->key, sme->value)))
365 {
366 GNUNET_assert (--map->next_cache_off < NEXT_CACHE_SIZE);
367 return GNUNET_SYSERR;
368 }
369 count++;
370 }
371 }
372 else
373 {
374 struct BigMapEntry *bme;
375
376 ce->bme = me.bme;
377 while (NULL != (bme = ce->bme))
378 {
379 ce->bme = bme->next;
380 if (NULL != it)
381 {
382 kc = bme->key;
383 if (GNUNET_OK != it (it_cls, &kc, bme->value))
384 {
385 GNUNET_assert (--map->next_cache_off < NEXT_CACHE_SIZE);
386 return GNUNET_SYSERR;
387 }
388 }
389 count++;
390 }
391 }
392 }
393 GNUNET_assert (--map->next_cache_off < NEXT_CACHE_SIZE);
394 return count;
395}
396
397
398/**
399 * We are about to free() the @a bme, make sure it is not in
400 * the list of next values for any iterator in the @a map's next_cache.
401 *
402 * @param map the map to check
403 * @param bme the entry that is about to be free'd
404 */
405static void
406update_next_cache_bme (struct GNUNET_CONTAINER_MultiUuidmap *map,
407 const struct BigMapEntry *bme)
408{
409 for (unsigned int i = 0; i < map->next_cache_off; i++)
410 if (map->next_cache[i].bme == bme)
411 map->next_cache[i].bme = bme->next;
412}
413
414
415/**
416 * We are about to free() the @a sme, make sure it is not in
417 * the list of next values for any iterator in the @a map's next_cache.
418 *
419 * @param map the map to check
420 * @param sme the entry that is about to be free'd
421 */
422static void
423update_next_cache_sme (struct GNUNET_CONTAINER_MultiUuidmap *map,
424 const struct SmallMapEntry *sme)
425{
426 for (unsigned int i = 0; i < map->next_cache_off; i++)
427 if (map->next_cache[i].sme == sme)
428 map->next_cache[i].sme = sme->next;
429}
430
431
432/**
433 * Remove the given key-value pair from the map. Note that if the
434 * key-value pair is in the map multiple times, only one of the pairs
435 * will be removed.
436 *
437 * @param map the map
438 * @param key key of the key-value pair
439 * @param value value of the key-value pair
440 * @return #GNUNET_YES on success, #GNUNET_NO if the key-value pair
441 * is not in the map
442 */
443int
444GNUNET_CONTAINER_multiuuidmap_remove (struct GNUNET_CONTAINER_MultiUuidmap *map,
445 const struct GNUNET_Uuid *key,
446 const void *value)
447{
448 union MapEntry me;
449 unsigned int i;
450
451 map->modification_counter++;
452 i = idx_of (map, key);
453 me = map->map[i];
454 if (map->use_small_entries)
455 {
456 struct SmallMapEntry *p = NULL;
457
458 for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
459 {
460 if ((0 == GNUNET_memcmp (key, sme->key)) && (value == sme->value))
461 {
462 if (NULL == p)
463 map->map[i].sme = sme->next;
464 else
465 p->next = sme->next;
466 update_next_cache_sme (map, sme);
467 GNUNET_free (sme);
468 map->size--;
469 return GNUNET_YES;
470 }
471 p = sme;
472 }
473 }
474 else
475 {
476 struct BigMapEntry *p = NULL;
477
478 for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
479 {
480 if ((0 == GNUNET_memcmp (key, &bme->key)) && (value == bme->value))
481 {
482 if (NULL == p)
483 map->map[i].bme = bme->next;
484 else
485 p->next = bme->next;
486 update_next_cache_bme (map, bme);
487 GNUNET_free (bme);
488 map->size--;
489 return GNUNET_YES;
490 }
491 p = bme;
492 }
493 }
494 return GNUNET_NO;
495}
496
497
498/**
499 * Remove all entries for the given key from the map.
500 * Note that the values would not be "freed".
501 *
502 * @param map the map
503 * @param key identifies values to be removed
504 * @return number of values removed
505 */
506int
507GNUNET_CONTAINER_multiuuidmap_remove_all (
508 struct GNUNET_CONTAINER_MultiUuidmap *map,
509 const struct GNUNET_Uuid *key)
510{
511 union MapEntry me;
512 unsigned int i;
513 int ret;
514
515 map->modification_counter++;
516
517 ret = 0;
518 i = idx_of (map, key);
519 me = map->map[i];
520 if (map->use_small_entries)
521 {
522 struct SmallMapEntry *sme;
523 struct SmallMapEntry *p;
524
525 p = NULL;
526 sme = me.sme;
527 while (NULL != sme)
528 {
529 if (0 == GNUNET_memcmp (key, sme->key))
530 {
531 if (NULL == p)
532 map->map[i].sme = sme->next;
533 else
534 p->next = sme->next;
535 update_next_cache_sme (map, sme);
536 GNUNET_free (sme);
537 map->size--;
538 if (NULL == p)
539 sme = map->map[i].sme;
540 else
541 sme = p->next;
542 ret++;
543 }
544 else
545 {
546 p = sme;
547 sme = sme->next;
548 }
549 }
550 }
551 else
552 {
553 struct BigMapEntry *bme;
554 struct BigMapEntry *p;
555
556 p = NULL;
557 bme = me.bme;
558 while (NULL != bme)
559 {
560 if (0 == GNUNET_memcmp (key, &bme->key))
561 {
562 if (NULL == p)
563 map->map[i].bme = bme->next;
564 else
565 p->next = bme->next;
566 update_next_cache_bme (map, bme);
567 GNUNET_free (bme);
568 map->size--;
569 if (NULL == p)
570 bme = map->map[i].bme;
571 else
572 bme = p->next;
573 ret++;
574 }
575 else
576 {
577 p = bme;
578 bme = bme->next;
579 }
580 }
581 }
582 return ret;
583}
584
585
586/**
587 * Check if the map contains any value under the given
588 * key (including values that are NULL).
589 *
590 * @param map the map
591 * @param key the key to test if a value exists for it
592 * @return #GNUNET_YES if such a value exists,
593 * #GNUNET_NO if not
594 */
595int
596GNUNET_CONTAINER_multiuuidmap_contains (
597 const struct GNUNET_CONTAINER_MultiUuidmap *map,
598 const struct GNUNET_Uuid *key)
599{
600 union MapEntry me;
601
602 me = map->map[idx_of (map, key)];
603 if (map->use_small_entries)
604 {
605 for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
606 if (0 == GNUNET_memcmp (key, sme->key))
607 return GNUNET_YES;
608 }
609 else
610 {
611 for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
612 if (0 == GNUNET_memcmp (key, &bme->key))
613 return GNUNET_YES;
614 }
615 return GNUNET_NO;
616}
617
618
619/**
620 * Check if the map contains the given value under the given
621 * key.
622 *
623 * @param map the map
624 * @param key the key to test if a value exists for it
625 * @param value value to test for
626 * @return #GNUNET_YES if such a value exists,
627 * #GNUNET_NO if not
628 */
629int
630GNUNET_CONTAINER_multiuuidmap_contains_value (
631 const struct GNUNET_CONTAINER_MultiUuidmap *map,
632 const struct GNUNET_Uuid *key,
633 const void *value)
634{
635 union MapEntry me;
636
637 me = map->map[idx_of (map, key)];
638 if (map->use_small_entries)
639 {
640 for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
641 if ((0 == GNUNET_memcmp (key, sme->key)) && (sme->value == value))
642 return GNUNET_YES;
643 }
644 else
645 {
646 for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
647 if ((0 == GNUNET_memcmp (key, &bme->key)) && (bme->value == value))
648 return GNUNET_YES;
649 }
650 return GNUNET_NO;
651}
652
653
654/**
655 * Grow the given map to a more appropriate size.
656 *
657 * @param map the hash map to grow
658 */
659static void
660grow (struct GNUNET_CONTAINER_MultiUuidmap *map)
661{
662 union MapEntry *old_map;
663 union MapEntry *new_map;
664 unsigned int old_len;
665 unsigned int new_len;
666 unsigned int idx;
667
668 old_map = map->map;
669 old_len = map->map_length;
670 new_len = old_len * 2;
671 if (0 == new_len) /* 2^31 * 2 == 0 */
672 new_len = old_len; /* never use 0 */
673 if (new_len == old_len)
674 return; /* nothing changed */
675 new_map = GNUNET_malloc_large (new_len * sizeof (union MapEntry));
676 if (NULL == new_map)
677 return; /* grow not possible */
678 map->modification_counter++;
679 map->map_length = new_len;
680 map->map = new_map;
681 for (unsigned int i = 0; i < old_len; i++)
682 {
683 if (map->use_small_entries)
684 {
685 struct SmallMapEntry *sme;
686
687 while (NULL != (sme = old_map[i].sme))
688 {
689 old_map[i].sme = sme->next;
690 idx = idx_of (map, sme->key);
691 sme->next = new_map[idx].sme;
692 new_map[idx].sme = sme;
693 }
694 }
695 else
696 {
697 struct BigMapEntry *bme;
698
699 while (NULL != (bme = old_map[i].bme))
700 {
701 old_map[i].bme = bme->next;
702 idx = idx_of (map, &bme->key);
703 bme->next = new_map[idx].bme;
704 new_map[idx].bme = bme;
705 }
706 }
707 }
708 GNUNET_free (old_map);
709}
710
711
712/**
713 * Store a key-value pair in the map.
714 *
715 * @param map the map
716 * @param key key to use
717 * @param value value to use
718 * @param opt options for put
719 * @return #GNUNET_OK on success,
720 * #GNUNET_NO if a value was replaced (with REPLACE)
721 * #GNUNET_SYSERR if #GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY was the option and the
722 * value already exists
723 */
724int
725GNUNET_CONTAINER_multiuuidmap_put (struct GNUNET_CONTAINER_MultiUuidmap *map,
726 const struct GNUNET_Uuid *key,
727 void *value,
728 enum GNUNET_CONTAINER_MultiHashMapOption opt)
729{
730 union MapEntry me;
731 unsigned int i;
732
733 i = idx_of (map, key);
734 if ((opt != GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE) &&
735 (opt != GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
736 {
737 me = map->map[i];
738 if (map->use_small_entries)
739 {
740 for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
741 if (0 == GNUNET_memcmp (key, sme->key))
742 {
743 if (opt == GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)
744 return GNUNET_SYSERR;
745 sme->value = value;
746 return GNUNET_NO;
747 }
748 }
749 else
750 {
751 for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
752 if (0 == GNUNET_memcmp (key, &bme->key))
753 {
754 if (opt == GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)
755 return GNUNET_SYSERR;
756 bme->value = value;
757 return GNUNET_NO;
758 }
759 }
760 }
761 if (map->size / 3 >= map->map_length / 4)
762 {
763 grow (map);
764 i = idx_of (map, key);
765 }
766 if (map->use_small_entries)
767 {
768 struct SmallMapEntry *sme;
769
770 sme = GNUNET_new (struct SmallMapEntry);
771 sme->key = key;
772 sme->value = value;
773 sme->next = map->map[i].sme;
774 map->map[i].sme = sme;
775 }
776 else
777 {
778 struct BigMapEntry *bme;
779
780 bme = GNUNET_new (struct BigMapEntry);
781 bme->key = *key;
782 bme->value = value;
783 bme->next = map->map[i].bme;
784 map->map[i].bme = bme;
785 }
786 map->size++;
787 return GNUNET_OK;
788}
789
790
791/**
792 * Iterate over all entries in the map that match a particular key.
793 *
794 * @param map the map
795 * @param key key that the entries must correspond to
796 * @param it function to call on each entry
797 * @param it_cls extra argument to @a it
798 * @return the number of key value pairs processed,
799 * #GNUNET_SYSERR if it aborted iteration
800 */
801int
802GNUNET_CONTAINER_multiuuidmap_get_multiple (
803 struct GNUNET_CONTAINER_MultiUuidmap *map,
804 const struct GNUNET_Uuid *key,
805 GNUNET_CONTAINER_MultiUuidmapIterator it,
806 void *it_cls)
807{
808 int count;
809 union MapEntry me;
810 union MapEntry *ce;
811
812 ce = &map->next_cache[map->next_cache_off];
813 GNUNET_assert (++map->next_cache_off < NEXT_CACHE_SIZE);
814 count = 0;
815 me = map->map[idx_of (map, key)];
816 if (map->use_small_entries)
817 {
818 struct SmallMapEntry *sme;
819
820 ce->sme = me.sme;
821 while (NULL != (sme = ce->sme))
822 {
823 ce->sme = sme->next;
824 if (0 != GNUNET_memcmp (key, sme->key))
825 continue;
826 if ((NULL != it) && (GNUNET_OK != it (it_cls, key, sme->value)))
827 {
828 GNUNET_assert (--map->next_cache_off < NEXT_CACHE_SIZE);
829 return GNUNET_SYSERR;
830 }
831 count++;
832 }
833 }
834 else
835 {
836 struct BigMapEntry *bme;
837
838 ce->bme = me.bme;
839 while (NULL != (bme = ce->bme))
840 {
841 ce->bme = bme->next;
842 if (0 != GNUNET_memcmp (key, &bme->key))
843 continue;
844 if ((NULL != it) && (GNUNET_OK != it (it_cls, key, bme->value)))
845 {
846 GNUNET_assert (--map->next_cache_off < NEXT_CACHE_SIZE);
847 return GNUNET_SYSERR;
848 }
849 count++;
850 }
851 }
852 GNUNET_assert (--map->next_cache_off < NEXT_CACHE_SIZE);
853 return count;
854}
855
856
857/**
858 * @ingroup hashmap
859 * Call @a it on a random value from the map, or not at all
860 * if the map is empty. Note that this function has linear
861 * complexity (in the size of the map).
862 *
863 * @param map the map
864 * @param it function to call on a random entry
865 * @param it_cls extra argument to @a it
866 * @return the number of key value pairs processed, zero or one.
867 */
868unsigned int
869GNUNET_CONTAINER_multiuuidmap_get_random (
870 const struct GNUNET_CONTAINER_MultiUuidmap *map,
871 GNUNET_CONTAINER_MultiUuidmapIterator it,
872 void *it_cls)
873{
874 unsigned int off;
875 union MapEntry me;
876
877 if (0 == map->size)
878 return 0;
879 if (NULL == it)
880 return 1;
881 off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, map->size);
882 for (unsigned int idx = 0; idx < map->map_length; idx++)
883 {
884 me = map->map[idx];
885 if (map->use_small_entries)
886 {
887 for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
888 {
889 if (0 == off)
890 {
891 if (GNUNET_OK != it (it_cls, sme->key, sme->value))
892 return GNUNET_SYSERR;
893 return 1;
894 }
895 off--;
896 }
897 }
898 else
899 {
900 for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
901 {
902 if (0 == off)
903 {
904 if (GNUNET_OK != it (it_cls, &bme->key, bme->value))
905 return GNUNET_SYSERR;
906 return 1;
907 }
908 off--;
909 }
910 }
911 }
912 GNUNET_break (0);
913 return GNUNET_SYSERR;
914}
915
916
917/**
918 * Create an iterator for a multiuuidmap.
919 * The iterator can be used to retrieve all the elements in the multiuuidmap
920 * one by one, without having to handle all elements at once (in contrast to
921 * #GNUNET_CONTAINER_multiuuidmap_iterate). Note that the iterator can not be
922 * used anymore if elements have been removed from 'map' after the creation of
923 * the iterator, or 'map' has been destroyed. Adding elements to 'map' may
924 * result in skipped or repeated elements.
925 *
926 * @param map the map to create an iterator for
927 * @return an iterator over the given multiuuidmap 'map'
928 */
929struct GNUNET_CONTAINER_MultiUuidmapIterator *
930GNUNET_CONTAINER_multiuuidmap_iterator_create (
931 const struct GNUNET_CONTAINER_MultiUuidmap *map)
932{
933 struct GNUNET_CONTAINER_MultiUuidmapIterator *iter;
934
935 iter = GNUNET_new (struct GNUNET_CONTAINER_MultiUuidmapIterator);
936 iter->map = map;
937 iter->modification_counter = map->modification_counter;
938 iter->me = map->map[0];
939 return iter;
940}
941
942
943/**
944 * Retrieve the next element from the hash map at the iterator's position.
945 * If there are no elements left, GNUNET_NO is returned, and 'key' and 'value'
946 * are not modified.
947 * This operation is only allowed if no elements have been removed from the
948 * multiuuidmap since the creation of 'iter', and the map has not been destroyed.
949 * Adding elements may result in repeating or skipping elements.
950 *
951 * @param iter the iterator to get the next element from
952 * @param key pointer to store the key in, can be NULL
953 * @param value pointer to store the value in, can be NULL
954 * @return #GNUNET_YES we returned an element,
955 * #GNUNET_NO if we are out of elements
956 */
957int
958GNUNET_CONTAINER_multiuuidmap_iterator_next (
959 struct GNUNET_CONTAINER_MultiUuidmapIterator *iter,
960 struct GNUNET_Uuid *key,
961 const void **value)
962{
963 /* make sure the map has not been modified */
964 GNUNET_assert (iter->modification_counter == iter->map->modification_counter);
965
966 /* look for the next entry, skipping empty buckets */
967 while (1)
968 {
969 if (iter->idx >= iter->map->map_length)
970 return GNUNET_NO;
971 if (GNUNET_YES == iter->map->use_small_entries)
972 {
973 if (NULL != iter->me.sme)
974 {
975 if (NULL != key)
976 *key = *iter->me.sme->key;
977 if (NULL != value)
978 *value = iter->me.sme->value;
979 iter->me.sme = iter->me.sme->next;
980 return GNUNET_YES;
981 }
982 }
983 else
984 {
985 if (NULL != iter->me.bme)
986 {
987 if (NULL != key)
988 *key = iter->me.bme->key;
989 if (NULL != value)
990 *value = iter->me.bme->value;
991 iter->me.bme = iter->me.bme->next;
992 return GNUNET_YES;
993 }
994 }
995 iter->idx += 1;
996 if (iter->idx < iter->map->map_length)
997 iter->me = iter->map->map[iter->idx];
998 }
999}
1000
1001
1002/**
1003 * Destroy a multiuuidmap iterator.
1004 *
1005 * @param iter the iterator to destroy
1006 */
1007void
1008GNUNET_CONTAINER_multiuuidmap_iterator_destroy (
1009 struct GNUNET_CONTAINER_MultiUuidmapIterator *iter)
1010{
1011 GNUNET_free (iter);
1012}
1013
1014
1015/* end of container_multiuuidmap.c */
diff --git a/src/util/crypto_random.c b/src/util/crypto_random.c
index 8bb5f0587..71eaab87a 100644
--- a/src/util/crypto_random.c
+++ b/src/util/crypto_random.c
@@ -28,22 +28,23 @@
28#include "gnunet_crypto_lib.h" 28#include "gnunet_crypto_lib.h"
29#include <gcrypt.h> 29#include <gcrypt.h>
30 30
31#define LOG(kind,...) GNUNET_log_from (kind, "util-crypto-random", __VA_ARGS__) 31#define LOG(kind, ...) GNUNET_log_from (kind, "util-crypto-random", __VA_ARGS__)
32 32
33#define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-crypto-random", syscall) 33#define LOG_STRERROR(kind, syscall) \
34 GNUNET_log_from_strerror (kind, "util-crypto-random", syscall)
34 35
35 36
36/* TODO: ndurner, move this to plibc? */ 37/* TODO: ndurner, move this to plibc? */
37/* The code is derived from glibc, obviously */ 38/* The code is derived from glibc, obviously */
38#if !HAVE_RANDOM || !HAVE_SRANDOM 39#if ! HAVE_RANDOM || ! HAVE_SRANDOM
39#ifdef RANDOM 40#ifdef RANDOM
40#undef RANDOM 41#undef RANDOM
41#endif 42#endif
42#ifdef SRANDOM 43#ifdef SRANDOM
43#undef SRANDOM 44#undef SRANDOM
44#endif 45#endif
45#define RANDOM() glibc_weak_rand32() 46#define RANDOM() glibc_weak_rand32 ()
46#define SRANDOM(s) glibc_weak_srand32(s) 47#define SRANDOM(s) glibc_weak_srand32 (s)
47#if defined(RAND_MAX) 48#if defined(RAND_MAX)
48#undef RAND_MAX 49#undef RAND_MAX
49#endif 50#endif
@@ -105,17 +106,12 @@ GNUNET_CRYPTO_seed_weak_random (int32_t seed)
105 * @param length buffer length 106 * @param length buffer length
106 */ 107 */
107void 108void
108GNUNET_CRYPTO_zero_keys (void *buffer, 109GNUNET_CRYPTO_zero_keys (void *buffer, size_t length)
109 size_t length)
110{ 110{
111#if HAVE_MEMSET_S 111#if HAVE_MEMSET_S
112 memset_s (buffer, 112 memset_s (buffer, length, 0, length);
113 length,
114 0,
115 length);
116#elif HAVE_EXPLICIT_BZERO 113#elif HAVE_EXPLICIT_BZERO
117 explicit_bzero (buffer, 114 explicit_bzero (buffer, length);
118 length);
119#else 115#else
120 volatile unsigned char *p = buffer; 116 volatile unsigned char *p = buffer;
121 while (length--) 117 while (length--)
@@ -175,8 +171,7 @@ GNUNET_CRYPTO_random_block (enum GNUNET_CRYPTO_Quality mode,
175 * @return a random value in the interval [0,i[. 171 * @return a random value in the interval [0,i[.
176 */ 172 */
177uint32_t 173uint32_t
178GNUNET_CRYPTO_random_u32 (enum GNUNET_CRYPTO_Quality mode, 174GNUNET_CRYPTO_random_u32 (enum GNUNET_CRYPTO_Quality mode, uint32_t i)
179 uint32_t i)
180{ 175{
181#ifdef gcry_fast_random_poll 176#ifdef gcry_fast_random_poll
182 static unsigned int invokeCount; 177 static unsigned int invokeCount;
@@ -197,18 +192,17 @@ GNUNET_CRYPTO_random_u32 (enum GNUNET_CRYPTO_Quality mode,
197 ul = UINT32_MAX - (UINT32_MAX % i); 192 ul = UINT32_MAX - (UINT32_MAX % i);
198 do 193 do
199 { 194 {
200 gcry_randomize ((unsigned char *) &ret, sizeof (uint32_t), 195 gcry_randomize ((unsigned char *) &ret,
196 sizeof (uint32_t),
201 GCRY_STRONG_RANDOM); 197 GCRY_STRONG_RANDOM);
202 } 198 } while (ret >= ul);
203 while (ret >= ul);
204 return ret % i; 199 return ret % i;
205 case GNUNET_CRYPTO_QUALITY_NONCE: 200 case GNUNET_CRYPTO_QUALITY_NONCE:
206 ul = UINT32_MAX - (UINT32_MAX % i); 201 ul = UINT32_MAX - (UINT32_MAX % i);
207 do 202 do
208 { 203 {
209 gcry_create_nonce (&ret, sizeof (ret)); 204 gcry_create_nonce (&ret, sizeof (ret));
210 } 205 } while (ret >= ul);
211 while (ret >= ul);
212 return ret % i; 206 return ret % i;
213 case GNUNET_CRYPTO_QUALITY_WEAK: 207 case GNUNET_CRYPTO_QUALITY_WEAK:
214 ret = i * get_weak_random (); 208 ret = i * get_weak_random ();
@@ -231,8 +225,7 @@ GNUNET_CRYPTO_random_u32 (enum GNUNET_CRYPTO_Quality mode,
231 * @return the permutation array (allocated from heap) 225 * @return the permutation array (allocated from heap)
232 */ 226 */
233unsigned int * 227unsigned int *
234GNUNET_CRYPTO_random_permute (enum GNUNET_CRYPTO_Quality mode, 228GNUNET_CRYPTO_random_permute (enum GNUNET_CRYPTO_Quality mode, unsigned int n)
235 unsigned int n)
236{ 229{
237 unsigned int *ret; 230 unsigned int *ret;
238 unsigned int i; 231 unsigned int i;
@@ -262,8 +255,7 @@ GNUNET_CRYPTO_random_permute (enum GNUNET_CRYPTO_Quality mode,
262 * @return random 64-bit number 255 * @return random 64-bit number
263 */ 256 */
264uint64_t 257uint64_t
265GNUNET_CRYPTO_random_u64 (enum GNUNET_CRYPTO_Quality mode, 258GNUNET_CRYPTO_random_u64 (enum GNUNET_CRYPTO_Quality mode, uint64_t max)
266 uint64_t max)
267{ 259{
268 uint64_t ret; 260 uint64_t ret;
269 uint64_t ul; 261 uint64_t ul;
@@ -275,18 +267,17 @@ GNUNET_CRYPTO_random_u64 (enum GNUNET_CRYPTO_Quality mode,
275 ul = UINT64_MAX - (UINT64_MAX % max); 267 ul = UINT64_MAX - (UINT64_MAX % max);
276 do 268 do
277 { 269 {
278 gcry_randomize ((unsigned char *) &ret, sizeof (uint64_t), 270 gcry_randomize ((unsigned char *) &ret,
271 sizeof (uint64_t),
279 GCRY_STRONG_RANDOM); 272 GCRY_STRONG_RANDOM);
280 } 273 } while (ret >= ul);
281 while (ret >= ul);
282 return ret % max; 274 return ret % max;
283 case GNUNET_CRYPTO_QUALITY_NONCE: 275 case GNUNET_CRYPTO_QUALITY_NONCE:
284 ul = UINT64_MAX - (UINT64_MAX % max); 276 ul = UINT64_MAX - (UINT64_MAX % max);
285 do 277 do
286 { 278 {
287 gcry_create_nonce (&ret, sizeof (ret)); 279 gcry_create_nonce (&ret, sizeof (ret));
288 } 280 } while (ret >= ul);
289 while (ret >= ul);
290 281
291 return ret % max; 282 return ret % max;
292 case GNUNET_CRYPTO_QUALITY_WEAK: 283 case GNUNET_CRYPTO_QUALITY_WEAK:
@@ -319,6 +310,7 @@ w_malloc (size_t n)
319static int 310static int
320w_check (const void *p) 311w_check (const void *p)
321{ 312{
313 (void) p;
322 return 0; /* not secure memory */ 314 return 0; /* not secure memory */
323} 315}
324 316
@@ -326,50 +318,45 @@ w_check (const void *p)
326/** 318/**
327 * Initialize libgcrypt. 319 * Initialize libgcrypt.
328 */ 320 */
329void __attribute__ ((constructor)) 321void __attribute__ ((constructor)) GNUNET_CRYPTO_random_init ()
330GNUNET_CRYPTO_random_init ()
331{ 322{
332 gcry_error_t rc; 323 gcry_error_t rc;
333 324
334 if (! gcry_check_version (NEED_LIBGCRYPT_VERSION)) 325 if (! gcry_check_version (NEED_LIBGCRYPT_VERSION))
335 { 326 {
336 FPRINTF (stderr, 327 FPRINTF (
337 _("libgcrypt has not the expected version (version %s is required).\n"), 328 stderr,
338 NEED_LIBGCRYPT_VERSION); 329 _ ("libgcrypt has not the expected version (version %s is required).\n"),
330 NEED_LIBGCRYPT_VERSION);
339 GNUNET_assert (0); 331 GNUNET_assert (0);
340 } 332 }
341 /* set custom allocators */ 333 /* set custom allocators */
342 gcry_set_allocation_handler (&w_malloc, 334 gcry_set_allocation_handler (&w_malloc, &w_malloc, &w_check, &realloc, &free);
343 &w_malloc,
344 &w_check,
345 &realloc,
346 &free);
347 /* Disable use of secure memory */ 335 /* Disable use of secure memory */
348 if ((rc = gcry_control (GCRYCTL_DISABLE_SECMEM, 0))) 336 if ((rc = gcry_control (GCRYCTL_DISABLE_SECMEM, 0)))
349 FPRINTF (stderr, 337 FPRINTF (stderr,
350 "Failed to set libgcrypt option %s: %s\n", 338 "Failed to set libgcrypt option %s: %s\n",
351 "DISABLE_SECMEM", 339 "DISABLE_SECMEM",
352 gcry_strerror (rc)); 340 gcry_strerror (rc));
353 /* Otherwise gnunet-ecc takes forever to complete, besides 341 /* Otherwise gnunet-ecc takes forever to complete, besides
354 we are fine with "just" using GCRY_STRONG_RANDOM */ 342 we are fine with "just" using GCRY_STRONG_RANDOM */
355 if ((rc = gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0))) 343 if ((rc = gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0)))
356 FPRINTF (stderr, 344 FPRINTF (stderr,
357 "Failed to set libgcrypt option %s: %s\n", 345 "Failed to set libgcrypt option %s: %s\n",
358 "ENABLE_QUICK_RANDOM", 346 "ENABLE_QUICK_RANDOM",
359 gcry_strerror (rc)); 347 gcry_strerror (rc));
360 gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); 348 gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
361 gcry_fast_random_poll (); 349 gcry_fast_random_poll ();
362 GNUNET_CRYPTO_seed_weak_random (time (NULL) ^ 350 GNUNET_CRYPTO_seed_weak_random (
363 GNUNET_CRYPTO_random_u32 351 time (NULL) ^
364 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX)); 352 GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX));
365} 353}
366 354
367 355
368/** 356/**
369 * Nicely shut down libgcrypt. 357 * Nicely shut down libgcrypt.
370 */ 358 */
371void __attribute__ ((destructor)) 359void __attribute__ ((destructor)) GNUNET_CRYPTO_random_fini ()
372GNUNET_CRYPTO_random_fini ()
373{ 360{
374 gcry_set_progress_handler (NULL, NULL); 361 gcry_set_progress_handler (NULL, NULL);
375#ifdef GCRYCTL_CLOSE_RANDOM_DEVICE 362#ifdef GCRYCTL_CLOSE_RANDOM_DEVICE
@@ -378,5 +365,4 @@ GNUNET_CRYPTO_random_fini ()
378} 365}
379 366
380 367
381
382/* end of crypto_random.c */ 368/* end of crypto_random.c */
diff --git a/src/util/gnunet-config.c b/src/util/gnunet-config.c
index f700428a2..9c292205a 100644
--- a/src/util/gnunet-config.c
+++ b/src/util/gnunet-config.c
@@ -43,6 +43,13 @@ static char *option;
43static char *value; 43static char *value;
44 44
45/** 45/**
46 * Backend to check if the respective plugin is
47 * loadable. NULL if no check is to be performed.
48 * The value is the "basename" of the plugin to load.
49 */
50static char *backend_check;
51
52/**
46 * Treat option as a filename. 53 * Treat option as a filename.
47 */ 54 */
48static int is_filename; 55static int is_filename;
@@ -55,7 +62,7 @@ static int list_sections;
55/** 62/**
56 * Return value from 'main'. 63 * Return value from 'main'.
57 */ 64 */
58static int ret; 65static int global_ret;
59 66
60/** 67/**
61 * Should we generate a configuration file that is clean and 68 * Should we generate a configuration file that is clean and
@@ -63,6 +70,7 @@ static int ret;
63 */ 70 */
64static int rewrite; 71static int rewrite;
65 72
73
66/** 74/**
67 * Print each option in a given section. 75 * Print each option in a given section.
68 * 76 *
@@ -149,6 +157,17 @@ run (void *cls,
149 157
150 (void) cls; 158 (void) cls;
151 (void) args; 159 (void) args;
160 if (NULL != backend_check)
161 {
162 char *name;
163
164 GNUNET_asprintf (&name,
165 "libgnunet_plugin_%s",
166 backend_check);
167 global_ret = (GNUNET_OK == GNUNET_PLUGIN_test (name)) ? 0 : 77;
168 GNUNET_free (name);
169 return;
170 }
152 if (rewrite) 171 if (rewrite)
153 { 172 {
154 struct GNUNET_CONFIGURATION_Handle *def; 173 struct GNUNET_CONFIGURATION_Handle *def;
@@ -159,7 +178,7 @@ run (void *cls,
159 { 178 {
160 fprintf (stderr, 179 fprintf (stderr,
161 _("failed to load configuration defaults")); 180 _("failed to load configuration defaults"));
162 ret = 1; 181 global_ret = 1;
163 return; 182 return;
164 } 183 }
165 diff = GNUNET_CONFIGURATION_get_diff (def, 184 diff = GNUNET_CONFIGURATION_get_diff (def,
@@ -174,7 +193,7 @@ run (void *cls,
174 _("%s or %s argument is required\n"), 193 _("%s or %s argument is required\n"),
175 "--section", 194 "--section",
176 "--list-sections"); 195 "--list-sections");
177 ret = 1; 196 global_ret = 1;
178 } 197 }
179 else 198 else
180 { 199 {
@@ -208,7 +227,7 @@ run (void *cls,
208 { 227 {
209 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, 228 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
210 section, option); 229 section, option);
211 ret = 3; 230 global_ret = 3;
212 goto cleanup; 231 goto cleanup;
213 } 232 }
214 } 233 }
@@ -220,7 +239,7 @@ run (void *cls,
220 { 239 {
221 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, 240 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
222 section, option); 241 section, option);
223 ret = 3; 242 global_ret = 3;
224 goto cleanup; 243 goto cleanup;
225 } 244 }
226 } 245 }
@@ -232,7 +251,7 @@ run (void *cls,
232 if (NULL == option) 251 if (NULL == option)
233 { 252 {
234 fprintf (stderr, _("--option argument required to set value\n")); 253 fprintf (stderr, _("--option argument required to set value\n"));
235 ret = 1; 254 global_ret = 1;
236 goto cleanup; 255 goto cleanup;
237 } 256 }
238 out = GNUNET_CONFIGURATION_dup (cfg); 257 out = GNUNET_CONFIGURATION_dup (cfg);
@@ -260,7 +279,7 @@ run (void *cls,
260 if (GNUNET_OK != 279 if (GNUNET_OK !=
261 GNUNET_CONFIGURATION_write ((NULL == out) ? diff : out, 280 GNUNET_CONFIGURATION_write ((NULL == out) ? diff : out,
262 cfgfile)) 281 cfgfile))
263 ret = 2; 282 global_ret = 2;
264 } 283 }
265 GNUNET_free_non_null (cfg_fn); 284 GNUNET_free_non_null (cfg_fn);
266 if (NULL != out) 285 if (NULL != out)
@@ -287,6 +306,12 @@ main (int argc,
287 "filename", 306 "filename",
288 gettext_noop ("interpret option value as a filename (with $-expansion)"), 307 gettext_noop ("interpret option value as a filename (with $-expansion)"),
289 &is_filename), 308 &is_filename),
309 //GNUNET_GETOPT_option_exclusive
310 (GNUNET_GETOPT_option_string ('b',
311 "supported-backend",
312 "BACKEND",
313 gettext_noop ("test if the current installation supports the specified BACKEND"),
314 &backend_check)),
290 GNUNET_GETOPT_option_string ('s', 315 GNUNET_GETOPT_option_string ('s',
291 "section", 316 "section",
292 "SECTION", 317 "SECTION",
@@ -312,20 +337,23 @@ main (int argc,
312 &rewrite), 337 &rewrite),
313 GNUNET_GETOPT_OPTION_END 338 GNUNET_GETOPT_OPTION_END
314 }; 339 };
340 int ret;
341
315 if (GNUNET_OK != 342 if (GNUNET_OK !=
316 GNUNET_STRINGS_get_utf8_args (argc, argv, 343 GNUNET_STRINGS_get_utf8_args (argc, argv,
317 &argc, &argv)) 344 &argc, &argv))
318 return 2; 345 return 2;
319 346
320 ret = (GNUNET_OK == 347 ret = GNUNET_PROGRAM_run (argc,
321 GNUNET_PROGRAM_run (argc, 348 argv,
322 argv, 349 "gnunet-config [OPTIONS]",
323 "gnunet-config [OPTIONS]", 350 gettext_noop ("Manipulate GNUnet configuration files"),
324 gettext_noop ("Manipulate GNUnet configuration files"), 351 options,
325 options, 352 &run, NULL);
326 &run, NULL)) ? 0 : ret;
327 GNUNET_free ((void*) argv); 353 GNUNET_free ((void*) argv);
328 return ret; 354 if (GNUNET_OK == ret)
355 return global_ret;
356 return 1;
329} 357}
330 358
331/* end of gnunet-config.c */ 359/* end of gnunet-config.c */
diff --git a/src/util/gnunet-scrypt.c b/src/util/gnunet-scrypt.c
index 5e15eb16a..f4149a398 100644
--- a/src/util/gnunet-scrypt.c
+++ b/src/util/gnunet-scrypt.c
@@ -57,15 +57,13 @@ static char *pwfn;
57static void 57static void
58shutdown_task (void *cls) 58shutdown_task (void *cls)
59{ 59{
60 if (sizeof (proof) != 60 (void) cls;
61 GNUNET_DISK_fn_write (pwfn, 61 if (sizeof (proof) != GNUNET_DISK_fn_write (pwfn,
62 &proof, 62 &proof,
63 sizeof (proof), 63 sizeof (proof),
64 GNUNET_DISK_PERM_USER_READ | 64 GNUNET_DISK_PERM_USER_READ |
65 GNUNET_DISK_PERM_USER_WRITE)) 65 GNUNET_DISK_PERM_USER_WRITE))
66 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, 66 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "write", pwfn);
67 "write",
68 pwfn);
69} 67}
70 68
71 69
@@ -77,17 +75,18 @@ shutdown_task (void *cls)
77 * @param result where to write the resulting hash 75 * @param result where to write the resulting hash
78 */ 76 */
79static void 77static void
80pow_hash (const void *buf, 78pow_hash (const void *buf, size_t buf_len, struct GNUNET_HashCode *result)
81 size_t buf_len,
82 struct GNUNET_HashCode *result)
83{ 79{
84 GNUNET_break (0 == 80 GNUNET_break (
85 gcry_kdf_derive (buf, buf_len, 81 0 == gcry_kdf_derive (buf,
86 GCRY_KDF_SCRYPT, 82 buf_len,
87 1 /* subalgo */, 83 GCRY_KDF_SCRYPT,
88 "gnunet-proof-of-work", strlen ("gnunet-proof-of-work"), 84 1 /* subalgo */,
89 2 /* iterations; keep cost of individual op small */, 85 "gnunet-proof-of-work",
90 sizeof (struct GNUNET_HashCode), result)); 86 strlen ("gnunet-proof-of-work"),
87 2 /* iterations; keep cost of individual op small */,
88 sizeof (struct GNUNET_HashCode),
89 result));
91} 90}
92 91
93 92
@@ -118,7 +117,7 @@ count_leading_zeroes (const struct GNUNET_HashCode *hash)
118static void 117static void
119find_proof (void *cls) 118find_proof (void *cls)
120{ 119{
121 #define ROUND_SIZE 10 120#define ROUND_SIZE 10
122 uint64_t counter; 121 uint64_t counter;
123 char buf[sizeof (struct GNUNET_CRYPTO_EddsaPublicKey) + 122 char buf[sizeof (struct GNUNET_CRYPTO_EddsaPublicKey) +
124 sizeof (uint64_t)] GNUNET_ALIGN; 123 sizeof (uint64_t)] GNUNET_ALIGN;
@@ -127,12 +126,14 @@ find_proof (void *cls)
127 struct GNUNET_TIME_Absolute timestamp; 126 struct GNUNET_TIME_Absolute timestamp;
128 struct GNUNET_TIME_Relative elapsed; 127 struct GNUNET_TIME_Relative elapsed;
129 128
129 (void) cls;
130 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 130 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
131 "Got Proof of Work %llu\n", 131 "Got Proof of Work %llu\n",
132 (unsigned long long) proof); 132 (unsigned long long) proof);
133 proof_task = NULL; 133 proof_task = NULL;
134 GNUNET_memcpy (&buf[sizeof (uint64_t)], &pub, 134 GNUNET_memcpy (&buf[sizeof (uint64_t)],
135 sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)); 135 &pub,
136 sizeof (struct GNUNET_CRYPTO_EddsaPublicKey));
136 i = 0; 137 i = 0;
137 counter = proof; 138 counter = proof;
138 timestamp = GNUNET_TIME_absolute_get (); 139 timestamp = GNUNET_TIME_absolute_get ();
@@ -143,7 +144,8 @@ find_proof (void *cls)
143 if (nse_work_required <= count_leading_zeroes (&result)) 144 if (nse_work_required <= count_leading_zeroes (&result))
144 { 145 {
145 proof = counter; 146 proof = counter;
146 FPRINTF (stdout, "Proof of work found: %llu!\n", 147 FPRINTF (stdout,
148 "Proof of work found: %llu!\n",
147 (unsigned long long) proof); 149 (unsigned long long) proof);
148 GNUNET_SCHEDULER_shutdown (); 150 GNUNET_SCHEDULER_shutdown ();
149 return; 151 return;
@@ -159,7 +161,8 @@ find_proof (void *cls)
159 GNUNET_STRINGS_relative_time_to_string (elapsed, 0)); 161 GNUNET_STRINGS_relative_time_to_string (elapsed, 0));
160 if (proof / (100 * ROUND_SIZE) < counter / (100 * ROUND_SIZE)) 162 if (proof / (100 * ROUND_SIZE) < counter / (100 * ROUND_SIZE))
161 { 163 {
162 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing proofs currently at %llu\n", 164 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
165 "Testing proofs currently at %llu\n",
163 (unsigned long long) counter); 166 (unsigned long long) counter);
164 /* remember progress every 100 rounds */ 167 /* remember progress every 100 rounds */
165 proof = counter; 168 proof = counter;
@@ -171,8 +174,9 @@ find_proof (void *cls)
171 } 174 }
172 proof_task = 175 proof_task =
173 GNUNET_SCHEDULER_add_delayed_with_priority (proof_find_delay, 176 GNUNET_SCHEDULER_add_delayed_with_priority (proof_find_delay,
174 GNUNET_SCHEDULER_PRIORITY_IDLE, 177 GNUNET_SCHEDULER_PRIORITY_IDLE,
175 &find_proof, NULL); 178 &find_proof,
179 NULL);
176} 180}
177 181
178 182
@@ -193,54 +197,46 @@ run (void *cls,
193 struct GNUNET_CRYPTO_EddsaPrivateKey *pk; 197 struct GNUNET_CRYPTO_EddsaPrivateKey *pk;
194 char *pids; 198 char *pids;
195 199
200 (void) cls;
201 (void) args;
202 (void) cfgfile;
196 cfg = config; 203 cfg = config;
197 /* load proof of work */ 204 /* load proof of work */
198 if (NULL == pwfn) 205 if (NULL == pwfn)
199 { 206 {
200 if (GNUNET_OK != 207 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg,
201 GNUNET_CONFIGURATION_get_value_filename (cfg, 208 "NSE",
202 "NSE", 209 "PROOFFILE",
203 "PROOFFILE", 210 &pwfn))
204 &pwfn))
205 { 211 {
206 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, 212 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "NSE", "PROOFFILE");
207 "NSE",
208 "PROOFFILE");
209 GNUNET_SCHEDULER_shutdown (); 213 GNUNET_SCHEDULER_shutdown ();
210 return; 214 return;
211 } 215 }
212 } 216 }
213 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 217 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Proof of Work file: %s\n", pwfn);
214 "Proof of Work file: %s\n", 218 if ((GNUNET_YES != GNUNET_DISK_file_test (pwfn)) ||
215 pwfn); 219 (sizeof (proof) != GNUNET_DISK_fn_read (pwfn, &proof, sizeof (proof))))
216 if ( (GNUNET_YES != GNUNET_DISK_file_test (pwfn)) ||
217 (sizeof (proof) !=
218 GNUNET_DISK_fn_read (pwfn, &proof, sizeof (proof))))
219 proof = 0; 220 proof = 0;
220 221
221 /* load private key */ 222 /* load private key */
222 if (NULL == pkfn) 223 if (NULL == pkfn)
223 { 224 {
224 if (GNUNET_OK != 225 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg,
225 GNUNET_CONFIGURATION_get_value_filename (cfg, 226 "PEER",
226 "PEER", 227 "PRIVATE_KEY",
227 "PRIVATE_KEY", 228 &pkfn))
228 &pkfn))
229 { 229 {
230 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, 230 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
231 "PEER", 231 "PEER",
232 "PRIVATE_KEY"); 232 "PRIVATE_KEY");
233 return; 233 return;
234 } 234 }
235 } 235 }
236 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 236 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Private Key file: %s\n", pkfn);
237 "Private Key file: %s\n",
238 pkfn);
239 if (NULL == (pk = GNUNET_CRYPTO_eddsa_key_create_from_file (pkfn))) 237 if (NULL == (pk = GNUNET_CRYPTO_eddsa_key_create_from_file (pkfn)))
240 { 238 {
241 FPRINTF (stderr, 239 FPRINTF (stderr, _ ("Loading hostkey from `%s' failed.\n"), pkfn);
242 _("Loading hostkey from `%s' failed.\n"),
243 pkfn);
244 GNUNET_free (pkfn); 240 GNUNET_free (pkfn);
245 return; 241 return;
246 } 242 }
@@ -248,32 +244,27 @@ run (void *cls,
248 GNUNET_CRYPTO_eddsa_key_get_public (pk, &pub); 244 GNUNET_CRYPTO_eddsa_key_get_public (pk, &pub);
249 GNUNET_free (pk); 245 GNUNET_free (pk);
250 pids = GNUNET_CRYPTO_eddsa_public_key_to_string (&pub); 246 pids = GNUNET_CRYPTO_eddsa_public_key_to_string (&pub);
251 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 247 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Peer ID: %s\n", pids);
252 "Peer ID: %s\n",
253 pids);
254 GNUNET_free (pids); 248 GNUNET_free (pids);
255 249
256 /* get target bit amount */ 250 /* get target bit amount */
257 if (0 == nse_work_required) 251 if (0 == nse_work_required)
258 { 252 {
259 if (GNUNET_OK != 253 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg,
260 GNUNET_CONFIGURATION_get_value_number (cfg, 254 "NSE",
261 "NSE", 255 "WORKBITS",
262 "WORKBITS", 256 &nse_work_required))
263 &nse_work_required))
264 { 257 {
265 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, 258 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "NSE", "WORKBITS");
266 "NSE",
267 "WORKBITS");
268 GNUNET_SCHEDULER_shutdown (); 259 GNUNET_SCHEDULER_shutdown ();
269 return; 260 return;
270 } 261 }
271 if (nse_work_required >= sizeof (struct GNUNET_HashCode) * 8) 262 if (nse_work_required >= sizeof (struct GNUNET_HashCode) * 8)
272 { 263 {
273 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, 264 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
274 "NSE", 265 "NSE",
275 "WORKBITS", 266 "WORKBITS",
276 _("Value is too large.\n")); 267 _ ("Value is too large.\n"));
277 GNUNET_SCHEDULER_shutdown (); 268 GNUNET_SCHEDULER_shutdown ();
278 return; 269 return;
279 } 270 }
@@ -283,19 +274,16 @@ run (void *cls,
283 return; 274 return;
284 } 275 }
285 } 276 }
286 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 277 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Bits: %llu\n", nse_work_required);
287 "Bits: %llu\n",
288 nse_work_required);
289 278
290 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 279 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
291 "Delay between tries: %s\n", 280 "Delay between tries: %s\n",
292 GNUNET_STRINGS_relative_time_to_string (proof_find_delay, 1)); 281 GNUNET_STRINGS_relative_time_to_string (proof_find_delay, 1));
293 proof_task = 282 proof_task =
294 GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE, 283 GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE,
295 &find_proof, 284 &find_proof,
296 NULL); 285 NULL);
297 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, 286 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL);
298 NULL);
299} 287}
300 288
301 289
@@ -307,46 +295,51 @@ run (void *cls,
307 * @return 0 ok, 1 on error 295 * @return 0 ok, 1 on error
308 */ 296 */
309int 297int
310main (int argc, 298main (int argc, char *const *argv)
311 char *const *argv)
312{ 299{
313 struct GNUNET_GETOPT_CommandLineOption options[] = { 300 struct GNUNET_GETOPT_CommandLineOption options[] =
314 GNUNET_GETOPT_option_ulong ('b', 301 {GNUNET_GETOPT_option_ulong (
315 "bits", 302 'b',
316 "BITS", 303 "bits",
317 gettext_noop ("number of bits to require for the proof of work"), 304 "BITS",
318 &nse_work_required), 305 gettext_noop ("number of bits to require for the proof of work"),
319 GNUNET_GETOPT_option_filename ('k', 306 &nse_work_required),
320 "keyfile", 307 GNUNET_GETOPT_option_filename (
321 "FILE", 308 'k',
322 gettext_noop ("file with private key, otherwise default is used"), 309 "keyfile",
323 &pkfn), 310 "FILE",
324 GNUNET_GETOPT_option_filename ('o', 311 gettext_noop ("file with private key, otherwise default is used"),
325 "outfile", 312 &pkfn),
326 "FILE", 313 GNUNET_GETOPT_option_filename (
327 gettext_noop ("file with proof of work, otherwise default is used"), 314 'o',
328 &pwfn), 315 "outfile",
329 GNUNET_GETOPT_option_relative_time ('t', 316 "FILE",
330 "timeout", 317 gettext_noop ("file with proof of work, otherwise default is used"),
331 "TIME", 318 &pwfn),
332 gettext_noop ("time to wait between calculations"), 319 GNUNET_GETOPT_option_relative_time ('t',
333 &proof_find_delay), 320 "timeout",
334 GNUNET_GETOPT_OPTION_END 321 "TIME",
335 }; 322 gettext_noop (
323 "time to wait between calculations"),
324 &proof_find_delay),
325 GNUNET_GETOPT_OPTION_END};
336 int ret; 326 int ret;
337 327
338 if (GNUNET_OK != 328 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
339 GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
340 return 2; 329 return 2;
341 330
342 ret = (GNUNET_OK == 331 ret =
343 GNUNET_PROGRAM_run (argc, argv, 332 (GNUNET_OK ==
344 "gnunet-scrypt [OPTIONS] prooffile", 333 GNUNET_PROGRAM_run (argc,
345 gettext_noop ("Manipulate GNUnet proof of work files"), 334 argv,
346 options, 335 "gnunet-scrypt [OPTIONS] prooffile",
347 &run, 336 gettext_noop ("Manipulate GNUnet proof of work files"),
348 NULL)) ? 0 : 1; 337 options,
349 GNUNET_free ((void*) argv); 338 &run,
339 NULL))
340 ? 0
341 : 1;
342 GNUNET_free ((void *) argv);
350 GNUNET_free_non_null (pwfn); 343 GNUNET_free_non_null (pwfn);
351 return ret; 344 return ret;
352} 345}
diff --git a/src/util/gnunet-uri.c b/src/util/gnunet-uri.c
index 58f9e331c..33ff7b1e6 100644
--- a/src/util/gnunet-uri.c
+++ b/src/util/gnunet-uri.c
@@ -53,9 +53,9 @@ maint_child_death (void *cls)
53{ 53{
54 enum GNUNET_OS_ProcessStatusType type; 54 enum GNUNET_OS_ProcessStatusType type;
55 55
56 if ( (GNUNET_OK != 56 (void) cls;
57 GNUNET_OS_process_status (p, &type, &exit_code)) || 57 if ((GNUNET_OK != GNUNET_OS_process_status (p, &type, &exit_code)) ||
58 (type != GNUNET_OS_PROCESS_EXITED) ) 58 (type != GNUNET_OS_PROCESS_EXITED))
59 GNUNET_break (0 == GNUNET_OS_process_kill (p, GNUNET_TERM_SIG)); 59 GNUNET_break (0 == GNUNET_OS_process_kill (p, GNUNET_TERM_SIG));
60 GNUNET_OS_process_destroy (p); 60 GNUNET_OS_process_destroy (p);
61} 61}
@@ -70,56 +70,60 @@ maint_child_death (void *cls)
70 * @param cfg configuration 70 * @param cfg configuration
71 */ 71 */
72static void 72static void
73run (void *cls, char *const *args, const char *cfgfile, 73run (void *cls,
74 char *const *args,
75 const char *cfgfile,
74 const struct GNUNET_CONFIGURATION_Handle *cfg) 76 const struct GNUNET_CONFIGURATION_Handle *cfg)
75{ 77{
76 const char *uri; 78 const char *uri;
77 const char *slash; 79 const char *slash;
78 char *subsystem; 80 char *subsystem;
79 char *program; 81 char *program;
80 struct GNUNET_SCHEDULER_Task * rt; 82 struct GNUNET_SCHEDULER_Task *rt;
81 83
84 (void) cls;
85 (void) cfgfile;
82 if (NULL == (uri = args[0])) 86 if (NULL == (uri = args[0]))
83 { 87 {
84 fprintf (stderr, 88 fprintf (stderr, _ ("No URI specified on command line\n"));
85 _("No URI specified on command line\n"));
86 return; 89 return;
87 } 90 }
88 if (0 != strncasecmp ("gnunet://", uri, strlen ("gnunet://"))) 91 if (0 != strncasecmp ("gnunet://", uri, strlen ("gnunet://")))
89 { 92 {
90 fprintf (stderr, 93 fprintf (stderr,
91 _("Invalid URI: does not start with `%s'\n"), 94 _ ("Invalid URI: does not start with `%s'\n"),
92 "gnunet://"); 95 "gnunet://");
93 return; 96 return;
94 } 97 }
95 uri += strlen ("gnunet://"); 98 uri += strlen ("gnunet://");
96 if (NULL == (slash = strchr (uri, '/'))) 99 if (NULL == (slash = strchr (uri, '/')))
97 { 100 {
98 fprintf (stderr, _("Invalid URI: fails to specify subsystem\n")); 101 fprintf (stderr, _ ("Invalid URI: fails to specify subsystem\n"));
99 return; 102 return;
100 } 103 }
101 subsystem = GNUNET_strndup (uri, slash - uri); 104 subsystem = GNUNET_strndup (uri, slash - uri);
102 if (GNUNET_OK != 105 if (GNUNET_OK !=
103 GNUNET_CONFIGURATION_get_value_string (cfg, 106 GNUNET_CONFIGURATION_get_value_string (cfg, "uri", subsystem, &program))
104 "uri",
105 subsystem,
106 &program))
107 { 107 {
108 fprintf (stderr, _("No handler known for subsystem `%s'\n"), subsystem); 108 fprintf (stderr, _ ("No handler known for subsystem `%s'\n"), subsystem);
109 GNUNET_free (subsystem); 109 GNUNET_free (subsystem);
110 return; 110 return;
111 } 111 }
112 GNUNET_free (subsystem); 112 GNUNET_free (subsystem);
113 rt = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, 113 rt = GNUNET_SCHEDULER_add_read_file (
114 GNUNET_DISK_pipe_handle (sigpipe, 114 GNUNET_TIME_UNIT_FOREVER_REL,
115 GNUNET_DISK_PIPE_END_READ), 115 GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ),
116 &maint_child_death, NULL); 116 &maint_child_death,
117 p = GNUNET_OS_start_process (GNUNET_NO, 0, 117 NULL);
118 NULL, NULL, NULL, 118 p = GNUNET_OS_start_process (GNUNET_NO,
119 program, 119 0,
120 program, 120 NULL,
121 args[0], 121 NULL,
122 NULL); 122 NULL,
123 program,
124 program,
125 args[0],
126 NULL);
123 GNUNET_free (program); 127 GNUNET_free (program);
124 if (NULL == p) 128 if (NULL == p)
125 GNUNET_SCHEDULER_cancel (rt); 129 GNUNET_SCHEDULER_cancel (rt);
@@ -134,13 +138,15 @@ static void
134sighandler_child_death () 138sighandler_child_death ()
135{ 139{
136 static char c; 140 static char c;
137 int old_errno = errno; /* back-up errno */ 141 int old_errno = errno; /* back-up errno */
138 142
139 GNUNET_break (1 == 143 GNUNET_break (
140 GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle 144 1 ==
141 (sigpipe, GNUNET_DISK_PIPE_END_WRITE), 145 GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle (sigpipe,
142 &c, sizeof (c))); 146 GNUNET_DISK_PIPE_END_WRITE),
143 errno = old_errno; /* restore errno */ 147 &c,
148 sizeof (c)));
149 errno = old_errno; /* restore errno */
144} 150}
145 151
146 152
@@ -155,8 +161,7 @@ int
155main (int argc, char *const *argv) 161main (int argc, char *const *argv)
156{ 162{
157 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 163 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
158 GNUNET_GETOPT_OPTION_END 164 GNUNET_GETOPT_OPTION_END};
159 };
160 struct GNUNET_SIGNAL_Context *shc_chld; 165 struct GNUNET_SIGNAL_Context *shc_chld;
161 int ret; 166 int ret;
162 167
@@ -166,9 +171,14 @@ main (int argc, char *const *argv)
166 GNUNET_assert (sigpipe != NULL); 171 GNUNET_assert (sigpipe != NULL);
167 shc_chld = 172 shc_chld =
168 GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD, &sighandler_child_death); 173 GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD, &sighandler_child_death);
169 ret = GNUNET_PROGRAM_run (argc, argv, "gnunet-uri URI", 174 ret = GNUNET_PROGRAM_run (argc,
170 gettext_noop ("Perform default-actions for GNUnet URIs"), 175 argv,
171 options, &run, NULL); 176 "gnunet-uri URI",
177 gettext_noop (
178 "Perform default-actions for GNUnet URIs"),
179 options,
180 &run,
181 NULL);
172 GNUNET_SIGNAL_handler_uninstall (shc_chld); 182 GNUNET_SIGNAL_handler_uninstall (shc_chld);
173 shc_chld = NULL; 183 shc_chld = NULL;
174 GNUNET_DISK_pipe_close (sigpipe); 184 GNUNET_DISK_pipe_close (sigpipe);
diff --git a/src/util/test_common_logging_dummy.c b/src/util/test_common_logging_dummy.c
index b8f2bef91..5c3709206 100644
--- a/src/util/test_common_logging_dummy.c
+++ b/src/util/test_common_logging_dummy.c
@@ -35,12 +35,20 @@
35 * This must be long enough for us to not to mistake skipped log call 35 * This must be long enough for us to not to mistake skipped log call
36 * on a slow machine for a non-skipped one. 36 * on a slow machine for a non-skipped one.
37 */ 37 */
38#define OUTPUT_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MICROSECONDS, 1000) 38#define OUTPUT_DELAY \
39 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MICROSECONDS, 1000)
39 40
40static void 41static void
41my_log (void *ctx, enum GNUNET_ErrorType kind, const char *component, 42my_log (void *ctx,
42 const char *date, const char *msg) 43 enum GNUNET_ErrorType kind,
44 const char *component,
45 const char *date,
46 const char *msg)
43{ 47{
48 (void) ctx;
49 (void) kind;
50 (void) component;
51 (void) date;
44 if (strncmp ("test-common-logging-dummy", component, 25) != 0) 52 if (strncmp ("test-common-logging-dummy", component, 25) != 0)
45 return; 53 return;
46 FPRINTF (stdout, "%s", msg); 54 FPRINTF (stdout, "%s", msg);
@@ -48,7 +56,7 @@ my_log (void *ctx, enum GNUNET_ErrorType kind, const char *component,
48} 56}
49 57
50 58
51#if !defined(GNUNET_CULL_LOGGING) 59#if ! defined(GNUNET_CULL_LOGGING)
52static int 60static int
53expensive_func () 61expensive_func ()
54{ 62{
@@ -57,27 +65,36 @@ expensive_func ()
57#endif 65#endif
58 66
59 67
60#define pr(kind,lvl) {\ 68#define pr(kind, lvl) \
61 struct GNUNET_TIME_Absolute t1, t2;\ 69 { \
62 t1 = GNUNET_TIME_absolute_get ();\ 70 struct GNUNET_TIME_Absolute t1, t2; \
63 GNUNET_log (kind, "L%s %d\n", lvl, expensive_func());\ 71 t1 = GNUNET_TIME_absolute_get (); \
64 t2 = GNUNET_TIME_absolute_get ();\ 72 GNUNET_log (kind, "L%s %d\n", lvl, expensive_func ()); \
65 printf ("1%s %llu\n", lvl,\ 73 t2 = GNUNET_TIME_absolute_get (); \
66 (unsigned long long) GNUNET_TIME_absolute_get_difference (t1, t2).rel_value_us); \ 74 printf ("1%s %llu\n", \
67} 75 lvl, \
76 (unsigned long long) GNUNET_TIME_absolute_get_difference (t1, t2) \
77 .rel_value_us); \
78 }
79
80#define pr2(kind, lvl) \
81 { \
82 struct GNUNET_TIME_Absolute t1, t2; \
83 t1 = GNUNET_TIME_absolute_get (); \
84 GNUNET_log (kind, "L%s %d\n", lvl, expensive_func ()); \
85 t2 = GNUNET_TIME_absolute_get (); \
86 printf ("2%s %llu\n", \
87 lvl, \
88 (unsigned long long) GNUNET_TIME_absolute_get_difference (t1, t2) \
89 .rel_value_us); \
90 }
68 91
69#define pr2(kind,lvl) {\
70 struct GNUNET_TIME_Absolute t1, t2;\
71 t1 = GNUNET_TIME_absolute_get ();\
72 GNUNET_log (kind, "L%s %d\n", lvl, expensive_func());\
73 t2 = GNUNET_TIME_absolute_get ();\
74 printf ("2%s %llu\n", lvl,\
75 (unsigned long long) GNUNET_TIME_absolute_get_difference (t1, t2).rel_value_us); \
76}
77 92
78int 93int
79main (int argc, char *argv[]) 94main (int argc, char *argv[])
80{ 95{
96 (void) argc;
97 (void) argv;
81 /* We set up logging with NULL level - will be overrided by 98 /* We set up logging with NULL level - will be overrided by
82 * GNUNET_LOG or GNUNET_FORCE_LOG at runtime. 99 * GNUNET_LOG or GNUNET_FORCE_LOG at runtime.
83 */ 100 */
@@ -97,6 +114,6 @@ main (int argc, char *argv[])
97 pr2 (GNUNET_ERROR_TYPE_INFO, "INFO"); 114 pr2 (GNUNET_ERROR_TYPE_INFO, "INFO");
98 pr2 (GNUNET_ERROR_TYPE_DEBUG, "DEBUG"); 115 pr2 (GNUNET_ERROR_TYPE_DEBUG, "DEBUG");
99 return 0; 116 return 0;
100} /* end of main */ 117} /* end of main */
101 118
102/* end of test_common_logging_dummy.c */ 119/* end of test_common_logging_dummy.c */
diff --git a/src/util/tun.c b/src/util/tun.c
index 97fbaa83b..e3643d0c6 100644
--- a/src/util/tun.c
+++ b/src/util/tun.c
@@ -44,24 +44,27 @@
44 */ 44 */
45void 45void
46GNUNET_TUN_initialize_ipv4_header (struct GNUNET_TUN_IPv4Header *ip, 46GNUNET_TUN_initialize_ipv4_header (struct GNUNET_TUN_IPv4Header *ip,
47 uint8_t protocol, 47 uint8_t protocol,
48 uint16_t payload_length, 48 uint16_t payload_length,
49 const struct in_addr *src, 49 const struct in_addr *src,
50 const struct in_addr *dst) 50 const struct in_addr *dst)
51{ 51{
52 GNUNET_assert (20 == sizeof (struct GNUNET_TUN_IPv4Header)); 52 GNUNET_assert (20 == sizeof (struct GNUNET_TUN_IPv4Header));
53 GNUNET_assert (payload_length <= UINT16_MAX - sizeof (struct GNUNET_TUN_IPv4Header)); 53 GNUNET_assert (payload_length <=
54 UINT16_MAX - sizeof (struct GNUNET_TUN_IPv4Header));
54 memset (ip, 0, sizeof (struct GNUNET_TUN_IPv4Header)); 55 memset (ip, 0, sizeof (struct GNUNET_TUN_IPv4Header));
55 ip->header_length = sizeof (struct GNUNET_TUN_IPv4Header) / 4; 56 ip->header_length = sizeof (struct GNUNET_TUN_IPv4Header) / 4;
56 ip->version = 4; 57 ip->version = 4;
57 ip->total_length = htons (sizeof (struct GNUNET_TUN_IPv4Header) + payload_length); 58 ip->total_length =
58 ip->identification = (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 59 htons (sizeof (struct GNUNET_TUN_IPv4Header) + payload_length);
59 65536); 60 ip->identification =
61 (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 65536);
60 ip->ttl = FRESH_TTL; 62 ip->ttl = FRESH_TTL;
61 ip->protocol = protocol; 63 ip->protocol = protocol;
62 ip->source_address = *src; 64 ip->source_address = *src;
63 ip->destination_address = *dst; 65 ip->destination_address = *dst;
64 ip->checksum = GNUNET_CRYPTO_crc16_n (ip, sizeof (struct GNUNET_TUN_IPv4Header)); 66 ip->checksum =
67 GNUNET_CRYPTO_crc16_n (ip, sizeof (struct GNUNET_TUN_IPv4Header));
65} 68}
66 69
67 70
@@ -76,13 +79,14 @@ GNUNET_TUN_initialize_ipv4_header (struct GNUNET_TUN_IPv4Header *ip,
76 */ 79 */
77void 80void
78GNUNET_TUN_initialize_ipv6_header (struct GNUNET_TUN_IPv6Header *ip, 81GNUNET_TUN_initialize_ipv6_header (struct GNUNET_TUN_IPv6Header *ip,
79 uint8_t protocol, 82 uint8_t protocol,
80 uint16_t payload_length, 83 uint16_t payload_length,
81 const struct in6_addr *src, 84 const struct in6_addr *src,
82 const struct in6_addr *dst) 85 const struct in6_addr *dst)
83{ 86{
84 GNUNET_assert (40 == sizeof (struct GNUNET_TUN_IPv6Header)); 87 GNUNET_assert (40 == sizeof (struct GNUNET_TUN_IPv6Header));
85 GNUNET_assert (payload_length <= UINT16_MAX - sizeof (struct GNUNET_TUN_IPv6Header)); 88 GNUNET_assert (payload_length <=
89 UINT16_MAX - sizeof (struct GNUNET_TUN_IPv6Header));
86 memset (ip, 0, sizeof (struct GNUNET_TUN_IPv6Header)); 90 memset (ip, 0, sizeof (struct GNUNET_TUN_IPv6Header));
87 ip->version = 6; 91 ip->version = 6;
88 ip->next_header = protocol; 92 ip->next_header = protocol;
@@ -103,27 +107,29 @@ GNUNET_TUN_initialize_ipv6_header (struct GNUNET_TUN_IPv6Header *ip,
103 */ 107 */
104void 108void
105GNUNET_TUN_calculate_tcp4_checksum (const struct GNUNET_TUN_IPv4Header *ip, 109GNUNET_TUN_calculate_tcp4_checksum (const struct GNUNET_TUN_IPv4Header *ip,
106 struct GNUNET_TUN_TcpHeader *tcp, 110 struct GNUNET_TUN_TcpHeader *tcp,
107 const void *payload, 111 const void *payload,
108 uint16_t payload_length) 112 uint16_t payload_length)
109{ 113{
110 uint32_t sum; 114 uint32_t sum;
111 uint16_t tmp; 115 uint16_t tmp;
112 116
113 GNUNET_assert (20 == sizeof (struct GNUNET_TUN_TcpHeader)); 117 GNUNET_assert (20 == sizeof (struct GNUNET_TUN_TcpHeader));
114 GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_IPv4Header) + sizeof (struct GNUNET_TUN_TcpHeader) == 118 GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_IPv4Header) +
115 ntohs (ip->total_length)); 119 sizeof (struct GNUNET_TUN_TcpHeader) ==
120 ntohs (ip->total_length));
116 GNUNET_assert (IPPROTO_TCP == ip->protocol); 121 GNUNET_assert (IPPROTO_TCP == ip->protocol);
117 122
118 tcp->crc = 0; 123 tcp->crc = 0;
119 sum = GNUNET_CRYPTO_crc16_step (0, 124 sum = GNUNET_CRYPTO_crc16_step (0,
120 &ip->source_address, 125 &ip->source_address,
121 sizeof (struct in_addr) * 2); 126 sizeof (struct in_addr) * 2);
122 tmp = htons (IPPROTO_TCP); 127 tmp = htons (IPPROTO_TCP);
123 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint16_t)); 128 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint16_t));
124 tmp = htons (payload_length + sizeof (struct GNUNET_TUN_TcpHeader)); 129 tmp = htons (payload_length + sizeof (struct GNUNET_TUN_TcpHeader));
125 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint16_t)); 130 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint16_t));
126 sum = GNUNET_CRYPTO_crc16_step (sum, tcp, sizeof (struct GNUNET_TUN_TcpHeader)); 131 sum =
132 GNUNET_CRYPTO_crc16_step (sum, tcp, sizeof (struct GNUNET_TUN_TcpHeader));
127 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length); 133 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length);
128 tcp->crc = GNUNET_CRYPTO_crc16_finish (sum); 134 tcp->crc = GNUNET_CRYPTO_crc16_finish (sum);
129} 135}
@@ -139,25 +145,27 @@ GNUNET_TUN_calculate_tcp4_checksum (const struct GNUNET_TUN_IPv4Header *ip,
139 */ 145 */
140void 146void
141GNUNET_TUN_calculate_tcp6_checksum (const struct GNUNET_TUN_IPv6Header *ip, 147GNUNET_TUN_calculate_tcp6_checksum (const struct GNUNET_TUN_IPv6Header *ip,
142 struct GNUNET_TUN_TcpHeader *tcp, 148 struct GNUNET_TUN_TcpHeader *tcp,
143 const void *payload, 149 const void *payload,
144 uint16_t payload_length) 150 uint16_t payload_length)
145{ 151{
146 uint32_t sum; 152 uint32_t sum;
147 uint32_t tmp; 153 uint32_t tmp;
148 154
149 GNUNET_assert (20 == sizeof (struct GNUNET_TUN_TcpHeader)); 155 GNUNET_assert (20 == sizeof (struct GNUNET_TUN_TcpHeader));
150 GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_TcpHeader) == 156 GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_TcpHeader) ==
151 ntohs (ip->payload_length)); 157 ntohs (ip->payload_length));
152 GNUNET_assert (IPPROTO_TCP == ip->next_header); 158 GNUNET_assert (IPPROTO_TCP == ip->next_header);
153 tcp->crc = 0; 159 tcp->crc = 0;
154 sum = GNUNET_CRYPTO_crc16_step (0, &ip->source_address, 2 * sizeof (struct in6_addr)); 160 sum = GNUNET_CRYPTO_crc16_step (0,
161 &ip->source_address,
162 2 * sizeof (struct in6_addr));
155 tmp = htonl (sizeof (struct GNUNET_TUN_TcpHeader) + payload_length); 163 tmp = htonl (sizeof (struct GNUNET_TUN_TcpHeader) + payload_length);
156 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t)); 164 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
157 tmp = htonl (IPPROTO_TCP); 165 tmp = htonl (IPPROTO_TCP);
158 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t)); 166 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
159 sum = GNUNET_CRYPTO_crc16_step (sum, tcp, 167 sum =
160 sizeof (struct GNUNET_TUN_TcpHeader)); 168 GNUNET_CRYPTO_crc16_step (sum, tcp, sizeof (struct GNUNET_TUN_TcpHeader));
161 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length); 169 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length);
162 tcp->crc = GNUNET_CRYPTO_crc16_finish (sum); 170 tcp->crc = GNUNET_CRYPTO_crc16_finish (sum);
163} 171}
@@ -173,36 +181,31 @@ GNUNET_TUN_calculate_tcp6_checksum (const struct GNUNET_TUN_IPv6Header *ip,
173 */ 181 */
174void 182void
175GNUNET_TUN_calculate_udp4_checksum (const struct GNUNET_TUN_IPv4Header *ip, 183GNUNET_TUN_calculate_udp4_checksum (const struct GNUNET_TUN_IPv4Header *ip,
176 struct GNUNET_TUN_UdpHeader *udp, 184 struct GNUNET_TUN_UdpHeader *udp,
177 const void *payload, 185 const void *payload,
178 uint16_t payload_length) 186 uint16_t payload_length)
179{ 187{
180 uint32_t sum; 188 uint32_t sum;
181 uint16_t tmp; 189 uint16_t tmp;
182 190
183 GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); 191 GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
184 GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_IPv4Header) + sizeof (struct GNUNET_TUN_UdpHeader) == 192 GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_IPv4Header) +
185 ntohs (ip->total_length)); 193 sizeof (struct GNUNET_TUN_UdpHeader) ==
194 ntohs (ip->total_length));
186 GNUNET_assert (IPPROTO_UDP == ip->protocol); 195 GNUNET_assert (IPPROTO_UDP == ip->protocol);
187 196
188 udp->crc = 0; /* technically optional, but we calculate it anyway, just to be sure */ 197 udp->crc =
198 0; /* technically optional, but we calculate it anyway, just to be sure */
189 sum = GNUNET_CRYPTO_crc16_step (0, 199 sum = GNUNET_CRYPTO_crc16_step (0,
190 &ip->source_address, 200 &ip->source_address,
191 sizeof (struct in_addr) * 2); 201 sizeof (struct in_addr) * 2);
192 tmp = htons (IPPROTO_UDP); 202 tmp = htons (IPPROTO_UDP);
193 sum = GNUNET_CRYPTO_crc16_step (sum, 203 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint16_t));
194 &tmp,
195 sizeof (uint16_t));
196 tmp = htons (sizeof (struct GNUNET_TUN_UdpHeader) + payload_length); 204 tmp = htons (sizeof (struct GNUNET_TUN_UdpHeader) + payload_length);
197 sum = GNUNET_CRYPTO_crc16_step (sum, 205 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint16_t));
198 &tmp, 206 sum =
199 sizeof (uint16_t)); 207 GNUNET_CRYPTO_crc16_step (sum, udp, sizeof (struct GNUNET_TUN_UdpHeader));
200 sum = GNUNET_CRYPTO_crc16_step (sum, 208 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length);
201 udp,
202 sizeof (struct GNUNET_TUN_UdpHeader));
203 sum = GNUNET_CRYPTO_crc16_step (sum,
204 payload,
205 payload_length);
206 udp->crc = GNUNET_CRYPTO_crc16_finish (sum); 209 udp->crc = GNUNET_CRYPTO_crc16_finish (sum);
207} 210}
208 211
@@ -217,28 +220,30 @@ GNUNET_TUN_calculate_udp4_checksum (const struct GNUNET_TUN_IPv4Header *ip,
217 */ 220 */
218void 221void
219GNUNET_TUN_calculate_udp6_checksum (const struct GNUNET_TUN_IPv6Header *ip, 222GNUNET_TUN_calculate_udp6_checksum (const struct GNUNET_TUN_IPv6Header *ip,
220 struct GNUNET_TUN_UdpHeader *udp, 223 struct GNUNET_TUN_UdpHeader *udp,
221 const void *payload, 224 const void *payload,
222 uint16_t payload_length) 225 uint16_t payload_length)
223{ 226{
224 uint32_t sum; 227 uint32_t sum;
225 uint32_t tmp; 228 uint32_t tmp;
226 229
227 GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_UdpHeader) == 230 GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_UdpHeader) ==
228 ntohs (ip->payload_length)); 231 ntohs (ip->payload_length));
229 GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_UdpHeader) == 232 GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_UdpHeader) ==
230 ntohs (udp->len)); 233 ntohs (udp->len));
231 GNUNET_assert (IPPROTO_UDP == ip->next_header); 234 GNUNET_assert (IPPROTO_UDP == ip->next_header);
232 235
233 udp->crc = 0; 236 udp->crc = 0;
234 sum = GNUNET_CRYPTO_crc16_step (0, 237 sum = GNUNET_CRYPTO_crc16_step (0,
235 &ip->source_address, 238 &ip->source_address,
236 sizeof (struct in6_addr) * 2); 239 sizeof (struct in6_addr) * 2);
237 tmp = htons (sizeof (struct GNUNET_TUN_UdpHeader) + payload_length); /* aka udp->len */ 240 tmp = htons (sizeof (struct GNUNET_TUN_UdpHeader) +
241 payload_length); /* aka udp->len */
238 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t)); 242 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
239 tmp = htons (ip->next_header); 243 tmp = htons (ip->next_header);
240 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t)); 244 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
241 sum = GNUNET_CRYPTO_crc16_step (sum, udp, sizeof (struct GNUNET_TUN_UdpHeader)); 245 sum =
246 GNUNET_CRYPTO_crc16_step (sum, udp, sizeof (struct GNUNET_TUN_UdpHeader));
242 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length); 247 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length);
243 udp->crc = GNUNET_CRYPTO_crc16_finish (sum); 248 udp->crc = GNUNET_CRYPTO_crc16_finish (sum);
244} 249}
@@ -253,16 +258,15 @@ GNUNET_TUN_calculate_udp6_checksum (const struct GNUNET_TUN_IPv6Header *ip,
253 */ 258 */
254void 259void
255GNUNET_TUN_calculate_icmp_checksum (struct GNUNET_TUN_IcmpHeader *icmp, 260GNUNET_TUN_calculate_icmp_checksum (struct GNUNET_TUN_IcmpHeader *icmp,
256 const void *payload, 261 const void *payload,
257 uint16_t payload_length) 262 uint16_t payload_length)
258{ 263{
259 uint32_t sum; 264 uint32_t sum;
260 265
261 GNUNET_assert (8 == sizeof (struct GNUNET_TUN_IcmpHeader)); 266 GNUNET_assert (8 == sizeof (struct GNUNET_TUN_IcmpHeader));
262 icmp->crc = 0; 267 icmp->crc = 0;
263 sum = GNUNET_CRYPTO_crc16_step (0, 268 sum =
264 icmp, 269 GNUNET_CRYPTO_crc16_step (0, icmp, sizeof (struct GNUNET_TUN_IcmpHeader));
265 sizeof (struct GNUNET_TUN_IcmpHeader));
266 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length); 270 sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length);
267 icmp->crc = GNUNET_CRYPTO_crc16_finish (sum); 271 icmp->crc = GNUNET_CRYPTO_crc16_finish (sum);
268} 272}
@@ -286,21 +290,22 @@ GNUNET_TUN_sockaddr_cmp (const struct sockaddr *sa,
286 290
287 switch (sa->sa_family) 291 switch (sa->sa_family)
288 { 292 {
289 case AF_INET: 293 case AF_INET: {
290 { 294 const struct sockaddr_in *sa4 = (const struct sockaddr_in *) sa;
291 const struct sockaddr_in *sa4 = (const struct sockaddr_in *) sa; 295 const struct sockaddr_in *sb4 = (const struct sockaddr_in *) sb;
292 const struct sockaddr_in *sb4 = (const struct sockaddr_in *) sb; 296 if ((include_port) && (sa4->sin_port != sb4->sin_port))
293 return (sa4->sin_addr.s_addr == sb4->sin_addr.s_addr); 297 return GNUNET_NO;
294 } 298 return (sa4->sin_addr.s_addr == sb4->sin_addr.s_addr);
295 case AF_INET6: 299 }
296 { 300 case AF_INET6: {
297 const struct sockaddr_in6 *sa6 = (const struct sockaddr_in6 *) sa; 301 const struct sockaddr_in6 *sa6 = (const struct sockaddr_in6 *) sa;
298 const struct sockaddr_in6 *sb6 = (const struct sockaddr_in6 *) sb; 302 const struct sockaddr_in6 *sb6 = (const struct sockaddr_in6 *) sb;
299 303
300 return (0 == memcmp(&sa6->sin6_addr, 304 if ((include_port) && (sa6->sin6_port != sb6->sin6_port))
301 &sb6->sin6_addr, 305 return GNUNET_NO;
302 sizeof (struct in6_addr))); 306 return (
303 } 307 0 == memcmp (&sa6->sin6_addr, &sb6->sin6_addr, sizeof (struct in6_addr)));
308 }
304 default: 309 default:
305 GNUNET_break (0); 310 GNUNET_break (0);
306 return GNUNET_SYSERR; 311 return GNUNET_SYSERR;